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