151440Smccanne /* 251440Smccanne * Copyright (c) 1990, 1991 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 751425Smccanne * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 851425Smccanne * Berkeley Laboratory. 947584Smccanne * 1051440Smccanne * %sccs.include.redist.c% 1149343Sbostic * 12*59122Storek * @(#)bpf.c 7.14 (Berkeley) 04/17/93 1349343Sbostic * 1449343Sbostic * static char rcsid[] = 1551425Smccanne * "$Header: bpf.c,v 1.33 91/10/27 21:21:58 mccanne Exp $"; 1647584Smccanne */ 1747584Smccanne 1847584Smccanne #include "bpfilter.h" 1947584Smccanne 2051425Smccanne #if NBPFILTER > 0 2147584Smccanne 2251425Smccanne #ifndef __GNUC__ 2351425Smccanne #define inline 2451425Smccanne #else 2554970Smckusick #define inline __inline 2651425Smccanne #endif 2751425Smccanne 2847584Smccanne #include <sys/param.h> 2947584Smccanne #include <sys/systm.h> 3047584Smccanne #include <sys/mbuf.h> 3147584Smccanne #include <sys/buf.h> 3253947Smccanne #include <sys/time.h> 3348932Smccanne #include <sys/proc.h> 3447584Smccanne #include <sys/user.h> 3547584Smccanne #include <sys/ioctl.h> 3647584Smccanne #include <sys/map.h> 3747584Smccanne 3847584Smccanne #include <sys/file.h> 3951425Smccanne #if defined(sparc) && BSD < 199103 4047584Smccanne #include <sys/stream.h> 4147584Smccanne #endif 4247584Smccanne #include <sys/tty.h> 4347584Smccanne #include <sys/uio.h> 4447584Smccanne 4547584Smccanne #include <sys/protosw.h> 4647584Smccanne #include <sys/socket.h> 4747584Smccanne #include <net/if.h> 4847584Smccanne 4947584Smccanne #include <net/bpf.h> 5047584Smccanne #include <net/bpfdesc.h> 5147584Smccanne 5247584Smccanne #include <sys/errno.h> 5347584Smccanne 5447584Smccanne #include <netinet/in.h> 5547584Smccanne #include <netinet/if_ether.h> 5647584Smccanne #include <sys/kernel.h> 5747584Smccanne 5851425Smccanne /* 5951425Smccanne * Older BSDs don't have kernel malloc. 6051425Smccanne */ 6151425Smccanne #if BSD < 199103 6251425Smccanne extern bcopy(); 6351425Smccanne static caddr_t bpf_alloc(); 6453947Smccanne #include <net/bpf_compat.h> 6551425Smccanne #define BPF_BUFSIZE (MCLBYTES-8) 6653947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio) 6751425Smccanne #else 6851425Smccanne #define BPF_BUFSIZE 4096 6953947Smccanne #define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio) 7051425Smccanne #endif 7151425Smccanne 7247584Smccanne #define PRINET 26 /* interruptible */ 7347584Smccanne 7447584Smccanne /* 7548932Smccanne * The default read buffer size is patchable. 7648932Smccanne */ 7751425Smccanne int bpf_bufsize = BPF_BUFSIZE; 7848932Smccanne 7948932Smccanne /* 8049202Smccanne * bpf_iflist is the list of interfaces; each corresponds to an ifnet 8149202Smccanne * bpf_dtab holds the descriptors, indexed by minor device # 8247584Smccanne */ 8353947Smccanne struct bpf_if *bpf_iflist; 8453947Smccanne struct bpf_d bpf_dtab[NBPFILTER]; 8547584Smccanne 86*59122Storek #if BSD >= 199207 87*59122Storek /* 88*59122Storek * bpfilterattach() is called at boot time in new systems. We do 89*59122Storek * nothing here since old systems will not call this. 90*59122Storek */ 91*59122Storek /* ARGSUSED */ 92*59122Storek void 93*59122Storek bpfilterattach(n) 94*59122Storek int n; 95*59122Storek { 96*59122Storek } 97*59122Storek #endif 98*59122Storek 9947584Smccanne static void bpf_ifname(); 10047584Smccanne static void catchpacket(); 10153947Smccanne static void bpf_freed(); 10247584Smccanne static int bpf_setif(); 10347584Smccanne static int bpf_initd(); 10453947Smccanne static int bpf_allocbufs(); 10547584Smccanne 10647584Smccanne static int 10755289Smckusick bpf_movein(uio, linktype, mp, sockp, datlen) 10847584Smccanne register struct uio *uio; 10955289Smckusick int linktype, *datlen; 11047584Smccanne register struct mbuf **mp; 11147584Smccanne register struct sockaddr *sockp; 11247584Smccanne { 11347584Smccanne struct mbuf *m; 11447584Smccanne int error; 11547584Smccanne int len; 11647584Smccanne int hlen; 11747584Smccanne 11847584Smccanne /* 11947584Smccanne * Build a sockaddr based on the data link layer type. 12047584Smccanne * We do this at this level because the ethernet header 12147584Smccanne * is copied directly into the data field of the sockaddr. 12247584Smccanne * In the case of SLIP, there is no header and the packet 12347584Smccanne * is forwarded as is. 12447584Smccanne * Also, we are careful to leave room at the front of the mbuf 12547584Smccanne * for the link level header. 12647584Smccanne */ 12747584Smccanne switch (linktype) { 12853947Smccanne 12947584Smccanne case DLT_SLIP: 13047584Smccanne sockp->sa_family = AF_INET; 13147584Smccanne hlen = 0; 13247584Smccanne break; 13347584Smccanne 13447584Smccanne case DLT_EN10MB: 13547584Smccanne sockp->sa_family = AF_UNSPEC; 13647584Smccanne /* XXX Would MAXLINKHDR be better? */ 13747584Smccanne hlen = sizeof(struct ether_header); 13847584Smccanne break; 13947584Smccanne 14053947Smccanne case DLT_FDDI: 14147584Smccanne sockp->sa_family = AF_UNSPEC; 14247584Smccanne /* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */ 14347584Smccanne hlen = 24; 14447584Smccanne break; 14547584Smccanne 14653947Smccanne case DLT_NULL: 14753947Smccanne sockp->sa_family = AF_UNSPEC; 14853947Smccanne hlen = 0; 14953947Smccanne break; 15053947Smccanne 15147584Smccanne default: 15248932Smccanne return (EIO); 15347584Smccanne } 15447584Smccanne 15547584Smccanne len = uio->uio_resid; 15655289Smckusick *datlen = len - hlen; 15747584Smccanne if ((unsigned)len > MCLBYTES) 15848932Smccanne return (EIO); 15947584Smccanne 16047584Smccanne MGET(m, M_WAIT, MT_DATA); 16147584Smccanne if (m == 0) 16248932Smccanne return (ENOBUFS); 16347584Smccanne if (len > MLEN) { 16451425Smccanne #if BSD >= 199103 16548932Smccanne MCLGET(m, M_WAIT); 16648932Smccanne if ((m->m_flags & M_EXT) == 0) { 16751425Smccanne #else 16851425Smccanne MCLGET(m); 16953947Smccanne if (m->m_len != MCLBYTES) { 17051425Smccanne #endif 17153947Smccanne error = ENOBUFS; 17247584Smccanne goto bad; 17347584Smccanne } 17447584Smccanne } 17547584Smccanne m->m_len = len; 17647584Smccanne *mp = m; 17747584Smccanne /* 17847584Smccanne * Make room for link header. 17947584Smccanne */ 18053947Smccanne if (hlen != 0) { 18147584Smccanne m->m_len -= hlen; 18251425Smccanne #if BSD >= 199103 18348932Smccanne m->m_data += hlen; /* XXX */ 18451425Smccanne #else 18551425Smccanne m->m_off += hlen; 18651425Smccanne #endif 18753947Smccanne error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio); 18847584Smccanne if (error) 18947584Smccanne goto bad; 19047584Smccanne } 19153947Smccanne error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio); 19253947Smccanne if (!error) 19348932Smccanne return (0); 19447584Smccanne bad: 19547584Smccanne m_freem(m); 19648932Smccanne return (error); 19747584Smccanne } 19847584Smccanne 19947584Smccanne /* 20051425Smccanne * Attach file to the bpf interface, i.e. make d listen on bp. 20147584Smccanne * Must be called at splimp. 20247584Smccanne */ 20347584Smccanne static void 20447584Smccanne bpf_attachd(d, bp) 20547584Smccanne struct bpf_d *d; 20647584Smccanne struct bpf_if *bp; 20747584Smccanne { 20851425Smccanne /* 20951425Smccanne * Point d at bp, and add d to the interface's list of listeners. 21051425Smccanne * Finally, point the driver's bpf cookie at the interface so 21151425Smccanne * it will divert packets to bpf. 21251425Smccanne */ 21347584Smccanne d->bd_bif = bp; 21447584Smccanne d->bd_next = bp->bif_dlist; 21547584Smccanne bp->bif_dlist = d; 21647584Smccanne 21747584Smccanne *bp->bif_driverp = bp; 21847584Smccanne } 21947584Smccanne 22051425Smccanne /* 22151425Smccanne * Detach a file from its interface. 22251425Smccanne */ 22347584Smccanne static void 22447584Smccanne bpf_detachd(d) 22547584Smccanne struct bpf_d *d; 22647584Smccanne { 22747584Smccanne struct bpf_d **p; 22847584Smccanne struct bpf_if *bp; 22947584Smccanne 23047584Smccanne bp = d->bd_bif; 23147584Smccanne /* 23247584Smccanne * Check if this descriptor had requested promiscuous mode. 23347584Smccanne * If so, turn it off. 23447584Smccanne */ 23547584Smccanne if (d->bd_promisc) { 23647584Smccanne d->bd_promisc = 0; 23747584Smccanne if (ifpromisc(bp->bif_ifp, 0)) 23847584Smccanne /* 23947584Smccanne * Something is really wrong if we were able to put 24047584Smccanne * the driver into promiscuous mode, but can't 24147584Smccanne * take it out. 24247584Smccanne */ 24351425Smccanne panic("bpf: ifpromisc failed"); 24447584Smccanne } 24551425Smccanne /* Remove d from the interface's descriptor list. */ 24647584Smccanne p = &bp->bif_dlist; 24747584Smccanne while (*p != d) { 24847584Smccanne p = &(*p)->bd_next; 24947584Smccanne if (*p == 0) 25047584Smccanne panic("bpf_detachd: descriptor not in list"); 25147584Smccanne } 25247584Smccanne *p = (*p)->bd_next; 25347584Smccanne if (bp->bif_dlist == 0) 25447584Smccanne /* 25547584Smccanne * Let the driver know that there are no more listeners. 25647584Smccanne */ 25747584Smccanne *d->bd_bif->bif_driverp = 0; 25847584Smccanne d->bd_bif = 0; 25947584Smccanne } 26047584Smccanne 26147584Smccanne 26247584Smccanne /* 26353947Smccanne * Mark a descriptor free by making it point to itself. 26447584Smccanne * This is probably cheaper than marking with a constant since 26547584Smccanne * the address should be in a register anyway. 26647584Smccanne */ 26747584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next) 26847584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d)) 26947584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0) 27047584Smccanne 27147584Smccanne /* 27253947Smccanne * Open ethernet device. Returns ENXIO for illegal minor device number, 27353947Smccanne * EBUSY if file is open by another process. 27447584Smccanne */ 27547584Smccanne /* ARGSUSED */ 27647584Smccanne int 27747584Smccanne bpfopen(dev, flag) 27847584Smccanne dev_t dev; 27947584Smccanne int flag; 28047584Smccanne { 28147584Smccanne register struct bpf_d *d; 28253947Smccanne 28347584Smccanne if (minor(dev) >= NBPFILTER) 28448932Smccanne return (ENXIO); 28547584Smccanne /* 28647584Smccanne * Each minor can be opened by only one process. If the requested 28747584Smccanne * minor is in use, return EBUSY. 28847584Smccanne */ 28947584Smccanne d = &bpf_dtab[minor(dev)]; 29053947Smccanne if (!D_ISFREE(d)) 29148932Smccanne return (EBUSY); 29247584Smccanne 29353947Smccanne /* Mark "free" and do most initialization. */ 29453947Smccanne bzero((char *)d, sizeof(*d)); 29553947Smccanne d->bd_bufsize = bpf_bufsize; 29653947Smccanne 29748932Smccanne return (0); 29847584Smccanne } 29947584Smccanne 30047584Smccanne /* 30147584Smccanne * Close the descriptor by detaching it from its interface, 30247584Smccanne * deallocating its buffers, and marking it free. 30347584Smccanne */ 30447584Smccanne /* ARGSUSED */ 30553947Smccanne int 30647584Smccanne bpfclose(dev, flag) 30747584Smccanne dev_t dev; 30847584Smccanne int flag; 30947584Smccanne { 31047584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 31153947Smccanne register int s; 31247584Smccanne 31347584Smccanne s = splimp(); 31447584Smccanne if (d->bd_bif) 31547584Smccanne bpf_detachd(d); 31647584Smccanne splx(s); 31753947Smccanne bpf_freed(d); 31847584Smccanne 31953947Smccanne return (0); 32047584Smccanne } 32147584Smccanne 32253947Smccanne /* 32353947Smccanne * Support for SunOS, which does not have tsleep. 32453947Smccanne */ 32551425Smccanne #if BSD < 199103 32651425Smccanne static 32751425Smccanne bpf_timeout(arg) 32851425Smccanne caddr_t arg; 32951425Smccanne { 33051425Smccanne struct bpf_d *d = (struct bpf_d *)arg; 33151425Smccanne d->bd_timedout = 1; 33251425Smccanne wakeup(arg); 33351425Smccanne } 33451425Smccanne 33553947Smccanne #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan) 33653947Smccanne 33753947Smccanne int 33853947Smccanne bpf_sleep(d) 33953947Smccanne register struct bpf_d *d; 34051425Smccanne { 34153947Smccanne register int rto = d->bd_rtout; 34253947Smccanne register int st; 34351425Smccanne 34453947Smccanne if (rto != 0) { 34551425Smccanne d->bd_timedout = 0; 34653947Smccanne timeout(bpf_timeout, (caddr_t)d, rto); 34751425Smccanne } 34853947Smccanne st = sleep((caddr_t)d, PRINET|PCATCH); 34953947Smccanne if (rto != 0) { 35053947Smccanne if (d->bd_timedout == 0) 35153947Smccanne untimeout(bpf_timeout, (caddr_t)d); 35253947Smccanne else if (st == 0) 35351425Smccanne return EWOULDBLOCK; 35451425Smccanne } 35553947Smccanne return (st != 0) ? EINTR : 0; 35651425Smccanne } 35753947Smccanne #else 35853947Smccanne #define BPF_SLEEP tsleep 35951425Smccanne #endif 36051425Smccanne 36147584Smccanne /* 36248932Smccanne * Rotate the packet buffers in descriptor d. Move the store buffer 36353947Smccanne * into the hold slot, and the free buffer into the store slot. 36448932Smccanne * Zero the length of the new store buffer. 36548932Smccanne */ 36648932Smccanne #define ROTATE_BUFFERS(d) \ 36748932Smccanne (d)->bd_hbuf = (d)->bd_sbuf; \ 36848932Smccanne (d)->bd_hlen = (d)->bd_slen; \ 36948932Smccanne (d)->bd_sbuf = (d)->bd_fbuf; \ 37048932Smccanne (d)->bd_slen = 0; \ 37153947Smccanne (d)->bd_fbuf = 0; 37248932Smccanne /* 37347584Smccanne * bpfread - read next chunk of packets from buffers 37447584Smccanne */ 37547584Smccanne int 37647584Smccanne bpfread(dev, uio) 37747584Smccanne dev_t dev; 37847584Smccanne register struct uio *uio; 37947584Smccanne { 38047584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 38147584Smccanne int error; 38247584Smccanne int s; 38347584Smccanne 38447584Smccanne /* 38553947Smccanne * Restrict application to use a buffer the same size as 38647584Smccanne * as kernel buffers. 38747584Smccanne */ 38848932Smccanne if (uio->uio_resid != d->bd_bufsize) 38949202Smccanne return (EINVAL); 39047584Smccanne 39147584Smccanne s = splimp(); 39247584Smccanne /* 39353947Smccanne * If the hold buffer is empty, then do a timed sleep, which 39453947Smccanne * ends when the timeout expires or when enough packets 39553947Smccanne * have arrived to fill the store buffer. 39647584Smccanne */ 39747584Smccanne while (d->bd_hbuf == 0) { 39848932Smccanne if (d->bd_immediate && d->bd_slen != 0) { 39947584Smccanne /* 40047584Smccanne * A packet(s) either arrived since the previous 40147584Smccanne * read or arrived while we were asleep. 40247584Smccanne * Rotate the buffers and return what's here. 40347584Smccanne */ 40448932Smccanne ROTATE_BUFFERS(d); 40547584Smccanne break; 40647584Smccanne } 40753947Smccanne error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf", 40853947Smccanne d->bd_rtout); 40948932Smccanne if (error == EINTR || error == ERESTART) { 41048932Smccanne splx(s); 41148932Smccanne return (error); 41247584Smccanne } 41348932Smccanne if (error == EWOULDBLOCK) { 41447584Smccanne /* 41547584Smccanne * On a timeout, return what's in the buffer, 41648932Smccanne * which may be nothing. If there is something 41748932Smccanne * in the store buffer, we can rotate the buffers. 41847584Smccanne */ 41947584Smccanne if (d->bd_hbuf) 42047584Smccanne /* 42153947Smccanne * We filled up the buffer in between 42247584Smccanne * getting the timeout and arriving 42347584Smccanne * here, so we don't need to rotate. 42447584Smccanne */ 42547584Smccanne break; 42647584Smccanne 42748932Smccanne if (d->bd_slen == 0) { 42847584Smccanne splx(s); 42948932Smccanne return (0); 43047584Smccanne } 43148932Smccanne ROTATE_BUFFERS(d); 43247584Smccanne break; 43347584Smccanne } 43447584Smccanne } 43547584Smccanne /* 43647584Smccanne * At this point, we know we have something in the hold slot. 43747584Smccanne */ 43847584Smccanne splx(s); 43953947Smccanne 44053947Smccanne /* 44147584Smccanne * Move data from hold buffer into user space. 44247584Smccanne * We know the entire buffer is transferred since 44348932Smccanne * we checked above that the read buffer is bpf_bufsize bytes. 44447584Smccanne */ 44553947Smccanne error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio); 44653947Smccanne 44747584Smccanne s = splimp(); 44848932Smccanne d->bd_fbuf = d->bd_hbuf; 44948932Smccanne d->bd_hbuf = 0; 45053947Smccanne d->bd_hlen = 0; 45147584Smccanne splx(s); 45253947Smccanne 45348932Smccanne return (error); 45447584Smccanne } 45547584Smccanne 45647584Smccanne 45747584Smccanne /* 45853947Smccanne * If there are processes sleeping on this descriptor, wake them up. 45947584Smccanne */ 46047584Smccanne static inline void 46147584Smccanne bpf_wakeup(d) 46247584Smccanne register struct bpf_d *d; 46347584Smccanne { 46448932Smccanne wakeup((caddr_t)d); 46553947Smccanne #if BSD >= 199103 46653947Smccanne selwakeup(&d->bd_sel); 46753947Smccanne /* XXX */ 46853947Smccanne d->bd_sel.si_pid = 0; 46953947Smccanne #else 47053947Smccanne if (d->bd_selproc) { 47153947Smccanne selwakeup(d->bd_selproc, (int)d->bd_selcoll); 47253947Smccanne d->bd_selcoll = 0; 47353947Smccanne d->bd_selproc = 0; 47453947Smccanne } 47553947Smccanne #endif 47647584Smccanne } 47747584Smccanne 47847584Smccanne int 47947584Smccanne bpfwrite(dev, uio) 48047584Smccanne dev_t dev; 48147584Smccanne struct uio *uio; 48247584Smccanne { 48347584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 48447584Smccanne struct ifnet *ifp; 48547584Smccanne struct mbuf *m; 48647584Smccanne int error, s; 48747584Smccanne static struct sockaddr dst; 48855289Smckusick int datlen; 48947584Smccanne 49047584Smccanne if (d->bd_bif == 0) 49148932Smccanne return (ENXIO); 49247584Smccanne 49347584Smccanne ifp = d->bd_bif->bif_ifp; 49447584Smccanne 49547584Smccanne if (uio->uio_resid == 0) 49648932Smccanne return (0); 49747584Smccanne 49855289Smckusick error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen); 49947584Smccanne if (error) 50048932Smccanne return (error); 50147584Smccanne 50255289Smckusick if (datlen > ifp->if_mtu) 50355289Smckusick return (EMSGSIZE); 50455289Smckusick 50547584Smccanne s = splnet(); 50651425Smccanne #if BSD >= 199103 50753947Smccanne error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0); 50851425Smccanne #else 50947584Smccanne error = (*ifp->if_output)(ifp, m, &dst); 51051425Smccanne #endif 51147584Smccanne splx(s); 51247584Smccanne /* 51353947Smccanne * The driver frees the mbuf. 51447584Smccanne */ 51548932Smccanne return (error); 51647584Smccanne } 51747584Smccanne 51847584Smccanne /* 51953947Smccanne * Reset a descriptor by flushing its packet buffer and clearing the 52053947Smccanne * receive and drop counts. Should be called at splimp. 52147584Smccanne */ 52247584Smccanne static void 52347584Smccanne reset_d(d) 52447584Smccanne struct bpf_d *d; 52547584Smccanne { 52647584Smccanne if (d->bd_hbuf) { 52747584Smccanne /* Free the hold buffer. */ 52847584Smccanne d->bd_fbuf = d->bd_hbuf; 52947584Smccanne d->bd_hbuf = 0; 53047584Smccanne } 53148932Smccanne d->bd_slen = 0; 53253947Smccanne d->bd_hlen = 0; 53347584Smccanne d->bd_rcount = 0; 53447584Smccanne d->bd_dcount = 0; 53547584Smccanne } 53647584Smccanne 53747584Smccanne /* 53847584Smccanne * FIONREAD Check for read packet available. 53947584Smccanne * SIOCGIFADDR Get interface address - convenient hook to driver. 54047584Smccanne * BIOCGBLEN Get buffer len [for read()]. 54147584Smccanne * BIOCSETF Set ethernet read filter. 54247584Smccanne * BIOCFLUSH Flush read packet buffer. 54347584Smccanne * BIOCPROMISC Put interface into promiscuous mode. 54449202Smccanne * BIOCGDLT Get link layer type. 54547584Smccanne * BIOCGETIF Get interface name. 54647584Smccanne * BIOCSETIF Set interface. 54747584Smccanne * BIOCSRTIMEOUT Set read timeout. 54847584Smccanne * BIOCGRTIMEOUT Get read timeout. 54947584Smccanne * BIOCGSTATS Get packet stats. 55047584Smccanne * BIOCIMMEDIATE Set immediate mode. 55153947Smccanne * BIOCVERSION Get filter language version. 55247584Smccanne */ 55347584Smccanne /* ARGSUSED */ 55447584Smccanne int 55547584Smccanne bpfioctl(dev, cmd, addr, flag) 55647584Smccanne dev_t dev; 55747584Smccanne int cmd; 55847584Smccanne caddr_t addr; 55947584Smccanne int flag; 56047584Smccanne { 56147584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 56247584Smccanne int s, error = 0; 56347584Smccanne 56447584Smccanne switch (cmd) { 56547584Smccanne 56647584Smccanne default: 56747584Smccanne error = EINVAL; 56847584Smccanne break; 56947584Smccanne 57047584Smccanne /* 57147584Smccanne * Check for read packet available. 57247584Smccanne */ 57347584Smccanne case FIONREAD: 57447584Smccanne { 57547584Smccanne int n; 57653947Smccanne 57747584Smccanne s = splimp(); 57848932Smccanne n = d->bd_slen; 57953947Smccanne if (d->bd_hbuf) 58048932Smccanne n += d->bd_hlen; 58147584Smccanne splx(s); 58247584Smccanne 58347584Smccanne *(int *)addr = n; 58447584Smccanne break; 58547584Smccanne } 58647584Smccanne 58747584Smccanne case SIOCGIFADDR: 58847584Smccanne { 58947584Smccanne struct ifnet *ifp; 59047584Smccanne 59147584Smccanne if (d->bd_bif == 0) 59247584Smccanne error = EINVAL; 59347584Smccanne else { 59447584Smccanne ifp = d->bd_bif->bif_ifp; 59553947Smccanne error = (*ifp->if_ioctl)(ifp, cmd, addr); 59647584Smccanne } 59747584Smccanne break; 59847584Smccanne } 59947584Smccanne 60047584Smccanne /* 60147584Smccanne * Get buffer len [for read()]. 60247584Smccanne */ 60347584Smccanne case BIOCGBLEN: 60448932Smccanne *(u_int *)addr = d->bd_bufsize; 60547584Smccanne break; 60647584Smccanne 60747584Smccanne /* 60853947Smccanne * Set buffer length. 60953947Smccanne */ 61053947Smccanne case BIOCSBLEN: 61153947Smccanne #if BSD < 199103 61253947Smccanne error = EINVAL; 61353947Smccanne #else 61453947Smccanne if (d->bd_bif != 0) 61553947Smccanne error = EINVAL; 61653947Smccanne else { 61753947Smccanne register u_int size = *(u_int *)addr; 61853947Smccanne 61953947Smccanne if (size > BPF_MAXBUFSIZE) 62053947Smccanne *(u_int *)addr = size = BPF_MAXBUFSIZE; 62153947Smccanne else if (size < BPF_MINBUFSIZE) 62253947Smccanne *(u_int *)addr = size = BPF_MINBUFSIZE; 62353947Smccanne d->bd_bufsize = size; 62453947Smccanne } 62553947Smccanne #endif 62653947Smccanne break; 62753947Smccanne 62853947Smccanne /* 62951425Smccanne * Set link layer read filter. 63047584Smccanne */ 63153947Smccanne case BIOCSETF: 63247584Smccanne error = bpf_setf(d, (struct bpf_program *)addr); 63347584Smccanne break; 63447584Smccanne 63547584Smccanne /* 63647584Smccanne * Flush read packet buffer. 63747584Smccanne */ 63847584Smccanne case BIOCFLUSH: 63947584Smccanne s = splimp(); 64047584Smccanne reset_d(d); 64147584Smccanne splx(s); 64247584Smccanne break; 64347584Smccanne 64447584Smccanne /* 64547584Smccanne * Put interface into promiscuous mode. 64647584Smccanne */ 64747584Smccanne case BIOCPROMISC: 64847584Smccanne if (d->bd_bif == 0) { 64947584Smccanne /* 65047584Smccanne * No interface attached yet. 65147584Smccanne */ 65247584Smccanne error = EINVAL; 65347584Smccanne break; 65447584Smccanne } 65547584Smccanne s = splimp(); 65647584Smccanne if (d->bd_promisc == 0) { 65747584Smccanne error = ifpromisc(d->bd_bif->bif_ifp, 1); 65851425Smccanne if (error == 0) 65951425Smccanne d->bd_promisc = 1; 66047584Smccanne } 66147584Smccanne splx(s); 66247584Smccanne break; 66347584Smccanne 66447584Smccanne /* 66547584Smccanne * Get device parameters. 66647584Smccanne */ 66749202Smccanne case BIOCGDLT: 66847584Smccanne if (d->bd_bif == 0) 66947584Smccanne error = EINVAL; 67047584Smccanne else 67149202Smccanne *(u_int *)addr = d->bd_bif->bif_dlt; 67247584Smccanne break; 67347584Smccanne 67447584Smccanne /* 67547584Smccanne * Set interface name. 67647584Smccanne */ 67747584Smccanne case BIOCGETIF: 67847584Smccanne if (d->bd_bif == 0) 67947584Smccanne error = EINVAL; 68047584Smccanne else 68147584Smccanne bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr); 68247584Smccanne break; 68347584Smccanne 68447584Smccanne /* 68547584Smccanne * Set interface. 68647584Smccanne */ 68747584Smccanne case BIOCSETIF: 68847584Smccanne error = bpf_setif(d, (struct ifreq *)addr); 68947584Smccanne break; 69047584Smccanne 69147584Smccanne /* 69247584Smccanne * Set read timeout. 69347584Smccanne */ 69453947Smccanne case BIOCSRTIMEOUT: 69547584Smccanne { 69647584Smccanne struct timeval *tv = (struct timeval *)addr; 69747584Smccanne u_long msec; 69847584Smccanne 69947584Smccanne /* Compute number of milliseconds. */ 70047584Smccanne msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; 70147584Smccanne /* Scale milliseconds to ticks. Assume hard 70247584Smccanne clock has millisecond or greater resolution 70347584Smccanne (i.e. tick >= 1000). For 10ms hardclock, 70447584Smccanne tick/1000 = 10, so rtout<-msec/10. */ 70547584Smccanne d->bd_rtout = msec / (tick / 1000); 70647584Smccanne break; 70747584Smccanne } 70847584Smccanne 70947584Smccanne /* 71047584Smccanne * Get read timeout. 71147584Smccanne */ 71253947Smccanne case BIOCGRTIMEOUT: 71347584Smccanne { 71447584Smccanne struct timeval *tv = (struct timeval *)addr; 71547584Smccanne u_long msec = d->bd_rtout; 71647584Smccanne 71747584Smccanne msec *= tick / 1000; 71847584Smccanne tv->tv_sec = msec / 1000; 71947584Smccanne tv->tv_usec = msec % 1000; 72047584Smccanne break; 72147584Smccanne } 72247584Smccanne 72347584Smccanne /* 72447584Smccanne * Get packet stats. 72547584Smccanne */ 72647584Smccanne case BIOCGSTATS: 72747584Smccanne { 72847584Smccanne struct bpf_stat *bs = (struct bpf_stat *)addr; 72947584Smccanne 73047584Smccanne bs->bs_recv = d->bd_rcount; 73147584Smccanne bs->bs_drop = d->bd_dcount; 73247584Smccanne break; 73347584Smccanne } 73447584Smccanne 73547584Smccanne /* 73647584Smccanne * Set immediate mode. 73747584Smccanne */ 73847584Smccanne case BIOCIMMEDIATE: 73947584Smccanne d->bd_immediate = *(u_int *)addr; 74047584Smccanne break; 74153947Smccanne 74253947Smccanne case BIOCVERSION: 74353947Smccanne { 74453947Smccanne struct bpf_version *bv = (struct bpf_version *)addr; 74553947Smccanne 74653947Smccanne bv->bv_major = BPF_MAJOR_VERSION; 74753947Smccanne bv->bv_minor = BPF_MINOR_VERSION; 74853947Smccanne break; 74953947Smccanne } 75047584Smccanne } 75148932Smccanne return (error); 75247584Smccanne } 75347584Smccanne 75453947Smccanne /* 75551425Smccanne * Set d's packet filter program to fp. If this file already has a filter, 75648932Smccanne * free it and replace it. Returns EINVAL for bogus requests. 75747584Smccanne */ 75847584Smccanne int 75947584Smccanne bpf_setf(d, fp) 76047584Smccanne struct bpf_d *d; 76147584Smccanne struct bpf_program *fp; 76247584Smccanne { 76348932Smccanne struct bpf_insn *fcode, *old; 76447584Smccanne u_int flen, size; 76547584Smccanne int s; 76647584Smccanne 76748932Smccanne old = d->bd_filter; 76847584Smccanne if (fp->bf_insns == 0) { 76947584Smccanne if (fp->bf_len != 0) 77048932Smccanne return (EINVAL); 77148932Smccanne s = splimp(); 77248967Smccanne d->bd_filter = 0; 77347584Smccanne reset_d(d); 77447584Smccanne splx(s); 77548967Smccanne if (old != 0) 77648932Smccanne free((caddr_t)old, M_DEVBUF); 77748932Smccanne return (0); 77847584Smccanne } 77947584Smccanne flen = fp->bf_len; 78048932Smccanne if (flen > BPF_MAXINSNS) 78148932Smccanne return (EINVAL); 78248932Smccanne 78347584Smccanne size = flen * sizeof(*fp->bf_insns); 78448932Smccanne fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK); 78550417Smccanne if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && 78650417Smccanne bpf_validate(fcode, (int)flen)) { 78748967Smccanne s = splimp(); 78848932Smccanne d->bd_filter = fcode; 78947584Smccanne reset_d(d); 79047584Smccanne splx(s); 79148967Smccanne if (old != 0) 79248932Smccanne free((caddr_t)old, M_DEVBUF); 79347584Smccanne 79448932Smccanne return (0); 79547584Smccanne } 79648932Smccanne free((caddr_t)fcode, M_DEVBUF); 79748932Smccanne return (EINVAL); 79847584Smccanne } 79947584Smccanne 80047584Smccanne /* 80153947Smccanne * Detach a file from its current interface (if attached at all) and attach 80253947Smccanne * to the interface indicated by the name stored in ifr. 80351425Smccanne * Return an errno or 0. 80447584Smccanne */ 80547584Smccanne static int 80647584Smccanne bpf_setif(d, ifr) 80747584Smccanne struct bpf_d *d; 80847584Smccanne struct ifreq *ifr; 80947584Smccanne { 81047584Smccanne struct bpf_if *bp; 81147584Smccanne char *cp; 81253947Smccanne int unit, s, error; 81347584Smccanne 81447584Smccanne /* 81547584Smccanne * Separate string into name part and unit number. Put a null 81653947Smccanne * byte at the end of the name part, and compute the number. 81747584Smccanne * If the a unit number is unspecified, the default is 0, 81848932Smccanne * as initialized above. XXX This should be common code. 81947584Smccanne */ 82047584Smccanne unit = 0; 82147584Smccanne cp = ifr->ifr_name; 82247584Smccanne cp[sizeof(ifr->ifr_name) - 1] = '\0'; 82347584Smccanne while (*cp++) { 82447584Smccanne if (*cp >= '0' && *cp <= '9') { 82547584Smccanne unit = *cp - '0'; 82647584Smccanne *cp++ = '\0'; 82747584Smccanne while (*cp) 82847584Smccanne unit = 10 * unit + *cp++ - '0'; 82947584Smccanne break; 83047584Smccanne } 83147584Smccanne } 83247584Smccanne /* 83347584Smccanne * Look through attached interfaces for the named one. 83447584Smccanne */ 83549202Smccanne for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { 83647584Smccanne struct ifnet *ifp = bp->bif_ifp; 83747584Smccanne 83853947Smccanne if (ifp == 0 || unit != ifp->if_unit 83947584Smccanne || strcmp(ifp->if_name, ifr->ifr_name) != 0) 84047584Smccanne continue; 84147584Smccanne /* 84253947Smccanne * We found the requested interface. 84347584Smccanne * If it's not up, return an error. 84453947Smccanne * Allocate the packet buffers if we need to. 84553947Smccanne * If we're already attached to requested interface, 84653947Smccanne * just flush the buffer. 84747584Smccanne */ 84847584Smccanne if ((ifp->if_flags & IFF_UP) == 0) 84948932Smccanne return (ENETDOWN); 85053947Smccanne 85153947Smccanne if (d->bd_sbuf == 0) { 85253947Smccanne error = bpf_allocbufs(d); 85353947Smccanne if (error != 0) 85453947Smccanne return (error); 85553947Smccanne } 85647584Smccanne s = splimp(); 85747584Smccanne if (bp != d->bd_bif) { 85847584Smccanne if (d->bd_bif) 85953947Smccanne /* 86048932Smccanne * Detach if attached to something else. 86147584Smccanne */ 86247584Smccanne bpf_detachd(d); 86347584Smccanne 86447584Smccanne bpf_attachd(d, bp); 86547584Smccanne } 86647584Smccanne reset_d(d); 86747584Smccanne splx(s); 86848932Smccanne return (0); 86947584Smccanne } 87047584Smccanne /* Not found. */ 87148932Smccanne return (ENXIO); 87247584Smccanne } 87347584Smccanne 87447584Smccanne /* 87551425Smccanne * Convert an interface name plus unit number of an ifp to a single 87651425Smccanne * name which is returned in the ifr. 87747584Smccanne */ 87847584Smccanne static void 87947584Smccanne bpf_ifname(ifp, ifr) 88047584Smccanne struct ifnet *ifp; 88147584Smccanne struct ifreq *ifr; 88247584Smccanne { 88347584Smccanne char *s = ifp->if_name; 88447584Smccanne char *d = ifr->ifr_name; 88547584Smccanne 88647584Smccanne while (*d++ = *s++) 88753947Smccanne continue; 88848932Smccanne /* XXX Assume that unit number is less than 10. */ 88947584Smccanne *d++ = ifp->if_unit + '0'; 89047584Smccanne *d = '\0'; 89147584Smccanne } 89247584Smccanne 89347584Smccanne /* 89451425Smccanne * The new select interface passes down the proc pointer; the old select 89551425Smccanne * stubs had to grab it out of the user struct. This glue allows either case. 89651425Smccanne */ 89751425Smccanne #if BSD >= 199103 89851425Smccanne #define bpf_select bpfselect 89951425Smccanne #else 90051425Smccanne int 90151425Smccanne bpfselect(dev, rw) 90251425Smccanne register dev_t dev; 90351425Smccanne int rw; 90451425Smccanne { 90553947Smccanne return (bpf_select(dev, rw, u.u_procp)); 90651425Smccanne } 90751425Smccanne #endif 90851425Smccanne 90951425Smccanne /* 91047584Smccanne * Support for select() system call 91147584Smccanne * Inspired by the code in tty.c for the same purpose. 91247584Smccanne * 91353947Smccanne * Return true iff the specific operation will not block indefinitely. 91453947Smccanne * Otherwise, return false but make a note that a selwakeup() must be done. 91547584Smccanne */ 91647584Smccanne int 91751425Smccanne bpf_select(dev, rw, p) 91847584Smccanne register dev_t dev; 91947584Smccanne int rw; 92048932Smccanne struct proc *p; 92147584Smccanne { 92247584Smccanne register struct bpf_d *d; 92347584Smccanne register int s; 92453947Smccanne 92547584Smccanne if (rw != FREAD) 92648932Smccanne return (0); 92747584Smccanne /* 92847584Smccanne * An imitation of the FIONREAD ioctl code. 92947584Smccanne */ 93047584Smccanne d = &bpf_dtab[minor(dev)]; 93153947Smccanne 93247584Smccanne s = splimp(); 93349723Smccanne if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) { 93447584Smccanne /* 93547584Smccanne * There is data waiting. 93647584Smccanne */ 93747584Smccanne splx(s); 93848932Smccanne return (1); 93947584Smccanne } 94053947Smccanne #if BSD >= 199103 94153947Smccanne selrecord(p, &d->bd_sel); 94253947Smccanne #else 94347584Smccanne /* 94447584Smccanne * No data ready. If there's already a select() waiting on this 94553947Smccanne * minor device then this is a collision. This shouldn't happen 94647584Smccanne * because minors really should not be shared, but if a process 94747584Smccanne * forks while one of these is open, it is possible that both 94847584Smccanne * processes could select on the same descriptor. 94947584Smccanne */ 95053947Smccanne if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait) 95153947Smccanne d->bd_selcoll = 1; 95253947Smccanne else 95353947Smccanne d->bd_selproc = p; 95453947Smccanne #endif 95553947Smccanne splx(s); 95648932Smccanne return (0); 95747584Smccanne } 95847584Smccanne 95947584Smccanne /* 96053947Smccanne * Incoming linkage from device drivers. Process the packet pkt, of length 96153947Smccanne * pktlen, which is stored in a contiguous buffer. The packet is parsed 96253947Smccanne * by each process' filter, and if accepted, stashed into the corresponding 96353947Smccanne * buffer. 96447584Smccanne */ 96547584Smccanne void 96648932Smccanne bpf_tap(arg, pkt, pktlen) 96747584Smccanne caddr_t arg; 96848932Smccanne register u_char *pkt; 96948932Smccanne register u_int pktlen; 97047584Smccanne { 97147584Smccanne struct bpf_if *bp; 97247584Smccanne register struct bpf_d *d; 97347584Smccanne register u_int slen; 97447584Smccanne /* 97547584Smccanne * Note that the ipl does not have to be raised at this point. 97647584Smccanne * The only problem that could arise here is that if two different 97747584Smccanne * interfaces shared any data. This is not the case. 97847584Smccanne */ 97947584Smccanne bp = (struct bpf_if *)arg; 98047584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 98147584Smccanne ++d->bd_rcount; 98249202Smccanne slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 98347584Smccanne if (slen != 0) 98449202Smccanne catchpacket(d, pkt, pktlen, slen, bcopy); 98547584Smccanne } 98647584Smccanne } 98747584Smccanne 98847584Smccanne /* 98947584Smccanne * Copy data from an mbuf chain into a buffer. This code is derived 99047584Smccanne * from m_copydata in sys/uipc_mbuf.c. 99147584Smccanne */ 99247584Smccanne static void 99349202Smccanne bpf_mcopy(src, dst, len) 99447584Smccanne u_char *src; 99547584Smccanne u_char *dst; 99647584Smccanne register int len; 99747584Smccanne { 99847584Smccanne register struct mbuf *m = (struct mbuf *)src; 99947584Smccanne register unsigned count; 100047584Smccanne 100147584Smccanne while (len > 0) { 100247584Smccanne if (m == 0) 100349202Smccanne panic("bpf_mcopy"); 100455065Spendry count = min(m->m_len, len); 100549202Smccanne bcopy(mtod(m, caddr_t), (caddr_t)dst, count); 100649202Smccanne m = m->m_next; 100749202Smccanne dst += count; 100847584Smccanne len -= count; 100947584Smccanne } 101047584Smccanne } 101147584Smccanne 101247584Smccanne /* 101353947Smccanne * Incoming linkage from device drivers, when packet is in an mbuf chain. 101447584Smccanne */ 101547584Smccanne void 101649202Smccanne bpf_mtap(arg, m) 101747584Smccanne caddr_t arg; 101849202Smccanne struct mbuf *m; 101947584Smccanne { 102047584Smccanne struct bpf_if *bp = (struct bpf_if *)arg; 102147584Smccanne struct bpf_d *d; 102249202Smccanne u_int pktlen, slen; 102349202Smccanne struct mbuf *m0; 102447584Smccanne 102548932Smccanne pktlen = 0; 102651425Smccanne for (m0 = m; m0 != 0; m0 = m0->m_next) 102749202Smccanne pktlen += m0->m_len; 102849723Smccanne 102947584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 103047584Smccanne ++d->bd_rcount; 103149202Smccanne slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); 103247584Smccanne if (slen != 0) 103349202Smccanne catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); 103447584Smccanne } 103547584Smccanne } 103647584Smccanne 103747584Smccanne /* 103849202Smccanne * Move the packet data from interface memory (pkt) into the 103947584Smccanne * store buffer. Return 1 if it's time to wakeup a listener (buffer full), 104053947Smccanne * otherwise 0. "copy" is the routine called to do the actual data 104151425Smccanne * transfer. bcopy is passed in to copy contiguous chunks, while 104251425Smccanne * bpf_mcopy is passed in to copy mbuf chains. In the latter case, 104351425Smccanne * pkt is really an mbuf. 104447584Smccanne */ 104547584Smccanne static void 104648932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn) 104748932Smccanne register struct bpf_d *d; 104848932Smccanne register u_char *pkt; 104948932Smccanne register u_int pktlen, snaplen; 105048932Smccanne register void (*cpfn)(); 105147584Smccanne { 105248932Smccanne register struct bpf_hdr *hp; 105348932Smccanne register int totlen, curlen; 105448932Smccanne register int hdrlen = d->bd_bif->bif_hdrlen; 105547584Smccanne /* 105647584Smccanne * Figure out how many bytes to move. If the packet is 105747584Smccanne * greater or equal to the snapshot length, transfer that 105847584Smccanne * much. Otherwise, transfer the whole packet (unless 105948932Smccanne * we hit the buffer size limit). 106047584Smccanne */ 106155065Spendry totlen = hdrlen + min(snaplen, pktlen); 106250082Smccanne if (totlen > d->bd_bufsize) 106350082Smccanne totlen = d->bd_bufsize; 106447584Smccanne 106547584Smccanne /* 106647584Smccanne * Round up the end of the previous packet to the next longword. 106747584Smccanne */ 106848932Smccanne curlen = BPF_WORDALIGN(d->bd_slen); 106948932Smccanne if (curlen + totlen > d->bd_bufsize) { 107047584Smccanne /* 107147584Smccanne * This packet will overflow the storage buffer. 107248932Smccanne * Rotate the buffers if we can, then wakeup any 107348932Smccanne * pending reads. 107447584Smccanne */ 107547584Smccanne if (d->bd_fbuf == 0) { 107653947Smccanne /* 107753947Smccanne * We haven't completed the previous read yet, 107848932Smccanne * so drop the packet. 107947584Smccanne */ 108047584Smccanne ++d->bd_dcount; 108147584Smccanne return; 108247584Smccanne } 108348932Smccanne ROTATE_BUFFERS(d); 108447584Smccanne bpf_wakeup(d); 108548932Smccanne curlen = 0; 108647584Smccanne } 108753947Smccanne else if (d->bd_immediate) 108847584Smccanne /* 108947584Smccanne * Immediate mode is set. A packet arrived so any 109047584Smccanne * reads should be woken up. 109147584Smccanne */ 109247584Smccanne bpf_wakeup(d); 109348932Smccanne 109447584Smccanne /* 109547584Smccanne * Append the bpf header. 109647584Smccanne */ 109748932Smccanne hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); 109851425Smccanne #if BSD >= 199103 109947584Smccanne microtime(&hp->bh_tstamp); 110053947Smccanne #elif defined(sun) 110153947Smccanne uniqtime(&hp->bh_tstamp); 110247584Smccanne #else 110347584Smccanne hp->bh_tstamp = time; 110447584Smccanne #endif 110548932Smccanne hp->bh_datalen = pktlen; 110647584Smccanne hp->bh_hdrlen = hdrlen; 110747584Smccanne /* 110848932Smccanne * Copy the packet data into the store buffer and update its length. 110947584Smccanne */ 111048932Smccanne (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); 111148932Smccanne d->bd_slen = curlen + totlen; 111247584Smccanne } 111347584Smccanne 111453947Smccanne /* 111547584Smccanne * Initialize all nonzero fields of a descriptor. 111647584Smccanne */ 111747584Smccanne static int 111853947Smccanne bpf_allocbufs(d) 111947584Smccanne register struct bpf_d *d; 112047584Smccanne { 112148932Smccanne d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 112248932Smccanne if (d->bd_fbuf == 0) 112348932Smccanne return (ENOBUFS); 112447584Smccanne 112548932Smccanne d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 112648932Smccanne if (d->bd_sbuf == 0) { 112748932Smccanne free(d->bd_fbuf, M_DEVBUF); 112848932Smccanne return (ENOBUFS); 112947584Smccanne } 113048932Smccanne d->bd_slen = 0; 113148932Smccanne d->bd_hlen = 0; 113248932Smccanne return (0); 113347584Smccanne } 113447584Smccanne 113547584Smccanne /* 113651425Smccanne * Free buffers currently in use by a descriptor. 113751425Smccanne * Called on close. 113847584Smccanne */ 113953947Smccanne static void 114051425Smccanne bpf_freed(d) 114151425Smccanne register struct bpf_d *d; 114251425Smccanne { 114351425Smccanne /* 114451425Smccanne * We don't need to lock out interrupts since this descriptor has 114553947Smccanne * been detached from its interface and it yet hasn't been marked 114651425Smccanne * free. 114751425Smccanne */ 114853947Smccanne if (d->bd_sbuf != 0) { 114953947Smccanne free(d->bd_sbuf, M_DEVBUF); 115053947Smccanne if (d->bd_hbuf != 0) 115153947Smccanne free(d->bd_hbuf, M_DEVBUF); 115253947Smccanne if (d->bd_fbuf != 0) 115353947Smccanne free(d->bd_fbuf, M_DEVBUF); 115453947Smccanne } 115551425Smccanne if (d->bd_filter) 115651425Smccanne free((caddr_t)d->bd_filter, M_DEVBUF); 115753947Smccanne 115851425Smccanne D_MARKFREE(d); 115951425Smccanne } 116051425Smccanne 116151425Smccanne /* 116251425Smccanne * Attach an interface to bpf. driverp is a pointer to a (struct bpf_if *) 116351425Smccanne * in the driver's softc; dlt is the link layer type; hdrlen is the fixed 116451425Smccanne * size of the link header (variable length headers not yet supported). 116551425Smccanne */ 116647584Smccanne void 116749202Smccanne bpfattach(driverp, ifp, dlt, hdrlen) 116847584Smccanne caddr_t *driverp; 116947584Smccanne struct ifnet *ifp; 117049202Smccanne u_int dlt, hdrlen; 117147584Smccanne { 117247584Smccanne struct bpf_if *bp; 117347584Smccanne int i; 117451425Smccanne #if BSD < 199103 117551425Smccanne static struct bpf_if bpf_ifs[NBPFILTER]; 117651425Smccanne static int bpfifno; 117747584Smccanne 117851425Smccanne bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0; 117951425Smccanne #else 118049202Smccanne bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT); 118151425Smccanne #endif 118249202Smccanne if (bp == 0) 118349202Smccanne panic("bpfattach"); 118447584Smccanne 118547584Smccanne bp->bif_dlist = 0; 118647584Smccanne bp->bif_driverp = (struct bpf_if **)driverp; 118747584Smccanne bp->bif_ifp = ifp; 118849202Smccanne bp->bif_dlt = dlt; 118947584Smccanne 119049202Smccanne bp->bif_next = bpf_iflist; 119149202Smccanne bpf_iflist = bp; 119249202Smccanne 119348932Smccanne *bp->bif_driverp = 0; 119448932Smccanne 119547584Smccanne /* 119647584Smccanne * Compute the length of the bpf header. This is not necessarily 119753947Smccanne * equal to SIZEOF_BPF_HDR because we want to insert spacing such 119853947Smccanne * that the network layer header begins on a longword boundary (for 119947584Smccanne * performance reasons and to alleviate alignment restrictions). 120047584Smccanne */ 120149202Smccanne bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; 120247584Smccanne 120347584Smccanne /* 120447584Smccanne * Mark all the descriptors free if this hasn't been done. 120547584Smccanne */ 120647584Smccanne if (!D_ISFREE(&bpf_dtab[0])) 120747584Smccanne for (i = 0; i < NBPFILTER; ++i) 120847584Smccanne D_MARKFREE(&bpf_dtab[i]); 120947584Smccanne 121047584Smccanne printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); 121147584Smccanne } 121247584Smccanne 121351425Smccanne #if BSD >= 199103 121448967Smccanne /* XXX This routine belongs in net/if.c. */ 121548932Smccanne /* 121653947Smccanne * Set/clear promiscuous mode on interface ifp based on the truth value 121748932Smccanne * of pswitch. The calls are reference counted so that only the first 121853947Smccanne * "on" request actually has an effect, as does the final "off" request. 121953947Smccanne * Results are undefined if the "off" and "on" requests are not matched. 122048932Smccanne */ 122148932Smccanne int 122248932Smccanne ifpromisc(ifp, pswitch) 122348932Smccanne struct ifnet *ifp; 122448932Smccanne int pswitch; 122548932Smccanne { 122649726Smccanne struct ifreq ifr; 122753947Smccanne /* 122848932Smccanne * If the device is not configured up, we cannot put it in 122948932Smccanne * promiscuous mode. 123048932Smccanne */ 123148932Smccanne if ((ifp->if_flags & IFF_UP) == 0) 123248932Smccanne return (ENETDOWN); 123348932Smccanne 123448932Smccanne if (pswitch) { 123548932Smccanne if (ifp->if_pcount++ != 0) 123648932Smccanne return (0); 123748932Smccanne ifp->if_flags |= IFF_PROMISC; 123848932Smccanne } else { 123948932Smccanne if (--ifp->if_pcount > 0) 124048932Smccanne return (0); 124148932Smccanne ifp->if_flags &= ~IFF_PROMISC; 124248932Smccanne } 124349726Smccanne ifr.ifr_flags = ifp->if_flags; 124449726Smccanne return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); 124548932Smccanne } 124651425Smccanne #endif 124748932Smccanne 124851425Smccanne #if BSD < 199103 124951425Smccanne /* 125051425Smccanne * Allocate some memory for bpf. This is temporary SunOS support, and 125153947Smccanne * is admittedly a hack. 125251425Smccanne * If resources unavaiable, return 0. 125351425Smccanne */ 125451425Smccanne static caddr_t 125551425Smccanne bpf_alloc(size, canwait) 125651425Smccanne register int size; 125751425Smccanne register int canwait; 125851425Smccanne { 125951425Smccanne register struct mbuf *m; 126051425Smccanne 126151425Smccanne if ((unsigned)size > (MCLBYTES-8)) 126251425Smccanne return 0; 126351425Smccanne 126451425Smccanne MGET(m, canwait, MT_DATA); 126551425Smccanne if (m == 0) 126651425Smccanne return 0; 126751425Smccanne if ((unsigned)size > (MLEN-8)) { 126851425Smccanne MCLGET(m); 126951425Smccanne if (m->m_len != MCLBYTES) { 127051425Smccanne m_freem(m); 127151425Smccanne return 0; 127251425Smccanne } 127351425Smccanne } 127451425Smccanne *mtod(m, struct mbuf **) = m; 127551425Smccanne return mtod(m, caddr_t) + 8; 127651425Smccanne } 127751425Smccanne #endif 127851425Smccanne #endif 1279