C语言的DNS客户端

发布于 2024-10-02 06:33:50 字数 692 浏览 0 评论 0原文

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

谢谢, 钱德

I am currently working on a school project which asks me to implement a DNS client, without using any library functions.

I have got to the point where i send a DNS request and Receive the Reply. I'm getting stuck at the parsing of the reply. I receive the reply in a char* array and i want to convert it into some meaningful structure, from which i can parse the answer.
I went through the RFC and i read about the packet structure, but implementing it in C is giving me problems.

Can anyone give me any examples, in C, or maybe in any other language that explains how this is done. Or any reference to a book is also fine.

Additional Details:

So, the following are the structures that i'm using.

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;
};

I have a char* buffer[], where im storing the response the i receive from the server. And, i need to extract information from this buffer and populate the structure result.

Thanks,
Chander

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无声情话 2024-10-09 06:33:50

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

希望这有帮助...

Your structures don't look like anything I recognise from the RFCs (yes, I've written lots of DNS packet decoding software).

Look at RFC 1035 in particular - most of the structures you need can be mapped directly from the field layouts show therein.

For example, you need a header (see 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;
};

Don't forget to use ntohs() to convert the wire format of these fields into your machine's native byte order. The network order is big-endian, and most machines these days are little-endian.

You'll need a "question" structure (see s4.1.2), and a generic "resource record" structure too (see s4.1.3).

Note however that the wire format of both of these starts with a variable length "label", which can also include compression pointers (see s4.1.4). This means that you can't in these cases trivially map the whole wire block onto a C structure.

Hope this helps...

弱骨蛰伏 2024-10-09 06:33:50

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

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

If I were you I'd be using wireshark (in combination with the RFC) to inspect the packet structure. Wireshark captures and displays the network packets flowing through your computer. It lets you see both the raw data you will be receiving, and the decoded packet structure.

For example, in the screenshot below you can see the IP address of chat.meta.stackoverflow.com returned in a DNS Response packet, rendered in three different ways. Firstly, you can see a human readable version, in the middle pane of the screen. Secondly, the highlighted text in the lower left pane shows the raw DNS packet as a series of hexadecimal bytes. Thirdly, in the highlighted text in the lower left pane, you can see the packet rendered as ASCII text (in this case, mostly but not entirely, gobbledigook).
a wireshark trace of a DNS response packet

梦情居士 2024-10-09 06:33:50

请求格式请求格式 cx/dns-response-format.php" rel="nofollow">响应格式非常相似 - 都包含可变长度字段,我猜这就是您所坚持的 - 但如果您设法做到了正确地形成请求,解析响应应该不会有太多麻烦。如果您可以发布更多详细信息,例如您具体陷入困境的位置,我们可以提供更好的帮助。

The request format and response format are quite similar - both contain variable length fields, which I guess is what you're stuck on - but if you've managed to form a request properly, you shouldn't have too much trouble parsing the response. If you can post some more details, like where exactly you're stuck, we could help better.

惜醉颜 2024-10-09 06:33:50

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

My advice is don't make a meal of it. Extract QDCOUNT and ANCOUNT from the header, then skip over the header, skip QDCOUNT questions, and start parsing answers. Skipping a label is easy (just look for the first byte that's 0 or has the high bit set), but decoding one is a little bit more work (you need to follow and validate "pointers" and make sure you don't get stuck in a loop). If you're only looking up addresses (and not PTR records) then you really never need to decode labels at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文