2012-11-18 29 views
0

Possible Duplicate:
C - byte array to structure (dns query)Ç - 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; 

我有从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协议进行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); 
+0

什么是'buf'?它从何而来?它真的指向你的结构的一个实例吗? – Mat

+0

Buf是来自'recvfrom'的字节数组。 –

+0

'struct dnsQuerySection * querySection;'< - 您不会从'recvfrom'获得有效的指针。它不分配内存,将相关数据复制到那里并将指针存储在结构中。如果您接收到的消息包含_pointer_值,那么这些值对您没有用处,因为他们会说出原始系统上的内容。 –

回答

3

首先,你可以开始通过将dnsQuery更改为:

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

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

然而,由于QNAME部分在DNS的问题是变长的,你可能不能够从QTYPEQCLASS分别做直接使用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 */; 
} 
+0

感谢这和解析功能,但我有零长度数组的问题。我得到错误:“数组类型具有不完整的元素类型”。 –

+0

@Bibo也许这有助于:http://stackoverflow.com/questions/6957766/array-type-has-incomplete-element-type –

+0

是的,它有帮助。我上面编辑了我的问题,但仍然遇到了seg错误。当编译时,我得到错误:“从不兼容的指针类型”和“ISO C禁止零大小的数组”中传递'parse'的参数1“。你能帮助我吗?现在我不需要域名,所以我从解析器中删除它。 –