2010-11-15 48 views
4

我目前正在研究一個學校項目,要求我實現DNS客戶端,而不使用任何庫函數。C中的DNS客戶端

我得在那裏我發送一個DNS請求和接收回復的地步。我被困在答覆的解析中。我收到一個char *數組的答覆,我想將其轉換成一些有意義的結構,從中我可以解析答案。 我經歷了RFC並且我讀了關於數據包結構,但是在C中實現它給我帶來了問題。

誰能給我任何的例子,在C,或者也許在解釋如何做到這一點任何其他語言。或者任何對書籍的引用也很好。

附加信息:

因此,以下是我正在使用的結構。

struct result{ 
    int type; 
    struct res_ip_cname ip_cname; 
    struct res_error error; 
    struct res_mx_ns mx_ns; 
}; 

struct res_ip_cname{ 
    char* lst; 
    int sec; 
    char* auth_flag; 
}; 

struct res_error{ 
    char * info; 
}; 

struct res_mx_ns{ 
    char * name; 
    unsigned short pref; 
    int sec; 
    char* auth_flag; 
}; 

我有一個char * buffer [],其中im存儲我從服務器收到的響應。而且,我需要從這個緩衝區提取信息並填充結構結果。

感謝, 錢德爾

回答

5

你的結構看起來不像我從RFC中識別的東西(是的,我已經寫了大量的DNS數據包解碼軟件)。

特別關注一下RFC 1035 - 最需要,可直接從現場佈局映射結構的顯示在其中。

例如,你需要一個標題(見S4.1。1):

struct dns_header { 
    uint16_t  query_id; 
    uint16_t  flags; 
    uint16_t  qdcount; 
    uint16_t  ancount; 
    uint16_t  nscount; 
    uint16_t  arcount; 
}; 

不要忘了使用ntohs()這些字段的傳輸格式轉換成你的機器的本地字節順序。網絡訂單是大端的,現在大多數機器都是小端的。你需要一個「問題」結構(見s4.1.2)和一個通用的「資源記錄」結構(見s4.1.3)。

但是請注意,這兩個的線格式都是以變量長度「label」開始的,它也可以包含壓縮指針(參見s4.1.4)。這意味着在這些情況下,您不能將整個導線塊簡單地映射到C結構上。

希望這有助於...

0

如果我是你,我會用wireshark(與RFC組合)來檢查數據包結構。 Wireshark捕獲並顯示流經計算機的網絡數據包。它可以讓你看到你將要接收的原始數據和解碼的數據包結構。

例如,在下面的截圖中可以看到在DNS響應數據包返回chat.meta.stackoverflow.com的IP地址,以三種不同的方式呈現。首先,您可以在屏幕的中間窗格中看到人類可讀的版本。其次,左下窗格中突出顯示的文本將原始DNS數據包顯示爲一系列十六進制字節。第三,在左下窗格的突出顯示的文本中,您可以看到數據包呈現爲ASCII文本(在這種情況下,大部分是但不完全是gobbledigook)。 a wireshark trace of a DNS response packet

0

我的建議是不要做它的一個餐。從頭中提取QDCOUNTANCOUNT,然後跳過頭,跳過QDCOUNT問題,並開始解析答案。跳過標籤很容易(只需查找第一個字節爲0或者設置爲高位),但解碼一個是更多的工作(您需要遵循並驗證「指針」,並確保您不會卡住在一個循環中)。如果你只查找地址(而不是PTR記錄),那麼你根本就不需要解碼標籤。

+0

這是典型的'連A'答案使用標籤 - 通常是'在回答name'場是指向回到問題的標籤。 – caf 2010-11-15 05:48:29

+0

但是當查找地址時,沒有理由解析標籤,除非您想(1)檢查答案實際上是對您的查詢的答案,或者(2)當您查找的名稱導致「 CNAME「記錄和相應的」A「或」AAAA「記錄。跳過它們比分析它們要容易得多。 :-) – 2010-11-15 08:48:04

0

request formatresponse format非常相似 - 兩者都包含可變長度的字段,我猜是你堅持的 - 但如果你已經設法正確地形成請求,你不應該有太多的解析麻煩響應。如果您可以發佈更多詳細信息,例如您卡在哪裏,我們可以提供更好的幫助。