Я работаю над DNS-резольвером в C++, создание заголовка DNS дает мне проблемы. Из того, что я смог собрать, заголовок можно построить через структуру.
typedef struct {
unsigned short id;
unsigned char qr :1; // 0 query, 1 response
unsigned char opcode :4; // 0 standard query
unsigned char aa :1; // authoritive answer
unsigned char tc :1; // truncated message
unsigned char rd :1; // recursion desired
unsigned char ra :1; // recursion available
unsigned char z :3; // reserved
unsigned char rcode :4; // response code
unsigned q_count :16; // number of question entries
unsigned ans_count :16; // number of answer entries
unsigned auth_count :16; // number of authority entries
unsigned add_count :16; // number of resource entries
} HEADER;
typedef union {
HEADER header;
unsigned char packet_data[1024];
} DNS_PACKET;
Я устанавливаю значения заголовка, размещаю заголовок в DNS_PACKET, отливая как (void *) и отправляю пакет с помощью sendto().
Просмотр одного из отправленных пакетов в Wireshark показывает, что биты не устанавливаются в правильных местах. Например, я установил q_count в 1, но Wireshark отображает пакет с 256 вопросами.
Во всей документации, которую я прочитал, это, по-видимому, правильный путь к созданию пакета. Я об этом неправильно? Есть ли лучший способ для создания пакета?
Я предлагаю вам использовать libnet для создания пакета DNS. Это будет намного проще, никогда не беспокоиться о формате заголовка.
и вы уверены, что сделали hton() или htonl()?