我正在制作一个使用pcap解析.pcap文件的程序。
事实上,我正在研究DNS协议,我能够获得标题并显示其信息。现在我想显示它的资源记录(问题、答案、权限、附加)。
我发现了一个有趣的医生:http://www.zytrax.com/books/dns/ch15/
而且,正如我之前解析不同的头文件时所做的那样,我想创建一个结构并在其中投射我的数据包
根据这个文档,我创建了如下结构:
struct question_s {
u_short *qname;
u_short qtype;
u_short qclass;
}
我正在选角:
struct question_s *record = (struct question_s*)(data + offset);
其中data是数据包表示,offset是以前协议的总大小。
现在我很难理解一些要点,而且由于我的英语不完美,可能是我在文档中遗漏了一些内容。以下是我的问题:
由于qname的大小是可变的,我把它作为u_short上的指针做得对吗?
所有指针都是8字节长,所以我的结构应该是12字节长,但内存中的名称在哪里?我应该在不考虑名字长度的情况下在偏移量上加12吗?
我试着显示qname,把它当作一个char*来处理,但它似乎不起作用(seg.fault),以下是我所做的:
void test(u_short *qname) {
for (int c = 0; qname[c] != 0; ++c)
write(1, &qname[c], 1);
}
但是字符串中可能没有"\0"?
这可能是endianes的问题吗?我在所有的u_short和u_int值上使用htons和htonl,因为网络字节顺序与我的不同,但我不确定它是否适用于指针。
如果您想了解如何解析DNS记录,请首先阅读并理解RFC 1035,然后查看tcpdump代码以解析DNS记录。这比你想象的要难;不能只是将一个结构覆盖在原始数据包数据之上。
而且你永远不能把一个有指针的结构覆盖在原始数据包数据之上。指针几乎肯定会指向你地址空间中的某个虚假位置;协议不通过网络发送原始指针,因为指针是特定地址空间中的指针,网络上的两个进程将具有不同的地址空间。
(事实上,数据包解析中的所有东西都比人们第一次尝试编写代码解析数据包时想象的要难。)