xref: /csrg-svn/sys/net/bpf.c (revision 51425)
149343Sbostic /*-
2*51425Smccanne  * Copyright (c) 1990-1991 The 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
7*51425Smccanne  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
8*51425Smccanne  * Berkeley Laboratory.
947584Smccanne  *
10*51425Smccanne  * Redistribution and use in source and binary forms, with or without
11*51425Smccanne  * modification, are permitted provided that the following conditions
12*51425Smccanne  * are met:
13*51425Smccanne  * 1. Redistributions of source code must retain the above copyright
14*51425Smccanne  *    notice, this list of conditions and the following disclaimer.
15*51425Smccanne  * 2. Redistributions in binary form must reproduce the above copyright
16*51425Smccanne  *    notice, this list of conditions and the following disclaimer in the
17*51425Smccanne  *    documentation and/or other materials provided with the distribution.
18*51425Smccanne  * 3. All advertising materials mentioning features or use of this software
19*51425Smccanne  *    must display the following acknowledgement:
20*51425Smccanne  *	This product includes software developed by the University of
21*51425Smccanne  *	California, Berkeley and its contributors.
22*51425Smccanne  * 4. Neither the name of the University nor the names of its contributors
23*51425Smccanne  *    may be used to endorse or promote products derived from this software
24*51425Smccanne  *    without specific prior written permission.
2549343Sbostic  *
26*51425Smccanne  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27*51425Smccanne  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28*51425Smccanne  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29*51425Smccanne  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30*51425Smccanne  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31*51425Smccanne  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32*51425Smccanne  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33*51425Smccanne  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34*51425Smccanne  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35*51425Smccanne  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36*51425Smccanne  * SUCH DAMAGE.
3749343Sbostic  *
38*51425Smccanne  *	@(#)bpf.c	7.5 (Berkeley) 7/15/91
39*51425Smccanne  *
4049343Sbostic  * static char rcsid[] =
41*51425Smccanne  * "$Header: bpf.c,v 1.33 91/10/27 21:21:58 mccanne Exp $";
4247584Smccanne  */
4347584Smccanne 
4447584Smccanne #include "bpfilter.h"
4547584Smccanne 
46*51425Smccanne #if NBPFILTER > 0
4747584Smccanne 
48*51425Smccanne #ifndef __GNUC__
49*51425Smccanne #define inline
50*51425Smccanne #else
51*51425Smccanne #define inline __inline__
52*51425Smccanne #endif
53*51425Smccanne 
5447584Smccanne #include <sys/param.h>
5547584Smccanne #include <sys/systm.h>
5647584Smccanne #include <sys/mbuf.h>
5747584Smccanne #include <sys/buf.h>
5847584Smccanne #include <sys/dir.h>
5948932Smccanne #include <sys/proc.h>
6047584Smccanne #include <sys/user.h>
6147584Smccanne #include <sys/ioctl.h>
6247584Smccanne #include <sys/map.h>
6347584Smccanne 
6447584Smccanne #include <sys/file.h>
65*51425Smccanne #if defined(sparc) && BSD < 199103
6647584Smccanne #include <sys/stream.h>
6747584Smccanne #endif
6847584Smccanne #include <sys/tty.h>
6947584Smccanne #include <sys/uio.h>
7047584Smccanne 
7147584Smccanne #include <sys/protosw.h>
7247584Smccanne #include <sys/socket.h>
7347584Smccanne #include <net/if.h>
7447584Smccanne 
7547584Smccanne #include <net/bpf.h>
7647584Smccanne #include <net/bpfdesc.h>
7747584Smccanne 
7847584Smccanne #include <sys/errno.h>
7947584Smccanne 
8047584Smccanne #include <netinet/in.h>
8147584Smccanne #include <netinet/if_ether.h>
8247584Smccanne #include <sys/kernel.h>
8347584Smccanne 
84*51425Smccanne /*
85*51425Smccanne  * Older BSDs don't have kernel malloc.
86*51425Smccanne  */
87*51425Smccanne #if BSD < 199103
88*51425Smccanne extern bcopy();
89*51425Smccanne static caddr_t bpf_alloc();
90*51425Smccanne #define malloc(size, type, canwait) bpf_alloc(size, canwait)
91*51425Smccanne #define free(cp, type) m_free(*(struct mbuf **)(cp - 8))
92*51425Smccanne #define M_WAITOK M_WAIT
93*51425Smccanne #define BPF_BUFSIZE (MCLBYTES-8)
94*51425Smccanne #define ERESTART EINTR
95*51425Smccanne #else
96*51425Smccanne #define BPF_BUFSIZE 4096
97*51425Smccanne #endif
98*51425Smccanne 
9947584Smccanne #define PRINET  26			/* interruptible */
10047584Smccanne 
10147584Smccanne /*
10248932Smccanne  * The default read buffer size is patchable.
10348932Smccanne  */
104*51425Smccanne int bpf_bufsize = BPF_BUFSIZE;
10548932Smccanne 
10648932Smccanne /*
10749202Smccanne  *  bpf_iflist is the list of interfaces; each corresponds to an ifnet
10849202Smccanne  *  bpf_dtab holds the descriptors, indexed by minor device #
10947584Smccanne  *
11047584Smccanne  * We really don't need NBPFILTER bpf_if entries, but this eliminates
11147584Smccanne  * the need to account for all possible drivers here.
11247584Smccanne  * This problem will go away when these structures are allocated dynamically.
11347584Smccanne  */
11449202Smccanne static struct bpf_if 	*bpf_iflist;
11547584Smccanne static struct bpf_d	bpf_dtab[NBPFILTER];
11647584Smccanne 
11747584Smccanne static void	bpf_ifname();
11847584Smccanne static void	catchpacket();
11947584Smccanne static int	bpf_setif();
12047584Smccanne static int	bpf_initd();
12147584Smccanne 
12247584Smccanne static int
12347584Smccanne bpf_movein(uio, linktype, mp, sockp)
12447584Smccanne 	register struct uio *uio;
12547584Smccanne 	int linktype;
12647584Smccanne 	register struct mbuf **mp;
12747584Smccanne 	register struct sockaddr *sockp;
12847584Smccanne {
12947584Smccanne 	struct mbuf *m;
13047584Smccanne 	int error;
13147584Smccanne 	int len;
13247584Smccanne 	int hlen;
13347584Smccanne 
13447584Smccanne 	/*
13547584Smccanne 	 * Build a sockaddr based on the data link layer type.
13647584Smccanne 	 * We do this at this level because the ethernet header
13747584Smccanne 	 * is copied directly into the data field of the sockaddr.
13847584Smccanne 	 * In the case of SLIP, there is no header and the packet
13947584Smccanne 	 * is forwarded as is.
14047584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
14147584Smccanne 	 * for the link level header.
14247584Smccanne 	 */
14347584Smccanne 	switch (linktype) {
14447584Smccanne 	case DLT_SLIP:
14547584Smccanne 		sockp->sa_family = AF_INET;
14647584Smccanne 		hlen = 0;
14747584Smccanne 		break;
14847584Smccanne 
14947584Smccanne 	case DLT_EN10MB:
15047584Smccanne 		sockp->sa_family = AF_UNSPEC;
15147584Smccanne 		/* XXX Would MAXLINKHDR be better? */
15247584Smccanne 		hlen = sizeof(struct ether_header);
15347584Smccanne 		break;
15447584Smccanne 
15547584Smccanne        case DLT_FDDI:
15647584Smccanne 		sockp->sa_family = AF_UNSPEC;
15747584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
15847584Smccanne 		hlen = 24;
15947584Smccanne 		break;
16047584Smccanne 
16147584Smccanne 	default:
16248932Smccanne 		return (EIO);
16347584Smccanne 	}
16447584Smccanne 
16547584Smccanne 	len = uio->uio_resid;
16647584Smccanne 	if ((unsigned)len > MCLBYTES)
16748932Smccanne 		return (EIO);
16847584Smccanne 
16947584Smccanne 	MGET(m, M_WAIT, MT_DATA);
17047584Smccanne 	if (m == 0)
17148932Smccanne 		return (ENOBUFS);
17247584Smccanne 	if (len > MLEN) {
173*51425Smccanne #if BSD >= 199103
17448932Smccanne 		MCLGET(m, M_WAIT);
17548932Smccanne 		if ((m->m_flags & M_EXT) == 0) {
176*51425Smccanne #else
177*51425Smccanne 		MCLGET(m);
178*51425Smccanne 		if (m->m_len == MCLBYTES) {
179*51425Smccanne #endif
180*51425Smccanne 			error = ENOBUFS;
18147584Smccanne 			goto bad;
18247584Smccanne 		}
18347584Smccanne 	}
18447584Smccanne 	m->m_len = len;
18547584Smccanne 	*mp = m;
18647584Smccanne 	/*
18747584Smccanne 	 * Make room for link header.
18847584Smccanne 	 */
18947584Smccanne 	if (hlen) {
19047584Smccanne 		m->m_len -= hlen;
191*51425Smccanne #if BSD >= 199103
19248932Smccanne 		m->m_data += hlen; /* XXX */
193*51425Smccanne #else
194*51425Smccanne 		m->m_off += hlen;
195*51425Smccanne #endif
19648932Smccanne 		error = uiomove((caddr_t)sockp->sa_data, hlen, uio);
19747584Smccanne 		if (error)
19847584Smccanne 			goto bad;
19947584Smccanne 	}
20048932Smccanne 	error = uiomove(mtod(m, caddr_t), len - hlen, uio);
20147584Smccanne 	if (!error)
20248932Smccanne 		return (0);
20347584Smccanne  bad:
20447584Smccanne 	m_freem(m);
20548932Smccanne 	return (error);
20647584Smccanne }
20747584Smccanne 
20847584Smccanne /*
209*51425Smccanne  * Attach file to the bpf interface, i.e. make d listen on bp.
21047584Smccanne  * Must be called at splimp.
21147584Smccanne  */
21247584Smccanne static void
21347584Smccanne bpf_attachd(d, bp)
21447584Smccanne 	struct bpf_d *d;
21547584Smccanne 	struct bpf_if *bp;
21647584Smccanne {
217*51425Smccanne 	/*
218*51425Smccanne 	 * Point d at bp, and add d to the interface's list of listeners.
219*51425Smccanne 	 * Finally, point the driver's bpf cookie at the interface so
220*51425Smccanne 	 * it will divert packets to bpf.
221*51425Smccanne 	 */
22247584Smccanne 	d->bd_bif = bp;
22347584Smccanne 	d->bd_next = bp->bif_dlist;
22447584Smccanne 	bp->bif_dlist = d;
22547584Smccanne 
22647584Smccanne 	*bp->bif_driverp = bp;
22747584Smccanne }
22847584Smccanne 
229*51425Smccanne /*
230*51425Smccanne  * Detach a file from its interface.
231*51425Smccanne  */
23247584Smccanne static void
23347584Smccanne bpf_detachd(d)
23447584Smccanne 	struct bpf_d *d;
23547584Smccanne {
23647584Smccanne 	struct bpf_d **p;
23747584Smccanne 	struct bpf_if *bp;
23847584Smccanne 
23947584Smccanne 	bp = d->bd_bif;
24047584Smccanne 	/*
24147584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
24247584Smccanne 	 * If so, turn it off.
24347584Smccanne 	 */
24447584Smccanne 	if (d->bd_promisc) {
24547584Smccanne 		d->bd_promisc = 0;
24647584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
24747584Smccanne 			/*
24847584Smccanne 			 * Something is really wrong if we were able to put
24947584Smccanne 			 * the driver into promiscuous mode, but can't
25047584Smccanne 			 * take it out.
25147584Smccanne 			 */
252*51425Smccanne 			panic("bpf: ifpromisc failed");
25347584Smccanne 	}
254*51425Smccanne 	/* Remove d from the interface's descriptor list. */
25547584Smccanne 	p = &bp->bif_dlist;
25647584Smccanne 	while (*p != d) {
25747584Smccanne 		p = &(*p)->bd_next;
25847584Smccanne 		if (*p == 0)
25947584Smccanne 			panic("bpf_detachd: descriptor not in list");
26047584Smccanne 	}
26147584Smccanne 	*p = (*p)->bd_next;
26247584Smccanne 	if (bp->bif_dlist == 0)
26347584Smccanne 		/*
26447584Smccanne 		 * Let the driver know that there are no more listeners.
26547584Smccanne 		 */
26647584Smccanne 		*d->bd_bif->bif_driverp = 0;
26747584Smccanne 	d->bd_bif = 0;
26847584Smccanne }
26947584Smccanne 
27047584Smccanne 
27147584Smccanne /*
27247584Smccanne  * Mark a descriptor free by making it point to itself.
27347584Smccanne  * This is probably cheaper than marking with a constant since
27447584Smccanne  * the address should be in a register anyway.
27547584Smccanne  */
27647584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
27747584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
27847584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
27947584Smccanne 
28047584Smccanne /*
28147584Smccanne  *  bpfopen - open ethernet device
28247584Smccanne  *
28347584Smccanne  *  Errors:	ENXIO	- illegal minor device number
28447584Smccanne  *		EBUSY	- too many files open
28547584Smccanne  */
28647584Smccanne /* ARGSUSED */
28747584Smccanne int
28847584Smccanne bpfopen(dev, flag)
28947584Smccanne 	dev_t dev;
29047584Smccanne 	int flag;
29147584Smccanne {
29247584Smccanne 	int error, s;
29347584Smccanne 	register struct bpf_d *d;
29447584Smccanne 
29547584Smccanne 	if (minor(dev) >= NBPFILTER)
29648932Smccanne 		return (ENXIO);
29747584Smccanne 
29847584Smccanne 	/*
29947584Smccanne 	 * Each minor can be opened by only one process.  If the requested
30047584Smccanne 	 * minor is in use, return EBUSY.
30147584Smccanne 	 */
30247584Smccanne 	s = splimp();
30347584Smccanne 	d = &bpf_dtab[minor(dev)];
30447584Smccanne 	if (!D_ISFREE(d)) {
30547584Smccanne 		splx(s);
30648932Smccanne 		return (EBUSY);
30747584Smccanne 	} else
30847584Smccanne 		/* Mark "free" and do most initialization. */
30947584Smccanne 		bzero((char *)d, sizeof(*d));
31047584Smccanne 	splx(s);
31147584Smccanne 
31247584Smccanne 	error = bpf_initd(d);
31347584Smccanne 	if (error) {
31447584Smccanne 		D_MARKFREE(d);
31548932Smccanne 		return (error);
31647584Smccanne 	}
31748932Smccanne 	return (0);
31847584Smccanne }
31947584Smccanne 
32047584Smccanne /*
32147584Smccanne  * Close the descriptor by detaching it from its interface,
32247584Smccanne  * deallocating its buffers, and marking it free.
32347584Smccanne  */
32447584Smccanne /* ARGSUSED */
32547584Smccanne bpfclose(dev, flag)
32647584Smccanne 	dev_t dev;
32747584Smccanne 	int flag;
32847584Smccanne {
32947584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
33047584Smccanne 	int s;
33147584Smccanne 
33247584Smccanne 	s = splimp();
33347584Smccanne 	if (d->bd_bif)
33447584Smccanne 		bpf_detachd(d);
33547584Smccanne 	splx(s);
33647584Smccanne 
337*51425Smccanne 	bpf_freed(d);
33847584Smccanne }
33947584Smccanne 
340*51425Smccanne #if BSD < 199103
341*51425Smccanne static
342*51425Smccanne bpf_timeout(arg)
343*51425Smccanne 	caddr_t arg;
344*51425Smccanne {
345*51425Smccanne 	struct bpf_d *d = (struct bpf_d *)arg;
346*51425Smccanne 	d->bd_timedout = 1;
347*51425Smccanne 	wakeup(arg);
348*51425Smccanne }
349*51425Smccanne 
350*51425Smccanne static int
351*51425Smccanne tsleep(cp, pri, s, t)
352*51425Smccanne 	register caddr_t cp;
353*51425Smccanne 	register int pri;
354*51425Smccanne 	char *s;
355*51425Smccanne 	register int t;
356*51425Smccanne {
357*51425Smccanne 	register struct bpf_d *d = (struct bpf_d *)cp;
358*51425Smccanne 	register int error;
359*51425Smccanne 
360*51425Smccanne 	if (t != 0) {
361*51425Smccanne 		d->bd_timedout = 0;
362*51425Smccanne 		timeout(bpf_timeout, cp);
363*51425Smccanne 	}
364*51425Smccanne 	error = sleep(cp, pri);
365*51425Smccanne 	if (t != 0) {
366*51425Smccanne 		if (d->bd_timedout != 0)
367*51425Smccanne 			return EWOULDBLOCK;
368*51425Smccanne 		untimeout(bpf_timeout, cp);
369*51425Smccanne 	}
370*51425Smccanne 	return error;
371*51425Smccanne }
372*51425Smccanne #endif
373*51425Smccanne 
37447584Smccanne /*
37548932Smccanne  * Rotate the packet buffers in descriptor d.  Move the store buffer
37648932Smccanne  * into the hold slot, and the free buffer into the store slot.
37748932Smccanne  * Zero the length of the new store buffer.
37848932Smccanne  */
37948932Smccanne #define ROTATE_BUFFERS(d) \
38048932Smccanne 	(d)->bd_hbuf = (d)->bd_sbuf; \
38148932Smccanne 	(d)->bd_hlen = (d)->bd_slen; \
38248932Smccanne 	(d)->bd_sbuf = (d)->bd_fbuf; \
38348932Smccanne 	(d)->bd_slen = 0; \
38448932Smccanne 	(d)->bd_fbuf = 0;
38548932Smccanne /*
38647584Smccanne  *  bpfread - read next chunk of packets from buffers
38747584Smccanne  */
38847584Smccanne int
38947584Smccanne bpfread(dev, uio)
39047584Smccanne 	dev_t dev;
39147584Smccanne 	register struct uio *uio;
39247584Smccanne {
39347584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
39447584Smccanne 	int error;
39547584Smccanne 	int s;
39647584Smccanne 
39747584Smccanne 	/*
39847584Smccanne 	 * Restrict application to use a buffer the same size as
39947584Smccanne 	 * as kernel buffers.
40047584Smccanne 	 */
40148932Smccanne 	if (uio->uio_resid != d->bd_bufsize)
40249202Smccanne 		return (EINVAL);
40347584Smccanne 
40447584Smccanne 	s = splimp();
40547584Smccanne 	/*
40647584Smccanne 	 * If the hold buffer is empty, then set a timer and sleep
40747584Smccanne 	 * until either the timeout has occurred or enough packets have
40847584Smccanne 	 * arrived to fill the store buffer.
40947584Smccanne 	 */
41047584Smccanne 	while (d->bd_hbuf == 0) {
41148932Smccanne 		if (d->bd_immediate && d->bd_slen != 0) {
41247584Smccanne 			/*
41347584Smccanne 			 * A packet(s) either arrived since the previous
41447584Smccanne 			 * read or arrived while we were asleep.
41547584Smccanne 			 * Rotate the buffers and return what's here.
41647584Smccanne 			 */
41748932Smccanne 			ROTATE_BUFFERS(d);
41847584Smccanne 			break;
41947584Smccanne 		}
42048932Smccanne 		error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf", d->bd_rtout);
42148932Smccanne 		if (error == EINTR || error == ERESTART) {
42248932Smccanne 			splx(s);
42348932Smccanne 			return (error);
42447584Smccanne 		}
42548932Smccanne 		if (error == EWOULDBLOCK) {
42647584Smccanne 			/*
42747584Smccanne 			 * On a timeout, return what's in the buffer,
42848932Smccanne 			 * which may be nothing.  If there is something
42948932Smccanne 			 * in the store buffer, we can rotate the buffers.
43047584Smccanne 			 */
43147584Smccanne 			if (d->bd_hbuf)
43247584Smccanne 				/*
43347584Smccanne 				 * We filled up the buffer in between
43447584Smccanne 				 * getting the timeout and arriving
43547584Smccanne 				 * here, so we don't need to rotate.
43647584Smccanne 				 */
43747584Smccanne 				break;
43847584Smccanne 
43948932Smccanne 			if (d->bd_slen == 0) {
44047584Smccanne 				splx(s);
44148932Smccanne 				return (0);
44247584Smccanne 			}
44348932Smccanne 			ROTATE_BUFFERS(d);
44447584Smccanne 			break;
44547584Smccanne 		}
44647584Smccanne 	}
44747584Smccanne 	/*
44847584Smccanne 	 * At this point, we know we have something in the hold slot.
44947584Smccanne 	 */
45047584Smccanne 	splx(s);
45147584Smccanne 
45247584Smccanne 	/*
45347584Smccanne 	 * Move data from hold buffer into user space.
45447584Smccanne 	 * We know the entire buffer is transferred since
45548932Smccanne 	 * we checked above that the read buffer is bpf_bufsize bytes.
45647584Smccanne 	 */
457*51425Smccanne #if BSD >= 199103
45848932Smccanne 	error = uiomove(d->bd_hbuf, d->bd_hlen, uio);
459*51425Smccanne #else
460*51425Smccanne 	error = uiomove(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
461*51425Smccanne #endif
46247584Smccanne 	s = splimp();
46348932Smccanne 	d->bd_fbuf = d->bd_hbuf;
46448932Smccanne 	d->bd_hbuf = 0;
46547584Smccanne 	splx(s);
46647584Smccanne 
46748932Smccanne 	return (error);
46847584Smccanne }
46947584Smccanne 
47047584Smccanne 
47147584Smccanne /*
47248932Smccanne  * If there are processes sleeping on this descriptor, wake them up.
47347584Smccanne  */
47447584Smccanne static inline void
47547584Smccanne bpf_wakeup(d)
47647584Smccanne 	register struct bpf_d *d;
47747584Smccanne {
47848932Smccanne 	wakeup((caddr_t)d);
47948932Smccanne 	if (d->bd_selproc) {
48048932Smccanne 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
48148932Smccanne 		d->bd_selcoll = 0;
48248932Smccanne 		d->bd_selproc = 0;
48347584Smccanne 	}
48447584Smccanne }
48547584Smccanne 
48647584Smccanne int
48747584Smccanne bpfwrite(dev, uio)
48847584Smccanne 	dev_t dev;
48947584Smccanne 	struct uio *uio;
49047584Smccanne {
49147584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
49247584Smccanne 	struct ifnet *ifp;
49347584Smccanne 	struct mbuf *m;
49447584Smccanne 	int error, s;
49547584Smccanne 	static struct sockaddr dst;
49647584Smccanne 
49747584Smccanne 	if (d->bd_bif == 0)
49848932Smccanne 		return (ENXIO);
49947584Smccanne 
50047584Smccanne 	ifp = d->bd_bif->bif_ifp;
50147584Smccanne 
50247584Smccanne 	if (uio->uio_resid == 0)
50348932Smccanne 		return (0);
50447584Smccanne 	if (uio->uio_resid > ifp->if_mtu)
50548932Smccanne 		return (EMSGSIZE);
50647584Smccanne 
50749202Smccanne 	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst);
50847584Smccanne 	if (error)
50948932Smccanne 		return (error);
51047584Smccanne 
51147584Smccanne 	s = splnet();
512*51425Smccanne #if BSD >= 199103
513*51425Smccanne 	error = (*ifp->if_output)(ifp, m, &dst, (struct rtenty *)0);
514*51425Smccanne #else
51547584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
516*51425Smccanne #endif
51747584Smccanne 	splx(s);
51847584Smccanne 	/*
51947584Smccanne 	 * The driver frees the mbuf.
52047584Smccanne 	 */
52148932Smccanne 	return (error);
52247584Smccanne }
52347584Smccanne 
52447584Smccanne /*
52548932Smccanne  * Reset a descriptor by flushing its packet bufferand clearing the receive
52648932Smccanne  * and drop counts.  Should be called at splimp.
52747584Smccanne  */
52847584Smccanne static void
52947584Smccanne reset_d(d)
53047584Smccanne 	struct bpf_d *d;
53147584Smccanne {
53247584Smccanne 	if (d->bd_hbuf) {
53347584Smccanne 		/* Free the hold buffer. */
53447584Smccanne 		d->bd_fbuf = d->bd_hbuf;
53547584Smccanne 		d->bd_hbuf = 0;
53647584Smccanne 	}
53748932Smccanne 	d->bd_slen = 0;
53847584Smccanne 	d->bd_rcount = 0;
53947584Smccanne 	d->bd_dcount = 0;
54047584Smccanne }
54147584Smccanne 
54247584Smccanne /*
54347584Smccanne  *  FIONREAD		Check for read packet available.
54447584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
54547584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
54647584Smccanne  *  BIOCSETF		Set ethernet read filter.
54747584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
54847584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
54949202Smccanne  *  BIOCGDLT		Get link layer type.
55047584Smccanne  *  BIOCGETIF		Get interface name.
55147584Smccanne  *  BIOCSETIF		Set interface.
55247584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
55347584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
55447584Smccanne  *  BIOCGSTATS		Get packet stats.
55547584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
55647584Smccanne  */
55747584Smccanne /* ARGSUSED */
55847584Smccanne int
55947584Smccanne bpfioctl(dev, cmd, addr, flag)
56047584Smccanne 	dev_t dev;
56147584Smccanne 	int 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;
58047584Smccanne 
58147584Smccanne 			s = splimp();
58248932Smccanne 			n = d->bd_slen;
58347584Smccanne 			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;
59947584Smccanne 				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 	/*
612*51425Smccanne 	 * Set link layer read filter.
61347584Smccanne 	 */
61447584Smccanne         case BIOCSETF:
61547584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
61647584Smccanne 		break;
61747584Smccanne 
61847584Smccanne 	/*
61947584Smccanne 	 * Flush read packet buffer.
62047584Smccanne 	 */
62147584Smccanne 	case BIOCFLUSH:
62247584Smccanne 		s = splimp();
62347584Smccanne 		reset_d(d);
62447584Smccanne 		splx(s);
62547584Smccanne 		break;
62647584Smccanne 
62747584Smccanne 	/*
62847584Smccanne 	 * Put interface into promiscuous mode.
62947584Smccanne 	 */
63047584Smccanne 	case BIOCPROMISC:
63147584Smccanne 		if (d->bd_bif == 0) {
63247584Smccanne 			/*
63347584Smccanne 			 * No interface attached yet.
63447584Smccanne 			 */
63547584Smccanne 			error = EINVAL;
63647584Smccanne 			break;
63747584Smccanne 		}
63847584Smccanne 		s = splimp();
63947584Smccanne 		if (d->bd_promisc == 0) {
64047584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
641*51425Smccanne 			if (error == 0)
642*51425Smccanne 				d->bd_promisc = 1;
64347584Smccanne 		}
64447584Smccanne 		splx(s);
64547584Smccanne 		break;
64647584Smccanne 
64747584Smccanne 	/*
64847584Smccanne 	 * Get device parameters.
64947584Smccanne 	 */
65049202Smccanne 	case BIOCGDLT:
65147584Smccanne 		if (d->bd_bif == 0)
65247584Smccanne 			error = EINVAL;
65347584Smccanne 		else
65449202Smccanne 			*(u_int *)addr = d->bd_bif->bif_dlt;
65547584Smccanne 		break;
65647584Smccanne 
65747584Smccanne 	/*
65847584Smccanne 	 * Set interface name.
65947584Smccanne 	 */
66047584Smccanne 	case BIOCGETIF:
66147584Smccanne 		if (d->bd_bif == 0)
66247584Smccanne 			error = EINVAL;
66347584Smccanne 		else
66447584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
66547584Smccanne 		break;
66647584Smccanne 
66747584Smccanne 	/*
66847584Smccanne 	 * Set interface.
66947584Smccanne 	 */
67047584Smccanne 	case BIOCSETIF:
67147584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
67247584Smccanne 		break;
67347584Smccanne 
67447584Smccanne 	/*
67547584Smccanne 	 * Set read timeout.
67647584Smccanne 	 */
67747584Smccanne  	case BIOCSRTIMEOUT:
67847584Smccanne 		{
67947584Smccanne 			struct timeval *tv = (struct timeval *)addr;
68047584Smccanne 			u_long msec;
68147584Smccanne 
68247584Smccanne 			/* Compute number of milliseconds. */
68347584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
68447584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
68547584Smccanne 			   clock has millisecond or greater resolution
68647584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
68747584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
68847584Smccanne 			d->bd_rtout = msec / (tick / 1000);
68947584Smccanne 			break;
69047584Smccanne 		}
69147584Smccanne 
69247584Smccanne 	/*
69347584Smccanne 	 * Get read timeout.
69447584Smccanne 	 */
69547584Smccanne  	case BIOCGRTIMEOUT:
69647584Smccanne 		{
69747584Smccanne 			struct timeval *tv = (struct timeval *)addr;
69847584Smccanne 			u_long msec = d->bd_rtout;
69947584Smccanne 
70047584Smccanne 			msec *= tick / 1000;
70147584Smccanne 			tv->tv_sec = msec / 1000;
70247584Smccanne 			tv->tv_usec = msec % 1000;
70347584Smccanne 			break;
70447584Smccanne 		}
70547584Smccanne 
70647584Smccanne 	/*
70747584Smccanne 	 * Get packet stats.
70847584Smccanne 	 */
70947584Smccanne 	case BIOCGSTATS:
71047584Smccanne 		{
71147584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
71247584Smccanne 
71347584Smccanne 			bs->bs_recv = d->bd_rcount;
71447584Smccanne 			bs->bs_drop = d->bd_dcount;
71547584Smccanne 			break;
71647584Smccanne 		}
71747584Smccanne 
71847584Smccanne 	/*
71947584Smccanne 	 * Set immediate mode.
72047584Smccanne 	 */
72147584Smccanne 	case BIOCIMMEDIATE:
72247584Smccanne 		d->bd_immediate = *(u_int *)addr;
72347584Smccanne 		break;
72447584Smccanne 	}
72548932Smccanne 	return (error);
72647584Smccanne }
72747584Smccanne 
72847584Smccanne /*
729*51425Smccanne  * Set d's packet filter program to fp.  If this file already has a filter,
73048932Smccanne  * free it and replace it.  Returns EINVAL for bogus requests.
73147584Smccanne  */
73247584Smccanne int
73347584Smccanne bpf_setf(d, fp)
73447584Smccanne 	struct bpf_d *d;
73547584Smccanne 	struct bpf_program *fp;
73647584Smccanne {
73748932Smccanne 	struct bpf_insn *fcode, *old;
73847584Smccanne 	u_int flen, size;
73947584Smccanne 	int s;
74047584Smccanne 
74148932Smccanne 	old = d->bd_filter;
74247584Smccanne 	if (fp->bf_insns == 0) {
74347584Smccanne 		if (fp->bf_len != 0)
74448932Smccanne 			return (EINVAL);
74548932Smccanne 		s = splimp();
74648967Smccanne 		d->bd_filter = 0;
74747584Smccanne 		reset_d(d);
74847584Smccanne 		splx(s);
74948967Smccanne 		if (old != 0)
75048932Smccanne 			free((caddr_t)old, M_DEVBUF);
75148932Smccanne 		return (0);
75247584Smccanne 	}
75347584Smccanne 	flen = fp->bf_len;
75448932Smccanne 	if (flen > BPF_MAXINSNS)
75548932Smccanne 		return (EINVAL);
75648932Smccanne 
75747584Smccanne 	size = flen * sizeof(*fp->bf_insns);
75848932Smccanne 	fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
75950417Smccanne 	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
76050417Smccanne 	    bpf_validate(fcode, (int)flen)) {
76148967Smccanne 		s = splimp();
76248932Smccanne 		d->bd_filter = fcode;
76347584Smccanne 		reset_d(d);
76447584Smccanne 		splx(s);
76548967Smccanne 		if (old != 0)
76648932Smccanne 			free((caddr_t)old, M_DEVBUF);
76747584Smccanne 
76848932Smccanne 		return (0);
76947584Smccanne 	}
77048932Smccanne 	free((caddr_t)fcode, M_DEVBUF);
77148932Smccanne 	return (EINVAL);
77247584Smccanne }
77347584Smccanne 
77447584Smccanne /*
775*51425Smccanne  * Detach a file from its current interface (if attached at all) and attach
776*51425Smccanne  * to the interface indicated by the name stored in ifr.
777*51425Smccanne  * Return an errno or 0.
77847584Smccanne  */
77947584Smccanne static int
78047584Smccanne bpf_setif(d, ifr)
78147584Smccanne 	struct bpf_d *d;
78247584Smccanne 	struct ifreq *ifr;
78347584Smccanne {
78447584Smccanne 	struct bpf_if *bp;
78547584Smccanne 	char *cp;
78649202Smccanne 	int unit, s;
78747584Smccanne 
78847584Smccanne 	/*
78947584Smccanne 	 * Separate string into name part and unit number.  Put a null
79047584Smccanne 	 * byte at the end of the name part, and compute the number.
79147584Smccanne 	 * If the a unit number is unspecified, the default is 0,
79248932Smccanne 	 * as initialized above.  XXX This should be common code.
79347584Smccanne 	 */
79447584Smccanne 	unit = 0;
79547584Smccanne 	cp = ifr->ifr_name;
79647584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
79747584Smccanne 	while (*cp++) {
79847584Smccanne 		if (*cp >= '0' && *cp <= '9') {
79947584Smccanne 			unit = *cp - '0';
80047584Smccanne 			*cp++ = '\0';
80147584Smccanne 			while (*cp)
80247584Smccanne 				unit = 10 * unit + *cp++ - '0';
80347584Smccanne 			break;
80447584Smccanne 		}
80547584Smccanne 	}
80647584Smccanne 	/*
80747584Smccanne 	 * Look through attached interfaces for the named one.
80847584Smccanne 	 */
80949202Smccanne 	for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
81047584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
81147584Smccanne 
81247584Smccanne 		if (ifp == 0 || unit != ifp->if_unit
81347584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
81447584Smccanne 			continue;
81547584Smccanne 		/*
81647584Smccanne 		 * We found the requested interface.  If we're
81747584Smccanne 		 * already attached to it, just flush the buffer.
81847584Smccanne 		 * If it's not up, return an error.
81947584Smccanne 		 */
82047584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
82148932Smccanne 			return (ENETDOWN);
82247584Smccanne 		s = splimp();
82347584Smccanne 		if (bp != d->bd_bif) {
82447584Smccanne 			if (d->bd_bif)
82547584Smccanne 				/*
82648932Smccanne 				 * Detach if attached to something else.
82747584Smccanne 				 */
82847584Smccanne 				bpf_detachd(d);
82947584Smccanne 
83047584Smccanne 			bpf_attachd(d, bp);
83147584Smccanne 		}
83247584Smccanne 		reset_d(d);
83347584Smccanne 		splx(s);
83448932Smccanne 		return (0);
83547584Smccanne 	}
83647584Smccanne 	/* Not found. */
83748932Smccanne 	return (ENXIO);
83847584Smccanne }
83947584Smccanne 
84047584Smccanne /*
841*51425Smccanne  * Convert an interface name plus unit number of an ifp to a single
842*51425Smccanne  * name which is returned in the ifr.
84347584Smccanne  */
84447584Smccanne static void
84547584Smccanne bpf_ifname(ifp, ifr)
84647584Smccanne 	struct ifnet *ifp;
84747584Smccanne 	struct ifreq *ifr;
84847584Smccanne {
84947584Smccanne 	char *s = ifp->if_name;
85047584Smccanne 	char *d = ifr->ifr_name;
85147584Smccanne 
85247584Smccanne 	while (*d++ = *s++)
85347584Smccanne 		;
85448932Smccanne 	/* XXX Assume that unit number is less than 10. */
85547584Smccanne 	*d++ = ifp->if_unit + '0';
85647584Smccanne 	*d = '\0';
85747584Smccanne }
85847584Smccanne 
85947584Smccanne /*
860*51425Smccanne  * The new select interface passes down the proc pointer; the old select
861*51425Smccanne  * stubs had to grab it out of the user struct.  This glue allows either case.
862*51425Smccanne  */
863*51425Smccanne #if BSD >= 199103
864*51425Smccanne #define bpf_select bpfselect
865*51425Smccanne #else
866*51425Smccanne int
867*51425Smccanne bpfselect(dev, rw)
868*51425Smccanne 	register dev_t dev;
869*51425Smccanne 	int rw;
870*51425Smccanne {
871*51425Smccanne 	bpf_select(dev, rw, u.u_procp);
872*51425Smccanne }
873*51425Smccanne #endif
874*51425Smccanne 
875*51425Smccanne /*
87647584Smccanne  * Support for select() system call
87747584Smccanne  * Inspired by the code in tty.c for the same purpose.
87847584Smccanne  *
87947584Smccanne  * bpfselect - returns true iff the specific operation
88047584Smccanne  *	will not block indefinitely.  Otherwise, return
88147584Smccanne  *	false but make a note that a selwakeup() must be done.
88247584Smccanne  */
88347584Smccanne int
884*51425Smccanne bpf_select(dev, rw, p)
88547584Smccanne 	register dev_t dev;
88647584Smccanne 	int rw;
88748932Smccanne 	struct proc *p;
88847584Smccanne {
88947584Smccanne 	register struct bpf_d *d;
89047584Smccanne 	register int s;
89147584Smccanne 
89247584Smccanne 	if (rw != FREAD)
89348932Smccanne 		return (0);
89447584Smccanne 	/*
89547584Smccanne 	 * An imitation of the FIONREAD ioctl code.
89647584Smccanne 	 */
89747584Smccanne 	d = &bpf_dtab[minor(dev)];
89847584Smccanne 
89947584Smccanne 	s = splimp();
90049723Smccanne 	if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
90147584Smccanne 		/*
90247584Smccanne 		 * There is data waiting.
90347584Smccanne 		 */
90447584Smccanne 		splx(s);
90548932Smccanne 		return (1);
90647584Smccanne 	}
90747584Smccanne 	/*
90847584Smccanne 	 * No data ready.  If there's already a select() waiting on this
90947584Smccanne 	 * minor device then this is a collision.  This shouldn't happen
91047584Smccanne 	 * because minors really should not be shared, but if a process
91147584Smccanne 	 * forks while one of these is open, it is possible that both
91247584Smccanne 	 * processes could select on the same descriptor.
91347584Smccanne 	 */
91448932Smccanne 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
91548932Smccanne 		d->bd_selcoll = 1;
91647584Smccanne 	else
91748932Smccanne 		d->bd_selproc = p;
91848932Smccanne 
91947584Smccanne 	splx(s);
92048932Smccanne 	return (0);
92147584Smccanne }
92247584Smccanne 
92347584Smccanne /*
92447584Smccanne  * bpf_tap - incoming linkage from device drivers
92547584Smccanne  */
92647584Smccanne void
92748932Smccanne bpf_tap(arg, pkt, pktlen)
92847584Smccanne 	caddr_t arg;
92948932Smccanne 	register u_char *pkt;
93048932Smccanne 	register u_int pktlen;
93147584Smccanne {
93247584Smccanne 	struct bpf_if *bp;
93347584Smccanne 	register struct bpf_d *d;
93447584Smccanne 	register u_int slen;
93547584Smccanne 	/*
93647584Smccanne 	 * Note that the ipl does not have to be raised at this point.
93747584Smccanne 	 * The only problem that could arise here is that if two different
93847584Smccanne 	 * interfaces shared any data.  This is not the case.
93947584Smccanne 	 */
94047584Smccanne 	bp = (struct bpf_if *)arg;
94147584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
94247584Smccanne 		++d->bd_rcount;
94349202Smccanne 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
94447584Smccanne 		if (slen != 0)
94549202Smccanne 			catchpacket(d, pkt, pktlen, slen, bcopy);
94647584Smccanne 	}
94747584Smccanne }
94847584Smccanne 
94947584Smccanne /*
95047584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
95147584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
95247584Smccanne  */
95347584Smccanne static void
95449202Smccanne bpf_mcopy(src, dst, len)
95547584Smccanne 	u_char *src;
95647584Smccanne 	u_char *dst;
95747584Smccanne 	register int len;
95847584Smccanne {
95947584Smccanne 	register struct mbuf *m = (struct mbuf *)src;
96047584Smccanne 	register unsigned count;
96147584Smccanne 
96247584Smccanne 	while (len > 0) {
96347584Smccanne 		if (m == 0)
96449202Smccanne 			panic("bpf_mcopy");
96547584Smccanne 		count = MIN(m->m_len, len);
96649202Smccanne 		bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
96749202Smccanne 		m = m->m_next;
96849202Smccanne 		dst += count;
96947584Smccanne 		len -= count;
97047584Smccanne 	}
97147584Smccanne }
97247584Smccanne 
97347584Smccanne /*
974*51425Smccanne  * bpf_mtap -	incoming linkage from device drivers, when packet
975*51425Smccanne  *		is in an mbuf chain
97647584Smccanne  */
97747584Smccanne void
97849202Smccanne bpf_mtap(arg, m)
97947584Smccanne 	caddr_t arg;
98049202Smccanne 	struct mbuf *m;
98147584Smccanne {
98247584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
98347584Smccanne 	struct bpf_d *d;
98449202Smccanne 	u_int pktlen, slen;
98549202Smccanne 	struct mbuf *m0;
98647584Smccanne 
98748932Smccanne 	pktlen = 0;
988*51425Smccanne 	for (m0 = m; m0 != 0; m0 = m0->m_next)
98949202Smccanne 		pktlen += m0->m_len;
99049723Smccanne 
99147584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
99247584Smccanne 		++d->bd_rcount;
99349202Smccanne 		slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
99447584Smccanne 		if (slen != 0)
99549202Smccanne 			catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
99647584Smccanne 	}
99747584Smccanne }
99847584Smccanne 
99947584Smccanne /*
100049202Smccanne  * Move the packet data from interface memory (pkt) into the
100147584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
1002*51425Smccanne  * otherwise 0.  "copy" is the routine called to do the actual data
1003*51425Smccanne  * transfer.  bcopy is passed in to copy contiguous chunks, while
1004*51425Smccanne  * bpf_mcopy is passed in to copy mbuf chains.  In the latter case,
1005*51425Smccanne  * pkt is really an mbuf.
100647584Smccanne  */
100747584Smccanne static void
100848932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn)
100948932Smccanne 	register struct bpf_d *d;
101048932Smccanne 	register u_char *pkt;
101148932Smccanne 	register u_int pktlen, snaplen;
101248932Smccanne 	register void (*cpfn)();
101347584Smccanne {
101448932Smccanne 	register struct bpf_hdr *hp;
101548932Smccanne 	register int totlen, curlen;
101648932Smccanne 	register int hdrlen = d->bd_bif->bif_hdrlen;
101747584Smccanne 	/*
101847584Smccanne 	 * Figure out how many bytes to move.  If the packet is
101947584Smccanne 	 * greater or equal to the snapshot length, transfer that
102047584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
102148932Smccanne 	 * we hit the buffer size limit).
102247584Smccanne 	 */
102350082Smccanne 	totlen = hdrlen + MIN(snaplen, pktlen);
102450082Smccanne 	if (totlen > d->bd_bufsize)
102550082Smccanne 		totlen = d->bd_bufsize;
102647584Smccanne 
102747584Smccanne 	/*
102847584Smccanne 	 * Round up the end of the previous packet to the next longword.
102947584Smccanne 	 */
103048932Smccanne 	curlen = BPF_WORDALIGN(d->bd_slen);
103148932Smccanne 	if (curlen + totlen > d->bd_bufsize) {
103247584Smccanne 		/*
103347584Smccanne 		 * This packet will overflow the storage buffer.
103448932Smccanne 		 * Rotate the buffers if we can, then wakeup any
103548932Smccanne 		 * pending reads.
103647584Smccanne 		 */
103747584Smccanne 		if (d->bd_fbuf == 0) {
103847584Smccanne 			/*
103948932Smccanne 			 * We haven't completed the previous read yet,
104048932Smccanne 			 * so drop the packet.
104147584Smccanne 			 */
104247584Smccanne 			++d->bd_dcount;
104347584Smccanne 			return;
104447584Smccanne 		}
104548932Smccanne 		ROTATE_BUFFERS(d);
104647584Smccanne 		bpf_wakeup(d);
104748932Smccanne 		curlen = 0;
104847584Smccanne 	}
104948932Smccanne 	else if (d->bd_immediate)
105047584Smccanne 		/*
105147584Smccanne 		 * Immediate mode is set.  A packet arrived so any
105247584Smccanne 		 * reads should be woken up.
105347584Smccanne 		 */
105447584Smccanne 		bpf_wakeup(d);
105548932Smccanne 
105647584Smccanne 	/*
105747584Smccanne 	 * Append the bpf header.
105847584Smccanne 	 */
105948932Smccanne 	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
106047584Smccanne #ifdef sun
106147584Smccanne 	uniqtime(&hp->bh_tstamp);
106247584Smccanne #else
1063*51425Smccanne #if BSD >= 199103
106447584Smccanne 	microtime(&hp->bh_tstamp);
106547584Smccanne #else
106647584Smccanne 	hp->bh_tstamp = time;
106747584Smccanne #endif
106847584Smccanne #endif
106948932Smccanne 	hp->bh_datalen = pktlen;
107047584Smccanne 	hp->bh_hdrlen = hdrlen;
107147584Smccanne 	/*
107248932Smccanne 	 * Copy the packet data into the store buffer and update its length.
107347584Smccanne 	 */
107448932Smccanne 	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
107548932Smccanne 	d->bd_slen = curlen + totlen;
107647584Smccanne }
107747584Smccanne 
107847584Smccanne /*
107947584Smccanne  * Initialize all nonzero fields of a descriptor.
108047584Smccanne  */
108147584Smccanne static int
108247584Smccanne bpf_initd(d)
108347584Smccanne 	register struct bpf_d *d;
108447584Smccanne {
108548932Smccanne 	d->bd_bufsize = bpf_bufsize;
108648932Smccanne 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
108748932Smccanne 	if (d->bd_fbuf == 0)
108848932Smccanne 		return (ENOBUFS);
108947584Smccanne 
109048932Smccanne 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
109148932Smccanne 	if (d->bd_sbuf == 0) {
109248932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
109348932Smccanne 		return (ENOBUFS);
109447584Smccanne 	}
109548932Smccanne 	d->bd_slen = 0;
109648932Smccanne 	d->bd_hlen = 0;
109748932Smccanne 	return (0);
109847584Smccanne }
109947584Smccanne 
110047584Smccanne /*
1101*51425Smccanne  * Free buffers currently in use by a descriptor.
1102*51425Smccanne  * Called on close.
110347584Smccanne  */
1104*51425Smccanne bpf_freed(d)
1105*51425Smccanne 	register struct bpf_d *d;
1106*51425Smccanne {
1107*51425Smccanne 	/*
1108*51425Smccanne 	 * We don't need to lock out interrupts since this descriptor has
1109*51425Smccanne 	 * been detached from its interface and it yet hasn't been marked
1110*51425Smccanne 	 * free.
1111*51425Smccanne 	 */
1112*51425Smccanne 	if (d->bd_hbuf)
1113*51425Smccanne 		free(d->bd_hbuf, M_DEVBUF);
1114*51425Smccanne 	if (d->bd_fbuf)
1115*51425Smccanne 		free(d->bd_fbuf, M_DEVBUF);
1116*51425Smccanne 	free(d->bd_sbuf, M_DEVBUF);
1117*51425Smccanne 	if (d->bd_filter)
1118*51425Smccanne 		free((caddr_t)d->bd_filter, M_DEVBUF);
1119*51425Smccanne 
1120*51425Smccanne 	D_MARKFREE(d);
1121*51425Smccanne }
1122*51425Smccanne 
1123*51425Smccanne /*
1124*51425Smccanne  * Attach an interface to bpf.  driverp is a pointer to a (struct bpf_if *)
1125*51425Smccanne  * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
1126*51425Smccanne  * size of the link header (variable length headers not yet supported).
1127*51425Smccanne  */
112847584Smccanne void
112949202Smccanne bpfattach(driverp, ifp, dlt, hdrlen)
113047584Smccanne 	caddr_t *driverp;
113147584Smccanne 	struct ifnet *ifp;
113249202Smccanne 	u_int dlt, hdrlen;
113347584Smccanne {
113447584Smccanne 	struct bpf_if *bp;
113547584Smccanne 	int i;
1136*51425Smccanne #if BSD < 199103
1137*51425Smccanne 	static struct bpf_if bpf_ifs[NBPFILTER];
1138*51425Smccanne 	static int bpfifno;
113947584Smccanne 
1140*51425Smccanne 	bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0;
1141*51425Smccanne #else
114249202Smccanne 	bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
1143*51425Smccanne #endif
114449202Smccanne 	if (bp == 0)
114549202Smccanne 		panic("bpfattach");
114647584Smccanne 
114747584Smccanne 	bp->bif_dlist = 0;
114847584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
114947584Smccanne 	bp->bif_ifp = ifp;
115049202Smccanne 	bp->bif_dlt = dlt;
115147584Smccanne 
115249202Smccanne 	bp->bif_next = bpf_iflist;
115349202Smccanne 	bpf_iflist = bp;
115449202Smccanne 
115548932Smccanne 	*bp->bif_driverp = 0;
115648932Smccanne 
115747584Smccanne 	/*
115847584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
115947584Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
116047584Smccanne 	 * that the network layer header begins on a longword boundary (for
116147584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
116247584Smccanne 	 */
116349202Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
116447584Smccanne 
116547584Smccanne 	/*
116647584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
116747584Smccanne 	 */
116847584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
116947584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
117047584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
117147584Smccanne 
117247584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
117347584Smccanne }
117447584Smccanne 
1175*51425Smccanne #if BSD >= 199103
117648967Smccanne /* XXX This routine belongs in net/if.c. */
117748932Smccanne /*
117848932Smccanne  * Set/clear promiscuous mode on interface ifp based on the truth value`
117948932Smccanne  * of pswitch.  The calls are reference counted so that only the first
118048932Smccanne  * on request actually has an effect, as does the final off request.
118148932Smccanne  * Results are undefined if the off and on requests are not matched.
118248932Smccanne  */
118348932Smccanne int
118448932Smccanne ifpromisc(ifp, pswitch)
118548932Smccanne 	struct ifnet *ifp;
118648932Smccanne 	int pswitch;
118748932Smccanne {
118849726Smccanne 	struct ifreq ifr;
118948932Smccanne 	/*
119048932Smccanne 	 * If the device is not configured up, we cannot put it in
119148932Smccanne 	 * promiscuous mode.
119248932Smccanne 	 */
119348932Smccanne 	if ((ifp->if_flags & IFF_UP) == 0)
119448932Smccanne 		return (ENETDOWN);
119548932Smccanne 
119648932Smccanne 	if (pswitch) {
119748932Smccanne 		if (ifp->if_pcount++ != 0)
119848932Smccanne 			return (0);
119948932Smccanne 		ifp->if_flags |= IFF_PROMISC;
120048932Smccanne 	} else {
120148932Smccanne 		if (--ifp->if_pcount > 0)
120248932Smccanne 			return (0);
120348932Smccanne 		ifp->if_flags &= ~IFF_PROMISC;
120448932Smccanne 	}
120549726Smccanne 	ifr.ifr_flags = ifp->if_flags;
120649726Smccanne 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
120748932Smccanne }
1208*51425Smccanne #endif
120948932Smccanne 
1210*51425Smccanne #if BSD < 199103
1211*51425Smccanne /*
1212*51425Smccanne  * Allocate some memory for bpf.  This is temporary SunOS support, and
1213*51425Smccanne  * is admittedly a gross hack.
1214*51425Smccanne  * If resources unavaiable, return 0.
1215*51425Smccanne  */
1216*51425Smccanne static caddr_t
1217*51425Smccanne bpf_alloc(size, canwait)
1218*51425Smccanne 	register int size;
1219*51425Smccanne 	register int canwait;
1220*51425Smccanne {
1221*51425Smccanne 	register struct mbuf *m;
1222*51425Smccanne 
1223*51425Smccanne 	if ((unsigned)size > (MCLBYTES-8))
1224*51425Smccanne 		return 0;
1225*51425Smccanne 
1226*51425Smccanne 	MGET(m, canwait, MT_DATA);
1227*51425Smccanne 	if (m == 0)
1228*51425Smccanne 		return 0;
1229*51425Smccanne 	if ((unsigned)size > (MLEN-8)) {
1230*51425Smccanne 		MCLGET(m);
1231*51425Smccanne 		if (m->m_len != MCLBYTES) {
1232*51425Smccanne 			m_freem(m);
1233*51425Smccanne 			return 0;
1234*51425Smccanne 		}
1235*51425Smccanne 	}
1236*51425Smccanne 	*mtod(m, struct mbuf **) = m;
1237*51425Smccanne 	return mtod(m, caddr_t) + 8;
1238*51425Smccanne }
1239*51425Smccanne #endif
1240*51425Smccanne #endif
1241