Search code examples
cheaderdnsbit-manipulationoperation

Reading flags from uint16_t


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 : enter image description here

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 ?


Solution

  • 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.