xref: /csrg-svn/sys/net/bpf.c (revision 53947)
151440Smccanne /*
251440Smccanne  * Copyright (c) 1990, 1991 Regents of the University of California.
347584Smccanne  * All rights reserved.
447584Smccanne  *
549343Sbostic  * This code is derived from the Stanford/CMU enet packet filter,
649343Sbostic  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
751425Smccanne  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
851425Smccanne  * Berkeley Laboratory.
947584Smccanne  *
1051440Smccanne  * %sccs.include.redist.c%
1149343Sbostic  *
12*53947Smccanne  *      @(#)bpf.c	7.9 (Berkeley) 06/07/92
1349343Sbostic  *
1449343Sbostic  * static char rcsid[] =
1551425Smccanne  * "$Header: bpf.c,v 1.33 91/10/27 21:21:58 mccanne Exp $";
1647584Smccanne  */
1747584Smccanne 
1847584Smccanne #include "bpfilter.h"
1947584Smccanne 
2051425Smccanne #if NBPFILTER > 0
2147584Smccanne 
2251425Smccanne #ifndef __GNUC__
2351425Smccanne #define inline
2451425Smccanne #else
2551425Smccanne #define inline __inline__
2651425Smccanne #endif
2751425Smccanne 
2847584Smccanne #include <sys/param.h>
2947584Smccanne #include <sys/systm.h>
3047584Smccanne #include <sys/mbuf.h>
3147584Smccanne #include <sys/buf.h>
3247584Smccanne #include <sys/dir.h>
33*53947Smccanne #include <sys/time.h>
3448932Smccanne #include <sys/proc.h>
3547584Smccanne #include <sys/user.h>
3647584Smccanne #include <sys/ioctl.h>
3747584Smccanne #include <sys/map.h>
3847584Smccanne 
3947584Smccanne #include <sys/file.h>
4051425Smccanne #if defined(sparc) && BSD < 199103
4147584Smccanne #include <sys/stream.h>
4247584Smccanne #endif
4347584Smccanne #include <sys/tty.h>
4447584Smccanne #include <sys/uio.h>
4547584Smccanne 
4647584Smccanne #include <sys/protosw.h>
4747584Smccanne #include <sys/socket.h>
4847584Smccanne #include <net/if.h>
4947584Smccanne 
5047584Smccanne #include <net/bpf.h>
5147584Smccanne #include <net/bpfdesc.h>
5247584Smccanne 
5347584Smccanne #include <sys/errno.h>
5447584Smccanne 
5547584Smccanne #include <netinet/in.h>
5647584Smccanne #include <netinet/if_ether.h>
5747584Smccanne #include <sys/kernel.h>
5847584Smccanne 
5951425Smccanne /*
6051425Smccanne  * Older BSDs don't have kernel malloc.
6151425Smccanne  */
6251425Smccanne #if BSD < 199103
6351425Smccanne extern bcopy();
6451425Smccanne static caddr_t bpf_alloc();
65*53947Smccanne #include <net/bpf_compat.h>
6651425Smccanne #define BPF_BUFSIZE (MCLBYTES-8)
67*53947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)
6851425Smccanne #else
6951425Smccanne #define BPF_BUFSIZE 4096
70*53947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)
7151425Smccanne #endif
7251425Smccanne 
7347584Smccanne #define PRINET  26			/* interruptible */
7447584Smccanne 
7547584Smccanne /*
7648932Smccanne  * The default read buffer size is patchable.
7748932Smccanne  */
7851425Smccanne int bpf_bufsize = BPF_BUFSIZE;
7948932Smccanne 
8048932Smccanne /*
8149202Smccanne  *  bpf_iflist is the list of interfaces; each corresponds to an ifnet
8249202Smccanne  *  bpf_dtab holds the descriptors, indexed by minor device #
8347584Smccanne  */
84*53947Smccanne struct bpf_if	*bpf_iflist;
85*53947Smccanne struct bpf_d	bpf_dtab[NBPFILTER];
8647584Smccanne 
8747584Smccanne static void	bpf_ifname();
8847584Smccanne static void	catchpacket();
89*53947Smccanne static void	bpf_freed();
9047584Smccanne static int	bpf_setif();
9147584Smccanne static int	bpf_initd();
92*53947Smccanne static int	bpf_allocbufs();
9347584Smccanne 
9447584Smccanne static int
9547584Smccanne bpf_movein(uio, linktype, mp, sockp)
9647584Smccanne 	register struct uio *uio;
9747584Smccanne 	int linktype;
9847584Smccanne 	register struct mbuf **mp;
9947584Smccanne 	register struct sockaddr *sockp;
10047584Smccanne {
10147584Smccanne 	struct mbuf *m;
10247584Smccanne 	int error;
10347584Smccanne 	int len;
10447584Smccanne 	int hlen;
10547584Smccanne 
10647584Smccanne 	/*
10747584Smccanne 	 * Build a sockaddr based on the data link layer type.
10847584Smccanne 	 * We do this at this level because the ethernet header
10947584Smccanne 	 * is copied directly into the data field of the sockaddr.
11047584Smccanne 	 * In the case of SLIP, there is no header and the packet
11147584Smccanne 	 * is forwarded as is.
11247584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
11347584Smccanne 	 * for the link level header.
11447584Smccanne 	 */
11547584Smccanne 	switch (linktype) {
116*53947Smccanne 
11747584Smccanne 	case DLT_SLIP:
11847584Smccanne 		sockp->sa_family = AF_INET;
11947584Smccanne 		hlen = 0;
12047584Smccanne 		break;
12147584Smccanne 
12247584Smccanne 	case DLT_EN10MB:
12347584Smccanne 		sockp->sa_family = AF_UNSPEC;
12447584Smccanne 		/* XXX Would MAXLINKHDR be better? */
12547584Smccanne 		hlen = sizeof(struct ether_header);
12647584Smccanne 		break;
12747584Smccanne 
128*53947Smccanne 	case DLT_FDDI:
12947584Smccanne 		sockp->sa_family = AF_UNSPEC;
13047584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
13147584Smccanne 		hlen = 24;
13247584Smccanne 		break;
13347584Smccanne 
134*53947Smccanne 	case DLT_NULL:
135*53947Smccanne 		sockp->sa_family = AF_UNSPEC;
136*53947Smccanne 		hlen = 0;
137*53947Smccanne 		break;
138*53947Smccanne 
13947584Smccanne 	default:
14048932Smccanne 		return (EIO);
14147584Smccanne 	}
14247584Smccanne 
14347584Smccanne 	len = uio->uio_resid;
14447584Smccanne 	if ((unsigned)len > MCLBYTES)
14548932Smccanne 		return (EIO);
14647584Smccanne 
14747584Smccanne 	MGET(m, M_WAIT, MT_DATA);
14847584Smccanne 	if (m == 0)
14948932Smccanne 		return (ENOBUFS);
15047584Smccanne 	if (len > MLEN) {
15151425Smccanne #if BSD >= 199103
15248932Smccanne 		MCLGET(m, M_WAIT);
15348932Smccanne 		if ((m->m_flags & M_EXT) == 0) {
15451425Smccanne #else
15551425Smccanne 		MCLGET(m);
156*53947Smccanne 		if (m->m_len != MCLBYTES) {
15751425Smccanne #endif
158*53947Smccanne 			error = ENOBUFS;
15947584Smccanne 			goto bad;
16047584Smccanne 		}
16147584Smccanne 	}
16247584Smccanne 	m->m_len = len;
16347584Smccanne 	*mp = m;
16447584Smccanne 	/*
16547584Smccanne 	 * Make room for link header.
16647584Smccanne 	 */
167*53947Smccanne 	if (hlen != 0) {
16847584Smccanne 		m->m_len -= hlen;
16951425Smccanne #if BSD >= 199103
17048932Smccanne 		m->m_data += hlen; /* XXX */
17151425Smccanne #else
17251425Smccanne 		m->m_off += hlen;
17351425Smccanne #endif
174*53947Smccanne 		error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
17547584Smccanne 		if (error)
17647584Smccanne 			goto bad;
17747584Smccanne 	}
178*53947Smccanne 	error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
179*53947Smccanne 	if (!error)
18048932Smccanne 		return (0);
18147584Smccanne  bad:
18247584Smccanne 	m_freem(m);
18348932Smccanne 	return (error);
18447584Smccanne }
18547584Smccanne 
18647584Smccanne /*
18751425Smccanne  * Attach file to the bpf interface, i.e. make d listen on bp.
18847584Smccanne  * Must be called at splimp.
18947584Smccanne  */
19047584Smccanne static void
19147584Smccanne bpf_attachd(d, bp)
19247584Smccanne 	struct bpf_d *d;
19347584Smccanne 	struct bpf_if *bp;
19447584Smccanne {
19551425Smccanne 	/*
19651425Smccanne 	 * Point d at bp, and add d to the interface's list of listeners.
19751425Smccanne 	 * Finally, point the driver's bpf cookie at the interface so
19851425Smccanne 	 * it will divert packets to bpf.
19951425Smccanne 	 */
20047584Smccanne 	d->bd_bif = bp;
20147584Smccanne 	d->bd_next = bp->bif_dlist;
20247584Smccanne 	bp->bif_dlist = d;
20347584Smccanne 
20447584Smccanne 	*bp->bif_driverp = bp;
20547584Smccanne }
20647584Smccanne 
20751425Smccanne /*
20851425Smccanne  * Detach a file from its interface.
20951425Smccanne  */
21047584Smccanne static void
21147584Smccanne bpf_detachd(d)
21247584Smccanne 	struct bpf_d *d;
21347584Smccanne {
21447584Smccanne 	struct bpf_d **p;
21547584Smccanne 	struct bpf_if *bp;
21647584Smccanne 
21747584Smccanne 	bp = d->bd_bif;
21847584Smccanne 	/*
21947584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
22047584Smccanne 	 * If so, turn it off.
22147584Smccanne 	 */
22247584Smccanne 	if (d->bd_promisc) {
22347584Smccanne 		d->bd_promisc = 0;
22447584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
22547584Smccanne 			/*
22647584Smccanne 			 * Something is really wrong if we were able to put
22747584Smccanne 			 * the driver into promiscuous mode, but can't
22847584Smccanne 			 * take it out.
22947584Smccanne 			 */
23051425Smccanne 			panic("bpf: ifpromisc failed");
23147584Smccanne 	}
23251425Smccanne 	/* Remove d from the interface's descriptor list. */
23347584Smccanne 	p = &bp->bif_dlist;
23447584Smccanne 	while (*p != d) {
23547584Smccanne 		p = &(*p)->bd_next;
23647584Smccanne 		if (*p == 0)
23747584Smccanne 			panic("bpf_detachd: descriptor not in list");
23847584Smccanne 	}
23947584Smccanne 	*p = (*p)->bd_next;
24047584Smccanne 	if (bp->bif_dlist == 0)
24147584Smccanne 		/*
24247584Smccanne 		 * Let the driver know that there are no more listeners.
24347584Smccanne 		 */
24447584Smccanne 		*d->bd_bif->bif_driverp = 0;
24547584Smccanne 	d->bd_bif = 0;
24647584Smccanne }
24747584Smccanne 
24847584Smccanne 
24947584Smccanne /*
250*53947Smccanne  * Mark a descriptor free by making it point to itself.
25147584Smccanne  * This is probably cheaper than marking with a constant since
25247584Smccanne  * the address should be in a register anyway.
25347584Smccanne  */
25447584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
25547584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
25647584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
25747584Smccanne 
25847584Smccanne /*
259*53947Smccanne  * Open ethernet device.  Returns ENXIO for illegal minor device number,
260*53947Smccanne  * EBUSY if file is open by another process.
26147584Smccanne  */
26247584Smccanne /* ARGSUSED */
26347584Smccanne int
26447584Smccanne bpfopen(dev, flag)
26547584Smccanne 	dev_t dev;
26647584Smccanne 	int flag;
26747584Smccanne {
26847584Smccanne 	register struct bpf_d *d;
269*53947Smccanne 
27047584Smccanne 	if (minor(dev) >= NBPFILTER)
27148932Smccanne 		return (ENXIO);
27247584Smccanne 	/*
27347584Smccanne 	 * Each minor can be opened by only one process.  If the requested
27447584Smccanne 	 * minor is in use, return EBUSY.
27547584Smccanne 	 */
27647584Smccanne 	d = &bpf_dtab[minor(dev)];
277*53947Smccanne 	if (!D_ISFREE(d))
27848932Smccanne 		return (EBUSY);
27947584Smccanne 
280*53947Smccanne 	/* Mark "free" and do most initialization. */
281*53947Smccanne 	bzero((char *)d, sizeof(*d));
282*53947Smccanne 	d->bd_bufsize = bpf_bufsize;
283*53947Smccanne 
28448932Smccanne 	return (0);
28547584Smccanne }
28647584Smccanne 
28747584Smccanne /*
28847584Smccanne  * Close the descriptor by detaching it from its interface,
28947584Smccanne  * deallocating its buffers, and marking it free.
29047584Smccanne  */
29147584Smccanne /* ARGSUSED */
292*53947Smccanne int
29347584Smccanne bpfclose(dev, flag)
29447584Smccanne 	dev_t dev;
29547584Smccanne 	int flag;
29647584Smccanne {
29747584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
298*53947Smccanne 	register int s;
29947584Smccanne 
30047584Smccanne 	s = splimp();
30147584Smccanne 	if (d->bd_bif)
30247584Smccanne 		bpf_detachd(d);
30347584Smccanne 	splx(s);
304*53947Smccanne 	bpf_freed(d);
30547584Smccanne 
306*53947Smccanne 	return (0);
30747584Smccanne }
30847584Smccanne 
309*53947Smccanne /*
310*53947Smccanne  * Support for SunOS, which does not have tsleep.
311*53947Smccanne  */
31251425Smccanne #if BSD < 199103
31351425Smccanne static
31451425Smccanne bpf_timeout(arg)
31551425Smccanne 	caddr_t arg;
31651425Smccanne {
31751425Smccanne 	struct bpf_d *d = (struct bpf_d *)arg;
31851425Smccanne 	d->bd_timedout = 1;
31951425Smccanne 	wakeup(arg);
32051425Smccanne }
32151425Smccanne 
322*53947Smccanne #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan)
323*53947Smccanne 
324*53947Smccanne int
325*53947Smccanne bpf_sleep(d)
326*53947Smccanne 	register struct bpf_d *d;
32751425Smccanne {
328*53947Smccanne 	register int rto = d->bd_rtout;
329*53947Smccanne 	register int st;
33051425Smccanne 
331*53947Smccanne 	if (rto != 0) {
33251425Smccanne 		d->bd_timedout = 0;
333*53947Smccanne 		timeout(bpf_timeout, (caddr_t)d, rto);
33451425Smccanne 	}
335*53947Smccanne 	st = sleep((caddr_t)d, PRINET|PCATCH);
336*53947Smccanne 	if (rto != 0) {
337*53947Smccanne 		if (d->bd_timedout == 0)
338*53947Smccanne 			untimeout(bpf_timeout, (caddr_t)d);
339*53947Smccanne 		else if (st == 0)
34051425Smccanne 			return EWOULDBLOCK;
34151425Smccanne 	}
342*53947Smccanne 	return (st != 0) ? EINTR : 0;
34351425Smccanne }
344*53947Smccanne #else
345*53947Smccanne #define BPF_SLEEP tsleep
34651425Smccanne #endif
34751425Smccanne 
34847584Smccanne /*
34948932Smccanne  * Rotate the packet buffers in descriptor d.  Move the store buffer
350*53947Smccanne  * into the hold slot, and the free buffer into the store slot.
35148932Smccanne  * Zero the length of the new store buffer.
35248932Smccanne  */
35348932Smccanne #define ROTATE_BUFFERS(d) \
35448932Smccanne 	(d)->bd_hbuf = (d)->bd_sbuf; \
35548932Smccanne 	(d)->bd_hlen = (d)->bd_slen; \
35648932Smccanne 	(d)->bd_sbuf = (d)->bd_fbuf; \
35748932Smccanne 	(d)->bd_slen = 0; \
358*53947Smccanne 	(d)->bd_fbuf = 0;
35948932Smccanne /*
36047584Smccanne  *  bpfread - read next chunk of packets from buffers
36147584Smccanne  */
36247584Smccanne int
36347584Smccanne bpfread(dev, uio)
36447584Smccanne 	dev_t dev;
36547584Smccanne 	register struct uio *uio;
36647584Smccanne {
36747584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
36847584Smccanne 	int error;
36947584Smccanne 	int s;
37047584Smccanne 
37147584Smccanne 	/*
372*53947Smccanne 	 * Restrict application to use a buffer the same size as
37347584Smccanne 	 * as kernel buffers.
37447584Smccanne 	 */
37548932Smccanne 	if (uio->uio_resid != d->bd_bufsize)
37649202Smccanne 		return (EINVAL);
37747584Smccanne 
37847584Smccanne 	s = splimp();
37947584Smccanne 	/*
380*53947Smccanne 	 * If the hold buffer is empty, then do a timed sleep, which
381*53947Smccanne 	 * ends when the timeout expires or when enough packets
382*53947Smccanne 	 * have arrived to fill the store buffer.
38347584Smccanne 	 */
38447584Smccanne 	while (d->bd_hbuf == 0) {
38548932Smccanne 		if (d->bd_immediate && d->bd_slen != 0) {
38647584Smccanne 			/*
38747584Smccanne 			 * A packet(s) either arrived since the previous
38847584Smccanne 			 * read or arrived while we were asleep.
38947584Smccanne 			 * Rotate the buffers and return what's here.
39047584Smccanne 			 */
39148932Smccanne 			ROTATE_BUFFERS(d);
39247584Smccanne 			break;
39347584Smccanne 		}
394*53947Smccanne 		error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf",
395*53947Smccanne 				  d->bd_rtout);
39648932Smccanne 		if (error == EINTR || error == ERESTART) {
39748932Smccanne 			splx(s);
39848932Smccanne 			return (error);
39947584Smccanne 		}
40048932Smccanne 		if (error == EWOULDBLOCK) {
40147584Smccanne 			/*
40247584Smccanne 			 * On a timeout, return what's in the buffer,
40348932Smccanne 			 * which may be nothing.  If there is something
40448932Smccanne 			 * in the store buffer, we can rotate the buffers.
40547584Smccanne 			 */
40647584Smccanne 			if (d->bd_hbuf)
40747584Smccanne 				/*
408*53947Smccanne 				 * We filled up the buffer in between
40947584Smccanne 				 * getting the timeout and arriving
41047584Smccanne 				 * here, so we don't need to rotate.
41147584Smccanne 				 */
41247584Smccanne 				break;
41347584Smccanne 
41448932Smccanne 			if (d->bd_slen == 0) {
41547584Smccanne 				splx(s);
41648932Smccanne 				return (0);
41747584Smccanne 			}
41848932Smccanne 			ROTATE_BUFFERS(d);
41947584Smccanne 			break;
42047584Smccanne 		}
42147584Smccanne 	}
42247584Smccanne 	/*
42347584Smccanne 	 * At this point, we know we have something in the hold slot.
42447584Smccanne 	 */
42547584Smccanne 	splx(s);
426*53947Smccanne 
427*53947Smccanne 	/*
42847584Smccanne 	 * Move data from hold buffer into user space.
42947584Smccanne 	 * We know the entire buffer is transferred since
43048932Smccanne 	 * we checked above that the read buffer is bpf_bufsize bytes.
43147584Smccanne 	 */
432*53947Smccanne 	error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
433*53947Smccanne 
43447584Smccanne 	s = splimp();
43548932Smccanne 	d->bd_fbuf = d->bd_hbuf;
43648932Smccanne 	d->bd_hbuf = 0;
437*53947Smccanne 	d->bd_hlen = 0;
43847584Smccanne 	splx(s);
439*53947Smccanne 
44048932Smccanne 	return (error);
44147584Smccanne }
44247584Smccanne 
44347584Smccanne 
44447584Smccanne /*
445*53947Smccanne  * If there are processes sleeping on this descriptor, wake them up.
44647584Smccanne  */
44747584Smccanne static inline void
44847584Smccanne bpf_wakeup(d)
44947584Smccanne 	register struct bpf_d *d;
45047584Smccanne {
45148932Smccanne 	wakeup((caddr_t)d);
452*53947Smccanne #if BSD >= 199103
453*53947Smccanne 	selwakeup(&d->bd_sel);
454*53947Smccanne 	/* XXX */
455*53947Smccanne 	d->bd_sel.si_pid = 0;
456*53947Smccanne #else
457*53947Smccanne 	if (d->bd_selproc) {
458*53947Smccanne 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
459*53947Smccanne 		d->bd_selcoll = 0;
460*53947Smccanne 		d->bd_selproc = 0;
461*53947Smccanne 	}
462*53947Smccanne #endif
46347584Smccanne }
46447584Smccanne 
46547584Smccanne int
46647584Smccanne bpfwrite(dev, uio)
46747584Smccanne 	dev_t dev;
46847584Smccanne 	struct uio *uio;
46947584Smccanne {
47047584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
47147584Smccanne 	struct ifnet *ifp;
47247584Smccanne 	struct mbuf *m;
47347584Smccanne 	int error, s;
47447584Smccanne 	static struct sockaddr dst;
47547584Smccanne 
47647584Smccanne 	if (d->bd_bif == 0)
47748932Smccanne 		return (ENXIO);
47847584Smccanne 
47947584Smccanne 	ifp = d->bd_bif->bif_ifp;
48047584Smccanne 
48147584Smccanne 	if (uio->uio_resid == 0)
48248932Smccanne 		return (0);
48347584Smccanne 	if (uio->uio_resid > ifp->if_mtu)
48448932Smccanne 		return (EMSGSIZE);
48547584Smccanne 
48649202Smccanne 	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst);
48747584Smccanne 	if (error)
48848932Smccanne 		return (error);
48947584Smccanne 
49047584Smccanne 	s = splnet();
49151425Smccanne #if BSD >= 199103
492*53947Smccanne 	error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
49351425Smccanne #else
49447584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
49551425Smccanne #endif
49647584Smccanne 	splx(s);
49747584Smccanne 	/*
498*53947Smccanne 	 * The driver frees the mbuf.
49947584Smccanne 	 */
50048932Smccanne 	return (error);
50147584Smccanne }
50247584Smccanne 
50347584Smccanne /*
504*53947Smccanne  * Reset a descriptor by flushing its packet buffer and clearing the
505*53947Smccanne  * receive and drop counts.  Should be called at splimp.
50647584Smccanne  */
50747584Smccanne static void
50847584Smccanne reset_d(d)
50947584Smccanne 	struct bpf_d *d;
51047584Smccanne {
51147584Smccanne 	if (d->bd_hbuf) {
51247584Smccanne 		/* Free the hold buffer. */
51347584Smccanne 		d->bd_fbuf = d->bd_hbuf;
51447584Smccanne 		d->bd_hbuf = 0;
51547584Smccanne 	}
51648932Smccanne 	d->bd_slen = 0;
517*53947Smccanne 	d->bd_hlen = 0;
51847584Smccanne 	d->bd_rcount = 0;
51947584Smccanne 	d->bd_dcount = 0;
52047584Smccanne }
52147584Smccanne 
52247584Smccanne /*
52347584Smccanne  *  FIONREAD		Check for read packet available.
52447584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
52547584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
52647584Smccanne  *  BIOCSETF		Set ethernet read filter.
52747584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
52847584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
52949202Smccanne  *  BIOCGDLT		Get link layer type.
53047584Smccanne  *  BIOCGETIF		Get interface name.
53147584Smccanne  *  BIOCSETIF		Set interface.
53247584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
53347584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
53447584Smccanne  *  BIOCGSTATS		Get packet stats.
53547584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
536*53947Smccanne  *  BIOCVERSION		Get filter language version.
53747584Smccanne  */
53847584Smccanne /* ARGSUSED */
53947584Smccanne int
54047584Smccanne bpfioctl(dev, cmd, addr, flag)
54147584Smccanne 	dev_t dev;
54247584Smccanne 	int cmd;
54347584Smccanne 	caddr_t addr;
54447584Smccanne 	int flag;
54547584Smccanne {
54647584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
54747584Smccanne 	int s, error = 0;
54847584Smccanne 
54947584Smccanne 	switch (cmd) {
55047584Smccanne 
55147584Smccanne 	default:
55247584Smccanne 		error = EINVAL;
55347584Smccanne 		break;
55447584Smccanne 
55547584Smccanne 	/*
55647584Smccanne 	 * Check for read packet available.
55747584Smccanne 	 */
55847584Smccanne 	case FIONREAD:
55947584Smccanne 		{
56047584Smccanne 			int n;
561*53947Smccanne 
56247584Smccanne 			s = splimp();
56348932Smccanne 			n = d->bd_slen;
564*53947Smccanne 			if (d->bd_hbuf)
56548932Smccanne 				n += d->bd_hlen;
56647584Smccanne 			splx(s);
56747584Smccanne 
56847584Smccanne 			*(int *)addr = n;
56947584Smccanne 			break;
57047584Smccanne 		}
57147584Smccanne 
57247584Smccanne 	case SIOCGIFADDR:
57347584Smccanne 		{
57447584Smccanne 			struct ifnet *ifp;
57547584Smccanne 
57647584Smccanne 			if (d->bd_bif == 0)
57747584Smccanne 				error = EINVAL;
57847584Smccanne 			else {
57947584Smccanne 				ifp = d->bd_bif->bif_ifp;
580*53947Smccanne 				error = (*ifp->if_ioctl)(ifp, cmd, addr);
58147584Smccanne 			}
58247584Smccanne 			break;
58347584Smccanne 		}
58447584Smccanne 
58547584Smccanne 	/*
58647584Smccanne 	 * Get buffer len [for read()].
58747584Smccanne 	 */
58847584Smccanne 	case BIOCGBLEN:
58948932Smccanne 		*(u_int *)addr = d->bd_bufsize;
59047584Smccanne 		break;
59147584Smccanne 
59247584Smccanne 	/*
593*53947Smccanne 	 * Set buffer length.
594*53947Smccanne 	 */
595*53947Smccanne 	case BIOCSBLEN:
596*53947Smccanne #if BSD < 199103
597*53947Smccanne 		error = EINVAL;
598*53947Smccanne #else
599*53947Smccanne 		if (d->bd_bif != 0)
600*53947Smccanne 			error = EINVAL;
601*53947Smccanne 		else {
602*53947Smccanne 			register u_int size = *(u_int *)addr;
603*53947Smccanne 
604*53947Smccanne 			if (size > BPF_MAXBUFSIZE)
605*53947Smccanne 				*(u_int *)addr = size = BPF_MAXBUFSIZE;
606*53947Smccanne 			else if (size < BPF_MINBUFSIZE)
607*53947Smccanne 				*(u_int *)addr = size = BPF_MINBUFSIZE;
608*53947Smccanne 			d->bd_bufsize = size;
609*53947Smccanne 		}
610*53947Smccanne #endif
611*53947Smccanne 		break;
612*53947Smccanne 
613*53947Smccanne 	/*
61451425Smccanne 	 * Set link layer read filter.
61547584Smccanne 	 */
616*53947Smccanne 	case BIOCSETF:
61747584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
61847584Smccanne 		break;
61947584Smccanne 
62047584Smccanne 	/*
62147584Smccanne 	 * Flush read packet buffer.
62247584Smccanne 	 */
62347584Smccanne 	case BIOCFLUSH:
62447584Smccanne 		s = splimp();
62547584Smccanne 		reset_d(d);
62647584Smccanne 		splx(s);
62747584Smccanne 		break;
62847584Smccanne 
62947584Smccanne 	/*
63047584Smccanne 	 * Put interface into promiscuous mode.
63147584Smccanne 	 */
63247584Smccanne 	case BIOCPROMISC:
63347584Smccanne 		if (d->bd_bif == 0) {
63447584Smccanne 			/*
63547584Smccanne 			 * No interface attached yet.
63647584Smccanne 			 */
63747584Smccanne 			error = EINVAL;
63847584Smccanne 			break;
63947584Smccanne 		}
64047584Smccanne 		s = splimp();
64147584Smccanne 		if (d->bd_promisc == 0) {
64247584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
64351425Smccanne 			if (error == 0)
64451425Smccanne 				d->bd_promisc = 1;
64547584Smccanne 		}
64647584Smccanne 		splx(s);
64747584Smccanne 		break;
64847584Smccanne 
64947584Smccanne 	/*
65047584Smccanne 	 * Get device parameters.
65147584Smccanne 	 */
65249202Smccanne 	case BIOCGDLT:
65347584Smccanne 		if (d->bd_bif == 0)
65447584Smccanne 			error = EINVAL;
65547584Smccanne 		else
65649202Smccanne 			*(u_int *)addr = d->bd_bif->bif_dlt;
65747584Smccanne 		break;
65847584Smccanne 
65947584Smccanne 	/*
66047584Smccanne 	 * Set interface name.
66147584Smccanne 	 */
66247584Smccanne 	case BIOCGETIF:
66347584Smccanne 		if (d->bd_bif == 0)
66447584Smccanne 			error = EINVAL;
66547584Smccanne 		else
66647584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
66747584Smccanne 		break;
66847584Smccanne 
66947584Smccanne 	/*
67047584Smccanne 	 * Set interface.
67147584Smccanne 	 */
67247584Smccanne 	case BIOCSETIF:
67347584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
67447584Smccanne 		break;
67547584Smccanne 
67647584Smccanne 	/*
67747584Smccanne 	 * Set read timeout.
67847584Smccanne 	 */
679*53947Smccanne 	case BIOCSRTIMEOUT:
68047584Smccanne 		{
68147584Smccanne 			struct timeval *tv = (struct timeval *)addr;
68247584Smccanne 			u_long msec;
68347584Smccanne 
68447584Smccanne 			/* Compute number of milliseconds. */
68547584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
68647584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
68747584Smccanne 			   clock has millisecond or greater resolution
68847584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
68947584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
69047584Smccanne 			d->bd_rtout = msec / (tick / 1000);
69147584Smccanne 			break;
69247584Smccanne 		}
69347584Smccanne 
69447584Smccanne 	/*
69547584Smccanne 	 * Get read timeout.
69647584Smccanne 	 */
697*53947Smccanne 	case BIOCGRTIMEOUT:
69847584Smccanne 		{
69947584Smccanne 			struct timeval *tv = (struct timeval *)addr;
70047584Smccanne 			u_long msec = d->bd_rtout;
70147584Smccanne 
70247584Smccanne 			msec *= tick / 1000;
70347584Smccanne 			tv->tv_sec = msec / 1000;
70447584Smccanne 			tv->tv_usec = msec % 1000;
70547584Smccanne 			break;
70647584Smccanne 		}
70747584Smccanne 
70847584Smccanne 	/*
70947584Smccanne 	 * Get packet stats.
71047584Smccanne 	 */
71147584Smccanne 	case BIOCGSTATS:
71247584Smccanne 		{
71347584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
71447584Smccanne 
71547584Smccanne 			bs->bs_recv = d->bd_rcount;
71647584Smccanne 			bs->bs_drop = d->bd_dcount;
71747584Smccanne 			break;
71847584Smccanne 		}
71947584Smccanne 
72047584Smccanne 	/*
72147584Smccanne 	 * Set immediate mode.
72247584Smccanne 	 */
72347584Smccanne 	case BIOCIMMEDIATE:
72447584Smccanne 		d->bd_immediate = *(u_int *)addr;
72547584Smccanne 		break;
726*53947Smccanne 
727*53947Smccanne 	case BIOCVERSION:
728*53947Smccanne 		{
729*53947Smccanne 			struct bpf_version *bv = (struct bpf_version *)addr;
730*53947Smccanne 
731*53947Smccanne 			bv->bv_major = BPF_MAJOR_VERSION;
732*53947Smccanne 			bv->bv_minor = BPF_MINOR_VERSION;
733*53947Smccanne 			break;
734*53947Smccanne 		}
73547584Smccanne 	}
73648932Smccanne 	return (error);
73747584Smccanne }
73847584Smccanne 
739*53947Smccanne /*
74051425Smccanne  * Set d's packet filter program to fp.  If this file already has a filter,
74148932Smccanne  * free it and replace it.  Returns EINVAL for bogus requests.
74247584Smccanne  */
74347584Smccanne int
74447584Smccanne bpf_setf(d, fp)
74547584Smccanne 	struct bpf_d *d;
74647584Smccanne 	struct bpf_program *fp;
74747584Smccanne {
74848932Smccanne 	struct bpf_insn *fcode, *old;
74947584Smccanne 	u_int flen, size;
75047584Smccanne 	int s;
75147584Smccanne 
75248932Smccanne 	old = d->bd_filter;
75347584Smccanne 	if (fp->bf_insns == 0) {
75447584Smccanne 		if (fp->bf_len != 0)
75548932Smccanne 			return (EINVAL);
75648932Smccanne 		s = splimp();
75748967Smccanne 		d->bd_filter = 0;
75847584Smccanne 		reset_d(d);
75947584Smccanne 		splx(s);
76048967Smccanne 		if (old != 0)
76148932Smccanne 			free((caddr_t)old, M_DEVBUF);
76248932Smccanne 		return (0);
76347584Smccanne 	}
76447584Smccanne 	flen = fp->bf_len;
76548932Smccanne 	if (flen > BPF_MAXINSNS)
76648932Smccanne 		return (EINVAL);
76748932Smccanne 
76847584Smccanne 	size = flen * sizeof(*fp->bf_insns);
76948932Smccanne 	fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
77050417Smccanne 	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
77150417Smccanne 	    bpf_validate(fcode, (int)flen)) {
77248967Smccanne 		s = splimp();
77348932Smccanne 		d->bd_filter = fcode;
77447584Smccanne 		reset_d(d);
77547584Smccanne 		splx(s);
77648967Smccanne 		if (old != 0)
77748932Smccanne 			free((caddr_t)old, M_DEVBUF);
77847584Smccanne 
77948932Smccanne 		return (0);
78047584Smccanne 	}
78148932Smccanne 	free((caddr_t)fcode, M_DEVBUF);
78248932Smccanne 	return (EINVAL);
78347584Smccanne }
78447584Smccanne 
78547584Smccanne /*
786*53947Smccanne  * Detach a file from its current interface (if attached at all) and attach
787*53947Smccanne  * to the interface indicated by the name stored in ifr.
78851425Smccanne  * Return an errno or 0.
78947584Smccanne  */
79047584Smccanne static int
79147584Smccanne bpf_setif(d, ifr)
79247584Smccanne 	struct bpf_d *d;
79347584Smccanne 	struct ifreq *ifr;
79447584Smccanne {
79547584Smccanne 	struct bpf_if *bp;
79647584Smccanne 	char *cp;
797*53947Smccanne 	int unit, s, error;
79847584Smccanne 
79947584Smccanne 	/*
80047584Smccanne 	 * Separate string into name part and unit number.  Put a null
801*53947Smccanne 	 * byte at the end of the name part, and compute the number.
80247584Smccanne 	 * If the a unit number is unspecified, the default is 0,
80348932Smccanne 	 * as initialized above.  XXX This should be common code.
80447584Smccanne 	 */
80547584Smccanne 	unit = 0;
80647584Smccanne 	cp = ifr->ifr_name;
80747584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
80847584Smccanne 	while (*cp++) {
80947584Smccanne 		if (*cp >= '0' && *cp <= '9') {
81047584Smccanne 			unit = *cp - '0';
81147584Smccanne 			*cp++ = '\0';
81247584Smccanne 			while (*cp)
81347584Smccanne 				unit = 10 * unit + *cp++ - '0';
81447584Smccanne 			break;
81547584Smccanne 		}
81647584Smccanne 	}
81747584Smccanne 	/*
81847584Smccanne 	 * Look through attached interfaces for the named one.
81947584Smccanne 	 */
82049202Smccanne 	for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
82147584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
82247584Smccanne 
823*53947Smccanne 		if (ifp == 0 || unit != ifp->if_unit
82447584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
82547584Smccanne 			continue;
82647584Smccanne 		/*
827*53947Smccanne 		 * We found the requested interface.
82847584Smccanne 		 * If it's not up, return an error.
829*53947Smccanne 		 * Allocate the packet buffers if we need to.
830*53947Smccanne 		 * If we're already attached to requested interface,
831*53947Smccanne 		 * just flush the buffer.
83247584Smccanne 		 */
83347584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
83448932Smccanne 			return (ENETDOWN);
835*53947Smccanne 
836*53947Smccanne 		if (d->bd_sbuf == 0) {
837*53947Smccanne 			error = bpf_allocbufs(d);
838*53947Smccanne 			if (error != 0)
839*53947Smccanne 				return (error);
840*53947Smccanne 		}
84147584Smccanne 		s = splimp();
84247584Smccanne 		if (bp != d->bd_bif) {
84347584Smccanne 			if (d->bd_bif)
844*53947Smccanne 				/*
84548932Smccanne 				 * Detach if attached to something else.
84647584Smccanne 				 */
84747584Smccanne 				bpf_detachd(d);
84847584Smccanne 
84947584Smccanne 			bpf_attachd(d, bp);
85047584Smccanne 		}
85147584Smccanne 		reset_d(d);
85247584Smccanne 		splx(s);
85348932Smccanne 		return (0);
85447584Smccanne 	}
85547584Smccanne 	/* Not found. */
85648932Smccanne 	return (ENXIO);
85747584Smccanne }
85847584Smccanne 
85947584Smccanne /*
86051425Smccanne  * Convert an interface name plus unit number of an ifp to a single
86151425Smccanne  * name which is returned in the ifr.
86247584Smccanne  */
86347584Smccanne static void
86447584Smccanne bpf_ifname(ifp, ifr)
86547584Smccanne 	struct ifnet *ifp;
86647584Smccanne 	struct ifreq *ifr;
86747584Smccanne {
86847584Smccanne 	char *s = ifp->if_name;
86947584Smccanne 	char *d = ifr->ifr_name;
87047584Smccanne 
87147584Smccanne 	while (*d++ = *s++)
872*53947Smccanne 		continue;
87348932Smccanne 	/* XXX Assume that unit number is less than 10. */
87447584Smccanne 	*d++ = ifp->if_unit + '0';
87547584Smccanne 	*d = '\0';
87647584Smccanne }
87747584Smccanne 
87847584Smccanne /*
87951425Smccanne  * The new select interface passes down the proc pointer; the old select
88051425Smccanne  * stubs had to grab it out of the user struct.  This glue allows either case.
88151425Smccanne  */
88251425Smccanne #if BSD >= 199103
88351425Smccanne #define bpf_select bpfselect
88451425Smccanne #else
88551425Smccanne int
88651425Smccanne bpfselect(dev, rw)
88751425Smccanne 	register dev_t dev;
88851425Smccanne 	int rw;
88951425Smccanne {
890*53947Smccanne 	return (bpf_select(dev, rw, u.u_procp));
89151425Smccanne }
89251425Smccanne #endif
89351425Smccanne 
89451425Smccanne /*
89547584Smccanne  * Support for select() system call
89647584Smccanne  * Inspired by the code in tty.c for the same purpose.
89747584Smccanne  *
898*53947Smccanne  * Return true iff the specific operation will not block indefinitely.
899*53947Smccanne  * Otherwise, return false but make a note that a selwakeup() must be done.
90047584Smccanne  */
90147584Smccanne int
90251425Smccanne bpf_select(dev, rw, p)
90347584Smccanne 	register dev_t dev;
90447584Smccanne 	int rw;
90548932Smccanne 	struct proc *p;
90647584Smccanne {
90747584Smccanne 	register struct bpf_d *d;
90847584Smccanne 	register int s;
909*53947Smccanne 
91047584Smccanne 	if (rw != FREAD)
91148932Smccanne 		return (0);
91247584Smccanne 	/*
91347584Smccanne 	 * An imitation of the FIONREAD ioctl code.
91447584Smccanne 	 */
91547584Smccanne 	d = &bpf_dtab[minor(dev)];
916*53947Smccanne 
91747584Smccanne 	s = splimp();
91849723Smccanne 	if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
91947584Smccanne 		/*
92047584Smccanne 		 * There is data waiting.
92147584Smccanne 		 */
92247584Smccanne 		splx(s);
92348932Smccanne 		return (1);
92447584Smccanne 	}
925*53947Smccanne #if BSD >= 199103
926*53947Smccanne 	selrecord(p, &d->bd_sel);
927*53947Smccanne #else
92847584Smccanne 	/*
92947584Smccanne 	 * No data ready.  If there's already a select() waiting on this
930*53947Smccanne 	 * minor device then this is a collision.  This shouldn't happen
93147584Smccanne 	 * because minors really should not be shared, but if a process
93247584Smccanne 	 * forks while one of these is open, it is possible that both
93347584Smccanne 	 * processes could select on the same descriptor.
93447584Smccanne 	 */
935*53947Smccanne 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
936*53947Smccanne 		d->bd_selcoll = 1;
937*53947Smccanne 	else
938*53947Smccanne 		d->bd_selproc = p;
939*53947Smccanne #endif
940*53947Smccanne 	splx(s);
94148932Smccanne 	return (0);
94247584Smccanne }
94347584Smccanne 
94447584Smccanne /*
945*53947Smccanne  * Incoming linkage from device drivers.  Process the packet pkt, of length
946*53947Smccanne  * pktlen, which is stored in a contiguous buffer.  The packet is parsed
947*53947Smccanne  * by each process' filter, and if accepted, stashed into the corresponding
948*53947Smccanne  * buffer.
94947584Smccanne  */
95047584Smccanne void
95148932Smccanne bpf_tap(arg, pkt, pktlen)
95247584Smccanne 	caddr_t arg;
95348932Smccanne 	register u_char *pkt;
95448932Smccanne 	register u_int pktlen;
95547584Smccanne {
95647584Smccanne 	struct bpf_if *bp;
95747584Smccanne 	register struct bpf_d *d;
95847584Smccanne 	register u_int slen;
95947584Smccanne 	/*
96047584Smccanne 	 * Note that the ipl does not have to be raised at this point.
96147584Smccanne 	 * The only problem that could arise here is that if two different
96247584Smccanne 	 * interfaces shared any data.  This is not the case.
96347584Smccanne 	 */
96447584Smccanne 	bp = (struct bpf_if *)arg;
96547584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
96647584Smccanne 		++d->bd_rcount;
96749202Smccanne 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
96847584Smccanne 		if (slen != 0)
96949202Smccanne 			catchpacket(d, pkt, pktlen, slen, bcopy);
97047584Smccanne 	}
97147584Smccanne }
97247584Smccanne 
97347584Smccanne /*
97447584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
97547584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
97647584Smccanne  */
97747584Smccanne static void
97849202Smccanne bpf_mcopy(src, dst, len)
97947584Smccanne 	u_char *src;
98047584Smccanne 	u_char *dst;
98147584Smccanne 	register int len;
98247584Smccanne {
98347584Smccanne 	register struct mbuf *m = (struct mbuf *)src;
98447584Smccanne 	register unsigned count;
98547584Smccanne 
98647584Smccanne 	while (len > 0) {
98747584Smccanne 		if (m == 0)
98849202Smccanne 			panic("bpf_mcopy");
98947584Smccanne 		count = MIN(m->m_len, len);
99049202Smccanne 		bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
99149202Smccanne 		m = m->m_next;
99249202Smccanne 		dst += count;
99347584Smccanne 		len -= count;
99447584Smccanne 	}
99547584Smccanne }
99647584Smccanne 
99747584Smccanne /*
998*53947Smccanne  * Incoming linkage from device drivers, when packet is in an mbuf chain.
99947584Smccanne  */
100047584Smccanne void
100149202Smccanne bpf_mtap(arg, m)
100247584Smccanne 	caddr_t arg;
100349202Smccanne 	struct mbuf *m;
100447584Smccanne {
100547584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
100647584Smccanne 	struct bpf_d *d;
100749202Smccanne 	u_int pktlen, slen;
100849202Smccanne 	struct mbuf *m0;
100947584Smccanne 
101048932Smccanne 	pktlen = 0;
101151425Smccanne 	for (m0 = m; m0 != 0; m0 = m0->m_next)
101249202Smccanne 		pktlen += m0->m_len;
101349723Smccanne 
101447584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
101547584Smccanne 		++d->bd_rcount;
101649202Smccanne 		slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
101747584Smccanne 		if (slen != 0)
101849202Smccanne 			catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
101947584Smccanne 	}
102047584Smccanne }
102147584Smccanne 
102247584Smccanne /*
102349202Smccanne  * Move the packet data from interface memory (pkt) into the
102447584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
1025*53947Smccanne  * otherwise 0.  "copy" is the routine called to do the actual data
102651425Smccanne  * transfer.  bcopy is passed in to copy contiguous chunks, while
102751425Smccanne  * bpf_mcopy is passed in to copy mbuf chains.  In the latter case,
102851425Smccanne  * pkt is really an mbuf.
102947584Smccanne  */
103047584Smccanne static void
103148932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn)
103248932Smccanne 	register struct bpf_d *d;
103348932Smccanne 	register u_char *pkt;
103448932Smccanne 	register u_int pktlen, snaplen;
103548932Smccanne 	register void (*cpfn)();
103647584Smccanne {
103748932Smccanne 	register struct bpf_hdr *hp;
103848932Smccanne 	register int totlen, curlen;
103948932Smccanne 	register int hdrlen = d->bd_bif->bif_hdrlen;
104047584Smccanne 	/*
104147584Smccanne 	 * Figure out how many bytes to move.  If the packet is
104247584Smccanne 	 * greater or equal to the snapshot length, transfer that
104347584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
104448932Smccanne 	 * we hit the buffer size limit).
104547584Smccanne 	 */
104650082Smccanne 	totlen = hdrlen + MIN(snaplen, pktlen);
104750082Smccanne 	if (totlen > d->bd_bufsize)
104850082Smccanne 		totlen = d->bd_bufsize;
104947584Smccanne 
105047584Smccanne 	/*
105147584Smccanne 	 * Round up the end of the previous packet to the next longword.
105247584Smccanne 	 */
105348932Smccanne 	curlen = BPF_WORDALIGN(d->bd_slen);
105448932Smccanne 	if (curlen + totlen > d->bd_bufsize) {
105547584Smccanne 		/*
105647584Smccanne 		 * This packet will overflow the storage buffer.
105748932Smccanne 		 * Rotate the buffers if we can, then wakeup any
105848932Smccanne 		 * pending reads.
105947584Smccanne 		 */
106047584Smccanne 		if (d->bd_fbuf == 0) {
1061*53947Smccanne 			/*
1062*53947Smccanne 			 * We haven't completed the previous read yet,
106348932Smccanne 			 * so drop the packet.
106447584Smccanne 			 */
106547584Smccanne 			++d->bd_dcount;
106647584Smccanne 			return;
106747584Smccanne 		}
106848932Smccanne 		ROTATE_BUFFERS(d);
106947584Smccanne 		bpf_wakeup(d);
107048932Smccanne 		curlen = 0;
107147584Smccanne 	}
1072*53947Smccanne 	else if (d->bd_immediate)
107347584Smccanne 		/*
107447584Smccanne 		 * Immediate mode is set.  A packet arrived so any
107547584Smccanne 		 * reads should be woken up.
107647584Smccanne 		 */
107747584Smccanne 		bpf_wakeup(d);
107848932Smccanne 
107947584Smccanne 	/*
108047584Smccanne 	 * Append the bpf header.
108147584Smccanne 	 */
108248932Smccanne 	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
108351425Smccanne #if BSD >= 199103
108447584Smccanne 	microtime(&hp->bh_tstamp);
1085*53947Smccanne #elif defined(sun)
1086*53947Smccanne 	uniqtime(&hp->bh_tstamp);
108747584Smccanne #else
108847584Smccanne 	hp->bh_tstamp = time;
108947584Smccanne #endif
109048932Smccanne 	hp->bh_datalen = pktlen;
109147584Smccanne 	hp->bh_hdrlen = hdrlen;
109247584Smccanne 	/*
109348932Smccanne 	 * Copy the packet data into the store buffer and update its length.
109447584Smccanne 	 */
109548932Smccanne 	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
109648932Smccanne 	d->bd_slen = curlen + totlen;
109747584Smccanne }
109847584Smccanne 
1099*53947Smccanne /*
110047584Smccanne  * Initialize all nonzero fields of a descriptor.
110147584Smccanne  */
110247584Smccanne static int
1103*53947Smccanne bpf_allocbufs(d)
110447584Smccanne 	register struct bpf_d *d;
110547584Smccanne {
110648932Smccanne 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
110748932Smccanne 	if (d->bd_fbuf == 0)
110848932Smccanne 		return (ENOBUFS);
110947584Smccanne 
111048932Smccanne 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
111148932Smccanne 	if (d->bd_sbuf == 0) {
111248932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
111348932Smccanne 		return (ENOBUFS);
111447584Smccanne 	}
111548932Smccanne 	d->bd_slen = 0;
111648932Smccanne 	d->bd_hlen = 0;
111748932Smccanne 	return (0);
111847584Smccanne }
111947584Smccanne 
112047584Smccanne /*
112151425Smccanne  * Free buffers currently in use by a descriptor.
112251425Smccanne  * Called on close.
112347584Smccanne  */
1124*53947Smccanne static void
112551425Smccanne bpf_freed(d)
112651425Smccanne 	register struct bpf_d *d;
112751425Smccanne {
112851425Smccanne 	/*
112951425Smccanne 	 * We don't need to lock out interrupts since this descriptor has
1130*53947Smccanne 	 * been detached from its interface and it yet hasn't been marked
113151425Smccanne 	 * free.
113251425Smccanne 	 */
1133*53947Smccanne 	if (d->bd_sbuf != 0) {
1134*53947Smccanne 		free(d->bd_sbuf, M_DEVBUF);
1135*53947Smccanne 		if (d->bd_hbuf != 0)
1136*53947Smccanne 			free(d->bd_hbuf, M_DEVBUF);
1137*53947Smccanne 		if (d->bd_fbuf != 0)
1138*53947Smccanne 			free(d->bd_fbuf, M_DEVBUF);
1139*53947Smccanne 	}
114051425Smccanne 	if (d->bd_filter)
114151425Smccanne 		free((caddr_t)d->bd_filter, M_DEVBUF);
1142*53947Smccanne 
114351425Smccanne 	D_MARKFREE(d);
114451425Smccanne }
114551425Smccanne 
114651425Smccanne /*
114751425Smccanne  * Attach an interface to bpf.  driverp is a pointer to a (struct bpf_if *)
114851425Smccanne  * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
114951425Smccanne  * size of the link header (variable length headers not yet supported).
115051425Smccanne  */
115147584Smccanne void
115249202Smccanne bpfattach(driverp, ifp, dlt, hdrlen)
115347584Smccanne 	caddr_t *driverp;
115447584Smccanne 	struct ifnet *ifp;
115549202Smccanne 	u_int dlt, hdrlen;
115647584Smccanne {
115747584Smccanne 	struct bpf_if *bp;
115847584Smccanne 	int i;
115951425Smccanne #if BSD < 199103
116051425Smccanne 	static struct bpf_if bpf_ifs[NBPFILTER];
116151425Smccanne 	static int bpfifno;
116247584Smccanne 
116351425Smccanne 	bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0;
116451425Smccanne #else
116549202Smccanne 	bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
116651425Smccanne #endif
116749202Smccanne 	if (bp == 0)
116849202Smccanne 		panic("bpfattach");
116947584Smccanne 
117047584Smccanne 	bp->bif_dlist = 0;
117147584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
117247584Smccanne 	bp->bif_ifp = ifp;
117349202Smccanne 	bp->bif_dlt = dlt;
117447584Smccanne 
117549202Smccanne 	bp->bif_next = bpf_iflist;
117649202Smccanne 	bpf_iflist = bp;
117749202Smccanne 
117848932Smccanne 	*bp->bif_driverp = 0;
117948932Smccanne 
118047584Smccanne 	/*
118147584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
1182*53947Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
1183*53947Smccanne 	 * that the network layer header begins on a longword boundary (for
118447584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
118547584Smccanne 	 */
118649202Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
118747584Smccanne 
118847584Smccanne 	/*
118947584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
119047584Smccanne 	 */
119147584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
119247584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
119347584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
119447584Smccanne 
119547584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
119647584Smccanne }
119747584Smccanne 
119851425Smccanne #if BSD >= 199103
119948967Smccanne /* XXX This routine belongs in net/if.c. */
120048932Smccanne /*
1201*53947Smccanne  * Set/clear promiscuous mode on interface ifp based on the truth value
120248932Smccanne  * of pswitch.  The calls are reference counted so that only the first
1203*53947Smccanne  * "on" request actually has an effect, as does the final "off" request.
1204*53947Smccanne  * Results are undefined if the "off" and "on" requests are not matched.
120548932Smccanne  */
120648932Smccanne int
120748932Smccanne ifpromisc(ifp, pswitch)
120848932Smccanne 	struct ifnet *ifp;
120948932Smccanne 	int pswitch;
121048932Smccanne {
121149726Smccanne 	struct ifreq ifr;
1212*53947Smccanne 	/*
121348932Smccanne 	 * If the device is not configured up, we cannot put it in
121448932Smccanne 	 * promiscuous mode.
121548932Smccanne 	 */
121648932Smccanne 	if ((ifp->if_flags & IFF_UP) == 0)
121748932Smccanne 		return (ENETDOWN);
121848932Smccanne 
121948932Smccanne 	if (pswitch) {
122048932Smccanne 		if (ifp->if_pcount++ != 0)
122148932Smccanne 			return (0);
122248932Smccanne 		ifp->if_flags |= IFF_PROMISC;
122348932Smccanne 	} else {
122448932Smccanne 		if (--ifp->if_pcount > 0)
122548932Smccanne 			return (0);
122648932Smccanne 		ifp->if_flags &= ~IFF_PROMISC;
122748932Smccanne 	}
122849726Smccanne 	ifr.ifr_flags = ifp->if_flags;
122949726Smccanne 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
123048932Smccanne }
123151425Smccanne #endif
123248932Smccanne 
123351425Smccanne #if BSD < 199103
123451425Smccanne /*
123551425Smccanne  * Allocate some memory for bpf.  This is temporary SunOS support, and
1236*53947Smccanne  * is admittedly a hack.
123751425Smccanne  * If resources unavaiable, return 0.
123851425Smccanne  */
123951425Smccanne static caddr_t
124051425Smccanne bpf_alloc(size, canwait)
124151425Smccanne 	register int size;
124251425Smccanne 	register int canwait;
124351425Smccanne {
124451425Smccanne 	register struct mbuf *m;
124551425Smccanne 
124651425Smccanne 	if ((unsigned)size > (MCLBYTES-8))
124751425Smccanne 		return 0;
124851425Smccanne 
124951425Smccanne 	MGET(m, canwait, MT_DATA);
125051425Smccanne 	if (m == 0)
125151425Smccanne 		return 0;
125251425Smccanne 	if ((unsigned)size > (MLEN-8)) {
125351425Smccanne 		MCLGET(m);
125451425Smccanne 		if (m->m_len != MCLBYTES) {
125551425Smccanne 			m_freem(m);
125651425Smccanne 			return 0;
125751425Smccanne 		}
125851425Smccanne 	}
125951425Smccanne 	*mtod(m, struct mbuf **) = m;
126051425Smccanne 	return mtod(m, caddr_t) + 8;
126151425Smccanne }
126251425Smccanne #endif
126351425Smccanne #endif
1264