Here is the packet struct for a dns resolver I made:
Code:
/* DNS Header common to queries and answers
* This structure starts at byte 0 for udp packets */
typedef struct tagDnsHdr {
/* id of this request - used by application to match queries
* with replies - usually process id, but can be anything */
short id;
/* Note: We could do flags with bit fields but then we have
* to declare them twice. Once for little endian and once
* for big endian layout */
/* First byte of flags. Contains the following fields:
* QR (1 bit), OPCODE(4 bits), AA(1 bit), TC(1 bit), RD(1 bit)
* These can be set or retrieved using the bit mask constants
* eg. DNSHDR.lFlags |= BITS_RD to set.
* and to retrieve: trunc = DNSHDR.lFlags & BITS_TC
* For more information on these fields see the comments with
* the bit masks */
unsigned char lFlags;
/* Second byte of flags. Contains the following fields:
* RA (1 bit), Z(3 bits), RCODE(4 bits)
* Note: Z is marked as reserved in rfc 1035 */
unsigned char rFlags;
unsigned short qCount; /* query count */
unsigned short anCount; /* answer count - return value only */
unsigned short nsCount; /* name server count - return value only */
unsigned short arCount; /* additional records count - return value only */
} DNSHDR;
/* lFlags bit masks */
/* zero for a query, one for a response */
#define BITS_QR 128
/* usually zero for a standard query */
#define BITS_OPCODE 120
/* Authoritative Answer - this bit is valid in responses,
* and specifies that the responding name server is an
* authority for the domain name in question section. */
#define BITS_AA 4
/* Set if the answer has been truncated for being over the
* 512 byte limit (udp only) */
#define BITS_TC 2
/* Recursion desired - Should be set in the query */
#define BITS_RD 1
/* rFlags bit masks */
/* Recursion available - set by server if it was able
* to use recursion */
#define BITS_RA 128
/* Reserved - should be zero */
#define BITS_Z 112
/* The response code is returned by the server */
#define BITS_RCODE 15
If I was doing this again I would use bitfields. Also, I would use types such as int16_t for maximum portability.
I could post my complete code but here is a much better example:
http://www.planet-source-code.com/vb...txtCodeId=5712
Search for dns.c for other examples.
NB. Buffer overruns are extremely easy to miss in a dns resolver, so if you don't want the dns server to be able to execute code on your machine be careful.
EDIT:
Bitfield example - PCs are little endian, Unix is typically big endian.