tcpdump mailing list archives

libpcap timeout weirdness


From: Robert Monaghan <bob () gluetools com>
Date: Sun, 24 Mar 2013 19:51:10 +0100

Hi Everyone!

I am using the built in Libpcap library that comes with MacOSX. (MacOSX 10.8.3)

I have set up a background GCD dispatch queue, where the libpcap is set up and waits for packets to arrive on my 10Gig 
card.

The code is very trivial, and appears as if it should works well..
Here is the problem.

I am using "pcap_loop" to grab a specific number of packets. This is set up using a snap size of 1504  (To match the 
packet size from my hardware device.)
The buffer is large, about 1Mb in size. I have the "pcap_loop" code in "blocking" mode, so that I can wait for all of 
the packets to finish, before triggering a semaphore.

When I start the pcap_loop to do its work, which grabs exactly 1879 packets.  (Precisely the number I am asking for.) I 
end up with a timeout being called. (I know this is a timeout, because if I change the timeout value in  
"pcap_open_live", the timeout matches the duration that I set.) As a test, I decide to trim the number of packets used 
in pcap_loop by 160, and everything speeds up dramatically! Absolutely no timeouts. Anything less that 159 packets 
(determined by trial & error), the time out occurs.

This isn't the only size, either.

Now I download another (smaller) set of data, this time I download only 782 packets. This download starts to timeout, 
as well! (Even though the 1700 or so, packet downloaded just fine!)  If I trim it by about 97 packet, the system no 
longer times out.

Weird.

Just for fun, I tried an really large data set, at 3130 packets. As expected it stalls. But again, trimming about 200 
packets removes the stall, and it moves the data extremely quickly.

If I use pcap_stats immediately after the pcap_loop, I see that in both fast and timed out situations, that I don't 
drop any packets.
The only issue seems to be that the timeout is triggered.

I am at a loss on this one. I have tried changing the 'snaplen' size, and altered the timeout, but i can't seem to see 
where the problem is.
This works if I trim the number of packets read, but slows down dramatically, if I do the full amount of packets 
requested.
I have also switched over to pcap_create and the assorted pcap_set commands to try to noodle with settings.
I have even set different buffersizes with sysctl debug.bpf_bufsize and maxbufsize. No luck there, either.

Can anyone make a suggestion?

Should I ditch the built in MacOSX libpcap and compile the one available from the tcpdump repository?


Attached is the relevant code:

        char filter_exp[] = "ether proto 0x7777";
        
        char errbuf[PCAP_ERRBUF_SIZE] = {0};
        int buffersize = (int)(1048576);
        //handle = pcap_open_live([ethernetInterface cStringUsingEncoding:NSASCIIStringEncoding], 65536 * 2, 0, 1000, 
errbuf);

        handle = pcap_create([ethernetInterface cStringUsingEncoding:NSASCIIStringEncoding], errbuf);
        
        if (handle != NULL) {
                //pcap_set_promisc(handle, 0);
                pcap_set_timeout(handle, 1000);
                //pcap_setdirection(handle,  PCAP_D_IN);
                pcap_set_snaplen(handle, 1504);
                pcap_set_buffer_size(handle, buffersize);
                //pcap_set_rfmon(handle, 0);
                pcap_activate(handle);
                
                /* compile the filter expression */
                bpf_u_int32 mask = 0xffff0000;
                if (pcap_compile(handle, &fp, filter_exp, 1, mask) == -1) {
                        fprintf(stderr, "Couldn't parse filter %s: %s\n",
                                        filter_exp, pcap_geterr(handle));
                        exit(EXIT_FAILURE);
                }
                
                /* apply the compiled filter */
                if (pcap_setfilter(handle, &fp) == -1) {
                        fprintf(stderr, "Couldn't install filter %s: %s\n",
                                        filter_exp, pcap_geterr(handle));
                        exit(EXIT_FAILURE);
                }
                
                return true;
        }

---
        int err = pcap_loop(handle, blockCount, processSingleImage, (u_char *)&dataOp);
and


void processSingleImage(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
        GT_DataOperation *dataOp = (GT_DataOperation *)args;
        static int count = 0;
        count++;
}

Thanks!

bob.
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers


Current thread: