OpenBSD Journal

Introducing bpflogd(8): capture packets via BPF to log files

Contributed by Peter N. M. Hansteen on from the deeply logged packets dept.

In a recent post to tech@, David Gwynne (dlg@) introduced a new daemon to log packets from BPF.

The message reads

List:       openbsd-tech
Subject:    bpflogd(8): capture packets via BPF to log files
From:       David Gwynne <david () gwynne ! id ! au>
Date:       2025-04-24 5:44:53

this is basically pflogd(8), but different.

the reason it exists is because i needed to continously log some packets
from span ports coming from multiple switches to try and help debug a
network issue that only seems to occur every couple of months. pflogd
provides that for a single pflog interface, but i needed it on multiple
ethernet interfaces.
im sending this out in case anyone else is interested in it.

the main differences are:

- it can log on any type of BPF interface and DLT, not just pflog(4)
- a single bpflogd can log packets from multiple BPF interfaces to the
  one log file
- it uses libevent and non-blocking FDs instead of a blocking on
  pcap_dispatch in a loop with crazy signal handling
  - this also avoids restartable syscalls
- it uses unveil and drops privs instead of chroot+privsep
  - this means the log file has to be writable by the user bpflogd
    runs as so it can reopen it after rotation.
- it captures full packets by default, not just 160 bytes
- you can provide a pcap-filter expression in a file
  - this makes the pexp handling in rc.subr a lot more robust
- the .c files are about half the number of lines
  - but it uses libevent so maybe this doesnt matter

the network issue i was dealing with was dhcp related, so i was
running it like this:

xdlg@sundew etc$ cat rc.d/bpflog_dhcp
#!/bin/ksh

daemon="/opt/local/sbin/bpflogd"
daemon_flags="-f /var/log/dhcp.pcap -F /etc/bpflog_dhcp.bpfilter -i mcx1 -i mcx2"

. /etc/rc.d/rc.subr

rc_cmd $1
xdlg@sundew etc$ cat /etc/bpflog_dhcp.bpfilter
vlan and udp and ((ip and (port bootpc or port bootps)) or (ip6 and (port \
dhcpv6-client or port dhcpv6-server))) xdlg@sundew etc$ ls -l /var/log/dhcp.pcap
-rw-r-----  1 _pflogd  sysadm  41027133 Apr 24 15:01 /var/log/dhcp.pcap
xdlg@sundew etc$ grep bpflog_dhcp /etc/newsyslog.conf
/var/log/dhcp.pcap			640  7     100000 *   ZB "rcctl reload bpflog_dhcp > /dev/null"

rcctl reload sends HUP by default, which is what bpflogd (and pflogd)
use to trigger a reopen of their logfiles.

for fun i replaced pflogd with bpflogd by changing /etc/rc.d/pflogd on a
few boxes:

and goes on with the patches (against -current) that introduces the deamon to the source tree.

As always, testing and comments from people who could potentially need this functionality is welcome. The code may find its way into a future release post OpenBSD 7.7


Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]