【问题标题】:Decoding DNS Header解码 DNS 标头
【发布时间】:2013-03-05 13:23:49
【问题描述】:

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

一切正常,但似乎 QRRCODE 字段返回错误值。我正在将我的结果与 Wireshark 的结果进行比较。

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

我用来查找 DNS 标头的站点之一是 this 之一。我在这里缺少什么吗?我用来解码数据包的代码是:(数据是一个包含有效负载数据的字节数组)

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

【问题讨论】:

  • "不确定为什么第二个字节必须在前" 与平台的 "endian" 相关 -- 参见:en.wikipedia.org/wiki/UTF-16
  • 您是否尝试过将标志读取为 16 位无符号,然后查看该变量中的位(使用 ToUInt16)。我认为这是相同的字节序问题 - 16 位无符号会自动将其置于正确的顺序。
  • 感谢您的回复,我决定听从您的建议,并且成功了。但是,getBit() 方法也是导致问题的方法之一(索引从数字的末尾开始)。再次感谢

标签: c# dns header sharppcap


【解决方案1】:

您是否尝试过使用Pcap.Net?它完全支持 DNS,因此您无需手动解码任何内容。

【讨论】:

  • 谢谢,我试过 Pcap。 Net,因为它看起来很有希望。我还在用它。再次感谢
猜你喜欢
  • 2014-02-08
  • 2014-12-15
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
相关资源
最近更新 更多