tcpdump mailing list archives

Re: select() on BPF devices and Mac OS X


From: Eloy Paris <peloy () chapus net>
Date: Thu, 29 Jun 2006 13:26:21 -0400

Wow, I feel like an idiot. Looks like I didn't do my homework well.
Further digging on the mailing list archive gave me the answer:

BIOCIMMEDIATE

Doing an ioctl() for BIOCIMMEDIATE on the file descriptor returned
by pcap_get_selectable_fd() completely fixes the problem.

select() works perfectly on BPF devices on OS X (tested in Panther and
Tiger.)

Sorry for the noise :-(

Cheers,

Eloy.-

On Thu, Jun 29, 2006 at 12:39:50PM -0400, Eloy A. Paris wrote:
Hello!

Sorry to bring this up yet again. I am aware of the history here, and
the caveats in the documentation. However, I am seeing some weirdness on
OS X when using pcap_get_selectable_fd() and select() that I can't find
any explanation for (documentation, mailing list, etc.) and that I was
wondering if someone can provide some insight on.

So, according to a comment from Guy in the CVS log for pcap-bpf.c,
select() should work on BPF devices on Tiger. I built my program on
Panther and it didn't work. Then I decided to give it a try on Tiger
(based on what I read in the CVS log) and it didn't work either.

However, I forgot and left the program running for a while. Then I
noticed that the program seemed to be working. Originally select() was
returning 0, indicating a timeout (and it was timing out after the right
number of seconds). After the program had been running for some time,
select() started to return 1, indicating that there was data ready to
be read from one file descriptor. I read the data and everything worked
great.

What I wonder is why this is happening, why it takes a while for
select() to start indicating that there is data ready to be read? Seems
like OS X is buffering data and indicating that there is data after the
buffer is full or something.

Oh, another interesting data point is that I then ran my program on
Panther (Tiger - 1) and saw the exact same behavior.

For those that have OS X and want to see first-hand what I am talking
about, I've included below a quick program that shows the behavior.
To test, I just run the program below and at the same time run a ping
from the same machine. The faster the pings are sent out (and responses
received) the less time it takes for select() to indicate that there's
data ready, which would support the buffering theory that I mentioned
above.

Any insight into what could be happening here, and any possible
workarounds/solutions, will be very welcome. Thanks in advance.

Cheers,

Eloy Paris.-

----------------------------------------------------------------------
/* gcc -lpcap pcaptest.c */

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <time.h>
#include <pcap.h>

int
main(void)
{
    pcap_t *pd;
    char errbuf[PCAP_ERRBUF_SIZE];
    int fd, retval = 0;
    struct bpf_program fcode;
    struct timeval tv;
    fd_set rfds;
    time_t t;

    pd = pcap_open_live("en0", 65000, 1, 1, errbuf);
    fd = pcap_get_selectable_fd(pd);
    pcap_compile(pd, &fcode, "icmp", 1, 0);
    pcap_setfilter(pd, &fcode);

    while (retval == 0) {
        FD_ZERO(&rfds);
        FD_SET(fd, &rfds);
        tv.tv_sec = 1; /* select() will timeout after one second */
        tv.tv_usec = 0;
        retval = select(fd + 1, &rfds, NULL, NULL, &tv);
        time(&t);
        printf("retval = %d %s", retval, ctime(&t) );
    }

    return 0;
}
----------------------------------------------------------------------
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.


Current thread: