xref: /csrg-svn/sys/net/bpf.c (revision 61337)
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*61337Sbostic  *      @(#)bpf.c	7.15 (Berkeley) 06/04/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 
8659122Storek #if BSD >= 199207
8759122Storek /*
8859122Storek  * bpfilterattach() is called at boot time in new systems.  We do
8959122Storek  * nothing here since old systems will not call this.
9059122Storek  */
9159122Storek /* ARGSUSED */
9259122Storek void
9359122Storek bpfilterattach(n)
9459122Storek 	int n;
9559122Storek {
9659122Storek }
9759122Storek #endif
9859122Storek 
99*61337Sbostic static int	bpf_allocbufs __P((struct bpf_d *));
100*61337Sbostic static int	bpf_allocbufs __P((struct bpf_d *));
101*61337Sbostic static void	bpf_freed __P((struct bpf_d *));
102*61337Sbostic static void	bpf_freed __P((struct bpf_d *));
103*61337Sbostic static void	bpf_ifname __P((struct ifnet *, struct ifreq *));
104*61337Sbostic static void	bpf_ifname __P((struct ifnet *, struct ifreq *));
105*61337Sbostic static void	bpf_mcopy __P((void *, void *, u_int));
106*61337Sbostic static int	bpf_movein __P((struct uio *, int,
107*61337Sbostic 		    struct mbuf **, struct sockaddr *, int *));
108*61337Sbostic static int	bpf_setif __P((struct bpf_d *, struct ifreq *));
109*61337Sbostic static int	bpf_setif __P((struct bpf_d *, struct ifreq *));
110*61337Sbostic static inline void
111*61337Sbostic 		bpf_wakeup __P((struct bpf_d *));
112*61337Sbostic static void	catchpacket __P((struct bpf_d *, u_char *, u_int,
113*61337Sbostic 		    u_int, void (*)(void *, void *, u_int)));
114*61337Sbostic static void	reset_d __P((struct bpf_d *));
11547584Smccanne 
11647584Smccanne static int
11755289Smckusick bpf_movein(uio, linktype, mp, sockp, datlen)
11847584Smccanne 	register struct uio *uio;
11955289Smckusick 	int linktype, *datlen;
12047584Smccanne 	register struct mbuf **mp;
12147584Smccanne 	register struct sockaddr *sockp;
12247584Smccanne {
12347584Smccanne 	struct mbuf *m;
12447584Smccanne 	int error;
12547584Smccanne 	int len;
12647584Smccanne 	int hlen;
12747584Smccanne 
12847584Smccanne 	/*
12947584Smccanne 	 * Build a sockaddr based on the data link layer type.
13047584Smccanne 	 * We do this at this level because the ethernet header
13147584Smccanne 	 * is copied directly into the data field of the sockaddr.
13247584Smccanne 	 * In the case of SLIP, there is no header and the packet
13347584Smccanne 	 * is forwarded as is.
13447584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
13547584Smccanne 	 * for the link level header.
13647584Smccanne 	 */
13747584Smccanne 	switch (linktype) {
13853947Smccanne 
13947584Smccanne 	case DLT_SLIP:
14047584Smccanne 		sockp->sa_family = AF_INET;
14147584Smccanne 		hlen = 0;
14247584Smccanne 		break;
14347584Smccanne 
14447584Smccanne 	case DLT_EN10MB:
14547584Smccanne 		sockp->sa_family = AF_UNSPEC;
14647584Smccanne 		/* XXX Would MAXLINKHDR be better? */
14747584Smccanne 		hlen = sizeof(struct ether_header);
14847584Smccanne 		break;
14947584Smccanne 
15053947Smccanne 	case DLT_FDDI:
15147584Smccanne 		sockp->sa_family = AF_UNSPEC;
15247584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
15347584Smccanne 		hlen = 24;
15447584Smccanne 		break;
15547584Smccanne 
15653947Smccanne 	case DLT_NULL:
15753947Smccanne 		sockp->sa_family = AF_UNSPEC;
15853947Smccanne 		hlen = 0;
15953947Smccanne 		break;
16053947Smccanne 
16147584Smccanne 	default:
16248932Smccanne 		return (EIO);
16347584Smccanne 	}
16447584Smccanne 
16547584Smccanne 	len = uio->uio_resid;
16655289Smckusick 	*datlen = len - hlen;
16747584Smccanne 	if ((unsigned)len > MCLBYTES)
16848932Smccanne 		return (EIO);
16947584Smccanne 
17047584Smccanne 	MGET(m, M_WAIT, MT_DATA);
17147584Smccanne 	if (m == 0)
17248932Smccanne 		return (ENOBUFS);
17347584Smccanne 	if (len > MLEN) {
17451425Smccanne #if BSD >= 199103
17548932Smccanne 		MCLGET(m, M_WAIT);
17648932Smccanne 		if ((m->m_flags & M_EXT) == 0) {
17751425Smccanne #else
17851425Smccanne 		MCLGET(m);
17953947Smccanne 		if (m->m_len != MCLBYTES) {
18051425Smccanne #endif
18153947Smccanne 			error = ENOBUFS;
18247584Smccanne 			goto bad;
18347584Smccanne 		}
18447584Smccanne 	}
18547584Smccanne 	m->m_len = len;
18647584Smccanne 	*mp = m;
18747584Smccanne 	/*
18847584Smccanne 	 * Make room for link header.
18947584Smccanne 	 */
19053947Smccanne 	if (hlen != 0) {
19147584Smccanne 		m->m_len -= hlen;
19251425Smccanne #if BSD >= 199103
19348932Smccanne 		m->m_data += hlen; /* XXX */
19451425Smccanne #else
19551425Smccanne 		m->m_off += hlen;
19651425Smccanne #endif
19753947Smccanne 		error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
19847584Smccanne 		if (error)
19947584Smccanne 			goto bad;
20047584Smccanne 	}
20153947Smccanne 	error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
20253947Smccanne 	if (!error)
20348932Smccanne 		return (0);
20447584Smccanne  bad:
20547584Smccanne 	m_freem(m);
20648932Smccanne 	return (error);
20747584Smccanne }
20847584Smccanne 
20947584Smccanne /*
21051425Smccanne  * Attach file to the bpf interface, i.e. make d listen on bp.
21147584Smccanne  * Must be called at splimp.
21247584Smccanne  */
21347584Smccanne static void
21447584Smccanne bpf_attachd(d, bp)
21547584Smccanne 	struct bpf_d *d;
21647584Smccanne 	struct bpf_if *bp;
21747584Smccanne {
21851425Smccanne 	/*
21951425Smccanne 	 * Point d at bp, and add d to the interface's list of listeners.
22051425Smccanne 	 * Finally, point the driver's bpf cookie at the interface so
22151425Smccanne 	 * it will divert packets to bpf.
22251425Smccanne 	 */
22347584Smccanne 	d->bd_bif = bp;
22447584Smccanne 	d->bd_next = bp->bif_dlist;
22547584Smccanne 	bp->bif_dlist = d;
22647584Smccanne 
22747584Smccanne 	*bp->bif_driverp = bp;
22847584Smccanne }
22947584Smccanne 
23051425Smccanne /*
23151425Smccanne  * Detach a file from its interface.
23251425Smccanne  */
23347584Smccanne static void
23447584Smccanne bpf_detachd(d)
23547584Smccanne 	struct bpf_d *d;
23647584Smccanne {
23747584Smccanne 	struct bpf_d **p;
23847584Smccanne 	struct bpf_if *bp;
23947584Smccanne 
24047584Smccanne 	bp = d->bd_bif;
24147584Smccanne 	/*
24247584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
24347584Smccanne 	 * If so, turn it off.
24447584Smccanne 	 */
24547584Smccanne 	if (d->bd_promisc) {
24647584Smccanne 		d->bd_promisc = 0;
24747584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
24847584Smccanne 			/*
24947584Smccanne 			 * Something is really wrong if we were able to put
25047584Smccanne 			 * the driver into promiscuous mode, but can't
25147584Smccanne 			 * take it out.
25247584Smccanne 			 */
25351425Smccanne 			panic("bpf: ifpromisc failed");
25447584Smccanne 	}
25551425Smccanne 	/* Remove d from the interface's descriptor list. */
25647584Smccanne 	p = &bp->bif_dlist;
25747584Smccanne 	while (*p != d) {
25847584Smccanne 		p = &(*p)->bd_next;
25947584Smccanne 		if (*p == 0)
26047584Smccanne 			panic("bpf_detachd: descriptor not in list");
26147584Smccanne 	}
26247584Smccanne 	*p = (*p)->bd_next;
26347584Smccanne 	if (bp->bif_dlist == 0)
26447584Smccanne 		/*
26547584Smccanne 		 * Let the driver know that there are no more listeners.
26647584Smccanne 		 */
26747584Smccanne 		*d->bd_bif->bif_driverp = 0;
26847584Smccanne 	d->bd_bif = 0;
26947584Smccanne }
27047584Smccanne 
27147584Smccanne 
27247584Smccanne /*
27353947Smccanne  * Mark a descriptor free by making it point to itself.
27447584Smccanne  * This is probably cheaper than marking with a constant since
27547584Smccanne  * the address should be in a register anyway.
27647584Smccanne  */
27747584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
27847584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
27947584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
28047584Smccanne 
28147584Smccanne /*
28253947Smccanne  * Open ethernet device.  Returns ENXIO for illegal minor device number,
28353947Smccanne  * EBUSY if file is open by another process.
28447584Smccanne  */
28547584Smccanne /* ARGSUSED */
28647584Smccanne int
28747584Smccanne bpfopen(dev, flag)
28847584Smccanne 	dev_t dev;
28947584Smccanne 	int flag;
29047584Smccanne {
29147584Smccanne 	register struct bpf_d *d;
29253947Smccanne 
29347584Smccanne 	if (minor(dev) >= NBPFILTER)
29448932Smccanne 		return (ENXIO);
29547584Smccanne 	/*
29647584Smccanne 	 * Each minor can be opened by only one process.  If the requested
29747584Smccanne 	 * minor is in use, return EBUSY.
29847584Smccanne 	 */
29947584Smccanne 	d = &bpf_dtab[minor(dev)];
30053947Smccanne 	if (!D_ISFREE(d))
30148932Smccanne 		return (EBUSY);
30247584Smccanne 
30353947Smccanne 	/* Mark "free" and do most initialization. */
30453947Smccanne 	bzero((char *)d, sizeof(*d));
30553947Smccanne 	d->bd_bufsize = bpf_bufsize;
30653947Smccanne 
30748932Smccanne 	return (0);
30847584Smccanne }
30947584Smccanne 
31047584Smccanne /*
31147584Smccanne  * Close the descriptor by detaching it from its interface,
31247584Smccanne  * deallocating its buffers, and marking it free.
31347584Smccanne  */
31447584Smccanne /* ARGSUSED */
31553947Smccanne int
31647584Smccanne bpfclose(dev, flag)
31747584Smccanne 	dev_t dev;
31847584Smccanne 	int flag;
31947584Smccanne {
32047584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
32153947Smccanne 	register int s;
32247584Smccanne 
32347584Smccanne 	s = splimp();
32447584Smccanne 	if (d->bd_bif)
32547584Smccanne 		bpf_detachd(d);
32647584Smccanne 	splx(s);
32753947Smccanne 	bpf_freed(d);
32847584Smccanne 
32953947Smccanne 	return (0);
33047584Smccanne }
33147584Smccanne 
33253947Smccanne /*
33353947Smccanne  * Support for SunOS, which does not have tsleep.
33453947Smccanne  */
33551425Smccanne #if BSD < 199103
33651425Smccanne static
33751425Smccanne bpf_timeout(arg)
33851425Smccanne 	caddr_t arg;
33951425Smccanne {
34051425Smccanne 	struct bpf_d *d = (struct bpf_d *)arg;
34151425Smccanne 	d->bd_timedout = 1;
34251425Smccanne 	wakeup(arg);
34351425Smccanne }
34451425Smccanne 
34553947Smccanne #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan)
34653947Smccanne 
34753947Smccanne int
34853947Smccanne bpf_sleep(d)
34953947Smccanne 	register struct bpf_d *d;
35051425Smccanne {
35153947Smccanne 	register int rto = d->bd_rtout;
35253947Smccanne 	register int st;
35351425Smccanne 
35453947Smccanne 	if (rto != 0) {
35551425Smccanne 		d->bd_timedout = 0;
35653947Smccanne 		timeout(bpf_timeout, (caddr_t)d, rto);
35751425Smccanne 	}
35853947Smccanne 	st = sleep((caddr_t)d, PRINET|PCATCH);
35953947Smccanne 	if (rto != 0) {
36053947Smccanne 		if (d->bd_timedout == 0)
36153947Smccanne 			untimeout(bpf_timeout, (caddr_t)d);
36253947Smccanne 		else if (st == 0)
36351425Smccanne 			return EWOULDBLOCK;
36451425Smccanne 	}
36553947Smccanne 	return (st != 0) ? EINTR : 0;
36651425Smccanne }
36753947Smccanne #else
36853947Smccanne #define BPF_SLEEP tsleep
36951425Smccanne #endif
37051425Smccanne 
37147584Smccanne /*
37248932Smccanne  * Rotate the packet buffers in descriptor d.  Move the store buffer
37353947Smccanne  * into the hold slot, and the free buffer into the store slot.
37448932Smccanne  * Zero the length of the new store buffer.
37548932Smccanne  */
37648932Smccanne #define ROTATE_BUFFERS(d) \
37748932Smccanne 	(d)->bd_hbuf = (d)->bd_sbuf; \
37848932Smccanne 	(d)->bd_hlen = (d)->bd_slen; \
37948932Smccanne 	(d)->bd_sbuf = (d)->bd_fbuf; \
38048932Smccanne 	(d)->bd_slen = 0; \
38153947Smccanne 	(d)->bd_fbuf = 0;
38248932Smccanne /*
38347584Smccanne  *  bpfread - read next chunk of packets from buffers
38447584Smccanne  */
38547584Smccanne int
38647584Smccanne bpfread(dev, uio)
38747584Smccanne 	dev_t dev;
38847584Smccanne 	register struct uio *uio;
38947584Smccanne {
39047584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
39147584Smccanne 	int error;
39247584Smccanne 	int s;
39347584Smccanne 
39447584Smccanne 	/*
39553947Smccanne 	 * Restrict application to use a buffer the same size as
39647584Smccanne 	 * as kernel buffers.
39747584Smccanne 	 */
39848932Smccanne 	if (uio->uio_resid != d->bd_bufsize)
39949202Smccanne 		return (EINVAL);
40047584Smccanne 
40147584Smccanne 	s = splimp();
40247584Smccanne 	/*
40353947Smccanne 	 * If the hold buffer is empty, then do a timed sleep, which
40453947Smccanne 	 * ends when the timeout expires or when enough packets
40553947Smccanne 	 * have arrived to fill the store buffer.
40647584Smccanne 	 */
40747584Smccanne 	while (d->bd_hbuf == 0) {
40848932Smccanne 		if (d->bd_immediate && d->bd_slen != 0) {
40947584Smccanne 			/*
41047584Smccanne 			 * A packet(s) either arrived since the previous
41147584Smccanne 			 * read or arrived while we were asleep.
41247584Smccanne 			 * Rotate the buffers and return what's here.
41347584Smccanne 			 */
41448932Smccanne 			ROTATE_BUFFERS(d);
41547584Smccanne 			break;
41647584Smccanne 		}
41753947Smccanne 		error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf",
41853947Smccanne 				  d->bd_rtout);
41948932Smccanne 		if (error == EINTR || error == ERESTART) {
42048932Smccanne 			splx(s);
42148932Smccanne 			return (error);
42247584Smccanne 		}
42348932Smccanne 		if (error == EWOULDBLOCK) {
42447584Smccanne 			/*
42547584Smccanne 			 * On a timeout, return what's in the buffer,
42648932Smccanne 			 * which may be nothing.  If there is something
42748932Smccanne 			 * in the store buffer, we can rotate the buffers.
42847584Smccanne 			 */
42947584Smccanne 			if (d->bd_hbuf)
43047584Smccanne 				/*
43153947Smccanne 				 * We filled up the buffer in between
43247584Smccanne 				 * getting the timeout and arriving
43347584Smccanne 				 * here, so we don't need to rotate.
43447584Smccanne 				 */
43547584Smccanne 				break;
43647584Smccanne 
43748932Smccanne 			if (d->bd_slen == 0) {
43847584Smccanne 				splx(s);
43948932Smccanne 				return (0);
44047584Smccanne 			}
44148932Smccanne 			ROTATE_BUFFERS(d);
44247584Smccanne 			break;
44347584Smccanne 		}
44447584Smccanne 	}
44547584Smccanne 	/*
44647584Smccanne 	 * At this point, we know we have something in the hold slot.
44747584Smccanne 	 */
44847584Smccanne 	splx(s);
44953947Smccanne 
45053947Smccanne 	/*
45147584Smccanne 	 * Move data from hold buffer into user space.
45247584Smccanne 	 * We know the entire buffer is transferred since
45348932Smccanne 	 * we checked above that the read buffer is bpf_bufsize bytes.
45447584Smccanne 	 */
45553947Smccanne 	error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
45653947Smccanne 
45747584Smccanne 	s = splimp();
45848932Smccanne 	d->bd_fbuf = d->bd_hbuf;
45948932Smccanne 	d->bd_hbuf = 0;
46053947Smccanne 	d->bd_hlen = 0;
46147584Smccanne 	splx(s);
46253947Smccanne 
46348932Smccanne 	return (error);
46447584Smccanne }
46547584Smccanne 
46647584Smccanne 
46747584Smccanne /*
46853947Smccanne  * If there are processes sleeping on this descriptor, wake them up.
46947584Smccanne  */
47047584Smccanne static inline void
47147584Smccanne bpf_wakeup(d)
47247584Smccanne 	register struct bpf_d *d;
47347584Smccanne {
47448932Smccanne 	wakeup((caddr_t)d);
47553947Smccanne #if BSD >= 199103
47653947Smccanne 	selwakeup(&d->bd_sel);
47753947Smccanne 	/* XXX */
47853947Smccanne 	d->bd_sel.si_pid = 0;
47953947Smccanne #else
48053947Smccanne 	if (d->bd_selproc) {
48153947Smccanne 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
48253947Smccanne 		d->bd_selcoll = 0;
48353947Smccanne 		d->bd_selproc = 0;
48453947Smccanne 	}
48553947Smccanne #endif
48647584Smccanne }
48747584Smccanne 
48847584Smccanne int
48947584Smccanne bpfwrite(dev, uio)
49047584Smccanne 	dev_t dev;
49147584Smccanne 	struct uio *uio;
49247584Smccanne {
49347584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
49447584Smccanne 	struct ifnet *ifp;
49547584Smccanne 	struct mbuf *m;
49647584Smccanne 	int error, s;
49747584Smccanne 	static struct sockaddr dst;
49855289Smckusick 	int datlen;
49947584Smccanne 
50047584Smccanne 	if (d->bd_bif == 0)
50148932Smccanne 		return (ENXIO);
50247584Smccanne 
50347584Smccanne 	ifp = d->bd_bif->bif_ifp;
50447584Smccanne 
50547584Smccanne 	if (uio->uio_resid == 0)
50648932Smccanne 		return (0);
50747584Smccanne 
50855289Smckusick 	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen);
50947584Smccanne 	if (error)
51048932Smccanne 		return (error);
51147584Smccanne 
51255289Smckusick 	if (datlen > ifp->if_mtu)
51355289Smckusick 		return (EMSGSIZE);
51455289Smckusick 
51547584Smccanne 	s = splnet();
51651425Smccanne #if BSD >= 199103
51753947Smccanne 	error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
51851425Smccanne #else
51947584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
52051425Smccanne #endif
52147584Smccanne 	splx(s);
52247584Smccanne 	/*
52353947Smccanne 	 * The driver frees the mbuf.
52447584Smccanne 	 */
52548932Smccanne 	return (error);
52647584Smccanne }
52747584Smccanne 
52847584Smccanne /*
52953947Smccanne  * Reset a descriptor by flushing its packet buffer and clearing the
53053947Smccanne  * receive and drop counts.  Should be called at splimp.
53147584Smccanne  */
53247584Smccanne static void
53347584Smccanne reset_d(d)
53447584Smccanne 	struct bpf_d *d;
53547584Smccanne {
53647584Smccanne 	if (d->bd_hbuf) {
53747584Smccanne 		/* Free the hold buffer. */
53847584Smccanne 		d->bd_fbuf = d->bd_hbuf;
53947584Smccanne 		d->bd_hbuf = 0;
54047584Smccanne 	}
54148932Smccanne 	d->bd_slen = 0;
54253947Smccanne 	d->bd_hlen = 0;
54347584Smccanne 	d->bd_rcount = 0;
54447584Smccanne 	d->bd_dcount = 0;
54547584Smccanne }
54647584Smccanne 
54747584Smccanne /*
54847584Smccanne  *  FIONREAD		Check for read packet available.
54947584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
55047584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
55147584Smccanne  *  BIOCSETF		Set ethernet read filter.
55247584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
55347584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
55449202Smccanne  *  BIOCGDLT		Get link layer type.
55547584Smccanne  *  BIOCGETIF		Get interface name.
55647584Smccanne  *  BIOCSETIF		Set interface.
55747584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
55847584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
55947584Smccanne  *  BIOCGSTATS		Get packet stats.
56047584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
56153947Smccanne  *  BIOCVERSION		Get filter language version.
56247584Smccanne  */
56347584Smccanne /* ARGSUSED */
56447584Smccanne int
56547584Smccanne bpfioctl(dev, cmd, addr, flag)
56647584Smccanne 	dev_t dev;
56747584Smccanne 	int cmd;
56847584Smccanne 	caddr_t addr;
56947584Smccanne 	int flag;
57047584Smccanne {
57147584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
57247584Smccanne 	int s, error = 0;
57347584Smccanne 
57447584Smccanne 	switch (cmd) {
57547584Smccanne 
57647584Smccanne 	default:
57747584Smccanne 		error = EINVAL;
57847584Smccanne 		break;
57947584Smccanne 
58047584Smccanne 	/*
58147584Smccanne 	 * Check for read packet available.
58247584Smccanne 	 */
58347584Smccanne 	case FIONREAD:
58447584Smccanne 		{
58547584Smccanne 			int n;
58653947Smccanne 
58747584Smccanne 			s = splimp();
58848932Smccanne 			n = d->bd_slen;
58953947Smccanne 			if (d->bd_hbuf)
59048932Smccanne 				n += d->bd_hlen;
59147584Smccanne 			splx(s);
59247584Smccanne 
59347584Smccanne 			*(int *)addr = n;
59447584Smccanne 			break;
59547584Smccanne 		}
59647584Smccanne 
59747584Smccanne 	case SIOCGIFADDR:
59847584Smccanne 		{
59947584Smccanne 			struct ifnet *ifp;
60047584Smccanne 
60147584Smccanne 			if (d->bd_bif == 0)
60247584Smccanne 				error = EINVAL;
60347584Smccanne 			else {
60447584Smccanne 				ifp = d->bd_bif->bif_ifp;
60553947Smccanne 				error = (*ifp->if_ioctl)(ifp, cmd, addr);
60647584Smccanne 			}
60747584Smccanne 			break;
60847584Smccanne 		}
60947584Smccanne 
61047584Smccanne 	/*
61147584Smccanne 	 * Get buffer len [for read()].
61247584Smccanne 	 */
61347584Smccanne 	case BIOCGBLEN:
61448932Smccanne 		*(u_int *)addr = d->bd_bufsize;
61547584Smccanne 		break;
61647584Smccanne 
61747584Smccanne 	/*
61853947Smccanne 	 * Set buffer length.
61953947Smccanne 	 */
62053947Smccanne 	case BIOCSBLEN:
62153947Smccanne #if BSD < 199103
62253947Smccanne 		error = EINVAL;
62353947Smccanne #else
62453947Smccanne 		if (d->bd_bif != 0)
62553947Smccanne 			error = EINVAL;
62653947Smccanne 		else {
62753947Smccanne 			register u_int size = *(u_int *)addr;
62853947Smccanne 
62953947Smccanne 			if (size > BPF_MAXBUFSIZE)
63053947Smccanne 				*(u_int *)addr = size = BPF_MAXBUFSIZE;
63153947Smccanne 			else if (size < BPF_MINBUFSIZE)
63253947Smccanne 				*(u_int *)addr = size = BPF_MINBUFSIZE;
63353947Smccanne 			d->bd_bufsize = size;
63453947Smccanne 		}
63553947Smccanne #endif
63653947Smccanne 		break;
63753947Smccanne 
63853947Smccanne 	/*
63951425Smccanne 	 * Set link layer read filter.
64047584Smccanne 	 */
64153947Smccanne 	case BIOCSETF:
64247584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
64347584Smccanne 		break;
64447584Smccanne 
64547584Smccanne 	/*
64647584Smccanne 	 * Flush read packet buffer.
64747584Smccanne 	 */
64847584Smccanne 	case BIOCFLUSH:
64947584Smccanne 		s = splimp();
65047584Smccanne 		reset_d(d);
65147584Smccanne 		splx(s);
65247584Smccanne 		break;
65347584Smccanne 
65447584Smccanne 	/*
65547584Smccanne 	 * Put interface into promiscuous mode.
65647584Smccanne 	 */
65747584Smccanne 	case BIOCPROMISC:
65847584Smccanne 		if (d->bd_bif == 0) {
65947584Smccanne 			/*
66047584Smccanne 			 * No interface attached yet.
66147584Smccanne 			 */
66247584Smccanne 			error = EINVAL;
66347584Smccanne 			break;
66447584Smccanne 		}
66547584Smccanne 		s = splimp();
66647584Smccanne 		if (d->bd_promisc == 0) {
66747584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
66851425Smccanne 			if (error == 0)
66951425Smccanne 				d->bd_promisc = 1;
67047584Smccanne 		}
67147584Smccanne 		splx(s);
67247584Smccanne 		break;
67347584Smccanne 
67447584Smccanne 	/*
67547584Smccanne 	 * Get device parameters.
67647584Smccanne 	 */
67749202Smccanne 	case BIOCGDLT:
67847584Smccanne 		if (d->bd_bif == 0)
67947584Smccanne 			error = EINVAL;
68047584Smccanne 		else
68149202Smccanne 			*(u_int *)addr = d->bd_bif->bif_dlt;
68247584Smccanne 		break;
68347584Smccanne 
68447584Smccanne 	/*
68547584Smccanne 	 * Set interface name.
68647584Smccanne 	 */
68747584Smccanne 	case BIOCGETIF:
68847584Smccanne 		if (d->bd_bif == 0)
68947584Smccanne 			error = EINVAL;
69047584Smccanne 		else
69147584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
69247584Smccanne 		break;
69347584Smccanne 
69447584Smccanne 	/*
69547584Smccanne 	 * Set interface.
69647584Smccanne 	 */
69747584Smccanne 	case BIOCSETIF:
69847584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
69947584Smccanne 		break;
70047584Smccanne 
70147584Smccanne 	/*
70247584Smccanne 	 * Set read timeout.
70347584Smccanne 	 */
70453947Smccanne 	case BIOCSRTIMEOUT:
70547584Smccanne 		{
70647584Smccanne 			struct timeval *tv = (struct timeval *)addr;
70747584Smccanne 			u_long msec;
70847584Smccanne 
70947584Smccanne 			/* Compute number of milliseconds. */
71047584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
71147584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
71247584Smccanne 			   clock has millisecond or greater resolution
71347584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
71447584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
71547584Smccanne 			d->bd_rtout = msec / (tick / 1000);
71647584Smccanne 			break;
71747584Smccanne 		}
71847584Smccanne 
71947584Smccanne 	/*
72047584Smccanne 	 * Get read timeout.
72147584Smccanne 	 */
72253947Smccanne 	case BIOCGRTIMEOUT:
72347584Smccanne 		{
72447584Smccanne 			struct timeval *tv = (struct timeval *)addr;
72547584Smccanne 			u_long msec = d->bd_rtout;
72647584Smccanne 
72747584Smccanne 			msec *= tick / 1000;
72847584Smccanne 			tv->tv_sec = msec / 1000;
72947584Smccanne 			tv->tv_usec = msec % 1000;
73047584Smccanne 			break;
73147584Smccanne 		}
73247584Smccanne 
73347584Smccanne 	/*
73447584Smccanne 	 * Get packet stats.
73547584Smccanne 	 */
73647584Smccanne 	case BIOCGSTATS:
73747584Smccanne 		{
73847584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
73947584Smccanne 
74047584Smccanne 			bs->bs_recv = d->bd_rcount;
74147584Smccanne 			bs->bs_drop = d->bd_dcount;
74247584Smccanne 			break;
74347584Smccanne 		}
74447584Smccanne 
74547584Smccanne 	/*
74647584Smccanne 	 * Set immediate mode.
74747584Smccanne 	 */
74847584Smccanne 	case BIOCIMMEDIATE:
74947584Smccanne 		d->bd_immediate = *(u_int *)addr;
75047584Smccanne 		break;
75153947Smccanne 
75253947Smccanne 	case BIOCVERSION:
75353947Smccanne 		{
75453947Smccanne 			struct bpf_version *bv = (struct bpf_version *)addr;
75553947Smccanne 
75653947Smccanne 			bv->bv_major = BPF_MAJOR_VERSION;
75753947Smccanne 			bv->bv_minor = BPF_MINOR_VERSION;
75853947Smccanne 			break;
75953947Smccanne 		}
76047584Smccanne 	}
76148932Smccanne 	return (error);
76247584Smccanne }
76347584Smccanne 
76453947Smccanne /*
76551425Smccanne  * Set d's packet filter program to fp.  If this file already has a filter,
76648932Smccanne  * free it and replace it.  Returns EINVAL for bogus requests.
76747584Smccanne  */
76847584Smccanne int
76947584Smccanne bpf_setf(d, fp)
77047584Smccanne 	struct bpf_d *d;
77147584Smccanne 	struct bpf_program *fp;
77247584Smccanne {
77348932Smccanne 	struct bpf_insn *fcode, *old;
77447584Smccanne 	u_int flen, size;
77547584Smccanne 	int s;
77647584Smccanne 
77748932Smccanne 	old = d->bd_filter;
77847584Smccanne 	if (fp->bf_insns == 0) {
77947584Smccanne 		if (fp->bf_len != 0)
78048932Smccanne 			return (EINVAL);
78148932Smccanne 		s = splimp();
78248967Smccanne 		d->bd_filter = 0;
78347584Smccanne 		reset_d(d);
78447584Smccanne 		splx(s);
78548967Smccanne 		if (old != 0)
78648932Smccanne 			free((caddr_t)old, M_DEVBUF);
78748932Smccanne 		return (0);
78847584Smccanne 	}
78947584Smccanne 	flen = fp->bf_len;
79048932Smccanne 	if (flen > BPF_MAXINSNS)
79148932Smccanne 		return (EINVAL);
79248932Smccanne 
79347584Smccanne 	size = flen * sizeof(*fp->bf_insns);
79448932Smccanne 	fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
79550417Smccanne 	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
79650417Smccanne 	    bpf_validate(fcode, (int)flen)) {
79748967Smccanne 		s = splimp();
79848932Smccanne 		d->bd_filter = fcode;
79947584Smccanne 		reset_d(d);
80047584Smccanne 		splx(s);
80148967Smccanne 		if (old != 0)
80248932Smccanne 			free((caddr_t)old, M_DEVBUF);
80347584Smccanne 
80448932Smccanne 		return (0);
80547584Smccanne 	}
80648932Smccanne 	free((caddr_t)fcode, M_DEVBUF);
80748932Smccanne 	return (EINVAL);
80847584Smccanne }
80947584Smccanne 
81047584Smccanne /*
81153947Smccanne  * Detach a file from its current interface (if attached at all) and attach
81253947Smccanne  * to the interface indicated by the name stored in ifr.
81351425Smccanne  * Return an errno or 0.
81447584Smccanne  */
81547584Smccanne static int
81647584Smccanne bpf_setif(d, ifr)
81747584Smccanne 	struct bpf_d *d;
81847584Smccanne 	struct ifreq *ifr;
81947584Smccanne {
82047584Smccanne 	struct bpf_if *bp;
82147584Smccanne 	char *cp;
82253947Smccanne 	int unit, s, error;
82347584Smccanne 
82447584Smccanne 	/*
82547584Smccanne 	 * Separate string into name part and unit number.  Put a null
82653947Smccanne 	 * byte at the end of the name part, and compute the number.
82747584Smccanne 	 * If the a unit number is unspecified, the default is 0,
82848932Smccanne 	 * as initialized above.  XXX This should be common code.
82947584Smccanne 	 */
83047584Smccanne 	unit = 0;
83147584Smccanne 	cp = ifr->ifr_name;
83247584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
83347584Smccanne 	while (*cp++) {
83447584Smccanne 		if (*cp >= '0' && *cp <= '9') {
83547584Smccanne 			unit = *cp - '0';
83647584Smccanne 			*cp++ = '\0';
83747584Smccanne 			while (*cp)
83847584Smccanne 				unit = 10 * unit + *cp++ - '0';
83947584Smccanne 			break;
84047584Smccanne 		}
84147584Smccanne 	}
84247584Smccanne 	/*
84347584Smccanne 	 * Look through attached interfaces for the named one.
84447584Smccanne 	 */
84549202Smccanne 	for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
84647584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
84747584Smccanne 
84853947Smccanne 		if (ifp == 0 || unit != ifp->if_unit
84947584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
85047584Smccanne 			continue;
85147584Smccanne 		/*
85253947Smccanne 		 * We found the requested interface.
85347584Smccanne 		 * If it's not up, return an error.
85453947Smccanne 		 * Allocate the packet buffers if we need to.
85553947Smccanne 		 * If we're already attached to requested interface,
85653947Smccanne 		 * just flush the buffer.
85747584Smccanne 		 */
85847584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
85948932Smccanne 			return (ENETDOWN);
86053947Smccanne 
86153947Smccanne 		if (d->bd_sbuf == 0) {
86253947Smccanne 			error = bpf_allocbufs(d);
86353947Smccanne 			if (error != 0)
86453947Smccanne 				return (error);
86553947Smccanne 		}
86647584Smccanne 		s = splimp();
86747584Smccanne 		if (bp != d->bd_bif) {
86847584Smccanne 			if (d->bd_bif)
86953947Smccanne 				/*
87048932Smccanne 				 * Detach if attached to something else.
87147584Smccanne 				 */
87247584Smccanne 				bpf_detachd(d);
87347584Smccanne 
87447584Smccanne 			bpf_attachd(d, bp);
87547584Smccanne 		}
87647584Smccanne 		reset_d(d);
87747584Smccanne 		splx(s);
87848932Smccanne 		return (0);
87947584Smccanne 	}
88047584Smccanne 	/* Not found. */
88148932Smccanne 	return (ENXIO);
88247584Smccanne }
88347584Smccanne 
88447584Smccanne /*
88551425Smccanne  * Convert an interface name plus unit number of an ifp to a single
88651425Smccanne  * name which is returned in the ifr.
88747584Smccanne  */
88847584Smccanne static void
88947584Smccanne bpf_ifname(ifp, ifr)
89047584Smccanne 	struct ifnet *ifp;
89147584Smccanne 	struct ifreq *ifr;
89247584Smccanne {
89347584Smccanne 	char *s = ifp->if_name;
89447584Smccanne 	char *d = ifr->ifr_name;
89547584Smccanne 
89647584Smccanne 	while (*d++ = *s++)
89753947Smccanne 		continue;
89848932Smccanne 	/* XXX Assume that unit number is less than 10. */
89947584Smccanne 	*d++ = ifp->if_unit + '0';
90047584Smccanne 	*d = '\0';
90147584Smccanne }
90247584Smccanne 
90347584Smccanne /*
90451425Smccanne  * The new select interface passes down the proc pointer; the old select
90551425Smccanne  * stubs had to grab it out of the user struct.  This glue allows either case.
90651425Smccanne  */
90751425Smccanne #if BSD >= 199103
90851425Smccanne #define bpf_select bpfselect
90951425Smccanne #else
91051425Smccanne int
91151425Smccanne bpfselect(dev, rw)
91251425Smccanne 	register dev_t dev;
91351425Smccanne 	int rw;
91451425Smccanne {
91553947Smccanne 	return (bpf_select(dev, rw, u.u_procp));
91651425Smccanne }
91751425Smccanne #endif
91851425Smccanne 
91951425Smccanne /*
92047584Smccanne  * Support for select() system call
92147584Smccanne  *
92253947Smccanne  * Return true iff the specific operation will not block indefinitely.
92353947Smccanne  * Otherwise, return false but make a note that a selwakeup() must be done.
92447584Smccanne  */
92547584Smccanne int
92651425Smccanne bpf_select(dev, rw, p)
92747584Smccanne 	register dev_t dev;
92847584Smccanne 	int rw;
92948932Smccanne 	struct proc *p;
93047584Smccanne {
93147584Smccanne 	register struct bpf_d *d;
93247584Smccanne 	register int s;
93353947Smccanne 
93447584Smccanne 	if (rw != FREAD)
93548932Smccanne 		return (0);
93647584Smccanne 	/*
93747584Smccanne 	 * An imitation of the FIONREAD ioctl code.
93847584Smccanne 	 */
93947584Smccanne 	d = &bpf_dtab[minor(dev)];
94053947Smccanne 
94147584Smccanne 	s = splimp();
94249723Smccanne 	if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
94347584Smccanne 		/*
94447584Smccanne 		 * There is data waiting.
94547584Smccanne 		 */
94647584Smccanne 		splx(s);
94748932Smccanne 		return (1);
94847584Smccanne 	}
94953947Smccanne #if BSD >= 199103
95053947Smccanne 	selrecord(p, &d->bd_sel);
95153947Smccanne #else
95247584Smccanne 	/*
95347584Smccanne 	 * No data ready.  If there's already a select() waiting on this
95453947Smccanne 	 * minor device then this is a collision.  This shouldn't happen
95547584Smccanne 	 * because minors really should not be shared, but if a process
95647584Smccanne 	 * forks while one of these is open, it is possible that both
95747584Smccanne 	 * processes could select on the same descriptor.
95847584Smccanne 	 */
95953947Smccanne 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
96053947Smccanne 		d->bd_selcoll = 1;
96153947Smccanne 	else
96253947Smccanne 		d->bd_selproc = p;
96353947Smccanne #endif
96453947Smccanne 	splx(s);
96548932Smccanne 	return (0);
96647584Smccanne }
96747584Smccanne 
96847584Smccanne /*
96953947Smccanne  * Incoming linkage from device drivers.  Process the packet pkt, of length
97053947Smccanne  * pktlen, which is stored in a contiguous buffer.  The packet is parsed
97153947Smccanne  * by each process' filter, and if accepted, stashed into the corresponding
97253947Smccanne  * buffer.
97347584Smccanne  */
97447584Smccanne void
97548932Smccanne bpf_tap(arg, pkt, pktlen)
97647584Smccanne 	caddr_t arg;
97748932Smccanne 	register u_char *pkt;
97848932Smccanne 	register u_int pktlen;
97947584Smccanne {
98047584Smccanne 	struct bpf_if *bp;
98147584Smccanne 	register struct bpf_d *d;
98247584Smccanne 	register u_int slen;
98347584Smccanne 	/*
98447584Smccanne 	 * Note that the ipl does not have to be raised at this point.
98547584Smccanne 	 * The only problem that could arise here is that if two different
98647584Smccanne 	 * interfaces shared any data.  This is not the case.
98747584Smccanne 	 */
98847584Smccanne 	bp = (struct bpf_if *)arg;
98947584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
99047584Smccanne 		++d->bd_rcount;
99149202Smccanne 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
99247584Smccanne 		if (slen != 0)
99349202Smccanne 			catchpacket(d, pkt, pktlen, slen, bcopy);
99447584Smccanne 	}
99547584Smccanne }
99647584Smccanne 
99747584Smccanne /*
99847584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
99947584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
100047584Smccanne  */
100147584Smccanne static void
1002*61337Sbostic bpf_mcopy(src_arg, dst_arg, len)
1003*61337Sbostic 	void *src_arg, *dst_arg;
1004*61337Sbostic 	register u_int len;
100547584Smccanne {
1006*61337Sbostic 	register struct mbuf *m;
1007*61337Sbostic 	register u_int count;
1008*61337Sbostic 	u_char *src, *dst;
100947584Smccanne 
1010*61337Sbostic 	src = src_arg;
1011*61337Sbostic 	dst = dst_arg;
1012*61337Sbostic 	m = src_arg;
101347584Smccanne 	while (len > 0) {
101447584Smccanne 		if (m == 0)
101549202Smccanne 			panic("bpf_mcopy");
101655065Spendry 		count = min(m->m_len, len);
101749202Smccanne 		bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
101849202Smccanne 		m = m->m_next;
101949202Smccanne 		dst += count;
102047584Smccanne 		len -= count;
102147584Smccanne 	}
102247584Smccanne }
102347584Smccanne 
102447584Smccanne /*
102553947Smccanne  * Incoming linkage from device drivers, when packet is in an mbuf chain.
102647584Smccanne  */
102747584Smccanne void
102849202Smccanne bpf_mtap(arg, m)
102947584Smccanne 	caddr_t arg;
103049202Smccanne 	struct mbuf *m;
103147584Smccanne {
103247584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
103347584Smccanne 	struct bpf_d *d;
103449202Smccanne 	u_int pktlen, slen;
103549202Smccanne 	struct mbuf *m0;
103647584Smccanne 
103748932Smccanne 	pktlen = 0;
103851425Smccanne 	for (m0 = m; m0 != 0; m0 = m0->m_next)
103949202Smccanne 		pktlen += m0->m_len;
104049723Smccanne 
104147584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
104247584Smccanne 		++d->bd_rcount;
104349202Smccanne 		slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
104447584Smccanne 		if (slen != 0)
104549202Smccanne 			catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
104647584Smccanne 	}
104747584Smccanne }
104847584Smccanne 
104947584Smccanne /*
105049202Smccanne  * Move the packet data from interface memory (pkt) into the
105147584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
105253947Smccanne  * otherwise 0.  "copy" is the routine called to do the actual data
105351425Smccanne  * transfer.  bcopy is passed in to copy contiguous chunks, while
105451425Smccanne  * bpf_mcopy is passed in to copy mbuf chains.  In the latter case,
105551425Smccanne  * pkt is really an mbuf.
105647584Smccanne  */
105747584Smccanne static void
105848932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn)
105948932Smccanne 	register struct bpf_d *d;
106048932Smccanne 	register u_char *pkt;
106148932Smccanne 	register u_int pktlen, snaplen;
106248932Smccanne 	register void (*cpfn)();
106347584Smccanne {
106448932Smccanne 	register struct bpf_hdr *hp;
106548932Smccanne 	register int totlen, curlen;
106648932Smccanne 	register int hdrlen = d->bd_bif->bif_hdrlen;
106747584Smccanne 	/*
106847584Smccanne 	 * Figure out how many bytes to move.  If the packet is
106947584Smccanne 	 * greater or equal to the snapshot length, transfer that
107047584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
107148932Smccanne 	 * we hit the buffer size limit).
107247584Smccanne 	 */
107355065Spendry 	totlen = hdrlen + min(snaplen, pktlen);
107450082Smccanne 	if (totlen > d->bd_bufsize)
107550082Smccanne 		totlen = d->bd_bufsize;
107647584Smccanne 
107747584Smccanne 	/*
107847584Smccanne 	 * Round up the end of the previous packet to the next longword.
107947584Smccanne 	 */
108048932Smccanne 	curlen = BPF_WORDALIGN(d->bd_slen);
108148932Smccanne 	if (curlen + totlen > d->bd_bufsize) {
108247584Smccanne 		/*
108347584Smccanne 		 * This packet will overflow the storage buffer.
108448932Smccanne 		 * Rotate the buffers if we can, then wakeup any
108548932Smccanne 		 * pending reads.
108647584Smccanne 		 */
108747584Smccanne 		if (d->bd_fbuf == 0) {
108853947Smccanne 			/*
108953947Smccanne 			 * We haven't completed the previous read yet,
109048932Smccanne 			 * so drop the packet.
109147584Smccanne 			 */
109247584Smccanne 			++d->bd_dcount;
109347584Smccanne 			return;
109447584Smccanne 		}
109548932Smccanne 		ROTATE_BUFFERS(d);
109647584Smccanne 		bpf_wakeup(d);
109748932Smccanne 		curlen = 0;
109847584Smccanne 	}
109953947Smccanne 	else if (d->bd_immediate)
110047584Smccanne 		/*
110147584Smccanne 		 * Immediate mode is set.  A packet arrived so any
110247584Smccanne 		 * reads should be woken up.
110347584Smccanne 		 */
110447584Smccanne 		bpf_wakeup(d);
110548932Smccanne 
110647584Smccanne 	/*
110747584Smccanne 	 * Append the bpf header.
110847584Smccanne 	 */
110948932Smccanne 	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
111051425Smccanne #if BSD >= 199103
111147584Smccanne 	microtime(&hp->bh_tstamp);
111253947Smccanne #elif defined(sun)
111353947Smccanne 	uniqtime(&hp->bh_tstamp);
111447584Smccanne #else
111547584Smccanne 	hp->bh_tstamp = time;
111647584Smccanne #endif
111748932Smccanne 	hp->bh_datalen = pktlen;
111847584Smccanne 	hp->bh_hdrlen = hdrlen;
111947584Smccanne 	/*
112048932Smccanne 	 * Copy the packet data into the store buffer and update its length.
112147584Smccanne 	 */
112248932Smccanne 	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
112348932Smccanne 	d->bd_slen = curlen + totlen;
112447584Smccanne }
112547584Smccanne 
112653947Smccanne /*
112747584Smccanne  * Initialize all nonzero fields of a descriptor.
112847584Smccanne  */
112947584Smccanne static int
113053947Smccanne bpf_allocbufs(d)
113147584Smccanne 	register struct bpf_d *d;
113247584Smccanne {
113348932Smccanne 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
113448932Smccanne 	if (d->bd_fbuf == 0)
113548932Smccanne 		return (ENOBUFS);
113647584Smccanne 
113748932Smccanne 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
113848932Smccanne 	if (d->bd_sbuf == 0) {
113948932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
114048932Smccanne 		return (ENOBUFS);
114147584Smccanne 	}
114248932Smccanne 	d->bd_slen = 0;
114348932Smccanne 	d->bd_hlen = 0;
114448932Smccanne 	return (0);
114547584Smccanne }
114647584Smccanne 
114747584Smccanne /*
114851425Smccanne  * Free buffers currently in use by a descriptor.
114951425Smccanne  * Called on close.
115047584Smccanne  */
115153947Smccanne static void
115251425Smccanne bpf_freed(d)
115351425Smccanne 	register struct bpf_d *d;
115451425Smccanne {
115551425Smccanne 	/*
115651425Smccanne 	 * We don't need to lock out interrupts since this descriptor has
115753947Smccanne 	 * been detached from its interface and it yet hasn't been marked
115851425Smccanne 	 * free.
115951425Smccanne 	 */
116053947Smccanne 	if (d->bd_sbuf != 0) {
116153947Smccanne 		free(d->bd_sbuf, M_DEVBUF);
116253947Smccanne 		if (d->bd_hbuf != 0)
116353947Smccanne 			free(d->bd_hbuf, M_DEVBUF);
116453947Smccanne 		if (d->bd_fbuf != 0)
116553947Smccanne 			free(d->bd_fbuf, M_DEVBUF);
116653947Smccanne 	}
116751425Smccanne 	if (d->bd_filter)
116851425Smccanne 		free((caddr_t)d->bd_filter, M_DEVBUF);
116953947Smccanne 
117051425Smccanne 	D_MARKFREE(d);
117151425Smccanne }
117251425Smccanne 
117351425Smccanne /*
117451425Smccanne  * Attach an interface to bpf.  driverp is a pointer to a (struct bpf_if *)
117551425Smccanne  * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
117651425Smccanne  * size of the link header (variable length headers not yet supported).
117751425Smccanne  */
117847584Smccanne void
117949202Smccanne bpfattach(driverp, ifp, dlt, hdrlen)
118047584Smccanne 	caddr_t *driverp;
118147584Smccanne 	struct ifnet *ifp;
118249202Smccanne 	u_int dlt, hdrlen;
118347584Smccanne {
118447584Smccanne 	struct bpf_if *bp;
118547584Smccanne 	int i;
118651425Smccanne #if BSD < 199103
118751425Smccanne 	static struct bpf_if bpf_ifs[NBPFILTER];
118851425Smccanne 	static int bpfifno;
118947584Smccanne 
119051425Smccanne 	bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0;
119151425Smccanne #else
119249202Smccanne 	bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
119351425Smccanne #endif
119449202Smccanne 	if (bp == 0)
119549202Smccanne 		panic("bpfattach");
119647584Smccanne 
119747584Smccanne 	bp->bif_dlist = 0;
119847584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
119947584Smccanne 	bp->bif_ifp = ifp;
120049202Smccanne 	bp->bif_dlt = dlt;
120147584Smccanne 
120249202Smccanne 	bp->bif_next = bpf_iflist;
120349202Smccanne 	bpf_iflist = bp;
120449202Smccanne 
120548932Smccanne 	*bp->bif_driverp = 0;
120648932Smccanne 
120747584Smccanne 	/*
120847584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
120953947Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
121053947Smccanne 	 * that the network layer header begins on a longword boundary (for
121147584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
121247584Smccanne 	 */
121349202Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
121447584Smccanne 
121547584Smccanne 	/*
121647584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
121747584Smccanne 	 */
121847584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
121947584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
122047584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
122147584Smccanne 
122247584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
122347584Smccanne }
122447584Smccanne 
122551425Smccanne #if BSD >= 199103
122648967Smccanne /* XXX This routine belongs in net/if.c. */
122748932Smccanne /*
122853947Smccanne  * Set/clear promiscuous mode on interface ifp based on the truth value
122948932Smccanne  * of pswitch.  The calls are reference counted so that only the first
123053947Smccanne  * "on" request actually has an effect, as does the final "off" request.
123153947Smccanne  * Results are undefined if the "off" and "on" requests are not matched.
123248932Smccanne  */
123348932Smccanne int
123448932Smccanne ifpromisc(ifp, pswitch)
123548932Smccanne 	struct ifnet *ifp;
123648932Smccanne 	int pswitch;
123748932Smccanne {
123849726Smccanne 	struct ifreq ifr;
123953947Smccanne 	/*
124048932Smccanne 	 * If the device is not configured up, we cannot put it in
124148932Smccanne 	 * promiscuous mode.
124248932Smccanne 	 */
124348932Smccanne 	if ((ifp->if_flags & IFF_UP) == 0)
124448932Smccanne 		return (ENETDOWN);
124548932Smccanne 
124648932Smccanne 	if (pswitch) {
124748932Smccanne 		if (ifp->if_pcount++ != 0)
124848932Smccanne 			return (0);
124948932Smccanne 		ifp->if_flags |= IFF_PROMISC;
125048932Smccanne 	} else {
125148932Smccanne 		if (--ifp->if_pcount > 0)
125248932Smccanne 			return (0);
125348932Smccanne 		ifp->if_flags &= ~IFF_PROMISC;
125448932Smccanne 	}
125549726Smccanne 	ifr.ifr_flags = ifp->if_flags;
125649726Smccanne 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
125748932Smccanne }
125851425Smccanne #endif
125948932Smccanne 
126051425Smccanne #if BSD < 199103
126151425Smccanne /*
126251425Smccanne  * Allocate some memory for bpf.  This is temporary SunOS support, and
126353947Smccanne  * is admittedly a hack.
126451425Smccanne  * If resources unavaiable, return 0.
126551425Smccanne  */
126651425Smccanne static caddr_t
126751425Smccanne bpf_alloc(size, canwait)
126851425Smccanne 	register int size;
126951425Smccanne 	register int canwait;
127051425Smccanne {
127151425Smccanne 	register struct mbuf *m;
127251425Smccanne 
127351425Smccanne 	if ((unsigned)size > (MCLBYTES-8))
127451425Smccanne 		return 0;
127551425Smccanne 
127651425Smccanne 	MGET(m, canwait, MT_DATA);
127751425Smccanne 	if (m == 0)
127851425Smccanne 		return 0;
127951425Smccanne 	if ((unsigned)size > (MLEN-8)) {
128051425Smccanne 		MCLGET(m);
128151425Smccanne 		if (m->m_len != MCLBYTES) {
128251425Smccanne 			m_freem(m);
128351425Smccanne 			return 0;
128451425Smccanne 		}
128551425Smccanne 	}
128651425Smccanne 	*mtod(m, struct mbuf **) = m;
128751425Smccanne 	return mtod(m, caddr_t) + 8;
128851425Smccanne }
128951425Smccanne #endif
129051425Smccanne #endif
1291