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?