bin/72814: libpcap opens bpf as O_RDONLY - doesn't work with ucarp
Brian Candler
b.candler at pobox.com
Mon Oct 18 04:30:26 PDT 2004
>Number: 72814
>Category: bin
>Synopsis: libpcap opens bpf as O_RDONLY - doesn't work with ucarp
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Mon Oct 18 11:30:25 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Brian Candler
>Release: FreeBSD 4.10-STABLE i386
>Organization:
>Environment:
System: FreeBSD vaio.linnet.org 4.10-STABLE FreeBSD 4.10-STABLE #0: Sun Sep 26 17:08:21 BST 2004 root at vaio.linnet.org:/usr/obj/usr/src/sys/VAIO i386
also tested with FreeBSD-5.2.1-RELEASE
>Description:
libpcap opens /dev/bpfX as O_RDONLY rather than O_RDWR. This affects
applications which open bpf using pcap_open_live, then get the fileno and
try to use it to send packets. The particular application I have a problem
with is ucarp - http://www.ucarp.org/ - which is a VRRP-type failover
system deriving from OpenBSD.
I do realise that carp may find its way into the FreeBSD kernel post 5.3
but a userland implementation is still convenient.
However note that NetBSD works with ucarp, and NetBSD opens the bpf device
in O_RDWR mode unconditionally:
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libpcap/pcap-bpf.c?rev=1.12
(search for bpf_open)
NetBSD and FreeBSD apparently both imported libpcap-0.8.3, so I don't know
where this difference arose.
>How-To-Repeat:
See src/contrib/libpcap/pcap-bpf.c
search for 'bpf_open'
Try installing and running ucarp - it silently fails to send packets.
Changing O_RDONLY to O_RDWR and make install for libpcap fixes it.
>Fix:
Consider:
(1) Changing libpcap to open in O_RDWR mode unconditionally, as NetBSD does
(2) Changing libpcap to attempt open in O_RDWR mode, fallback to O_RDONLY if
it fails.
*/
do {
(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
- fd = open(device, O_RDONLY);
+ fd = open(device, O_RDWR);
+ if (fd < 0 && errno == EACCES)
+ fd = open(device, O_RDONLY);
} while (fd < 0 && errno == EBUSY);
/*
(3) Adding a new entry point to libpcap which does the same as
pcap_open_live but uses O_RDWR instead of O_RDONLY
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list