I'm currently working on a packet sniffer/analyzer for a school project, and I'm having trouble extracting the DNS flags from the DNS header.
A DNS header looks like this :
The DNS header struct looks like this :
struct dnshdr {
uint16_t xid;
uint16_t flags;
uint16_t qdcount;
uint16_t ancount;
uint16_t nscount;
uint16_t arcount;
};
How can I extract the individual flags from the uint16_t ?
you can either define a structure with bitfields, which always sounds the cleanest way on paper but turns out to be a nightmare of implementation-defined features and almost completely unportable, or you do it the simple way with masks and shifts - macros are the common implementation:
#define QR(f) (f & 0x0001)
#define OPCODE(f) ((f & 0x001E) >> 1)
#define AA(f) ((f & 0x0020) >> 5)
...etc
This is of course assuming any necessary endianness correction has been done already (so the two bytes of the uint16_t
are in the correct order to be interpreted this way)
Afterthought: the one-bit flags don't really need to be shifted either - once they're masked they're going to be zero or non-zero, which is enough for testing them in C.