147584Smccanne /* 247584Smccanne * Copyright (c) 1990 The Regents of the University of California. 347584Smccanne * All rights reserved. 447584Smccanne * 547584Smccanne * Redistribution and use in source and binary forms, with or without 647584Smccanne * modification, are permitted provided that: (1) source code distributions 747584Smccanne * retain the above copyright notice and this paragraph in its entirety, (2) 847584Smccanne * distributions including binary code include the above copyright notice and 947584Smccanne * this paragraph in its entirety in the documentation or other materials 1047584Smccanne * provided with the distribution, and (3) all advertising materials mentioning 1147584Smccanne * features or use of this software display the following acknowledgement: 1247584Smccanne * ``This product includes software developed by the University of California, 1347584Smccanne * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1447584Smccanne * the University nor the names of its contributors may be used to endorse 1547584Smccanne * or promote products derived from this software without specific prior 1647584Smccanne * written permission. 1747584Smccanne * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1847584Smccanne * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1947584Smccanne * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2047584Smccanne * 2147584Smccanne * This code is derived from the Stanford/CMU enet packet filter, 2247584Smccanne * (net/enet.c) distributed in 4.3BSD Unix. 2347584Smccanne */ 2447584Smccanne #ifndef lint 2547584Smccanne static char rcsid[] = 2647584Smccanne "$Header: bpf.c,v 1.23 91/01/30 18:22:13 mccanne Exp $"; 2747584Smccanne #endif 2847584Smccanne 2947584Smccanne #include "bpfilter.h" 3047584Smccanne 3147584Smccanne #if (NBPFILTER > 0) 3247584Smccanne 3347584Smccanne #ifndef __GNUC__ 3447584Smccanne #define inline 3547584Smccanne #endif 3647584Smccanne 3747584Smccanne #include <sys/param.h> 3847584Smccanne #include <sys/systm.h> 3947584Smccanne #include <sys/mbuf.h> 4047584Smccanne #include <sys/buf.h> 4147584Smccanne #include <sys/dir.h> 42*48932Smccanne #include <sys/proc.h> 4347584Smccanne #include <sys/user.h> 4447584Smccanne #include <sys/ioctl.h> 4547584Smccanne #include <sys/map.h> 4647584Smccanne 4747584Smccanne #include <sys/file.h> 4847584Smccanne #ifdef sparc 4947584Smccanne #include <sys/stream.h> 5047584Smccanne #endif 5147584Smccanne #include <sys/tty.h> 5247584Smccanne #include <sys/uio.h> 5347584Smccanne 5447584Smccanne #include <sys/protosw.h> 5547584Smccanne #include <sys/socket.h> 5647584Smccanne #include <net/if.h> 5747584Smccanne 5847584Smccanne #include <net/bpf.h> 5947584Smccanne #include <net/bpfdesc.h> 6047584Smccanne 6147584Smccanne #include <sys/errno.h> 6247584Smccanne 6347584Smccanne #include <netinet/in.h> 6447584Smccanne #include <netinet/if_ether.h> 6547584Smccanne #include <sys/kernel.h> 6647584Smccanne 6747584Smccanne #define PRINET 26 /* interruptible */ 6847584Smccanne 6947584Smccanne /* 70*48932Smccanne * The default read buffer size is patchable. 71*48932Smccanne */ 72*48932Smccanne int bpf_bufsize = MCLBYTES; 73*48932Smccanne 74*48932Smccanne /* 7547584Smccanne * 'bpf_iftab' is the driver state table per logical unit number 7647584Smccanne * 'bpf_dtab' holds the descriptors, indexed by minor device # 7747584Smccanne * 'bpf_units' is the number of attached units 7847584Smccanne * 7947584Smccanne * We really don't need NBPFILTER bpf_if entries, but this eliminates 8047584Smccanne * the need to account for all possible drivers here. 8147584Smccanne * This problem will go away when these structures are allocated dynamically. 8247584Smccanne */ 8347584Smccanne static struct bpf_if bpf_iftab[NBPFILTER]; 8447584Smccanne static struct bpf_d bpf_dtab[NBPFILTER]; 8547584Smccanne static u_int bpf_units = 0; 8647584Smccanne 8747584Smccanne static void bpf_ifname(); 8847584Smccanne static void catchpacket(); 8947584Smccanne static int bpf_setif(); 9047584Smccanne static int bpf_initd(); 9147584Smccanne 9247584Smccanne /* 9347584Smccanne * The default filter accepts the maximum number of bytes from each packet. 9447584Smccanne */ 9547584Smccanne struct bpf_insn bpf_default_filter[] = { 96*48932Smccanne BPF_STMT(RetOp, -1), 9747584Smccanne }; 9847584Smccanne 9947584Smccanne static int 10047584Smccanne bpf_movein(uio, linktype, mp, sockp) 10147584Smccanne register struct uio *uio; 10247584Smccanne int linktype; 10347584Smccanne register struct mbuf **mp; 10447584Smccanne register struct sockaddr *sockp; 10547584Smccanne { 10647584Smccanne struct mbuf *m; 10747584Smccanne int error; 10847584Smccanne int len; 10947584Smccanne int hlen; 11047584Smccanne 11147584Smccanne /* 11247584Smccanne * Build a sockaddr based on the data link layer type. 11347584Smccanne * We do this at this level because the ethernet header 11447584Smccanne * is copied directly into the data field of the sockaddr. 11547584Smccanne * In the case of SLIP, there is no header and the packet 11647584Smccanne * is forwarded as is. 11747584Smccanne * Also, we are careful to leave room at the front of the mbuf 11847584Smccanne * for the link level header. 11947584Smccanne */ 12047584Smccanne switch (linktype) { 12147584Smccanne case DLT_SLIP: 12247584Smccanne sockp->sa_family = AF_INET; 12347584Smccanne hlen = 0; 12447584Smccanne break; 12547584Smccanne 12647584Smccanne case DLT_EN10MB: 12747584Smccanne sockp->sa_family = AF_UNSPEC; 12847584Smccanne /* XXX Would MAXLINKHDR be better? */ 12947584Smccanne hlen = sizeof(struct ether_header); 13047584Smccanne break; 13147584Smccanne 13247584Smccanne case DLT_FDDI: 13347584Smccanne sockp->sa_family = AF_UNSPEC; 13447584Smccanne /* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */ 13547584Smccanne hlen = 24; 13647584Smccanne break; 13747584Smccanne 13847584Smccanne default: 139*48932Smccanne return (EIO); 14047584Smccanne } 14147584Smccanne 14247584Smccanne len = uio->uio_resid; 14347584Smccanne if ((unsigned)len > MCLBYTES) 144*48932Smccanne return (EIO); 14547584Smccanne 14647584Smccanne MGET(m, M_WAIT, MT_DATA); 14747584Smccanne if (m == 0) 148*48932Smccanne return (ENOBUFS); 14947584Smccanne if (len > MLEN) { 150*48932Smccanne MCLGET(m, M_WAIT); 151*48932Smccanne if ((m->m_flags & M_EXT) == 0) { 15247584Smccanne error = ENOBUFS; 15347584Smccanne goto bad; 15447584Smccanne } 15547584Smccanne } 15647584Smccanne m->m_len = len; 15747584Smccanne *mp = m; 15847584Smccanne /* 15947584Smccanne * Make room for link header. 16047584Smccanne */ 16147584Smccanne if (hlen) { 16247584Smccanne m->m_len -= hlen; 163*48932Smccanne m->m_data += hlen; /* XXX */ 16447584Smccanne 165*48932Smccanne error = uiomove((caddr_t)sockp->sa_data, hlen, uio); 16647584Smccanne if (error) 16747584Smccanne goto bad; 16847584Smccanne } 169*48932Smccanne error = uiomove(mtod(m, caddr_t), len - hlen, uio); 17047584Smccanne if (!error) 171*48932Smccanne return (0); 17247584Smccanne bad: 17347584Smccanne m_freem(m); 174*48932Smccanne return (error); 17547584Smccanne } 17647584Smccanne 17747584Smccanne /* 17847584Smccanne * Attach 'd' to the bpf interface 'bp', i.e. make 'd' listen on 'bp'. 17947584Smccanne * Must be called at splimp. 18047584Smccanne */ 18147584Smccanne static void 18247584Smccanne bpf_attachd(d, bp) 18347584Smccanne struct bpf_d *d; 18447584Smccanne struct bpf_if *bp; 18547584Smccanne { 186*48932Smccanne /* Point d at bp. */ 18747584Smccanne d->bd_bif = bp; 18847584Smccanne 189*48932Smccanne /* Add d to bp's list of listeners. */ 19047584Smccanne d->bd_next = bp->bif_dlist; 19147584Smccanne bp->bif_dlist = d; 19247584Smccanne 19347584Smccanne /* 19447584Smccanne * Let the driver know we're here (if it doesn't already). 19547584Smccanne */ 19647584Smccanne *bp->bif_driverp = bp; 19747584Smccanne } 19847584Smccanne 19947584Smccanne static void 20047584Smccanne bpf_detachd(d) 20147584Smccanne struct bpf_d *d; 20247584Smccanne { 20347584Smccanne struct bpf_d **p; 20447584Smccanne struct bpf_if *bp; 20547584Smccanne 20647584Smccanne bp = d->bd_bif; 20747584Smccanne /* 20847584Smccanne * Check if this descriptor had requested promiscuous mode. 20947584Smccanne * If so, turn it off. 21047584Smccanne */ 21147584Smccanne if (d->bd_promisc) { 21247584Smccanne d->bd_promisc = 0; 21347584Smccanne if (ifpromisc(bp->bif_ifp, 0)) 21447584Smccanne /* 21547584Smccanne * Something is really wrong if we were able to put 21647584Smccanne * the driver into promiscuous mode, but can't 21747584Smccanne * take it out. 21847584Smccanne */ 219*48932Smccanne panic("bpf_detachd: ifpromisc failed"); 22047584Smccanne } 22147584Smccanne /* Remove 'd' from the interface's descriptor list. */ 22247584Smccanne p = &bp->bif_dlist; 22347584Smccanne while (*p != d) { 22447584Smccanne p = &(*p)->bd_next; 22547584Smccanne if (*p == 0) 22647584Smccanne panic("bpf_detachd: descriptor not in list"); 22747584Smccanne } 22847584Smccanne *p = (*p)->bd_next; 22947584Smccanne if (bp->bif_dlist == 0) 23047584Smccanne /* 23147584Smccanne * Let the driver know that there are no more listeners. 23247584Smccanne */ 23347584Smccanne *d->bd_bif->bif_driverp = 0; 23447584Smccanne d->bd_bif = 0; 23547584Smccanne } 23647584Smccanne 23747584Smccanne 23847584Smccanne /* 23947584Smccanne * Mark a descriptor free by making it point to itself. 24047584Smccanne * This is probably cheaper than marking with a constant since 24147584Smccanne * the address should be in a register anyway. 24247584Smccanne */ 24347584Smccanne #define D_ISFREE(d) ((d) == (d)->bd_next) 24447584Smccanne #define D_MARKFREE(d) ((d)->bd_next = (d)) 24547584Smccanne #define D_MARKUSED(d) ((d)->bd_next = 0) 24647584Smccanne 24747584Smccanne /* 24847584Smccanne * bpfopen - open ethernet device 24947584Smccanne * 25047584Smccanne * Errors: ENXIO - illegal minor device number 25147584Smccanne * EBUSY - too many files open 25247584Smccanne */ 25347584Smccanne /* ARGSUSED */ 25447584Smccanne int 25547584Smccanne bpfopen(dev, flag) 25647584Smccanne dev_t dev; 25747584Smccanne int flag; 25847584Smccanne { 25947584Smccanne int error, s; 26047584Smccanne register struct bpf_d *d; 26147584Smccanne 26247584Smccanne if (minor(dev) >= NBPFILTER) 263*48932Smccanne return (ENXIO); 26447584Smccanne 26547584Smccanne /* 26647584Smccanne * Each minor can be opened by only one process. If the requested 26747584Smccanne * minor is in use, return EBUSY. 26847584Smccanne */ 26947584Smccanne s = splimp(); 27047584Smccanne d = &bpf_dtab[minor(dev)]; 27147584Smccanne if (!D_ISFREE(d)) { 27247584Smccanne splx(s); 273*48932Smccanne return (EBUSY); 27447584Smccanne } else 27547584Smccanne /* Mark "free" and do most initialization. */ 27647584Smccanne bzero((char *)d, sizeof(*d)); 27747584Smccanne d->bd_filter = bpf_default_filter; 27847584Smccanne splx(s); 27947584Smccanne 28047584Smccanne error = bpf_initd(d); 28147584Smccanne if (error) { 28247584Smccanne D_MARKFREE(d); 283*48932Smccanne return (error); 28447584Smccanne } 285*48932Smccanne return (0); 28647584Smccanne } 28747584Smccanne 28847584Smccanne /* 28947584Smccanne * Close the descriptor by detaching it from its interface, 29047584Smccanne * deallocating its buffers, and marking it free. 29147584Smccanne */ 29247584Smccanne /* ARGSUSED */ 29347584Smccanne bpfclose(dev, flag) 29447584Smccanne dev_t dev; 29547584Smccanne int flag; 29647584Smccanne { 29747584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 29847584Smccanne int s; 29947584Smccanne 30047584Smccanne s = splimp(); 30147584Smccanne if (d->bd_bif) 30247584Smccanne bpf_detachd(d); 30347584Smccanne splx(s); 30447584Smccanne 305*48932Smccanne /* Free the buffer space. */ 306*48932Smccanne if (d->bd_hbuf) 307*48932Smccanne free(d->bd_hbuf, M_DEVBUF); 308*48932Smccanne if (d->bd_fbuf) 309*48932Smccanne free(d->bd_fbuf, M_DEVBUF); 310*48932Smccanne free(d->bd_sbuf, M_DEVBUF); 311*48932Smccanne 312*48932Smccanne if (d->bd_filter != bpf_default_filter) 313*48932Smccanne free((caddr_t)d->bd_filter, M_DEVBUF); 31447584Smccanne 31547584Smccanne D_MARKFREE(d); 31647584Smccanne } 31747584Smccanne 31847584Smccanne /* 319*48932Smccanne * Rotate the packet buffers in descriptor d. Move the store buffer 320*48932Smccanne * into the hold slot, and the free buffer into the store slot. 321*48932Smccanne * Zero the length of the new store buffer. 322*48932Smccanne */ 323*48932Smccanne #define ROTATE_BUFFERS(d) \ 324*48932Smccanne (d)->bd_hbuf = (d)->bd_sbuf; \ 325*48932Smccanne (d)->bd_hlen = (d)->bd_slen; \ 326*48932Smccanne (d)->bd_sbuf = (d)->bd_fbuf; \ 327*48932Smccanne (d)->bd_slen = 0; \ 328*48932Smccanne (d)->bd_fbuf = 0; 329*48932Smccanne /* 33047584Smccanne * bpfread - read next chunk of packets from buffers 33147584Smccanne */ 33247584Smccanne int 33347584Smccanne bpfread(dev, uio) 33447584Smccanne dev_t dev; 33547584Smccanne register struct uio *uio; 33647584Smccanne { 33747584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 33847584Smccanne int error; 33947584Smccanne int s; 34047584Smccanne 34147584Smccanne /* 34247584Smccanne * Restrict application to use a buffer the same size as 34347584Smccanne * as kernel buffers. 34447584Smccanne */ 345*48932Smccanne if (uio->uio_resid != d->bd_bufsize) 346*48932Smccanne return (EIO); 34747584Smccanne 34847584Smccanne s = splimp(); 34947584Smccanne /* 35047584Smccanne * If the hold buffer is empty, then set a timer and sleep 35147584Smccanne * until either the timeout has occurred or enough packets have 35247584Smccanne * arrived to fill the store buffer. 35347584Smccanne */ 35447584Smccanne while (d->bd_hbuf == 0) { 355*48932Smccanne if (d->bd_immediate && d->bd_slen != 0) { 35647584Smccanne /* 35747584Smccanne * A packet(s) either arrived since the previous 35847584Smccanne * read or arrived while we were asleep. 35947584Smccanne * Rotate the buffers and return what's here. 36047584Smccanne */ 361*48932Smccanne ROTATE_BUFFERS(d); 36247584Smccanne break; 36347584Smccanne } 364*48932Smccanne error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf", d->bd_rtout); 365*48932Smccanne if (error == EINTR || error == ERESTART) { 366*48932Smccanne splx(s); 367*48932Smccanne return (error); 36847584Smccanne } 369*48932Smccanne if (error == EWOULDBLOCK) { 37047584Smccanne /* 37147584Smccanne * On a timeout, return what's in the buffer, 372*48932Smccanne * which may be nothing. If there is something 373*48932Smccanne * in the store buffer, we can rotate the buffers. 37447584Smccanne */ 37547584Smccanne if (d->bd_hbuf) 37647584Smccanne /* 37747584Smccanne * We filled up the buffer in between 37847584Smccanne * getting the timeout and arriving 37947584Smccanne * here, so we don't need to rotate. 38047584Smccanne */ 38147584Smccanne break; 38247584Smccanne 383*48932Smccanne if (d->bd_slen == 0) { 38447584Smccanne splx(s); 385*48932Smccanne return (0); 38647584Smccanne } 387*48932Smccanne ROTATE_BUFFERS(d); 38847584Smccanne break; 38947584Smccanne } 39047584Smccanne } 39147584Smccanne /* 39247584Smccanne * At this point, we know we have something in the hold slot. 39347584Smccanne */ 39447584Smccanne splx(s); 39547584Smccanne 39647584Smccanne /* 39747584Smccanne * Move data from hold buffer into user space. 39847584Smccanne * We know the entire buffer is transferred since 399*48932Smccanne * we checked above that the read buffer is bpf_bufsize bytes. 40047584Smccanne */ 401*48932Smccanne error = uiomove(d->bd_hbuf, d->bd_hlen, uio); 40247584Smccanne 40347584Smccanne s = splimp(); 404*48932Smccanne d->bd_fbuf = d->bd_hbuf; 405*48932Smccanne d->bd_hbuf = 0; 40647584Smccanne splx(s); 40747584Smccanne 408*48932Smccanne return (error); 40947584Smccanne } 41047584Smccanne 41147584Smccanne 41247584Smccanne /* 413*48932Smccanne * If there are processes sleeping on this descriptor, wake them up. 41447584Smccanne */ 41547584Smccanne static inline void 41647584Smccanne bpf_wakeup(d) 41747584Smccanne register struct bpf_d *d; 41847584Smccanne { 419*48932Smccanne wakeup((caddr_t)d); 420*48932Smccanne if (d->bd_selproc) { 421*48932Smccanne selwakeup(d->bd_selproc, (int)d->bd_selcoll); 422*48932Smccanne d->bd_selcoll = 0; 423*48932Smccanne d->bd_selproc = 0; 42447584Smccanne } 42547584Smccanne } 42647584Smccanne 42747584Smccanne int 42847584Smccanne bpfwrite(dev, uio) 42947584Smccanne dev_t dev; 43047584Smccanne struct uio *uio; 43147584Smccanne { 43247584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 43347584Smccanne struct ifnet *ifp; 43447584Smccanne struct mbuf *m; 43547584Smccanne int error, s; 43647584Smccanne static struct sockaddr dst; 43747584Smccanne 43847584Smccanne if (d->bd_bif == 0) 439*48932Smccanne return (ENXIO); 44047584Smccanne 44147584Smccanne ifp = d->bd_bif->bif_ifp; 44247584Smccanne 44347584Smccanne if (uio->uio_resid == 0) 444*48932Smccanne return (0); 44547584Smccanne if (uio->uio_resid > ifp->if_mtu) 446*48932Smccanne return (EMSGSIZE); 44747584Smccanne 44847584Smccanne error = bpf_movein(uio, (int)d->bd_bif->bif_devp.bdev_type, &m, &dst); 44947584Smccanne if (error) 450*48932Smccanne return (error); 45147584Smccanne 45247584Smccanne s = splnet(); 45347584Smccanne error = (*ifp->if_output)(ifp, m, &dst); 45447584Smccanne splx(s); 45547584Smccanne /* 45647584Smccanne * The driver frees the mbuf. 45747584Smccanne */ 458*48932Smccanne return (error); 45947584Smccanne } 46047584Smccanne 46147584Smccanne /* 462*48932Smccanne * Reset a descriptor by flushing its packet bufferand clearing the receive 463*48932Smccanne * and drop counts. Should be called at splimp. 46447584Smccanne */ 46547584Smccanne static void 46647584Smccanne reset_d(d) 46747584Smccanne struct bpf_d *d; 46847584Smccanne { 46947584Smccanne if (d->bd_hbuf) { 47047584Smccanne /* Free the hold buffer. */ 47147584Smccanne d->bd_fbuf = d->bd_hbuf; 47247584Smccanne d->bd_hbuf = 0; 47347584Smccanne } 474*48932Smccanne d->bd_slen = 0; 47547584Smccanne d->bd_rcount = 0; 47647584Smccanne d->bd_dcount = 0; 47747584Smccanne } 47847584Smccanne 47947584Smccanne /* 48047584Smccanne * bpfioctl - packet filter control 48147584Smccanne * 48247584Smccanne * FIONREAD Check for read packet available. 48347584Smccanne * SIOCGIFADDR Get interface address - convenient hook to driver. 48447584Smccanne * BIOCGFLEN Get max filter len. 48547584Smccanne * BIOCGBLEN Get buffer len [for read()]. 48647584Smccanne * BIOCSETF Set ethernet read filter. 48747584Smccanne * BIOCFLUSH Flush read packet buffer. 48847584Smccanne * BIOCPROMISC Put interface into promiscuous mode. 48947584Smccanne * BIOCDEVP Get device parameters. 49047584Smccanne * BIOCGETIF Get interface name. 49147584Smccanne * BIOCSETIF Set interface. 49247584Smccanne * BIOCSRTIMEOUT Set read timeout. 49347584Smccanne * BIOCGRTIMEOUT Get read timeout. 49447584Smccanne * BIOCGSTATS Get packet stats. 49547584Smccanne * BIOCIMMEDIATE Set immediate mode. 49647584Smccanne */ 49747584Smccanne /* ARGSUSED */ 49847584Smccanne int 49947584Smccanne bpfioctl(dev, cmd, addr, flag) 50047584Smccanne dev_t dev; 50147584Smccanne int cmd; 50247584Smccanne caddr_t addr; 50347584Smccanne int flag; 50447584Smccanne { 50547584Smccanne register struct bpf_d *d = &bpf_dtab[minor(dev)]; 50647584Smccanne int s, error = 0; 50747584Smccanne 50847584Smccanne switch (cmd) { 50947584Smccanne 51047584Smccanne default: 51147584Smccanne error = EINVAL; 51247584Smccanne break; 51347584Smccanne 51447584Smccanne /* 51547584Smccanne * Check for read packet available. 51647584Smccanne */ 51747584Smccanne case FIONREAD: 51847584Smccanne { 51947584Smccanne int n; 52047584Smccanne 52147584Smccanne s = splimp(); 522*48932Smccanne n = d->bd_slen; 52347584Smccanne if (d->bd_hbuf) 524*48932Smccanne n += d->bd_hlen; 52547584Smccanne splx(s); 52647584Smccanne 52747584Smccanne *(int *)addr = n; 52847584Smccanne break; 52947584Smccanne } 53047584Smccanne 53147584Smccanne case SIOCGIFADDR: 53247584Smccanne { 53347584Smccanne struct ifnet *ifp; 53447584Smccanne 53547584Smccanne if (d->bd_bif == 0) 53647584Smccanne error = EINVAL; 53747584Smccanne else { 53847584Smccanne ifp = d->bd_bif->bif_ifp; 53947584Smccanne error = (*ifp->if_ioctl)(ifp, cmd, addr); 54047584Smccanne } 54147584Smccanne break; 54247584Smccanne } 54347584Smccanne 54447584Smccanne /* 54547584Smccanne * Get max filter len. 54647584Smccanne */ 54747584Smccanne case BIOCGFLEN: 548*48932Smccanne *(u_int *)addr = BPF_MAXINSNS; 54947584Smccanne break; 55047584Smccanne /* 55147584Smccanne * Get buffer len [for read()]. 55247584Smccanne */ 55347584Smccanne case BIOCGBLEN: 554*48932Smccanne *(u_int *)addr = d->bd_bufsize; 55547584Smccanne break; 55647584Smccanne 55747584Smccanne /* 55847584Smccanne * Set ethernet read filter. 55947584Smccanne */ 56047584Smccanne case BIOCSETF: 56147584Smccanne error = bpf_setf(d, (struct bpf_program *)addr); 56247584Smccanne break; 56347584Smccanne 56447584Smccanne /* 56547584Smccanne * Flush read packet buffer. 56647584Smccanne */ 56747584Smccanne case BIOCFLUSH: 56847584Smccanne s = splimp(); 56947584Smccanne reset_d(d); 57047584Smccanne splx(s); 57147584Smccanne break; 57247584Smccanne 57347584Smccanne /* 57447584Smccanne * Put interface into promiscuous mode. 57547584Smccanne */ 57647584Smccanne case BIOCPROMISC: 57747584Smccanne if (d->bd_bif == 0) { 57847584Smccanne /* 57947584Smccanne * No interface attached yet. 58047584Smccanne */ 58147584Smccanne error = EINVAL; 58247584Smccanne break; 58347584Smccanne } 58447584Smccanne s = splimp(); 58547584Smccanne if (d->bd_promisc == 0) { 58647584Smccanne d->bd_promisc = 1; 58747584Smccanne error = ifpromisc(d->bd_bif->bif_ifp, 1); 58847584Smccanne } 58947584Smccanne splx(s); 59047584Smccanne break; 59147584Smccanne 59247584Smccanne /* 59347584Smccanne * Get device parameters. 59447584Smccanne */ 59547584Smccanne case BIOCDEVP: 59647584Smccanne if (d->bd_bif == 0) 59747584Smccanne error = EINVAL; 59847584Smccanne else 59947584Smccanne *(struct bpf_devp *)addr = d->bd_bif->bif_devp; 60047584Smccanne break; 60147584Smccanne 60247584Smccanne /* 60347584Smccanne * Set interface name. 60447584Smccanne */ 60547584Smccanne case BIOCGETIF: 60647584Smccanne if (d->bd_bif == 0) 60747584Smccanne error = EINVAL; 60847584Smccanne else 60947584Smccanne bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr); 61047584Smccanne break; 61147584Smccanne 61247584Smccanne /* 61347584Smccanne * Set interface. 61447584Smccanne */ 61547584Smccanne case BIOCSETIF: 61647584Smccanne error = bpf_setif(d, (struct ifreq *)addr); 61747584Smccanne break; 61847584Smccanne 61947584Smccanne /* 62047584Smccanne * Set read timeout. 62147584Smccanne */ 62247584Smccanne case BIOCSRTIMEOUT: 62347584Smccanne { 62447584Smccanne struct timeval *tv = (struct timeval *)addr; 62547584Smccanne u_long msec; 62647584Smccanne 62747584Smccanne /* Compute number of milliseconds. */ 62847584Smccanne msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; 62947584Smccanne /* Scale milliseconds to ticks. Assume hard 63047584Smccanne clock has millisecond or greater resolution 63147584Smccanne (i.e. tick >= 1000). For 10ms hardclock, 63247584Smccanne tick/1000 = 10, so rtout<-msec/10. */ 63347584Smccanne d->bd_rtout = msec / (tick / 1000); 63447584Smccanne break; 63547584Smccanne } 63647584Smccanne 63747584Smccanne /* 63847584Smccanne * Get read timeout. 63947584Smccanne */ 64047584Smccanne case BIOCGRTIMEOUT: 64147584Smccanne { 64247584Smccanne struct timeval *tv = (struct timeval *)addr; 64347584Smccanne u_long msec = d->bd_rtout; 64447584Smccanne 64547584Smccanne msec *= tick / 1000; 64647584Smccanne tv->tv_sec = msec / 1000; 64747584Smccanne tv->tv_usec = msec % 1000; 64847584Smccanne break; 64947584Smccanne } 65047584Smccanne 65147584Smccanne /* 65247584Smccanne * Get packet stats. 65347584Smccanne */ 65447584Smccanne case BIOCGSTATS: 65547584Smccanne { 65647584Smccanne struct bpf_stat *bs = (struct bpf_stat *)addr; 65747584Smccanne 65847584Smccanne bs->bs_recv = d->bd_rcount; 65947584Smccanne bs->bs_drop = d->bd_dcount; 66047584Smccanne break; 66147584Smccanne } 66247584Smccanne 66347584Smccanne /* 66447584Smccanne * Set immediate mode. 66547584Smccanne */ 66647584Smccanne case BIOCIMMEDIATE: 66747584Smccanne d->bd_immediate = *(u_int *)addr; 66847584Smccanne break; 66947584Smccanne } 670*48932Smccanne return (error); 67147584Smccanne } 67247584Smccanne 67347584Smccanne /* 67447584Smccanne * Set d's packet filter program to 'fp'. If 'd' already has a filter, 675*48932Smccanne * free it and replace it. Returns EINVAL for bogus requests. 67647584Smccanne */ 67747584Smccanne int 67847584Smccanne bpf_setf(d, fp) 67947584Smccanne struct bpf_d *d; 68047584Smccanne struct bpf_program *fp; 68147584Smccanne { 682*48932Smccanne struct bpf_insn *fcode, *old; 68347584Smccanne u_int flen, size; 68447584Smccanne int s; 68547584Smccanne 686*48932Smccanne old = d->bd_filter; 68747584Smccanne if (fp->bf_insns == 0) { 68847584Smccanne if (fp->bf_len != 0) 689*48932Smccanne return (EINVAL); 69047584Smccanne d->bd_filter = bpf_default_filter; 691*48932Smccanne s = splimp(); 69247584Smccanne reset_d(d); 69347584Smccanne splx(s); 694*48932Smccanne if (old != bpf_default_filter) 695*48932Smccanne free((caddr_t)old, M_DEVBUF); 696*48932Smccanne return (0); 69747584Smccanne } 69847584Smccanne flen = fp->bf_len; 699*48932Smccanne if (flen > BPF_MAXINSNS) 700*48932Smccanne return (EINVAL); 701*48932Smccanne 70247584Smccanne size = flen * sizeof(*fp->bf_insns); 703*48932Smccanne fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK); 704*48932Smccanne if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size)) 705*48932Smccanne return (EINVAL); 70647584Smccanne 70747584Smccanne if (bpf_validate(fcode, (int)flen)) { 708*48932Smccanne d->bd_filter = fcode; 70947584Smccanne s = splimp(); 71047584Smccanne reset_d(d); 71147584Smccanne splx(s); 712*48932Smccanne if (old != bpf_default_filter) 713*48932Smccanne free((caddr_t)old, M_DEVBUF); 71447584Smccanne 715*48932Smccanne return (0); 71647584Smccanne } 717*48932Smccanne free((caddr_t)fcode, M_DEVBUF); 718*48932Smccanne return (EINVAL); 71947584Smccanne } 72047584Smccanne 72147584Smccanne /* 72247584Smccanne * Detach 'd' from its current interface (if attached at all) and attach to 72347584Smccanne * the interface named 'name'. Return ioctl error code or 0. 72447584Smccanne */ 72547584Smccanne static int 72647584Smccanne bpf_setif(d, ifr) 72747584Smccanne struct bpf_d *d; 72847584Smccanne struct ifreq *ifr; 72947584Smccanne { 73047584Smccanne struct bpf_if *bp; 73147584Smccanne char *cp; 73247584Smccanne int unit, i, s; 73347584Smccanne 73447584Smccanne /* 73547584Smccanne * Separate string into name part and unit number. Put a null 73647584Smccanne * byte at the end of the name part, and compute the number. 73747584Smccanne * If the a unit number is unspecified, the default is 0, 738*48932Smccanne * as initialized above. XXX This should be common code. 73947584Smccanne */ 74047584Smccanne unit = 0; 74147584Smccanne cp = ifr->ifr_name; 74247584Smccanne cp[sizeof(ifr->ifr_name) - 1] = '\0'; 74347584Smccanne while (*cp++) { 74447584Smccanne if (*cp >= '0' && *cp <= '9') { 74547584Smccanne unit = *cp - '0'; 74647584Smccanne *cp++ = '\0'; 74747584Smccanne while (*cp) 74847584Smccanne unit = 10 * unit + *cp++ - '0'; 74947584Smccanne break; 75047584Smccanne } 75147584Smccanne } 75247584Smccanne /* 75347584Smccanne * Look through attached interfaces for the named one. 75447584Smccanne */ 75547584Smccanne bp = bpf_iftab; 75647584Smccanne for (i = 0; i < NBPFILTER; ++bp, ++i) { 75747584Smccanne struct ifnet *ifp = bp->bif_ifp; 75847584Smccanne 75947584Smccanne if (ifp == 0 || unit != ifp->if_unit 76047584Smccanne || strcmp(ifp->if_name, ifr->ifr_name) != 0) 76147584Smccanne continue; 76247584Smccanne /* 76347584Smccanne * We found the requested interface. If we're 76447584Smccanne * already attached to it, just flush the buffer. 76547584Smccanne * If it's not up, return an error. 76647584Smccanne */ 76747584Smccanne if ((ifp->if_flags & IFF_UP) == 0) 768*48932Smccanne return (ENETDOWN); 76947584Smccanne s = splimp(); 77047584Smccanne if (bp != d->bd_bif) { 77147584Smccanne if (d->bd_bif) 77247584Smccanne /* 773*48932Smccanne * Detach if attached to something else. 77447584Smccanne */ 77547584Smccanne bpf_detachd(d); 77647584Smccanne 77747584Smccanne bpf_attachd(d, bp); 77847584Smccanne } 77947584Smccanne reset_d(d); 78047584Smccanne splx(s); 781*48932Smccanne return (0); 78247584Smccanne } 78347584Smccanne /* Not found. */ 784*48932Smccanne return (ENXIO); 78547584Smccanne } 78647584Smccanne 78747584Smccanne /* 78847584Smccanne * Lookup the name of the 'ifp' interface and return it in 'ifr->ifr_name'. 78947584Smccanne * We augment the ifp's base name with its unit number. 79047584Smccanne */ 79147584Smccanne static void 79247584Smccanne bpf_ifname(ifp, ifr) 79347584Smccanne struct ifnet *ifp; 79447584Smccanne struct ifreq *ifr; 79547584Smccanne { 79647584Smccanne char *s = ifp->if_name; 79747584Smccanne char *d = ifr->ifr_name; 79847584Smccanne 79947584Smccanne while (*d++ = *s++) 80047584Smccanne ; 801*48932Smccanne /* XXX Assume that unit number is less than 10. */ 80247584Smccanne *d++ = ifp->if_unit + '0'; 80347584Smccanne *d = '\0'; 80447584Smccanne } 80547584Smccanne 80647584Smccanne /* 80747584Smccanne * Support for select() system call 80847584Smccanne * Inspired by the code in tty.c for the same purpose. 80947584Smccanne * 81047584Smccanne * bpfselect - returns true iff the specific operation 81147584Smccanne * will not block indefinitely. Otherwise, return 81247584Smccanne * false but make a note that a selwakeup() must be done. 81347584Smccanne */ 81447584Smccanne int 815*48932Smccanne bpfselect(dev, rw, p) 81647584Smccanne register dev_t dev; 81747584Smccanne int rw; 818*48932Smccanne struct proc *p; 81947584Smccanne { 82047584Smccanne register struct bpf_d *d; 82147584Smccanne register int s; 82247584Smccanne 82347584Smccanne if (rw != FREAD) 824*48932Smccanne return (0); 82547584Smccanne /* 82647584Smccanne * An imitation of the FIONREAD ioctl code. 82747584Smccanne */ 82847584Smccanne d = &bpf_dtab[minor(dev)]; 82947584Smccanne 83047584Smccanne s = splimp(); 831*48932Smccanne if (d->bd_slen != 0 || d->bd_hbuf && d->bd_hlen != 0) { 83247584Smccanne /* 83347584Smccanne * There is data waiting. 83447584Smccanne */ 83547584Smccanne splx(s); 836*48932Smccanne return (1); 83747584Smccanne } 83847584Smccanne /* 83947584Smccanne * No data ready. If there's already a select() waiting on this 84047584Smccanne * minor device then this is a collision. This shouldn't happen 84147584Smccanne * because minors really should not be shared, but if a process 84247584Smccanne * forks while one of these is open, it is possible that both 84347584Smccanne * processes could select on the same descriptor. 84447584Smccanne */ 845*48932Smccanne if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait) 846*48932Smccanne d->bd_selcoll = 1; 84747584Smccanne else 848*48932Smccanne d->bd_selproc = p; 849*48932Smccanne 85047584Smccanne splx(s); 851*48932Smccanne return (0); 85247584Smccanne } 85347584Smccanne 85447584Smccanne /* 85547584Smccanne * bpf_tap - incoming linkage from device drivers 85647584Smccanne */ 85747584Smccanne void 858*48932Smccanne bpf_tap(arg, pkt, pktlen) 85947584Smccanne caddr_t arg; 860*48932Smccanne register u_char *pkt; 861*48932Smccanne register u_int pktlen; 86247584Smccanne { 86347584Smccanne struct bpf_if *bp; 86447584Smccanne register struct bpf_d *d; 86547584Smccanne register u_int slen; 86647584Smccanne extern bcopy(); 86747584Smccanne /* 86847584Smccanne * Note that the ipl does not have to be raised at this point. 86947584Smccanne * The only problem that could arise here is that if two different 87047584Smccanne * interfaces shared any data. This is not the case. 87147584Smccanne */ 87247584Smccanne bp = (struct bpf_if *)arg; 87347584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 87447584Smccanne ++d->bd_rcount; 875*48932Smccanne slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 87647584Smccanne if (slen != 0) 877*48932Smccanne catchpacket(d, pkt, pktlen, slen, (void (*)())bcopy); 87847584Smccanne } 87947584Smccanne } 88047584Smccanne 88147584Smccanne /* 88247584Smccanne * Copy data from an mbuf chain into a buffer. This code is derived 88347584Smccanne * from m_copydata in sys/uipc_mbuf.c. 88447584Smccanne */ 88547584Smccanne static void 88647584Smccanne bpf_m_copydata(src, dst, len) 88747584Smccanne u_char *src; 88847584Smccanne u_char *dst; 88947584Smccanne register int len; 89047584Smccanne { 89147584Smccanne register struct mbuf *m = (struct mbuf *)src; 89247584Smccanne register unsigned count; 89347584Smccanne 89447584Smccanne while (len > 0) { 89547584Smccanne if (m == 0) 89647584Smccanne panic("bpf_m_copydata"); 89747584Smccanne count = MIN(m->m_len, len); 89847584Smccanne (void)bcopy(mtod(m, caddr_t), (caddr_t)dst, count); 89947584Smccanne len -= count; 90047584Smccanne dst += count; 90147584Smccanne m = m->m_next; 90247584Smccanne } 90347584Smccanne } 90447584Smccanne 90547584Smccanne /* 906*48932Smccanne * Length of ethernet and TCP/IP header with no IP options. 90747584Smccanne */ 90847584Smccanne #define BPF_MIN_SNAPLEN 50 90947584Smccanne 91047584Smccanne /* 91147584Smccanne * bpf_mtap - incoming linkage from device drivers, when packet 91247584Smccanne * is in an mbuf chain 91347584Smccanne */ 91447584Smccanne void 91547584Smccanne bpf_mtap(arg, m0) 91647584Smccanne caddr_t arg; 91747584Smccanne struct mbuf *m0; 91847584Smccanne { 91947584Smccanne struct bpf_if *bp = (struct bpf_if *)arg; 92047584Smccanne struct bpf_d *d; 92147584Smccanne u_char *cp; 922*48932Smccanne u_int slen, pktlen; 92347584Smccanne int nbytes; 92447584Smccanne struct mbuf *m; 925*48932Smccanne static u_char buf[BPF_MIN_SNAPLEN]; 92647584Smccanne 92747584Smccanne if (m0->m_len >= BPF_MIN_SNAPLEN) { 92847584Smccanne slen = m0->m_len; 92947584Smccanne cp = mtod(m0, u_char *); 93047584Smccanne } 93147584Smccanne else { 93247584Smccanne nbytes = BPF_MIN_SNAPLEN; 93347584Smccanne cp = buf; 93447584Smccanne m = m0; 93547584Smccanne while (m && nbytes > 0) { 93647584Smccanne slen = MIN(m->m_len, nbytes); 93747584Smccanne bcopy(mtod(m, char *), (char *)cp, slen); 93847584Smccanne cp += slen; 93947584Smccanne nbytes -= slen; 94047584Smccanne m = m->m_next; 94147584Smccanne } 94247584Smccanne if (nbytes > 0) 94347584Smccanne /* Packet too small? */ 94447584Smccanne return; 94547584Smccanne 94647584Smccanne slen = BPF_MIN_SNAPLEN; 94747584Smccanne cp = buf; 94847584Smccanne } 949*48932Smccanne pktlen = 0; 95047584Smccanne m = m0; 95147584Smccanne while (m) { 952*48932Smccanne pktlen += m->m_len; 95347584Smccanne m = m->m_next; 95447584Smccanne } 95547584Smccanne for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 95647584Smccanne ++d->bd_rcount; 957*48932Smccanne slen = bpf_filter(d->bd_filter, cp, pktlen, slen); 95847584Smccanne if (slen != 0) 959*48932Smccanne catchpacket(d, (u_char *)m0, pktlen, slen, 96047584Smccanne bpf_m_copydata); 96147584Smccanne } 96247584Smccanne } 96347584Smccanne 96447584Smccanne /* 965*48932Smccanne * Move the packet data from interface memory ('pkt') into the 96647584Smccanne * store buffer. Return 1 if it's time to wakeup a listener (buffer full), 96747584Smccanne * otherwise 0. 'copy' is the routine called to do the actual data 96847584Smccanne * transfer. 'bcopy' is passed in to copy contiguous chunks, while 96947584Smccanne * 'bpf_m_copydata' is passed in to copy mbuf chains. In the latter 970*48932Smccanne * case, 'pkt' is really an mbuf. 97147584Smccanne */ 97247584Smccanne static void 973*48932Smccanne catchpacket(d, pkt, pktlen, snaplen, cpfn) 974*48932Smccanne register struct bpf_d *d; 975*48932Smccanne register u_char *pkt; 976*48932Smccanne register u_int pktlen, snaplen; 977*48932Smccanne register void (*cpfn)(); 97847584Smccanne { 979*48932Smccanne register struct bpf_hdr *hp; 980*48932Smccanne register int totlen, curlen; 981*48932Smccanne register int hdrlen = d->bd_bif->bif_hdrlen; 98247584Smccanne /* 98347584Smccanne * Figure out how many bytes to move. If the packet is 98447584Smccanne * greater or equal to the snapshot length, transfer that 98547584Smccanne * much. Otherwise, transfer the whole packet (unless 986*48932Smccanne * we hit the buffer size limit). 98747584Smccanne */ 988*48932Smccanne if (snaplen <= pktlen) 98947584Smccanne totlen = snaplen + hdrlen; 99047584Smccanne else { 991*48932Smccanne totlen = pktlen + hdrlen; 992*48932Smccanne if (totlen > d->bd_bufsize) 993*48932Smccanne totlen = d->bd_bufsize; 99447584Smccanne } 99547584Smccanne 99647584Smccanne /* 99747584Smccanne * Round up the end of the previous packet to the next longword. 99847584Smccanne */ 999*48932Smccanne curlen = BPF_WORDALIGN(d->bd_slen); 1000*48932Smccanne if (curlen + totlen > d->bd_bufsize) { 100147584Smccanne /* 100247584Smccanne * This packet will overflow the storage buffer. 1003*48932Smccanne * Rotate the buffers if we can, then wakeup any 1004*48932Smccanne * pending reads. 100547584Smccanne */ 100647584Smccanne if (d->bd_fbuf == 0) { 100747584Smccanne /* 1008*48932Smccanne * We haven't completed the previous read yet, 1009*48932Smccanne * so drop the packet. 101047584Smccanne */ 101147584Smccanne ++d->bd_dcount; 101247584Smccanne return; 101347584Smccanne } 1014*48932Smccanne ROTATE_BUFFERS(d); 101547584Smccanne bpf_wakeup(d); 1016*48932Smccanne curlen = 0; 101747584Smccanne } 1018*48932Smccanne else if (d->bd_immediate) 101947584Smccanne /* 102047584Smccanne * Immediate mode is set. A packet arrived so any 102147584Smccanne * reads should be woken up. 102247584Smccanne */ 102347584Smccanne bpf_wakeup(d); 1024*48932Smccanne 102547584Smccanne /* 102647584Smccanne * Append the bpf header. 102747584Smccanne */ 1028*48932Smccanne hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); 102947584Smccanne #ifdef sun 103047584Smccanne uniqtime(&hp->bh_tstamp); 103147584Smccanne #else 103247584Smccanne #ifdef hp300 103347584Smccanne microtime(&hp->bh_tstamp); 103447584Smccanne #else 103547584Smccanne hp->bh_tstamp = time; 103647584Smccanne #endif 103747584Smccanne #endif 1038*48932Smccanne hp->bh_datalen = pktlen; 103947584Smccanne hp->bh_hdrlen = hdrlen; 104047584Smccanne /* 1041*48932Smccanne * Copy the packet data into the store buffer and update its length. 104247584Smccanne */ 1043*48932Smccanne (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); 1044*48932Smccanne d->bd_slen = curlen + totlen; 104547584Smccanne } 104647584Smccanne 104747584Smccanne /* 104847584Smccanne * Initialize all nonzero fields of a descriptor. 104947584Smccanne */ 105047584Smccanne static int 105147584Smccanne bpf_initd(d) 105247584Smccanne register struct bpf_d *d; 105347584Smccanne { 1054*48932Smccanne d->bd_bufsize = bpf_bufsize; 1055*48932Smccanne d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 1056*48932Smccanne if (d->bd_fbuf == 0) 1057*48932Smccanne return (ENOBUFS); 105847584Smccanne 1059*48932Smccanne d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); 1060*48932Smccanne if (d->bd_sbuf == 0) { 1061*48932Smccanne free(d->bd_fbuf, M_DEVBUF); 1062*48932Smccanne return (ENOBUFS); 106347584Smccanne } 1064*48932Smccanne d->bd_slen = 0; 1065*48932Smccanne d->bd_hlen = 0; 1066*48932Smccanne return (0); 106747584Smccanne } 106847584Smccanne 106947584Smccanne /* 107047584Smccanne * Register 'ifp' with bpf. 'devp' is the link-level device descriptor 107147584Smccanne * and 'driverp' is a pointer to the 'struct bpf_if *' in the driver's softc. 107247584Smccanne */ 107347584Smccanne void 107447584Smccanne bpfattach(driverp, ifp, devp) 107547584Smccanne caddr_t *driverp; 107647584Smccanne struct ifnet *ifp; 107747584Smccanne struct bpf_devp *devp; 107847584Smccanne { 107947584Smccanne struct bpf_if *bp; 108047584Smccanne int i; 108147584Smccanne 108247584Smccanne if (bpf_units >= NBPFILTER) { 108347584Smccanne printf("bpf: too many interfaces: %s%d not attached\n", 108447584Smccanne ifp->if_name, ifp->if_unit); 108547584Smccanne return; 108647584Smccanne } 108747584Smccanne bp = &bpf_iftab[bpf_units++]; 108847584Smccanne 108947584Smccanne bp->bif_dlist = 0; 109047584Smccanne bp->bif_driverp = (struct bpf_if **)driverp; 109147584Smccanne bp->bif_ifp = ifp; 109247584Smccanne bp->bif_devp = *devp; 109347584Smccanne 1094*48932Smccanne *bp->bif_driverp = 0; 1095*48932Smccanne 109647584Smccanne /* 109747584Smccanne * Compute the length of the bpf header. This is not necessarily 109847584Smccanne * equal to SIZEOF_BPF_HDR because we want to insert spacing such 109947584Smccanne * that the network layer header begins on a longword boundary (for 110047584Smccanne * performance reasons and to alleviate alignment restrictions). 110147584Smccanne */ 110247584Smccanne i = devp->bdev_hdrlen; 110347584Smccanne bp->bif_hdrlen = BPF_WORDALIGN(i + SIZEOF_BPF_HDR) - i; 110447584Smccanne 110547584Smccanne /* 110647584Smccanne * Mark all the descriptors free if this hasn't been done. 110747584Smccanne */ 110847584Smccanne if (!D_ISFREE(&bpf_dtab[0])) 110947584Smccanne for (i = 0; i < NBPFILTER; ++i) 111047584Smccanne D_MARKFREE(&bpf_dtab[i]); 111147584Smccanne 111247584Smccanne printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); 111347584Smccanne } 111447584Smccanne 1115*48932Smccanne /* XXX This routine goes in net/if.c. */ 1116*48932Smccanne /* 1117*48932Smccanne * Set/clear promiscuous mode on interface ifp based on the truth value` 1118*48932Smccanne * of pswitch. The calls are reference counted so that only the first 1119*48932Smccanne * on request actually has an effect, as does the final off request. 1120*48932Smccanne * Results are undefined if the off and on requests are not matched. 1121*48932Smccanne */ 1122*48932Smccanne int 1123*48932Smccanne ifpromisc(ifp, pswitch) 1124*48932Smccanne struct ifnet *ifp; 1125*48932Smccanne int pswitch; 1126*48932Smccanne { 1127*48932Smccanne /* 1128*48932Smccanne * If the device is not configured up, we cannot put it in 1129*48932Smccanne * promiscuous mode. 1130*48932Smccanne */ 1131*48932Smccanne if ((ifp->if_flags & IFF_UP) == 0) 1132*48932Smccanne return (ENETDOWN); 1133*48932Smccanne 1134*48932Smccanne if (pswitch) { 1135*48932Smccanne if (ifp->if_pcount++ != 0) 1136*48932Smccanne return (0); 1137*48932Smccanne ifp->if_flags |= IFF_PROMISC; 1138*48932Smccanne } else { 1139*48932Smccanne if (--ifp->if_pcount > 0) 1140*48932Smccanne return (0); 1141*48932Smccanne ifp->if_flags &= ~IFF_PROMISC; 1142*48932Smccanne } 1143*48932Smccanne return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)0)); 1144*48932Smccanne } 1145*48932Smccanne 114647584Smccanne #endif (NBPFILTER > 0) 1147