2013-03-16 65 views
4

我試圖解碼C#中的DNS數據包,雖然它並不重要,但我使用的是SharpPcap解碼DNS標頭

一切運作良好,但似乎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); 
} 
+0

「不確定爲什麼第二個字節必須是第一個」與平臺的「endian」有關 - 請參閱:http://en.wikipedia.org/wiki/UTF-16 – Hogan 2013-03-17 00:36:37

+0

您是否試過閱讀標誌爲16位無符號,然後查看該變量中的位(使用ToUInt16)。我認爲這是相同的endian問題 - 16位無符號將自動按正確的順序。 – Hogan 2013-03-17 02:01:20

+0

謝謝你的回覆,我決定按照你的建議,它的工作。但是,getBit()方法也是導致問題的原因之一(索引從數字的末尾開始)。再次感謝 – 2013-03-25 14:30:49

回答

2

您是否嘗試過使用Pcap.Net?它完全支持DNS,因此您不必手動解碼任何內容。

+0

謝謝,我試過Pcap。淨因爲它看起來很有前途。我仍在使用它。再次感謝 – 2013-03-25 14:31:37