7
#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?

alk
  • 69,737
  • 10
  • 105
  • 255
bengaluriga
  • 319
  • 2
  • 5
  • 9

1 Answers1

15

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.

alk
  • 69,737
  • 10
  • 105
  • 255
  • I.e., a buffer size of 65535 makes the buffer *smaller*. Unless you want to reduce the amount of wired-down memory, or *increase* the number of dropped packets, you probably don't want to shrink the buffer size. –  Jul 10 '12 at 02:08
  • @alk and Guy Harris
    yes ... increasing the buffer size solves the problem ... I increased it to 2097152.
    The reason why I set the buffer size to 65535 is because the man page had a statement that "A snapshot length of 65535 should be sufficient, on most if not all networks, to capture all the data available from the packet." ... I don't know why I got confused between snapshot length and buffer size.
    So, any idea what is the ideal buffer size on 32-bit linux machine?
    – bengaluriga Jul 10 '12 at 06:28
  • Please see my updated answer. There should not be a difference between 32 and 64bit linux regarding the optimal size of the receive buffer. The only difference I see is for the minimum possible value, as this depends on the alignment of the buffer, and alignment is different from 32 to 64bit OS. @user1512195 – alk Jul 10 '12 at 07:36