捕获性能与pcap与原始套接字

捕获networkingstream量进行debugging时,似乎有两种常见的方法:

  1. 使用原始套接字。

  2. 使用libpcap

在性能方面,这两种方法有什么不同? libpcap似乎是一个很好的兼容方式来听一个真正的networking连接或重放一些jar头数据,但是function集是否带有性能问题?

Solutions Collecting From Web of "捕获性能与pcap与原始套接字"

答案旨在解释更多关于libpcap。

libpcap使用PF_PACKET来捕获接口上的数据包。 请参阅以下链接。 https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt

从上面的链接

在Linux 2.4 / 2.6 / 3.x中,如果未启用PACKET_MMAP,则捕获过程效率非常低。 它使用非常有限的缓冲区,需要一个系统调用来捕获每个数据包,如果你想获得数据包的时间戳,就需要两个(像libpcap总是这样)。 另一方面,PACKET_MMAP非常有效。 PACKET_MMAP提供一个映射到用户空间的大小可配置的循环缓冲区,可用于发送或接收数据包。 读取数据包只需要等待它们,大部分时间不需要发出单个系统调用。 关于传输,可以通过一次系统调用发送多个数据包,以获得最高的带宽。 通过使用内核和用户之间的共享缓冲区,还可以使包复制最小化。

性能改进可能会因使用PF_PACKET实现而有所不同。

https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt

据说TPACKET_V3带来以下好处:*)CPU使用减少15-20%*)数据包捕获率增加20%

使用libpcap的缺点 –

  1. 如果应用程序需要保存数据包,则可能需要复制传入数据包。

    请参阅pcap_next_ex的联机帮助页。

    pcap_next_ex()读取下一个数据包并返回成功/失败指示。 如果数据包的读取没有问题,pkt_header参数指向的指针被设置为指向数据包的pcap_pkthdr结构,并且由pkt_data参数指向的指针被设置为指向数据包中的数据。 struct pcap_pkthdr和分组数据不会被调用者释放,并且在下一次调用pcap_next_ex(),pcap_next(),pcap_loop()或pcap_dispatch()时不保证有效。 如果代码需要它们保持有效,则必须复制它们。

  2. 如果应用程序只对传入数据包感兴趣,性能会受到损失

    PF_PACKET作为内核中的分支,即将所有传入和传出的数据包传送到PF_SOCKET。 这将导致所有传出数据包的调用packet_rcv的代价很高。 由于libpcap使用PF_PACKET,所以libpcap可以捕获所有的入站和出站数据包。 如果应用程序只对传入数据包感兴趣,则可以通过在libpcap句柄上设置pcap_setdirection来丢弃传出数据包。 libpcap内部通过检查数据包元数据上的标志来丢弃传出数据包。 所以从本质上来说,传出的数据包仍然可以被libpcap看到,但是以后只能被丢弃。 这是仅对传入数据包感兴趣的应用程序的性能损失。

原始数据包在IP级别(OSI第3层),数据链路层(OSI第2层)上的pcap。 所以它不是一个性能问题,更多的是你想要捕获的问题。 如果性能是您搜索PF_RING等的主要问题,那么这就是当前的IDS使用的捕获。

编辑:原始数据包可以是IP级别(AF_INET)或数据链路层(AF_PACKET),pcap实际上可能使用原始套接字,请参阅libpcap使用下面的原始套接字?