*** bpf.h.orig	Tue Mar  3 21:12:56 1998
--- bpf.h	Wed Sep  2 16:11:15 1998
***************
*** 38,44 ****
   *      @(#)bpf.h	8.1 (Berkeley) 6/10/93
   *	@(#)bpf.h	1.34 (LBL)     6/16/96
   *
!  * $Id: bpf.h,v 1.1.1.1 1997/11/03 18:30:19 andrew Exp $
   */
  
  #ifndef _NET_BPF_H_
--- 38,44 ----
   *      @(#)bpf.h	8.1 (Berkeley) 6/10/93
   *	@(#)bpf.h	1.34 (LBL)     6/16/96
   *
!  * $Id: bpf.h,v 1.13 1998/07/13 10:44:02 bde Exp $
   */
  
  #ifndef _NET_BPF_H_
***************
*** 128,134 ****
   * Only the kernel needs to know about it; applications use bh_hdrlen.
   */
  #ifdef KERNEL
! #define SIZEOF_BPF_HDR 18
  #endif
  
  /*
--- 128,135 ----
   * Only the kernel needs to know about it; applications use bh_hdrlen.
   */
  #ifdef KERNEL
! #define	SIZEOF_BPF_HDR	(sizeof(struct bpf_hdr) <= 20 ? 18 : \
!     sizeof(struct bpf_hdr))
  #endif
  
  /*
*** bpf.c.orig	Tue Mar  3 21:12:56 1998
--- bpf.c	Wed Sep  2 16:08:40 1998
***************
*** 37,43 ****
   *
   *      @(#)bpf.c	8.2 (Berkeley) 3/28/94
   *
!  * $Id: bpf.c,v 1.2 1997/11/19 22:55:45 mts Exp $
   */
  
  #include "bpfilter.h"
--- 37,43 ----
   *
   *      @(#)bpf.c	8.2 (Berkeley) 3/28/94
   *
!  * $Id: bpf.c,v 1.40 1998/07/29 05:34:59 kjc Exp $
   */
  
  #include "bpfilter.h"
***************
*** 53,106 ****
  #include <sys/param.h>
  #include <sys/systm.h>
  #include <sys/conf.h>
  #include <sys/mbuf.h>
- #include <sys/buf.h>
  #include <sys/time.h>
  #include <sys/proc.h>
  #include <sys/signalvar.h>
! #include <sys/ioctl.h>
  
! #include <sys/file.h>
! #if defined(sparc) && BSD < 199103
! #include <sys/stream.h>
! #endif
! #include <sys/uio.h>
  
  #include <sys/socket.h>
! #include <sys/socketvar.h>
! #include <sys/protosw.h>
! #include <net/if.h>
  
  #include <net/bpf.h>
  #include <net/bpfdesc.h>
  
- #include <sys/errno.h>
- 
  #include <netinet/in.h>
  #include <netinet/if_ether.h>
  #include <sys/kernel.h>
  #include <sys/sysctl.h>
! #include <sys/conf.h>
  #ifdef DEVFS
  #include <sys/devfsext.h>
  #endif /*DEVFS*/
  
  
- /*
-  * Older BSDs don't have kernel malloc.
-  */
- #if BSD < 199103
- extern bcopy();
- static caddr_t bpf_alloc();
- #include <net/bpf_compat.h>
- #define BPF_BUFSIZE (MCLBYTES-8)
- #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)
- #else
  #define BPF_BUFSIZE 4096
- #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)
- #endif
  
! #define PRINET  6			/* interruptible */
  
  /*
   * The default read buffer size is patchable.
--- 53,91 ----
  #include <sys/param.h>
  #include <sys/systm.h>
  #include <sys/conf.h>
+ #include <sys/malloc.h>
  #include <sys/mbuf.h>
  #include <sys/time.h>
  #include <sys/proc.h>
  #include <sys/signalvar.h>
! #include <sys/filio.h>
! #include <sys/sockio.h>
! #include <sys/ttycom.h>
  
! #include <sys/poll.h>
  
  #include <sys/socket.h>
! #include <sys/vnode.h>
  
+ #include <net/if.h>
  #include <net/bpf.h>
  #include <net/bpfdesc.h>
  
  #include <netinet/in.h>
  #include <netinet/if_ether.h>
  #include <sys/kernel.h>
  #include <sys/sysctl.h>
! 
! #include "opt_devfs.h"
! 
  #ifdef DEVFS
  #include <sys/devfsext.h>
  #endif /*DEVFS*/
  
  
  #define BPF_BUFSIZE 4096
  
! #define PRINET  26			/* interruptible */
  
  /*
   * The default read buffer size is patchable.
***************
*** 115,120 ****
--- 100,106 ----
   */
  static struct bpf_if	*bpf_iflist;
  static struct bpf_d	bpf_dtab[NBPFILTER];
+ static int		bpf_dtab_init;
  
  static int	bpf_allocbufs __P((struct bpf_d *));
  static void	bpf_attachd __P((struct bpf_d *d, struct bpf_if *bp));
***************
*** 137,149 ****
  static	d_read_t	bpfread;
  static	d_write_t	bpfwrite;
  static	d_ioctl_t	bpfioctl;
! static	d_select_t	bpfselect;
  
  #define CDEV_MAJOR 23
  static struct cdevsw bpf_cdevsw = 
   	{ bpfopen,	bpfclose,	bpfread,	bpfwrite,	/*23*/
   	  bpfioctl,	nostop,		nullreset,	nodevtotty,/* bpf */
!  	  bpfselect,	nommap,		NULL,	"bpf",	NULL,	-1 };
  
  
  static int
--- 123,135 ----
  static	d_read_t	bpfread;
  static	d_write_t	bpfwrite;
  static	d_ioctl_t	bpfioctl;
! static	d_poll_t	bpfpoll;
  
  #define CDEV_MAJOR 23
  static struct cdevsw bpf_cdevsw = 
   	{ bpfopen,	bpfclose,	bpfread,	bpfwrite,	/*23*/
   	  bpfioctl,	nostop,		nullreset,	nodevtotty,/* bpf */
!  	  bpfpoll,	nommap,		NULL,	"bpf",	NULL,	-1 };
  
  
  static int
***************
*** 196,201 ****
--- 182,199 ----
  		hlen = 0;
  		break;
  
+ #ifdef __FreeBSD__
+ 	case DLT_ATM_RFC1483:
+ 		/*
+ 		 * en atm driver requires 4-byte atm pseudo header.
+ 		 * though it isn't standard, vpi:vci needs to be
+ 		 * specified anyway.
+ 		 */
+ 		sockp->sa_family = AF_UNSPEC;
+ 		hlen = 12; 	/* XXX 4(ATM_PH) + 3(LLC) + 5(SNAP) */
+ 		break;
+ #endif
+ 
  	default:
  		return (EIO);
  	}
***************
*** 209,221 ****
  	if (m == 0)
  		return (ENOBUFS);
  	if (len > MHLEN) {
- #if BSD >= 199103
  		MCLGET(m, M_WAIT);
  		if ((m->m_flags & M_EXT) == 0) {
- #else
- 		MCLGET(m);
- 		if (m->m_len != MCLBYTES) {
- #endif
  			error = ENOBUFS;
  			goto bad;
  		}
--- 207,214 ----
***************
*** 229,244 ****
  	if (hlen != 0) {
  		m->m_pkthdr.len -= hlen;
  		m->m_len -= hlen;
! #if BSD >= 199103
! 		m->m_data += hlen; /* XXX */
! #else
! 		m->m_off += hlen;
! #endif
! 		error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
  		if (error)
  			goto bad;
  	}
! 	error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
  	if (!error)
  		return (0);
   bad:
--- 222,233 ----
  	if (hlen != 0) {
  		m->m_pkthdr.len -= hlen;
  		m->m_len -= hlen;
! 		m->m_data += hlen;	/* note, not necessarily aligned */
! 		error = uiomove((caddr_t)sockp->sa_data, hlen, uio);
  		if (error)
  			goto bad;
  	}
! 	error = uiomove(mtod(m, caddr_t), len - hlen, uio);
  	if (!error)
  		return (0);
   bad:
***************
*** 375,419 ****
  }
  
  /*
-  * Support for SunOS, which does not have tsleep.
-  */
- #if BSD < 199103
- static
- bpf_timeout(arg)
- 	caddr_t arg;
- {
- 	struct bpf_d *d = (struct bpf_d *)arg;
- 	d->bd_timedout = 1;
- 	wakeup(arg);
- }
- 
- #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan)
- 
- int
- bpf_sleep(d)
- 	register struct bpf_d *d;
- {
- 	register int rto = d->bd_rtout;
- 	register int st;
- 
- 	if (rto != 0) {
- 		d->bd_timedout = 0;
- 		timeout(bpf_timeout, (caddr_t)d, rto);
- 	}
- 	st = sleep((caddr_t)d, PRINET|PCATCH);
- 	if (rto != 0) {
- 		if (d->bd_timedout == 0)
- 			untimeout(bpf_timeout, (caddr_t)d);
- 		else if (st == 0)
- 			return EWOULDBLOCK;
- 	}
- 	return (st != 0) ? EINTR : 0;
- }
- #else
- #define BPF_SLEEP tsleep
- #endif
- 
- /*
   * Rotate the packet buffers in descriptor d.  Move the store buffer
   * into the hold slot, and the free buffer into the store slot.
   * Zero the length of the new store buffer.
--- 364,369 ----
***************
*** 436,441 ****
--- 386,392 ----
  	register struct bpf_d *d = &bpf_dtab[minor(dev)];
  	int error;
  	int s;
+ 	int now;
  
  	/*
  	 * Restrict application to use a buffer the same size as
***************
*** 449,455 ****
  	** bd_rdStart is tagged when we start the read, iff there's a timeout.
  	** we can then figure out when we're done reading.
  	*/
! 	if ((d->bd_rtout != -1) && (d->bd_rdStart == 0)) {
  	    d->bd_rdStart = ticks;
  	} else {
  	    d->bd_rdStart = 0;
--- 400,406 ----
  	** bd_rdStart is tagged when we start the read, iff there's a timeout.
  	** we can then figure out when we're done reading.
  	*/
! 	if (d->bd_rtout && (d->bd_rdStart == 0)) {
  	    d->bd_rdStart = ticks;
  	} else {
  	    d->bd_rdStart = 0;
***************
*** 461,466 ****
--- 412,425 ----
  	 * have arrived to fill the store buffer.
  	 */
  	while (d->bd_hbuf == 0) {
+ 		if (ioflag & IO_NDELAY) {
+ 			if (d->bd_slen == 0) {
+ 				splx(s);
+ 				return (EWOULDBLOCK);
+ 			}
+ 			ROTATE_BUFFERS(d);
+ 			break;
+ 		}
  		if (d->bd_immediate && d->bd_slen != 0) {
  			/*
  			 * A packet(s) either arrived since the previous
***************
*** 470,487 ****
  			ROTATE_BUFFERS(d);
  			break;
  		}
! 		if ((d->bd_rtout != -1) || (d->bd_rdStart + d->bd_rtout) < ticks) {
! 			error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf",
! 					  d->bd_rtout);
  		} else {
! 			if (d->bd_rtout == -1) {
! 			    error = EWOULDBLOCK; /* User requested non-blocking I/O */
! 			} else {
! 			    error = 0;
! 			}
  		}
  		if (error == EINTR || error == ERESTART) {
  			splx(s);
  			return (error);
  		}
  		if (error == EWOULDBLOCK) {
--- 429,452 ----
  			ROTATE_BUFFERS(d);
  			break;
  		}
! 		now = ticks;
! 		if ((d->bd_rtout == 0) || (d->bd_rdStart + d->bd_rtout) > now) {
! 			error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf",
! 				d->bd_rtout ? d->bd_rdStart + d->bd_rtout - now : 0);
  		} else {
! 			error = 0;
  		}
+ 		/*
+ 		** We don't necessarily get a timeout errro, so we hafta
+ 		** fake one when the time runs out.
+ 		*/
+ 		if (d->bd_rtout && (d->bd_rtout + d->bd_rdStart) < now) {
+ 		    error = EWOULDBLOCK;
+ 		}
+ 
  		if (error == EINTR || error == ERESTART) {
  			splx(s);
+ 			d->bd_rdStart = 0;
  			return (error);
  		}
  		if (error == EWOULDBLOCK) {
***************
*** 500,505 ****
--- 465,471 ----
  
  			if (d->bd_slen == 0) {
  				splx(s);
+ 				d->bd_rdStart = 0;
  				return (0);
  			}
  			ROTATE_BUFFERS(d);
***************
*** 516,527 ****
  	 * We know the entire buffer is transferred since
  	 * we checked above that the read buffer is bpf_bufsize bytes.
  	 */
! 	error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
  
  	s = splimp();
  	d->bd_fbuf = d->bd_hbuf;
  	d->bd_hbuf = 0;
  	d->bd_hlen = 0;
  	splx(s);
  
  	return (error);
--- 482,494 ----
  	 * We know the entire buffer is transferred since
  	 * we checked above that the read buffer is bpf_bufsize bytes.
  	 */
! 	error = uiomove(d->bd_hbuf, d->bd_hlen, uio);
  
  	s = splimp();
  	d->bd_fbuf = d->bd_hbuf;
  	d->bd_hbuf = 0;
  	d->bd_hlen = 0;
+ 	d->bd_rdStart = 0;	/* timeout's over */
  	splx(s);
  
  	return (error);
***************
*** 544,560 ****
  		else if (p = pfind (-d->bd_pgid))
  			psignal (p, d->bd_sig);
  
- #if BSD >= 199103
  	selwakeup(&d->bd_sel);
  	/* XXX */
  	d->bd_sel.si_pid = 0;
- #else
- 	if (d->bd_selproc) {
- 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
- 		d->bd_selcoll = 0;
- 		d->bd_selproc = 0;
- 	}
- #endif
  }
  
  static	int
--- 511,519 ----
***************
*** 586,596 ****
  		return (EMSGSIZE);
  
  	s = splnet();
- #if BSD >= 199103
  	error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
- #else
- 	error = (*ifp->if_output)(ifp, m, &dst);
- #endif
  	splx(s);
  	/*
  	 * The driver frees the mbuf.
--- 545,551 ----
***************
*** 637,643 ****
  static	int
  bpfioctl(dev, cmd, addr, flags, p)
  	dev_t dev;
! 	int cmd;
  	caddr_t addr;
  	int flags;
  	struct proc *p;
--- 592,598 ----
  static	int
  bpfioctl(dev, cmd, addr, flags, p)
  	dev_t dev;
! 	u_long cmd;
  	caddr_t addr;
  	int flags;
  	struct proc *p;
***************
*** 834,843 ****
  
  
  	case FIONBIO:		/* Non-blocking I/O */
- 		if (*(int *)addr)
- 			d->bd_rtout = -1;
- 		else
- 			d->bd_rtout = 0;
  		break;
  
  	case FIOASYNC:		/* Send signal on receive packets */
--- 789,794 ----
***************
*** 1003,1087 ****
  }
  
  /*
!  * The new select interface passes down the proc pointer; the old select
!  * stubs had to grab it out of the user struct.  This glue allows either case.
!  */
! #if BSD >= 199103
! #define bpf_select bpfselect
! #else
! static	int
! bpfselect(dev, rw)
! 	register dev_t dev;
! 	int rw;
! {
! 	/*
! 	** if there isn't data waiting, and there's a timeout,
! 	** mark the time we started waiting.
! 	*/
! 	if ((b->db_rtout != -1) && ((d->bd_rdStart == 0)) {
! 	    d->bd_rdStart = ticks;
! 	}
! 			    
! 	return (bpf_select(dev, rw, u.u_procp));
! }
! #endif
! 
! /*
!  * Support for select() system call
   *
   * Return true iff the specific operation will not block indefinitely.
   * Otherwise, return false but make a note that a selwakeup() must be done.
   */
  int
! bpf_select(dev, rw, p)
  	register dev_t dev;
! 	int rw;
  	struct proc *p;
  {
  	register struct bpf_d *d;
  	register int s;
  
- 	if (rw != FREAD)
- 		return (0);
  	/*
  	 * An imitation of the FIONREAD ioctl code.
  	 */
  	d = &bpf_dtab[minor(dev)];
  
  	s = splimp();
! 	if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
! 		/*
! 		 * There is data waiting.
! 		 */
! 		splx(s);
! 		return (1);
! 	}
  
- 	/*
- 	** if there isn't data waiting, and there's a timeout,
- 	** mark the time we started waiting.
- 	*/
- 	if ((d->bd_rtout != -1) && (d->bd_rdStart == 0)) {
- 	    d->bd_rdStart = ticks;
- 	}
- 			    
- #if BSD >= 199103
- 	selrecord(p, &d->bd_sel);
- #else
- 	/*
- 	 * No data ready.  If there's already a select() waiting on this
- 	 * minor device then this is a collision.  This shouldn't happen
- 	 * because minors really should not be shared, but if a process
- 	 * forks while one of these is open, it is possible that both
- 	 * processes could select on the same descriptor.
- 	 */
- 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
- 		d->bd_selcoll = 1;
- 	else
- 		d->bd_selproc = p;
- #endif
  	splx(s);
! 	return (0);
  }
  
  /*
--- 954,997 ----
  }
  
  /*
!  * Support for select() and poll() system calls
   *
   * Return true iff the specific operation will not block indefinitely.
   * Otherwise, return false but make a note that a selwakeup() must be done.
   */
  int
! bpfpoll(dev, events, p)
  	register dev_t dev;
! 	int events;
  	struct proc *p;
  {
  	register struct bpf_d *d;
  	register int s;
+ 	int revents = 0;
  
  	/*
  	 * An imitation of the FIONREAD ioctl code.
  	 */
  	d = &bpf_dtab[minor(dev)];
  
  	s = splimp();
! 	if (events & (POLLIN | POLLRDNORM))
! 		if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
! 			revents |= events & (POLLIN | POLLRDNORM);
! 		else {
! 			/*
! 			** If there isn't data waiting, and there's a timeout,
! 			** mark the time we started waiting.
! 			*/
! 			if (d->bd_rtout && (d->bd_rdStart == 0)) {
! 			    d->bd_rdStart = ticks;
! 			}
! 
! 			selrecord(p, &d->bd_sel);
! 		}
  
  	splx(s);
! 	return (revents);
  }
  
  /*
***************
*** 1178,1184 ****
  	register struct bpf_d *d;
  	register u_char *pkt;
  	register u_int pktlen, snaplen;
! 	register void (*cpfn)(const void *, void *, u_int);
  {
  	register struct bpf_hdr *hp;
  	register int totlen, curlen;
--- 1088,1094 ----
  	register struct bpf_d *d;
  	register u_char *pkt;
  	register u_int pktlen, snaplen;
! 	register void (*cpfn) __P((const void *, void *, u_int));
  {
  	register struct bpf_hdr *hp;
  	register int totlen, curlen;
***************
*** 1227,1239 ****
  	 * Append the bpf header.
  	 */
  	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
- #if BSD >= 199103
  	microtime(&hp->bh_tstamp);
- #elif defined(sun)
- 	uniqtime(&hp->bh_tstamp);
- #else
- 	hp->bh_tstamp = time;
- #endif
  	hp->bh_datalen = pktlen;
  	hp->bh_hdrlen = hdrlen;
  	/*
--- 1137,1143 ----
***************
*** 1244,1251 ****
  
  	if (d->bd_rdStart && (d->bd_rtout + d->bd_rdStart < ticks)) {
  		/*
! 		** we could be selecting on the bpf, and we
! 		** may have timeouts set.  We got here by getting
  		** a packet, so wake up the reader.
  		*/
  		if (d->bd_fbuf) {
--- 1148,1155 ----
  
  	if (d->bd_rdStart && (d->bd_rtout + d->bd_rdStart < ticks)) {
  		/*
! 		** we could be selecting on the bpf, and
! 		** have timeouts set.  We got here by getting
  		** a packet, so wake up the reader.
  		*/
  		if (d->bd_fbuf) {
***************
*** 1340,1348 ****
  	/*
  	 * Mark all the descriptors free if this hasn't been done.
  	 */
! 	if (!D_ISFREE(&bpf_dtab[0]))
  		for (i = 0; i < NBPFILTER; ++i)
  			D_MARKFREE(&bpf_dtab[i]);
  
  	if (bootverbose)
  		printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
--- 1244,1254 ----
  	/*
  	 * Mark all the descriptors free if this hasn't been done.
  	 */
! 	if (!bpf_dtab_init) {
  		for (i = 0; i < NBPFILTER; ++i)
  			D_MARKFREE(&bpf_dtab[i]);
+ 		bpf_dtab_init = 1;
+ 	}
  
  	if (bootverbose)
  		printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
***************
*** 1352,1360 ****
  static	void *bpf_devfs_token[NBPFILTER];
  #endif
  
! static bpf_devsw_installed = 0;
  
! static void 	bpf_drvinit(void *unused)
  {
  	dev_t dev;
  #ifdef DEVFS
--- 1258,1269 ----
  static	void *bpf_devfs_token[NBPFILTER];
  #endif
  
! static	int bpf_devsw_installed;
  
! static void bpf_drvinit __P((void *unused));
! static void
! bpf_drvinit(unused)
! 	void *unused;
  {
  	dev_t dev;
  #ifdef DEVFS
