DNS Header Decoding

I am trying to decode DNS packets in C #, and although this does not really matter, I use SharpPcap .

Everything works well, but it seems that the QR and RCODE fields are returning incorrect values. I compare my results with the results of Wireshark.

QR is always 1 (reply), even if the message is a request. Another strange thing that happens is that the return code is 0 when the message is a request and 1 when the message is a response.

One of the sites I used to determine the DNS header was this . Is something missing here? The code I use to decode the packet is: (the data is a byte array that contains the payload data)

//TransactionID 16 bits (This is correct) //Not sure why second byte has to be first but that how wireshark displays it transactionID = new byte[] { data[1], data[0] }; //Flags 16 bits isResponse = Utilities.getBit(data[2], 0); //always returns 1 //What I'm doing here is converting the boolean returned by getBit into a //1 or 0 which is used to create a string which will then be converted //into a UInt16 (If there an easier way to do this please let me know) OpCode = Convert.ToUInt16(Convert.ToUInt16(Utilities.getBit(data[2], 1)).ToString() + Convert.ToUInt16(Utilities.getBit(data[2], 2)).ToString() + Convert.ToUInt16(Utilities.getBit(data[2], 3)).ToString() + Convert.ToUInt16(Utilities.getBit(data[2], 4)).ToString(), 2); //These seem correct (Untested though since wireshark doesn't display them) authAnswer = Utilities.getBit(data[2], 5); truncation = Utilities.getBit(data[2], 6); recursionDesired = Utilities.getBit(data[2], 7); recursionAvail = Utilities.getBit(data[3], 0); //skip 3 bits here (reserved and set to 0)... //ReturnCode returns 0 for queries and 1 for responses, this is pretty weird returnCode = Convert.ToUInt16(Convert.ToUInt16(Utilities.getBit(data[3], 4)).ToString() + Convert.ToUInt16(Utilities.getBit(data[3], 5)).ToString() + Convert.ToUInt16(Utilities.getBit(data[3], 6)).ToString() + Convert.ToUInt16(Utilities.getBit(data[3], 7)).ToString(), 2); //Questions count, Answers count, ARR count, Additional ARR: 1 byte each //These are correct questionsCount = Convert.ToUInt16(data[4] * 256 + data[5]); answersCount = Convert.ToUInt16(data[6] * 256 + data[7]); authorityRRs = Convert.ToUInt16(data[8] * 256 + data[9]); additionalRRs = Convert.ToUInt16(data[10] * 256 + data[11]); 

The getBit method is here:

 public static bool getBit(byte b, int index) { //Logical AND with number to find if bit is 0 or 1 //Shift by index to represent value in binary (2^index) bool bit = (b & (1 << index)) != 0; return (bit); } 
+4
source share
1 answer

Have you tried using Pcap.Net ? It has full DNS support, so you do not need to decode anything manually.

+2
source

All Articles