2013-01-17 13 views

回答

1

如何捕获真正从vir_device_1中出来的完整数据包,即在ndo_start_xmit()设备调用之后?

通过编写自己的代码直接使用PF_PACKET/SOCK_RAW插座(你说“SLL头”,所以这大概是Linux的),或者通过:

  • 确保您指定为您的虚拟接口提供一个特殊的ARPHRD_值;
  • 使用DLT_USERñ值之一为您的特殊套头的,或要求[email protected]对于要分配给他们的官方DLT_值;
  • 修改libpcap以将ARPHRD_值映射到您正在使用的DLT_值;
  • 修改tcpdump来处理DLT_值;
  • 如果需要,修改其他程序在该接口上捕获或读取该接口上由tcpdump写入的捕获文件以处理该值。

注意,DLT_USERñ值是专门保留给私人使用,以及libpcap的,tcpdump的的没有官方版本,或者Wireshark的将不断它们分配供自己使用(即,如果您使用一个DLT_USERñ值,也懒得贡献补丁到值分配给你的类型头,因为他们将不被接受;其他人可能已经在使用它他们自己的特殊的头,而且必须继续被支持),所以你将不得不维护libpcap,tcpdump等的修改版本。如果你使用这些值中的一个,而不是获得指定的官方价值,那么你自己。

+0

感谢您的答案,我一定会尝试两种方法。 – wei

+0

一个后续问题,我试过SOCK_RAW/PF_PACKET选项。通过recvmsg(),我确实获得了接口上的传出数据包,现在我想知道这是如何工作的? recvmsg()如何接收传出数据包,我的意思是我们通常不使用recvmsg()来接收传入消息?当recvmsg()返回一个数据包时,这个数据包是处于刚刚被放入这个接口队列中的状态还是即将从该队列中退出?谢谢。 – wei

+0

PF_PACKET套接字通过Linux上的数据包传输代码路径获取传出数据包。只有驱动程序知道数据包何时要传输; PF_PACKET代码不会,因此传出的数据包会在传输之前的某个时间位于PF_PACKET套接字队列中。 – 2013-01-21 20:37:22

1

感谢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()所做的任何更改之前的状态。

相关问题