6

我正在为一个流量非常大的网络编写监控程序(高清视频通过网络流式传输)。大多数数据包都非常大,我只想查看标头(仅限 IP 和 UDP/TCP)。当然,我想避免复制整个数据的开销。libpcap 是否一定要给我一份整个数据包的副本?如果是,是否有符合我需求的图书馆?

4

1 回答 1

6

这里似乎有两个问题:

  • 标题中的那个,听起来好像是在询问 libpcap 是否复制了数据包;
  • 正文中的那个,询问它是否总是复制整个数据包。

对于第一个问题:

使用 libpcap 在各种操作系统中运行的机制的任何代码可能至少完成了一个副本 - 从 mbufs/skbuff/STREAMS 缓冲区/任何到机制缓冲区的副本。对于 Linux,当使用 tpacket 机制时,skbuff可能只是在接收队列中排队等待PF_PACKETlibpcap 正在使用的套接字。

可能还有另一个副本 - 从该缓冲区到用户区的副本;如果 libpcap 使用“零拷贝”机制,例如 Linux tpacket 机制(libpcap 1.0 及更高版本默认使用),则不会发生第二次拷贝。如果不使用零拷贝机制,就会发生这种情况

但是,如果您使用pcap_next()pcap_next_ex()在 Linux 系统上使用 tpacket 机制,则从内存映射缓冲区到私有缓冲区的单独副本;pcap_dispatch()如果您使用or ,则不会发生这种情况pcap_loop()

对于第二个问题:

这就是“snaplen”参数pcap_open_live()pcap_set_snaplen()用途 - 它允许您指定不应捕获超过“snaplen”字节的数据包数据,这意味着复制的字节数不超过那么多。

请注意,此长度包括链路层标头,并且可以包括“元数据”标头,例如您可能在 802.11 适配器上获得的radiotap标头。此标头可能是可变长度的(例如,在 802.11 上,802.11 标头是可变长度的,并且,如果您要获取 radiotap 标头,它们也是可变长度的)。

另外,IPv4 和 TCP 头都可以有选项,而 IPv6 数据包可以有扩展头,所以 IP 和 TCP 头的长度也可以是可变的。

这意味着您可能必须确定要使用的“最坏情况”快照长度;没有办法明确地说“不要给我任何超出 TCP/UDP 标头的东西”,您只能说“给我不超过 N 个字节”。

于 2012-04-29T18:40:55.570 回答