0

可能重复:
C - 字节数组到结构(dns 查询)

我有这些结构:

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;

我在一个字节数组中有一个 DNSbuf查询recvfrom。我正在尝试从字节数组中获取结构,如下所示:

TdnsQuery* dnsQuery = (TdnsQuery*)buf;

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

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

我得到段错误 11。

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

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

并从字节数组映射这个结构,但它没有帮助。有人可以帮我处理这些结构吗?对于使用 UDP 协议的 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);
4

1 回答 1

3

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

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

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

但是,由于QNAMEDNS 问题中的部分是可变长度的,因此您可能无法单独使用QTYPE或直接使用。例如,QCLASSstruct

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 */;
}
于 2012-11-18T10:56:46.163 回答