xref: /csrg-svn/sys/net/bpf.c (revision 59122)
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*59122Storek  *      @(#)bpf.c	7.14 (Berkeley) 04/17/93
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
2554970Smckusick #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>
3253947Smccanne #include <sys/time.h>
3348932Smccanne #include <sys/proc.h>
3447584Smccanne #include <sys/user.h>
3547584Smccanne #include <sys/ioctl.h>
3647584Smccanne #include <sys/map.h>
3747584Smccanne 
3847584Smccanne #include <sys/file.h>
3951425Smccanne #if defined(sparc) && BSD < 199103
4047584Smccanne #include <sys/stream.h>
4147584Smccanne #endif
4247584Smccanne #include <sys/tty.h>
4347584Smccanne #include <sys/uio.h>
4447584Smccanne 
4547584Smccanne #include <sys/protosw.h>
4647584Smccanne #include <sys/socket.h>
4747584Smccanne #include <net/if.h>
4847584Smccanne 
4947584Smccanne #include <net/bpf.h>
5047584Smccanne #include <net/bpfdesc.h>
5147584Smccanne 
5247584Smccanne #include <sys/errno.h>
5347584Smccanne 
5447584Smccanne #include <netinet/in.h>
5547584Smccanne #include <netinet/if_ether.h>
5647584Smccanne #include <sys/kernel.h>
5747584Smccanne 
5851425Smccanne /*
5951425Smccanne  * Older BSDs don't have kernel malloc.
6051425Smccanne  */
6151425Smccanne #if BSD < 199103
6251425Smccanne extern bcopy();
6351425Smccanne static caddr_t bpf_alloc();
6453947Smccanne #include <net/bpf_compat.h>
6551425Smccanne #define BPF_BUFSIZE (MCLBYTES-8)
6653947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)
6751425Smccanne #else
6851425Smccanne #define BPF_BUFSIZE 4096
6953947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)
7051425Smccanne #endif
7151425Smccanne 
7247584Smccanne #define PRINET  26			/* interruptible */
7347584Smccanne 
7447584Smccanne /*
7548932Smccanne  * The default read buffer size is patchable.
7648932Smccanne  */
7751425Smccanne int bpf_bufsize = BPF_BUFSIZE;
7848932Smccanne 
7948932Smccanne /*
8049202Smccanne  *  bpf_iflist is the list of interfaces; each corresponds to an ifnet
8149202Smccanne  *  bpf_dtab holds the descriptors, indexed by minor device #
8247584Smccanne  */
8353947Smccanne struct bpf_if	*bpf_iflist;
8453947Smccanne struct bpf_d	bpf_dtab[NBPFILTER];
8547584Smccanne 
86*59122Storek #if BSD >= 199207
87*59122Storek /*
88*59122Storek  * bpfilterattach() is called at boot time in new systems.  We do
89*59122Storek  * nothing here since old systems will not call this.
90*59122Storek  */
91*59122Storek /* ARGSUSED */
92*59122Storek void
93*59122Storek bpfilterattach(n)
94*59122Storek 	int n;
95*59122Storek {
96*59122Storek }
97*59122Storek #endif
98*59122Storek 
9947584Smccanne static void	bpf_ifname();
10047584Smccanne static void	catchpacket();
10153947Smccanne static void	bpf_freed();
10247584Smccanne static int	bpf_setif();
10347584Smccanne static int	bpf_initd();
10453947Smccanne static int	bpf_allocbufs();
10547584Smccanne 
10647584Smccanne static int
10755289Smckusick bpf_movein(uio, linktype, mp, sockp, datlen)
10847584Smccanne 	register struct uio *uio;
10955289Smckusick 	int linktype, *datlen;
11047584Smccanne 	register struct mbuf **mp;
11147584Smccanne 	register struct sockaddr *sockp;
11247584Smccanne {
11347584Smccanne 	struct mbuf *m;
11447584Smccanne 	int error;
11547584Smccanne 	int len;
11647584Smccanne 	int hlen;
11747584Smccanne 
11847584Smccanne 	/*
11947584Smccanne 	 * Build a sockaddr based on the data link layer type.
12047584Smccanne 	 * We do this at this level because the ethernet header
12147584Smccanne 	 * is copied directly into the data field of the sockaddr.
12247584Smccanne 	 * In the case of SLIP, there is no header and the packet
12347584Smccanne 	 * is forwarded as is.
12447584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
12547584Smccanne 	 * for the link level header.
12647584Smccanne 	 */
12747584Smccanne 	switch (linktype) {
12853947Smccanne 
12947584Smccanne 	case DLT_SLIP:
13047584Smccanne 		sockp->sa_family = AF_INET;
13147584Smccanne 		hlen = 0;
13247584Smccanne 		break;
13347584Smccanne 
13447584Smccanne 	case DLT_EN10MB:
13547584Smccanne 		sockp->sa_family = AF_UNSPEC;
13647584Smccanne 		/* XXX Would MAXLINKHDR be better? */
13747584Smccanne 		hlen = sizeof(struct ether_header);
13847584Smccanne 		break;
13947584Smccanne 
14053947Smccanne 	case DLT_FDDI:
14147584Smccanne 		sockp->sa_family = AF_UNSPEC;
14247584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
14347584Smccanne 		hlen = 24;
14447584Smccanne 		break;
14547584Smccanne 
14653947Smccanne 	case DLT_NULL:
14753947Smccanne 		sockp->sa_family = AF_UNSPEC;
14853947Smccanne 		hlen = 0;
14953947Smccanne 		break;
15053947Smccanne 
15147584Smccanne 	default:
15248932Smccanne 		return (EIO);
15347584Smccanne 	}
15447584Smccanne 
15547584Smccanne 	len = uio->uio_resid;
15655289Smckusick 	*datlen = len - hlen;
15747584Smccanne 	if ((unsigned)len > MCLBYTES)
15848932Smccanne 		return (EIO);
15947584Smccanne 
16047584Smccanne 	MGET(m, M_WAIT, MT_DATA);
16147584Smccanne 	if (m == 0)
16248932Smccanne 		return (ENOBUFS);
16347584Smccanne 	if (len > MLEN) {
16451425Smccanne #if BSD >= 199103
16548932Smccanne 		MCLGET(m, M_WAIT);
16648932Smccanne 		if ((m->m_flags & M_EXT) == 0) {
16751425Smccanne #else
16851425Smccanne 		MCLGET(m);
16953947Smccanne 		if (m->m_len != MCLBYTES) {
17051425Smccanne #endif
17153947Smccanne 			error = ENOBUFS;
17247584Smccanne 			goto bad;
17347584Smccanne 		}
17447584Smccanne 	}
17547584Smccanne 	m->m_len = len;
17647584Smccanne 	*mp = m;
17747584Smccanne 	/*
17847584Smccanne 	 * Make room for link header.
17947584Smccanne 	 */
18053947Smccanne 	if (hlen != 0) {
18147584Smccanne 		m->m_len -= hlen;
18251425Smccanne #if BSD >= 199103
18348932Smccanne 		m->m_data += hlen; /* XXX */
18451425Smccanne #else
18551425Smccanne 		m->m_off += hlen;
18651425Smccanne #endif
18753947Smccanne 		error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
18847584Smccanne 		if (error)
18947584Smccanne 			goto bad;
19047584Smccanne 	}
19153947Smccanne 	error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
19253947Smccanne 	if (!error)
19348932Smccanne 		return (0);
19447584Smccanne  bad:
19547584Smccanne 	m_freem(m);
19648932Smccanne 	return (error);
19747584Smccanne }
19847584Smccanne 
19947584Smccanne /*
20051425Smccanne  * Attach file to the bpf interface, i.e. make d listen on bp.
20147584Smccanne  * Must be called at splimp.
20247584Smccanne  */
20347584Smccanne static void
20447584Smccanne bpf_attachd(d, bp)
20547584Smccanne 	struct bpf_d *d;
20647584Smccanne 	struct bpf_if *bp;
20747584Smccanne {
20851425Smccanne 	/*
20951425Smccanne 	 * Point d at bp, and add d to the interface's list of listeners.
21051425Smccanne 	 * Finally, point the driver's bpf cookie at the interface so
21151425Smccanne 	 * it will divert packets to bpf.
21251425Smccanne 	 */
21347584Smccanne 	d->bd_bif = bp;
21447584Smccanne 	d->bd_next = bp->bif_dlist;
21547584Smccanne 	bp->bif_dlist = d;
21647584Smccanne 
21747584Smccanne 	*bp->bif_driverp = bp;
21847584Smccanne }
21947584Smccanne 
22051425Smccanne /*
22151425Smccanne  * Detach a file from its interface.
22251425Smccanne  */
22347584Smccanne static void
22447584Smccanne bpf_detachd(d)
22547584Smccanne 	struct bpf_d *d;
22647584Smccanne {
22747584Smccanne 	struct bpf_d **p;
22847584Smccanne 	struct bpf_if *bp;
22947584Smccanne 
23047584Smccanne 	bp = d->bd_bif;
23147584Smccanne 	/*
23247584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
23347584Smccanne 	 * If so, turn it off.
23447584Smccanne 	 */
23547584Smccanne 	if (d->bd_promisc) {
23647584Smccanne 		d->bd_promisc = 0;
23747584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
23847584Smccanne 			/*
23947584Smccanne 			 * Something is really wrong if we were able to put
24047584Smccanne 			 * the driver into promiscuous mode, but can't
24147584Smccanne 			 * take it out.
24247584Smccanne 			 */
24351425Smccanne 			panic("bpf: ifpromisc failed");
24447584Smccanne 	}
24551425Smccanne 	/* Remove d from the interface's descriptor list. */
24647584Smccanne 	p = &bp->bif_dlist;
24747584Smccanne 	while (*p != d) {
24847584Smccanne 		p = &(*p)->bd_next;
24947584Smccanne 		if (*p == 0)
25047584Smccanne 			panic("bpf_detachd: descriptor not in list");
25147584Smccanne 	}
25247584Smccanne 	*p = (*p)->bd_next;
25347584Smccanne 	if (bp->bif_dlist == 0)
25447584Smccanne 		/*
25547584Smccanne 		 * Let the driver know that there are no more listeners.
25647584Smccanne 		 */
25747584Smccanne 		*d->bd_bif->bif_driverp = 0;
25847584Smccanne 	d->bd_bif = 0;
25947584Smccanne }
26047584Smccanne 
26147584Smccanne 
26247584Smccanne /*
26353947Smccanne  * Mark a descriptor free by making it point to itself.
26447584Smccanne  * This is probably cheaper than marking with a constant since
26547584Smccanne  * the address should be in a register anyway.
26647584Smccanne  */
26747584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
26847584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
26947584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
27047584Smccanne 
27147584Smccanne /*
27253947Smccanne  * Open ethernet device.  Returns ENXIO for illegal minor device number,
27353947Smccanne  * EBUSY if file is open by another process.
27447584Smccanne  */
27547584Smccanne /* ARGSUSED */
27647584Smccanne int
27747584Smccanne bpfopen(dev, flag)
27847584Smccanne 	dev_t dev;
27947584Smccanne 	int flag;
28047584Smccanne {
28147584Smccanne 	register struct bpf_d *d;
28253947Smccanne 
28347584Smccanne 	if (minor(dev) >= NBPFILTER)
28448932Smccanne 		return (ENXIO);
28547584Smccanne 	/*
28647584Smccanne 	 * Each minor can be opened by only one process.  If the requested
28747584Smccanne 	 * minor is in use, return EBUSY.
28847584Smccanne 	 */
28947584Smccanne 	d = &bpf_dtab[minor(dev)];
29053947Smccanne 	if (!D_ISFREE(d))
29148932Smccanne 		return (EBUSY);
29247584Smccanne 
29353947Smccanne 	/* Mark "free" and do most initialization. */
29453947Smccanne 	bzero((char *)d, sizeof(*d));
29553947Smccanne 	d->bd_bufsize = bpf_bufsize;
29653947Smccanne 
29748932Smccanne 	return (0);
29847584Smccanne }
29947584Smccanne 
30047584Smccanne /*
30147584Smccanne  * Close the descriptor by detaching it from its interface,
30247584Smccanne  * deallocating its buffers, and marking it free.
30347584Smccanne  */
30447584Smccanne /* ARGSUSED */
30553947Smccanne int
30647584Smccanne bpfclose(dev, flag)
30747584Smccanne 	dev_t dev;
30847584Smccanne 	int flag;
30947584Smccanne {
31047584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
31153947Smccanne 	register int s;
31247584Smccanne 
31347584Smccanne 	s = splimp();
31447584Smccanne 	if (d->bd_bif)
31547584Smccanne 		bpf_detachd(d);
31647584Smccanne 	splx(s);
31753947Smccanne 	bpf_freed(d);
31847584Smccanne 
31953947Smccanne 	return (0);
32047584Smccanne }
32147584Smccanne 
32253947Smccanne /*
32353947Smccanne  * Support for SunOS, which does not have tsleep.
32453947Smccanne  */
32551425Smccanne #if BSD < 199103
32651425Smccanne static
32751425Smccanne bpf_timeout(arg)
32851425Smccanne 	caddr_t arg;
32951425Smccanne {
33051425Smccanne 	struct bpf_d *d = (struct bpf_d *)arg;
33151425Smccanne 	d->bd_timedout = 1;
33251425Smccanne 	wakeup(arg);
33351425Smccanne }
33451425Smccanne 
33553947Smccanne #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan)
33653947Smccanne 
33753947Smccanne int
33853947Smccanne bpf_sleep(d)
33953947Smccanne 	register struct bpf_d *d;
34051425Smccanne {
34153947Smccanne 	register int rto = d->bd_rtout;
34253947Smccanne 	register int st;
34351425Smccanne 
34453947Smccanne 	if (rto != 0) {
34551425Smccanne 		d->bd_timedout = 0;
34653947Smccanne 		timeout(bpf_timeout, (caddr_t)d, rto);
34751425Smccanne 	}
34853947Smccanne 	st = sleep((caddr_t)d, PRINET|PCATCH);
34953947Smccanne 	if (rto != 0) {
35053947Smccanne 		if (d->bd_timedout == 0)
35153947Smccanne 			untimeout(bpf_timeout, (caddr_t)d);
35253947Smccanne 		else if (st == 0)
35351425Smccanne 			return EWOULDBLOCK;
35451425Smccanne 	}
35553947Smccanne 	return (st != 0) ? EINTR : 0;
35651425Smccanne }
35753947Smccanne #else
35853947Smccanne #define BPF_SLEEP tsleep
35951425Smccanne #endif
36051425Smccanne 
36147584Smccanne /*
36248932Smccanne  * Rotate the packet buffers in descriptor d.  Move the store buffer
36353947Smccanne  * into the hold slot, and the free buffer into the store slot.
36448932Smccanne  * Zero the length of the new store buffer.
36548932Smccanne  */
36648932Smccanne #define ROTATE_BUFFERS(d) \
36748932Smccanne 	(d)->bd_hbuf = (d)->bd_sbuf; \
36848932Smccanne 	(d)->bd_hlen = (d)->bd_slen; \
36948932Smccanne 	(d)->bd_sbuf = (d)->bd_fbuf; \
37048932Smccanne 	(d)->bd_slen = 0; \
37153947Smccanne 	(d)->bd_fbuf = 0;
37248932Smccanne /*
37347584Smccanne  *  bpfread - read next chunk of packets from buffers
37447584Smccanne  */
37547584Smccanne int
37647584Smccanne bpfread(dev, uio)
37747584Smccanne 	dev_t dev;
37847584Smccanne 	register struct uio *uio;
37947584Smccanne {
38047584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
38147584Smccanne 	int error;
38247584Smccanne 	int s;
38347584Smccanne 
38447584Smccanne 	/*
38553947Smccanne 	 * Restrict application to use a buffer the same size as
38647584Smccanne 	 * as kernel buffers.
38747584Smccanne 	 */
38848932Smccanne 	if (uio->uio_resid != d->bd_bufsize)
38949202Smccanne 		return (EINVAL);
39047584Smccanne 
39147584Smccanne 	s = splimp();
39247584Smccanne 	/*
39353947Smccanne 	 * If the hold buffer is empty, then do a timed sleep, which
39453947Smccanne 	 * ends when the timeout expires or when enough packets
39553947Smccanne 	 * have arrived to fill the store buffer.
39647584Smccanne 	 */
39747584Smccanne 	while (d->bd_hbuf == 0) {
39848932Smccanne 		if (d->bd_immediate && d->bd_slen != 0) {
39947584Smccanne 			/*
40047584Smccanne 			 * A packet(s) either arrived since the previous
40147584Smccanne 			 * read or arrived while we were asleep.
40247584Smccanne 			 * Rotate the buffers and return what's here.
40347584Smccanne 			 */
40448932Smccanne 			ROTATE_BUFFERS(d);
40547584Smccanne 			break;
40647584Smccanne 		}
40753947Smccanne 		error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf",
40853947Smccanne 				  d->bd_rtout);
40948932Smccanne 		if (error == EINTR || error == ERESTART) {
41048932Smccanne 			splx(s);
41148932Smccanne 			return (error);
41247584Smccanne 		}
41348932Smccanne 		if (error == EWOULDBLOCK) {
41447584Smccanne 			/*
41547584Smccanne 			 * On a timeout, return what's in the buffer,
41648932Smccanne 			 * which may be nothing.  If there is something
41748932Smccanne 			 * in the store buffer, we can rotate the buffers.
41847584Smccanne 			 */
41947584Smccanne 			if (d->bd_hbuf)
42047584Smccanne 				/*
42153947Smccanne 				 * We filled up the buffer in between
42247584Smccanne 				 * getting the timeout and arriving
42347584Smccanne 				 * here, so we don't need to rotate.
42447584Smccanne 				 */
42547584Smccanne 				break;
42647584Smccanne 
42748932Smccanne 			if (d->bd_slen == 0) {
42847584Smccanne 				splx(s);
42948932Smccanne 				return (0);
43047584Smccanne 			}
43148932Smccanne 			ROTATE_BUFFERS(d);
43247584Smccanne 			break;
43347584Smccanne 		}
43447584Smccanne 	}
43547584Smccanne 	/*
43647584Smccanne 	 * At this point, we know we have something in the hold slot.
43747584Smccanne 	 */
43847584Smccanne 	splx(s);
43953947Smccanne 
44053947Smccanne 	/*
44147584Smccanne 	 * Move data from hold buffer into user space.
44247584Smccanne 	 * We know the entire buffer is transferred since
44348932Smccanne 	 * we checked above that the read buffer is bpf_bufsize bytes.
44447584Smccanne 	 */
44553947Smccanne 	error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
44653947Smccanne 
44747584Smccanne 	s = splimp();
44848932Smccanne 	d->bd_fbuf = d->bd_hbuf;
44948932Smccanne 	d->bd_hbuf = 0;
45053947Smccanne 	d->bd_hlen = 0;
45147584Smccanne 	splx(s);
45253947Smccanne 
45348932Smccanne 	return (error);
45447584Smccanne }
45547584Smccanne 
45647584Smccanne 
45747584Smccanne /*
45853947Smccanne  * If there are processes sleeping on this descriptor, wake them up.
45947584Smccanne  */
46047584Smccanne static inline void
46147584Smccanne bpf_wakeup(d)
46247584Smccanne 	register struct bpf_d *d;
46347584Smccanne {
46448932Smccanne 	wakeup((caddr_t)d);
46553947Smccanne #if BSD >= 199103
46653947Smccanne 	selwakeup(&d->bd_sel);
46753947Smccanne 	/* XXX */
46853947Smccanne 	d->bd_sel.si_pid = 0;
46953947Smccanne #else
47053947Smccanne 	if (d->bd_selproc) {
47153947Smccanne 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
47253947Smccanne 		d->bd_selcoll = 0;
47353947Smccanne 		d->bd_selproc = 0;
47453947Smccanne 	}
47553947Smccanne #endif
47647584Smccanne }
47747584Smccanne 
47847584Smccanne int
47947584Smccanne bpfwrite(dev, uio)
48047584Smccanne 	dev_t dev;
48147584Smccanne 	struct uio *uio;
48247584Smccanne {
48347584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
48447584Smccanne 	struct ifnet *ifp;
48547584Smccanne 	struct mbuf *m;
48647584Smccanne 	int error, s;
48747584Smccanne 	static struct sockaddr dst;
48855289Smckusick 	int datlen;
48947584Smccanne 
49047584Smccanne 	if (d->bd_bif == 0)
49148932Smccanne 		return (ENXIO);
49247584Smccanne 
49347584Smccanne 	ifp = d->bd_bif->bif_ifp;
49447584Smccanne 
49547584Smccanne 	if (uio->uio_resid == 0)
49648932Smccanne 		return (0);
49747584Smccanne 
49855289Smckusick 	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen);
49947584Smccanne 	if (error)
50048932Smccanne 		return (error);
50147584Smccanne 
50255289Smckusick 	if (datlen > ifp->if_mtu)
50355289Smckusick 		return (EMSGSIZE);
50455289Smckusick 
50547584Smccanne 	s = splnet();
50651425Smccanne #if BSD >= 199103
50753947Smccanne 	error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
50851425Smccanne #else
50947584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
51051425Smccanne #endif
51147584Smccanne 	splx(s);
51247584Smccanne 	/*
51353947Smccanne 	 * The driver frees the mbuf.
51447584Smccanne 	 */
51548932Smccanne 	return (error);
51647584Smccanne }
51747584Smccanne 
51847584Smccanne /*
51953947Smccanne  * Reset a descriptor by flushing its packet buffer and clearing the
52053947Smccanne  * receive and drop counts.  Should be called at splimp.
52147584Smccanne  */
52247584Smccanne static void
52347584Smccanne reset_d(d)
52447584Smccanne 	struct bpf_d *d;
52547584Smccanne {
52647584Smccanne 	if (d->bd_hbuf) {
52747584Smccanne 		/* Free the hold buffer. */
52847584Smccanne 		d->bd_fbuf = d->bd_hbuf;
52947584Smccanne 		d->bd_hbuf = 0;
53047584Smccanne 	}
53148932Smccanne 	d->bd_slen = 0;
53253947Smccanne 	d->bd_hlen = 0;
53347584Smccanne 	d->bd_rcount = 0;
53447584Smccanne 	d->bd_dcount = 0;
53547584Smccanne }
53647584Smccanne 
53747584Smccanne /*
53847584Smccanne  *  FIONREAD		Check for read packet available.
53947584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
54047584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
54147584Smccanne  *  BIOCSETF		Set ethernet read filter.
54247584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
54347584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
54449202Smccanne  *  BIOCGDLT		Get link layer type.
54547584Smccanne  *  BIOCGETIF		Get interface name.
54647584Smccanne  *  BIOCSETIF		Set interface.
54747584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
54847584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
54947584Smccanne  *  BIOCGSTATS		Get packet stats.
55047584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
55153947Smccanne  *  BIOCVERSION		Get filter language version.
55247584Smccanne  */
55347584Smccanne /* ARGSUSED */
55447584Smccanne int
55547584Smccanne bpfioctl(dev, cmd, addr, flag)
55647584Smccanne 	dev_t dev;
55747584Smccanne 	int cmd;
55847584Smccanne 	caddr_t addr;
55947584Smccanne 	int flag;
56047584Smccanne {
56147584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
56247584Smccanne 	int s, error = 0;
56347584Smccanne 
56447584Smccanne 	switch (cmd) {
56547584Smccanne 
56647584Smccanne 	default:
56747584Smccanne 		error = EINVAL;
56847584Smccanne 		break;
56947584Smccanne 
57047584Smccanne 	/*
57147584Smccanne 	 * Check for read packet available.
57247584Smccanne 	 */
57347584Smccanne 	case FIONREAD:
57447584Smccanne 		{
57547584Smccanne 			int n;
57653947Smccanne 
57747584Smccanne 			s = splimp();
57848932Smccanne 			n = d->bd_slen;
57953947Smccanne 			if (d->bd_hbuf)
58048932Smccanne 				n += d->bd_hlen;
58147584Smccanne 			splx(s);
58247584Smccanne 
58347584Smccanne 			*(int *)addr = n;
58447584Smccanne 			break;
58547584Smccanne 		}
58647584Smccanne 
58747584Smccanne 	case SIOCGIFADDR:
58847584Smccanne 		{
58947584Smccanne 			struct ifnet *ifp;
59047584Smccanne 
59147584Smccanne 			if (d->bd_bif == 0)
59247584Smccanne 				error = EINVAL;
59347584Smccanne 			else {
59447584Smccanne 				ifp = d->bd_bif->bif_ifp;
59553947Smccanne 				error = (*ifp->if_ioctl)(ifp, cmd, addr);
59647584Smccanne 			}
59747584Smccanne 			break;
59847584Smccanne 		}
59947584Smccanne 
60047584Smccanne 	/*
60147584Smccanne 	 * Get buffer len [for read()].
60247584Smccanne 	 */
60347584Smccanne 	case BIOCGBLEN:
60448932Smccanne 		*(u_int *)addr = d->bd_bufsize;
60547584Smccanne 		break;
60647584Smccanne 
60747584Smccanne 	/*
60853947Smccanne 	 * Set buffer length.
60953947Smccanne 	 */
61053947Smccanne 	case BIOCSBLEN:
61153947Smccanne #if BSD < 199103
61253947Smccanne 		error = EINVAL;
61353947Smccanne #else
61453947Smccanne 		if (d->bd_bif != 0)
61553947Smccanne 			error = EINVAL;
61653947Smccanne 		else {
61753947Smccanne 			register u_int size = *(u_int *)addr;
61853947Smccanne 
61953947Smccanne 			if (size > BPF_MAXBUFSIZE)
62053947Smccanne 				*(u_int *)addr = size = BPF_MAXBUFSIZE;
62153947Smccanne 			else if (size < BPF_MINBUFSIZE)
62253947Smccanne 				*(u_int *)addr = size = BPF_MINBUFSIZE;
62353947Smccanne 			d->bd_bufsize = size;
62453947Smccanne 		}
62553947Smccanne #endif
62653947Smccanne 		break;
62753947Smccanne 
62853947Smccanne 	/*
62951425Smccanne 	 * Set link layer read filter.
63047584Smccanne 	 */
63153947Smccanne 	case BIOCSETF:
63247584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
63347584Smccanne 		break;
63447584Smccanne 
63547584Smccanne 	/*
63647584Smccanne 	 * Flush read packet buffer.
63747584Smccanne 	 */
63847584Smccanne 	case BIOCFLUSH:
63947584Smccanne 		s = splimp();
64047584Smccanne 		reset_d(d);
64147584Smccanne 		splx(s);
64247584Smccanne 		break;
64347584Smccanne 
64447584Smccanne 	/*
64547584Smccanne 	 * Put interface into promiscuous mode.
64647584Smccanne 	 */
64747584Smccanne 	case BIOCPROMISC:
64847584Smccanne 		if (d->bd_bif == 0) {
64947584Smccanne 			/*
65047584Smccanne 			 * No interface attached yet.
65147584Smccanne 			 */
65247584Smccanne 			error = EINVAL;
65347584Smccanne 			break;
65447584Smccanne 		}
65547584Smccanne 		s = splimp();
65647584Smccanne 		if (d->bd_promisc == 0) {
65747584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
65851425Smccanne 			if (error == 0)
65951425Smccanne 				d->bd_promisc = 1;
66047584Smccanne 		}
66147584Smccanne 		splx(s);
66247584Smccanne 		break;
66347584Smccanne 
66447584Smccanne 	/*
66547584Smccanne 	 * Get device parameters.
66647584Smccanne 	 */
66749202Smccanne 	case BIOCGDLT:
66847584Smccanne 		if (d->bd_bif == 0)
66947584Smccanne 			error = EINVAL;
67047584Smccanne 		else
67149202Smccanne 			*(u_int *)addr = d->bd_bif->bif_dlt;
67247584Smccanne 		break;
67347584Smccanne 
67447584Smccanne 	/*
67547584Smccanne 	 * Set interface name.
67647584Smccanne 	 */
67747584Smccanne 	case BIOCGETIF:
67847584Smccanne 		if (d->bd_bif == 0)
67947584Smccanne 			error = EINVAL;
68047584Smccanne 		else
68147584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
68247584Smccanne 		break;
68347584Smccanne 
68447584Smccanne 	/*
68547584Smccanne 	 * Set interface.
68647584Smccanne 	 */
68747584Smccanne 	case BIOCSETIF:
68847584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
68947584Smccanne 		break;
69047584Smccanne 
69147584Smccanne 	/*
69247584Smccanne 	 * Set read timeout.
69347584Smccanne 	 */
69453947Smccanne 	case BIOCSRTIMEOUT:
69547584Smccanne 		{
69647584Smccanne 			struct timeval *tv = (struct timeval *)addr;
69747584Smccanne 			u_long msec;
69847584Smccanne 
69947584Smccanne 			/* Compute number of milliseconds. */
70047584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
70147584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
70247584Smccanne 			   clock has millisecond or greater resolution
70347584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
70447584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
70547584Smccanne 			d->bd_rtout = msec / (tick / 1000);
70647584Smccanne 			break;
70747584Smccanne 		}
70847584Smccanne 
70947584Smccanne 	/*
71047584Smccanne 	 * Get read timeout.
71147584Smccanne 	 */
71253947Smccanne 	case BIOCGRTIMEOUT:
71347584Smccanne 		{
71447584Smccanne 			struct timeval *tv = (struct timeval *)addr;
71547584Smccanne 			u_long msec = d->bd_rtout;
71647584Smccanne 
71747584Smccanne 			msec *= tick / 1000;
71847584Smccanne 			tv->tv_sec = msec / 1000;
71947584Smccanne 			tv->tv_usec = msec % 1000;
72047584Smccanne 			break;
72147584Smccanne 		}
72247584Smccanne 
72347584Smccanne 	/*
72447584Smccanne 	 * Get packet stats.
72547584Smccanne 	 */
72647584Smccanne 	case BIOCGSTATS:
72747584Smccanne 		{
72847584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
72947584Smccanne 
73047584Smccanne 			bs->bs_recv = d->bd_rcount;
73147584Smccanne 			bs->bs_drop = d->bd_dcount;
73247584Smccanne 			break;
73347584Smccanne 		}
73447584Smccanne 
73547584Smccanne 	/*
73647584Smccanne 	 * Set immediate mode.
73747584Smccanne 	 */
73847584Smccanne 	case BIOCIMMEDIATE:
73947584Smccanne 		d->bd_immediate = *(u_int *)addr;
74047584Smccanne 		break;
74153947Smccanne 
74253947Smccanne 	case BIOCVERSION:
74353947Smccanne 		{
74453947Smccanne 			struct bpf_version *bv = (struct bpf_version *)addr;
74553947Smccanne 
74653947Smccanne 			bv->bv_major = BPF_MAJOR_VERSION;
74753947Smccanne 			bv->bv_minor = BPF_MINOR_VERSION;
74853947Smccanne 			break;
74953947Smccanne 		}
75047584Smccanne 	}
75148932Smccanne 	return (error);
75247584Smccanne }
75347584Smccanne 
75453947Smccanne /*
75551425Smccanne  * Set d's packet filter program to fp.  If this file already has a filter,
75648932Smccanne  * free it and replace it.  Returns EINVAL for bogus requests.
75747584Smccanne  */
75847584Smccanne int
75947584Smccanne bpf_setf(d, fp)
76047584Smccanne 	struct bpf_d *d;
76147584Smccanne 	struct bpf_program *fp;
76247584Smccanne {
76348932Smccanne 	struct bpf_insn *fcode, *old;
76447584Smccanne 	u_int flen, size;
76547584Smccanne 	int s;
76647584Smccanne 
76748932Smccanne 	old = d->bd_filter;
76847584Smccanne 	if (fp->bf_insns == 0) {
76947584Smccanne 		if (fp->bf_len != 0)
77048932Smccanne 			return (EINVAL);
77148932Smccanne 		s = splimp();
77248967Smccanne 		d->bd_filter = 0;
77347584Smccanne 		reset_d(d);
77447584Smccanne 		splx(s);
77548967Smccanne 		if (old != 0)
77648932Smccanne 			free((caddr_t)old, M_DEVBUF);
77748932Smccanne 		return (0);
77847584Smccanne 	}
77947584Smccanne 	flen = fp->bf_len;
78048932Smccanne 	if (flen > BPF_MAXINSNS)
78148932Smccanne 		return (EINVAL);
78248932Smccanne 
78347584Smccanne 	size = flen * sizeof(*fp->bf_insns);
78448932Smccanne 	fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
78550417Smccanne 	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
78650417Smccanne 	    bpf_validate(fcode, (int)flen)) {
78748967Smccanne 		s = splimp();
78848932Smccanne 		d->bd_filter = fcode;
78947584Smccanne 		reset_d(d);
79047584Smccanne 		splx(s);
79148967Smccanne 		if (old != 0)
79248932Smccanne 			free((caddr_t)old, M_DEVBUF);
79347584Smccanne 
79448932Smccanne 		return (0);
79547584Smccanne 	}
79648932Smccanne 	free((caddr_t)fcode, M_DEVBUF);
79748932Smccanne 	return (EINVAL);
79847584Smccanne }
79947584Smccanne 
80047584Smccanne /*
80153947Smccanne  * Detach a file from its current interface (if attached at all) and attach
80253947Smccanne  * to the interface indicated by the name stored in ifr.
80351425Smccanne  * Return an errno or 0.
80447584Smccanne  */
80547584Smccanne static int
80647584Smccanne bpf_setif(d, ifr)
80747584Smccanne 	struct bpf_d *d;
80847584Smccanne 	struct ifreq *ifr;
80947584Smccanne {
81047584Smccanne 	struct bpf_if *bp;
81147584Smccanne 	char *cp;
81253947Smccanne 	int unit, s, error;
81347584Smccanne 
81447584Smccanne 	/*
81547584Smccanne 	 * Separate string into name part and unit number.  Put a null
81653947Smccanne 	 * byte at the end of the name part, and compute the number.
81747584Smccanne 	 * If the a unit number is unspecified, the default is 0,
81848932Smccanne 	 * as initialized above.  XXX This should be common code.
81947584Smccanne 	 */
82047584Smccanne 	unit = 0;
82147584Smccanne 	cp = ifr->ifr_name;
82247584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
82347584Smccanne 	while (*cp++) {
82447584Smccanne 		if (*cp >= '0' && *cp <= '9') {
82547584Smccanne 			unit = *cp - '0';
82647584Smccanne 			*cp++ = '\0';
82747584Smccanne 			while (*cp)
82847584Smccanne 				unit = 10 * unit + *cp++ - '0';
82947584Smccanne 			break;
83047584Smccanne 		}
83147584Smccanne 	}
83247584Smccanne 	/*
83347584Smccanne 	 * Look through attached interfaces for the named one.
83447584Smccanne 	 */
83549202Smccanne 	for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
83647584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
83747584Smccanne 
83853947Smccanne 		if (ifp == 0 || unit != ifp->if_unit
83947584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
84047584Smccanne 			continue;
84147584Smccanne 		/*
84253947Smccanne 		 * We found the requested interface.
84347584Smccanne 		 * If it's not up, return an error.
84453947Smccanne 		 * Allocate the packet buffers if we need to.
84553947Smccanne 		 * If we're already attached to requested interface,
84653947Smccanne 		 * just flush the buffer.
84747584Smccanne 		 */
84847584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
84948932Smccanne 			return (ENETDOWN);
85053947Smccanne 
85153947Smccanne 		if (d->bd_sbuf == 0) {
85253947Smccanne 			error = bpf_allocbufs(d);
85353947Smccanne 			if (error != 0)
85453947Smccanne 				return (error);
85553947Smccanne 		}
85647584Smccanne 		s = splimp();
85747584Smccanne 		if (bp != d->bd_bif) {
85847584Smccanne 			if (d->bd_bif)
85953947Smccanne 				/*
86048932Smccanne 				 * Detach if attached to something else.
86147584Smccanne 				 */
86247584Smccanne 				bpf_detachd(d);
86347584Smccanne 
86447584Smccanne 			bpf_attachd(d, bp);
86547584Smccanne 		}
86647584Smccanne 		reset_d(d);
86747584Smccanne 		splx(s);
86848932Smccanne 		return (0);
86947584Smccanne 	}
87047584Smccanne 	/* Not found. */
87148932Smccanne 	return (ENXIO);
87247584Smccanne }
87347584Smccanne 
87447584Smccanne /*
87551425Smccanne  * Convert an interface name plus unit number of an ifp to a single
87651425Smccanne  * name which is returned in the ifr.
87747584Smccanne  */
87847584Smccanne static void
87947584Smccanne bpf_ifname(ifp, ifr)
88047584Smccanne 	struct ifnet *ifp;
88147584Smccanne 	struct ifreq *ifr;
88247584Smccanne {
88347584Smccanne 	char *s = ifp->if_name;
88447584Smccanne 	char *d = ifr->ifr_name;
88547584Smccanne 
88647584Smccanne 	while (*d++ = *s++)
88753947Smccanne 		continue;
88848932Smccanne 	/* XXX Assume that unit number is less than 10. */
88947584Smccanne 	*d++ = ifp->if_unit + '0';
89047584Smccanne 	*d = '\0';
89147584Smccanne }
89247584Smccanne 
89347584Smccanne /*
89451425Smccanne  * The new select interface passes down the proc pointer; the old select
89551425Smccanne  * stubs had to grab it out of the user struct.  This glue allows either case.
89651425Smccanne  */
89751425Smccanne #if BSD >= 199103
89851425Smccanne #define bpf_select bpfselect
89951425Smccanne #else
90051425Smccanne int
90151425Smccanne bpfselect(dev, rw)
90251425Smccanne 	register dev_t dev;
90351425Smccanne 	int rw;
90451425Smccanne {
90553947Smccanne 	return (bpf_select(dev, rw, u.u_procp));
90651425Smccanne }
90751425Smccanne #endif
90851425Smccanne 
90951425Smccanne /*
91047584Smccanne  * Support for select() system call
91147584Smccanne  * Inspired by the code in tty.c for the same purpose.
91247584Smccanne  *
91353947Smccanne  * Return true iff the specific operation will not block indefinitely.
91453947Smccanne  * Otherwise, return false but make a note that a selwakeup() must be done.
91547584Smccanne  */
91647584Smccanne int
91751425Smccanne bpf_select(dev, rw, p)
91847584Smccanne 	register dev_t dev;
91947584Smccanne 	int rw;
92048932Smccanne 	struct proc *p;
92147584Smccanne {
92247584Smccanne 	register struct bpf_d *d;
92347584Smccanne 	register int s;
92453947Smccanne 
92547584Smccanne 	if (rw != FREAD)
92648932Smccanne 		return (0);
92747584Smccanne 	/*
92847584Smccanne 	 * An imitation of the FIONREAD ioctl code.
92947584Smccanne 	 */
93047584Smccanne 	d = &bpf_dtab[minor(dev)];
93153947Smccanne 
93247584Smccanne 	s = splimp();
93349723Smccanne 	if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
93447584Smccanne 		/*
93547584Smccanne 		 * There is data waiting.
93647584Smccanne 		 */
93747584Smccanne 		splx(s);
93848932Smccanne 		return (1);
93947584Smccanne 	}
94053947Smccanne #if BSD >= 199103
94153947Smccanne 	selrecord(p, &d->bd_sel);
94253947Smccanne #else
94347584Smccanne 	/*
94447584Smccanne 	 * No data ready.  If there's already a select() waiting on this
94553947Smccanne 	 * minor device then this is a collision.  This shouldn't happen
94647584Smccanne 	 * because minors really should not be shared, but if a process
94747584Smccanne 	 * forks while one of these is open, it is possible that both
94847584Smccanne 	 * processes could select on the same descriptor.
94947584Smccanne 	 */
95053947Smccanne 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
95153947Smccanne 		d->bd_selcoll = 1;
95253947Smccanne 	else
95353947Smccanne 		d->bd_selproc = p;
95453947Smccanne #endif
95553947Smccanne 	splx(s);
95648932Smccanne 	return (0);
95747584Smccanne }
95847584Smccanne 
95947584Smccanne /*
96053947Smccanne  * Incoming linkage from device drivers.  Process the packet pkt, of length
96153947Smccanne  * pktlen, which is stored in a contiguous buffer.  The packet is parsed
96253947Smccanne  * by each process' filter, and if accepted, stashed into the corresponding
96353947Smccanne  * buffer.
96447584Smccanne  */
96547584Smccanne void
96648932Smccanne bpf_tap(arg, pkt, pktlen)
96747584Smccanne 	caddr_t arg;
96848932Smccanne 	register u_char *pkt;
96948932Smccanne 	register u_int pktlen;
97047584Smccanne {
97147584Smccanne 	struct bpf_if *bp;
97247584Smccanne 	register struct bpf_d *d;
97347584Smccanne 	register u_int slen;
97447584Smccanne 	/*
97547584Smccanne 	 * Note that the ipl does not have to be raised at this point.
97647584Smccanne 	 * The only problem that could arise here is that if two different
97747584Smccanne 	 * interfaces shared any data.  This is not the case.
97847584Smccanne 	 */
97947584Smccanne 	bp = (struct bpf_if *)arg;
98047584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
98147584Smccanne 		++d->bd_rcount;
98249202Smccanne 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
98347584Smccanne 		if (slen != 0)
98449202Smccanne 			catchpacket(d, pkt, pktlen, slen, bcopy);
98547584Smccanne 	}
98647584Smccanne }
98747584Smccanne 
98847584Smccanne /*
98947584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
99047584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
99147584Smccanne  */
99247584Smccanne static void
99349202Smccanne bpf_mcopy(src, dst, len)
99447584Smccanne 	u_char *src;
99547584Smccanne 	u_char *dst;
99647584Smccanne 	register int len;
99747584Smccanne {
99847584Smccanne 	register struct mbuf *m = (struct mbuf *)src;
99947584Smccanne 	register unsigned count;
100047584Smccanne 
100147584Smccanne 	while (len > 0) {
100247584Smccanne 		if (m == 0)
100349202Smccanne 			panic("bpf_mcopy");
100455065Spendry 		count = min(m->m_len, len);
100549202Smccanne 		bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
100649202Smccanne 		m = m->m_next;
100749202Smccanne 		dst += count;
100847584Smccanne 		len -= count;
100947584Smccanne 	}
101047584Smccanne }
101147584Smccanne 
101247584Smccanne /*
101353947Smccanne  * Incoming linkage from device drivers, when packet is in an mbuf chain.
101447584Smccanne  */
101547584Smccanne void
101649202Smccanne bpf_mtap(arg, m)
101747584Smccanne 	caddr_t arg;
101849202Smccanne 	struct mbuf *m;
101947584Smccanne {
102047584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
102147584Smccanne 	struct bpf_d *d;
102249202Smccanne 	u_int pktlen, slen;
102349202Smccanne 	struct mbuf *m0;
102447584Smccanne 
102548932Smccanne 	pktlen = 0;
102651425Smccanne 	for (m0 = m; m0 != 0; m0 = m0->m_next)
102749202Smccanne 		pktlen += m0->m_len;
102849723Smccanne 
102947584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
103047584Smccanne 		++d->bd_rcount;
103149202Smccanne 		slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
103247584Smccanne 		if (slen != 0)
103349202Smccanne 			catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
103447584Smccanne 	}
103547584Smccanne }
103647584Smccanne 
103747584Smccanne /*
103849202Smccanne  * Move the packet data from interface memory (pkt) into the
103947584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
104053947Smccanne  * otherwise 0.  "copy" is the routine called to do the actual data
104151425Smccanne  * transfer.  bcopy is passed in to copy contiguous chunks, while
104251425Smccanne  * bpf_mcopy is passed in to copy mbuf chains.  In the latter case,
104351425Smccanne  * pkt is really an mbuf.
104447584Smccanne  */
104547584Smccanne static void
104648932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn)
104748932Smccanne 	register struct bpf_d *d;
104848932Smccanne 	register u_char *pkt;
104948932Smccanne 	register u_int pktlen, snaplen;
105048932Smccanne 	register void (*cpfn)();
105147584Smccanne {
105248932Smccanne 	register struct bpf_hdr *hp;
105348932Smccanne 	register int totlen, curlen;
105448932Smccanne 	register int hdrlen = d->bd_bif->bif_hdrlen;
105547584Smccanne 	/*
105647584Smccanne 	 * Figure out how many bytes to move.  If the packet is
105747584Smccanne 	 * greater or equal to the snapshot length, transfer that
105847584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
105948932Smccanne 	 * we hit the buffer size limit).
106047584Smccanne 	 */
106155065Spendry 	totlen = hdrlen + min(snaplen, pktlen);
106250082Smccanne 	if (totlen > d->bd_bufsize)
106350082Smccanne 		totlen = d->bd_bufsize;
106447584Smccanne 
106547584Smccanne 	/*
106647584Smccanne 	 * Round up the end of the previous packet to the next longword.
106747584Smccanne 	 */
106848932Smccanne 	curlen = BPF_WORDALIGN(d->bd_slen);
106948932Smccanne 	if (curlen + totlen > d->bd_bufsize) {
107047584Smccanne 		/*
107147584Smccanne 		 * This packet will overflow the storage buffer.
107248932Smccanne 		 * Rotate the buffers if we can, then wakeup any
107348932Smccanne 		 * pending reads.
107447584Smccanne 		 */
107547584Smccanne 		if (d->bd_fbuf == 0) {
107653947Smccanne 			/*
107753947Smccanne 			 * We haven't completed the previous read yet,
107848932Smccanne 			 * so drop the packet.
107947584Smccanne 			 */
108047584Smccanne 			++d->bd_dcount;
108147584Smccanne 			return;
108247584Smccanne 		}
108348932Smccanne 		ROTATE_BUFFERS(d);
108447584Smccanne 		bpf_wakeup(d);
108548932Smccanne 		curlen = 0;
108647584Smccanne 	}
108753947Smccanne 	else if (d->bd_immediate)
108847584Smccanne 		/*
108947584Smccanne 		 * Immediate mode is set.  A packet arrived so any
109047584Smccanne 		 * reads should be woken up.
109147584Smccanne 		 */
109247584Smccanne 		bpf_wakeup(d);
109348932Smccanne 
109447584Smccanne 	/*
109547584Smccanne 	 * Append the bpf header.
109647584Smccanne 	 */
109748932Smccanne 	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
109851425Smccanne #if BSD >= 199103
109947584Smccanne 	microtime(&hp->bh_tstamp);
110053947Smccanne #elif defined(sun)
110153947Smccanne 	uniqtime(&hp->bh_tstamp);
110247584Smccanne #else
110347584Smccanne 	hp->bh_tstamp = time;
110447584Smccanne #endif
110548932Smccanne 	hp->bh_datalen = pktlen;
110647584Smccanne 	hp->bh_hdrlen = hdrlen;
110747584Smccanne 	/*
110848932Smccanne 	 * Copy the packet data into the store buffer and update its length.
110947584Smccanne 	 */
111048932Smccanne 	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
111148932Smccanne 	d->bd_slen = curlen + totlen;
111247584Smccanne }
111347584Smccanne 
111453947Smccanne /*
111547584Smccanne  * Initialize all nonzero fields of a descriptor.
111647584Smccanne  */
111747584Smccanne static int
111853947Smccanne bpf_allocbufs(d)
111947584Smccanne 	register struct bpf_d *d;
112047584Smccanne {
112148932Smccanne 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
112248932Smccanne 	if (d->bd_fbuf == 0)
112348932Smccanne 		return (ENOBUFS);
112447584Smccanne 
112548932Smccanne 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
112648932Smccanne 	if (d->bd_sbuf == 0) {
112748932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
112848932Smccanne 		return (ENOBUFS);
112947584Smccanne 	}
113048932Smccanne 	d->bd_slen = 0;
113148932Smccanne 	d->bd_hlen = 0;
113248932Smccanne 	return (0);
113347584Smccanne }
113447584Smccanne 
113547584Smccanne /*
113651425Smccanne  * Free buffers currently in use by a descriptor.
113751425Smccanne  * Called on close.
113847584Smccanne  */
113953947Smccanne static void
114051425Smccanne bpf_freed(d)
114151425Smccanne 	register struct bpf_d *d;
114251425Smccanne {
114351425Smccanne 	/*
114451425Smccanne 	 * We don't need to lock out interrupts since this descriptor has
114553947Smccanne 	 * been detached from its interface and it yet hasn't been marked
114651425Smccanne 	 * free.
114751425Smccanne 	 */
114853947Smccanne 	if (d->bd_sbuf != 0) {
114953947Smccanne 		free(d->bd_sbuf, M_DEVBUF);
115053947Smccanne 		if (d->bd_hbuf != 0)
115153947Smccanne 			free(d->bd_hbuf, M_DEVBUF);
115253947Smccanne 		if (d->bd_fbuf != 0)
115353947Smccanne 			free(d->bd_fbuf, M_DEVBUF);
115453947Smccanne 	}
115551425Smccanne 	if (d->bd_filter)
115651425Smccanne 		free((caddr_t)d->bd_filter, M_DEVBUF);
115753947Smccanne 
115851425Smccanne 	D_MARKFREE(d);
115951425Smccanne }
116051425Smccanne 
116151425Smccanne /*
116251425Smccanne  * Attach an interface to bpf.  driverp is a pointer to a (struct bpf_if *)
116351425Smccanne  * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
116451425Smccanne  * size of the link header (variable length headers not yet supported).
116551425Smccanne  */
116647584Smccanne void
116749202Smccanne bpfattach(driverp, ifp, dlt, hdrlen)
116847584Smccanne 	caddr_t *driverp;
116947584Smccanne 	struct ifnet *ifp;
117049202Smccanne 	u_int dlt, hdrlen;
117147584Smccanne {
117247584Smccanne 	struct bpf_if *bp;
117347584Smccanne 	int i;
117451425Smccanne #if BSD < 199103
117551425Smccanne 	static struct bpf_if bpf_ifs[NBPFILTER];
117651425Smccanne 	static int bpfifno;
117747584Smccanne 
117851425Smccanne 	bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0;
117951425Smccanne #else
118049202Smccanne 	bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
118151425Smccanne #endif
118249202Smccanne 	if (bp == 0)
118349202Smccanne 		panic("bpfattach");
118447584Smccanne 
118547584Smccanne 	bp->bif_dlist = 0;
118647584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
118747584Smccanne 	bp->bif_ifp = ifp;
118849202Smccanne 	bp->bif_dlt = dlt;
118947584Smccanne 
119049202Smccanne 	bp->bif_next = bpf_iflist;
119149202Smccanne 	bpf_iflist = bp;
119249202Smccanne 
119348932Smccanne 	*bp->bif_driverp = 0;
119448932Smccanne 
119547584Smccanne 	/*
119647584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
119753947Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
119853947Smccanne 	 * that the network layer header begins on a longword boundary (for
119947584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
120047584Smccanne 	 */
120149202Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
120247584Smccanne 
120347584Smccanne 	/*
120447584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
120547584Smccanne 	 */
120647584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
120747584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
120847584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
120947584Smccanne 
121047584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
121147584Smccanne }
121247584Smccanne 
121351425Smccanne #if BSD >= 199103
121448967Smccanne /* XXX This routine belongs in net/if.c. */
121548932Smccanne /*
121653947Smccanne  * Set/clear promiscuous mode on interface ifp based on the truth value
121748932Smccanne  * of pswitch.  The calls are reference counted so that only the first
121853947Smccanne  * "on" request actually has an effect, as does the final "off" request.
121953947Smccanne  * Results are undefined if the "off" and "on" requests are not matched.
122048932Smccanne  */
122148932Smccanne int
122248932Smccanne ifpromisc(ifp, pswitch)
122348932Smccanne 	struct ifnet *ifp;
122448932Smccanne 	int pswitch;
122548932Smccanne {
122649726Smccanne 	struct ifreq ifr;
122753947Smccanne 	/*
122848932Smccanne 	 * If the device is not configured up, we cannot put it in
122948932Smccanne 	 * promiscuous mode.
123048932Smccanne 	 */
123148932Smccanne 	if ((ifp->if_flags & IFF_UP) == 0)
123248932Smccanne 		return (ENETDOWN);
123348932Smccanne 
123448932Smccanne 	if (pswitch) {
123548932Smccanne 		if (ifp->if_pcount++ != 0)
123648932Smccanne 			return (0);
123748932Smccanne 		ifp->if_flags |= IFF_PROMISC;
123848932Smccanne 	} else {
123948932Smccanne 		if (--ifp->if_pcount > 0)
124048932Smccanne 			return (0);
124148932Smccanne 		ifp->if_flags &= ~IFF_PROMISC;
124248932Smccanne 	}
124349726Smccanne 	ifr.ifr_flags = ifp->if_flags;
124449726Smccanne 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
124548932Smccanne }
124651425Smccanne #endif
124748932Smccanne 
124851425Smccanne #if BSD < 199103
124951425Smccanne /*
125051425Smccanne  * Allocate some memory for bpf.  This is temporary SunOS support, and
125153947Smccanne  * is admittedly a hack.
125251425Smccanne  * If resources unavaiable, return 0.
125351425Smccanne  */
125451425Smccanne static caddr_t
125551425Smccanne bpf_alloc(size, canwait)
125651425Smccanne 	register int size;
125751425Smccanne 	register int canwait;
125851425Smccanne {
125951425Smccanne 	register struct mbuf *m;
126051425Smccanne 
126151425Smccanne 	if ((unsigned)size > (MCLBYTES-8))
126251425Smccanne 		return 0;
126351425Smccanne 
126451425Smccanne 	MGET(m, canwait, MT_DATA);
126551425Smccanne 	if (m == 0)
126651425Smccanne 		return 0;
126751425Smccanne 	if ((unsigned)size > (MLEN-8)) {
126851425Smccanne 		MCLGET(m);
126951425Smccanne 		if (m->m_len != MCLBYTES) {
127051425Smccanne 			m_freem(m);
127151425Smccanne 			return 0;
127251425Smccanne 		}
127351425Smccanne 	}
127451425Smccanne 	*mtod(m, struct mbuf **) = m;
127551425Smccanne 	return mtod(m, caddr_t) + 8;
127651425Smccanne }
127751425Smccanne #endif
127851425Smccanne #endif
1279