我有这些结构:
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);
答案 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
部分是可变长度的,因此您可能无法使用QTYPE
从QCLASS
和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 */;
}