xref: /csrg-svn/sys/net/bpf.c (revision 68168)
151440Smccanne /*
263207Sbostic  * Copyright (c) 1990, 1991, 1993
363207Sbostic  *	The Regents of the University of California.  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*68168Scgd  *      @(#)bpf.c	8.4 (Berkeley) 01/09/95
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 
2247584Smccanne #include <sys/param.h>
2347584Smccanne #include <sys/systm.h>
2447584Smccanne #include <sys/mbuf.h>
2547584Smccanne #include <sys/buf.h>
2653947Smccanne #include <sys/time.h>
2748932Smccanne #include <sys/proc.h>
2847584Smccanne #include <sys/user.h>
2947584Smccanne #include <sys/ioctl.h>
3047584Smccanne #include <sys/map.h>
3147584Smccanne 
3247584Smccanne #include <sys/file.h>
3351425Smccanne #if defined(sparc) && BSD < 199103
3447584Smccanne #include <sys/stream.h>
3547584Smccanne #endif
3647584Smccanne #include <sys/tty.h>
3747584Smccanne #include <sys/uio.h>
3847584Smccanne 
3947584Smccanne #include <sys/protosw.h>
4047584Smccanne #include <sys/socket.h>
4147584Smccanne #include <net/if.h>
4247584Smccanne 
4347584Smccanne #include <net/bpf.h>
4447584Smccanne #include <net/bpfdesc.h>
4547584Smccanne 
4647584Smccanne #include <sys/errno.h>
4747584Smccanne 
4847584Smccanne #include <netinet/in.h>
4947584Smccanne #include <netinet/if_ether.h>
5047584Smccanne #include <sys/kernel.h>
5147584Smccanne 
5251425Smccanne /*
5351425Smccanne  * Older BSDs don't have kernel malloc.
5451425Smccanne  */
5551425Smccanne #if BSD < 199103
5651425Smccanne extern bcopy();
5751425Smccanne static caddr_t bpf_alloc();
5853947Smccanne #include <net/bpf_compat.h>
5951425Smccanne #define BPF_BUFSIZE (MCLBYTES-8)
6053947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)
6151425Smccanne #else
6251425Smccanne #define BPF_BUFSIZE 4096
6353947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)
6451425Smccanne #endif
6551425Smccanne 
6647584Smccanne #define PRINET  26			/* interruptible */
6747584Smccanne 
6847584Smccanne /*
6948932Smccanne  * The default read buffer size is patchable.
7048932Smccanne  */
7151425Smccanne int bpf_bufsize = BPF_BUFSIZE;
7248932Smccanne 
7348932Smccanne /*
7449202Smccanne  *  bpf_iflist is the list of interfaces; each corresponds to an ifnet
7549202Smccanne  *  bpf_dtab holds the descriptors, indexed by minor device #
7647584Smccanne  */
7753947Smccanne struct bpf_if	*bpf_iflist;
7853947Smccanne struct bpf_d	bpf_dtab[NBPFILTER];
7947584Smccanne 
8059122Storek #if BSD >= 199207
8159122Storek /*
8259122Storek  * bpfilterattach() is called at boot time in new systems.  We do
8359122Storek  * nothing here since old systems will not call this.
8459122Storek  */
8559122Storek /* ARGSUSED */
8659122Storek void
bpfilterattach(n)8759122Storek bpfilterattach(n)
8859122Storek 	int n;
8959122Storek {
9059122Storek }
9159122Storek #endif
9259122Storek 
9361337Sbostic static int	bpf_allocbufs __P((struct bpf_d *));
9461337Sbostic static int	bpf_allocbufs __P((struct bpf_d *));
9561337Sbostic static void	bpf_freed __P((struct bpf_d *));
9661337Sbostic static void	bpf_freed __P((struct bpf_d *));
9761337Sbostic static void	bpf_ifname __P((struct ifnet *, struct ifreq *));
9861337Sbostic static void	bpf_ifname __P((struct ifnet *, struct ifreq *));
9966504Sbostic static void	bpf_mcopy __P((const void *, void *, u_int));
10061337Sbostic static int	bpf_movein __P((struct uio *, int,
10161337Sbostic 		    struct mbuf **, struct sockaddr *, int *));
10261337Sbostic static int	bpf_setif __P((struct bpf_d *, struct ifreq *));
10361337Sbostic static int	bpf_setif __P((struct bpf_d *, struct ifreq *));
10467634Smckusick static __inline void
10561337Sbostic 		bpf_wakeup __P((struct bpf_d *));
10661337Sbostic static void	catchpacket __P((struct bpf_d *, u_char *, u_int,
10766504Sbostic 		    u_int, void (*)(const void *, void *, u_int)));
10861337Sbostic static void	reset_d __P((struct bpf_d *));
10947584Smccanne 
11047584Smccanne static int
bpf_movein(uio,linktype,mp,sockp,datlen)11155289Smckusick bpf_movein(uio, linktype, mp, sockp, datlen)
11247584Smccanne 	register struct uio *uio;
11355289Smckusick 	int linktype, *datlen;
11447584Smccanne 	register struct mbuf **mp;
11547584Smccanne 	register struct sockaddr *sockp;
11647584Smccanne {
11747584Smccanne 	struct mbuf *m;
11847584Smccanne 	int error;
11947584Smccanne 	int len;
12047584Smccanne 	int hlen;
12147584Smccanne 
12247584Smccanne 	/*
12347584Smccanne 	 * Build a sockaddr based on the data link layer type.
12447584Smccanne 	 * We do this at this level because the ethernet header
12547584Smccanne 	 * is copied directly into the data field of the sockaddr.
12647584Smccanne 	 * In the case of SLIP, there is no header and the packet
12747584Smccanne 	 * is forwarded as is.
12847584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
12947584Smccanne 	 * for the link level header.
13047584Smccanne 	 */
13147584Smccanne 	switch (linktype) {
13253947Smccanne 
13347584Smccanne 	case DLT_SLIP:
13447584Smccanne 		sockp->sa_family = AF_INET;
13547584Smccanne 		hlen = 0;
13647584Smccanne 		break;
13747584Smccanne 
13847584Smccanne 	case DLT_EN10MB:
13947584Smccanne 		sockp->sa_family = AF_UNSPEC;
14047584Smccanne 		/* XXX Would MAXLINKHDR be better? */
14147584Smccanne 		hlen = sizeof(struct ether_header);
14247584Smccanne 		break;
14347584Smccanne 
14453947Smccanne 	case DLT_FDDI:
14547584Smccanne 		sockp->sa_family = AF_UNSPEC;
14647584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
14747584Smccanne 		hlen = 24;
14847584Smccanne 		break;
14947584Smccanne 
15053947Smccanne 	case DLT_NULL:
15153947Smccanne 		sockp->sa_family = AF_UNSPEC;
15253947Smccanne 		hlen = 0;
15353947Smccanne 		break;
15453947Smccanne 
15547584Smccanne 	default:
15648932Smccanne 		return (EIO);
15747584Smccanne 	}
15847584Smccanne 
15947584Smccanne 	len = uio->uio_resid;
16055289Smckusick 	*datlen = len - hlen;
16147584Smccanne 	if ((unsigned)len > MCLBYTES)
16248932Smccanne 		return (EIO);
16347584Smccanne 
16447584Smccanne 	MGET(m, M_WAIT, MT_DATA);
16547584Smccanne 	if (m == 0)
16648932Smccanne 		return (ENOBUFS);
16747584Smccanne 	if (len > MLEN) {
16851425Smccanne #if BSD >= 199103
16948932Smccanne 		MCLGET(m, M_WAIT);
17048932Smccanne 		if ((m->m_flags & M_EXT) == 0) {
17151425Smccanne #else
17251425Smccanne 		MCLGET(m);
17353947Smccanne 		if (m->m_len != MCLBYTES) {
17451425Smccanne #endif
17553947Smccanne 			error = ENOBUFS;
17647584Smccanne 			goto bad;
17747584Smccanne 		}
17847584Smccanne 	}
17947584Smccanne 	m->m_len = len;
18047584Smccanne 	*mp = m;
18147584Smccanne 	/*
18247584Smccanne 	 * Make room for link header.
18347584Smccanne 	 */
18453947Smccanne 	if (hlen != 0) {
18547584Smccanne 		m->m_len -= hlen;
18651425Smccanne #if BSD >= 199103
18748932Smccanne 		m->m_data += hlen; /* XXX */
18851425Smccanne #else
18951425Smccanne 		m->m_off += hlen;
19051425Smccanne #endif
19153947Smccanne 		error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
19247584Smccanne 		if (error)
19347584Smccanne 			goto bad;
19447584Smccanne 	}
19553947Smccanne 	error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
19653947Smccanne 	if (!error)
19748932Smccanne 		return (0);
19847584Smccanne  bad:
19947584Smccanne 	m_freem(m);
20048932Smccanne 	return (error);
20147584Smccanne }
20247584Smccanne 
20347584Smccanne /*
20451425Smccanne  * Attach file to the bpf interface, i.e. make d listen on bp.
20547584Smccanne  * Must be called at splimp.
20647584Smccanne  */
20747584Smccanne static void
bpf_attachd(d,bp)20847584Smccanne bpf_attachd(d, bp)
20947584Smccanne 	struct bpf_d *d;
21047584Smccanne 	struct bpf_if *bp;
21147584Smccanne {
21251425Smccanne 	/*
21351425Smccanne 	 * Point d at bp, and add d to the interface's list of listeners.
21451425Smccanne 	 * Finally, point the driver's bpf cookie at the interface so
21551425Smccanne 	 * it will divert packets to bpf.
21651425Smccanne 	 */
21747584Smccanne 	d->bd_bif = bp;
21847584Smccanne 	d->bd_next = bp->bif_dlist;
21947584Smccanne 	bp->bif_dlist = d;
22047584Smccanne 
22147584Smccanne 	*bp->bif_driverp = bp;
22247584Smccanne }
22347584Smccanne 
22451425Smccanne /*
22551425Smccanne  * Detach a file from its interface.
22651425Smccanne  */
22747584Smccanne static void
bpf_detachd(d)22847584Smccanne bpf_detachd(d)
22947584Smccanne 	struct bpf_d *d;
23047584Smccanne {
23147584Smccanne 	struct bpf_d **p;
23247584Smccanne 	struct bpf_if *bp;
23347584Smccanne 
23447584Smccanne 	bp = d->bd_bif;
23547584Smccanne 	/*
23647584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
23747584Smccanne 	 * If so, turn it off.
23847584Smccanne 	 */
23947584Smccanne 	if (d->bd_promisc) {
24047584Smccanne 		d->bd_promisc = 0;
24147584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
24247584Smccanne 			/*
24347584Smccanne 			 * Something is really wrong if we were able to put
24447584Smccanne 			 * the driver into promiscuous mode, but can't
24547584Smccanne 			 * take it out.
24647584Smccanne 			 */
24751425Smccanne 			panic("bpf: ifpromisc failed");
24847584Smccanne 	}
24951425Smccanne 	/* Remove d from the interface's descriptor list. */
25047584Smccanne 	p = &bp->bif_dlist;
25147584Smccanne 	while (*p != d) {
25247584Smccanne 		p = &(*p)->bd_next;
25347584Smccanne 		if (*p == 0)
25447584Smccanne 			panic("bpf_detachd: descriptor not in list");
25547584Smccanne 	}
25647584Smccanne 	*p = (*p)->bd_next;
25747584Smccanne 	if (bp->bif_dlist == 0)
25847584Smccanne 		/*
25947584Smccanne 		 * Let the driver know that there are no more listeners.
26047584Smccanne 		 */
26147584Smccanne 		*d->bd_bif->bif_driverp = 0;
26247584Smccanne 	d->bd_bif = 0;
26347584Smccanne }
26447584Smccanne 
26547584Smccanne 
26647584Smccanne /*
26753947Smccanne  * Mark a descriptor free by making it point to itself.
26847584Smccanne  * This is probably cheaper than marking with a constant since
26947584Smccanne  * the address should be in a register anyway.
27047584Smccanne  */
27147584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
27247584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
27347584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
27447584Smccanne 
27547584Smccanne /*
27653947Smccanne  * Open ethernet device.  Returns ENXIO for illegal minor device number,
27753947Smccanne  * EBUSY if file is open by another process.
27847584Smccanne  */
27947584Smccanne /* ARGSUSED */
28047584Smccanne int
bpfopen(dev,flag)28147584Smccanne bpfopen(dev, flag)
28247584Smccanne 	dev_t dev;
28347584Smccanne 	int flag;
28447584Smccanne {
28547584Smccanne 	register struct bpf_d *d;
28653947Smccanne 
28747584Smccanne 	if (minor(dev) >= NBPFILTER)
28848932Smccanne 		return (ENXIO);
28947584Smccanne 	/*
29047584Smccanne 	 * Each minor can be opened by only one process.  If the requested
29147584Smccanne 	 * minor is in use, return EBUSY.
29247584Smccanne 	 */
29347584Smccanne 	d = &bpf_dtab[minor(dev)];
29453947Smccanne 	if (!D_ISFREE(d))
29548932Smccanne 		return (EBUSY);
29647584Smccanne 
29753947Smccanne 	/* Mark "free" and do most initialization. */
29853947Smccanne 	bzero((char *)d, sizeof(*d));
29953947Smccanne 	d->bd_bufsize = bpf_bufsize;
30053947Smccanne 
30148932Smccanne 	return (0);
30247584Smccanne }
30347584Smccanne 
30447584Smccanne /*
30547584Smccanne  * Close the descriptor by detaching it from its interface,
30647584Smccanne  * deallocating its buffers, and marking it free.
30747584Smccanne  */
30847584Smccanne /* ARGSUSED */
30953947Smccanne int
bpfclose(dev,flag)31047584Smccanne bpfclose(dev, flag)
31147584Smccanne 	dev_t dev;
31247584Smccanne 	int flag;
31347584Smccanne {
31447584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
31553947Smccanne 	register int s;
31647584Smccanne 
31747584Smccanne 	s = splimp();
31847584Smccanne 	if (d->bd_bif)
31947584Smccanne 		bpf_detachd(d);
32047584Smccanne 	splx(s);
32153947Smccanne 	bpf_freed(d);
32247584Smccanne 
32353947Smccanne 	return (0);
32447584Smccanne }
32547584Smccanne 
32653947Smccanne /*
32753947Smccanne  * Support for SunOS, which does not have tsleep.
32853947Smccanne  */
32951425Smccanne #if BSD < 199103
33051425Smccanne static
bpf_timeout(arg)33151425Smccanne bpf_timeout(arg)
33251425Smccanne 	caddr_t arg;
33351425Smccanne {
33451425Smccanne 	struct bpf_d *d = (struct bpf_d *)arg;
33551425Smccanne 	d->bd_timedout = 1;
33651425Smccanne 	wakeup(arg);
33751425Smccanne }
33851425Smccanne 
33953947Smccanne #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan)
34053947Smccanne 
34153947Smccanne int
bpf_sleep(d)34253947Smccanne bpf_sleep(d)
34353947Smccanne 	register struct bpf_d *d;
34451425Smccanne {
34553947Smccanne 	register int rto = d->bd_rtout;
34653947Smccanne 	register int st;
34751425Smccanne 
34853947Smccanne 	if (rto != 0) {
34951425Smccanne 		d->bd_timedout = 0;
35053947Smccanne 		timeout(bpf_timeout, (caddr_t)d, rto);
35151425Smccanne 	}
35253947Smccanne 	st = sleep((caddr_t)d, PRINET|PCATCH);
35353947Smccanne 	if (rto != 0) {
35453947Smccanne 		if (d->bd_timedout == 0)
35553947Smccanne 			untimeout(bpf_timeout, (caddr_t)d);
35653947Smccanne 		else if (st == 0)
35751425Smccanne 			return EWOULDBLOCK;
35851425Smccanne 	}
35953947Smccanne 	return (st != 0) ? EINTR : 0;
36051425Smccanne }
36153947Smccanne #else
36253947Smccanne #define BPF_SLEEP tsleep
36351425Smccanne #endif
36451425Smccanne 
36547584Smccanne /*
36648932Smccanne  * Rotate the packet buffers in descriptor d.  Move the store buffer
36753947Smccanne  * into the hold slot, and the free buffer into the store slot.
36848932Smccanne  * Zero the length of the new store buffer.
36948932Smccanne  */
37048932Smccanne #define ROTATE_BUFFERS(d) \
37148932Smccanne 	(d)->bd_hbuf = (d)->bd_sbuf; \
37248932Smccanne 	(d)->bd_hlen = (d)->bd_slen; \
37348932Smccanne 	(d)->bd_sbuf = (d)->bd_fbuf; \
37448932Smccanne 	(d)->bd_slen = 0; \
37553947Smccanne 	(d)->bd_fbuf = 0;
37648932Smccanne /*
37747584Smccanne  *  bpfread - read next chunk of packets from buffers
37847584Smccanne  */
37947584Smccanne int
bpfread(dev,uio)38047584Smccanne bpfread(dev, uio)
38147584Smccanne 	dev_t dev;
38247584Smccanne 	register struct uio *uio;
38347584Smccanne {
38447584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
38547584Smccanne 	int error;
38647584Smccanne 	int s;
38747584Smccanne 
38847584Smccanne 	/*
38953947Smccanne 	 * Restrict application to use a buffer the same size as
39047584Smccanne 	 * as kernel buffers.
39147584Smccanne 	 */
39248932Smccanne 	if (uio->uio_resid != d->bd_bufsize)
39349202Smccanne 		return (EINVAL);
39447584Smccanne 
39547584Smccanne 	s = splimp();
39647584Smccanne 	/*
39753947Smccanne 	 * If the hold buffer is empty, then do a timed sleep, which
39853947Smccanne 	 * ends when the timeout expires or when enough packets
39953947Smccanne 	 * have arrived to fill the store buffer.
40047584Smccanne 	 */
40147584Smccanne 	while (d->bd_hbuf == 0) {
40248932Smccanne 		if (d->bd_immediate && d->bd_slen != 0) {
40347584Smccanne 			/*
40447584Smccanne 			 * A packet(s) either arrived since the previous
40547584Smccanne 			 * read or arrived while we were asleep.
40647584Smccanne 			 * Rotate the buffers and return what's here.
40747584Smccanne 			 */
40848932Smccanne 			ROTATE_BUFFERS(d);
40947584Smccanne 			break;
41047584Smccanne 		}
41153947Smccanne 		error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf",
41253947Smccanne 				  d->bd_rtout);
41348932Smccanne 		if (error == EINTR || error == ERESTART) {
41448932Smccanne 			splx(s);
41548932Smccanne 			return (error);
41647584Smccanne 		}
41748932Smccanne 		if (error == EWOULDBLOCK) {
41847584Smccanne 			/*
41947584Smccanne 			 * On a timeout, return what's in the buffer,
42048932Smccanne 			 * which may be nothing.  If there is something
42148932Smccanne 			 * in the store buffer, we can rotate the buffers.
42247584Smccanne 			 */
42347584Smccanne 			if (d->bd_hbuf)
42447584Smccanne 				/*
42553947Smccanne 				 * We filled up the buffer in between
42647584Smccanne 				 * getting the timeout and arriving
42747584Smccanne 				 * here, so we don't need to rotate.
42847584Smccanne 				 */
42947584Smccanne 				break;
43047584Smccanne 
43148932Smccanne 			if (d->bd_slen == 0) {
43247584Smccanne 				splx(s);
43348932Smccanne 				return (0);
43447584Smccanne 			}
43548932Smccanne 			ROTATE_BUFFERS(d);
43647584Smccanne 			break;
43747584Smccanne 		}
43847584Smccanne 	}
43947584Smccanne 	/*
44047584Smccanne 	 * At this point, we know we have something in the hold slot.
44147584Smccanne 	 */
44247584Smccanne 	splx(s);
44353947Smccanne 
44453947Smccanne 	/*
44547584Smccanne 	 * Move data from hold buffer into user space.
44647584Smccanne 	 * We know the entire buffer is transferred since
44748932Smccanne 	 * we checked above that the read buffer is bpf_bufsize bytes.
44847584Smccanne 	 */
44953947Smccanne 	error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
45053947Smccanne 
45147584Smccanne 	s = splimp();
45248932Smccanne 	d->bd_fbuf = d->bd_hbuf;
45348932Smccanne 	d->bd_hbuf = 0;
45453947Smccanne 	d->bd_hlen = 0;
45547584Smccanne 	splx(s);
45653947Smccanne 
45748932Smccanne 	return (error);
45847584Smccanne }
45947584Smccanne 
46047584Smccanne 
46147584Smccanne /*
46253947Smccanne  * If there are processes sleeping on this descriptor, wake them up.
46347584Smccanne  */
46467634Smckusick static __inline void
bpf_wakeup(d)46547584Smccanne bpf_wakeup(d)
46647584Smccanne 	register struct bpf_d *d;
46747584Smccanne {
46848932Smccanne 	wakeup((caddr_t)d);
46953947Smccanne #if BSD >= 199103
47053947Smccanne 	selwakeup(&d->bd_sel);
47153947Smccanne 	/* XXX */
47253947Smccanne 	d->bd_sel.si_pid = 0;
47353947Smccanne #else
47453947Smccanne 	if (d->bd_selproc) {
47553947Smccanne 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
47653947Smccanne 		d->bd_selcoll = 0;
47753947Smccanne 		d->bd_selproc = 0;
47853947Smccanne 	}
47953947Smccanne #endif
48047584Smccanne }
48147584Smccanne 
48247584Smccanne int
bpfwrite(dev,uio)48347584Smccanne bpfwrite(dev, uio)
48447584Smccanne 	dev_t dev;
48547584Smccanne 	struct uio *uio;
48647584Smccanne {
48747584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
48847584Smccanne 	struct ifnet *ifp;
48947584Smccanne 	struct mbuf *m;
49047584Smccanne 	int error, s;
49147584Smccanne 	static struct sockaddr dst;
49255289Smckusick 	int datlen;
49347584Smccanne 
49447584Smccanne 	if (d->bd_bif == 0)
49548932Smccanne 		return (ENXIO);
49647584Smccanne 
49747584Smccanne 	ifp = d->bd_bif->bif_ifp;
49847584Smccanne 
49947584Smccanne 	if (uio->uio_resid == 0)
50048932Smccanne 		return (0);
50147584Smccanne 
50255289Smckusick 	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen);
50347584Smccanne 	if (error)
50448932Smccanne 		return (error);
50547584Smccanne 
50655289Smckusick 	if (datlen > ifp->if_mtu)
50755289Smckusick 		return (EMSGSIZE);
50855289Smckusick 
50947584Smccanne 	s = splnet();
51051425Smccanne #if BSD >= 199103
51153947Smccanne 	error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
51251425Smccanne #else
51347584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
51451425Smccanne #endif
51547584Smccanne 	splx(s);
51647584Smccanne 	/*
51753947Smccanne 	 * The driver frees the mbuf.
51847584Smccanne 	 */
51948932Smccanne 	return (error);
52047584Smccanne }
52147584Smccanne 
52247584Smccanne /*
52353947Smccanne  * Reset a descriptor by flushing its packet buffer and clearing the
52453947Smccanne  * receive and drop counts.  Should be called at splimp.
52547584Smccanne  */
52647584Smccanne static void
reset_d(d)52747584Smccanne reset_d(d)
52847584Smccanne 	struct bpf_d *d;
52947584Smccanne {
53047584Smccanne 	if (d->bd_hbuf) {
53147584Smccanne 		/* Free the hold buffer. */
53247584Smccanne 		d->bd_fbuf = d->bd_hbuf;
53347584Smccanne 		d->bd_hbuf = 0;
53447584Smccanne 	}
53548932Smccanne 	d->bd_slen = 0;
53653947Smccanne 	d->bd_hlen = 0;
53747584Smccanne 	d->bd_rcount = 0;
53847584Smccanne 	d->bd_dcount = 0;
53947584Smccanne }
54047584Smccanne 
54147584Smccanne /*
54247584Smccanne  *  FIONREAD		Check for read packet available.
54347584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
54447584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
54547584Smccanne  *  BIOCSETF		Set ethernet read filter.
54647584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
54747584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
54849202Smccanne  *  BIOCGDLT		Get link layer type.
54947584Smccanne  *  BIOCGETIF		Get interface name.
55047584Smccanne  *  BIOCSETIF		Set interface.
55147584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
55247584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
55347584Smccanne  *  BIOCGSTATS		Get packet stats.
55447584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
55553947Smccanne  *  BIOCVERSION		Get filter language version.
55647584Smccanne  */
55747584Smccanne /* ARGSUSED */
55847584Smccanne int
bpfioctl(dev,cmd,addr,flag)55947584Smccanne bpfioctl(dev, cmd, addr, flag)
56047584Smccanne 	dev_t dev;
561*68168Scgd 	u_long cmd;
56247584Smccanne 	caddr_t addr;
56347584Smccanne 	int flag;
56447584Smccanne {
56547584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
56647584Smccanne 	int s, error = 0;
56747584Smccanne 
56847584Smccanne 	switch (cmd) {
56947584Smccanne 
57047584Smccanne 	default:
57147584Smccanne 		error = EINVAL;
57247584Smccanne 		break;
57347584Smccanne 
57447584Smccanne 	/*
57547584Smccanne 	 * Check for read packet available.
57647584Smccanne 	 */
57747584Smccanne 	case FIONREAD:
57847584Smccanne 		{
57947584Smccanne 			int n;
58053947Smccanne 
58147584Smccanne 			s = splimp();
58248932Smccanne 			n = d->bd_slen;
58353947Smccanne 			if (d->bd_hbuf)
58448932Smccanne 				n += d->bd_hlen;
58547584Smccanne 			splx(s);
58647584Smccanne 
58747584Smccanne 			*(int *)addr = n;
58847584Smccanne 			break;
58947584Smccanne 		}
59047584Smccanne 
59147584Smccanne 	case SIOCGIFADDR:
59247584Smccanne 		{
59347584Smccanne 			struct ifnet *ifp;
59447584Smccanne 
59547584Smccanne 			if (d->bd_bif == 0)
59647584Smccanne 				error = EINVAL;
59747584Smccanne 			else {
59847584Smccanne 				ifp = d->bd_bif->bif_ifp;
59953947Smccanne 				error = (*ifp->if_ioctl)(ifp, cmd, addr);
60047584Smccanne 			}
60147584Smccanne 			break;
60247584Smccanne 		}
60347584Smccanne 
60447584Smccanne 	/*
60547584Smccanne 	 * Get buffer len [for read()].
60647584Smccanne 	 */
60747584Smccanne 	case BIOCGBLEN:
60848932Smccanne 		*(u_int *)addr = d->bd_bufsize;
60947584Smccanne 		break;
61047584Smccanne 
61147584Smccanne 	/*
61253947Smccanne 	 * Set buffer length.
61353947Smccanne 	 */
61453947Smccanne 	case BIOCSBLEN:
61553947Smccanne #if BSD < 199103
61653947Smccanne 		error = EINVAL;
61753947Smccanne #else
61853947Smccanne 		if (d->bd_bif != 0)
61953947Smccanne 			error = EINVAL;
62053947Smccanne 		else {
62153947Smccanne 			register u_int size = *(u_int *)addr;
62253947Smccanne 
62353947Smccanne 			if (size > BPF_MAXBUFSIZE)
62453947Smccanne 				*(u_int *)addr = size = BPF_MAXBUFSIZE;
62553947Smccanne 			else if (size < BPF_MINBUFSIZE)
62653947Smccanne 				*(u_int *)addr = size = BPF_MINBUFSIZE;
62753947Smccanne 			d->bd_bufsize = size;
62853947Smccanne 		}
62953947Smccanne #endif
63053947Smccanne 		break;
63153947Smccanne 
63253947Smccanne 	/*
63351425Smccanne 	 * Set link layer read filter.
63447584Smccanne 	 */
63553947Smccanne 	case BIOCSETF:
63647584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
63747584Smccanne 		break;
63847584Smccanne 
63947584Smccanne 	/*
64047584Smccanne 	 * Flush read packet buffer.
64147584Smccanne 	 */
64247584Smccanne 	case BIOCFLUSH:
64347584Smccanne 		s = splimp();
64447584Smccanne 		reset_d(d);
64547584Smccanne 		splx(s);
64647584Smccanne 		break;
64747584Smccanne 
64847584Smccanne 	/*
64947584Smccanne 	 * Put interface into promiscuous mode.
65047584Smccanne 	 */
65147584Smccanne 	case BIOCPROMISC:
65247584Smccanne 		if (d->bd_bif == 0) {
65347584Smccanne 			/*
65447584Smccanne 			 * No interface attached yet.
65547584Smccanne 			 */
65647584Smccanne 			error = EINVAL;
65747584Smccanne 			break;
65847584Smccanne 		}
65947584Smccanne 		s = splimp();
66047584Smccanne 		if (d->bd_promisc == 0) {
66147584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
66251425Smccanne 			if (error == 0)
66351425Smccanne 				d->bd_promisc = 1;
66447584Smccanne 		}
66547584Smccanne 		splx(s);
66647584Smccanne 		break;
66747584Smccanne 
66847584Smccanne 	/*
66947584Smccanne 	 * Get device parameters.
67047584Smccanne 	 */
67149202Smccanne 	case BIOCGDLT:
67247584Smccanne 		if (d->bd_bif == 0)
67347584Smccanne 			error = EINVAL;
67447584Smccanne 		else
67549202Smccanne 			*(u_int *)addr = d->bd_bif->bif_dlt;
67647584Smccanne 		break;
67747584Smccanne 
67847584Smccanne 	/*
67947584Smccanne 	 * Set interface name.
68047584Smccanne 	 */
68147584Smccanne 	case BIOCGETIF:
68247584Smccanne 		if (d->bd_bif == 0)
68347584Smccanne 			error = EINVAL;
68447584Smccanne 		else
68547584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
68647584Smccanne 		break;
68747584Smccanne 
68847584Smccanne 	/*
68947584Smccanne 	 * Set interface.
69047584Smccanne 	 */
69147584Smccanne 	case BIOCSETIF:
69247584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
69347584Smccanne 		break;
69447584Smccanne 
69547584Smccanne 	/*
69647584Smccanne 	 * Set read timeout.
69747584Smccanne 	 */
69853947Smccanne 	case BIOCSRTIMEOUT:
69947584Smccanne 		{
70047584Smccanne 			struct timeval *tv = (struct timeval *)addr;
70147584Smccanne 			u_long msec;
70247584Smccanne 
70347584Smccanne 			/* Compute number of milliseconds. */
70447584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
70547584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
70647584Smccanne 			   clock has millisecond or greater resolution
70747584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
70847584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
70947584Smccanne 			d->bd_rtout = msec / (tick / 1000);
71047584Smccanne 			break;
71147584Smccanne 		}
71247584Smccanne 
71347584Smccanne 	/*
71447584Smccanne 	 * Get read timeout.
71547584Smccanne 	 */
71653947Smccanne 	case BIOCGRTIMEOUT:
71747584Smccanne 		{
71847584Smccanne 			struct timeval *tv = (struct timeval *)addr;
71947584Smccanne 			u_long msec = d->bd_rtout;
72047584Smccanne 
72147584Smccanne 			msec *= tick / 1000;
72247584Smccanne 			tv->tv_sec = msec / 1000;
72347584Smccanne 			tv->tv_usec = msec % 1000;
72447584Smccanne 			break;
72547584Smccanne 		}
72647584Smccanne 
72747584Smccanne 	/*
72847584Smccanne 	 * Get packet stats.
72947584Smccanne 	 */
73047584Smccanne 	case BIOCGSTATS:
73147584Smccanne 		{
73247584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
73347584Smccanne 
73447584Smccanne 			bs->bs_recv = d->bd_rcount;
73547584Smccanne 			bs->bs_drop = d->bd_dcount;
73647584Smccanne 			break;
73747584Smccanne 		}
73847584Smccanne 
73947584Smccanne 	/*
74047584Smccanne 	 * Set immediate mode.
74147584Smccanne 	 */
74247584Smccanne 	case BIOCIMMEDIATE:
74347584Smccanne 		d->bd_immediate = *(u_int *)addr;
74447584Smccanne 		break;
74553947Smccanne 
74653947Smccanne 	case BIOCVERSION:
74753947Smccanne 		{
74853947Smccanne 			struct bpf_version *bv = (struct bpf_version *)addr;
74953947Smccanne 
75053947Smccanne 			bv->bv_major = BPF_MAJOR_VERSION;
75153947Smccanne 			bv->bv_minor = BPF_MINOR_VERSION;
75253947Smccanne 			break;
75353947Smccanne 		}
75447584Smccanne 	}
75548932Smccanne 	return (error);
75647584Smccanne }
75747584Smccanne 
75853947Smccanne /*
75951425Smccanne  * Set d's packet filter program to fp.  If this file already has a filter,
76048932Smccanne  * free it and replace it.  Returns EINVAL for bogus requests.
76147584Smccanne  */
76247584Smccanne int
bpf_setf(d,fp)76347584Smccanne bpf_setf(d, fp)
76447584Smccanne 	struct bpf_d *d;
76547584Smccanne 	struct bpf_program *fp;
76647584Smccanne {
76748932Smccanne 	struct bpf_insn *fcode, *old;
76847584Smccanne 	u_int flen, size;
76947584Smccanne 	int s;
77047584Smccanne 
77148932Smccanne 	old = d->bd_filter;
77247584Smccanne 	if (fp->bf_insns == 0) {
77347584Smccanne 		if (fp->bf_len != 0)
77448932Smccanne 			return (EINVAL);
77548932Smccanne 		s = splimp();
77648967Smccanne 		d->bd_filter = 0;
77747584Smccanne 		reset_d(d);
77847584Smccanne 		splx(s);
77948967Smccanne 		if (old != 0)
78048932Smccanne 			free((caddr_t)old, M_DEVBUF);
78148932Smccanne 		return (0);
78247584Smccanne 	}
78347584Smccanne 	flen = fp->bf_len;
78448932Smccanne 	if (flen > BPF_MAXINSNS)
78548932Smccanne 		return (EINVAL);
78648932Smccanne 
78747584Smccanne 	size = flen * sizeof(*fp->bf_insns);
78848932Smccanne 	fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
78950417Smccanne 	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
79050417Smccanne 	    bpf_validate(fcode, (int)flen)) {
79148967Smccanne 		s = splimp();
79248932Smccanne 		d->bd_filter = fcode;
79347584Smccanne 		reset_d(d);
79447584Smccanne 		splx(s);
79548967Smccanne 		if (old != 0)
79648932Smccanne 			free((caddr_t)old, M_DEVBUF);
79747584Smccanne 
79848932Smccanne 		return (0);
79947584Smccanne 	}
80048932Smccanne 	free((caddr_t)fcode, M_DEVBUF);
80148932Smccanne 	return (EINVAL);
80247584Smccanne }
80347584Smccanne 
80447584Smccanne /*
80553947Smccanne  * Detach a file from its current interface (if attached at all) and attach
80653947Smccanne  * to the interface indicated by the name stored in ifr.
80751425Smccanne  * Return an errno or 0.
80847584Smccanne  */
80947584Smccanne static int
bpf_setif(d,ifr)81047584Smccanne bpf_setif(d, ifr)
81147584Smccanne 	struct bpf_d *d;
81247584Smccanne 	struct ifreq *ifr;
81347584Smccanne {
81447584Smccanne 	struct bpf_if *bp;
81547584Smccanne 	char *cp;
81653947Smccanne 	int unit, s, error;
81747584Smccanne 
81847584Smccanne 	/*
81947584Smccanne 	 * Separate string into name part and unit number.  Put a null
82053947Smccanne 	 * byte at the end of the name part, and compute the number.
82147584Smccanne 	 * If the a unit number is unspecified, the default is 0,
82248932Smccanne 	 * as initialized above.  XXX This should be common code.
82347584Smccanne 	 */
82447584Smccanne 	unit = 0;
82547584Smccanne 	cp = ifr->ifr_name;
82647584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
82747584Smccanne 	while (*cp++) {
82847584Smccanne 		if (*cp >= '0' && *cp <= '9') {
82947584Smccanne 			unit = *cp - '0';
83047584Smccanne 			*cp++ = '\0';
83147584Smccanne 			while (*cp)
83247584Smccanne 				unit = 10 * unit + *cp++ - '0';
83347584Smccanne 			break;
83447584Smccanne 		}
83547584Smccanne 	}
83647584Smccanne 	/*
83747584Smccanne 	 * Look through attached interfaces for the named one.
83847584Smccanne 	 */
83949202Smccanne 	for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
84047584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
84147584Smccanne 
84253947Smccanne 		if (ifp == 0 || unit != ifp->if_unit
84347584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
84447584Smccanne 			continue;
84547584Smccanne 		/*
84653947Smccanne 		 * We found the requested interface.
84747584Smccanne 		 * If it's not up, return an error.
84853947Smccanne 		 * Allocate the packet buffers if we need to.
84953947Smccanne 		 * If we're already attached to requested interface,
85053947Smccanne 		 * just flush the buffer.
85147584Smccanne 		 */
85247584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
85348932Smccanne 			return (ENETDOWN);
85453947Smccanne 
85553947Smccanne 		if (d->bd_sbuf == 0) {
85653947Smccanne 			error = bpf_allocbufs(d);
85753947Smccanne 			if (error != 0)
85853947Smccanne 				return (error);
85953947Smccanne 		}
86047584Smccanne 		s = splimp();
86147584Smccanne 		if (bp != d->bd_bif) {
86247584Smccanne 			if (d->bd_bif)
86353947Smccanne 				/*
86448932Smccanne 				 * Detach if attached to something else.
86547584Smccanne 				 */
86647584Smccanne 				bpf_detachd(d);
86747584Smccanne 
86847584Smccanne 			bpf_attachd(d, bp);
86947584Smccanne 		}
87047584Smccanne 		reset_d(d);
87147584Smccanne 		splx(s);
87248932Smccanne 		return (0);
87347584Smccanne 	}
87447584Smccanne 	/* Not found. */
87548932Smccanne 	return (ENXIO);
87647584Smccanne }
87747584Smccanne 
87847584Smccanne /*
87951425Smccanne  * Convert an interface name plus unit number of an ifp to a single
88051425Smccanne  * name which is returned in the ifr.
88147584Smccanne  */
88247584Smccanne static void
bpf_ifname(ifp,ifr)88347584Smccanne bpf_ifname(ifp, ifr)
88447584Smccanne 	struct ifnet *ifp;
88547584Smccanne 	struct ifreq *ifr;
88647584Smccanne {
88747584Smccanne 	char *s = ifp->if_name;
88847584Smccanne 	char *d = ifr->ifr_name;
88947584Smccanne 
89047584Smccanne 	while (*d++ = *s++)
89153947Smccanne 		continue;
89248932Smccanne 	/* XXX Assume that unit number is less than 10. */
89347584Smccanne 	*d++ = ifp->if_unit + '0';
89447584Smccanne 	*d = '\0';
89547584Smccanne }
89647584Smccanne 
89747584Smccanne /*
89851425Smccanne  * The new select interface passes down the proc pointer; the old select
89951425Smccanne  * stubs had to grab it out of the user struct.  This glue allows either case.
90051425Smccanne  */
90151425Smccanne #if BSD >= 199103
90251425Smccanne #define bpf_select bpfselect
90351425Smccanne #else
90451425Smccanne int
bpfselect(dev,rw)90551425Smccanne bpfselect(dev, rw)
90651425Smccanne 	register dev_t dev;
90751425Smccanne 	int rw;
90851425Smccanne {
90953947Smccanne 	return (bpf_select(dev, rw, u.u_procp));
91051425Smccanne }
91151425Smccanne #endif
91251425Smccanne 
91351425Smccanne /*
91447584Smccanne  * Support for select() system call
91547584Smccanne  *
91653947Smccanne  * Return true iff the specific operation will not block indefinitely.
91753947Smccanne  * Otherwise, return false but make a note that a selwakeup() must be done.
91847584Smccanne  */
91947584Smccanne int
bpf_select(dev,rw,p)92051425Smccanne bpf_select(dev, rw, p)
92147584Smccanne 	register dev_t dev;
92247584Smccanne 	int rw;
92348932Smccanne 	struct proc *p;
92447584Smccanne {
92547584Smccanne 	register struct bpf_d *d;
92647584Smccanne 	register int s;
92753947Smccanne 
92847584Smccanne 	if (rw != FREAD)
92948932Smccanne 		return (0);
93047584Smccanne 	/*
93147584Smccanne 	 * An imitation of the FIONREAD ioctl code.
93247584Smccanne 	 */
93347584Smccanne 	d = &bpf_dtab[minor(dev)];
93453947Smccanne 
93547584Smccanne 	s = splimp();
93649723Smccanne 	if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
93747584Smccanne 		/*
93847584Smccanne 		 * There is data waiting.
93947584Smccanne 		 */
94047584Smccanne 		splx(s);
94148932Smccanne 		return (1);
94247584Smccanne 	}
94353947Smccanne #if BSD >= 199103
94453947Smccanne 	selrecord(p, &d->bd_sel);
94553947Smccanne #else
94647584Smccanne 	/*
94747584Smccanne 	 * No data ready.  If there's already a select() waiting on this
94853947Smccanne 	 * minor device then this is a collision.  This shouldn't happen
94947584Smccanne 	 * because minors really should not be shared, but if a process
95047584Smccanne 	 * forks while one of these is open, it is possible that both
95147584Smccanne 	 * processes could select on the same descriptor.
95247584Smccanne 	 */
95353947Smccanne 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
95453947Smccanne 		d->bd_selcoll = 1;
95553947Smccanne 	else
95653947Smccanne 		d->bd_selproc = p;
95753947Smccanne #endif
95853947Smccanne 	splx(s);
95948932Smccanne 	return (0);
96047584Smccanne }
96147584Smccanne 
96247584Smccanne /*
96353947Smccanne  * Incoming linkage from device drivers.  Process the packet pkt, of length
96453947Smccanne  * pktlen, which is stored in a contiguous buffer.  The packet is parsed
96553947Smccanne  * by each process' filter, and if accepted, stashed into the corresponding
96653947Smccanne  * buffer.
96747584Smccanne  */
96847584Smccanne void
bpf_tap(arg,pkt,pktlen)96948932Smccanne bpf_tap(arg, pkt, pktlen)
97047584Smccanne 	caddr_t arg;
97148932Smccanne 	register u_char *pkt;
97248932Smccanne 	register u_int pktlen;
97347584Smccanne {
97447584Smccanne 	struct bpf_if *bp;
97547584Smccanne 	register struct bpf_d *d;
97647584Smccanne 	register u_int slen;
97747584Smccanne 	/*
97847584Smccanne 	 * Note that the ipl does not have to be raised at this point.
97947584Smccanne 	 * The only problem that could arise here is that if two different
98047584Smccanne 	 * interfaces shared any data.  This is not the case.
98147584Smccanne 	 */
98247584Smccanne 	bp = (struct bpf_if *)arg;
98347584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
98447584Smccanne 		++d->bd_rcount;
98549202Smccanne 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
98647584Smccanne 		if (slen != 0)
98749202Smccanne 			catchpacket(d, pkt, pktlen, slen, bcopy);
98847584Smccanne 	}
98947584Smccanne }
99047584Smccanne 
99147584Smccanne /*
99247584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
99347584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
99447584Smccanne  */
99547584Smccanne static void
bpf_mcopy(src_arg,dst_arg,len)99661337Sbostic bpf_mcopy(src_arg, dst_arg, len)
99766504Sbostic 	const void *src_arg;
99866504Sbostic 	void *dst_arg;
99961337Sbostic 	register u_int len;
100047584Smccanne {
100166504Sbostic 	register const struct mbuf *m;
100261337Sbostic 	register u_int count;
100366504Sbostic 	u_char *dst;
100447584Smccanne 
100566504Sbostic 	m = src_arg;
100661337Sbostic 	dst = dst_arg;
100747584Smccanne 	while (len > 0) {
100847584Smccanne 		if (m == 0)
100949202Smccanne 			panic("bpf_mcopy");
101055065Spendry 		count = min(m->m_len, len);
101149202Smccanne 		bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
101249202Smccanne 		m = m->m_next;
101349202Smccanne 		dst += count;
101447584Smccanne 		len -= count;
101547584Smccanne 	}
101647584Smccanne }
101747584Smccanne 
101847584Smccanne /*
101953947Smccanne  * Incoming linkage from device drivers, when packet is in an mbuf chain.
102047584Smccanne  */
102147584Smccanne void
bpf_mtap(arg,m)102249202Smccanne bpf_mtap(arg, m)
102347584Smccanne 	caddr_t arg;
102449202Smccanne 	struct mbuf *m;
102547584Smccanne {
102647584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
102747584Smccanne 	struct bpf_d *d;
102849202Smccanne 	u_int pktlen, slen;
102949202Smccanne 	struct mbuf *m0;
103047584Smccanne 
103148932Smccanne 	pktlen = 0;
103251425Smccanne 	for (m0 = m; m0 != 0; m0 = m0->m_next)
103349202Smccanne 		pktlen += m0->m_len;
103449723Smccanne 
103547584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
103647584Smccanne 		++d->bd_rcount;
103749202Smccanne 		slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
103847584Smccanne 		if (slen != 0)
103949202Smccanne 			catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
104047584Smccanne 	}
104147584Smccanne }
104247584Smccanne 
104347584Smccanne /*
104449202Smccanne  * Move the packet data from interface memory (pkt) into the
104547584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
104653947Smccanne  * otherwise 0.  "copy" is the routine called to do the actual data
104751425Smccanne  * transfer.  bcopy is passed in to copy contiguous chunks, while
104851425Smccanne  * bpf_mcopy is passed in to copy mbuf chains.  In the latter case,
104951425Smccanne  * pkt is really an mbuf.
105047584Smccanne  */
105147584Smccanne static void
catchpacket(d,pkt,pktlen,snaplen,cpfn)105248932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn)
105348932Smccanne 	register struct bpf_d *d;
105448932Smccanne 	register u_char *pkt;
105548932Smccanne 	register u_int pktlen, snaplen;
105666504Sbostic 	register void (*cpfn)(const void *, void *, u_int);
105747584Smccanne {
105848932Smccanne 	register struct bpf_hdr *hp;
105948932Smccanne 	register int totlen, curlen;
106048932Smccanne 	register int hdrlen = d->bd_bif->bif_hdrlen;
106147584Smccanne 	/*
106247584Smccanne 	 * Figure out how many bytes to move.  If the packet is
106347584Smccanne 	 * greater or equal to the snapshot length, transfer that
106447584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
106548932Smccanne 	 * we hit the buffer size limit).
106647584Smccanne 	 */
106755065Spendry 	totlen = hdrlen + min(snaplen, pktlen);
106850082Smccanne 	if (totlen > d->bd_bufsize)
106950082Smccanne 		totlen = d->bd_bufsize;
107047584Smccanne 
107147584Smccanne 	/*
107247584Smccanne 	 * Round up the end of the previous packet to the next longword.
107347584Smccanne 	 */
107448932Smccanne 	curlen = BPF_WORDALIGN(d->bd_slen);
107548932Smccanne 	if (curlen + totlen > d->bd_bufsize) {
107647584Smccanne 		/*
107747584Smccanne 		 * This packet will overflow the storage buffer.
107848932Smccanne 		 * Rotate the buffers if we can, then wakeup any
107948932Smccanne 		 * pending reads.
108047584Smccanne 		 */
108147584Smccanne 		if (d->bd_fbuf == 0) {
108253947Smccanne 			/*
108353947Smccanne 			 * We haven't completed the previous read yet,
108448932Smccanne 			 * so drop the packet.
108547584Smccanne 			 */
108647584Smccanne 			++d->bd_dcount;
108747584Smccanne 			return;
108847584Smccanne 		}
108948932Smccanne 		ROTATE_BUFFERS(d);
109047584Smccanne 		bpf_wakeup(d);
109148932Smccanne 		curlen = 0;
109247584Smccanne 	}
109353947Smccanne 	else if (d->bd_immediate)
109447584Smccanne 		/*
109547584Smccanne 		 * Immediate mode is set.  A packet arrived so any
109647584Smccanne 		 * reads should be woken up.
109747584Smccanne 		 */
109847584Smccanne 		bpf_wakeup(d);
109948932Smccanne 
110047584Smccanne 	/*
110147584Smccanne 	 * Append the bpf header.
110247584Smccanne 	 */
110348932Smccanne 	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
110451425Smccanne #if BSD >= 199103
110547584Smccanne 	microtime(&hp->bh_tstamp);
110653947Smccanne #elif defined(sun)
110753947Smccanne 	uniqtime(&hp->bh_tstamp);
110847584Smccanne #else
110947584Smccanne 	hp->bh_tstamp = time;
111047584Smccanne #endif
111148932Smccanne 	hp->bh_datalen = pktlen;
111247584Smccanne 	hp->bh_hdrlen = hdrlen;
111347584Smccanne 	/*
111448932Smccanne 	 * Copy the packet data into the store buffer and update its length.
111547584Smccanne 	 */
111648932Smccanne 	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
111748932Smccanne 	d->bd_slen = curlen + totlen;
111847584Smccanne }
111947584Smccanne 
112053947Smccanne /*
112147584Smccanne  * Initialize all nonzero fields of a descriptor.
112247584Smccanne  */
112347584Smccanne static int
bpf_allocbufs(d)112453947Smccanne bpf_allocbufs(d)
112547584Smccanne 	register struct bpf_d *d;
112647584Smccanne {
112748932Smccanne 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
112848932Smccanne 	if (d->bd_fbuf == 0)
112948932Smccanne 		return (ENOBUFS);
113047584Smccanne 
113148932Smccanne 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
113248932Smccanne 	if (d->bd_sbuf == 0) {
113348932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
113448932Smccanne 		return (ENOBUFS);
113547584Smccanne 	}
113648932Smccanne 	d->bd_slen = 0;
113748932Smccanne 	d->bd_hlen = 0;
113848932Smccanne 	return (0);
113947584Smccanne }
114047584Smccanne 
114147584Smccanne /*
114251425Smccanne  * Free buffers currently in use by a descriptor.
114351425Smccanne  * Called on close.
114447584Smccanne  */
114553947Smccanne static void
bpf_freed(d)114651425Smccanne bpf_freed(d)
114751425Smccanne 	register struct bpf_d *d;
114851425Smccanne {
114951425Smccanne 	/*
115051425Smccanne 	 * We don't need to lock out interrupts since this descriptor has
115153947Smccanne 	 * been detached from its interface and it yet hasn't been marked
115251425Smccanne 	 * free.
115351425Smccanne 	 */
115453947Smccanne 	if (d->bd_sbuf != 0) {
115553947Smccanne 		free(d->bd_sbuf, M_DEVBUF);
115653947Smccanne 		if (d->bd_hbuf != 0)
115753947Smccanne 			free(d->bd_hbuf, M_DEVBUF);
115853947Smccanne 		if (d->bd_fbuf != 0)
115953947Smccanne 			free(d->bd_fbuf, M_DEVBUF);
116053947Smccanne 	}
116151425Smccanne 	if (d->bd_filter)
116251425Smccanne 		free((caddr_t)d->bd_filter, M_DEVBUF);
116353947Smccanne 
116451425Smccanne 	D_MARKFREE(d);
116551425Smccanne }
116651425Smccanne 
116751425Smccanne /*
116851425Smccanne  * Attach an interface to bpf.  driverp is a pointer to a (struct bpf_if *)
116951425Smccanne  * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
117051425Smccanne  * size of the link header (variable length headers not yet supported).
117151425Smccanne  */
117247584Smccanne void
bpfattach(driverp,ifp,dlt,hdrlen)117349202Smccanne bpfattach(driverp, ifp, dlt, hdrlen)
117447584Smccanne 	caddr_t *driverp;
117547584Smccanne 	struct ifnet *ifp;
117649202Smccanne 	u_int dlt, hdrlen;
117747584Smccanne {
117847584Smccanne 	struct bpf_if *bp;
117947584Smccanne 	int i;
118051425Smccanne #if BSD < 199103
118151425Smccanne 	static struct bpf_if bpf_ifs[NBPFILTER];
118251425Smccanne 	static int bpfifno;
118347584Smccanne 
118451425Smccanne 	bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0;
118551425Smccanne #else
118649202Smccanne 	bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
118751425Smccanne #endif
118849202Smccanne 	if (bp == 0)
118949202Smccanne 		panic("bpfattach");
119047584Smccanne 
119147584Smccanne 	bp->bif_dlist = 0;
119247584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
119347584Smccanne 	bp->bif_ifp = ifp;
119449202Smccanne 	bp->bif_dlt = dlt;
119547584Smccanne 
119649202Smccanne 	bp->bif_next = bpf_iflist;
119749202Smccanne 	bpf_iflist = bp;
119849202Smccanne 
119948932Smccanne 	*bp->bif_driverp = 0;
120048932Smccanne 
120147584Smccanne 	/*
120247584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
120353947Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
120453947Smccanne 	 * that the network layer header begins on a longword boundary (for
120547584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
120647584Smccanne 	 */
120749202Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
120847584Smccanne 
120947584Smccanne 	/*
121047584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
121147584Smccanne 	 */
121247584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
121347584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
121447584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
121547584Smccanne 
121647584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
121747584Smccanne }
121847584Smccanne 
121951425Smccanne #if BSD >= 199103
122048967Smccanne /* XXX This routine belongs in net/if.c. */
122148932Smccanne /*
122253947Smccanne  * Set/clear promiscuous mode on interface ifp based on the truth value
122348932Smccanne  * of pswitch.  The calls are reference counted so that only the first
122453947Smccanne  * "on" request actually has an effect, as does the final "off" request.
122553947Smccanne  * Results are undefined if the "off" and "on" requests are not matched.
122648932Smccanne  */
122748932Smccanne int
ifpromisc(ifp,pswitch)122848932Smccanne ifpromisc(ifp, pswitch)
122948932Smccanne 	struct ifnet *ifp;
123048932Smccanne 	int pswitch;
123148932Smccanne {
123249726Smccanne 	struct ifreq ifr;
123353947Smccanne 	/*
123448932Smccanne 	 * If the device is not configured up, we cannot put it in
123548932Smccanne 	 * promiscuous mode.
123648932Smccanne 	 */
123748932Smccanne 	if ((ifp->if_flags & IFF_UP) == 0)
123848932Smccanne 		return (ENETDOWN);
123948932Smccanne 
124048932Smccanne 	if (pswitch) {
124148932Smccanne 		if (ifp->if_pcount++ != 0)
124248932Smccanne 			return (0);
124348932Smccanne 		ifp->if_flags |= IFF_PROMISC;
124448932Smccanne 	} else {
124548932Smccanne 		if (--ifp->if_pcount > 0)
124648932Smccanne 			return (0);
124748932Smccanne 		ifp->if_flags &= ~IFF_PROMISC;
124848932Smccanne 	}
124949726Smccanne 	ifr.ifr_flags = ifp->if_flags;
125049726Smccanne 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
125148932Smccanne }
125251425Smccanne #endif
125348932Smccanne 
125451425Smccanne #if BSD < 199103
125551425Smccanne /*
125651425Smccanne  * Allocate some memory for bpf.  This is temporary SunOS support, and
125753947Smccanne  * is admittedly a hack.
125851425Smccanne  * If resources unavaiable, return 0.
125951425Smccanne  */
126051425Smccanne static caddr_t
bpf_alloc(size,canwait)126151425Smccanne bpf_alloc(size, canwait)
126251425Smccanne 	register int size;
126351425Smccanne 	register int canwait;
126451425Smccanne {
126551425Smccanne 	register struct mbuf *m;
126651425Smccanne 
126751425Smccanne 	if ((unsigned)size > (MCLBYTES-8))
126851425Smccanne 		return 0;
126951425Smccanne 
127051425Smccanne 	MGET(m, canwait, MT_DATA);
127151425Smccanne 	if (m == 0)
127251425Smccanne 		return 0;
127351425Smccanne 	if ((unsigned)size > (MLEN-8)) {
127451425Smccanne 		MCLGET(m);
127551425Smccanne 		if (m->m_len != MCLBYTES) {
127651425Smccanne 			m_freem(m);
127751425Smccanne 			return 0;
127851425Smccanne 		}
127951425Smccanne 	}
128051425Smccanne 	*mtod(m, struct mbuf **) = m;
128151425Smccanne 	return mtod(m, caddr_t) + 8;
128251425Smccanne }
128351425Smccanne #endif
128451425Smccanne #endif
1285