xref: /csrg-svn/sys/net/bpf.c (revision 47584)
1*47584Smccanne /*
2*47584Smccanne  * Copyright (c) 1990 The Regents of the University of California.
3*47584Smccanne  * All rights reserved.
4*47584Smccanne  *
5*47584Smccanne  * Redistribution and use in source and binary forms, with or without
6*47584Smccanne  * modification, are permitted provided that: (1) source code distributions
7*47584Smccanne  * retain the above copyright notice and this paragraph in its entirety, (2)
8*47584Smccanne  * distributions including binary code include the above copyright notice and
9*47584Smccanne  * this paragraph in its entirety in the documentation or other materials
10*47584Smccanne  * provided with the distribution, and (3) all advertising materials mentioning
11*47584Smccanne  * features or use of this software display the following acknowledgement:
12*47584Smccanne  * ``This product includes software developed by the University of California,
13*47584Smccanne  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*47584Smccanne  * the University nor the names of its contributors may be used to endorse
15*47584Smccanne  * or promote products derived from this software without specific prior
16*47584Smccanne  * written permission.
17*47584Smccanne  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*47584Smccanne  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*47584Smccanne  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*47584Smccanne  *
21*47584Smccanne  * This code is derived from the Stanford/CMU enet packet filter,
22*47584Smccanne  * (net/enet.c) distributed in 4.3BSD Unix.
23*47584Smccanne  */
24*47584Smccanne #ifndef lint
25*47584Smccanne static char rcsid[] =
26*47584Smccanne     "$Header: bpf.c,v 1.23 91/01/30 18:22:13 mccanne Exp $";
27*47584Smccanne #endif
28*47584Smccanne 
29*47584Smccanne #include "bpfilter.h"
30*47584Smccanne 
31*47584Smccanne #if (NBPFILTER > 0)
32*47584Smccanne 
33*47584Smccanne #ifndef __GNUC__
34*47584Smccanne #define inline
35*47584Smccanne #endif
36*47584Smccanne 
37*47584Smccanne #include <sys/param.h>
38*47584Smccanne #include <sys/systm.h>
39*47584Smccanne #include <sys/mbuf.h>
40*47584Smccanne #include <sys/buf.h>
41*47584Smccanne #include <sys/dir.h>
42*47584Smccanne #include <sys/user.h>
43*47584Smccanne #include <sys/ioctl.h>
44*47584Smccanne #include <sys/map.h>
45*47584Smccanne #include <sys/proc.h>
46*47584Smccanne 
47*47584Smccanne #include <sys/file.h>
48*47584Smccanne #ifdef sparc
49*47584Smccanne #include <sys/stream.h>
50*47584Smccanne #endif
51*47584Smccanne #include <sys/tty.h>
52*47584Smccanne #include <sys/uio.h>
53*47584Smccanne 
54*47584Smccanne #include <sys/protosw.h>
55*47584Smccanne #include <sys/socket.h>
56*47584Smccanne #include <net/if.h>
57*47584Smccanne 
58*47584Smccanne #include <net/bpf.h>
59*47584Smccanne #include <net/bpfdesc.h>
60*47584Smccanne 
61*47584Smccanne #include <sys/errno.h>
62*47584Smccanne 
63*47584Smccanne #include <netinet/in.h>
64*47584Smccanne #include <netinet/if_ether.h>
65*47584Smccanne #include <sys/kernel.h>
66*47584Smccanne 
67*47584Smccanne #define PRINET  26			/* interruptible */
68*47584Smccanne 
69*47584Smccanne /*
70*47584Smccanne  *  'bpf_iftab' is the driver state table per logical unit number
71*47584Smccanne  *  'bpf_dtab' holds the descriptors, indexed by minor device #
72*47584Smccanne  *  'bpf_units' is the number of attached units
73*47584Smccanne  *
74*47584Smccanne  * We really don't need NBPFILTER bpf_if entries, but this eliminates
75*47584Smccanne  * the need to account for all possible drivers here.
76*47584Smccanne  * This problem will go away when these structures are allocated dynamically.
77*47584Smccanne  */
78*47584Smccanne static struct bpf_if 	bpf_iftab[NBPFILTER];
79*47584Smccanne static struct bpf_d	bpf_dtab[NBPFILTER];
80*47584Smccanne static u_int		bpf_units = 0;
81*47584Smccanne 
82*47584Smccanne static int	bpf_timeout();
83*47584Smccanne static void	bpf_ifname();
84*47584Smccanne static void	catchpacket();
85*47584Smccanne static int	bpf_setif();
86*47584Smccanne static int	bpf_initd();
87*47584Smccanne 
88*47584Smccanne /*
89*47584Smccanne  * The default filter accepts the maximum number of bytes from each packet.
90*47584Smccanne  */
91*47584Smccanne struct bpf_insn bpf_default_filter[] = {
92*47584Smccanne 	BPF_STMT(RetOp, MCLBYTES),
93*47584Smccanne };
94*47584Smccanne 
95*47584Smccanne /*
96*47584Smccanne  * This routine was inspired by/stolen from ../sys/uipc_socket.c
97*47584Smccanne  * Move data from 'm' to user's read buffer.
98*47584Smccanne  * We assume 'm' is not chained.
99*47584Smccanne  * Returns error code (or 0 if success).
100*47584Smccanne  */
101*47584Smccanne static inline int
102*47584Smccanne bpf_moveout(m, uio)
103*47584Smccanne 	register struct mbuf *m;
104*47584Smccanne 	register struct uio *uio;
105*47584Smccanne {
106*47584Smccanne 	register int len;
107*47584Smccanne 
108*47584Smccanne 	len = m->m_len;
109*47584Smccanne 	if (uio->uio_resid < len)
110*47584Smccanne 		len = uio->uio_resid;
111*47584Smccanne 
112*47584Smccanne 	if (len > 0)
113*47584Smccanne 		return uiomove(mtod(m, caddr_t), len, UIO_READ, uio);
114*47584Smccanne 
115*47584Smccanne 	return 0;
116*47584Smccanne }
117*47584Smccanne 
118*47584Smccanne static int
119*47584Smccanne bpf_movein(uio, linktype, mp, sockp)
120*47584Smccanne 	register struct uio *uio;
121*47584Smccanne 	int linktype;
122*47584Smccanne 	register struct mbuf **mp;
123*47584Smccanne 	register struct sockaddr *sockp;
124*47584Smccanne {
125*47584Smccanne 	struct mbuf *m;
126*47584Smccanne 	int error;
127*47584Smccanne 	int len;
128*47584Smccanne 	int hlen;
129*47584Smccanne 
130*47584Smccanne 	/*
131*47584Smccanne 	 * Build a sockaddr based on the data link layer type.
132*47584Smccanne 	 * We do this at this level because the ethernet header
133*47584Smccanne 	 * is copied directly into the data field of the sockaddr.
134*47584Smccanne 	 * In the case of SLIP, there is no header and the packet
135*47584Smccanne 	 * is forwarded as is.
136*47584Smccanne 	 * Also, we are careful to leave room at the front of the mbuf
137*47584Smccanne 	 * for the link level header.
138*47584Smccanne 	 */
139*47584Smccanne 	switch (linktype) {
140*47584Smccanne 	case DLT_SLIP:
141*47584Smccanne 		sockp->sa_family = AF_INET;
142*47584Smccanne 		hlen = 0;
143*47584Smccanne 		break;
144*47584Smccanne 
145*47584Smccanne 	case DLT_EN10MB:
146*47584Smccanne 		sockp->sa_family = AF_UNSPEC;
147*47584Smccanne 		/* XXX Would MAXLINKHDR be better? */
148*47584Smccanne 		hlen = sizeof(struct ether_header);
149*47584Smccanne 		break;
150*47584Smccanne 
151*47584Smccanne        case DLT_FDDI:
152*47584Smccanne 		sockp->sa_family = AF_UNSPEC;
153*47584Smccanne 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
154*47584Smccanne 		hlen = 24;
155*47584Smccanne 		break;
156*47584Smccanne 
157*47584Smccanne 	default:
158*47584Smccanne 		return EIO;
159*47584Smccanne 	}
160*47584Smccanne 
161*47584Smccanne 	len = uio->uio_resid;
162*47584Smccanne 	if ((unsigned)len > MCLBYTES)
163*47584Smccanne 		return EIO;
164*47584Smccanne 
165*47584Smccanne 	MGET(m, M_WAIT, MT_DATA);
166*47584Smccanne 	if (m == 0)
167*47584Smccanne 		return ENOBUFS;
168*47584Smccanne 	if (len > MLEN) {
169*47584Smccanne 		MCLGET(m);
170*47584Smccanne 		if (m->m_len != MCLBYTES) {
171*47584Smccanne 			error = ENOBUFS;
172*47584Smccanne 			goto bad;
173*47584Smccanne 		}
174*47584Smccanne 	}
175*47584Smccanne 	m->m_len = len;
176*47584Smccanne 	*mp = m;
177*47584Smccanne 	/*
178*47584Smccanne 	 * Make room for link header.
179*47584Smccanne 	 */
180*47584Smccanne 	if (hlen) {
181*47584Smccanne 		m->m_len -= hlen;
182*47584Smccanne 		m->m_off += hlen;
183*47584Smccanne 
184*47584Smccanne 		error = uiomove((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
185*47584Smccanne 		if (error)
186*47584Smccanne 			goto bad;
187*47584Smccanne 	}
188*47584Smccanne 	error = uiomove(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
189*47584Smccanne 	if (!error)
190*47584Smccanne 		return 0;
191*47584Smccanne  bad:
192*47584Smccanne 	m_freem(m);
193*47584Smccanne 	return error;
194*47584Smccanne }
195*47584Smccanne 
196*47584Smccanne /*
197*47584Smccanne  * Attach 'd' to the bpf interface 'bp', i.e. make 'd' listen on 'bp'.
198*47584Smccanne  * Must be called at splimp.
199*47584Smccanne  */
200*47584Smccanne static void
201*47584Smccanne bpf_attachd(d, bp)
202*47584Smccanne 	struct bpf_d *d;
203*47584Smccanne 	struct bpf_if *bp;
204*47584Smccanne {
205*47584Smccanne 	/* Point 'd' at 'bp'. */
206*47584Smccanne 	d->bd_bif = bp;
207*47584Smccanne 
208*47584Smccanne 	/* Add 'd' to 'bp's list of listeners. */
209*47584Smccanne 	d->bd_next = bp->bif_dlist;
210*47584Smccanne 	bp->bif_dlist = d;
211*47584Smccanne 
212*47584Smccanne 	/*
213*47584Smccanne 	 * Let the driver know we're here (if it doesn't already).
214*47584Smccanne 	 */
215*47584Smccanne 	*bp->bif_driverp = bp;
216*47584Smccanne }
217*47584Smccanne 
218*47584Smccanne static void
219*47584Smccanne bpf_detachd(d)
220*47584Smccanne 	struct bpf_d *d;
221*47584Smccanne {
222*47584Smccanne 	struct bpf_d **p;
223*47584Smccanne 	struct bpf_if *bp;
224*47584Smccanne 
225*47584Smccanne 	bp = d->bd_bif;
226*47584Smccanne 	/*
227*47584Smccanne 	 * Check if this descriptor had requested promiscuous mode.
228*47584Smccanne 	 * If so, turn it off.
229*47584Smccanne 	 */
230*47584Smccanne 	if (d->bd_promisc) {
231*47584Smccanne 		d->bd_promisc = 0;
232*47584Smccanne 		if (ifpromisc(bp->bif_ifp, 0))
233*47584Smccanne 			/*
234*47584Smccanne 			 * Something is really wrong if we were able to put
235*47584Smccanne 			 * the driver into promiscuous mode, but can't
236*47584Smccanne 			 * take it out.
237*47584Smccanne 			 */
238*47584Smccanne 			panic("bpf_detachd: exit promisc unsucessful");
239*47584Smccanne 	}
240*47584Smccanne 	/* Remove 'd' from the interface's descriptor list. */
241*47584Smccanne 	p = &bp->bif_dlist;
242*47584Smccanne 	while (*p != d) {
243*47584Smccanne 		p = &(*p)->bd_next;
244*47584Smccanne 		if (*p == 0)
245*47584Smccanne 			panic("bpf_detachd: descriptor not in list");
246*47584Smccanne 	}
247*47584Smccanne 	*p = (*p)->bd_next;
248*47584Smccanne 	if (bp->bif_dlist == 0)
249*47584Smccanne 		/*
250*47584Smccanne 		 * Let the driver know that there are no more listeners.
251*47584Smccanne 		 */
252*47584Smccanne 		*d->bd_bif->bif_driverp = 0;
253*47584Smccanne 	d->bd_bif = 0;
254*47584Smccanne }
255*47584Smccanne 
256*47584Smccanne 
257*47584Smccanne /*
258*47584Smccanne  * Mark a descriptor free by making it point to itself.
259*47584Smccanne  * This is probably cheaper than marking with a constant since
260*47584Smccanne  * the address should be in a register anyway.
261*47584Smccanne  */
262*47584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next)
263*47584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d))
264*47584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0)
265*47584Smccanne 
266*47584Smccanne /*
267*47584Smccanne  *  bpfopen - open ethernet device
268*47584Smccanne  *
269*47584Smccanne  *  Errors:	ENXIO	- illegal minor device number
270*47584Smccanne  *		EBUSY	- too many files open
271*47584Smccanne  */
272*47584Smccanne /* ARGSUSED */
273*47584Smccanne int
274*47584Smccanne bpfopen(dev, flag)
275*47584Smccanne 	dev_t dev;
276*47584Smccanne 	int flag;
277*47584Smccanne {
278*47584Smccanne 	int error, s;
279*47584Smccanne 	register struct bpf_d *d;
280*47584Smccanne 
281*47584Smccanne 	if (minor(dev) >= NBPFILTER)
282*47584Smccanne 		return ENXIO;
283*47584Smccanne 
284*47584Smccanne 	/*
285*47584Smccanne 	 * Each minor can be opened by only one process.  If the requested
286*47584Smccanne 	 * minor is in use, return EBUSY.
287*47584Smccanne 	 */
288*47584Smccanne 	s = splimp();
289*47584Smccanne 	d = &bpf_dtab[minor(dev)];
290*47584Smccanne 	if (!D_ISFREE(d)) {
291*47584Smccanne 		splx(s);
292*47584Smccanne 		return EBUSY;
293*47584Smccanne 	} else
294*47584Smccanne 		/* Mark "free" and do most initialization. */
295*47584Smccanne 		bzero((char *)d, sizeof(*d));
296*47584Smccanne 	d->bd_filter = bpf_default_filter;
297*47584Smccanne 	splx(s);
298*47584Smccanne 
299*47584Smccanne 	error = bpf_initd(d);
300*47584Smccanne 	if (error) {
301*47584Smccanne 		D_MARKFREE(d);
302*47584Smccanne 		return error;
303*47584Smccanne 	}
304*47584Smccanne 	return 0;
305*47584Smccanne }
306*47584Smccanne 
307*47584Smccanne /*
308*47584Smccanne  * Close the descriptor by detaching it from its interface,
309*47584Smccanne  * deallocating its buffers, and marking it free.
310*47584Smccanne  */
311*47584Smccanne /* ARGSUSED */
312*47584Smccanne bpfclose(dev, flag)
313*47584Smccanne 	dev_t dev;
314*47584Smccanne 	int flag;
315*47584Smccanne {
316*47584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
317*47584Smccanne 	int s;
318*47584Smccanne 
319*47584Smccanne 	s = splimp();
320*47584Smccanne 	if (d->bd_bif)
321*47584Smccanne 		bpf_detachd(d);
322*47584Smccanne 	splx(s);
323*47584Smccanne 
324*47584Smccanne 	/* Let the buffers go. */
325*47584Smccanne 	m_freem(d->bd_hbuf);
326*47584Smccanne 	m_freem(d->bd_sbuf);
327*47584Smccanne 	m_freem(d->bd_fbuf);
328*47584Smccanne 	m_freem(d->bd_filterm);
329*47584Smccanne 
330*47584Smccanne 	D_MARKFREE(d);
331*47584Smccanne }
332*47584Smccanne 
333*47584Smccanne #define RS_IDLE 0
334*47584Smccanne #define RS_WAIT 1
335*47584Smccanne #define RS_TIMEDOUT 2
336*47584Smccanne 
337*47584Smccanne /*
338*47584Smccanne  *  bpfread - read next chunk of packets from buffers
339*47584Smccanne  */
340*47584Smccanne int
341*47584Smccanne bpfread(dev, uio)
342*47584Smccanne 	dev_t dev;
343*47584Smccanne 	register struct uio *uio;
344*47584Smccanne {
345*47584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
346*47584Smccanne 	struct mbuf *m;
347*47584Smccanne 	int error;
348*47584Smccanne 	int s;
349*47584Smccanne 
350*47584Smccanne 	/*
351*47584Smccanne 	 * Restrict application to use a buffer the same size as
352*47584Smccanne 	 * as kernel buffers.
353*47584Smccanne 	 */
354*47584Smccanne 	if (uio->uio_resid != MCLBYTES)
355*47584Smccanne 		return EIO;
356*47584Smccanne 
357*47584Smccanne 	s = splimp();
358*47584Smccanne 	/*
359*47584Smccanne 	 * If the hold buffer is empty, then set a timer and sleep
360*47584Smccanne 	 * until either the timeout has occurred or enough packets have
361*47584Smccanne 	 * arrived to fill the store buffer.
362*47584Smccanne 	 */
363*47584Smccanne 	while (d->bd_hbuf == 0) {
364*47584Smccanne 		if (d->bd_immediate && d->bd_sbuf->m_len) {
365*47584Smccanne 			/*
366*47584Smccanne 			 * A packet(s) either arrived since the previous
367*47584Smccanne 			 * read or arrived while we were asleep.
368*47584Smccanne 			 * Rotate the buffers and return what's here.
369*47584Smccanne 			 */
370*47584Smccanne 			d->bd_hbuf = d->bd_sbuf;
371*47584Smccanne 			d->bd_sbuf = d->bd_fbuf;
372*47584Smccanne 			d->bd_sbuf->m_len = 0;
373*47584Smccanne 			d->bd_fbuf = 0;
374*47584Smccanne 			break;
375*47584Smccanne 		}
376*47584Smccanne 		if (d->bd_rtout) {
377*47584Smccanne 			/*
378*47584Smccanne 			 * If there was a previous timeout pending for this
379*47584Smccanne 			 * file, cancel it before setting another.  This is
380*47584Smccanne 			 * necessary since a cancel after the sleep might
381*47584Smccanne 			 * never happen if the read is interrupted by a signal.
382*47584Smccanne 			 */
383*47584Smccanne 			if (d->bd_state == RS_WAIT)
384*47584Smccanne 				untimeout(bpf_timeout, (caddr_t)d);
385*47584Smccanne 			timeout(bpf_timeout, (caddr_t)d, (int)d->bd_rtout);
386*47584Smccanne 			d->bd_state = RS_WAIT;
387*47584Smccanne 		}
388*47584Smccanne 		else
389*47584Smccanne 			d->bd_state = RS_IDLE;
390*47584Smccanne 
391*47584Smccanne 		sleep((caddr_t)d, PRINET);
392*47584Smccanne 
393*47584Smccanne 		if (d->bd_state == RS_WAIT) {
394*47584Smccanne 			untimeout(bpf_timeout, (caddr_t)d);
395*47584Smccanne 			d->bd_state = RS_IDLE;
396*47584Smccanne 		}
397*47584Smccanne 		else if (d->bd_state == RS_TIMEDOUT) {
398*47584Smccanne 			/*
399*47584Smccanne 			 * On a timeout, return what's in the buffer,
400*47584Smccanne 			 * which may be nothing.  We do this by moving
401*47584Smccanne 			 * the store buffer into the hold slot.
402*47584Smccanne 			 */
403*47584Smccanne 			if (d->bd_hbuf)
404*47584Smccanne 				/*
405*47584Smccanne 				 * We filled up the buffer in between
406*47584Smccanne 				 * getting the timeout and arriving
407*47584Smccanne 				 * here, so we don't need to rotate.
408*47584Smccanne 				 */
409*47584Smccanne 				break;
410*47584Smccanne 
411*47584Smccanne 			if (d->bd_sbuf->m_len == 0) {
412*47584Smccanne 				splx(s);
413*47584Smccanne 				return(0);
414*47584Smccanne 			}
415*47584Smccanne 			d->bd_hbuf = d->bd_sbuf;
416*47584Smccanne 			d->bd_sbuf = d->bd_fbuf;
417*47584Smccanne 			d->bd_sbuf->m_len = 0;
418*47584Smccanne 			d->bd_fbuf = 0;
419*47584Smccanne 			break;
420*47584Smccanne 		}
421*47584Smccanne 	}
422*47584Smccanne 	/*
423*47584Smccanne 	 * At this point, we know we have something in the hold slot.
424*47584Smccanne 	 */
425*47584Smccanne 	m = d->bd_hbuf;
426*47584Smccanne 
427*47584Smccanne 	splx(s);
428*47584Smccanne 
429*47584Smccanne 	/*
430*47584Smccanne 	 * Move data from hold buffer into user space.
431*47584Smccanne 	 * We know the entire buffer is transferred since
432*47584Smccanne 	 * we checked above that the read buffer is MCLBYTES.
433*47584Smccanne 	 */
434*47584Smccanne 	error = bpf_moveout(m, uio);
435*47584Smccanne 
436*47584Smccanne 	s = splimp();
437*47584Smccanne 	if (d->bd_fbuf != 0)
438*47584Smccanne 		panic("bpfread: free mbuf slot occupied");
439*47584Smccanne 	d->bd_fbuf = m;
440*47584Smccanne 	d->bd_hbuf = (struct mbuf *)0;
441*47584Smccanne 	splx(s);
442*47584Smccanne 
443*47584Smccanne 	return error;
444*47584Smccanne }
445*47584Smccanne 
446*47584Smccanne 
447*47584Smccanne /*
448*47584Smccanne  * If there are processes select sleeping on this descriptor,
449*47584Smccanne  * wake them up.
450*47584Smccanne  */
451*47584Smccanne static inline void
452*47584Smccanne bpf_wakeup(d)
453*47584Smccanne 	register struct bpf_d *d;
454*47584Smccanne {
455*47584Smccanne 	if (d->bd_SelProc) {
456*47584Smccanne 		selwakeup(d->bd_SelProc, (int)d->bd_SelColl);
457*47584Smccanne 		d->bd_SelColl = 0;
458*47584Smccanne 		d->bd_SelProc = 0;
459*47584Smccanne 	}
460*47584Smccanne }
461*47584Smccanne 
462*47584Smccanne /*
463*47584Smccanne  *  bpf_timeout - process ethernet read timeout
464*47584Smccanne  */
465*47584Smccanne static int
466*47584Smccanne bpf_timeout(d)
467*47584Smccanne 	register struct bpf_d * d;
468*47584Smccanne {
469*47584Smccanne 	register int s = splimp();
470*47584Smccanne 
471*47584Smccanne 	d->bd_state = RS_TIMEDOUT;
472*47584Smccanne 	wakeup((caddr_t)d);
473*47584Smccanne 	bpf_wakeup(d);
474*47584Smccanne 
475*47584Smccanne 	splx(s);
476*47584Smccanne }
477*47584Smccanne 
478*47584Smccanne int
479*47584Smccanne bpfwrite(dev, uio)
480*47584Smccanne 	dev_t dev;
481*47584Smccanne 	struct uio *uio;
482*47584Smccanne {
483*47584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
484*47584Smccanne 	struct ifnet *ifp;
485*47584Smccanne 	struct mbuf *m;
486*47584Smccanne 	int error, s;
487*47584Smccanne 	static struct sockaddr dst;
488*47584Smccanne 
489*47584Smccanne 	if (d->bd_bif == 0)
490*47584Smccanne 		return ENXIO;
491*47584Smccanne 
492*47584Smccanne 	ifp = d->bd_bif->bif_ifp;
493*47584Smccanne 
494*47584Smccanne 	if (uio->uio_resid == 0)
495*47584Smccanne 		return 0;
496*47584Smccanne 	if (uio->uio_resid > ifp->if_mtu)
497*47584Smccanne 		return EMSGSIZE;
498*47584Smccanne 
499*47584Smccanne 	error = bpf_movein(uio, (int)d->bd_bif->bif_devp.bdev_type, &m, &dst);
500*47584Smccanne 	if (error)
501*47584Smccanne 		return error;
502*47584Smccanne 
503*47584Smccanne 	s = splnet();
504*47584Smccanne 	error = (*ifp->if_output)(ifp, m, &dst);
505*47584Smccanne 	splx(s);
506*47584Smccanne 	/*
507*47584Smccanne 	 * The driver frees the mbuf.
508*47584Smccanne 	 */
509*47584Smccanne 	return error;
510*47584Smccanne }
511*47584Smccanne 
512*47584Smccanne /*
513*47584Smccanne  * Reset a descriptor by flushing its packet before
514*47584Smccanne  * and clearing the receive and drop counts.  Should
515*47584Smccanne  * be called at splimp.
516*47584Smccanne  */
517*47584Smccanne static void
518*47584Smccanne reset_d(d)
519*47584Smccanne 	struct bpf_d *d;
520*47584Smccanne {
521*47584Smccanne 	if (d->bd_hbuf) {
522*47584Smccanne 		/* Free the hold buffer. */
523*47584Smccanne 		d->bd_fbuf = d->bd_hbuf;
524*47584Smccanne 		d->bd_hbuf = 0;
525*47584Smccanne 	}
526*47584Smccanne 	d->bd_sbuf->m_len = 0;
527*47584Smccanne 	d->bd_rcount = 0;
528*47584Smccanne 	d->bd_dcount = 0;
529*47584Smccanne }
530*47584Smccanne 
531*47584Smccanne /*
532*47584Smccanne  *  bpfioctl - packet filter control
533*47584Smccanne  *
534*47584Smccanne  *  FIONREAD		Check for read packet available.
535*47584Smccanne  *  SIOCGIFADDR		Get interface address - convenient hook to driver.
536*47584Smccanne  *  BIOCGFLEN		Get max filter len.
537*47584Smccanne  *  BIOCGBLEN		Get buffer len [for read()].
538*47584Smccanne  *  BIOCSETF		Set ethernet read filter.
539*47584Smccanne  *  BIOCFLUSH		Flush read packet buffer.
540*47584Smccanne  *  BIOCPROMISC		Put interface into promiscuous mode.
541*47584Smccanne  *  BIOCDEVP		Get device parameters.
542*47584Smccanne  *  BIOCGETIF		Get interface name.
543*47584Smccanne  *  BIOCSETIF		Set interface.
544*47584Smccanne  *  BIOCSRTIMEOUT	Set read timeout.
545*47584Smccanne  *  BIOCGRTIMEOUT	Get read timeout.
546*47584Smccanne  *  BIOCGSTATS		Get packet stats.
547*47584Smccanne  *  BIOCIMMEDIATE	Set immediate mode.
548*47584Smccanne  */
549*47584Smccanne /* ARGSUSED */
550*47584Smccanne int
551*47584Smccanne bpfioctl(dev, cmd, addr, flag)
552*47584Smccanne 	dev_t dev;
553*47584Smccanne 	int cmd;
554*47584Smccanne 	caddr_t addr;
555*47584Smccanne 	int flag;
556*47584Smccanne {
557*47584Smccanne 	register struct bpf_d *d = &bpf_dtab[minor(dev)];
558*47584Smccanne 	int s, error = 0;
559*47584Smccanne 
560*47584Smccanne 	switch (cmd) {
561*47584Smccanne 
562*47584Smccanne 	default:
563*47584Smccanne 		error = EINVAL;
564*47584Smccanne 		break;
565*47584Smccanne 
566*47584Smccanne 	/*
567*47584Smccanne 	 * Check for read packet available.
568*47584Smccanne 	 */
569*47584Smccanne 	case FIONREAD:
570*47584Smccanne 		{
571*47584Smccanne 			int n;
572*47584Smccanne 
573*47584Smccanne 			s = splimp();
574*47584Smccanne 			n = d->bd_sbuf->m_len;
575*47584Smccanne 			if (d->bd_hbuf)
576*47584Smccanne 				n += d->bd_hbuf->m_len;
577*47584Smccanne 			splx(s);
578*47584Smccanne 
579*47584Smccanne 			*(int *)addr = n;
580*47584Smccanne 			break;
581*47584Smccanne 		}
582*47584Smccanne 
583*47584Smccanne 	case SIOCGIFADDR:
584*47584Smccanne 		{
585*47584Smccanne 			struct ifnet *ifp;
586*47584Smccanne 
587*47584Smccanne 			if (d->bd_bif == 0)
588*47584Smccanne 				error = EINVAL;
589*47584Smccanne 			else {
590*47584Smccanne 				ifp = d->bd_bif->bif_ifp;
591*47584Smccanne 				error =  (*ifp->if_ioctl)(ifp, cmd, addr);
592*47584Smccanne 			}
593*47584Smccanne 			break;
594*47584Smccanne 		}
595*47584Smccanne 
596*47584Smccanne 	/*
597*47584Smccanne 	 * Get max filter len.
598*47584Smccanne 	 */
599*47584Smccanne 	case BIOCGFLEN:
600*47584Smccanne 		*(u_int *)addr = MCLBYTES / sizeof(struct bpf_insn);
601*47584Smccanne 		break;
602*47584Smccanne 	/*
603*47584Smccanne 	 * Get buffer len [for read()].
604*47584Smccanne 	 */
605*47584Smccanne 	case BIOCGBLEN:
606*47584Smccanne 		*(u_int *)addr = MCLBYTES;
607*47584Smccanne 		break;
608*47584Smccanne 
609*47584Smccanne 	/*
610*47584Smccanne 	 * Set ethernet read filter.
611*47584Smccanne 	 */
612*47584Smccanne         case BIOCSETF:
613*47584Smccanne 		error = bpf_setf(d, (struct bpf_program *)addr);
614*47584Smccanne 		break;
615*47584Smccanne 
616*47584Smccanne 	/*
617*47584Smccanne 	 * Flush read packet buffer.
618*47584Smccanne 	 */
619*47584Smccanne 	case BIOCFLUSH:
620*47584Smccanne 		s = splimp();
621*47584Smccanne 		reset_d(d);
622*47584Smccanne 		splx(s);
623*47584Smccanne 		break;
624*47584Smccanne 
625*47584Smccanne 	/*
626*47584Smccanne 	 * Put interface into promiscuous mode.
627*47584Smccanne 	 */
628*47584Smccanne 	case BIOCPROMISC:
629*47584Smccanne 		if (d->bd_bif == 0) {
630*47584Smccanne 			/*
631*47584Smccanne 			 * No interface attached yet.
632*47584Smccanne 			 */
633*47584Smccanne 			error = EINVAL;
634*47584Smccanne 			break;
635*47584Smccanne 		}
636*47584Smccanne 		s = splimp();
637*47584Smccanne 		if (d->bd_promisc == 0) {
638*47584Smccanne 			d->bd_promisc = 1;
639*47584Smccanne 			error = ifpromisc(d->bd_bif->bif_ifp, 1);
640*47584Smccanne 		}
641*47584Smccanne 		splx(s);
642*47584Smccanne 		break;
643*47584Smccanne 
644*47584Smccanne 	/*
645*47584Smccanne 	 * Get device parameters.
646*47584Smccanne 	 */
647*47584Smccanne 	case BIOCDEVP:
648*47584Smccanne 		if (d->bd_bif == 0)
649*47584Smccanne 			error = EINVAL;
650*47584Smccanne 		else
651*47584Smccanne 			*(struct bpf_devp *)addr = d->bd_bif->bif_devp;
652*47584Smccanne 		break;
653*47584Smccanne 
654*47584Smccanne 	/*
655*47584Smccanne 	 * Set interface name.
656*47584Smccanne 	 */
657*47584Smccanne 	case BIOCGETIF:
658*47584Smccanne 		if (d->bd_bif == 0)
659*47584Smccanne 			error = EINVAL;
660*47584Smccanne 		else
661*47584Smccanne 			bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
662*47584Smccanne 		break;
663*47584Smccanne 
664*47584Smccanne 	/*
665*47584Smccanne 	 * Set interface.
666*47584Smccanne 	 */
667*47584Smccanne 	case BIOCSETIF:
668*47584Smccanne 		error = bpf_setif(d, (struct ifreq *)addr);
669*47584Smccanne 		break;
670*47584Smccanne 
671*47584Smccanne 	/*
672*47584Smccanne 	 * Set read timeout.
673*47584Smccanne 	 */
674*47584Smccanne  	case BIOCSRTIMEOUT:
675*47584Smccanne 		{
676*47584Smccanne 			struct timeval *tv = (struct timeval *)addr;
677*47584Smccanne 			u_long msec;
678*47584Smccanne 
679*47584Smccanne 			/* Compute number of milliseconds. */
680*47584Smccanne 			msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
681*47584Smccanne 			/* Scale milliseconds to ticks.  Assume hard
682*47584Smccanne 			   clock has millisecond or greater resolution
683*47584Smccanne 			   (i.e. tick >= 1000).  For 10ms hardclock,
684*47584Smccanne 			   tick/1000 = 10, so rtout<-msec/10. */
685*47584Smccanne 			d->bd_rtout = msec / (tick / 1000);
686*47584Smccanne 			break;
687*47584Smccanne 		}
688*47584Smccanne 
689*47584Smccanne 	/*
690*47584Smccanne 	 * Get read timeout.
691*47584Smccanne 	 */
692*47584Smccanne  	case BIOCGRTIMEOUT:
693*47584Smccanne 		{
694*47584Smccanne 			struct timeval *tv = (struct timeval *)addr;
695*47584Smccanne 			u_long msec = d->bd_rtout;
696*47584Smccanne 
697*47584Smccanne 			msec *= tick / 1000;
698*47584Smccanne 			tv->tv_sec = msec / 1000;
699*47584Smccanne 			tv->tv_usec = msec % 1000;
700*47584Smccanne 			break;
701*47584Smccanne 		}
702*47584Smccanne 
703*47584Smccanne 	/*
704*47584Smccanne 	 * Get packet stats.
705*47584Smccanne 	 */
706*47584Smccanne 	case BIOCGSTATS:
707*47584Smccanne 		{
708*47584Smccanne 			struct bpf_stat *bs = (struct bpf_stat *)addr;
709*47584Smccanne 
710*47584Smccanne 			bs->bs_recv = d->bd_rcount;
711*47584Smccanne 			bs->bs_drop = d->bd_dcount;
712*47584Smccanne 			break;
713*47584Smccanne 		}
714*47584Smccanne 
715*47584Smccanne 	/*
716*47584Smccanne 	 * Set immediate mode.
717*47584Smccanne 	 */
718*47584Smccanne 	case BIOCIMMEDIATE:
719*47584Smccanne 		d->bd_immediate = *(u_int *)addr;
720*47584Smccanne 		break;
721*47584Smccanne 	}
722*47584Smccanne 	return error;
723*47584Smccanne }
724*47584Smccanne 
725*47584Smccanne /*
726*47584Smccanne  * Set d's packet filter program to 'fp'.  If 'd' already has a filter,
727*47584Smccanne  * free it and replace it.  Returns an appropriate ioctl error code.
728*47584Smccanne  */
729*47584Smccanne int
730*47584Smccanne bpf_setf(d, fp)
731*47584Smccanne 	struct bpf_d *d;
732*47584Smccanne 	struct bpf_program *fp;
733*47584Smccanne {
734*47584Smccanne 	struct bpf_insn *fcode;
735*47584Smccanne 	struct mbuf *m;
736*47584Smccanne 	u_int flen, size;
737*47584Smccanne 	int s;
738*47584Smccanne 
739*47584Smccanne 	if (fp->bf_insns == 0) {
740*47584Smccanne 		s = splimp();
741*47584Smccanne 		if (fp->bf_len != 0)
742*47584Smccanne 			return EINVAL;
743*47584Smccanne 		if (d->bd_filterm)
744*47584Smccanne 			m_freem(d->bd_filterm);
745*47584Smccanne 		d->bd_filterm = 0;
746*47584Smccanne 		d->bd_filter = bpf_default_filter;
747*47584Smccanne 		reset_d(d);
748*47584Smccanne 		splx(s);
749*47584Smccanne 		return 0;
750*47584Smccanne 	}
751*47584Smccanne 	flen = fp->bf_len;
752*47584Smccanne 	size = flen * sizeof(*fp->bf_insns);
753*47584Smccanne 
754*47584Smccanne 	if (size > MCLBYTES)
755*47584Smccanne 		return EINVAL;
756*47584Smccanne 
757*47584Smccanne 	MGET(m, M_DONTWAIT, MT_DATA);
758*47584Smccanne 	if (m == 0)
759*47584Smccanne 		return ENOBUFS;
760*47584Smccanne 
761*47584Smccanne 	if (size > MLEN) {
762*47584Smccanne 		MCLGET(m);
763*47584Smccanne 		if (m->m_len != MCLBYTES) {
764*47584Smccanne 			m_freem(m);
765*47584Smccanne 			return ENOBUFS;
766*47584Smccanne 		}
767*47584Smccanne 	}
768*47584Smccanne 	fcode = mtod(m, struct bpf_insn *);
769*47584Smccanne 	if (copyin((caddr_t)(fp->bf_insns), (caddr_t)fcode, size))
770*47584Smccanne 		return EINVAL;
771*47584Smccanne 
772*47584Smccanne 	if (bpf_validate(fcode, (int)flen)) {
773*47584Smccanne 		s = splimp();
774*47584Smccanne 		if (d->bd_filterm)
775*47584Smccanne 			m_freem(d->bd_filterm);
776*47584Smccanne 		d->bd_filterm = m;
777*47584Smccanne 		d->bd_filter = fcode;
778*47584Smccanne 		reset_d(d);
779*47584Smccanne 		splx(s);
780*47584Smccanne 
781*47584Smccanne 		return 0;
782*47584Smccanne 	}
783*47584Smccanne 	m_freem(m);
784*47584Smccanne 	return EINVAL;
785*47584Smccanne }
786*47584Smccanne 
787*47584Smccanne /*
788*47584Smccanne  * Detach 'd' from its current interface (if attached at all) and attach to
789*47584Smccanne  * the interface named 'name'.  Return ioctl error code or 0.
790*47584Smccanne  */
791*47584Smccanne static int
792*47584Smccanne bpf_setif(d, ifr)
793*47584Smccanne 	struct bpf_d *d;
794*47584Smccanne 	struct ifreq *ifr;
795*47584Smccanne {
796*47584Smccanne 	struct bpf_if *bp;
797*47584Smccanne 	char *cp;
798*47584Smccanne 	int unit, i, s;
799*47584Smccanne 
800*47584Smccanne 	/*
801*47584Smccanne 	 * Separate string into name part and unit number.  Put a null
802*47584Smccanne 	 * byte at the end of the name part, and compute the number.
803*47584Smccanne 	 * If the a unit number is unspecified, the default is 0,
804*47584Smccanne 	 * as initialized above.
805*47584Smccanne 	 */
806*47584Smccanne 	unit = 0;
807*47584Smccanne 	cp = ifr->ifr_name;
808*47584Smccanne 	cp[sizeof(ifr->ifr_name) - 1] = '\0';
809*47584Smccanne 	while (*cp++) {
810*47584Smccanne 		if (*cp >= '0' && *cp <= '9') {
811*47584Smccanne 			unit = *cp - '0';
812*47584Smccanne 			*cp++ = '\0';
813*47584Smccanne 			while (*cp)
814*47584Smccanne 				unit = 10 * unit + *cp++ - '0';
815*47584Smccanne 			break;
816*47584Smccanne 		}
817*47584Smccanne 	}
818*47584Smccanne 	/*
819*47584Smccanne 	 * Look through attached interfaces for the named one.
820*47584Smccanne 	 */
821*47584Smccanne 	bp = bpf_iftab;
822*47584Smccanne 	for (i = 0; i < NBPFILTER; ++bp, ++i) {
823*47584Smccanne 		struct ifnet *ifp = bp->bif_ifp;
824*47584Smccanne 
825*47584Smccanne 		if (ifp == 0 || unit != ifp->if_unit
826*47584Smccanne 		    || strcmp(ifp->if_name, ifr->ifr_name) != 0)
827*47584Smccanne 			continue;
828*47584Smccanne 		/*
829*47584Smccanne 		 * We found the requested interface.  If we're
830*47584Smccanne 		 * already attached to it, just flush the buffer.
831*47584Smccanne 		 * If it's not up, return an error.
832*47584Smccanne 		 */
833*47584Smccanne 		if ((ifp->if_flags & IFF_UP) == 0)
834*47584Smccanne 			return ENETDOWN;
835*47584Smccanne 		s = splimp();
836*47584Smccanne 		if (bp != d->bd_bif) {
837*47584Smccanne 			if (d->bd_bif)
838*47584Smccanne 				/*
839*47584Smccanne 				 * Detach if attached to  something else.
840*47584Smccanne 				 */
841*47584Smccanne 				bpf_detachd(d);
842*47584Smccanne 
843*47584Smccanne 			bpf_attachd(d, bp);
844*47584Smccanne 		}
845*47584Smccanne 		reset_d(d);
846*47584Smccanne 		splx(s);
847*47584Smccanne 		return 0;
848*47584Smccanne 	}
849*47584Smccanne 	/* Not found. */
850*47584Smccanne 	return ENXIO;
851*47584Smccanne }
852*47584Smccanne 
853*47584Smccanne /*
854*47584Smccanne  * Lookup the name of the 'ifp' interface and return it in 'ifr->ifr_name'.
855*47584Smccanne  * We augment the ifp's base name with its unit number.
856*47584Smccanne  */
857*47584Smccanne static void
858*47584Smccanne bpf_ifname(ifp, ifr)
859*47584Smccanne 	struct ifnet *ifp;
860*47584Smccanne 	struct ifreq *ifr;
861*47584Smccanne {
862*47584Smccanne 	char *s = ifp->if_name;
863*47584Smccanne 	char *d = ifr->ifr_name;
864*47584Smccanne 
865*47584Smccanne 	while (*d++ = *s++)
866*47584Smccanne 		;
867*47584Smccanne 	/* Assume that unit number is less than 10. */
868*47584Smccanne 	*d++ = ifp->if_unit + '0';
869*47584Smccanne 	*d = '\0';
870*47584Smccanne }
871*47584Smccanne 
872*47584Smccanne /*
873*47584Smccanne  * Support for select() system call
874*47584Smccanne  * Inspired by the code in tty.c for the same purpose.
875*47584Smccanne  *
876*47584Smccanne  * bpfselect - returns true iff the specific operation
877*47584Smccanne  *	will not block indefinitely.  Otherwise, return
878*47584Smccanne  *	false but make a note that a selwakeup() must be done.
879*47584Smccanne  */
880*47584Smccanne int
881*47584Smccanne bpfselect(dev, rw)
882*47584Smccanne 	register dev_t dev;
883*47584Smccanne 	int rw;
884*47584Smccanne {
885*47584Smccanne 	register struct bpf_d *d;
886*47584Smccanne 	register int s;
887*47584Smccanne 
888*47584Smccanne 	if (rw != FREAD)
889*47584Smccanne 		return 0;
890*47584Smccanne 	/*
891*47584Smccanne 	 * An imitation of the FIONREAD ioctl code.
892*47584Smccanne 	 */
893*47584Smccanne 	d = &bpf_dtab[minor(dev)];
894*47584Smccanne 
895*47584Smccanne 	s = splimp();
896*47584Smccanne 	if (d->bd_sbuf->m_len ||
897*47584Smccanne 	    d->bd_hbuf && d->bd_hbuf->m_len) {
898*47584Smccanne 		/*
899*47584Smccanne 		 * There is data waiting.
900*47584Smccanne 		 */
901*47584Smccanne 		splx(s);
902*47584Smccanne 		return 1;
903*47584Smccanne 	}
904*47584Smccanne 	/*
905*47584Smccanne 	 * No data ready.  If there's already a select() waiting on this
906*47584Smccanne 	 * minor device then this is a collision.  This shouldn't happen
907*47584Smccanne 	 * because minors really should not be shared, but if a process
908*47584Smccanne 	 * forks while one of these is open, it is possible that both
909*47584Smccanne 	 * processes could select on the same descriptor.
910*47584Smccanne 	 */
911*47584Smccanne 	if (d->bd_SelProc && d->bd_SelProc->p_wchan == (caddr_t)&selwait)
912*47584Smccanne 		d->bd_SelColl = 1;
913*47584Smccanne 	else
914*47584Smccanne 		d->bd_SelProc = u.u_procp;
915*47584Smccanne 	splx(s);
916*47584Smccanne 	return 0;
917*47584Smccanne }
918*47584Smccanne 
919*47584Smccanne /*
920*47584Smccanne  * bpf_tap - incoming linkage from device drivers
921*47584Smccanne  */
922*47584Smccanne void
923*47584Smccanne bpf_tap(arg, pbuf, plen)
924*47584Smccanne 	caddr_t arg;
925*47584Smccanne 	register u_char *pbuf;
926*47584Smccanne 	register u_int plen;
927*47584Smccanne {
928*47584Smccanne 	struct bpf_if *bp;
929*47584Smccanne 	register struct bpf_d *d;
930*47584Smccanne 	register u_int slen;
931*47584Smccanne 	extern bcopy();
932*47584Smccanne 	/*
933*47584Smccanne 	 * Note that the ipl does not have to be raised at this point.
934*47584Smccanne 	 * The only problem that could arise here is that if two different
935*47584Smccanne 	 * interfaces shared any data.  This is not the case.
936*47584Smccanne 	 */
937*47584Smccanne 	bp = (struct bpf_if *)arg;
938*47584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
939*47584Smccanne 		++d->bd_rcount;
940*47584Smccanne 		slen = bpf_filter(d->bd_filter, pbuf, plen, plen);
941*47584Smccanne 		if (slen != 0)
942*47584Smccanne 			catchpacket(d, pbuf, plen, slen, (void (*)())bcopy);
943*47584Smccanne 	}
944*47584Smccanne }
945*47584Smccanne 
946*47584Smccanne /*
947*47584Smccanne  * Copy data from an mbuf chain into a buffer.  This code is derived
948*47584Smccanne  * from m_copydata in sys/uipc_mbuf.c.
949*47584Smccanne  */
950*47584Smccanne static void
951*47584Smccanne bpf_m_copydata(src, dst, len)
952*47584Smccanne 	u_char *src;
953*47584Smccanne 	u_char *dst;
954*47584Smccanne 	register int len;
955*47584Smccanne {
956*47584Smccanne 	register struct mbuf *m = (struct mbuf *)src;
957*47584Smccanne 	register unsigned count;
958*47584Smccanne 
959*47584Smccanne 	while (len > 0) {
960*47584Smccanne 		if (m == 0)
961*47584Smccanne 			panic("bpf_m_copydata");
962*47584Smccanne 		count = MIN(m->m_len, len);
963*47584Smccanne 		(void)bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
964*47584Smccanne 		len -= count;
965*47584Smccanne 		dst += count;
966*47584Smccanne 		m = m->m_next;
967*47584Smccanne 	}
968*47584Smccanne }
969*47584Smccanne 
970*47584Smccanne /*
971*47584Smccanne  * Length of ethernet and TCP/IP header header with no IP options.
972*47584Smccanne  */
973*47584Smccanne #define BPF_MIN_SNAPLEN 50
974*47584Smccanne 
975*47584Smccanne /*
976*47584Smccanne  * bpf_mtap - incoming linkage from device drivers, when packet
977*47584Smccanne  *   is in an mbuf chain
978*47584Smccanne  */
979*47584Smccanne void
980*47584Smccanne bpf_mtap(arg, m0)
981*47584Smccanne 	caddr_t arg;
982*47584Smccanne 	struct mbuf *m0;
983*47584Smccanne {
984*47584Smccanne 	static u_char buf[BPF_MIN_SNAPLEN];
985*47584Smccanne 
986*47584Smccanne 	struct bpf_if *bp = (struct bpf_if *)arg;
987*47584Smccanne 	struct bpf_d *d;
988*47584Smccanne 	u_char *cp;
989*47584Smccanne 	u_int slen, plen;
990*47584Smccanne 	int nbytes;
991*47584Smccanne 	struct mbuf *m;
992*47584Smccanne 
993*47584Smccanne 	if (m0->m_len >= BPF_MIN_SNAPLEN) {
994*47584Smccanne 		slen = m0->m_len;
995*47584Smccanne 		cp = mtod(m0, u_char *);
996*47584Smccanne 	}
997*47584Smccanne 	else {
998*47584Smccanne 		nbytes = BPF_MIN_SNAPLEN;
999*47584Smccanne 		cp = buf;
1000*47584Smccanne 		m = m0;
1001*47584Smccanne 		while (m && nbytes > 0) {
1002*47584Smccanne 			slen = MIN(m->m_len, nbytes);
1003*47584Smccanne 			bcopy(mtod(m, char *), (char *)cp, slen);
1004*47584Smccanne 			cp += slen;
1005*47584Smccanne 			nbytes -= slen;
1006*47584Smccanne 			m = m->m_next;
1007*47584Smccanne 		}
1008*47584Smccanne 		if (nbytes > 0)
1009*47584Smccanne 			/* Packet too small? */
1010*47584Smccanne 			return;
1011*47584Smccanne 
1012*47584Smccanne 		slen = BPF_MIN_SNAPLEN;
1013*47584Smccanne 		cp = buf;
1014*47584Smccanne 	}
1015*47584Smccanne 	plen = 0;
1016*47584Smccanne 	m = m0;
1017*47584Smccanne 	while (m) {
1018*47584Smccanne 		plen += m->m_len;
1019*47584Smccanne 		m = m->m_next;
1020*47584Smccanne 	}
1021*47584Smccanne 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
1022*47584Smccanne 		++d->bd_rcount;
1023*47584Smccanne 		slen = bpf_filter(d->bd_filter, cp, plen, slen);
1024*47584Smccanne 		if (slen != 0)
1025*47584Smccanne 			catchpacket(d, (u_char *)m0, plen, slen,
1026*47584Smccanne 				    bpf_m_copydata);
1027*47584Smccanne 	}
1028*47584Smccanne }
1029*47584Smccanne 
1030*47584Smccanne /*
1031*47584Smccanne  * Move the packet data from interface memory ('pbuf') into the
1032*47584Smccanne  * store buffer.  Return 1 if it's time to wakeup a listener (buffer full),
1033*47584Smccanne  * otherwise 0.  'copy' is the routine called to do the actual data
1034*47584Smccanne  * transfer.  'bcopy' is passed in to copy contiguous chunks, while
1035*47584Smccanne  * 'bpf_m_copydata' is passed in to copy mbuf chains.  In the latter
1036*47584Smccanne  * case, 'pbuf' is really an mbuf.
1037*47584Smccanne  */
1038*47584Smccanne static void
1039*47584Smccanne catchpacket(d, pbuf, plen, snaplen, cpfn)
1040*47584Smccanne 	struct bpf_d *d;
1041*47584Smccanne 	u_char *pbuf;
1042*47584Smccanne 	u_int plen, snaplen;
1043*47584Smccanne 	void (*cpfn)();
1044*47584Smccanne {
1045*47584Smccanne 	struct mbuf *m;
1046*47584Smccanne 	struct bpf_hdr *hp;
1047*47584Smccanne 	int totlen, curlen;
1048*47584Smccanne 	int hdrlen = d->bd_bif->bif_hdrlen;
1049*47584Smccanne 	/*
1050*47584Smccanne 	 * Figure out how many bytes to move.  If the packet is
1051*47584Smccanne 	 * greater or equal to the snapshot length, transfer that
1052*47584Smccanne 	 * much.  Otherwise, transfer the whole packet (unless
1053*47584Smccanne 	 * we hit the cluster limit).
1054*47584Smccanne 	 */
1055*47584Smccanne 	if (snaplen <= plen)
1056*47584Smccanne 		totlen = snaplen + hdrlen;
1057*47584Smccanne 	else {
1058*47584Smccanne 		totlen = plen + hdrlen;
1059*47584Smccanne 		if (totlen > MCLBYTES)
1060*47584Smccanne 			totlen = MCLBYTES;
1061*47584Smccanne 	}
1062*47584Smccanne 
1063*47584Smccanne 	m = d->bd_sbuf;
1064*47584Smccanne 
1065*47584Smccanne 	/*
1066*47584Smccanne 	 * Round up the end of the previous packet to the next longword.
1067*47584Smccanne 	 */
1068*47584Smccanne 	curlen = BPF_WORDALIGN(m->m_len);
1069*47584Smccanne 
1070*47584Smccanne 	if (curlen + totlen > MCLBYTES) {
1071*47584Smccanne 		/*
1072*47584Smccanne 		 * This packet will overflow the storage buffer.
1073*47584Smccanne 		 * Move the current cluster buffer to the hold slot,
1074*47584Smccanne 		 * and grab the free one.
1075*47584Smccanne 		 */
1076*47584Smccanne 		if (d->bd_fbuf == 0) {
1077*47584Smccanne 			/*
1078*47584Smccanne 			 * We haven't completed the previous read yet?
1079*47584Smccanne 			 * Drop the packet.
1080*47584Smccanne 			 */
1081*47584Smccanne 			++d->bd_dcount;
1082*47584Smccanne 			return;
1083*47584Smccanne 		}
1084*47584Smccanne 		/*
1085*47584Smccanne 		 * Rotate the buffers.  Move the 'store' buffer
1086*47584Smccanne 		 * into the 'hold' slot, and the 'free' buffer
1087*47584Smccanne 		 * into the 'store' slot.  Zero out the length of
1088*47584Smccanne 		 * the new 'store' buffer.
1089*47584Smccanne 		 */
1090*47584Smccanne 		d->bd_hbuf = d->bd_sbuf;
1091*47584Smccanne 		m = d->bd_sbuf = d->bd_fbuf;
1092*47584Smccanne 		d->bd_fbuf = 0;
1093*47584Smccanne 		curlen = m->m_len = 0;
1094*47584Smccanne 
1095*47584Smccanne 		/*
1096*47584Smccanne 		 * Wake up anyone sleeping on this descriptor.
1097*47584Smccanne 		 */
1098*47584Smccanne 		wakeup((caddr_t)d);
1099*47584Smccanne 		bpf_wakeup(d);
1100*47584Smccanne 	}
1101*47584Smccanne 	else if (d->bd_immediate) {
1102*47584Smccanne 		/*
1103*47584Smccanne 		 * Immediate mode is set.  A packet arrived so any
1104*47584Smccanne 		 * reads should be woken up.
1105*47584Smccanne 		 */
1106*47584Smccanne 		wakeup((caddr_t)d);
1107*47584Smccanne 		bpf_wakeup(d);
1108*47584Smccanne 	}
1109*47584Smccanne 	/*
1110*47584Smccanne 	 * Append the bpf header.
1111*47584Smccanne 	 */
1112*47584Smccanne 	hp = (struct bpf_hdr *)(mtod(m, u_char *) + curlen);
1113*47584Smccanne #ifdef sun
1114*47584Smccanne 	uniqtime(&hp->bh_tstamp);
1115*47584Smccanne #else
1116*47584Smccanne #ifdef hp300
1117*47584Smccanne 	microtime(&hp->bh_tstamp);
1118*47584Smccanne #else
1119*47584Smccanne 	hp->bh_tstamp = time;
1120*47584Smccanne #endif
1121*47584Smccanne #endif
1122*47584Smccanne 	hp->bh_datalen = plen;
1123*47584Smccanne 	hp->bh_hdrlen = hdrlen;
1124*47584Smccanne 	/*
1125*47584Smccanne 	 * Copy the packet data into the 'store' buffer and
1126*47584Smccanne 	 * update the cluster length.
1127*47584Smccanne 	 */
1128*47584Smccanne 	(*cpfn)(pbuf, (u_char *)hp + hdrlen, hp->bh_caplen = totlen - hdrlen);
1129*47584Smccanne 
1130*47584Smccanne 	m->m_len = curlen + totlen;
1131*47584Smccanne }
1132*47584Smccanne 
1133*47584Smccanne /*
1134*47584Smccanne  * Allocate an mbuf cluster and clear its length field.
1135*47584Smccanne  * If resources unavaiable, return 0.
1136*47584Smccanne  * We can wait in MGET since we assume that we are called
1137*47584Smccanne  * at a low priority.
1138*47584Smccanne  */
1139*47584Smccanne static struct mbuf *
1140*47584Smccanne bpf_mcluster()
1141*47584Smccanne {
1142*47584Smccanne 	struct mbuf *m;
1143*47584Smccanne 
1144*47584Smccanne 	MGET(m, M_WAIT, MT_DATA);
1145*47584Smccanne 	if (m == 0)
1146*47584Smccanne 		return 0;
1147*47584Smccanne 	MCLGET(m);
1148*47584Smccanne 	if (m->m_len == MCLBYTES) {
1149*47584Smccanne 		m->m_len = 0;
1150*47584Smccanne 		return m;
1151*47584Smccanne 	}
1152*47584Smccanne 	m_freem(m);
1153*47584Smccanne 	return 0;
1154*47584Smccanne }
1155*47584Smccanne 
1156*47584Smccanne /*
1157*47584Smccanne  * Initialize all nonzero fields of a descriptor.
1158*47584Smccanne  */
1159*47584Smccanne static int
1160*47584Smccanne bpf_initd(d)
1161*47584Smccanne 	register struct bpf_d *d;
1162*47584Smccanne {
1163*47584Smccanne 	struct mbuf *m;
1164*47584Smccanne 
1165*47584Smccanne 	/* Get the buffer space. */
1166*47584Smccanne 	m = bpf_mcluster();
1167*47584Smccanne 	if (m == 0)
1168*47584Smccanne 		return ENOBUFS;
1169*47584Smccanne 	d->bd_fbuf = m;
1170*47584Smccanne 	m = bpf_mcluster();
1171*47584Smccanne 	if (m == 0) {
1172*47584Smccanne 		m_freem(d->bd_fbuf);
1173*47584Smccanne 		return ENOBUFS;
1174*47584Smccanne 	}
1175*47584Smccanne 	d->bd_sbuf = m;
1176*47584Smccanne 
1177*47584Smccanne 	return 0;
1178*47584Smccanne }
1179*47584Smccanne 
1180*47584Smccanne /*
1181*47584Smccanne  * Register 'ifp' with bpf.  'devp' is the link-level device descriptor
1182*47584Smccanne  * and 'driverp' is a pointer to the 'struct bpf_if *' in the driver's softc.
1183*47584Smccanne  */
1184*47584Smccanne void
1185*47584Smccanne bpfattach(driverp, ifp, devp)
1186*47584Smccanne 	caddr_t *driverp;
1187*47584Smccanne 	struct ifnet *ifp;
1188*47584Smccanne 	struct bpf_devp *devp;
1189*47584Smccanne {
1190*47584Smccanne 	struct bpf_if *bp;
1191*47584Smccanne 	int i;
1192*47584Smccanne 
1193*47584Smccanne 	if (bpf_units >= NBPFILTER) {
1194*47584Smccanne 		printf("bpf: too many interfaces: %s%d not attached\n",
1195*47584Smccanne 		       ifp->if_name, ifp->if_unit);
1196*47584Smccanne 		return;
1197*47584Smccanne 	}
1198*47584Smccanne 	bp = &bpf_iftab[bpf_units++];
1199*47584Smccanne 
1200*47584Smccanne 	bp->bif_dlist = 0;
1201*47584Smccanne 	bp->bif_driverp = (struct bpf_if **)driverp;
1202*47584Smccanne 	bp->bif_ifp = ifp;
1203*47584Smccanne 	bp->bif_devp = *devp;
1204*47584Smccanne 
1205*47584Smccanne 	/*
1206*47584Smccanne 	 * Compute the length of the bpf header.  This is not necessarily
1207*47584Smccanne 	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
1208*47584Smccanne 	 * that the network layer header begins on a longword boundary (for
1209*47584Smccanne 	 * performance reasons and to alleviate alignment restrictions).
1210*47584Smccanne 	 */
1211*47584Smccanne 	i = devp->bdev_hdrlen;
1212*47584Smccanne 	bp->bif_hdrlen = BPF_WORDALIGN(i + SIZEOF_BPF_HDR) - i;
1213*47584Smccanne 
1214*47584Smccanne 	/*
1215*47584Smccanne 	 * Mark all the descriptors free if this hasn't been done.
1216*47584Smccanne 	 */
1217*47584Smccanne 	if (!D_ISFREE(&bpf_dtab[0]))
1218*47584Smccanne 		for (i = 0; i < NBPFILTER; ++i)
1219*47584Smccanne 			D_MARKFREE(&bpf_dtab[i]);
1220*47584Smccanne 
1221*47584Smccanne 	printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
1222*47584Smccanne }
1223*47584Smccanne 
1224*47584Smccanne #endif (NBPFILTER > 0)
1225