151440Smccanne /* 2*63207Sbostic * Copyright (c) 1990, 1991, 1993 3*63207Sbostic * The Regents of the University of California. 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*63207Sbostic * @(#)bpf.c 8.1 (Berkeley) 06/10/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 8659122Storek #if BSD >= 199207 8759122Storek /* 8859122Storek * bpfilterattach() is called at boot time in new systems. We do 8959122Storek * nothing here since old systems will not call this. 9059122Storek */ 9159122Storek /* ARGSUSED */ 9259122Storek void 9359122Storek bpfilterattach(n) 9459122Storek int n; 9559122Storek { 9659122Storek } 9759122Storek #endif 9859122Storek 9961337Sbostic static int bpf_allocbufs __P((struct bpf_d *)); 10061337Sbostic static int bpf_allocbufs __P((struct bpf_d *)); 10161337Sbostic static void bpf_freed __P((struct bpf_d *)); 10261337Sbostic static void bpf_freed __P((struct bpf_d *)); 10361337Sbostic static void bpf_ifname __P((struct ifnet *, struct ifreq *)); 10461337Sbostic static void bpf_ifname __P((struct ifnet *, struct ifreq *)); 10561337Sbostic static void bpf_mcopy __P((void *, void *, u_int)); 10661337Sbostic static int bpf_movein __P((struct uio *, int, 10761337Sbostic struct mbuf **, struct sockaddr *, int *)); 10861337Sbostic static int bpf_setif __P((struct bpf_d *, struct ifreq *)); 10961337Sbostic static int bpf_setif __P((struct bpf_d *, struct ifreq *)); 11061337Sbostic static inline void 11161337Sbostic bpf_wakeup __P((struct bpf_d *)); 11261337Sbostic static void catchpacket __P((struct bpf_d *, u_char *, u_int, 11361337Sbostic u_int, void (*)(void *, void *, u_int))); 11461337Sbostic static void reset_d __P((struct bpf_d *)); 11547584Smccanne 11647584Smccanne static int 11755289Smckusick bpf_movein(uio, linktype, mp, sockp, datlen) 11847584Smccanne register struct uio *uio; 11955289Smckusick int linktype, *datlen; 12047584Smccanne register struct mbuf **mp; 12147584Smccanne register struct sockaddr *sockp; 12247584Smccanne { 12347584Smccanne struct mbuf *m; 12447584Smccanne int error; 12547584Smccanne int len; 12647584Smccanne int hlen; 12747584Smccanne 12847584Smccanne /* 12947584Smccanne * Build a sockaddr based on the data link layer type. 13047584Smccanne * We do this at this level because the ethernet header 13147584Smccanne * is copied directly into the data field of the sockaddr. 13247584Smccanne * In the case of SLIP, there is no header and the packet 13347584Smccanne * is forwarded as is. 13447584Smccanne * Also, we are careful to leave room at the front of the mbuf 13547584Smccanne * for the link level header. 13647584Smccanne */ 13747584Smccanne switch (linktype) { 13853947Smccanne 13947584Smccanne case DLT_SLIP: 14047584Smccanne sockp->sa_family = AF_INET; 14147584Smccanne hlen = 0; 14247584Smccanne break; 14347584Smccanne 14447584Smccanne case DLT_EN10MB: 14547584Smccanne sockp->sa_family = AF_UNSPEC; 14647584Smccanne /* XXX Would MAXLINKHDR be better? */ 14747584Smccanne hlen = sizeof(struct ether_header); 14847584Smccanne break; 14947584Smccanne 15053947Smccanne case DLT_FDDI: 15147584Smccanne sockp->sa_family = AF_UNSPEC; 15247584Smccanne /* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */ 15347584Smccanne hlen = 24; 15447584Smccanne break; 15547584Smccanne 15653947Smccanne case DLT_NULL: 15753947Smccanne sockp->sa_family = AF_UNSPEC; 15853947Smccanne hlen = 0; 15953947Smccanne break; 16053947Smccanne 16147584Smccanne default: 16248932Smccanne return (EIO); 16347584Smccanne } 16447584Smccanne 16547584Smccanne len = uio->uio_resid; 16655289Smckusick *datlen = len - hlen; 16747584Smccanne if ((unsigned)len > MCLBYTES) 16848932Smccanne return (EIO); 16947584Smccanne 17047584Smccanne MGET(m, M_WAIT, MT_DATA); 17147584Smccanne if (m == 0) 17248932Smccanne return (ENOBUFS); 17347584Smccanne if (len > MLEN) { 17451425Smccanne #if BSD >= 199103 17548932Smccanne MCLGET(m, M_WAIT); 17648932Smccanne if ((m->m_flags & M_EXT) == 0) { 17751425Smccanne #else 17851425Smccanne MCLGET(m); 17953947Smccanne if (m->m_len != MCLBYTES) { 18051425Smccanne #endif 18153947Smccanne error = ENOBUFS; 18247584Smccanne goto bad; 18347584Smccanne } 18447584Smccanne } 18547584Smccanne m->m_len = len; 18647584Smccanne *mp = m; 18747584Smccanne /* 18847584Smccanne * Make room for link header. 18947584Smccanne */ 19053947Smccanne if (hlen != 0) { 19147584Smccanne m->m_len -= hlen; 19251425Smccanne #if BSD >= 199103 19348932Smccanne m->m_data += hlen; /* XXX */ 19451425Smccanne #else 19551425Smccanne m->m_off += hlen; 19651425Smccanne #endif 19753947Smccanne error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio); 19847584Smccanne if (error) 19947584Smccanne goto bad; 20047584Smccanne } 20153947Smccanne error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio); 20253947Smccanne if (!error) 20348932Smccanne return (0); 20447584Smccanne bad: 20547584Smccanne m_freem(m); 20648932Smccanne return (error); 20747584Smccanne } 20847584Smccanne 20947584Smccanne /* 21051425Smccanne * Attach file to the bpf interface, i.e. make d listen on bp. 21147584Smccanne * Must be called at splimp. 21247584Smccanne */ 21347584Smccanne static void 21447584Smccanne bpf_attachd(d, bp) 21547584Smccanne struct bpf_d *d; 21647584Smccanne struct bpf_if *bp; 21747584Smccanne { 21851425Smccanne /* 21951425Smccanne * Point d at bp, and add d to the interface's list of listeners. 22051425Smccanne * Finally, point the driver's bpf cookie at the interface so 22151425Smccanne * it will divert packets to bpf. 22251425Smccanne */ 22347584Smccanne d->bd_bif = bp; 22447584Smccanne d->bd_next = bp->bif_dlist; 22547584Smccanne bp->bif_dlist = d; 22647584Smccanne 22747584Smccanne *bp->bif_driverp = bp; 22847584Smccanne } 22947584Smccanne 23051425Smccanne /* 23151425Smccanne * Detach a file from its interface. 23251425Smccanne */ 23347584Smccanne static void 23447584Smccanne bpf_detachd(d) 23547584Smccanne struct bpf_d *d; 23647584Smccanne { 23747584Smccanne struct bpf_d **p; 23847584Smccanne struct bpf_if *bp; 23947584Smccanne 24047584Smccanne bp = d->bd_bif; 24147584Smccanne /* 24247584Smccanne * Check if this descriptor had requested promiscuous mode. 24347584Smccanne * If so, turn it off. 24447584Smccanne */ 24547584Smccanne if (d->bd_promisc) { 24647584Smccanne d->bd_promisc = 0; 24747584Smccanne if (ifpromisc(bp->bif_ifp, 0)) 24847584Smccanne /* 24947584Smccanne * Something is really wrong if we were able to put 25047584Smccanne * the driver into promiscuous mode, but can't 25147584Smccanne * take it out. 25247584Smccanne */ 25351425Smccanne panic("bpf: ifpromisc failed"); 25447584Smccanne } 25551425Smccanne /* Remove d from the interface's descriptor list. */ 25647584Smccanne p = &bp->bif_dlist; 25747584Smccanne while (*p != d) { 25847584Smccanne p = &(*p)->bd_next; 25947584Smccanne if (*p == 0) 26047584Smccanne panic("bpf_detachd: descriptor not in list"); 26147584Smccanne } 26247584Smccanne *p = (*p)->bd_next; 26347584Smccanne if (bp->bif_dlist == 0) 26447584Smccanne /* 26547584Smccanne * Let the driver know that there are no more listeners. 26647584Smccanne */ 26747584Smccanne *d->bd_bif->bif_driverp = 0; 26847584Smccanne d->bd_bif = 0; 26947584Smccanne } 27047584Smccanne 27147584Smccanne 27247584Smccanne /* 27353947Smccanne * Mark a descriptor free by making it point to itself. 27447584Smccanne * This is probably cheaper than marking with a constant since 27547584Smccanne * the address should be in a register anyway. 27647584Smccanne */ 27747584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next) 27847584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d)) 27947584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0) 28047584Smccanne 28147584Smccanne /* 28253947Smccanne * Open ethernet device. Returns ENXIO for illegal minor device number, 28353947Smccanne * EBUSY if file is open by another process. 28447584Smccanne */ 28547584Smccanne /* ARGSUSED */ 28647584Smccanne int 28747584Smccanne bpfopen(dev, flag) 28847584Smccanne dev_t dev; 28947584Smccanne int flag; 29047584Smccanne { 29147584Smccanne register struct bpf_d *d; 29253947Smccanne 29347584Smccanne if (minor(dev) >= NBPFILTER) 29448932Smccanne return (ENXIO); 29547584Smccanne /* 29647584Smccanne * Each minor can be opened by only one process. If the requested 29747584Smccanne * minor is in use, return EBUSY. 29847584Smccanne */ 29947584Smccanne d = &bpf_dtab[minor(dev)]; 30053947Smccanne if (!D_ISFREE(d)) 30148932Smccanne return (EBUSY); 30247584Smccanne 30353947Smccanne /* Mark "free" and do most initialization. */ 30453947Smccanne bzero((char *)d, sizeof(*d)); 30553947Smccanne d->bd_bufsize = bpf_bufsize; 30653947Smccanne 30748932Smccanne return (0); 30847584Smccanne } 30947584Smccanne 31047584Smccanne /* 31147584Smccanne * Close the descriptor by detaching it from its interface, 31247584Smccanne * deallocating its buffers, and marking it free. 31347584Smccanne */ 31447584Smccanne /* ARGSUSED */ 31553947Smccanne int 31647584Smccanne bpfclose(dev, flag) 31747584Smccanne dev_t dev; 31847584Smccanne int flag; 31947584Smccanne { 32047584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 32153947Smccanne register int s; 32247584Smccanne 32347584Smccanne s = splimp(); 32447584Smccanne if (d->bd_bif) 32547584Smccanne bpf_detachd(d); 32647584Smccanne splx(s); 32753947Smccanne bpf_freed(d); 32847584Smccanne 32953947Smccanne return (0); 33047584Smccanne } 33147584Smccanne 33253947Smccanne /* 33353947Smccanne * Support for SunOS, which does not have tsleep. 33453947Smccanne */ 33551425Smccanne #if BSD < 199103 33651425Smccanne static 33751425Smccanne bpf_timeout(arg) 33851425Smccanne caddr_t arg; 33951425Smccanne { 34051425Smccanne struct bpf_d *d = (struct bpf_d *)arg; 34151425Smccanne d->bd_timedout = 1; 34251425Smccanne wakeup(arg); 34351425Smccanne } 34451425Smccanne 34553947Smccanne #define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan) 34653947Smccanne 34753947Smccanne int 34853947Smccanne bpf_sleep(d) 34953947Smccanne register struct bpf_d *d; 35051425Smccanne { 35153947Smccanne register int rto = d->bd_rtout; 35253947Smccanne register int st; 35351425Smccanne 35453947Smccanne if (rto != 0) { 35551425Smccanne d->bd_timedout = 0; 35653947Smccanne timeout(bpf_timeout, (caddr_t)d, rto); 35751425Smccanne } 35853947Smccanne st = sleep((caddr_t)d, PRINET|PCATCH); 35953947Smccanne if (rto != 0) { 36053947Smccanne if (d->bd_timedout == 0) 36153947Smccanne untimeout(bpf_timeout, (caddr_t)d); 36253947Smccanne else if (st == 0) 36351425Smccanne return EWOULDBLOCK; 36451425Smccanne } 36553947Smccanne return (st != 0) ? EINTR : 0; 36651425Smccanne } 36753947Smccanne #else 36853947Smccanne #define BPF_SLEEP tsleep 36951425Smccanne #endif 37051425Smccanne 37147584Smccanne /* 37248932Smccanne * Rotate the packet buffers in descriptor d. Move the store buffer 37353947Smccanne * into the hold slot, and the free buffer into the store slot. 37448932Smccanne * Zero the length of the new store buffer. 37548932Smccanne */ 37648932Smccanne #define ROTATE_BUFFERS(d) \ 37748932Smccanne (d)->bd_hbuf = (d)->bd_sbuf; \ 37848932Smccanne (d)->bd_hlen = (d)->bd_slen; \ 37948932Smccanne (d)->bd_sbuf = (d)->bd_fbuf; \ 38048932Smccanne (d)->bd_slen = 0; \ 38153947Smccanne (d)->bd_fbuf = 0; 38248932Smccanne /* 38347584Smccanne * bpfread - read next chunk of packets from buffers 38447584Smccanne */ 38547584Smccanne int 38647584Smccanne bpfread(dev, uio) 38747584Smccanne dev_t dev; 38847584Smccanne register struct uio *uio; 38947584Smccanne { 39047584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 39147584Smccanne int error; 39247584Smccanne int s; 39347584Smccanne 39447584Smccanne /* 39553947Smccanne * Restrict application to use a buffer the same size as 39647584Smccanne * as kernel buffers. 39747584Smccanne */ 39848932Smccanne if (uio->uio_resid != d->bd_bufsize) 39949202Smccanne return (EINVAL); 40047584Smccanne 40147584Smccanne s = splimp(); 40247584Smccanne /* 40353947Smccanne * If the hold buffer is empty, then do a timed sleep, which 40453947Smccanne * ends when the timeout expires or when enough packets 40553947Smccanne * have arrived to fill the store buffer. 40647584Smccanne */ 40747584Smccanne while (d->bd_hbuf == 0) { 40848932Smccanne if (d->bd_immediate && d->bd_slen != 0) { 40947584Smccanne /* 41047584Smccanne * A packet(s) either arrived since the previous 41147584Smccanne * read or arrived while we were asleep. 41247584Smccanne * Rotate the buffers and return what's here. 41347584Smccanne */ 41448932Smccanne ROTATE_BUFFERS(d); 41547584Smccanne break; 41647584Smccanne } 41753947Smccanne error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf", 41853947Smccanne d->bd_rtout); 41948932Smccanne if (error == EINTR || error == ERESTART) { 42048932Smccanne splx(s); 42148932Smccanne return (error); 42247584Smccanne } 42348932Smccanne if (error == EWOULDBLOCK) { 42447584Smccanne /* 42547584Smccanne * On a timeout, return what's in the buffer, 42648932Smccanne * which may be nothing. If there is something 42748932Smccanne * in the store buffer, we can rotate the buffers. 42847584Smccanne */ 42947584Smccanne if (d->bd_hbuf) 43047584Smccanne /* 43153947Smccanne * We filled up the buffer in between 43247584Smccanne * getting the timeout and arriving 43347584Smccanne * here, so we don't need to rotate. 43447584Smccanne */ 43547584Smccanne break; 43647584Smccanne 43748932Smccanne if (d->bd_slen == 0) { 43847584Smccanne splx(s); 43948932Smccanne return (0); 44047584Smccanne } 44148932Smccanne ROTATE_BUFFERS(d); 44247584Smccanne break; 44347584Smccanne } 44447584Smccanne } 44547584Smccanne /* 44647584Smccanne * At this point, we know we have something in the hold slot. 44747584Smccanne */ 44847584Smccanne splx(s); 44953947Smccanne 45053947Smccanne /* 45147584Smccanne * Move data from hold buffer into user space. 45247584Smccanne * We know the entire buffer is transferred since 45348932Smccanne * we checked above that the read buffer is bpf_bufsize bytes. 45447584Smccanne */ 45553947Smccanne error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio); 45653947Smccanne 45747584Smccanne s = splimp(); 45848932Smccanne d->bd_fbuf = d->bd_hbuf; 45948932Smccanne d->bd_hbuf = 0; 46053947Smccanne d->bd_hlen = 0; 46147584Smccanne splx(s); 46253947Smccanne 46348932Smccanne return (error); 46447584Smccanne } 46547584Smccanne 46647584Smccanne 46747584Smccanne /* 46853947Smccanne * If there are processes sleeping on this descriptor, wake them up. 46947584Smccanne */ 47047584Smccanne static inline void 47147584Smccanne bpf_wakeup(d) 47247584Smccanne register struct bpf_d *d; 47347584Smccanne { 47448932Smccanne wakeup((caddr_t)d); 47553947Smccanne #if BSD >= 199103 47653947Smccanne selwakeup(&d->bd_sel); 47753947Smccanne /* XXX */ 47853947Smccanne d->bd_sel.si_pid = 0; 47953947Smccanne #else 48053947Smccanne if (d->bd_selproc) { 48153947Smccanne selwakeup(d->bd_selproc, (int)d->bd_selcoll); 48253947Smccanne d->bd_selcoll = 0; 48353947Smccanne d->bd_selproc = 0; 48453947Smccanne } 48553947Smccanne #endif 48647584Smccanne } 48747584Smccanne 48847584Smccanne int 48947584Smccanne bpfwrite(dev, uio) 49047584Smccanne dev_t dev; 49147584Smccanne struct uio *uio; 49247584Smccanne { 49347584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 49447584Smccanne struct ifnet *ifp; 49547584Smccanne struct mbuf *m; 49647584Smccanne int error, s; 49747584Smccanne static struct sockaddr dst; 49855289Smckusick int datlen; 49947584Smccanne 50047584Smccanne if (d->bd_bif == 0) 50148932Smccanne return (ENXIO); 50247584Smccanne 50347584Smccanne ifp = d->bd_bif->bif_ifp; 50447584Smccanne 50547584Smccanne if (uio->uio_resid == 0) 50648932Smccanne return (0); 50747584Smccanne 50855289Smckusick error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen); 50947584Smccanne if (error) 51048932Smccanne return (error); 51147584Smccanne 51255289Smckusick if (datlen > ifp->if_mtu) 51355289Smckusick return (EMSGSIZE); 51455289Smckusick 51547584Smccanne s = splnet(); 51651425Smccanne #if BSD >= 199103 51753947Smccanne error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0); 51851425Smccanne #else 51947584Smccanne error = (*ifp->if_output)(ifp, m, &dst); 52051425Smccanne #endif 52147584Smccanne splx(s); 52247584Smccanne /* 52353947Smccanne * The driver frees the mbuf. 52447584Smccanne */ 52548932Smccanne return (error); 52647584Smccanne } 52747584Smccanne 52847584Smccanne /* 52953947Smccanne * Reset a descriptor by flushing its packet buffer and clearing the 53053947Smccanne * receive and drop counts. Should be called at splimp. 53147584Smccanne */ 53247584Smccanne static void 53347584Smccanne reset_d(d) 53447584Smccanne struct bpf_d *d; 53547584Smccanne { 53647584Smccanne if (d->bd_hbuf) { 53747584Smccanne /* Free the hold buffer. */ 53847584Smccanne d->bd_fbuf = d->bd_hbuf; 53947584Smccanne d->bd_hbuf = 0; 54047584Smccanne } 54148932Smccanne d->bd_slen = 0; 54253947Smccanne d->bd_hlen = 0; 54347584Smccanne d->bd_rcount = 0; 54447584Smccanne d->bd_dcount = 0; 54547584Smccanne } 54647584Smccanne 54747584Smccanne /* 54847584Smccanne * FIONREAD Check for read packet available. 54947584Smccanne * SIOCGIFADDR Get interface address - convenient hook to driver. 55047584Smccanne * BIOCGBLEN Get buffer len [for read()]. 55147584Smccanne * BIOCSETF Set ethernet read filter. 55247584Smccanne * BIOCFLUSH Flush read packet buffer. 55347584Smccanne * BIOCPROMISC Put interface into promiscuous mode. 55449202Smccanne * BIOCGDLT Get link layer type. 55547584Smccanne * BIOCGETIF Get interface name. 55647584Smccanne * BIOCSETIF Set interface. 55747584Smccanne * BIOCSRTIMEOUT Set read timeout. 55847584Smccanne * BIOCGRTIMEOUT Get read timeout. 55947584Smccanne * BIOCGSTATS Get packet stats. 56047584Smccanne * BIOCIMMEDIATE Set immediate mode. 56153947Smccanne * BIOCVERSION Get filter language version. 56247584Smccanne */ 56347584Smccanne /* ARGSUSED */ 56447584Smccanne int 56547584Smccanne bpfioctl(dev, cmd, addr, flag) 56647584Smccanne dev_t dev; 56747584Smccanne int cmd; 56847584Smccanne caddr_t addr; 56947584Smccanne int flag; 57047584Smccanne { 57147584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 57247584Smccanne int s, error = 0; 57347584Smccanne 57447584Smccanne switch (cmd) { 57547584Smccanne 57647584Smccanne default: 57747584Smccanne error = EINVAL; 57847584Smccanne break; 57947584Smccanne 58047584Smccanne /* 58147584Smccanne * Check for read packet available. 58247584Smccanne */ 58347584Smccanne case FIONREAD: 58447584Smccanne { 58547584Smccanne int n; 58653947Smccanne 58747584Smccanne s = splimp(); 58848932Smccanne n = d->bd_slen; 58953947Smccanne if (d->bd_hbuf) 59048932Smccanne n += d->bd_hlen; 59147584Smccanne splx(s); 59247584Smccanne 59347584Smccanne *(int *)addr = n; 59447584Smccanne break; 59547584Smccanne } 59647584Smccanne 59747584Smccanne case SIOCGIFADDR: 59847584Smccanne { 59947584Smccanne struct ifnet *ifp; 60047584Smccanne 60147584Smccanne if (d->bd_bif == 0) 60247584Smccanne error = EINVAL; 60347584Smccanne else { 60447584Smccanne ifp = d->bd_bif->bif_ifp; 60553947Smccanne error = (*ifp->if_ioctl)(ifp, cmd, addr); 60647584Smccanne } 60747584Smccanne break; 60847584Smccanne } 60947584Smccanne 61047584Smccanne /* 61147584Smccanne * Get buffer len [for read()]. 61247584Smccanne */ 61347584Smccanne case BIOCGBLEN: 61448932Smccanne *(u_int *)addr = d->bd_bufsize; 61547584Smccanne break; 61647584Smccanne 61747584Smccanne /* 61853947Smccanne * Set buffer length. 61953947Smccanne */ 62053947Smccanne case BIOCSBLEN: 62153947Smccanne #if BSD < 199103 62253947Smccanne error = EINVAL; 62353947Smccanne #else 62453947Smccanne if (d->bd_bif != 0) 62553947Smccanne error = EINVAL; 62653947Smccanne else { 62753947Smccanne register u_int size = *(u_int *)addr; 62853947Smccanne 62953947Smccanne if (size > BPF_MAXBUFSIZE) 63053947Smccanne *(u_int *)addr = size = BPF_MAXBUFSIZE; 63153947Smccanne else if (size < BPF_MINBUFSIZE) 63253947Smccanne *(u_int *)addr = size = BPF_MINBUFSIZE; 63353947Smccanne d->bd_bufsize = size; 63453947Smccanne } 63553947Smccanne #endif 63653947Smccanne break; 63753947Smccanne 63853947Smccanne /* 63951425Smccanne * Set link layer read filter. 64047584Smccanne */ 64153947Smccanne case BIOCSETF: 64247584Smccanne error = bpf_setf(d, (struct bpf_program *)addr); 64347584Smccanne break; 64447584Smccanne 64547584Smccanne /* 64647584Smccanne * Flush read packet buffer. 64747584Smccanne */ 64847584Smccanne case BIOCFLUSH: 64947584Smccanne s = splimp(); 65047584Smccanne reset_d(d); 65147584Smccanne splx(s); 65247584Smccanne break; 65347584Smccanne 65447584Smccanne /* 65547584Smccanne * Put interface into promiscuous mode. 65647584Smccanne */ 65747584Smccanne case BIOCPROMISC: 65847584Smccanne if (d->bd_bif == 0) { 65947584Smccanne /* 66047584Smccanne * No interface attached yet. 66147584Smccanne */ 66247584Smccanne error = EINVAL; 66347584Smccanne break; 66447584Smccanne } 66547584Smccanne s = splimp(); 66647584Smccanne if (d->bd_promisc == 0) { 66747584Smccanne error = ifpromisc(d->bd_bif->bif_ifp, 1); 66851425Smccanne if (error == 0) 66951425Smccanne d->bd_promisc = 1; 67047584Smccanne } 67147584Smccanne splx(s); 67247584Smccanne break; 67347584Smccanne 67447584Smccanne /* 67547584Smccanne * Get device parameters. 67647584Smccanne */ 67749202Smccanne case BIOCGDLT: 67847584Smccanne if (d->bd_bif == 0) 67947584Smccanne error = EINVAL; 68047584Smccanne else 68149202Smccanne *(u_int *)addr = d->bd_bif->bif_dlt; 68247584Smccanne break; 68347584Smccanne 68447584Smccanne /* 68547584Smccanne * Set interface name. 68647584Smccanne */ 68747584Smccanne case BIOCGETIF: 68847584Smccanne if (d->bd_bif == 0) 68947584Smccanne error = EINVAL; 69047584Smccanne else 69147584Smccanne bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr); 69247584Smccanne break; 69347584Smccanne 69447584Smccanne /* 69547584Smccanne * Set interface. 69647584Smccanne */ 69747584Smccanne case BIOCSETIF: 69847584Smccanne error = bpf_setif(d, (struct ifreq *)addr); 69947584Smccanne break; 70047584Smccanne 70147584Smccanne /* 70247584Smccanne * Set read timeout. 70347584Smccanne */ 70453947Smccanne case BIOCSRTIMEOUT: 70547584Smccanne { 70647584Smccanne struct timeval *tv = (struct timeval *)addr; 70747584Smccanne u_long msec; 70847584Smccanne 70947584Smccanne /* Compute number of milliseconds. */ 71047584Smccanne msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; 71147584Smccanne /* Scale milliseconds to ticks. Assume hard 71247584Smccanne clock has millisecond or greater resolution 71347584Smccanne (i.e. tick >= 1000). For 10ms hardclock, 71447584Smccanne tick/1000 = 10, so rtout<-msec/10. */ 71547584Smccanne d->bd_rtout = msec / (tick / 1000); 71647584Smccanne break; 71747584Smccanne } 71847584Smccanne 71947584Smccanne /* 72047584Smccanne * Get read timeout. 72147584Smccanne */ 72253947Smccanne case BIOCGRTIMEOUT: 72347584Smccanne { 72447584Smccanne struct timeval *tv = (struct timeval *)addr; 72547584Smccanne u_long msec = d->bd_rtout; 72647584Smccanne 72747584Smccanne msec *= tick / 1000; 72847584Smccanne tv->tv_sec = msec / 1000; 72947584Smccanne tv->tv_usec = msec % 1000; 73047584Smccanne break; 73147584Smccanne } 73247584Smccanne 73347584Smccanne /* 73447584Smccanne * Get packet stats. 73547584Smccanne */ 73647584Smccanne case BIOCGSTATS: 73747584Smccanne { 73847584Smccanne struct bpf_stat *bs = (struct bpf_stat *)addr; 73947584Smccanne 74047584Smccanne bs->bs_recv = d->bd_rcount; 74147584Smccanne bs->bs_drop = d->bd_dcount; 74247584Smccanne break; 74347584Smccanne } 74447584Smccanne 74547584Smccanne /* 74647584Smccanne * Set immediate mode. 74747584Smccanne */ 74847584Smccanne case BIOCIMMEDIATE: 74947584Smccanne d->bd_immediate = *(u_int *)addr; 75047584Smccanne break; 75153947Smccanne 75253947Smccanne case BIOCVERSION: 75353947Smccanne { 75453947Smccanne struct bpf_version *bv = (struct bpf_version *)addr; 75553947Smccanne 75653947Smccanne bv->bv_major = BPF_MAJOR_VERSION; 75753947Smccanne bv->bv_minor = BPF_MINOR_VERSION; 75853947Smccanne break; 75953947Smccanne } 76047584Smccanne } 76148932Smccanne return (error); 76247584Smccanne } 76347584Smccanne 76453947Smccanne /* 76551425Smccanne * Set d's packet filter program to fp. If this file already has a filter, 76648932Smccanne * free it and replace it. Returns EINVAL for bogus requests. 76747584Smccanne */ 76847584Smccanne int 76947584Smccanne bpf_setf(d, fp) 77047584Smccanne struct bpf_d *d; 77147584Smccanne struct bpf_program *fp; 77247584Smccanne { 77348932Smccanne struct bpf_insn *fcode, *old; 77447584Smccanne u_int flen, size; 77547584Smccanne int s; 77647584Smccanne 77748932Smccanne old = d->bd_filter; 77847584Smccanne if (fp->bf_insns == 0) { 77947584Smccanne if (fp->bf_len != 0) 78048932Smccanne return (EINVAL); 78148932Smccanne s = splimp(); 78248967Smccanne d->bd_filter = 0; 78347584Smccanne reset_d(d); 78447584Smccanne splx(s); 78548967Smccanne if (old != 0) 78648932Smccanne free((caddr_t)old, M_DEVBUF); 78748932Smccanne return (0); 78847584Smccanne } 78947584Smccanne flen = fp->bf_len; 79048932Smccanne if (flen > BPF_MAXINSNS) 79148932Smccanne return (EINVAL); 79248932Smccanne 79347584Smccanne size = flen * sizeof(*fp->bf_insns); 79448932Smccanne fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK); 79550417Smccanne if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && 79650417Smccanne bpf_validate(fcode, (int)flen)) { 79748967Smccanne s = splimp(); 79848932Smccanne d->bd_filter = fcode; 79947584Smccanne reset_d(d); 80047584Smccanne splx(s); 80148967Smccanne if (old != 0) 80248932Smccanne free((caddr_t)old, M_DEVBUF); 80347584Smccanne 80448932Smccanne return (0); 80547584Smccanne } 80648932Smccanne free((caddr_t)fcode, M_DEVBUF); 80748932Smccanne return (EINVAL); 80847584Smccanne } 80947584Smccanne 81047584Smccanne /* 81153947Smccanne * Detach a file from its current interface (if attached at all) and attach 81253947Smccanne * to the interface indicated by the name stored in ifr. 81351425Smccanne * Return an errno or 0. 81447584Smccanne */ 81547584Smccanne static int 81647584Smccanne bpf_setif(d, ifr) 81747584Smccanne struct bpf_d *d; 81847584Smccanne struct ifreq *ifr; 81947584Smccanne { 82047584Smccanne struct bpf_if *bp; 82147584Smccanne char *cp; 82253947Smccanne int unit, s, error; 82347584Smccanne 82447584Smccanne /* 82547584Smccanne * Separate string into name part and unit number. Put a null 82653947Smccanne * byte at the end of the name part, and compute the number. 82747584Smccanne * If the a unit number is unspecified, the default is 0, 82848932Smccanne * as initialized above. XXX This should be common code. 82947584Smccanne */ 83047584Smccanne unit = 0; 83147584Smccanne cp = ifr->ifr_name; 83247584Smccanne cp[sizeof(ifr->ifr_name) - 1] = '\0'; 83347584Smccanne while (*cp++) { 83447584Smccanne if (*cp >= '0' && *cp <= '9') { 83547584Smccanne unit = *cp - '0'; 83647584Smccanne *cp++ = '\0'; 83747584Smccanne while (*cp) 83847584Smccanne unit = 10 * unit + *cp++ - '0'; 83947584Smccanne break; 84047584Smccanne } 84147584Smccanne } 84247584Smccanne /* 84347584Smccanne * Look through attached interfaces for the named one. 84447584Smccanne */ 84549202Smccanne for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { 84647584Smccanne struct ifnet *ifp = bp->bif_ifp; 84747584Smccanne 84853947Smccanne if (ifp == 0 || unit != ifp->if_unit 84947584Smccanne || strcmp(ifp->if_name, ifr->ifr_name) != 0) 85047584Smccanne continue; 85147584Smccanne /* 85253947Smccanne * We found the requested interface. 85347584Smccanne * If it's not up, return an error. 85453947Smccanne * Allocate the packet buffers if we need to. 85553947Smccanne * If we're already attached to requested interface, 85653947Smccanne * just flush the buffer. 85747584Smccanne */ 85847584Smccanne if ((ifp->if_flags & IFF_UP) == 0) 85948932Smccanne return (ENETDOWN); 86053947Smccanne 86153947Smccanne if (d->bd_sbuf == 0) { 86253947Smccanne error = bpf_allocbufs(d); 86353947Smccanne if (error != 0) 86453947Smccanne return (error); 86553947Smccanne } 86647584Smccanne s = splimp(); 86747584Smccanne if (bp != d->bd_bif) { 86847584Smccanne if (d->bd_bif) 86953947Smccanne /* 87048932Smccanne * Detach if attached to something else. 87147584Smccanne */ 87247584Smccanne bpf_detachd(d); 87347584Smccanne 87447584Smccanne bpf_attachd(d, bp); 87547584Smccanne } 87647584Smccanne reset_d(d); 87747584Smccanne splx(s); 87848932Smccanne return (0); 87947584Smccanne } 88047584Smccanne /* Not found. */ 88148932Smccanne return (ENXIO); 88247584Smccanne } 88347584Smccanne 88447584Smccanne /* 88551425Smccanne * Convert an interface name plus unit number of an ifp to a single 88651425Smccanne * name which is returned in the ifr. 88747584Smccanne */ 88847584Smccanne static void 88947584Smccanne bpf_ifname(ifp, ifr) 89047584Smccanne struct ifnet *ifp; 89147584Smccanne struct ifreq *ifr; 89247584Smccanne { 89347584Smccanne char *s = ifp->if_name; 89447584Smccanne char *d = ifr->ifr_name; 89547584Smccanne 89647584Smccanne while (*d++ = *s++) 89753947Smccanne continue; 89848932Smccanne /* XXX Assume that unit number is less than 10. */ 89947584Smccanne *d++ = ifp->if_unit + '0'; 90047584Smccanne *d = '\0'; 90147584Smccanne } 90247584Smccanne 90347584Smccanne /* 90451425Smccanne * The new select interface passes down the proc pointer; the old select 90551425Smccanne * stubs had to grab it out of the user struct. This glue allows either case. 90651425Smccanne */ 90751425Smccanne #if BSD >= 199103 90851425Smccanne #define bpf_select bpfselect 90951425Smccanne #else 91051425Smccanne int 91151425Smccanne bpfselect(dev, rw) 91251425Smccanne register dev_t dev; 91351425Smccanne int rw; 91451425Smccanne { 91553947Smccanne return (bpf_select(dev, rw, u.u_procp)); 91651425Smccanne } 91751425Smccanne #endif 91851425Smccanne 91951425Smccanne /* 92047584Smccanne * Support for select() system call 92147584Smccanne * 92253947Smccanne * Return true iff the specific operation will not block indefinitely. 92353947Smccanne * Otherwise, return false but make a note that a selwakeup() must be done. 92447584Smccanne */ 92547584Smccanne int 92651425Smccanne bpf_select(dev, rw, p) 92747584Smccanne register dev_t dev; 92847584Smccanne int rw; 92948932Smccanne struct proc *p; 93047584Smccanne { 93147584Smccanne register struct bpf_d *d; 93247584Smccanne register int s; 93353947Smccanne 93447584Smccanne if (rw != FREAD) 93548932Smccanne return (0); 93647584Smccanne /* 93747584Smccanne * An imitation of the FIONREAD ioctl code. 93847584Smccanne */ 93947584Smccanne d = &bpf_dtab[minor(dev)]; 94053947Smccanne 94147584Smccanne s = splimp(); 94249723Smccanne if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) { 94347584Smccanne /* 94447584Smccanne * There is data waiting. 94547584Smccanne */ 94647584Smccanne splx(s); 94748932Smccanne return (1); 94847584Smccanne } 94953947Smccanne #if BSD >= 199103 95053947Smccanne selrecord(p, &d->bd_sel); 95153947Smccanne #else 95247584Smccanne /* 95347584Smccanne * No data ready. If there's already a select() waiting on this 95453947Smccanne * minor device then this is a collision. This shouldn't happen 95547584Smccanne * because minors really should not be shared, but if a process 95647584Smccanne * forks while one of these is open, it is possible that both 95747584Smccanne * processes could select on the same descriptor. 95847584Smccanne */ 95953947Smccanne if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait) 96053947Smccanne d->bd_selcoll = 1; 96153947Smccanne else 96253947Smccanne d->bd_selproc = p; 96353947Smccanne #endif 96453947Smccanne splx(s); 96548932Smccanne return (0); 96647584Smccanne } 96747584Smccanne 96847584Smccanne /* 96953947Smccanne * Incoming linkage from device drivers. Process the packet pkt, of length 97053947Smccanne * pktlen, which is stored in a contiguous buffer. The packet is parsed 97153947Smccanne * by each process' filter, and if accepted, stashed into the corresponding 97253947Smccanne * buffer. 97347584Smccanne */ 97447584Smccanne void 97548932Smccanne bpf_tap(arg, pkt, pktlen) 97647584Smccanne caddr_t arg; 97748932Smccanne register u_char *pkt; 97848932Smccanne register u_int pktlen; 97947584Smccanne { 98047584Smccanne struct bpf_if *bp; 98147584Smccanne register struct bpf_d *d; 98247584Smccanne register u_int slen; 98347584Smccanne /* 98447584Smccanne * Note that the ipl does not have to be raised at this point. 98547584Smccanne * The only problem that could arise here is that if two different 98647584Smccanne * interfaces shared any data. This is not the case. 98747584Smccanne */ 98847584Smccanne bp = (struct bpf_if *)arg; 98947584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 99047584Smccanne ++d->bd_rcount; 99149202Smccanne slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 99247584Smccanne if (slen != 0) 99349202Smccanne catchpacket(d, pkt, pktlen, slen, bcopy); 99447584Smccanne } 99547584Smccanne } 99647584Smccanne 99747584Smccanne /* 99847584Smccanne * Copy data from an mbuf chain into a buffer. This code is derived 99947584Smccanne * from m_copydata in sys/uipc_mbuf.c. 100047584Smccanne */ 100147584Smccanne static void 100261337Sbostic bpf_mcopy(src_arg, dst_arg, len) 100361337Sbostic void *src_arg, *dst_arg; 100461337Sbostic register u_int len; 100547584Smccanne { 100661337Sbostic register struct mbuf *m; 100761337Sbostic register u_int count; 100861337Sbostic u_char *src, *dst; 100947584Smccanne 101061337Sbostic src = src_arg; 101161337Sbostic dst = dst_arg; 101261337Sbostic m = src_arg; 101347584Smccanne while (len > 0) { 101447584Smccanne if (m == 0) 101549202Smccanne panic("bpf_mcopy"); 101655065Spendry count = min(m->m_len, len); 101749202Smccanne bcopy(mtod(m, caddr_t), (caddr_t)dst, count); 101849202Smccanne m = m->m_next; 101949202Smccanne dst += count; 102047584Smccanne len -= count; 102147584Smccanne } 102247584Smccanne } 102347584Smccanne 102447584Smccanne /* 102553947Smccanne * Incoming linkage from device drivers, when packet is in an mbuf chain. 102647584Smccanne */ 102747584Smccanne void 102849202Smccanne bpf_mtap(arg, m) 102947584Smccanne caddr_t arg; 103049202Smccanne struct mbuf *m; 103147584Smccanne { 103247584Smccanne struct bpf_if *bp = (struct bpf_if *)arg; 103347584Smccanne struct bpf_d *d; 103449202Smccanne u_int pktlen, slen; 103549202Smccanne struct mbuf *m0; 103647584Smccanne 103748932Smccanne pktlen = 0; 103851425Smccanne for (m0 = m; m0 != 0; m0 = m0->m_next) 103949202Smccanne pktlen += m0->m_len; 104049723Smccanne 104147584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 104247584Smccanne ++d->bd_rcount; 104349202Smccanne slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); 104447584Smccanne if (slen != 0) 104549202Smccanne catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); 104647584Smccanne } 104747584Smccanne } 104847584Smccanne 104947584Smccanne /* 105049202Smccanne * Move the packet data from interface memory (pkt) into the 105147584Smccanne * store buffer. Return 1 if it's time to wakeup a listener (buffer full), 105253947Smccanne * otherwise 0. "copy" is the routine called to do the actual data 105351425Smccanne * transfer. bcopy is passed in to copy contiguous chunks, while 105451425Smccanne * bpf_mcopy is passed in to copy mbuf chains. In the latter case, 105551425Smccanne * pkt is really an mbuf. 105647584Smccanne */ 105747584Smccanne static void 105848932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn) 105948932Smccanne register struct bpf_d *d; 106048932Smccanne register u_char *pkt; 106148932Smccanne register u_int pktlen, snaplen; 106248932Smccanne register void (*cpfn)(); 106347584Smccanne { 106448932Smccanne register struct bpf_hdr *hp; 106548932Smccanne register int totlen, curlen; 106648932Smccanne register int hdrlen = d->bd_bif->bif_hdrlen; 106747584Smccanne /* 106847584Smccanne * Figure out how many bytes to move. If the packet is 106947584Smccanne * greater or equal to the snapshot length, transfer that 107047584Smccanne * much. Otherwise, transfer the whole packet (unless 107148932Smccanne * we hit the buffer size limit). 107247584Smccanne */ 107355065Spendry totlen = hdrlen + min(snaplen, pktlen); 107450082Smccanne if (totlen > d->bd_bufsize) 107550082Smccanne totlen = d->bd_bufsize; 107647584Smccanne 107747584Smccanne /* 107847584Smccanne * Round up the end of the previous packet to the next longword. 107947584Smccanne */ 108048932Smccanne curlen = BPF_WORDALIGN(d->bd_slen); 108148932Smccanne if (curlen + totlen > d->bd_bufsize) { 108247584Smccanne /* 108347584Smccanne * This packet will overflow the storage buffer. 108448932Smccanne * Rotate the buffers if we can, then wakeup any 108548932Smccanne * pending reads. 108647584Smccanne */ 108747584Smccanne if (d->bd_fbuf == 0) { 108853947Smccanne /* 108953947Smccanne * We haven't completed the previous read yet, 109048932Smccanne * so drop the packet. 109147584Smccanne */ 109247584Smccanne ++d->bd_dcount; 109347584Smccanne return; 109447584Smccanne } 109548932Smccanne ROTATE_BUFFERS(d); 109647584Smccanne bpf_wakeup(d); 109748932Smccanne curlen = 0; 109847584Smccanne } 109953947Smccanne else if (d->bd_immediate) 110047584Smccanne /* 110147584Smccanne * Immediate mode is set. A packet arrived so any 110247584Smccanne * reads should be woken up. 110347584Smccanne */ 110447584Smccanne bpf_wakeup(d); 110548932Smccanne 110647584Smccanne /* 110747584Smccanne * Append the bpf header. 110847584Smccanne */ 110948932Smccanne hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); 111051425Smccanne #if BSD >= 199103 111147584Smccanne microtime(&hp->bh_tstamp); 111253947Smccanne #elif defined(sun) 111353947Smccanne uniqtime(&hp->bh_tstamp); 111447584Smccanne #else 111547584Smccanne hp->bh_tstamp = time; 111647584Smccanne #endif 111748932Smccanne hp->bh_datalen = pktlen; 111847584Smccanne hp->bh_hdrlen = hdrlen; 111947584Smccanne /* 112048932Smccanne * Copy the packet data into the store buffer and update its length. 112147584Smccanne */ 112248932Smccanne (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); 112348932Smccanne d->bd_slen = curlen + totlen; 112447584Smccanne } 112547584Smccanne 112653947Smccanne /* 112747584Smccanne * Initialize all nonzero fields of a descriptor. 112847584Smccanne */ 112947584Smccanne static int 113053947Smccanne bpf_allocbufs(d) 113147584Smccanne register struct bpf_d *d; 113247584Smccanne { 113348932Smccanne d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 113448932Smccanne if (d->bd_fbuf == 0) 113548932Smccanne return (ENOBUFS); 113647584Smccanne 113748932Smccanne d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 113848932Smccanne if (d->bd_sbuf == 0) { 113948932Smccanne free(d->bd_fbuf, M_DEVBUF); 114048932Smccanne return (ENOBUFS); 114147584Smccanne } 114248932Smccanne d->bd_slen = 0; 114348932Smccanne d->bd_hlen = 0; 114448932Smccanne return (0); 114547584Smccanne } 114647584Smccanne 114747584Smccanne /* 114851425Smccanne * Free buffers currently in use by a descriptor. 114951425Smccanne * Called on close. 115047584Smccanne */ 115153947Smccanne static void 115251425Smccanne bpf_freed(d) 115351425Smccanne register struct bpf_d *d; 115451425Smccanne { 115551425Smccanne /* 115651425Smccanne * We don't need to lock out interrupts since this descriptor has 115753947Smccanne * been detached from its interface and it yet hasn't been marked 115851425Smccanne * free. 115951425Smccanne */ 116053947Smccanne if (d->bd_sbuf != 0) { 116153947Smccanne free(d->bd_sbuf, M_DEVBUF); 116253947Smccanne if (d->bd_hbuf != 0) 116353947Smccanne free(d->bd_hbuf, M_DEVBUF); 116453947Smccanne if (d->bd_fbuf != 0) 116553947Smccanne free(d->bd_fbuf, M_DEVBUF); 116653947Smccanne } 116751425Smccanne if (d->bd_filter) 116851425Smccanne free((caddr_t)d->bd_filter, M_DEVBUF); 116953947Smccanne 117051425Smccanne D_MARKFREE(d); 117151425Smccanne } 117251425Smccanne 117351425Smccanne /* 117451425Smccanne * Attach an interface to bpf. driverp is a pointer to a (struct bpf_if *) 117551425Smccanne * in the driver's softc; dlt is the link layer type; hdrlen is the fixed 117651425Smccanne * size of the link header (variable length headers not yet supported). 117751425Smccanne */ 117847584Smccanne void 117949202Smccanne bpfattach(driverp, ifp, dlt, hdrlen) 118047584Smccanne caddr_t *driverp; 118147584Smccanne struct ifnet *ifp; 118249202Smccanne u_int dlt, hdrlen; 118347584Smccanne { 118447584Smccanne struct bpf_if *bp; 118547584Smccanne int i; 118651425Smccanne #if BSD < 199103 118751425Smccanne static struct bpf_if bpf_ifs[NBPFILTER]; 118851425Smccanne static int bpfifno; 118947584Smccanne 119051425Smccanne bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0; 119151425Smccanne #else 119249202Smccanne bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT); 119351425Smccanne #endif 119449202Smccanne if (bp == 0) 119549202Smccanne panic("bpfattach"); 119647584Smccanne 119747584Smccanne bp->bif_dlist = 0; 119847584Smccanne bp->bif_driverp = (struct bpf_if **)driverp; 119947584Smccanne bp->bif_ifp = ifp; 120049202Smccanne bp->bif_dlt = dlt; 120147584Smccanne 120249202Smccanne bp->bif_next = bpf_iflist; 120349202Smccanne bpf_iflist = bp; 120449202Smccanne 120548932Smccanne *bp->bif_driverp = 0; 120648932Smccanne 120747584Smccanne /* 120847584Smccanne * Compute the length of the bpf header. This is not necessarily 120953947Smccanne * equal to SIZEOF_BPF_HDR because we want to insert spacing such 121053947Smccanne * that the network layer header begins on a longword boundary (for 121147584Smccanne * performance reasons and to alleviate alignment restrictions). 121247584Smccanne */ 121349202Smccanne bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; 121447584Smccanne 121547584Smccanne /* 121647584Smccanne * Mark all the descriptors free if this hasn't been done. 121747584Smccanne */ 121847584Smccanne if (!D_ISFREE(&bpf_dtab[0])) 121947584Smccanne for (i = 0; i < NBPFILTER; ++i) 122047584Smccanne D_MARKFREE(&bpf_dtab[i]); 122147584Smccanne 122247584Smccanne printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); 122347584Smccanne } 122447584Smccanne 122551425Smccanne #if BSD >= 199103 122648967Smccanne /* XXX This routine belongs in net/if.c. */ 122748932Smccanne /* 122853947Smccanne * Set/clear promiscuous mode on interface ifp based on the truth value 122948932Smccanne * of pswitch. The calls are reference counted so that only the first 123053947Smccanne * "on" request actually has an effect, as does the final "off" request. 123153947Smccanne * Results are undefined if the "off" and "on" requests are not matched. 123248932Smccanne */ 123348932Smccanne int 123448932Smccanne ifpromisc(ifp, pswitch) 123548932Smccanne struct ifnet *ifp; 123648932Smccanne int pswitch; 123748932Smccanne { 123849726Smccanne struct ifreq ifr; 123953947Smccanne /* 124048932Smccanne * If the device is not configured up, we cannot put it in 124148932Smccanne * promiscuous mode. 124248932Smccanne */ 124348932Smccanne if ((ifp->if_flags & IFF_UP) == 0) 124448932Smccanne return (ENETDOWN); 124548932Smccanne 124648932Smccanne if (pswitch) { 124748932Smccanne if (ifp->if_pcount++ != 0) 124848932Smccanne return (0); 124948932Smccanne ifp->if_flags |= IFF_PROMISC; 125048932Smccanne } else { 125148932Smccanne if (--ifp->if_pcount > 0) 125248932Smccanne return (0); 125348932Smccanne ifp->if_flags &= ~IFF_PROMISC; 125448932Smccanne } 125549726Smccanne ifr.ifr_flags = ifp->if_flags; 125649726Smccanne return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); 125748932Smccanne } 125851425Smccanne #endif 125948932Smccanne 126051425Smccanne #if BSD < 199103 126151425Smccanne /* 126251425Smccanne * Allocate some memory for bpf. This is temporary SunOS support, and 126353947Smccanne * is admittedly a hack. 126451425Smccanne * If resources unavaiable, return 0. 126551425Smccanne */ 126651425Smccanne static caddr_t 126751425Smccanne bpf_alloc(size, canwait) 126851425Smccanne register int size; 126951425Smccanne register int canwait; 127051425Smccanne { 127151425Smccanne register struct mbuf *m; 127251425Smccanne 127351425Smccanne if ((unsigned)size > (MCLBYTES-8)) 127451425Smccanne return 0; 127551425Smccanne 127651425Smccanne MGET(m, canwait, MT_DATA); 127751425Smccanne if (m == 0) 127851425Smccanne return 0; 127951425Smccanne if ((unsigned)size > (MLEN-8)) { 128051425Smccanne MCLGET(m); 128151425Smccanne if (m->m_len != MCLBYTES) { 128251425Smccanne m_freem(m); 128351425Smccanne return 0; 128451425Smccanne } 128551425Smccanne } 128651425Smccanne *mtod(m, struct mbuf **) = m; 128751425Smccanne return mtod(m, caddr_t) + 8; 128851425Smccanne } 128951425Smccanne #endif 129051425Smccanne #endif 1291