Reputation: 161
I'm working on a DNS resolver in C++, constructing the DNS header is giving me problems. From what I've been able to gather, the header can be constructed through a struct.
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;
I set the header values, place the header in DNS_PACKET, cast as (void *) and send the packet using sendto().
Viewing one of the sent packets in Wireshark shows that the bits are not being set in the correct locations. For example I set q_count to 1, but Wireshark displays the packet with 256 questions.
In all the documentation I've read, this appears to be a valid route to constructing a packet. Am I going about this incorrectly? Is there a better method to construct a packet?
Upvotes: 1
Views: 2053
Reputation: 462
I suggest you can use libnet to build the DNS packet. It will be much easier, never worry about the header's format.
and you sure you have done the hton() or htonl() ?
Upvotes: 2