我写了一个小应用程序来尝试显示捕获数据包的协议头。我的所有数据包都是用libpcap的pcap_loop捕获的。我的程序的工作方式如下:我根据if_ether.h ip.h和tcp.h中定义的结构编写了自己的头文件。 pcap_loop设置一个指向数据包开头的char指针,然后逐步执行数据包,每次都转换为适当的结构,并按指针的大小递增指针。现在重要的是要记住我的问题不是代码特定的;我的代码有效,但有一些我不理解的逻辑缺陷;请记住,我的数据包是通过同一台机器,不同的端口发送的(我写了一个微小的python服务器,我用telnet发送数据):
1.当通过localhost发送数据包时,以太网标头不会显示任何看起来正确的内容(当我在互联网数据包上使用我的程序时,MAC地址会被正确显示)
2.通过反复试验,我已经确定结构iphdr在数据包缓冲区启动后正好从16个字节开始,而不是预期的14个字节,即以太网头的大小
这些观察引导我提出以下问题: 当数据包通过本地主机发送时,我们是否在第2层使用其他协议? 是否有任何分隔数据包标题的东西? ip.h和tcp.h中定义的iphdr和tcphdr结构是否已过时?
答案 0 :(得分:1)
当通过本地主机发送数据包时,我们是否在第2层使用其他协议?
确实没有第2层协议,因为没有真正的网络适配器。
但是,为捕获流量的程序提供了假的第2层标头。提供的伪标题取决于操作系统。
在Linux上,假的第2层标头是虚假的以太网标头。
在* BSD,OS X,iOS和我认为的Solaris 11上,它们是DLT_NULL或DLT_LOOP标头,如the list of libpcap/WinPcap/pcap/pcap-ng link-layer header types中所述。
然而:
通过反复试验,我确定结构iphdr在数据包缓冲区启动后恰好16字节开始
如果您在“任意”设备上捕获,则标头为DLT_LINUX_SLL headers,长度为16个字节。
如果您正在使用pcap或任何pcap包装器,那么<strong> 必须 ,在尝试解析之前,无一例外地调用pcap_datalink()
或包装器的等效项em>您从保存文件中捕获或读取的任何数据包。您 绝不能 假设数据包具有 ANY 特定的链路层标头类型。