在我现在正在测试的系统中,它有几个链接在一起的虚拟L2设备,以在Eth报头和IP报头之间添加我们自己的L2.5报头。现在,当我使用tcpdump:捕获具有未知链接类型的虚拟接口上的传出数据包到libpcap?
tcpdump -xx -i vir_device_1
,它实际上显示了IP报头中的SLL头。如何捕获真正从vir_device_1中出来的完整数据包,即在ndo_start_xmit()设备调用之后?
在我现在正在测试的系统中,它有几个链接在一起的虚拟L2设备,以在Eth报头和IP报头之间添加我们自己的L2.5报头。现在,当我使用tcpdump:捕获具有未知链接类型的虚拟接口上的传出数据包到libpcap?
tcpdump -xx -i vir_device_1
,它实际上显示了IP报头中的SLL头。如何捕获真正从vir_device_1中出来的完整数据包,即在ndo_start_xmit()设备调用之后?
如何捕获真正从vir_device_1中出来的完整数据包,即在ndo_start_xmit()设备调用之后?
通过编写自己的代码直接使用PF_PACKET/SOCK_RAW插座(你说“SLL头”,所以这大概是Linux的),或者通过:
ARPHRD_
值;DLT_USER
ñ值之一为您的特殊套头的,或要求[email protected]对于要分配给他们的官方DLT_
值;ARPHRD_
值映射到您正在使用的DLT_
值;DLT_
值;注意,DLT_USER
ñ值是专门保留给私人使用,以及libpcap的,tcpdump的的没有官方版本,或者Wireshark的将不断它们分配供自己使用(即,如果您使用一个DLT_USER
ñ值,也懒得贡献补丁到值分配给你的类型头,因为他们将不被接受;其他人可能已经在使用它他们自己的特殊的头,而且必须继续被支持),所以你将不得不维护libpcap,tcpdump等的修改版本。如果你使用这些值中的一个,而不是获得指定的官方价值,那么你自己。
感谢Guy Harris为我原来的问题提供了非常有帮助的答案!
我将此作为回答/注释添加到我在评论中询问的后续问题。 基本上我的问题是什么是PF_PACKET/SOCK_RAW收到的数据包的状态。
对于软件设备(无队列),dev_queue_xmit()
将调用dev_hard_start_xmit(skb, dev)
开始发送skb缓冲区。该函数在调用dev->ops->ndo_start_xmit(skb,dev)
之前调用dev_queue_xmit_nit()
,这意味着PF_PACKET所看到的数据包处于ndo_start_xmit()
所做的任何更改之前的状态。
感谢您的答案,我一定会尝试两种方法。 – wei
一个后续问题,我试过SOCK_RAW/PF_PACKET选项。通过recvmsg(),我确实获得了接口上的传出数据包,现在我想知道这是如何工作的? recvmsg()如何接收传出数据包,我的意思是我们通常不使用recvmsg()来接收传入消息?当recvmsg()返回一个数据包时,这个数据包是处于刚刚被放入这个接口队列中的状态还是即将从该队列中退出?谢谢。 – wei
PF_PACKET套接字通过Linux上的数据包传输代码路径获取传出数据包。只有驱动程序知道数据包何时要传输; PF_PACKET代码不会,因此传出的数据包会在传输之前的某个时间位于PF_PACKET套接字队列中。 – 2013-01-21 20:37:22