tcpdump mailing list archives

Re: libpcap & poll()


From: Ben Greear <greearb () candelatech com>
Date: Thu, 13 Nov 2008 15:13:05 -0800

Aaron Turner wrote:
On Thu, Nov 13, 2008 at 1:34 PM, Ben Greear <greearb () candelatech com> wrote:
Aaron Turner wrote:
I've been told by an end user under Linux 2.6.x at least that, he's
seeing very high CPU utilization numbers with tcpbridge which uses
libpcap to read packets.  Sounds like the cause of the issue is that
I'm using poll() to determine when to read from libpcap.  I'm using
poll() because my code listens on multiple interfaces, hence I need a
way to look at multiple pcap handles.

Questions basically boil down to:
1) Is this expected?
2) Is there a better way?
poll is good generally.

Are you reading multiple packets when poll says the descriptor
is readable?

yes, I'm passing -1 as the count to pcap_dispatch() on the active pcap
handle(s).

If you set the descriptor to non-blocking mode, you can read as
many as are available each loop...

So basically instead of using poll(), use pcap_setnonblock() on both
handles, and then use pcap_dispatch() in a loop, processing both
handles?

I run poll on all of the pcap descriptors I have open.
All descriptors are set to nonblocking.

Then, when poll returns, I run this for each descriptor
to read up to 30 packets at a time:

      int cnt = 0;
      while (cnt < 30) {
         cnt++;

         errno = 0;
         int res = pcap_next_ex(pcap_dev, &header, &pkt_data);
         if (res < 0) {
            VLOG << "pcap_next_ex failed, possible error:  " << strerror(errno)
                 << endl;
            stopTest(false, true, "pcap_next_ex failed");
         }
         else if (res == 0) {
            // no more to read right now
            break;
         }
         else {
            // Got one, process packet
         }
     }//while


Is this going to be portable & consistent?  I remember there being
some issues with something like this under Solaris with timeouts- i
think it was the timeout didn't start counting down until the first
packet arrived or something like that.  I would of assumed that using
poll() would be more efficient since the code effectively blocks until
a packet arrives rather then looping constantly even when idle.

The code above works on Solaris, but does not work on Windows since
there is nothing to poll() on windows.

On Linux, I just use raw sockets, which are faster and easier to deal
with than pcap..but my app is probabl different in nature from yours.
I see no reason why this would NOT work on Linux.

Thanks,
Ben


--
Ben Greear <greearb () candelatech com>
Candela Technologies Inc  http://www.candelatech.com

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: