Issue in pcap_set_buffer_size()

10,307

For a recent 64bit Linux:

Any buffer size equal or larger then 65616 should do.

For how the value is calculated please see the implementation of create_ring() in pcap-linux.c from the libpcap sources.

The default is 2*1024*1024 = 2097152.

The default buffer size on windows is 1000000.


Update:

The buffer size to be set by pcap_set_buffer_size() refers to the (ring-)buffer, which stores the already received packages. The optimal size depends on the use case and on the affordable system resources (non-pageable memory).

Please see the following statements on the receive buffer's size verbatim from man pcap:

Packets that arrive for a capture are stored in a buffer, so that they do not have to be read by the application as soon as they arrive. On some platforms, the buffer's size can be set; a size that's too small could mean that, if too many packets are being captured and the snapshot length doesn't limit the amount of data that's buffered, packets could be dropped if the buffer fills up before the application can read packets from it, while a size that's too large could use more non-pageable operating system memory than is necessary to prevent packets from being dropped.


Update 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.

Share:
10,307
bengaluriga
Author by

bengaluriga

Updated on June 11, 2022

Comments

  • bengaluriga
    bengaluriga almost 2 years
    #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;
    }
    

    When you run the above program using:

    gcc -Wall -lpcap sample.c -o sample
    

    I get the follwing error:

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

    However, if I comment out the section of code containing pcap_set_buffer_size() function call, the program works perfectly fine.

    So, what is this problem with pcap_set_buffer_size()?

    Why is it causing pcap_activate() to fail?