2012-11-14 35 views
0

我正在寫一個程序來接收DNS信息並回應一個合適的答案(一個簡單的DNS服務器,只答復A記錄)。
但是當我收到消息時,它不像1035 RFC中描述的格式。
例如,這是通過NSLOOKUP產生的DNS查詢:
我如何解密DNS的消息?

'\xe1\x0c\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06google\x03com\x00\x00\x01\x00\x01' 

我知道DNS頭和位在1035 RFC定義,但爲什麼它應該是十六進制?
我應該認爲它們是十六進制數還是它們的utf-8等價物?
我的回覆也應該有這種格式嗎?

+1

這是在十六進制中,因爲您用來打印出的代碼在十六進制中打印了不可打印的字符。你可以用任何你喜歡的格式打印出來。 –

+0

你打電話給nslookup?在腳本中? – xxpor

+1

字節,字符,二進制,十六進制,UTF等...這些是人類的事情。計算機只處理位數,通常按8的倍數分組。不管你希望如何編寫一個程序來解釋這些位。 –

回答

5

它以十六進制形式出現,因爲它是一個原始的二進制請求,但您大概試圖將其打印爲字符串。這顯然是不可打印的字符是如何顯示的,無論你用什麼打印出來;它將它們作爲十六進制序列轉義。

您不會將其解釋爲「hex」或UTF-8;你需要解釋RFC所描述的二進制格式。如果您提及您使用的語言,我(或其他人)可能會向您描述如何以二進制格式處理數據。

取消平鋪那麼,讓我們來看看RFC 1035,看看如何用手工來解釋您的查詢:

The header contains the following fields: 

            1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |      ID      | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |QR| Opcode |AA|TC|RD|RA| Z | RCODE | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     QDCOUNT     | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     ANCOUNT     | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     NSCOUNT     | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     ARCOUNT     | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 

每行有16位,所以這是12個字節。讓我們填寫我們的第一個12字節到那裏:

        1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     ID = e10c     | \xe1 \x0c 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    | 0| Opcode=0 | 0| 0| 1| 0| Z=0 | RCODE=0 | \x01 \x00 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     QDCOUNT = 1     | \x00 \x01 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     ANCOUNT = 0     | \x00 \x00 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     NSCOUNT = 0     | \x00 \x00 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     ARCOUNT = 0     | \x00 \x00 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 

所以。我們有一個查詢ID = e10c(只是一個任意數字,所以客戶端可以將查詢與響應進行匹配),QR = 0表示它是查詢,opcode = 0表示它是標準查詢,AA和TC用於響應, RD = 1表示需要遞歸(我們正在對本地名稱服務器進行遞歸查詢)。 Z保留供將來使用,RCODE是響應的響應代碼。 QDCOUNT = 1表示我們有1個問題,其餘的是響應中不同類型記錄的數量。

現在我們來回答問題。每種格式都有以下格式:

        1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |            | 
    /     QNAME     /
    /           /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |      QTYPE      | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |      QCLASS     | 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 

QNAME是查詢的名稱。格式是一個八位組,表示一個標籤的長度,後面跟着標籤,由長度爲0的標籤終止。

因此,我們有:

        1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |  LEN = 6   |   g   | \x06 g 
    |   o   |   o   | o o 
    |   g   |   l   | g l 
    |   e   |  LEN = 3   | e \x03 
    |   c   |   o   | c o 
    |   m   |  LEN = 0   | m \x00 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     QTYPE = 1     | \x00 \x01 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
    |     QCLASS = 1     | \x00 \x01 
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 

這表明,我們正在尋找這名字是google.com(有時寫爲google.com.,與空標籤在年底作出了明確)。 QTYPE = 1是一個A(IPv4地址)記錄。 QCLASS = 1是一個IN(互聯網)查詢。所以這是要求google.com的IPv4地址。

+0

tnx,這是非常有用的。你也會說明一個迴應嗎? – sia