正在解码DNS报头

本文关键字:报头 DNS 解码 | 更新日期: 2023-09-27 18:04:10

我试图在c#中解码DNS数据包,而且,虽然这并不重要,我正在使用SharpPcap

一切都很好,但似乎QRRCODE字段返回错误的值。我在对比我的结果和Wireshark的结果。

QR总是1(响应),即使消息是请求。发生的另一件奇怪的事情是,当消息是查询时返回代码为0,当消息是响应时返回代码为1。

我用来查找DNS头的一个网站是这个。我是不是漏掉了什么?我用来解码数据包的代码是:(数据是包含有效载荷数据的字节数组)

//TransactionID 16 bits (This is correct)
//Not sure why second byte has to be first but that's 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's 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]);

getBit方法在这里:

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);
}

正在解码DNS报头

您尝试过使用Pcap.Net吗?它完全支持DNS,所以你不必手动解码任何东西。