5
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>

#define BUFFER_SIZE 65535

char errbuf[PCAP_ERRBUF_SIZE];

int main(int argc, char **argv)
{
    int d;
    pcap_if_t *alldevsp;
    pcap_t *pkt_handle;

    if((pcap_findalldevs(&alldevsp,errbuf))==-1)
    {
        printf("findalldevices: %s\n",errbuf);
        exit(1);
    }
    printf("Availabel network devices are\n");
    pcap_if_t *temp = alldevsp;
    while((temp)!=NULL)
    {
        printf("%s: %s\n",(temp)->name,(temp)->description);
        (temp)=(temp)->next;
    }
    pcap_freealldevs(alldevsp);

    pkt_handle = pcap_create("wlan1",errbuf);
    if(pkt_handle==NULL)
    {
        printf("create: %s\n",errbuf);
        exit(1);
    }


    if((pcap_set_rfmon(pkt_handle, 1))!=0)
    {
        printf("Monitor mode could not be set\n");
        exit(1);
    }

    if((pcap_set_buffer_size(pkt_handle, BUFFER_SIZE))!=0)
        {
        printf("ERROR\n");
        exit(1);
    }

    if((d=(pcap_activate(pkt_handle)))!=0)
    {
        if(d==PCAP_ERROR_RFMON_NOTSUP)
            printf("%d : PCAP_ERROR_RFMON_NOTSUP\n",d);
        if(d==PCAP_WARNING)
            printf("%d : PCAP_WARNING\n",d);
        if(d==PCAP_ERROR)
            printf("%d : PCAP_ERROR\n",d);
        pcap_perror(pkt_handle,"Activate");
        exit(1);
    }
    printf("d=%d\n",d);

    while(1)
    {
        scanf("%d",&d);
        if(d==-1)
            break;
    }

    pcap_close(pkt_handle);
    printf("Bye\n");

    return 0;
}

当您使用以下命令运行上述程序时:

gcc -Wall -lpcap sample.c -o sample

我收到以下错误:

-1 : PCAP_ERROR
Activate: can't mmap rx ring: Invalid argument

但是,如果我注释掉包含pcap_set_buffer_size()函数调用的代码部分,则程序运行良好。

那么,这个问题是pcap_set_buffer_size()什么?

为什么会导致pcap_activate()失败?

4

1 回答 1

12

对于最近的 64 位 Linux:

任何等于或大于 65616 的缓冲区大小都应该这样做。

有关如何计算该值,请参阅来源中的increate_ring()实现。pcap-linux.clibpcap

默认值为 2*1024*1024 = 2097152。

Windows 上的默认缓冲区大小为 1000000。


更新:

要设置的缓冲区大小是pcap_set_buffer_size()指(环)缓冲区,它存储已经收到的包。最佳大小取决于用例和可负担的系统资源(不可分页内存)。

请逐字查看以下有关接收缓冲区大小的语句 man pcap

为捕获而到达的数据包存储在缓冲区中,因此应用程序不必在它们到达后立即读取它们。在某些平台上,可以设置缓冲区的大小;尺寸太小可能意味着,如果捕获的数据包太多并且快照长度不限制缓冲的数据量,如果缓冲区在应用程序可以从中读取数据包之前填满,则数据包可能会被丢弃,而太大的大小可能会使用比防止数据包丢失所需的更多的不可分页操作系统内存。


更新1:

Anyway, the buffer's size should be least the snap length set for the handle in use, plus some bytes needed to properly align the buffer itself, otherwise activating the handle ends up as described in the original question.

One can retrieve the handle's current snap length using pcap_snapshot(). The default snap length is 65535 bytes.

于 2012-07-09T16:38:49.540 回答