C - dns查询结构

时间:2012-11-18 10:36:27

标签: c dns udp structure

  

可能重复:
  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;

我在buf的字节数组recvfrom中有一个DNS查询。我试图从字节数组得到结构:

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

1 个答案:

答案 0 :(得分:3)

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

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

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

但是,由于DNS问题中的QNAME部分是可变长度的,因此您可能无法使用QTYPEQCLASSstruct单独执行此操作直。例如,

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