C中的DNS客户端

时间:2010-11-15 04:52:12

标签: c sockets network-programming 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

4 个答案:

答案 0 :(得分:6)

您的结构看起来不像我在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结构上。

希望这会有所帮助......

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

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