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

Reply via email to