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