如何在C语言中捕获DNS数据包?

4

我正在使用C编写一个数据包嗅探器程序。目前它只能找到HTTP数据包,但我想让它也能获取DNS数据包。我知道DNS数据包是UDP的,但不知道如何识别它们。在DNS数据包中有特定的内容可以检查吗?我知道53端口是DNS请求的默认端口,但这是一种可靠的方法来找到它们吗?


1
我知道53端口是DNS请求的默认端口,但这是一种可靠的查找方式吗? 是的。而且这是唯一正确的方法。 - Patrick Mevzek
1个回答

3

没有一个好的方法可以确定一个 UDP 数据包是否包含 DNS 数据:在 UDP 头或 IP 头中没有任何直接告诉你数据是 DNS 的信息。但是,您可以首先查看 UDP 头中的源端口是否为53号端口DNS 的标准 UDP 端口),然后第二检查数据是否符合您用于解码头部的数据结构(最可能是一个结构体)。这是一个非常好的问题。

要将数据包适配到结构体中,您可以使用以下代码:

这是一个在 C 语言中以结构体形式布置 DNS 标头数据包的实际结构:

#pragma pack(push, 1)
typedef struct 
{
    uint16_t id; // identification number 2b
    
    uint8_t rd : 1; // recursion desired
    uint8_t tc : 1; // truncated message
    uint8_t aa : 1; // authoritive answer
    uint8_t opcode : 4; // purpose of message
    uint8_t qr : 1; // query/response flag

    uint8_t rcode : 4; // response code
    uint8_t cd : 1; // checking disabled
    uint8_t ad : 1; // authenticated data
    uint8_t z : 1; // its z! reserved
    uint8_t ra : 1; // recursion available 4b

    uint16_t q_count; // number of question entries 6b
    uint16_t ans_count; // number of answer entries 8b
    uint16_t auth_count; // number of authority entries 10b
    uint16_t add_count; // number of resource entries 12b
}Dns_Header, *Dns_Header_P;
#pragma pack(pop)

为了测试这个,你可以这样做:

Dns_Header_P header = (Dns_Header_P)capture;

capture 是一个包含DNS头部的字节数组。

根据你抓取数据包和存储数据包的方式,你可能需要更改结构体的字节序。如果你使用程序测试后发现数据不正确或数据混乱,请告诉我。


我该如何在C语言中查看数据包的结构?你能给我提供方法或链接吗? - Amir reza Riahi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接