代码之家  ›  专栏  ›  技术社区  ›  Chander Shivdasani

C中的DNS客户端

  •  4
  • Chander Shivdasani  · 技术社区  · 14 年前

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

    谢谢, 钱德尔

    4 回复  |  直到 14 年前
        1
  •  6
  •   Alnitak    14 年前

    你的结构看起来不像我从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() 将这些字段的wire格式转换为计算机的本机字节顺序。网络秩序是大端的,现在大多数机器都是小端的。

    你需要一个“问题”结构(见s4.1.2)和一个通用的“资源记录”结构(见s4.1.3)。

    但是请注意,这两种类型的wire格式 开始 带有可变长度的“标签”,也可以包括压缩指针(见s4.1.4)。这意味着在这些情况下,不能简单地将整个wire块映射到C结构上。

    希望这有帮助。。。

        2
  •  0
  •   fmark    14 年前

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

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

        3
  •  0
  •   casablanca    14 年前

    这个 request format response format 两者非常相似-都包含可变长度的字段,我想这正是您所坚持的-但是如果您成功地形成了一个请求,那么解析响应应该不会有太多麻烦。如果你能发布更多的细节,比如你到底被困在哪里,我们可以提供更好的帮助。

        4
  •  -1
  •   R.. GitHub STOP HELPING ICE    14 年前

    我的建议是不要大吃一惊。提取 QDCOUNT ANCOUNT 从标题,然后跳过标题,跳过 数量 开始分析答案。跳过一个标签很容易(只需查找第一个字节是0或设置了高位),但解码一个标签则要做更多的工作(您需要跟踪并验证“指针”,确保不会陷入循环)。如果你只查地址(而不是 PTR 然后你真的根本不需要解码标签。