C中的DNS客户端

我目前正在开展一个学校项目,要求我实现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 [],其中我存储了我从服务器收到的响应。 并且,我需要从此缓冲区中提取信息并填充结构结果。

谢谢,Chander

你的结构看起来不像我从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)。

但请注意,这两者的有线格式都以可变长度“标签” 开头 ,它还可以包含压缩指针(参见s4.1.4)。 这意味着在这些情况下,您无法将整个线块简单地映射到C结构上。

希望这可以帮助…

如果我是你,我将使用wireshark (与RFC结合)来检查数据包结构。 Wireshark捕获并显示流经计算机的网络数据包。 它允许您查看要接收的原始数据和解码的数据包结构。

例如,在下面的屏幕截图中,您可以看到在DNS响应数据包中返回的chat.meta.stackoverflow.com的IP地址,以三种不同的方式呈现。 首先,您可以在屏幕的中间窗格中看到人类可读的版本。 其次,左下方窗格中突出显示的文本将原始DNS数据包显示为一系列hex字节。 第三,在左下方窗格中突出显示的文本中,您可以看到呈现为ASCII文本的数据包(在这种情况下,大多数但不完全是gobbledigook)。 DNS响应数据包的wireshark跟踪

请求格式和响应格式非常相似 – 都包含可变长度字段,我想这就是你所坚持的 – 但是如果你设法正确地形成了一个请求,那么解析响应就不会有太多麻烦。 如果您可以发布更多详细信息,例如您遇到的确切位置,我们可以提供更好的帮助。

我的建议是不要吃饭。 从标题中提取QDCOUNTANCOUNT ,然后跳过标题,跳过QDCOUNT问题,然后开始解析答案。 跳过标签很简单(只需查找第一个字节为0或设置高位),但解码一个是更多的工作(你需要关注并validation“指针”并确保你不会卡住在循环中)。 如果您只查找地址(而不是PTR记录),那么您根本不需要解码标签。