为什么 libpcap 比使用 raw 嗅探更好?

yfr*_*com 4 c linux packet-sniffers libpcap

如果我想在 Linux 中嗅探数据包而不设置任何过滤器,我看到了 2 个选项。

  1. 使用libpcap

  2. 自己使用原始套接字,例如https://www.binarytides.com/packet-sniffer-code-in-c-using-linux-sockets-bsd-part-2/

为什么libpcap比我自己使用原始套接字更好?

Opp*_*pen 8

三个原因:

1)正确设置更容易。

2) 它是可移植的,甚至可以移植到 Windows,它使用非常相似但不同的套接字 API。

3)速度快得多。

1和2,IMO,不需要太多解释。我将深入探讨3。

要理解为什么 libpcap(通常)更快,我们需要了解套接字 API 中的瓶颈。

libpcap 倾向于避免的两个最大瓶颈是系统调用和副本。

它如何做到这一点是特定于平台的。

我将讲述 Linux 的故事。

Linux 从 2.0 IIRC 开始,实现了所谓的 AF_PACKET 套接字系列,后来又实现了 PACKET_MMAP。我不太记得前者的好处,但后者对于避免从内核复制到用户空间(内核端仍然有一些副本)和系统调用至关重要。

在 PACKET_MMAP 中,您在用户空间中分配一个大的环形缓冲区,然后将其关联到 AF_PACKET 套接字。该环形缓冲区将包含一些元数据(最重要的是,一个标记,表明某个区域是否已准备好供用户处理)和数据包内容。

当数据包到达相关接口(通常是您将套接字绑定到的接口)时,内核会在环形缓冲区中创建一个副本,并将该位置标记为可供用户空间*使用。如果应用程序正在等待套接字,则会收到通知*。

那么,为什么这比原始套接字更好呢?因为在设置套接字后,您可以使用很少或没有系统调用,具体取决于您是要忙轮询缓冲区本身还是等待poll几个数据包准备好,并且因为您不需要来自套接字内部的副本RX 缓冲区到您的用户缓冲区,因为它与您共享。

libpcap 会为您完成所有这些工作。并且可以在 Mac、*BSD 以及几乎任何为您提供更快捕获方法的平台上执行此操作。

*版本 3 有点复杂,粒度是“块”而不是数据包。