tcpdump mailing list archives
Re: pcap_t not writeable on OpenBSD
From: Guy Harris <guy () alum mit edu>
Date: Tue, 10 Jan 2012 14:57:14 -0800
On Jan 9, 2012, at 8:49 PM, Fernando Gont wrote:
I'm doing I/O multiplexing with the pcap descriptor, and it turns out that on OpenBSD the underlying descriptor for a pcap_t is never writeable.
I presume from "I'm doing I/O multiplexing" that by "writeable" you're referring to "writeable" as in "a select() or poll() or... on the descriptor says it's writable" rather than "the descriptor is open for writing.
Note: No problems in Linux and FreeBSD -- so far only in OpenBSD. Is this the right place to report this? Or should I report this to OpenBSD, instead?
It's probably an OpenBSD issue.
Looking at the OpenBSD kernel's net/bpf.c:
http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/bpf.c?rev=1.78;content-type=text%2Fplain
its poll routine only appears to check the readability of the BPF device, not its writability.
Then again, looking at the FreeBSD kernel's net/bpf.c:
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/net/bpf.c?rev=1.233;content-type=text%2Fplain
its poll routine doesn't check the BPF device's writability, either.
The difference is that the OpenBSD one appears always to say "no" if asked about writability:
revents = events & (POLLIN | POLLRDNORM);
if (revents == 0)
return (0); /* only support reading */
while the FreeBSD one appears always to say "yes":
revents = events & (POLLOUT | POLLWRNORM);
As per Sam Roberts' comment:
For injection, on linux anyhow, a PF_PACKET device is always writeable, but I'm pretty sure it discards packets if you write too fast.
the OpenBSD bpfwrite() routine does not appear to block for any "no room to buffer the packet" reason (it just calls
the interface's if_output routine to send the packet, and I think that routine is supposed to fail, not block, if
there's no buffering space available in the driver), and the FreeBSD one behaves the same.
For completeness:
the NetBSD poll routine works like FreeBSD, and the NetBSD write routine just hands the packet to if_output;
DragonFly BSD appears to have only a kqueue routine, presumably also used for select() and poll(), and appears
to return an error if asked to create an EVFILT_WRITE kevent, and I'm not sure what happens on writes due to what
appears to be an extra message-sending path, but from looking at the code my guess is that it ultimately just hands the
packet to if_output;
the xnu (Mac OS X and, if you could ever manage to arrange to have sufficient privileges to open a BPF device,
iOS) select routine returns "yes" when asked about writability, its kqueue routine (used for poll() and kqueues)
rejects EVFILT_WRITE kevents, and, from looking at the code, the packet is probably ultimately just handed to the
output routine.
So:
it appears that on all of the BSD-flavored platforms there's nothing to multiplex on the output side - the
service offered when sending raw packets is a "best effort" service with no guarantee that the packet will even make it
onto the wire (which is pretty much what you get with, for example, Ethernet in any case);
on most platforms select() will always say "you can write", with OpenBSD as an exception and DragonFly BSD as
another possible exception - poll() might be the same except that it might also fail on Mac OS X, and kqueues will
probably fail with an error on all platforms if you try to create a EVFILT_WRITE kevent for a BPF device.-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.
Current thread:
- pcap_t not writeable on OpenBSD Fernando Gont (Jan 10)
- Re: pcap_t not writeable on OpenBSD Sam Roberts (Jan 10)
- Re: pcap_t not writeable on OpenBSD Fernando Gont (Jan 10)
- Re: pcap_t not writeable on OpenBSD Guy Harris (Jan 10)
- Re: pcap_t not writeable on OpenBSD Fernando Gont (Jan 10)
- Re: pcap_t not writeable on OpenBSD Guy Harris (Jan 10)
- Re: pcap_t not writeable on OpenBSD Fernando Gont (Jan 11)
- Re: pcap_t not writeable on OpenBSD Fernando Gont (Jan 10)
- Re: pcap_t not writeable on OpenBSD Sam Roberts (Jan 10)
