DNS-клиент в C - PullRequest
       41

DNS-клиент в C

4 голосов
/ 15 ноября 2010

В настоящее время я работаю над школьным проектом, который просит меня реализовать клиент DNS без использования каких-либо библиотечных функций.

Я дошел до того, что отправил запрос DNS и получил ответ.Я застреваю при разборе ответа.Я получаю ответ в массиве char * и хочу преобразовать его в какую-то значимую структуру, из которой я могу разобрать ответ.Я прошел RFC и прочитал о структуре пакета, но его реализация на C доставляет мне проблемы.

Может ли кто-нибудь дать мне какие-либо примеры на C или, может быть, на любом другом языке, который объясняет, как это делается.Или любая ссылка на книгу тоже подойдет.

Дополнительные сведения:

Итак, ниже приведены структуры, которые я использую.

struct result{
  int type;
  struct res_ip_cname ip_cname;
  struct res_error error;
  struct res_mx_ns mx_ns;
};

struct res_ip_cname{
  char* lst;
  int sec;
  char* auth_flag;
};

struct res_error{
  char * info;
};

struct res_mx_ns{
  char * name;
  unsigned short pref;
  int sec;
  char* auth_flag;
};

У меня есть буфер char * [], в котором я сохраняю ответ, который я получаю от сервера.И мне нужно извлечь информацию из этого буфера и заполнить результат структуры.

Спасибо, Чандер

Ответы [ 4 ]

6 голосов
/ 15 ноября 2010

Ваши структуры не похожи на то, что я узнаю по RFC (да, я написал много программ для декодирования пакетов DNS).

Посмотрите, в частности, RFC 1035 - большинство нужных вам структур можно сопоставить непосредственно из отображенных там схем полей.

Например, вам нужен заголовок (см. S4.1.1):

struct dns_header {
     uint16_t     query_id;
     uint16_t     flags;
     uint16_t     qdcount;
     uint16_t     ancount;
     uint16_t     nscount;
     uint16_t     arcount;
};

Не забудьте использовать ntohs() для преобразования формата этих полей в проводной порядок байтов вашего компьютера. Порядок в сети имеет порядок байтов, и большинство машин в наши дни имеют порядок байтов.

Вам понадобится структура «вопрос» (см. S4.1.2), а также общая структура «запись ресурса» (см. S4.1.3).

Обратите внимание, однако, что формат проводов обоих этих начинается с «метки» переменной длины, которая также может включать указатели сжатия (см. Раздел 4.1.4). Это означает, что вы не можете в этих случаях тривиально отобразить весь проводной блок на структуру C.

Надеюсь, это поможет ...

0 голосов
/ 15 ноября 2010

Мой совет: не ешьте это.Извлеките QDCOUNT и ANCOUNT из заголовка, затем пропустите заголовок, пропустите QDCOUNT вопросы и начните анализ ответов.Пропустить метку легко (просто ищите первый байт, который равен 0 или установлен старший бит), но декодирование одного - это немного больше работы (вам нужно следовать и проверять «указатели» и быть уверенным, что вы не застрялив петле).Если вы просматриваете только адреса (а не PTR записи), вам вообще не нужно декодировать метки.

0 голосов
/ 15 ноября 2010

Формат запроса и формат ответа очень похожи - оба содержат поля переменной длины, которые, как я полагаю, и есть то, на чем вы застряли - но если вам удалось сформироватьправильно запрос, у вас не должно быть особых проблем с анализом ответа.Если вы можете опубликовать более подробную информацию, например, где именно вы застряли, мы могли бы помочь лучше.

0 голосов
/ 15 ноября 2010

На вашем месте я бы использовал wireshark (в сочетании с RFC) для проверки структуры пакета.Wireshark захватывает и отображает сетевые пакеты, проходящие через ваш компьютер.Это позволяет вам видеть как необработанные данные, которые вы будете получать, так и структуру декодированных пакетов.

Например, на приведенном ниже снимке экрана вы видите IP-адрес chat.meta.stackoverflow.com, возвращенный в пакете ответа DNS, который представлен тремя различными способами.Во-первых, вы можете увидеть читаемую человеком версию в средней части экрана.Во-вторых, выделенный текст в нижней левой панели показывает необработанный пакет DNS в виде последовательности шестнадцатеричных байтов.В-третьих, в выделенном тексте в нижней левой панели вы можете увидеть пакет, отображаемый как текст ASCII (в данном случае, в основном, но не полностью, gobbledigook).a wireshark trace of a DNS response packet

...