xref: /csrg-svn/sys/net/bpf.c (revision 48932)
147584Smccanne /*
247584Smccanne  * Copyright (c) 1990 The Regents of the University of California.
347584Smccanne  * All rights reserved.
447584Smccanne  *
547584Smccanne  * Redistribution and use in source and binary forms, with or without
647584Smccanne  * modification, are permitted provided that: (1) source code distributions
747584Smccanne  * retain the above copyright notice and this paragraph in its entirety, (2)
847584Smccanne  * distributions including binary code include the above copyright notice and
947584Smccanne  * this paragraph in its entirety in the documentation or other materials
1047584Smccanne  * provided with the distribution, and (3) all advertising materials mentioning
1147584Smccanne  * features or use of this software display the following acknowledgement:
1247584Smccanne  * ``This product includes software developed by the University of California,
1347584Smccanne  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1447584Smccanne  * the University nor the names of its contributors may be used to endorse
1547584Smccanne  * or promote products derived from this software without specific prior
1647584Smccanne  * written permission.
1747584Smccanne  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1847584Smccanne  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1947584Smccanne  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2047584Smccanne  *
2147584Smccanne  * This code is derived from the Stanford/CMU enet packet filter,
2247584Smccanne  * (net/enet.c) distributed in 4.3BSD Unix.
2347584Smccanne  */
2447584Smccanne #ifndef lint
2547584Smccanne static char rcsid[] =
2647584Smccanne     "$Header: bpf.c,v 1.23 91/01/30 18:22:13 mccanne Exp $";
2747584Smccanne #endif
2847584Smccanne 
2947584Smccanne #include "bpfilter.h"
3047584Smccanne 
3147584Smccanne #if (NBPFILTER > 0)
3247584Smccanne 
3347584Smccanne #ifndef __GNUC__
3447584Smccanne #define inline
3547584Smccanne #endif
3647584Smccanne 
3747584Smccanne #include <sys/param.h>
3847584Smccanne #include <sys/systm.h>
3947584Smccanne #include <sys/mbuf.h>
4047584Smccanne #include <sys/buf.h>
4147584Smccanne #include <sys/dir.h>
42*48932Smccanne #include <sys/proc.h>
4347584Smccanne #include <sys/user.h>
4447584Smccanne #include <sys/ioctl.h>
4547584Smccanne #include <sys/map.h>
4647584Smccanne 
4747584Smccanne #include <sys/file.h>
4847584Smccanne #ifdef sparc
4947584Smccanne #include <sys/stream.h>
5047584Smccanne #endif
5147584Smccanne #include <sys/tty.h>
5247584Smccanne #include <sys/uio.h>
5347584Smccanne 
5447584Smccanne #include <sys/protosw.h>
5547584Smccanne #include <sys/socket.h>
5647584Smccanne #include <net/if.h>
5747584Smccanne 
5847584Smccanne #include <net/bpf.h>
5947584Smccanne #include <net/bpfdesc.h>
6047584Smccanne 
6147584Smccanne #include <sys/errno.h>
6247584Smccanne 
6347584Smccanne #include <netinet/in.h>
6447584Smccanne #include <netinet/if_ether.h>
6547584Smccanne #include <sys/kernel.h>
6647584Smccanne 
6747584Smccanne #define PRINET  26			/* interruptible */
6847584Smccanne 
6947584Smccanne /*
70*48932Smccanne  * The default read buffer size is patchable.
71*48932Smccanne  */
72*48932Smccanne int bpf_bufsize = MCLBYTES;
73*48932Smccanne 
74*48932Smccanne /*
7547584Smccanne  *  'bpf_iftab' is the driver state table per logical unit number
7647584Smccanne  *  'bpf_dtab' holds the descriptors, indexed by minor device #
7747584Smccanne  *  'bpf_units' is the number of attached units
7847584Smccanne  *
7947584Smccanne  * We really don't need NBPFILTER bpf_if entries, but this eliminates
8047584Smccanne  * the need to account for all possible drivers here.
8147584Smccanne  * This problem will go away when these structures are allocated dynamically.
8247584Smccanne  */
8347584Smccanne static struct bpf_if 	bpf_iftab[NBPFILTER];
8447584Smccanne static struct bpf_d	bpf_dtab[NBPFILTER];
8547584Smccanne static u_int		bpf_units = 0;
8647584Smccanne 
8747584Smccanne static void	bpf_ifname();
8847584Smccanne static void	catchpacket();
8947584Smccanne static int	bpf_setif();
9047584Smccanne static int	bpf_initd();
9147584Smccanne 
9247584Smccanne /*
9347584Smccanne  * The default filter accepts the maximum number of bytes from each packet.
9447584Smccanne  */
9547584Smccanne struct bpf_insn bpf_default_filter[] = {
96*48932Smccanne 	BPF_STMT(RetOp, -1),
9747584Smccanne };
9847584Smccanne 
9947584Smccanne static int
10047584Smccanne bpf_movein(uio, linktype, mp, sockp)
10147584Smccanne 	register struct uio *uio;
10247584Smccanne 	int linktype;
10347584Smccanne 	register struct mbuf **mp;
10447584Smccanne 	register struct sockaddr *sockp;
10547584Smccanne {
10647584Smccanne 	struct mbuf *m;
10747584Smccanne 	int error;
10847584Smccanne 	int len;
10947584Smccanne 	int hlen;
11047584Smccanne 
11147584Smccanne 	/*
11247584Smccanne 	 * Build a sockaddr based on the data link layer type.
11347584Smccanne 	 * We do this at this level because the ethernet header
11447584Smccanne 	 * is copied directly into the data field of the sockaddr.
11547584Smccanne 	 * In the case of SLIP, there is no header and the packet
11647584Smccanne 	 * is forwarded as is.
11747584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
11847584Smccanne 	 * for the link level header.
11947584Smccanne 	 */
12047584Smccanne 	switch (linktype) {
12147584Smccanne 	case DLT_SLIP:
12247584Smccanne 		sockp->sa_family = AF_INET;
12347584Smccanne 		hlen = 0;
12447584Smccanne 		break;
12547584Smccanne 
12647584Smccanne 	case DLT_EN10MB:
12747584Smccanne 		sockp->sa_family = AF_UNSPEC;
12847584Smccanne 		/* XXX Would MAXLINKHDR be better? */
12947584Smccanne 		hlen = sizeof(struct ether_header);
13047584Smccanne 		break;
13147584Smccanne 
13247584Smccanne        case DLT_FDDI:
13347584Smccanne 		sockp->sa_family = AF_UNSPEC;
13447584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
13547584Smccanne 		hlen = 24;
13647584Smccanne 		break;
13747584Smccanne 
13847584Smccanne 	default:
139*48932Smccanne 		return (EIO);
14047584Smccanne 	}
14147584Smccanne 
14247584Smccanne 	len = uio->uio_resid;
14347584Smccanne 	if ((unsigned)len > MCLBYTES)
144*48932Smccanne 		return (EIO);
14547584Smccanne 
14647584Smccanne 	MGET(m, M_WAIT, MT_DATA);
14747584Smccanne 	if (m == 0)
148*48932Smccanne 		return (ENOBUFS);
14947584Smccanne 	if (len > MLEN) {
150*48932Smccanne 		MCLGET(m, M_WAIT);
151*48932Smccanne 		if ((m->m_flags & M_EXT) == 0) {
15247584Smccanne 			error = ENOBUFS;
15347584Smccanne 			goto bad;
15447584Smccanne 		}
15547584Smccanne 	}
15647584Smccanne 	m->m_len = len;
15747584Smccanne 	*mp = m;
15847584Smccanne 	/*
15947584Smccanne 	 * Make room for link header.
16047584Smccanne 	 */
16147584Smccanne 	if (hlen) {
16247584Smccanne 		m->m_len -= hlen;
163*48932Smccanne 		m->m_data += hlen; /* XXX */
16447584Smccanne 
165*48932Smccanne 		error = uiomove((caddr_t)sockp->sa_data, hlen, uio);
16647584Smccanne 		if (error)
16747584Smccanne 			goto bad;
16847584Smccanne 	}
169*48932Smccanne 	error = uiomove(mtod(m, caddr_t), len - hlen, uio);
17047584Smccanne 	if (!error)
171*48932Smccanne 		return (0);
17247584Smccanne  bad:
17347584Smccanne 	m_freem(m);
174*48932Smccanne 	return (error);
17547584Smccanne }
17647584Smccanne 
17747584Smccanne /*
17847584Smccanne  * Attach 'd' to the bpf interface 'bp', i.e. make 'd' listen on 'bp'.
17947584Smccanne  * Must be called at splimp.
18047584Smccanne  */
18147584Smccanne static void
18247584Smccanne bpf_attachd(d, bp)
18347584Smccanne 	struct bpf_d *d;
18447584Smccanne 	struct bpf_if *bp;
18547584Smccanne {
186*48932Smccanne 	/* Point d at bp. */
18747584Smccanne 	d->bd_bif = bp;
18847584Smccanne 
189*48932Smccanne 	/* Add d to bp's list of listeners. */
19047584Smccanne 	d->bd_next = bp->bif_dlist;
19147584Smccanne 	bp->bif_dlist = d;
19247584Smccanne 
19347584Smccanne 	/*
19447584Smccanne 	 * Let the driver know we're here (if it doesn't already).
19547584Smccanne 	 */
19647584Smccanne 	*bp->bif_driverp = bp;
19747584Smccanne }
19847584Smccanne 
19947584Smccanne static void
20047584Smccanne bpf_detachd(d)
20147584Smccanne 	struct bpf_d *d;
20247584Smccanne {
20347584Smccanne 	struct bpf_d **p;
20447584Smccanne 	struct bpf_if *bp;
20547584Smccanne 
20647584Smccanne 	bp = d->bd_bif;
20747584Smccanne 	/*
20847584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
20947584Smccanne 	 * If so, turn it off.
21047584Smccanne 	 */
21147584Smccanne 	if (d->bd_promisc) {
21247584Smccanne 		d->bd_promisc = 0;
21347584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
21447584Smccanne 			/*
21547584Smccanne 			 * Something is really wrong if we were able to put
21647584Smccanne 			 * the driver into promiscuous mode, but can't
21747584Smccanne 			 * take it out.
21847584Smccanne 			 */
219*48932Smccanne 			panic("bpf_detachd: ifpromisc failed");
22047584Smccanne 	}
22147584Smccanne 	/* Remove 'd' from the interface's descriptor list. */
22247584Smccanne 	p = &bp->bif_dlist;
22347584Smccanne 	while (*p != d) {
22447584Smccanne 		p = &(*p)->bd_next;
22547584Smccanne 		if (*p == 0)
22647584Smccanne 			panic("bpf_detachd: descriptor not in list");
22747584Smccanne 	}
22847584Smccanne 	*p = (*p)->bd_next;
22947584Smccanne 	if (bp->bif_dlist == 0)
23047584Smccanne 		/*
23147584Smccanne 		 * Let the driver know that there are no more listeners.
23247584Smccanne 		 */
23347584Smccanne 		*d->bd_bif->bif_driverp = 0;
23447584Smccanne 	d->bd_bif = 0;
23547584Smccanne }
23647584Smccanne 
23747584Smccanne 
23847584Smccanne /*
23947584Smccanne  * Mark a descriptor free by making it point to itself.
24047584Smccanne  * This is probably cheaper than marking with a constant since
24147584Smccanne  * the address should be in a register anyway.
24247584Smccanne  */
24347584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
24447584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
24547584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
24647584Smccanne 
24747584Smccanne /*
24847584Smccanne  *  bpfopen - open ethernet device
24947584Smccanne  *
25047584Smccanne  *  Errors:	ENXIO	- illegal minor device number
25147584Smccanne  *		EBUSY	- too many files open
25247584Smccanne  */
25347584Smccanne /* ARGSUSED */
25447584Smccanne int
25547584Smccanne bpfopen(dev, flag)
25647584Smccanne 	dev_t dev;
25747584Smccanne 	int flag;
25847584Smccanne {
25947584Smccanne 	int error, s;
26047584Smccanne 	register struct bpf_d *d;
26147584Smccanne 
26247584Smccanne 	if (minor(dev) >= NBPFILTER)
263*48932Smccanne 		return (ENXIO);
26447584Smccanne 
26547584Smccanne 	/*
26647584Smccanne 	 * Each minor can be opened by only one process.  If the requested
26747584Smccanne 	 * minor is in use, return EBUSY.
26847584Smccanne 	 */
26947584Smccanne 	s = splimp();
27047584Smccanne 	d = &bpf_dtab[minor(dev)];
27147584Smccanne 	if (!D_ISFREE(d)) {
27247584Smccanne 		splx(s);
273*48932Smccanne 		return (EBUSY);
27447584Smccanne 	} else
27547584Smccanne 		/* Mark "free" and do most initialization. */
27647584Smccanne 		bzero((char *)d, sizeof(*d));
27747584Smccanne 	d->bd_filter = bpf_default_filter;
27847584Smccanne 	splx(s);
27947584Smccanne 
28047584Smccanne 	error = bpf_initd(d);
28147584Smccanne 	if (error) {
28247584Smccanne 		D_MARKFREE(d);
283*48932Smccanne 		return (error);
28447584Smccanne 	}
285*48932Smccanne 	return (0);
28647584Smccanne }
28747584Smccanne 
28847584Smccanne /*
28947584Smccanne  * Close the descriptor by detaching it from its interface,
29047584Smccanne  * deallocating its buffers, and marking it free.
29147584Smccanne  */
29247584Smccanne /* ARGSUSED */
29347584Smccanne bpfclose(dev, flag)
29447584Smccanne 	dev_t dev;
29547584Smccanne 	int flag;
29647584Smccanne {
29747584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
29847584Smccanne 	int s;
29947584Smccanne 
30047584Smccanne 	s = splimp();
30147584Smccanne 	if (d->bd_bif)
30247584Smccanne 		bpf_detachd(d);
30347584Smccanne 	splx(s);
30447584Smccanne 
305*48932Smccanne 	/* Free the buffer space. */
306*48932Smccanne 	if (d->bd_hbuf)
307*48932Smccanne 		free(d->bd_hbuf, M_DEVBUF);
308*48932Smccanne 	if (d->bd_fbuf)
309*48932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
310*48932Smccanne 	free(d->bd_sbuf, M_DEVBUF);
311*48932Smccanne 
312*48932Smccanne 	if (d->bd_filter != bpf_default_filter)
313*48932Smccanne 		free((caddr_t)d->bd_filter, M_DEVBUF);
31447584Smccanne 
31547584Smccanne 	D_MARKFREE(d);
31647584Smccanne }
31747584Smccanne 
31847584Smccanne /*
319*48932Smccanne  * Rotate the packet buffers in descriptor d.  Move the store buffer
320*48932Smccanne  * into the hold slot, and the free buffer into the store slot.
321*48932Smccanne  * Zero the length of the new store buffer.
322*48932Smccanne  */
323*48932Smccanne #define ROTATE_BUFFERS(d) \
324*48932Smccanne 	(d)->bd_hbuf = (d)->bd_sbuf; \
325*48932Smccanne 	(d)->bd_hlen = (d)->bd_slen; \
326*48932Smccanne 	(d)->bd_sbuf = (d)->bd_fbuf; \
327*48932Smccanne 	(d)->bd_slen = 0; \
328*48932Smccanne 	(d)->bd_fbuf = 0;
329*48932Smccanne /*
33047584Smccanne  *  bpfread - read next chunk of packets from buffers
33147584Smccanne  */
33247584Smccanne int
33347584Smccanne bpfread(dev, uio)
33447584Smccanne 	dev_t dev;
33547584Smccanne 	register struct uio *uio;
33647584Smccanne {
33747584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
33847584Smccanne 	int error;
33947584Smccanne 	int s;
34047584Smccanne 
34147584Smccanne 	/*
34247584Smccanne 	 * Restrict application to use a buffer the same size as
34347584Smccanne 	 * as kernel buffers.
34447584Smccanne 	 */
345*48932Smccanne 	if (uio->uio_resid != d->bd_bufsize)
346*48932Smccanne 		return (EIO);
34747584Smccanne 
34847584Smccanne 	s = splimp();
34947584Smccanne 	/*
35047584Smccanne 	 * If the hold buffer is empty, then set a timer and sleep
35147584Smccanne 	 * until either the timeout has occurred or enough packets have
35247584Smccanne 	 * arrived to fill the store buffer.
35347584Smccanne 	 */
35447584Smccanne 	while (d->bd_hbuf == 0) {
355*48932Smccanne 		if (d->bd_immediate && d->bd_slen != 0) {
35647584Smccanne 			/*
35747584Smccanne 			 * A packet(s) either arrived since the previous
35847584Smccanne 			 * read or arrived while we were asleep.
35947584Smccanne 			 * Rotate the buffers and return what's here.
36047584Smccanne 			 */
361*48932Smccanne 			ROTATE_BUFFERS(d);
36247584Smccanne 			break;
36347584Smccanne 		}
364*48932Smccanne 		error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf", d->bd_rtout);
365*48932Smccanne 		if (error == EINTR || error == ERESTART) {
366*48932Smccanne 			splx(s);
367*48932Smccanne 			return (error);
36847584Smccanne 		}
369*48932Smccanne 		if (error == EWOULDBLOCK) {
37047584Smccanne 			/*
37147584Smccanne 			 * On a timeout, return what's in the buffer,
372*48932Smccanne 			 * which may be nothing.  If there is something
373*48932Smccanne 			 * in the store buffer, we can rotate the buffers.
37447584Smccanne 			 */
37547584Smccanne 			if (d->bd_hbuf)
37647584Smccanne 				/*
37747584Smccanne 				 * We filled up the buffer in between
37847584Smccanne 				 * getting the timeout and arriving
37947584Smccanne 				 * here, so we don't need to rotate.
38047584Smccanne 				 */
38147584Smccanne 				break;
38247584Smccanne 
383*48932Smccanne 			if (d->bd_slen == 0) {
38447584Smccanne 				splx(s);
385*48932Smccanne 				return (0);
38647584Smccanne 			}
387*48932Smccanne 			ROTATE_BUFFERS(d);
38847584Smccanne 			break;
38947584Smccanne 		}
39047584Smccanne 	}
39147584Smccanne 	/*
39247584Smccanne 	 * At this point, we know we have something in the hold slot.
39347584Smccanne 	 */
39447584Smccanne 	splx(s);
39547584Smccanne 
39647584Smccanne 	/*
39747584Smccanne 	 * Move data from hold buffer into user space.
39847584Smccanne 	 * We know the entire buffer is transferred since
399*48932Smccanne 	 * we checked above that the read buffer is bpf_bufsize bytes.
40047584Smccanne 	 */
401*48932Smccanne 	error = uiomove(d->bd_hbuf, d->bd_hlen, uio);
40247584Smccanne 
40347584Smccanne 	s = splimp();
404*48932Smccanne 	d->bd_fbuf = d->bd_hbuf;
405*48932Smccanne 	d->bd_hbuf = 0;
40647584Smccanne 	splx(s);
40747584Smccanne 
408*48932Smccanne 	return (error);
40947584Smccanne }
41047584Smccanne 
41147584Smccanne 
41247584Smccanne /*
413*48932Smccanne  * If there are processes sleeping on this descriptor, wake them up.
41447584Smccanne  */
41547584Smccanne static inline void
41647584Smccanne bpf_wakeup(d)
41747584Smccanne 	register struct bpf_d *d;
41847584Smccanne {
419*48932Smccanne 	wakeup((caddr_t)d);
420*48932Smccanne 	if (d->bd_selproc) {
421*48932Smccanne 		selwakeup(d->bd_selproc, (int)d->bd_selcoll);
422*48932Smccanne 		d->bd_selcoll = 0;
423*48932Smccanne 		d->bd_selproc = 0;
42447584Smccanne 	}
42547584Smccanne }
42647584Smccanne 
42747584Smccanne int
42847584Smccanne bpfwrite(dev, uio)
42947584Smccanne 	dev_t dev;
43047584Smccanne 	struct uio *uio;
43147584Smccanne {
43247584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
43347584Smccanne 	struct ifnet *ifp;
43447584Smccanne 	struct mbuf *m;
43547584Smccanne 	int error, s;
43647584Smccanne 	static struct sockaddr dst;
43747584Smccanne 
43847584Smccanne 	if (d->bd_bif == 0)
439*48932Smccanne 		return (ENXIO);
44047584Smccanne 
44147584Smccanne 	ifp = d->bd_bif->bif_ifp;
44247584Smccanne 
44347584Smccanne 	if (uio->uio_resid == 0)
444*48932Smccanne 		return (0);
44547584Smccanne 	if (uio->uio_resid > ifp->if_mtu)
446*48932Smccanne 		return (EMSGSIZE);
44747584Smccanne 
44847584Smccanne 	error = bpf_movein(uio, (int)d->bd_bif->bif_devp.bdev_type, &m, &dst);
44947584Smccanne 	if (error)
450*48932Smccanne 		return (error);
45147584Smccanne 
45247584Smccanne 	s = splnet();
45347584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
45447584Smccanne 	splx(s);
45547584Smccanne 	/*
45647584Smccanne 	 * The driver frees the mbuf.
45747584Smccanne 	 */
458*48932Smccanne 	return (error);
45947584Smccanne }
46047584Smccanne 
46147584Smccanne /*
462*48932Smccanne  * Reset a descriptor by flushing its packet bufferand clearing the receive
463*48932Smccanne  * and drop counts.  Should be called at splimp.
46447584Smccanne  */
46547584Smccanne static void
46647584Smccanne reset_d(d)
46747584Smccanne 	struct bpf_d *d;
46847584Smccanne {
46947584Smccanne 	if (d->bd_hbuf) {
47047584Smccanne 		/* Free the hold buffer. */
47147584Smccanne 		d->bd_fbuf = d->bd_hbuf;
47247584Smccanne 		d->bd_hbuf = 0;
47347584Smccanne 	}
474*48932Smccanne 	d->bd_slen = 0;
47547584Smccanne 	d->bd_rcount = 0;
47647584Smccanne 	d->bd_dcount = 0;
47747584Smccanne }
47847584Smccanne 
47947584Smccanne /*
48047584Smccanne  *  bpfioctl - packet filter control
48147584Smccanne  *
48247584Smccanne  *  FIONREAD		Check for read packet available.
48347584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
48447584Smccanne  *  BIOCGFLEN		Get max filter len.
48547584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
48647584Smccanne  *  BIOCSETF		Set ethernet read filter.
48747584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
48847584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
48947584Smccanne  *  BIOCDEVP		Get device parameters.
49047584Smccanne  *  BIOCGETIF		Get interface name.
49147584Smccanne  *  BIOCSETIF		Set interface.
49247584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
49347584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
49447584Smccanne  *  BIOCGSTATS		Get packet stats.
49547584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
49647584Smccanne  */
49747584Smccanne /* ARGSUSED */
49847584Smccanne int
49947584Smccanne bpfioctl(dev, cmd, addr, flag)
50047584Smccanne 	dev_t dev;
50147584Smccanne 	int cmd;
50247584Smccanne 	caddr_t addr;
50347584Smccanne 	int flag;
50447584Smccanne {
50547584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
50647584Smccanne 	int s, error = 0;
50747584Smccanne 
50847584Smccanne 	switch (cmd) {
50947584Smccanne 
51047584Smccanne 	default:
51147584Smccanne 		error = EINVAL;
51247584Smccanne 		break;
51347584Smccanne 
51447584Smccanne 	/*
51547584Smccanne 	 * Check for read packet available.
51647584Smccanne 	 */
51747584Smccanne 	case FIONREAD:
51847584Smccanne 		{
51947584Smccanne 			int n;
52047584Smccanne 
52147584Smccanne 			s = splimp();
522*48932Smccanne 			n = d->bd_slen;
52347584Smccanne 			if (d->bd_hbuf)
524*48932Smccanne 				n += d->bd_hlen;
52547584Smccanne 			splx(s);
52647584Smccanne 
52747584Smccanne 			*(int *)addr = n;
52847584Smccanne 			break;
52947584Smccanne 		}
53047584Smccanne 
53147584Smccanne 	case SIOCGIFADDR:
53247584Smccanne 		{
53347584Smccanne 			struct ifnet *ifp;
53447584Smccanne 
53547584Smccanne 			if (d->bd_bif == 0)
53647584Smccanne 				error = EINVAL;
53747584Smccanne 			else {
53847584Smccanne 				ifp = d->bd_bif->bif_ifp;
53947584Smccanne 				error =  (*ifp->if_ioctl)(ifp, cmd, addr);
54047584Smccanne 			}
54147584Smccanne 			break;
54247584Smccanne 		}
54347584Smccanne 
54447584Smccanne 	/*
54547584Smccanne 	 * Get max filter len.
54647584Smccanne 	 */
54747584Smccanne 	case BIOCGFLEN:
548*48932Smccanne 		*(u_int *)addr = BPF_MAXINSNS;
54947584Smccanne 		break;
55047584Smccanne 	/*
55147584Smccanne 	 * Get buffer len [for read()].
55247584Smccanne 	 */
55347584Smccanne 	case BIOCGBLEN:
554*48932Smccanne 		*(u_int *)addr = d->bd_bufsize;
55547584Smccanne 		break;
55647584Smccanne 
55747584Smccanne 	/*
55847584Smccanne 	 * Set ethernet read filter.
55947584Smccanne 	 */
56047584Smccanne         case BIOCSETF:
56147584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
56247584Smccanne 		break;
56347584Smccanne 
56447584Smccanne 	/*
56547584Smccanne 	 * Flush read packet buffer.
56647584Smccanne 	 */
56747584Smccanne 	case BIOCFLUSH:
56847584Smccanne 		s = splimp();
56947584Smccanne 		reset_d(d);
57047584Smccanne 		splx(s);
57147584Smccanne 		break;
57247584Smccanne 
57347584Smccanne 	/*
57447584Smccanne 	 * Put interface into promiscuous mode.
57547584Smccanne 	 */
57647584Smccanne 	case BIOCPROMISC:
57747584Smccanne 		if (d->bd_bif == 0) {
57847584Smccanne 			/*
57947584Smccanne 			 * No interface attached yet.
58047584Smccanne 			 */
58147584Smccanne 			error = EINVAL;
58247584Smccanne 			break;
58347584Smccanne 		}
58447584Smccanne 		s = splimp();
58547584Smccanne 		if (d->bd_promisc == 0) {
58647584Smccanne 			d->bd_promisc = 1;
58747584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
58847584Smccanne 		}
58947584Smccanne 		splx(s);
59047584Smccanne 		break;
59147584Smccanne 
59247584Smccanne 	/*
59347584Smccanne 	 * Get device parameters.
59447584Smccanne 	 */
59547584Smccanne 	case BIOCDEVP:
59647584Smccanne 		if (d->bd_bif == 0)
59747584Smccanne 			error = EINVAL;
59847584Smccanne 		else
59947584Smccanne 			*(struct bpf_devp *)addr = d->bd_bif->bif_devp;
60047584Smccanne 		break;
60147584Smccanne 
60247584Smccanne 	/*
60347584Smccanne 	 * Set interface name.
60447584Smccanne 	 */
60547584Smccanne 	case BIOCGETIF:
60647584Smccanne 		if (d->bd_bif == 0)
60747584Smccanne 			error = EINVAL;
60847584Smccanne 		else
60947584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
61047584Smccanne 		break;
61147584Smccanne 
61247584Smccanne 	/*
61347584Smccanne 	 * Set interface.
61447584Smccanne 	 */
61547584Smccanne 	case BIOCSETIF:
61647584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
61747584Smccanne 		break;
61847584Smccanne 
61947584Smccanne 	/*
62047584Smccanne 	 * Set read timeout.
62147584Smccanne 	 */
62247584Smccanne  	case BIOCSRTIMEOUT:
62347584Smccanne 		{
62447584Smccanne 			struct timeval *tv = (struct timeval *)addr;
62547584Smccanne 			u_long msec;
62647584Smccanne 
62747584Smccanne 			/* Compute number of milliseconds. */
62847584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
62947584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
63047584Smccanne 			   clock has millisecond or greater resolution
63147584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
63247584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
63347584Smccanne 			d->bd_rtout = msec / (tick / 1000);
63447584Smccanne 			break;
63547584Smccanne 		}
63647584Smccanne 
63747584Smccanne 	/*
63847584Smccanne 	 * Get read timeout.
63947584Smccanne 	 */
64047584Smccanne  	case BIOCGRTIMEOUT:
64147584Smccanne 		{
64247584Smccanne 			struct timeval *tv = (struct timeval *)addr;
64347584Smccanne 			u_long msec = d->bd_rtout;
64447584Smccanne 
64547584Smccanne 			msec *= tick / 1000;
64647584Smccanne 			tv->tv_sec = msec / 1000;
64747584Smccanne 			tv->tv_usec = msec % 1000;
64847584Smccanne 			break;
64947584Smccanne 		}
65047584Smccanne 
65147584Smccanne 	/*
65247584Smccanne 	 * Get packet stats.
65347584Smccanne 	 */
65447584Smccanne 	case BIOCGSTATS:
65547584Smccanne 		{
65647584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
65747584Smccanne 
65847584Smccanne 			bs->bs_recv = d->bd_rcount;
65947584Smccanne 			bs->bs_drop = d->bd_dcount;
66047584Smccanne 			break;
66147584Smccanne 		}
66247584Smccanne 
66347584Smccanne 	/*
66447584Smccanne 	 * Set immediate mode.
66547584Smccanne 	 */
66647584Smccanne 	case BIOCIMMEDIATE:
66747584Smccanne 		d->bd_immediate = *(u_int *)addr;
66847584Smccanne 		break;
66947584Smccanne 	}
670*48932Smccanne 	return (error);
67147584Smccanne }
67247584Smccanne 
67347584Smccanne /*
67447584Smccanne  * Set d's packet filter program to 'fp'.  If 'd' already has a filter,
675*48932Smccanne  * free it and replace it.  Returns EINVAL for bogus requests.
67647584Smccanne  */
67747584Smccanne int
67847584Smccanne bpf_setf(d, fp)
67947584Smccanne 	struct bpf_d *d;
68047584Smccanne 	struct bpf_program *fp;
68147584Smccanne {
682*48932Smccanne 	struct bpf_insn *fcode, *old;
68347584Smccanne 	u_int flen, size;
68447584Smccanne 	int s;
68547584Smccanne 
686*48932Smccanne 	old = d->bd_filter;
68747584Smccanne 	if (fp->bf_insns == 0) {
68847584Smccanne 		if (fp->bf_len != 0)
689*48932Smccanne 			return (EINVAL);
69047584Smccanne 		d->bd_filter = bpf_default_filter;
691*48932Smccanne 		s = splimp();
69247584Smccanne 		reset_d(d);
69347584Smccanne 		splx(s);
694*48932Smccanne 		if (old != bpf_default_filter)
695*48932Smccanne 			free((caddr_t)old, M_DEVBUF);
696*48932Smccanne 		return (0);
69747584Smccanne 	}
69847584Smccanne 	flen = fp->bf_len;
699*48932Smccanne 	if (flen > BPF_MAXINSNS)
700*48932Smccanne 		return (EINVAL);
701*48932Smccanne 
70247584Smccanne 	size = flen * sizeof(*fp->bf_insns);
703*48932Smccanne 	fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
704*48932Smccanne 	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size))
705*48932Smccanne 		return (EINVAL);
70647584Smccanne 
70747584Smccanne 	if (bpf_validate(fcode, (int)flen)) {
708*48932Smccanne 		d->bd_filter = fcode;
70947584Smccanne 		s = splimp();
71047584Smccanne 		reset_d(d);
71147584Smccanne 		splx(s);
712*48932Smccanne 		if (old != bpf_default_filter)
713*48932Smccanne 			free((caddr_t)old, M_DEVBUF);
71447584Smccanne 
715*48932Smccanne 		return (0);
71647584Smccanne 	}
717*48932Smccanne 	free((caddr_t)fcode, M_DEVBUF);
718*48932Smccanne 	return (EINVAL);
71947584Smccanne }
72047584Smccanne 
72147584Smccanne /*
72247584Smccanne  * Detach 'd' from its current interface (if attached at all) and attach to
72347584Smccanne  * the interface named 'name'.  Return ioctl error code or 0.
72447584Smccanne  */
72547584Smccanne static int
72647584Smccanne bpf_setif(d, ifr)
72747584Smccanne 	struct bpf_d *d;
72847584Smccanne 	struct ifreq *ifr;
72947584Smccanne {
73047584Smccanne 	struct bpf_if *bp;
73147584Smccanne 	char *cp;
73247584Smccanne 	int unit, i, s;
73347584Smccanne 
73447584Smccanne 	/*
73547584Smccanne 	 * Separate string into name part and unit number.  Put a null
73647584Smccanne 	 * byte at the end of the name part, and compute the number.
73747584Smccanne 	 * If the a unit number is unspecified, the default is 0,
738*48932Smccanne 	 * as initialized above.  XXX This should be common code.
73947584Smccanne 	 */
74047584Smccanne 	unit = 0;
74147584Smccanne 	cp = ifr->ifr_name;
74247584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
74347584Smccanne 	while (*cp++) {
74447584Smccanne 		if (*cp >= '0' && *cp <= '9') {
74547584Smccanne 			unit = *cp - '0';
74647584Smccanne 			*cp++ = '\0';
74747584Smccanne 			while (*cp)
74847584Smccanne 				unit = 10 * unit + *cp++ - '0';
74947584Smccanne 			break;
75047584Smccanne 		}
75147584Smccanne 	}
75247584Smccanne 	/*
75347584Smccanne 	 * Look through attached interfaces for the named one.
75447584Smccanne 	 */
75547584Smccanne 	bp = bpf_iftab;
75647584Smccanne 	for (i = 0; i < NBPFILTER; ++bp, ++i) {
75747584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
75847584Smccanne 
75947584Smccanne 		if (ifp == 0 || unit != ifp->if_unit
76047584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
76147584Smccanne 			continue;
76247584Smccanne 		/*
76347584Smccanne 		 * We found the requested interface.  If we're
76447584Smccanne 		 * already attached to it, just flush the buffer.
76547584Smccanne 		 * If it's not up, return an error.
76647584Smccanne 		 */
76747584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
768*48932Smccanne 			return (ENETDOWN);
76947584Smccanne 		s = splimp();
77047584Smccanne 		if (bp != d->bd_bif) {
77147584Smccanne 			if (d->bd_bif)
77247584Smccanne 				/*
773*48932Smccanne 				 * Detach if attached to something else.
77447584Smccanne 				 */
77547584Smccanne 				bpf_detachd(d);
77647584Smccanne 
77747584Smccanne 			bpf_attachd(d, bp);
77847584Smccanne 		}
77947584Smccanne 		reset_d(d);
78047584Smccanne 		splx(s);
781*48932Smccanne 		return (0);
78247584Smccanne 	}
78347584Smccanne 	/* Not found. */
784*48932Smccanne 	return (ENXIO);
78547584Smccanne }
78647584Smccanne 
78747584Smccanne /*
78847584Smccanne  * Lookup the name of the 'ifp' interface and return it in 'ifr->ifr_name'.
78947584Smccanne  * We augment the ifp's base name with its unit number.
79047584Smccanne  */
79147584Smccanne static void
79247584Smccanne bpf_ifname(ifp, ifr)
79347584Smccanne 	struct ifnet *ifp;
79447584Smccanne 	struct ifreq *ifr;
79547584Smccanne {
79647584Smccanne 	char *s = ifp->if_name;
79747584Smccanne 	char *d = ifr->ifr_name;
79847584Smccanne 
79947584Smccanne 	while (*d++ = *s++)
80047584Smccanne 		;
801*48932Smccanne 	/* XXX Assume that unit number is less than 10. */
80247584Smccanne 	*d++ = ifp->if_unit + '0';
80347584Smccanne 	*d = '\0';
80447584Smccanne }
80547584Smccanne 
80647584Smccanne /*
80747584Smccanne  * Support for select() system call
80847584Smccanne  * Inspired by the code in tty.c for the same purpose.
80947584Smccanne  *
81047584Smccanne  * bpfselect - returns true iff the specific operation
81147584Smccanne  *	will not block indefinitely.  Otherwise, return
81247584Smccanne  *	false but make a note that a selwakeup() must be done.
81347584Smccanne  */
81447584Smccanne int
815*48932Smccanne bpfselect(dev, rw, p)
81647584Smccanne 	register dev_t dev;
81747584Smccanne 	int rw;
818*48932Smccanne 	struct proc *p;
81947584Smccanne {
82047584Smccanne 	register struct bpf_d *d;
82147584Smccanne 	register int s;
82247584Smccanne 
82347584Smccanne 	if (rw != FREAD)
824*48932Smccanne 		return (0);
82547584Smccanne 	/*
82647584Smccanne 	 * An imitation of the FIONREAD ioctl code.
82747584Smccanne 	 */
82847584Smccanne 	d = &bpf_dtab[minor(dev)];
82947584Smccanne 
83047584Smccanne 	s = splimp();
831*48932Smccanne 	if (d->bd_slen != 0 || d->bd_hbuf && d->bd_hlen != 0) {
83247584Smccanne 		/*
83347584Smccanne 		 * There is data waiting.
83447584Smccanne 		 */
83547584Smccanne 		splx(s);
836*48932Smccanne 		return (1);
83747584Smccanne 	}
83847584Smccanne 	/*
83947584Smccanne 	 * No data ready.  If there's already a select() waiting on this
84047584Smccanne 	 * minor device then this is a collision.  This shouldn't happen
84147584Smccanne 	 * because minors really should not be shared, but if a process
84247584Smccanne 	 * forks while one of these is open, it is possible that both
84347584Smccanne 	 * processes could select on the same descriptor.
84447584Smccanne 	 */
845*48932Smccanne 	if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
846*48932Smccanne 		d->bd_selcoll = 1;
84747584Smccanne 	else
848*48932Smccanne 		d->bd_selproc = p;
849*48932Smccanne 
85047584Smccanne 	splx(s);
851*48932Smccanne 	return (0);
85247584Smccanne }
85347584Smccanne 
85447584Smccanne /*
85547584Smccanne  * bpf_tap - incoming linkage from device drivers
85647584Smccanne  */
85747584Smccanne void
858*48932Smccanne bpf_tap(arg, pkt, pktlen)
85947584Smccanne 	caddr_t arg;
860*48932Smccanne 	register u_char *pkt;
861*48932Smccanne 	register u_int pktlen;
86247584Smccanne {
86347584Smccanne 	struct bpf_if *bp;
86447584Smccanne 	register struct bpf_d *d;
86547584Smccanne 	register u_int slen;
86647584Smccanne 	extern bcopy();
86747584Smccanne 	/*
86847584Smccanne 	 * Note that the ipl does not have to be raised at this point.
86947584Smccanne 	 * The only problem that could arise here is that if two different
87047584Smccanne 	 * interfaces shared any data.  This is not the case.
87147584Smccanne 	 */
87247584Smccanne 	bp = (struct bpf_if *)arg;
87347584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
87447584Smccanne 		++d->bd_rcount;
875*48932Smccanne 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
87647584Smccanne 		if (slen != 0)
877*48932Smccanne 			catchpacket(d, pkt, pktlen, slen, (void (*)())bcopy);
87847584Smccanne 	}
87947584Smccanne }
88047584Smccanne 
88147584Smccanne /*
88247584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
88347584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
88447584Smccanne  */
88547584Smccanne static void
88647584Smccanne bpf_m_copydata(src, dst, len)
88747584Smccanne 	u_char *src;
88847584Smccanne 	u_char *dst;
88947584Smccanne 	register int len;
89047584Smccanne {
89147584Smccanne 	register struct mbuf *m = (struct mbuf *)src;
89247584Smccanne 	register unsigned count;
89347584Smccanne 
89447584Smccanne 	while (len > 0) {
89547584Smccanne 		if (m == 0)
89647584Smccanne 			panic("bpf_m_copydata");
89747584Smccanne 		count = MIN(m->m_len, len);
89847584Smccanne 		(void)bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
89947584Smccanne 		len -= count;
90047584Smccanne 		dst += count;
90147584Smccanne 		m = m->m_next;
90247584Smccanne 	}
90347584Smccanne }
90447584Smccanne 
90547584Smccanne /*
906*48932Smccanne  * Length of ethernet and TCP/IP header with no IP options.
90747584Smccanne  */
90847584Smccanne #define BPF_MIN_SNAPLEN 50
90947584Smccanne 
91047584Smccanne /*
91147584Smccanne  * bpf_mtap - incoming linkage from device drivers, when packet
91247584Smccanne  *   is in an mbuf chain
91347584Smccanne  */
91447584Smccanne void
91547584Smccanne bpf_mtap(arg, m0)
91647584Smccanne 	caddr_t arg;
91747584Smccanne 	struct mbuf *m0;
91847584Smccanne {
91947584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
92047584Smccanne 	struct bpf_d *d;
92147584Smccanne 	u_char *cp;
922*48932Smccanne 	u_int slen, pktlen;
92347584Smccanne 	int nbytes;
92447584Smccanne 	struct mbuf *m;
925*48932Smccanne 	static u_char buf[BPF_MIN_SNAPLEN];
92647584Smccanne 
92747584Smccanne 	if (m0->m_len >= BPF_MIN_SNAPLEN) {
92847584Smccanne 		slen = m0->m_len;
92947584Smccanne 		cp = mtod(m0, u_char *);
93047584Smccanne 	}
93147584Smccanne 	else {
93247584Smccanne 		nbytes = BPF_MIN_SNAPLEN;
93347584Smccanne 		cp = buf;
93447584Smccanne 		m = m0;
93547584Smccanne 		while (m && nbytes > 0) {
93647584Smccanne 			slen = MIN(m->m_len, nbytes);
93747584Smccanne 			bcopy(mtod(m, char *), (char *)cp, slen);
93847584Smccanne 			cp += slen;
93947584Smccanne 			nbytes -= slen;
94047584Smccanne 			m = m->m_next;
94147584Smccanne 		}
94247584Smccanne 		if (nbytes > 0)
94347584Smccanne 			/* Packet too small? */
94447584Smccanne 			return;
94547584Smccanne 
94647584Smccanne 		slen = BPF_MIN_SNAPLEN;
94747584Smccanne 		cp = buf;
94847584Smccanne 	}
949*48932Smccanne 	pktlen = 0;
95047584Smccanne 	m = m0;
95147584Smccanne 	while (m) {
952*48932Smccanne 		pktlen += m->m_len;
95347584Smccanne 		m = m->m_next;
95447584Smccanne 	}
95547584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
95647584Smccanne 		++d->bd_rcount;
957*48932Smccanne 		slen = bpf_filter(d->bd_filter, cp, pktlen, slen);
95847584Smccanne 		if (slen != 0)
959*48932Smccanne 			catchpacket(d, (u_char *)m0, pktlen, slen,
96047584Smccanne 				    bpf_m_copydata);
96147584Smccanne 	}
96247584Smccanne }
96347584Smccanne 
96447584Smccanne /*
965*48932Smccanne  * Move the packet data from interface memory ('pkt') into the
96647584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
96747584Smccanne  * otherwise 0.  'copy' is the routine called to do the actual data
96847584Smccanne  * transfer.  'bcopy' is passed in to copy contiguous chunks, while
96947584Smccanne  * 'bpf_m_copydata' is passed in to copy mbuf chains.  In the latter
970*48932Smccanne  * case, 'pkt' is really an mbuf.
97147584Smccanne  */
97247584Smccanne static void
973*48932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn)
974*48932Smccanne 	register struct bpf_d *d;
975*48932Smccanne 	register u_char *pkt;
976*48932Smccanne 	register u_int pktlen, snaplen;
977*48932Smccanne 	register void (*cpfn)();
97847584Smccanne {
979*48932Smccanne 	register struct bpf_hdr *hp;
980*48932Smccanne 	register int totlen, curlen;
981*48932Smccanne 	register int hdrlen = d->bd_bif->bif_hdrlen;
98247584Smccanne 	/*
98347584Smccanne 	 * Figure out how many bytes to move.  If the packet is
98447584Smccanne 	 * greater or equal to the snapshot length, transfer that
98547584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
986*48932Smccanne 	 * we hit the buffer size limit).
98747584Smccanne 	 */
988*48932Smccanne 	if (snaplen <= pktlen)
98947584Smccanne 		totlen = snaplen + hdrlen;
99047584Smccanne 	else {
991*48932Smccanne 		totlen = pktlen + hdrlen;
992*48932Smccanne 		if (totlen > d->bd_bufsize)
993*48932Smccanne 			totlen = d->bd_bufsize;
99447584Smccanne 	}
99547584Smccanne 
99647584Smccanne 	/*
99747584Smccanne 	 * Round up the end of the previous packet to the next longword.
99847584Smccanne 	 */
999*48932Smccanne 	curlen = BPF_WORDALIGN(d->bd_slen);
1000*48932Smccanne 	if (curlen + totlen > d->bd_bufsize) {
100147584Smccanne 		/*
100247584Smccanne 		 * This packet will overflow the storage buffer.
1003*48932Smccanne 		 * Rotate the buffers if we can, then wakeup any
1004*48932Smccanne 		 * pending reads.
100547584Smccanne 		 */
100647584Smccanne 		if (d->bd_fbuf == 0) {
100747584Smccanne 			/*
1008*48932Smccanne 			 * We haven't completed the previous read yet,
1009*48932Smccanne 			 * so drop the packet.
101047584Smccanne 			 */
101147584Smccanne 			++d->bd_dcount;
101247584Smccanne 			return;
101347584Smccanne 		}
1014*48932Smccanne 		ROTATE_BUFFERS(d);
101547584Smccanne 		bpf_wakeup(d);
1016*48932Smccanne 		curlen = 0;
101747584Smccanne 	}
1018*48932Smccanne 	else if (d->bd_immediate)
101947584Smccanne 		/*
102047584Smccanne 		 * Immediate mode is set.  A packet arrived so any
102147584Smccanne 		 * reads should be woken up.
102247584Smccanne 		 */
102347584Smccanne 		bpf_wakeup(d);
1024*48932Smccanne 
102547584Smccanne 	/*
102647584Smccanne 	 * Append the bpf header.
102747584Smccanne 	 */
1028*48932Smccanne 	hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
102947584Smccanne #ifdef sun
103047584Smccanne 	uniqtime(&hp->bh_tstamp);
103147584Smccanne #else
103247584Smccanne #ifdef hp300
103347584Smccanne 	microtime(&hp->bh_tstamp);
103447584Smccanne #else
103547584Smccanne 	hp->bh_tstamp = time;
103647584Smccanne #endif
103747584Smccanne #endif
1038*48932Smccanne 	hp->bh_datalen = pktlen;
103947584Smccanne 	hp->bh_hdrlen = hdrlen;
104047584Smccanne 	/*
1041*48932Smccanne 	 * Copy the packet data into the store buffer and update its length.
104247584Smccanne 	 */
1043*48932Smccanne 	(*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
1044*48932Smccanne 	d->bd_slen = curlen + totlen;
104547584Smccanne }
104647584Smccanne 
104747584Smccanne /*
104847584Smccanne  * Initialize all nonzero fields of a descriptor.
104947584Smccanne  */
105047584Smccanne static int
105147584Smccanne bpf_initd(d)
105247584Smccanne 	register struct bpf_d *d;
105347584Smccanne {
1054*48932Smccanne 	d->bd_bufsize = bpf_bufsize;
1055*48932Smccanne 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
1056*48932Smccanne 	if (d->bd_fbuf == 0)
1057*48932Smccanne 		return (ENOBUFS);
105847584Smccanne 
1059*48932Smccanne 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
1060*48932Smccanne 	if (d->bd_sbuf == 0) {
1061*48932Smccanne 		free(d->bd_fbuf, M_DEVBUF);
1062*48932Smccanne 		return (ENOBUFS);
106347584Smccanne 	}
1064*48932Smccanne 	d->bd_slen = 0;
1065*48932Smccanne 	d->bd_hlen = 0;
1066*48932Smccanne 	return (0);
106747584Smccanne }
106847584Smccanne 
106947584Smccanne /*
107047584Smccanne  * Register 'ifp' with bpf.  'devp' is the link-level device descriptor
107147584Smccanne  * and 'driverp' is a pointer to the 'struct bpf_if *' in the driver's softc.
107247584Smccanne  */
107347584Smccanne void
107447584Smccanne bpfattach(driverp, ifp, devp)
107547584Smccanne 	caddr_t *driverp;
107647584Smccanne 	struct ifnet *ifp;
107747584Smccanne 	struct bpf_devp *devp;
107847584Smccanne {
107947584Smccanne 	struct bpf_if *bp;
108047584Smccanne 	int i;
108147584Smccanne 
108247584Smccanne 	if (bpf_units >= NBPFILTER) {
108347584Smccanne 		printf("bpf: too many interfaces: %s%d not attached\n",
108447584Smccanne 		       ifp->if_name, ifp->if_unit);
108547584Smccanne 		return;
108647584Smccanne 	}
108747584Smccanne 	bp = &bpf_iftab[bpf_units++];
108847584Smccanne 
108947584Smccanne 	bp->bif_dlist = 0;
109047584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
109147584Smccanne 	bp->bif_ifp = ifp;
109247584Smccanne 	bp->bif_devp = *devp;
109347584Smccanne 
1094*48932Smccanne 	*bp->bif_driverp = 0;
1095*48932Smccanne 
109647584Smccanne 	/*
109747584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
109847584Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
109947584Smccanne 	 * that the network layer header begins on a longword boundary (for
110047584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
110147584Smccanne 	 */
110247584Smccanne 	i = devp->bdev_hdrlen;
110347584Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(i + SIZEOF_BPF_HDR) - i;
110447584Smccanne 
110547584Smccanne 	/*
110647584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
110747584Smccanne 	 */
110847584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
110947584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
111047584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
111147584Smccanne 
111247584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
111347584Smccanne }
111447584Smccanne 
1115*48932Smccanne /* XXX This routine goes in net/if.c. */
1116*48932Smccanne /*
1117*48932Smccanne  * Set/clear promiscuous mode on interface ifp based on the truth value`
1118*48932Smccanne  * of pswitch.  The calls are reference counted so that only the first
1119*48932Smccanne  * on request actually has an effect, as does the final off request.
1120*48932Smccanne  * Results are undefined if the off and on requests are not matched.
1121*48932Smccanne  */
1122*48932Smccanne int
1123*48932Smccanne ifpromisc(ifp, pswitch)
1124*48932Smccanne 	struct ifnet *ifp;
1125*48932Smccanne 	int pswitch;
1126*48932Smccanne {
1127*48932Smccanne 	/*
1128*48932Smccanne 	 * If the device is not configured up, we cannot put it in
1129*48932Smccanne 	 * promiscuous mode.
1130*48932Smccanne 	 */
1131*48932Smccanne 	if ((ifp->if_flags & IFF_UP) == 0)
1132*48932Smccanne 		return (ENETDOWN);
1133*48932Smccanne 
1134*48932Smccanne 	if (pswitch) {
1135*48932Smccanne 		if (ifp->if_pcount++ != 0)
1136*48932Smccanne 			return (0);
1137*48932Smccanne 		ifp->if_flags |= IFF_PROMISC;
1138*48932Smccanne 	} else {
1139*48932Smccanne 		if (--ifp->if_pcount > 0)
1140*48932Smccanne 			return (0);
1141*48932Smccanne 		ifp->if_flags &= ~IFF_PROMISC;
1142*48932Smccanne 	}
1143*48932Smccanne 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)0));
1144*48932Smccanne }
1145*48932Smccanne 
114647584Smccanne #endif (NBPFILTER > 0)
1147