C - 对结构的 DNS 查询

标签 c dns udp structure

<分区>

Possible Duplicate:
C - byte array to structure (dns query)

我有这些结构:

typedef struct dnsQuery {
  char header[12];
  struct dnsQuerySection *querySection;
} TdnsQuery;

typedef struct dnsQuerySection {
  unsigned char *name;
  struct dnsQueryQuestion *question;
} TdnsQuerySection;

typedef struct dnsQueryQuestion {
  unsigned short qtype;
  unsigned short qclass;
} TdnsQueryQuestion;

我在 recvfrom 的字节数组 buf 中有一个 DNS 查询。我正在尝试从这样的字节数组中获取结构:

TdnsQuery* dnsQuery = (TdnsQuery*)buf;

当我尝试像这样访问 qtype 时:

printf("%u", dnsQuery->querySection->question.qtype);

我遇到段错误 11。

有人可以帮我处理这些结构吗?他们怎么了?我试图添加结构:

typedef struct udpPacket {
  char header[8];
  structr dnsQuery query;
}

并从字节数组映射这个结构,但它没有帮助。有人可以帮我处理这些结构吗?对于使用 UDP 协议(protocol)的 DNS 查询,它们应该是什么样子?

编辑:我的结构现在看起来像这样:

 typedef struct {
      unsigned short qtype;
      unsigned short qclass;
 } dnsQueryQuestion;

 typedef struct {

      dnsQueryQuestion *question;
      unsigned char *data[0];
 } dnsQuerySection;

 typedef struct {
      char header[12];
      dnsQuerySection querySection[0];
 } dnsQuery;

 typedef struct udpPacket {
      char header[8];
      dnsQuery query[0];
 } TudpPacket;

我添加了解析函数:

void parse(unsigned char *data, unsigned short *qtype, unsigned short *qclass) {
    int i = 0;
    while (data[i]) {
        int len = data[i];
        i += len + 1;
    }
    *qtype = (unsigned short) data[i+1];
    *qclass = (unsigned short) data[i+3];
    return;
} 

并尝试解析:

TudpPacket udpPack = (TudpPacket)buf;
parse(udpPack.query.querySection.data, &(udpPack.query.querySection.question.qtype), &(udpPack.query.querySection.question.qclass));
printf("%u\n", udpPack.query.querySection.question.qtype);

最佳答案

首先,您可以将 dnsQuery 更改为:

typedef struct dnsQuery {
  char header[12];
  struct dnsQuerySection querySection[0];
} TdnsQuery;

在这里查看零长度数组的用法:http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

但是,由于 DNS 问题中的 QNAME 部分是可变长度的,您可能无法将其与 QTYPEQCLASS 分开code> 直接使用struct。例如,

Header

00 01   - ID = 1
01 00   - RD = 1
00 01   - QD = 1
00 00   - AN
00 00   - NS
00 00   - NR

   Question  for www.google.com

   03 77   - 3 w
   77 77   - w w
   06 67   - 6 g
   6f 6f   - o o
   67 6c   - g l
   65 03   - e 3
   63 6f   - c o
   6d 00   - m 0
   00 01   - QTYPE
   00 01   - QCLASS

如果你能保证传入请求中只有一个问题,试试这个:

typedef struct dnsQuerySection {
  unsigned char *data[0];
} TdnsQuerySection;

并编写一个函数来解析它。

编辑:下面是解析函数的草图,只是为了您的方便。

char* parse(unsigned char *data, unsigned short *qtype, unsigned short *qclass) {
    int i = 0;
    while (data[i]) {
        int len = data[i];
        i += len + 1;
    }
    /* data[i] == 0 */
    /* you may need to loop data[] again and do strcpy to get the domain name */
    *qtype = (unsigned short) data[i+1];
    *qclass = (unsigned short) data[i+3];
    return /* domain name */;
}

关于C - 对结构的 DNS 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13439361/

相关文章:

c++ - 如何从 CMakeLists.txt 生成 cscope.files

delphi - Delphi 上通过 Winsock2 的原始 UDP 数据包

linux - 使用 select 系统调用阻止 recvfrom

c - 如何在 POSIX C 中枚举连接到机器的所有 IP 地址?

c - 有没有办法使用 libcurl >=7.3.x 从 HTTP header 获取内容长度?

c - 当在函数中声明相同变量时全局变量不起作用

linux - recvfrom(2) 收到两次 UDP 广播,但 tcpdump(8) 只收到一次

azure - 为什么 CNAME 记录在 Azure DNS 上返回 404 错误

dns - cert-manager DNS01 挑战失败 - 找不到通配符域的区域

mobile - 通过移动网络进行实时多人游戏?