我编写了一个小应用程序来尝试显示捕获的数据包的协议标头。我所有的数据包都是通过libpcap的pcap_loop捕获的。我的程序的工作方式如下:我根据if_ether.h ip.h和tcp.h中定义的结构编写了自己的标头。 pcap_loop将char指针设置为数据包的开头,然后我逐步遍历该数据包,每次都强制转换为适当的结构,然后将指针增加头大小。现在重要的是要记住我的问题不是特定于代码的。我的代码可以运行,但是有一些我不理解的逻辑缺陷;请记住,我的数据包是通过同一台机器,不同的端口发送的(我编写了一个微型python服务器,通过telnet将数据发送到该服务器):

1,当通过本地主机发送数据包时,以太网头未显示任何看起来正确的内容(当我在互联网数据包上使用程序时,MAC地址会正确播放)

2通过反复试验,我确定结构iphdr在数据包缓冲区开始之后恰好开始16个字节,而不是预期的14个字节(以太网头的大小)

这些观察使我提出以下问题:
当数据包通过本地主机发送时,我们是否在第2层上使用其他协议?
包头是否有任何分隔符?
ip.h和tcp.h中定义的iphdr和tcphdr结构是否过时?

最佳答案

当数据包通过本地主机发送时,我们是否在第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个字节


如果要在“ any”设备上捕获,则标头为DLT_LINUX_SLL headers,长度为16个字节。

如果使用的是pcap或任何pcap包装器,则在尝试解析从保存文件捕获或读取的任何数据包之前,必须无例外地调用pcap_datalink()或包装器的等效项。您不得假定数据包将具有任何特定的链路层头类型。

关于c - 本地主机上的OSI层,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31054972/

10-11 18:31