tcpdump mailing list archives

Re: pcap_next returns "Didn't grab packet"


From: Sam Carleton <sam () linux-info net>
Date: Mon, 16 Dec 2002 15:29:50 -0500

Guy,

Thank you!  How I know that I can move on with faith that the next
example, using pcap_dispatch() will work.

Sam

On Mon, Dec 16, 2002 at 12:07:02PM -0800, Guy Harris wrote:
On Sat, Dec 14, 2002 at 02:41:29PM -0500, Sam Carleton wrote:
I know that pcap works because I have compiled snort and have been
able to get that to work fine.  I was wondering if anyone might have
some thoughts on why the  testpcap1.c sample will not work.

Because it was written by somebody who thought "the whole world runs
Linux". :-)

"pcap_next()" returns a null pointer if "pcap_dispatch()" returns a
value <= 0.  To quote the current CVS version of the libpcap man page:

     pcap_dispatch() is       used to collect and process packets.  cnt
     specifies        the  maximum  number of packets to process before
     returning.        This is not a minimum  number;  when  reading  a
     live  capture,  only  one        bufferful of packets is read at a
     time, so fewer than cnt packets may be processed. A  cnt  of
     -1        processes  all  the  packets received in one buffer when
     reading a live capture, or       all the packets in the file  when
     reading  a       ``savefile''. ...

              ...

     The number       of packets read is returned.  0 is returned if no
     packets were read from a live capture (if,       for example, they
     were discarded because they didn't       pass the  packet  filter,
     or        if, on platforms that support a read timeout that starts
     before any       packets arrive, the timeout  expires  before  any
     packets  arrive,  or  if the file descriptor for the capture
     device is in non-blocking mode and       no packets were available
     to       be read) or if no more packets are available in a ``save-
     file.'' A return of -1 indicates  an  error  in  which  case
     pcap_perror()  or        pcap_geterr()  may be used to display the
     error text.

so it can return 0 if, for example:

      1) on a platform where packet filtering is done in user mode
         rather than the kernel, the kernel hands a buffer full of
         packets to libpcap but none of them pass the filter;

      2) on a platform that supports a read timeout that starts before
         any packets arrive, and that causes the
         read/recvfrom/getmsg/whatever from the kernel to return when
         the timeout expires even if no packets have arrived, no
         packets arrive within the timeout interval.

(Those are a more detailed and complete description of the first two
cases mentioned in the parenthetical note in the second paragraph I
cited from the man page.)

NetBSD (along with the other BSDs) is a platform that supports a read
timeout that starts before any packets arrive, and that causes the read
from the kernel to return when the timeout expires even if no packets
have arrived.  Linux is not.

Therefore, on *some* Linux systems (those running a 2.2 or later kernel,
and with the socket filter mechanism compiled in, so that packet
filtering is done in the kernel), "pcap_dispatch()" isn't likely to
return 0, so "pcap_next()" is unlikely to return NULL, and the sample
program is more likely to work.

On BSD systems - and Linux systems without socket filter support, or
with an old libpcap that doesn't support that mechanism - "pcap_next()"
is more likely to return NULL, although it's much more likely to do so
on BSD systems.

Unfortunately, "pcap_next()" is a somewhat crappy API, and doesn't
indicate to its caller why "pcap_dispatch()" returned 0, so there's not
much that can be done to fix testpcap1.c without changing it to use
"pcap_dispatch()" rather than "pcap_next()".
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:tcpdump-workers-request () tcpdump org?body=unsubscribe


Current thread: