FreeBSD bpf patch

Peter Van Epp vanepp at sfu.ca
Fri Feb 16 10:59:13 EST 2001


	As promised here is the FreeBSD bpf patch. I expect you want to point
to this from the INSTALL readme for those folks running on FreeBSD. I need
to check OpenBSD and netBSD but I expect (from communication with the OpenBSD
folks) that it is fixed in OpenBSD 2.8 (but not in 2.7).

Peter Van Epp / Operations and Technical Support 
Simon Fraser University, Burnaby, B.C. Canada



	For running argus (1.8 or 2.0) on FreeBSD at least up to 4.2-RELEASE
and until FreeBSD PR kern/22063 gets applied, you need to apply the following
patch to /sys/net/bpf.c and /sys/net/bpfdesc.h and rebuild the kernel to 
make bpf function correctly with argus. As bpf currently stands partly filled
buffers won't get forwarded to argus when a select timeout occurs and argus will
lose packets. To demonstrate the bug start argus on Freebsd and send a small
number of packets (10 or so) which won't fill the bpf buffer. You will discover
when you hup argus that ra will report no data received with an unpatched
FreeBSD kernel. When you apply the patch the packets will show up correctly
(because they get forwarded when the select system call from argus times out).

*** /sys/net/bpf.c.orig	Sat Oct 14 19:00:59 2000
--- /sys/net/bpf.c	Mon Oct 16 09:30:24 2000
***************
*** 1054,1061 ****
  	if (events & (POLLIN | POLLRDNORM)) {
  		if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
  			revents |= events & (POLLIN | POLLRDNORM);
! 		else
! 			selrecord(p, &d->bd_sel);
  	}
  	splx(s);
  	return (revents);
--- 1054,1076 ----
  	if (events & (POLLIN | POLLRDNORM)) {
  		if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
  			revents |= events & (POLLIN | POLLRDNORM);
! 		else {
!         		/*
!          		 * If there is a timeout and no data in the hold buffer
!        			 * see if there has been data in the capture buffer
! 			 * for more than a timeout interval. If so rotate the
! 			 * buffer to push the packets to the user.
!         		 */
! 			if ((d->bd_slen != 0) && (d->bd_hlen == 0)) {
! 				if ((d->bd_rtout != -1) && 
! 				    (d->bd_rdstart + d->bd_rtout) > ticks) {
! 					ROTATE_BUFFERS(d);
! 					revents |= events & (POLLIN | POLLRDNORM);
! 				}
! 			} else 
! 				selrecord(p, &d->bd_sel);
! 				
! 		}
  	}
  	splx(s);
  	return (revents);
***************
*** 1219,1224 ****
--- 1234,1245 ----
  	 */
  	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
  	d->bd_slen = curlen + totlen;
+ 
+ 	/*
+ 	 * Mark the time the last packet was seen for poll timeout processing.
+ 	 */
+ 
+ 	d->bd_rdstart = ticks;
  }
  
  /*
*** /sys/net/bpfdesc.h.orig	Sat Oct 14 19:16:07 2000
--- /sys/net/bpfdesc.h	Sat Oct 14 19:21:54 2000
***************
*** 69,74 ****
--- 69,75 ----
  
  	struct bpf_if *	bd_bif;		/* interface descriptor */
  	u_long		bd_rtout;	/* Read timeout in 'ticks' */
+         u_long          bd_rdstart;     /* when the read started */
  	struct bpf_insn *bd_filter; 	/* filter code */
  	u_long		bd_rcount;	/* number of packets received */
  	u_long		bd_dcount;	/* number of packets dropped */



More information about the argus mailing list