libpcap: pcap_next_ex 有 "own" 个缓冲区

libpcap: pcap_next_ex with "own" buffers

我目前做的是:

struct pcap_pkthdr *phdr;
const u_char *data;

pcap_next_ex(descriptor, &phdr, &data);
memcpy((void*)mybuf, phdr, sizeof(*phdr));
memcpy((void*)mybuf + sizeof(*phdr), data, phdr->len);

但我想做的是下面的,即提供一个预分配的缓冲区。

u_char mybuf[2048];

pcap_next_ex(descriptor, mybuf, mybuf + 16); // 16 is size of pkthdr

由于指针类型错误,第二个示例无论如何都无法编译,但我认为这样可以更好地理解我的问题。我正在从 10G 接口读取,速度非常重要。我想对代码的某些部分进行基准测试,例如,使用自己的预分配数据包缓冲区而不是 libpcap.

中隐藏的 allocations/buffers

有没有办法 API 让 libpcap 使用预先分配的缓冲区来写入 pcap_next_ex 的结果?

libpcap source code there does not appear to be a way to pass a pre-allocated buffer. However, chances are it's already using an internally preallocated buffer. For example, for live captures on Linux, pcap_next_ex() drills down into a call to pcap_read_packet() in pcap-linux.c 的一眼。在这里您可以看到返回的指针只是一个更大的属于捕获句柄的读取缓冲区的偏移量。我没有看过其他 OS 的实现,但我怀疑它们是相似的。

允许您传入自己的缓冲区将需要平台实现将数据从它们自己的内部缓冲区复制到您的缓冲区(效率非常低),或者严重限制它们管理自己的系统调用缓冲等的能力(内存映射,每个系统调用接收多个数据包等)。无论哪种方式,这很可能不是您潜在优化的来源。

另请参阅 this mailing list thread,其中讨论了 pcap_next_ex() 和较旧的 pcap_loop() 界面的相对性能。

编辑

interjay 指出,Linux 实时捕获实现无论如何都会生成一个副本,因为缓冲区内容在调用后保持有效的要求(请参阅 pcap-linux.c 的第 4452 行)。代码中的注释表明 pcap_loop() 可能确实更快,因为缓冲区只暴露给回调函数,因此它的内容不需要在回调 returns.[=19= 之后保持有效。 ]