1*51440Smccanne /* 2*51440Smccanne * 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 * 10*51440Smccanne * %sccs.include.redist.c% 1149343Sbostic * 12*51440Smccanne * @(#)bpf.c 7.7 (Berkeley) 10/29/91 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 2551425Smccanne #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> 3247584Smccanne #include <sys/dir.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(); 6451425Smccanne #define malloc(size, type, canwait) bpf_alloc(size, canwait) 6551425Smccanne #define free(cp, type) m_free(*(struct mbuf **)(cp - 8)) 6651425Smccanne #define M_WAITOK M_WAIT 6751425Smccanne #define BPF_BUFSIZE (MCLBYTES-8) 6851425Smccanne #define ERESTART EINTR 6951425Smccanne #else 7051425Smccanne #define BPF_BUFSIZE 4096 7151425Smccanne #endif 7251425Smccanne 7347584Smccanne #define PRINET 26 /* interruptible */ 7447584Smccanne 7547584Smccanne /* 7648932Smccanne * The default read buffer size is patchable. 7748932Smccanne */ 7851425Smccanne int bpf_bufsize = BPF_BUFSIZE; 7948932Smccanne 8048932Smccanne /* 8149202Smccanne * bpf_iflist is the list of interfaces; each corresponds to an ifnet 8249202Smccanne * bpf_dtab holds the descriptors, indexed by minor device # 8347584Smccanne * 8447584Smccanne * We really don't need NBPFILTER bpf_if entries, but this eliminates 8547584Smccanne * the need to account for all possible drivers here. 8647584Smccanne * This problem will go away when these structures are allocated dynamically. 8747584Smccanne */ 8849202Smccanne static struct bpf_if *bpf_iflist; 8947584Smccanne static struct bpf_d bpf_dtab[NBPFILTER]; 9047584Smccanne 9147584Smccanne static void bpf_ifname(); 9247584Smccanne static void catchpacket(); 9347584Smccanne static int bpf_setif(); 9447584Smccanne static int bpf_initd(); 9547584Smccanne 9647584Smccanne static int 9747584Smccanne bpf_movein(uio, linktype, mp, sockp) 9847584Smccanne register struct uio *uio; 9947584Smccanne int linktype; 10047584Smccanne register struct mbuf **mp; 10147584Smccanne register struct sockaddr *sockp; 10247584Smccanne { 10347584Smccanne struct mbuf *m; 10447584Smccanne int error; 10547584Smccanne int len; 10647584Smccanne int hlen; 10747584Smccanne 10847584Smccanne /* 10947584Smccanne * Build a sockaddr based on the data link layer type. 11047584Smccanne * We do this at this level because the ethernet header 11147584Smccanne * is copied directly into the data field of the sockaddr. 11247584Smccanne * In the case of SLIP, there is no header and the packet 11347584Smccanne * is forwarded as is. 11447584Smccanne * Also, we are careful to leave room at the front of the mbuf 11547584Smccanne * for the link level header. 11647584Smccanne */ 11747584Smccanne switch (linktype) { 11847584Smccanne case DLT_SLIP: 11947584Smccanne sockp->sa_family = AF_INET; 12047584Smccanne hlen = 0; 12147584Smccanne break; 12247584Smccanne 12347584Smccanne case DLT_EN10MB: 12447584Smccanne sockp->sa_family = AF_UNSPEC; 12547584Smccanne /* XXX Would MAXLINKHDR be better? */ 12647584Smccanne hlen = sizeof(struct ether_header); 12747584Smccanne break; 12847584Smccanne 12947584Smccanne case DLT_FDDI: 13047584Smccanne sockp->sa_family = AF_UNSPEC; 13147584Smccanne /* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */ 13247584Smccanne hlen = 24; 13347584Smccanne break; 13447584Smccanne 13547584Smccanne default: 13648932Smccanne return (EIO); 13747584Smccanne } 13847584Smccanne 13947584Smccanne len = uio->uio_resid; 14047584Smccanne if ((unsigned)len > MCLBYTES) 14148932Smccanne return (EIO); 14247584Smccanne 14347584Smccanne MGET(m, M_WAIT, MT_DATA); 14447584Smccanne if (m == 0) 14548932Smccanne return (ENOBUFS); 14647584Smccanne if (len > MLEN) { 14751425Smccanne #if BSD >= 199103 14848932Smccanne MCLGET(m, M_WAIT); 14948932Smccanne if ((m->m_flags & M_EXT) == 0) { 15051425Smccanne #else 15151425Smccanne MCLGET(m); 15251425Smccanne if (m->m_len == MCLBYTES) { 15351425Smccanne #endif 15451425Smccanne error = ENOBUFS; 15547584Smccanne goto bad; 15647584Smccanne } 15747584Smccanne } 15847584Smccanne m->m_len = len; 15947584Smccanne *mp = m; 16047584Smccanne /* 16147584Smccanne * Make room for link header. 16247584Smccanne */ 16347584Smccanne if (hlen) { 16447584Smccanne m->m_len -= hlen; 16551425Smccanne #if BSD >= 199103 16648932Smccanne m->m_data += hlen; /* XXX */ 16751425Smccanne #else 16851425Smccanne m->m_off += hlen; 16951425Smccanne #endif 17048932Smccanne error = uiomove((caddr_t)sockp->sa_data, hlen, uio); 17147584Smccanne if (error) 17247584Smccanne goto bad; 17347584Smccanne } 17448932Smccanne error = uiomove(mtod(m, caddr_t), len - hlen, uio); 17547584Smccanne if (!error) 17648932Smccanne return (0); 17747584Smccanne bad: 17847584Smccanne m_freem(m); 17948932Smccanne return (error); 18047584Smccanne } 18147584Smccanne 18247584Smccanne /* 18351425Smccanne * Attach file to the bpf interface, i.e. make d listen on bp. 18447584Smccanne * Must be called at splimp. 18547584Smccanne */ 18647584Smccanne static void 18747584Smccanne bpf_attachd(d, bp) 18847584Smccanne struct bpf_d *d; 18947584Smccanne struct bpf_if *bp; 19047584Smccanne { 19151425Smccanne /* 19251425Smccanne * Point d at bp, and add d to the interface's list of listeners. 19351425Smccanne * Finally, point the driver's bpf cookie at the interface so 19451425Smccanne * it will divert packets to bpf. 19551425Smccanne */ 19647584Smccanne d->bd_bif = bp; 19747584Smccanne d->bd_next = bp->bif_dlist; 19847584Smccanne bp->bif_dlist = d; 19947584Smccanne 20047584Smccanne *bp->bif_driverp = bp; 20147584Smccanne } 20247584Smccanne 20351425Smccanne /* 20451425Smccanne * Detach a file from its interface. 20551425Smccanne */ 20647584Smccanne static void 20747584Smccanne bpf_detachd(d) 20847584Smccanne struct bpf_d *d; 20947584Smccanne { 21047584Smccanne struct bpf_d **p; 21147584Smccanne struct bpf_if *bp; 21247584Smccanne 21347584Smccanne bp = d->bd_bif; 21447584Smccanne /* 21547584Smccanne * Check if this descriptor had requested promiscuous mode. 21647584Smccanne * If so, turn it off. 21747584Smccanne */ 21847584Smccanne if (d->bd_promisc) { 21947584Smccanne d->bd_promisc = 0; 22047584Smccanne if (ifpromisc(bp->bif_ifp, 0)) 22147584Smccanne /* 22247584Smccanne * Something is really wrong if we were able to put 22347584Smccanne * the driver into promiscuous mode, but can't 22447584Smccanne * take it out. 22547584Smccanne */ 22651425Smccanne panic("bpf: ifpromisc failed"); 22747584Smccanne } 22851425Smccanne /* Remove d from the interface's descriptor list. */ 22947584Smccanne p = &bp->bif_dlist; 23047584Smccanne while (*p != d) { 23147584Smccanne p = &(*p)->bd_next; 23247584Smccanne if (*p == 0) 23347584Smccanne panic("bpf_detachd: descriptor not in list"); 23447584Smccanne } 23547584Smccanne *p = (*p)->bd_next; 23647584Smccanne if (bp->bif_dlist == 0) 23747584Smccanne /* 23847584Smccanne * Let the driver know that there are no more listeners. 23947584Smccanne */ 24047584Smccanne *d->bd_bif->bif_driverp = 0; 24147584Smccanne d->bd_bif = 0; 24247584Smccanne } 24347584Smccanne 24447584Smccanne 24547584Smccanne /* 24647584Smccanne * Mark a descriptor free by making it point to itself. 24747584Smccanne * This is probably cheaper than marking with a constant since 24847584Smccanne * the address should be in a register anyway. 24947584Smccanne */ 25047584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next) 25147584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d)) 25247584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0) 25347584Smccanne 25447584Smccanne /* 25547584Smccanne * bpfopen - open ethernet device 25647584Smccanne * 25747584Smccanne * Errors: ENXIO - illegal minor device number 25847584Smccanne * EBUSY - too many files open 25947584Smccanne */ 26047584Smccanne /* ARGSUSED */ 26147584Smccanne int 26247584Smccanne bpfopen(dev, flag) 26347584Smccanne dev_t dev; 26447584Smccanne int flag; 26547584Smccanne { 26647584Smccanne int error, s; 26747584Smccanne register struct bpf_d *d; 26847584Smccanne 26947584Smccanne if (minor(dev) >= NBPFILTER) 27048932Smccanne return (ENXIO); 27147584Smccanne 27247584Smccanne /* 27347584Smccanne * Each minor can be opened by only one process. If the requested 27447584Smccanne * minor is in use, return EBUSY. 27547584Smccanne */ 27647584Smccanne s = splimp(); 27747584Smccanne d = &bpf_dtab[minor(dev)]; 27847584Smccanne if (!D_ISFREE(d)) { 27947584Smccanne splx(s); 28048932Smccanne return (EBUSY); 28147584Smccanne } else 28247584Smccanne /* Mark "free" and do most initialization. */ 28347584Smccanne bzero((char *)d, sizeof(*d)); 28447584Smccanne splx(s); 28547584Smccanne 28647584Smccanne error = bpf_initd(d); 28747584Smccanne if (error) { 28847584Smccanne D_MARKFREE(d); 28948932Smccanne return (error); 29047584Smccanne } 29148932Smccanne return (0); 29247584Smccanne } 29347584Smccanne 29447584Smccanne /* 29547584Smccanne * Close the descriptor by detaching it from its interface, 29647584Smccanne * deallocating its buffers, and marking it free. 29747584Smccanne */ 29847584Smccanne /* ARGSUSED */ 29947584Smccanne bpfclose(dev, flag) 30047584Smccanne dev_t dev; 30147584Smccanne int flag; 30247584Smccanne { 30347584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 30447584Smccanne int s; 30547584Smccanne 30647584Smccanne s = splimp(); 30747584Smccanne if (d->bd_bif) 30847584Smccanne bpf_detachd(d); 30947584Smccanne splx(s); 31047584Smccanne 31151425Smccanne bpf_freed(d); 31247584Smccanne } 31347584Smccanne 31451425Smccanne #if BSD < 199103 31551425Smccanne static 31651425Smccanne bpf_timeout(arg) 31751425Smccanne caddr_t arg; 31851425Smccanne { 31951425Smccanne struct bpf_d *d = (struct bpf_d *)arg; 32051425Smccanne d->bd_timedout = 1; 32151425Smccanne wakeup(arg); 32251425Smccanne } 32351425Smccanne 32451425Smccanne static int 32551425Smccanne tsleep(cp, pri, s, t) 32651425Smccanne register caddr_t cp; 32751425Smccanne register int pri; 32851425Smccanne char *s; 32951425Smccanne register int t; 33051425Smccanne { 33151425Smccanne register struct bpf_d *d = (struct bpf_d *)cp; 33251425Smccanne register int error; 33351425Smccanne 33451425Smccanne if (t != 0) { 33551425Smccanne d->bd_timedout = 0; 33651425Smccanne timeout(bpf_timeout, cp); 33751425Smccanne } 33851425Smccanne error = sleep(cp, pri); 33951425Smccanne if (t != 0) { 34051425Smccanne if (d->bd_timedout != 0) 34151425Smccanne return EWOULDBLOCK; 34251425Smccanne untimeout(bpf_timeout, cp); 34351425Smccanne } 34451425Smccanne return error; 34551425Smccanne } 34651425Smccanne #endif 34751425Smccanne 34847584Smccanne /* 34948932Smccanne * Rotate the packet buffers in descriptor d. Move the store buffer 35048932Smccanne * into the hold slot, and the free buffer into the store slot. 35148932Smccanne * Zero the length of the new store buffer. 35248932Smccanne */ 35348932Smccanne #define ROTATE_BUFFERS(d) \ 35448932Smccanne (d)->bd_hbuf = (d)->bd_sbuf; \ 35548932Smccanne (d)->bd_hlen = (d)->bd_slen; \ 35648932Smccanne (d)->bd_sbuf = (d)->bd_fbuf; \ 35748932Smccanne (d)->bd_slen = 0; \ 35848932Smccanne (d)->bd_fbuf = 0; 35948932Smccanne /* 36047584Smccanne * bpfread - read next chunk of packets from buffers 36147584Smccanne */ 36247584Smccanne int 36347584Smccanne bpfread(dev, uio) 36447584Smccanne dev_t dev; 36547584Smccanne register struct uio *uio; 36647584Smccanne { 36747584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 36847584Smccanne int error; 36947584Smccanne int s; 37047584Smccanne 37147584Smccanne /* 37247584Smccanne * Restrict application to use a buffer the same size as 37347584Smccanne * as kernel buffers. 37447584Smccanne */ 37548932Smccanne if (uio->uio_resid != d->bd_bufsize) 37649202Smccanne return (EINVAL); 37747584Smccanne 37847584Smccanne s = splimp(); 37947584Smccanne /* 38047584Smccanne * If the hold buffer is empty, then set a timer and sleep 38147584Smccanne * until either the timeout has occurred or enough packets have 38247584Smccanne * arrived to fill the store buffer. 38347584Smccanne */ 38447584Smccanne while (d->bd_hbuf == 0) { 38548932Smccanne if (d->bd_immediate && d->bd_slen != 0) { 38647584Smccanne /* 38747584Smccanne * A packet(s) either arrived since the previous 38847584Smccanne * read or arrived while we were asleep. 38947584Smccanne * Rotate the buffers and return what's here. 39047584Smccanne */ 39148932Smccanne ROTATE_BUFFERS(d); 39247584Smccanne break; 39347584Smccanne } 39448932Smccanne error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf", d->bd_rtout); 39548932Smccanne if (error == EINTR || error == ERESTART) { 39648932Smccanne splx(s); 39748932Smccanne return (error); 39847584Smccanne } 39948932Smccanne if (error == EWOULDBLOCK) { 40047584Smccanne /* 40147584Smccanne * On a timeout, return what's in the buffer, 40248932Smccanne * which may be nothing. If there is something 40348932Smccanne * in the store buffer, we can rotate the buffers. 40447584Smccanne */ 40547584Smccanne if (d->bd_hbuf) 40647584Smccanne /* 40747584Smccanne * We filled up the buffer in between 40847584Smccanne * getting the timeout and arriving 40947584Smccanne * here, so we don't need to rotate. 41047584Smccanne */ 41147584Smccanne break; 41247584Smccanne 41348932Smccanne if (d->bd_slen == 0) { 41447584Smccanne splx(s); 41548932Smccanne return (0); 41647584Smccanne } 41748932Smccanne ROTATE_BUFFERS(d); 41847584Smccanne break; 41947584Smccanne } 42047584Smccanne } 42147584Smccanne /* 42247584Smccanne * At this point, we know we have something in the hold slot. 42347584Smccanne */ 42447584Smccanne splx(s); 42547584Smccanne 42647584Smccanne /* 42747584Smccanne * Move data from hold buffer into user space. 42847584Smccanne * We know the entire buffer is transferred since 42948932Smccanne * we checked above that the read buffer is bpf_bufsize bytes. 43047584Smccanne */ 43151425Smccanne #if BSD >= 199103 43248932Smccanne error = uiomove(d->bd_hbuf, d->bd_hlen, uio); 43351425Smccanne #else 43451425Smccanne error = uiomove(d->bd_hbuf, d->bd_hlen, UIO_READ, uio); 43551425Smccanne #endif 43647584Smccanne s = splimp(); 43748932Smccanne d->bd_fbuf = d->bd_hbuf; 43848932Smccanne d->bd_hbuf = 0; 43947584Smccanne splx(s); 44047584Smccanne 44148932Smccanne return (error); 44247584Smccanne } 44347584Smccanne 44447584Smccanne 44547584Smccanne /* 44648932Smccanne * If there are processes sleeping on this descriptor, wake them up. 44747584Smccanne */ 44847584Smccanne static inline void 44947584Smccanne bpf_wakeup(d) 45047584Smccanne register struct bpf_d *d; 45147584Smccanne { 45248932Smccanne wakeup((caddr_t)d); 45348932Smccanne if (d->bd_selproc) { 45448932Smccanne selwakeup(d->bd_selproc, (int)d->bd_selcoll); 45548932Smccanne d->bd_selcoll = 0; 45648932Smccanne d->bd_selproc = 0; 45747584Smccanne } 45847584Smccanne } 45947584Smccanne 46047584Smccanne int 46147584Smccanne bpfwrite(dev, uio) 46247584Smccanne dev_t dev; 46347584Smccanne struct uio *uio; 46447584Smccanne { 46547584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 46647584Smccanne struct ifnet *ifp; 46747584Smccanne struct mbuf *m; 46847584Smccanne int error, s; 46947584Smccanne static struct sockaddr dst; 47047584Smccanne 47147584Smccanne if (d->bd_bif == 0) 47248932Smccanne return (ENXIO); 47347584Smccanne 47447584Smccanne ifp = d->bd_bif->bif_ifp; 47547584Smccanne 47647584Smccanne if (uio->uio_resid == 0) 47748932Smccanne return (0); 47847584Smccanne if (uio->uio_resid > ifp->if_mtu) 47948932Smccanne return (EMSGSIZE); 48047584Smccanne 48149202Smccanne error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst); 48247584Smccanne if (error) 48348932Smccanne return (error); 48447584Smccanne 48547584Smccanne s = splnet(); 48651425Smccanne #if BSD >= 199103 48751425Smccanne error = (*ifp->if_output)(ifp, m, &dst, (struct rtenty *)0); 48851425Smccanne #else 48947584Smccanne error = (*ifp->if_output)(ifp, m, &dst); 49051425Smccanne #endif 49147584Smccanne splx(s); 49247584Smccanne /* 49347584Smccanne * The driver frees the mbuf. 49447584Smccanne */ 49548932Smccanne return (error); 49647584Smccanne } 49747584Smccanne 49847584Smccanne /* 49948932Smccanne * Reset a descriptor by flushing its packet bufferand clearing the receive 50048932Smccanne * and drop counts. Should be called at splimp. 50147584Smccanne */ 50247584Smccanne static void 50347584Smccanne reset_d(d) 50447584Smccanne struct bpf_d *d; 50547584Smccanne { 50647584Smccanne if (d->bd_hbuf) { 50747584Smccanne /* Free the hold buffer. */ 50847584Smccanne d->bd_fbuf = d->bd_hbuf; 50947584Smccanne d->bd_hbuf = 0; 51047584Smccanne } 51148932Smccanne d->bd_slen = 0; 51247584Smccanne d->bd_rcount = 0; 51347584Smccanne d->bd_dcount = 0; 51447584Smccanne } 51547584Smccanne 51647584Smccanne /* 51747584Smccanne * FIONREAD Check for read packet available. 51847584Smccanne * SIOCGIFADDR Get interface address - convenient hook to driver. 51947584Smccanne * BIOCGBLEN Get buffer len [for read()]. 52047584Smccanne * BIOCSETF Set ethernet read filter. 52147584Smccanne * BIOCFLUSH Flush read packet buffer. 52247584Smccanne * BIOCPROMISC Put interface into promiscuous mode. 52349202Smccanne * BIOCGDLT Get link layer type. 52447584Smccanne * BIOCGETIF Get interface name. 52547584Smccanne * BIOCSETIF Set interface. 52647584Smccanne * BIOCSRTIMEOUT Set read timeout. 52747584Smccanne * BIOCGRTIMEOUT Get read timeout. 52847584Smccanne * BIOCGSTATS Get packet stats. 52947584Smccanne * BIOCIMMEDIATE Set immediate mode. 53047584Smccanne */ 53147584Smccanne /* ARGSUSED */ 53247584Smccanne int 53347584Smccanne bpfioctl(dev, cmd, addr, flag) 53447584Smccanne dev_t dev; 53547584Smccanne int cmd; 53647584Smccanne caddr_t addr; 53747584Smccanne int flag; 53847584Smccanne { 53947584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 54047584Smccanne int s, error = 0; 54147584Smccanne 54247584Smccanne switch (cmd) { 54347584Smccanne 54447584Smccanne default: 54547584Smccanne error = EINVAL; 54647584Smccanne break; 54747584Smccanne 54847584Smccanne /* 54947584Smccanne * Check for read packet available. 55047584Smccanne */ 55147584Smccanne case FIONREAD: 55247584Smccanne { 55347584Smccanne int n; 55447584Smccanne 55547584Smccanne s = splimp(); 55648932Smccanne n = d->bd_slen; 55747584Smccanne if (d->bd_hbuf) 55848932Smccanne n += d->bd_hlen; 55947584Smccanne splx(s); 56047584Smccanne 56147584Smccanne *(int *)addr = n; 56247584Smccanne break; 56347584Smccanne } 56447584Smccanne 56547584Smccanne case SIOCGIFADDR: 56647584Smccanne { 56747584Smccanne struct ifnet *ifp; 56847584Smccanne 56947584Smccanne if (d->bd_bif == 0) 57047584Smccanne error = EINVAL; 57147584Smccanne else { 57247584Smccanne ifp = d->bd_bif->bif_ifp; 57347584Smccanne error = (*ifp->if_ioctl)(ifp, cmd, addr); 57447584Smccanne } 57547584Smccanne break; 57647584Smccanne } 57747584Smccanne 57847584Smccanne /* 57947584Smccanne * Get buffer len [for read()]. 58047584Smccanne */ 58147584Smccanne case BIOCGBLEN: 58248932Smccanne *(u_int *)addr = d->bd_bufsize; 58347584Smccanne break; 58447584Smccanne 58547584Smccanne /* 58651425Smccanne * Set link layer read filter. 58747584Smccanne */ 58847584Smccanne case BIOCSETF: 58947584Smccanne error = bpf_setf(d, (struct bpf_program *)addr); 59047584Smccanne break; 59147584Smccanne 59247584Smccanne /* 59347584Smccanne * Flush read packet buffer. 59447584Smccanne */ 59547584Smccanne case BIOCFLUSH: 59647584Smccanne s = splimp(); 59747584Smccanne reset_d(d); 59847584Smccanne splx(s); 59947584Smccanne break; 60047584Smccanne 60147584Smccanne /* 60247584Smccanne * Put interface into promiscuous mode. 60347584Smccanne */ 60447584Smccanne case BIOCPROMISC: 60547584Smccanne if (d->bd_bif == 0) { 60647584Smccanne /* 60747584Smccanne * No interface attached yet. 60847584Smccanne */ 60947584Smccanne error = EINVAL; 61047584Smccanne break; 61147584Smccanne } 61247584Smccanne s = splimp(); 61347584Smccanne if (d->bd_promisc == 0) { 61447584Smccanne error = ifpromisc(d->bd_bif->bif_ifp, 1); 61551425Smccanne if (error == 0) 61651425Smccanne d->bd_promisc = 1; 61747584Smccanne } 61847584Smccanne splx(s); 61947584Smccanne break; 62047584Smccanne 62147584Smccanne /* 62247584Smccanne * Get device parameters. 62347584Smccanne */ 62449202Smccanne case BIOCGDLT: 62547584Smccanne if (d->bd_bif == 0) 62647584Smccanne error = EINVAL; 62747584Smccanne else 62849202Smccanne *(u_int *)addr = d->bd_bif->bif_dlt; 62947584Smccanne break; 63047584Smccanne 63147584Smccanne /* 63247584Smccanne * Set interface name. 63347584Smccanne */ 63447584Smccanne case BIOCGETIF: 63547584Smccanne if (d->bd_bif == 0) 63647584Smccanne error = EINVAL; 63747584Smccanne else 63847584Smccanne bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr); 63947584Smccanne break; 64047584Smccanne 64147584Smccanne /* 64247584Smccanne * Set interface. 64347584Smccanne */ 64447584Smccanne case BIOCSETIF: 64547584Smccanne error = bpf_setif(d, (struct ifreq *)addr); 64647584Smccanne break; 64747584Smccanne 64847584Smccanne /* 64947584Smccanne * Set read timeout. 65047584Smccanne */ 65147584Smccanne case BIOCSRTIMEOUT: 65247584Smccanne { 65347584Smccanne struct timeval *tv = (struct timeval *)addr; 65447584Smccanne u_long msec; 65547584Smccanne 65647584Smccanne /* Compute number of milliseconds. */ 65747584Smccanne msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; 65847584Smccanne /* Scale milliseconds to ticks. Assume hard 65947584Smccanne clock has millisecond or greater resolution 66047584Smccanne (i.e. tick >= 1000). For 10ms hardclock, 66147584Smccanne tick/1000 = 10, so rtout<-msec/10. */ 66247584Smccanne d->bd_rtout = msec / (tick / 1000); 66347584Smccanne break; 66447584Smccanne } 66547584Smccanne 66647584Smccanne /* 66747584Smccanne * Get read timeout. 66847584Smccanne */ 66947584Smccanne case BIOCGRTIMEOUT: 67047584Smccanne { 67147584Smccanne struct timeval *tv = (struct timeval *)addr; 67247584Smccanne u_long msec = d->bd_rtout; 67347584Smccanne 67447584Smccanne msec *= tick / 1000; 67547584Smccanne tv->tv_sec = msec / 1000; 67647584Smccanne tv->tv_usec = msec % 1000; 67747584Smccanne break; 67847584Smccanne } 67947584Smccanne 68047584Smccanne /* 68147584Smccanne * Get packet stats. 68247584Smccanne */ 68347584Smccanne case BIOCGSTATS: 68447584Smccanne { 68547584Smccanne struct bpf_stat *bs = (struct bpf_stat *)addr; 68647584Smccanne 68747584Smccanne bs->bs_recv = d->bd_rcount; 68847584Smccanne bs->bs_drop = d->bd_dcount; 68947584Smccanne break; 69047584Smccanne } 69147584Smccanne 69247584Smccanne /* 69347584Smccanne * Set immediate mode. 69447584Smccanne */ 69547584Smccanne case BIOCIMMEDIATE: 69647584Smccanne d->bd_immediate = *(u_int *)addr; 69747584Smccanne break; 69847584Smccanne } 69948932Smccanne return (error); 70047584Smccanne } 70147584Smccanne 70247584Smccanne /* 70351425Smccanne * Set d's packet filter program to fp. If this file already has a filter, 70448932Smccanne * free it and replace it. Returns EINVAL for bogus requests. 70547584Smccanne */ 70647584Smccanne int 70747584Smccanne bpf_setf(d, fp) 70847584Smccanne struct bpf_d *d; 70947584Smccanne struct bpf_program *fp; 71047584Smccanne { 71148932Smccanne struct bpf_insn *fcode, *old; 71247584Smccanne u_int flen, size; 71347584Smccanne int s; 71447584Smccanne 71548932Smccanne old = d->bd_filter; 71647584Smccanne if (fp->bf_insns == 0) { 71747584Smccanne if (fp->bf_len != 0) 71848932Smccanne return (EINVAL); 71948932Smccanne s = splimp(); 72048967Smccanne d->bd_filter = 0; 72147584Smccanne reset_d(d); 72247584Smccanne splx(s); 72348967Smccanne if (old != 0) 72448932Smccanne free((caddr_t)old, M_DEVBUF); 72548932Smccanne return (0); 72647584Smccanne } 72747584Smccanne flen = fp->bf_len; 72848932Smccanne if (flen > BPF_MAXINSNS) 72948932Smccanne return (EINVAL); 73048932Smccanne 73147584Smccanne size = flen * sizeof(*fp->bf_insns); 73248932Smccanne fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK); 73350417Smccanne if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && 73450417Smccanne bpf_validate(fcode, (int)flen)) { 73548967Smccanne s = splimp(); 73648932Smccanne d->bd_filter = fcode; 73747584Smccanne reset_d(d); 73847584Smccanne splx(s); 73948967Smccanne if (old != 0) 74048932Smccanne free((caddr_t)old, M_DEVBUF); 74147584Smccanne 74248932Smccanne return (0); 74347584Smccanne } 74448932Smccanne free((caddr_t)fcode, M_DEVBUF); 74548932Smccanne return (EINVAL); 74647584Smccanne } 74747584Smccanne 74847584Smccanne /* 74951425Smccanne * Detach a file from its current interface (if attached at all) and attach 75051425Smccanne * to the interface indicated by the name stored in ifr. 75151425Smccanne * Return an errno or 0. 75247584Smccanne */ 75347584Smccanne static int 75447584Smccanne bpf_setif(d, ifr) 75547584Smccanne struct bpf_d *d; 75647584Smccanne struct ifreq *ifr; 75747584Smccanne { 75847584Smccanne struct bpf_if *bp; 75947584Smccanne char *cp; 76049202Smccanne int unit, s; 76147584Smccanne 76247584Smccanne /* 76347584Smccanne * Separate string into name part and unit number. Put a null 76447584Smccanne * byte at the end of the name part, and compute the number. 76547584Smccanne * If the a unit number is unspecified, the default is 0, 76648932Smccanne * as initialized above. XXX This should be common code. 76747584Smccanne */ 76847584Smccanne unit = 0; 76947584Smccanne cp = ifr->ifr_name; 77047584Smccanne cp[sizeof(ifr->ifr_name) - 1] = '\0'; 77147584Smccanne while (*cp++) { 77247584Smccanne if (*cp >= '0' && *cp <= '9') { 77347584Smccanne unit = *cp - '0'; 77447584Smccanne *cp++ = '\0'; 77547584Smccanne while (*cp) 77647584Smccanne unit = 10 * unit + *cp++ - '0'; 77747584Smccanne break; 77847584Smccanne } 77947584Smccanne } 78047584Smccanne /* 78147584Smccanne * Look through attached interfaces for the named one. 78247584Smccanne */ 78349202Smccanne for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { 78447584Smccanne struct ifnet *ifp = bp->bif_ifp; 78547584Smccanne 78647584Smccanne if (ifp == 0 || unit != ifp->if_unit 78747584Smccanne || strcmp(ifp->if_name, ifr->ifr_name) != 0) 78847584Smccanne continue; 78947584Smccanne /* 79047584Smccanne * We found the requested interface. If we're 79147584Smccanne * already attached to it, just flush the buffer. 79247584Smccanne * If it's not up, return an error. 79347584Smccanne */ 79447584Smccanne if ((ifp->if_flags & IFF_UP) == 0) 79548932Smccanne return (ENETDOWN); 79647584Smccanne s = splimp(); 79747584Smccanne if (bp != d->bd_bif) { 79847584Smccanne if (d->bd_bif) 79947584Smccanne /* 80048932Smccanne * Detach if attached to something else. 80147584Smccanne */ 80247584Smccanne bpf_detachd(d); 80347584Smccanne 80447584Smccanne bpf_attachd(d, bp); 80547584Smccanne } 80647584Smccanne reset_d(d); 80747584Smccanne splx(s); 80848932Smccanne return (0); 80947584Smccanne } 81047584Smccanne /* Not found. */ 81148932Smccanne return (ENXIO); 81247584Smccanne } 81347584Smccanne 81447584Smccanne /* 81551425Smccanne * Convert an interface name plus unit number of an ifp to a single 81651425Smccanne * name which is returned in the ifr. 81747584Smccanne */ 81847584Smccanne static void 81947584Smccanne bpf_ifname(ifp, ifr) 82047584Smccanne struct ifnet *ifp; 82147584Smccanne struct ifreq *ifr; 82247584Smccanne { 82347584Smccanne char *s = ifp->if_name; 82447584Smccanne char *d = ifr->ifr_name; 82547584Smccanne 82647584Smccanne while (*d++ = *s++) 82747584Smccanne ; 82848932Smccanne /* XXX Assume that unit number is less than 10. */ 82947584Smccanne *d++ = ifp->if_unit + '0'; 83047584Smccanne *d = '\0'; 83147584Smccanne } 83247584Smccanne 83347584Smccanne /* 83451425Smccanne * The new select interface passes down the proc pointer; the old select 83551425Smccanne * stubs had to grab it out of the user struct. This glue allows either case. 83651425Smccanne */ 83751425Smccanne #if BSD >= 199103 83851425Smccanne #define bpf_select bpfselect 83951425Smccanne #else 84051425Smccanne int 84151425Smccanne bpfselect(dev, rw) 84251425Smccanne register dev_t dev; 84351425Smccanne int rw; 84451425Smccanne { 84551425Smccanne bpf_select(dev, rw, u.u_procp); 84651425Smccanne } 84751425Smccanne #endif 84851425Smccanne 84951425Smccanne /* 85047584Smccanne * Support for select() system call 85147584Smccanne * Inspired by the code in tty.c for the same purpose. 85247584Smccanne * 85347584Smccanne * bpfselect - returns true iff the specific operation 85447584Smccanne * will not block indefinitely. Otherwise, return 85547584Smccanne * false but make a note that a selwakeup() must be done. 85647584Smccanne */ 85747584Smccanne int 85851425Smccanne bpf_select(dev, rw, p) 85947584Smccanne register dev_t dev; 86047584Smccanne int rw; 86148932Smccanne struct proc *p; 86247584Smccanne { 86347584Smccanne register struct bpf_d *d; 86447584Smccanne register int s; 86547584Smccanne 86647584Smccanne if (rw != FREAD) 86748932Smccanne return (0); 86847584Smccanne /* 86947584Smccanne * An imitation of the FIONREAD ioctl code. 87047584Smccanne */ 87147584Smccanne d = &bpf_dtab[minor(dev)]; 87247584Smccanne 87347584Smccanne s = splimp(); 87449723Smccanne if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) { 87547584Smccanne /* 87647584Smccanne * There is data waiting. 87747584Smccanne */ 87847584Smccanne splx(s); 87948932Smccanne return (1); 88047584Smccanne } 88147584Smccanne /* 88247584Smccanne * No data ready. If there's already a select() waiting on this 88347584Smccanne * minor device then this is a collision. This shouldn't happen 88447584Smccanne * because minors really should not be shared, but if a process 88547584Smccanne * forks while one of these is open, it is possible that both 88647584Smccanne * processes could select on the same descriptor. 88747584Smccanne */ 88848932Smccanne if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait) 88948932Smccanne d->bd_selcoll = 1; 89047584Smccanne else 89148932Smccanne d->bd_selproc = p; 89248932Smccanne 89347584Smccanne splx(s); 89448932Smccanne return (0); 89547584Smccanne } 89647584Smccanne 89747584Smccanne /* 89847584Smccanne * bpf_tap - incoming linkage from device drivers 89947584Smccanne */ 90047584Smccanne void 90148932Smccanne bpf_tap(arg, pkt, pktlen) 90247584Smccanne caddr_t arg; 90348932Smccanne register u_char *pkt; 90448932Smccanne register u_int pktlen; 90547584Smccanne { 90647584Smccanne struct bpf_if *bp; 90747584Smccanne register struct bpf_d *d; 90847584Smccanne register u_int slen; 90947584Smccanne /* 91047584Smccanne * Note that the ipl does not have to be raised at this point. 91147584Smccanne * The only problem that could arise here is that if two different 91247584Smccanne * interfaces shared any data. This is not the case. 91347584Smccanne */ 91447584Smccanne bp = (struct bpf_if *)arg; 91547584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 91647584Smccanne ++d->bd_rcount; 91749202Smccanne slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 91847584Smccanne if (slen != 0) 91949202Smccanne catchpacket(d, pkt, pktlen, slen, bcopy); 92047584Smccanne } 92147584Smccanne } 92247584Smccanne 92347584Smccanne /* 92447584Smccanne * Copy data from an mbuf chain into a buffer. This code is derived 92547584Smccanne * from m_copydata in sys/uipc_mbuf.c. 92647584Smccanne */ 92747584Smccanne static void 92849202Smccanne bpf_mcopy(src, dst, len) 92947584Smccanne u_char *src; 93047584Smccanne u_char *dst; 93147584Smccanne register int len; 93247584Smccanne { 93347584Smccanne register struct mbuf *m = (struct mbuf *)src; 93447584Smccanne register unsigned count; 93547584Smccanne 93647584Smccanne while (len > 0) { 93747584Smccanne if (m == 0) 93849202Smccanne panic("bpf_mcopy"); 93947584Smccanne count = MIN(m->m_len, len); 94049202Smccanne bcopy(mtod(m, caddr_t), (caddr_t)dst, count); 94149202Smccanne m = m->m_next; 94249202Smccanne dst += count; 94347584Smccanne len -= count; 94447584Smccanne } 94547584Smccanne } 94647584Smccanne 94747584Smccanne /* 94851425Smccanne * bpf_mtap - incoming linkage from device drivers, when packet 94951425Smccanne * is in an mbuf chain 95047584Smccanne */ 95147584Smccanne void 95249202Smccanne bpf_mtap(arg, m) 95347584Smccanne caddr_t arg; 95449202Smccanne struct mbuf *m; 95547584Smccanne { 95647584Smccanne struct bpf_if *bp = (struct bpf_if *)arg; 95747584Smccanne struct bpf_d *d; 95849202Smccanne u_int pktlen, slen; 95949202Smccanne struct mbuf *m0; 96047584Smccanne 96148932Smccanne pktlen = 0; 96251425Smccanne for (m0 = m; m0 != 0; m0 = m0->m_next) 96349202Smccanne pktlen += m0->m_len; 96449723Smccanne 96547584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 96647584Smccanne ++d->bd_rcount; 96749202Smccanne slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); 96847584Smccanne if (slen != 0) 96949202Smccanne catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); 97047584Smccanne } 97147584Smccanne } 97247584Smccanne 97347584Smccanne /* 97449202Smccanne * Move the packet data from interface memory (pkt) into the 97547584Smccanne * store buffer. Return 1 if it's time to wakeup a listener (buffer full), 97651425Smccanne * otherwise 0. "copy" is the routine called to do the actual data 97751425Smccanne * transfer. bcopy is passed in to copy contiguous chunks, while 97851425Smccanne * bpf_mcopy is passed in to copy mbuf chains. In the latter case, 97951425Smccanne * pkt is really an mbuf. 98047584Smccanne */ 98147584Smccanne static void 98248932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn) 98348932Smccanne register struct bpf_d *d; 98448932Smccanne register u_char *pkt; 98548932Smccanne register u_int pktlen, snaplen; 98648932Smccanne register void (*cpfn)(); 98747584Smccanne { 98848932Smccanne register struct bpf_hdr *hp; 98948932Smccanne register int totlen, curlen; 99048932Smccanne register int hdrlen = d->bd_bif->bif_hdrlen; 99147584Smccanne /* 99247584Smccanne * Figure out how many bytes to move. If the packet is 99347584Smccanne * greater or equal to the snapshot length, transfer that 99447584Smccanne * much. Otherwise, transfer the whole packet (unless 99548932Smccanne * we hit the buffer size limit). 99647584Smccanne */ 99750082Smccanne totlen = hdrlen + MIN(snaplen, pktlen); 99850082Smccanne if (totlen > d->bd_bufsize) 99950082Smccanne totlen = d->bd_bufsize; 100047584Smccanne 100147584Smccanne /* 100247584Smccanne * Round up the end of the previous packet to the next longword. 100347584Smccanne */ 100448932Smccanne curlen = BPF_WORDALIGN(d->bd_slen); 100548932Smccanne if (curlen + totlen > d->bd_bufsize) { 100647584Smccanne /* 100747584Smccanne * This packet will overflow the storage buffer. 100848932Smccanne * Rotate the buffers if we can, then wakeup any 100948932Smccanne * pending reads. 101047584Smccanne */ 101147584Smccanne if (d->bd_fbuf == 0) { 101247584Smccanne /* 101348932Smccanne * We haven't completed the previous read yet, 101448932Smccanne * so drop the packet. 101547584Smccanne */ 101647584Smccanne ++d->bd_dcount; 101747584Smccanne return; 101847584Smccanne } 101948932Smccanne ROTATE_BUFFERS(d); 102047584Smccanne bpf_wakeup(d); 102148932Smccanne curlen = 0; 102247584Smccanne } 102348932Smccanne else if (d->bd_immediate) 102447584Smccanne /* 102547584Smccanne * Immediate mode is set. A packet arrived so any 102647584Smccanne * reads should be woken up. 102747584Smccanne */ 102847584Smccanne bpf_wakeup(d); 102948932Smccanne 103047584Smccanne /* 103147584Smccanne * Append the bpf header. 103247584Smccanne */ 103348932Smccanne hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); 103447584Smccanne #ifdef sun 103547584Smccanne uniqtime(&hp->bh_tstamp); 103647584Smccanne #else 103751425Smccanne #if BSD >= 199103 103847584Smccanne microtime(&hp->bh_tstamp); 103947584Smccanne #else 104047584Smccanne hp->bh_tstamp = time; 104147584Smccanne #endif 104247584Smccanne #endif 104348932Smccanne hp->bh_datalen = pktlen; 104447584Smccanne hp->bh_hdrlen = hdrlen; 104547584Smccanne /* 104648932Smccanne * Copy the packet data into the store buffer and update its length. 104747584Smccanne */ 104848932Smccanne (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); 104948932Smccanne d->bd_slen = curlen + totlen; 105047584Smccanne } 105147584Smccanne 105247584Smccanne /* 105347584Smccanne * Initialize all nonzero fields of a descriptor. 105447584Smccanne */ 105547584Smccanne static int 105647584Smccanne bpf_initd(d) 105747584Smccanne register struct bpf_d *d; 105847584Smccanne { 105948932Smccanne d->bd_bufsize = bpf_bufsize; 106048932Smccanne d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 106148932Smccanne if (d->bd_fbuf == 0) 106248932Smccanne return (ENOBUFS); 106347584Smccanne 106448932Smccanne d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 106548932Smccanne if (d->bd_sbuf == 0) { 106648932Smccanne free(d->bd_fbuf, M_DEVBUF); 106748932Smccanne return (ENOBUFS); 106847584Smccanne } 106948932Smccanne d->bd_slen = 0; 107048932Smccanne d->bd_hlen = 0; 107148932Smccanne return (0); 107247584Smccanne } 107347584Smccanne 107447584Smccanne /* 107551425Smccanne * Free buffers currently in use by a descriptor. 107651425Smccanne * Called on close. 107747584Smccanne */ 107851425Smccanne bpf_freed(d) 107951425Smccanne register struct bpf_d *d; 108051425Smccanne { 108151425Smccanne /* 108251425Smccanne * We don't need to lock out interrupts since this descriptor has 108351425Smccanne * been detached from its interface and it yet hasn't been marked 108451425Smccanne * free. 108551425Smccanne */ 108651425Smccanne if (d->bd_hbuf) 108751425Smccanne free(d->bd_hbuf, M_DEVBUF); 108851425Smccanne if (d->bd_fbuf) 108951425Smccanne free(d->bd_fbuf, M_DEVBUF); 109051425Smccanne free(d->bd_sbuf, M_DEVBUF); 109151425Smccanne if (d->bd_filter) 109251425Smccanne free((caddr_t)d->bd_filter, M_DEVBUF); 109351425Smccanne 109451425Smccanne D_MARKFREE(d); 109551425Smccanne } 109651425Smccanne 109751425Smccanne /* 109851425Smccanne * Attach an interface to bpf. driverp is a pointer to a (struct bpf_if *) 109951425Smccanne * in the driver's softc; dlt is the link layer type; hdrlen is the fixed 110051425Smccanne * size of the link header (variable length headers not yet supported). 110151425Smccanne */ 110247584Smccanne void 110349202Smccanne bpfattach(driverp, ifp, dlt, hdrlen) 110447584Smccanne caddr_t *driverp; 110547584Smccanne struct ifnet *ifp; 110649202Smccanne u_int dlt, hdrlen; 110747584Smccanne { 110847584Smccanne struct bpf_if *bp; 110947584Smccanne int i; 111051425Smccanne #if BSD < 199103 111151425Smccanne static struct bpf_if bpf_ifs[NBPFILTER]; 111251425Smccanne static int bpfifno; 111347584Smccanne 111451425Smccanne bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0; 111551425Smccanne #else 111649202Smccanne bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT); 111751425Smccanne #endif 111849202Smccanne if (bp == 0) 111949202Smccanne panic("bpfattach"); 112047584Smccanne 112147584Smccanne bp->bif_dlist = 0; 112247584Smccanne bp->bif_driverp = (struct bpf_if **)driverp; 112347584Smccanne bp->bif_ifp = ifp; 112449202Smccanne bp->bif_dlt = dlt; 112547584Smccanne 112649202Smccanne bp->bif_next = bpf_iflist; 112749202Smccanne bpf_iflist = bp; 112849202Smccanne 112948932Smccanne *bp->bif_driverp = 0; 113048932Smccanne 113147584Smccanne /* 113247584Smccanne * Compute the length of the bpf header. This is not necessarily 113347584Smccanne * equal to SIZEOF_BPF_HDR because we want to insert spacing such 113447584Smccanne * that the network layer header begins on a longword boundary (for 113547584Smccanne * performance reasons and to alleviate alignment restrictions). 113647584Smccanne */ 113749202Smccanne bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; 113847584Smccanne 113947584Smccanne /* 114047584Smccanne * Mark all the descriptors free if this hasn't been done. 114147584Smccanne */ 114247584Smccanne if (!D_ISFREE(&bpf_dtab[0])) 114347584Smccanne for (i = 0; i < NBPFILTER; ++i) 114447584Smccanne D_MARKFREE(&bpf_dtab[i]); 114547584Smccanne 114647584Smccanne printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); 114747584Smccanne } 114847584Smccanne 114951425Smccanne #if BSD >= 199103 115048967Smccanne /* XXX This routine belongs in net/if.c. */ 115148932Smccanne /* 115248932Smccanne * Set/clear promiscuous mode on interface ifp based on the truth value` 115348932Smccanne * of pswitch. The calls are reference counted so that only the first 115448932Smccanne * on request actually has an effect, as does the final off request. 115548932Smccanne * Results are undefined if the off and on requests are not matched. 115648932Smccanne */ 115748932Smccanne int 115848932Smccanne ifpromisc(ifp, pswitch) 115948932Smccanne struct ifnet *ifp; 116048932Smccanne int pswitch; 116148932Smccanne { 116249726Smccanne struct ifreq ifr; 116348932Smccanne /* 116448932Smccanne * If the device is not configured up, we cannot put it in 116548932Smccanne * promiscuous mode. 116648932Smccanne */ 116748932Smccanne if ((ifp->if_flags & IFF_UP) == 0) 116848932Smccanne return (ENETDOWN); 116948932Smccanne 117048932Smccanne if (pswitch) { 117148932Smccanne if (ifp->if_pcount++ != 0) 117248932Smccanne return (0); 117348932Smccanne ifp->if_flags |= IFF_PROMISC; 117448932Smccanne } else { 117548932Smccanne if (--ifp->if_pcount > 0) 117648932Smccanne return (0); 117748932Smccanne ifp->if_flags &= ~IFF_PROMISC; 117848932Smccanne } 117949726Smccanne ifr.ifr_flags = ifp->if_flags; 118049726Smccanne return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); 118148932Smccanne } 118251425Smccanne #endif 118348932Smccanne 118451425Smccanne #if BSD < 199103 118551425Smccanne /* 118651425Smccanne * Allocate some memory for bpf. This is temporary SunOS support, and 118751425Smccanne * is admittedly a gross hack. 118851425Smccanne * If resources unavaiable, return 0. 118951425Smccanne */ 119051425Smccanne static caddr_t 119151425Smccanne bpf_alloc(size, canwait) 119251425Smccanne register int size; 119351425Smccanne register int canwait; 119451425Smccanne { 119551425Smccanne register struct mbuf *m; 119651425Smccanne 119751425Smccanne if ((unsigned)size > (MCLBYTES-8)) 119851425Smccanne return 0; 119951425Smccanne 120051425Smccanne MGET(m, canwait, MT_DATA); 120151425Smccanne if (m == 0) 120251425Smccanne return 0; 120351425Smccanne if ((unsigned)size > (MLEN-8)) { 120451425Smccanne MCLGET(m); 120551425Smccanne if (m->m_len != MCLBYTES) { 120651425Smccanne m_freem(m); 120751425Smccanne return 0; 120851425Smccanne } 120951425Smccanne } 121051425Smccanne *mtod(m, struct mbuf **) = m; 121151425Smccanne return mtod(m, caddr_t) + 8; 121251425Smccanne } 121351425Smccanne #endif 121451425Smccanne #endif 1215