tcpdump mailing list archives

Re: libpcap on FreeBSD with broadcom interface


From: Guy Harris <guy () alum mit edu>
Date: Mon, 1 Mar 2004 13:07:09 -0800


On Feb 26, 2004, at 8:10 AM, Greg wrote:

Using the following simple program, the pcap_next() call never returns,
altough it is listening on port 25 and there is a mail server running
with some traffic.
When running the program, the interface is getting in promiscuous mode.

I'm seeking for any tip to go further on that.
What i do not really understand is that tcpdump is able to capture
the packets i am looking for...

        ...

        dev = pcap_lookupdev(errbuf);
printf("DEV: %s\n",dev);

I'd suggest checking whether "dev" is null, and reporting the error from "errbuf" and exiting if it is, although that's not the source of your problem.

        /* Find the properties for the device */
        pcap_lookupnet(dev, &net, &mask, errbuf);

I'd also suggest checking whether "pcap_lookupnet()" succeeded, and report the error from "errbuf" and set "net" and "mask" to 0 if it fails.

        /* Open the session in promiscuous mode */
        handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);

...and I'd suggest checking whether "handle" is null and, if it is, report the error from "errbuf" and exit...

        /* Compile and apply the filter */
        pcap_compile(handle, &filter, filter_app, 0, net);
        pcap_setfilter(handle, &filter);

...and, for those calls, check whether they succeed and return the value from "pcap_geterr(handle)" and exit if they fail...

Those aren't the problem, but they'll at least make *other* problems show up more clearly.

The problem is that in the "pcap_open_live()" call you specified a "to_ms" argument value of 0. On BSD, a timeout value of 0 means "no timeout - do not read any packets until the kernel's packet buffer fills up", which means that you won't see any packets until enough packets arrive to fill up the BPF buffer in the kernel.

If you specify a timeout of, for example, 1 second:

        handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);

libpcap will return packets if the buffer fills up *or* if at least 1000 milliseconds have elapsed since the read was started.

However, this means that it'll *also* return from the read but return *no* packets if 1000 milliseconds elapse and *no* packets arrive; "pcap_next()" will return a null pointer in that case - and it'll also do so if you get an error, which is why "pcap_next()" somewhat sucks as an API.

If you wanted to use "pcap_next()", you would have to have a loop, and, if "pcap_next()" returns a null pointer, just continue in the loop, otherwise process the packet it returned.

I don't think you should use "pcap_next()", however, even though it's the most "convenient" interface to use. You should either use "pcap_loop()" and have a callback routine to process the packet, or should, if you're willing to have your program require libpcap 0.8.1 or later, use "pcap_next_ex()", which returns a success/failure/no packets available right now/EOF indication as well as supplying packet header and data information on success.

Tcpdump works because it specifies a timeout of 1 second. (It also uses "pcap_loop()".)

-
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: