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.