bpf.c revision 112463
1219820Sjeff/* 2219820Sjeff * Copyright (c) 1990, 1991, 1993 3219820Sjeff * The Regents of the University of California. All rights reserved. 4219820Sjeff * 5219820Sjeff * This code is derived from the Stanford/CMU enet packet filter, 6219820Sjeff * (net/enet.c) distributed as part of 4.3BSD, and code contributed 7219820Sjeff * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 8219820Sjeff * Berkeley Laboratory. 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or without 11219820Sjeff * modification, are permitted provided that the following conditions 12219820Sjeff * are met: 13219820Sjeff * 1. Redistributions of source code must retain the above copyright 14219820Sjeff * notice, this list of conditions and the following disclaimer. 15219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 16219820Sjeff * notice, this list of conditions and the following disclaimer in the 17219820Sjeff * documentation and/or other materials provided with the distribution. 18219820Sjeff * 3. All advertising materials mentioning features or use of this software 19219820Sjeff * must display the following acknowledgement: 20219820Sjeff * This product includes software developed by the University of 21219820Sjeff * California, Berkeley and its contributors. 22219820Sjeff * 4. Neither the name of the University nor the names of its contributors 23219820Sjeff * may be used to endorse or promote products derived from this software 24219820Sjeff * without specific prior written permission. 25219820Sjeff * 26219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36219820Sjeff * SUCH DAMAGE. 37219820Sjeff * 38219820Sjeff * @(#)bpf.c 8.4 (Berkeley) 1/9/95 39219820Sjeff * 40219820Sjeff * $FreeBSD: head/sys/net/bpf.c 112463 2003-03-21 15:13:29Z mdodd $ 41219820Sjeff */ 42219820Sjeff 43219820Sjeff#include "opt_bpf.h" 44219820Sjeff#include "opt_mac.h" 45219820Sjeff#include "opt_netgraph.h" 46219820Sjeff 47219820Sjeff#include <sys/param.h> 48219820Sjeff#include <sys/systm.h> 49219820Sjeff#include <sys/conf.h> 50219820Sjeff#include <sys/mac.h> 51219820Sjeff#include <sys/malloc.h> 52219820Sjeff#include <sys/mbuf.h> 53219820Sjeff#include <sys/time.h> 54219820Sjeff#include <sys/proc.h> 55219820Sjeff#include <sys/signalvar.h> 56219820Sjeff#include <sys/filio.h> 57219820Sjeff#include <sys/sockio.h> 58219820Sjeff#include <sys/ttycom.h> 59219820Sjeff#include <sys/filedesc.h> 60219820Sjeff 61219820Sjeff#include <sys/poll.h> 62219820Sjeff 63219820Sjeff#include <sys/socket.h> 64219820Sjeff#include <sys/vnode.h> 65219820Sjeff 66219820Sjeff#include <net/if.h> 67219820Sjeff#include <net/bpf.h> 68219820Sjeff#include <net/bpfdesc.h> 69219820Sjeff 70219820Sjeff#include <netinet/in.h> 71219820Sjeff#include <netinet/if_ether.h> 72219820Sjeff#include <sys/kernel.h> 73219820Sjeff#include <sys/sysctl.h> 74219820Sjeff 75219820Sjeffstatic MALLOC_DEFINE(M_BPF, "BPF", "BPF data"); 76219820Sjeff 77219820Sjeff#if defined(DEV_BPF) || defined(NETGRAPH_BPF) 78219820Sjeff 79219820Sjeff#define PRINET 26 /* interruptible */ 80219820Sjeff 81219820Sjeff/* 82219820Sjeff * The default read buffer size is patchable. 83219820Sjeff */ 84219820Sjeffstatic int bpf_bufsize = 4096; 85219820SjeffSYSCTL_INT(_debug, OID_AUTO, bpf_bufsize, CTLFLAG_RW, 86219820Sjeff &bpf_bufsize, 0, ""); 87219820Sjeffstatic int bpf_maxbufsize = BPF_MAXBUFSIZE; 88219820SjeffSYSCTL_INT(_debug, OID_AUTO, bpf_maxbufsize, CTLFLAG_RW, 89219820Sjeff &bpf_maxbufsize, 0, ""); 90219820Sjeff 91219820Sjeff/* 92219820Sjeff * bpf_iflist is the list of interfaces; each corresponds to an ifnet 93219820Sjeff */ 94219820Sjeffstatic struct bpf_if *bpf_iflist; 95219820Sjeffstatic struct mtx bpf_mtx; /* bpf global lock */ 96219820Sjeff 97219820Sjeffstatic int bpf_allocbufs(struct bpf_d *); 98219820Sjeffstatic void bpf_attachd(struct bpf_d *d, struct bpf_if *bp); 99219820Sjeffstatic void bpf_detachd(struct bpf_d *d); 100219820Sjeffstatic void bpf_freed(struct bpf_d *); 101219820Sjeffstatic void bpf_mcopy(const void *, void *, size_t); 102219820Sjeffstatic int bpf_movein(struct uio *, int, 103219820Sjeff struct mbuf **, struct sockaddr *, int *); 104219820Sjeffstatic int bpf_setif(struct bpf_d *, struct ifreq *); 105219820Sjeffstatic void bpf_timed_out(void *); 106219820Sjeffstatic __inline void 107219820Sjeff bpf_wakeup(struct bpf_d *); 108219820Sjeffstatic void catchpacket(struct bpf_d *, u_char *, u_int, 109219820Sjeff u_int, void (*)(const void *, void *, size_t)); 110219820Sjeffstatic void reset_d(struct bpf_d *); 111219820Sjeffstatic int bpf_setf(struct bpf_d *, struct bpf_program *); 112219820Sjeffstatic int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *); 113219820Sjeffstatic int bpf_setdlt(struct bpf_d *, u_int); 114219820Sjeff 115219820Sjeffstatic d_open_t bpfopen; 116219820Sjeffstatic d_close_t bpfclose; 117219820Sjeffstatic d_read_t bpfread; 118219820Sjeffstatic d_write_t bpfwrite; 119219820Sjeffstatic d_ioctl_t bpfioctl; 120219820Sjeffstatic d_poll_t bpfpoll; 121219820Sjeff 122219820Sjeff#define CDEV_MAJOR 23 123219820Sjeffstatic struct cdevsw bpf_cdevsw = { 124219820Sjeff .d_open = bpfopen, 125219820Sjeff .d_close = bpfclose, 126219820Sjeff .d_read = bpfread, 127219820Sjeff .d_write = bpfwrite, 128219820Sjeff .d_ioctl = bpfioctl, 129219820Sjeff .d_poll = bpfpoll, 130219820Sjeff .d_name = "bpf", 131219820Sjeff .d_maj = CDEV_MAJOR, 132219820Sjeff}; 133219820Sjeff 134219820Sjeff 135219820Sjeffstatic int 136219820Sjeffbpf_movein(uio, linktype, mp, sockp, datlen) 137219820Sjeff struct uio *uio; 138219820Sjeff int linktype, *datlen; 139219820Sjeff struct mbuf **mp; 140219820Sjeff struct sockaddr *sockp; 141219820Sjeff{ 142219820Sjeff struct mbuf *m; 143219820Sjeff int error; 144219820Sjeff int len; 145219820Sjeff int hlen; 146219820Sjeff 147219820Sjeff /* 148219820Sjeff * Build a sockaddr based on the data link layer type. 149219820Sjeff * We do this at this level because the ethernet header 150219820Sjeff * is copied directly into the data field of the sockaddr. 151219820Sjeff * In the case of SLIP, there is no header and the packet 152219820Sjeff * is forwarded as is. 153219820Sjeff * Also, we are careful to leave room at the front of the mbuf 154219820Sjeff * for the link level header. 155219820Sjeff */ 156219820Sjeff switch (linktype) { 157219820Sjeff 158219820Sjeff case DLT_SLIP: 159219820Sjeff sockp->sa_family = AF_INET; 160219820Sjeff hlen = 0; 161219820Sjeff break; 162219820Sjeff 163219820Sjeff case DLT_EN10MB: 164219820Sjeff sockp->sa_family = AF_UNSPEC; 165219820Sjeff /* XXX Would MAXLINKHDR be better? */ 166219820Sjeff hlen = ETHER_HDR_LEN; 167219820Sjeff break; 168219820Sjeff 169219820Sjeff case DLT_FDDI: 170219820Sjeff sockp->sa_family = AF_IMPLINK; 171219820Sjeff hlen = 0; 172219820Sjeff break; 173219820Sjeff 174219820Sjeff case DLT_RAW: 175219820Sjeff case DLT_NULL: 176219820Sjeff sockp->sa_family = AF_UNSPEC; 177219820Sjeff hlen = 0; 178219820Sjeff break; 179219820Sjeff 180219820Sjeff case DLT_ATM_RFC1483: 181219820Sjeff /* 182219820Sjeff * en atm driver requires 4-byte atm pseudo header. 183219820Sjeff * though it isn't standard, vpi:vci needs to be 184219820Sjeff * specified anyway. 185219820Sjeff */ 186219820Sjeff sockp->sa_family = AF_UNSPEC; 187219820Sjeff hlen = 12; /* XXX 4(ATM_PH) + 3(LLC) + 5(SNAP) */ 188219820Sjeff break; 189219820Sjeff 190219820Sjeff case DLT_PPP: 191219820Sjeff sockp->sa_family = AF_UNSPEC; 192219820Sjeff hlen = 4; /* This should match PPP_HDRLEN */ 193219820Sjeff break; 194219820Sjeff 195219820Sjeff default: 196219820Sjeff return (EIO); 197219820Sjeff } 198219820Sjeff 199219820Sjeff len = uio->uio_resid; 200219820Sjeff *datlen = len - hlen; 201219820Sjeff if ((unsigned)len > MCLBYTES) 202219820Sjeff return (EIO); 203219820Sjeff 204219820Sjeff if (len > MHLEN) { 205219820Sjeff m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); 206219820Sjeff } else { 207219820Sjeff MGETHDR(m, M_TRYWAIT, MT_DATA); 208219820Sjeff } 209219820Sjeff if (m == NULL) 210219820Sjeff return (ENOBUFS); 211219820Sjeff m->m_pkthdr.len = m->m_len = len; 212219820Sjeff m->m_pkthdr.rcvif = NULL; 213219820Sjeff *mp = m; 214219820Sjeff 215219820Sjeff /* 216219820Sjeff * Make room for link header. 217219820Sjeff */ 218219820Sjeff if (hlen != 0) { 219219820Sjeff m->m_pkthdr.len -= hlen; 220219820Sjeff m->m_len -= hlen; 221219820Sjeff#if BSD >= 199103 222219820Sjeff m->m_data += hlen; /* XXX */ 223219820Sjeff#else 224219820Sjeff m->m_off += hlen; 225219820Sjeff#endif 226219820Sjeff error = uiomove(sockp->sa_data, hlen, uio); 227219820Sjeff if (error) 228219820Sjeff goto bad; 229219820Sjeff } 230219820Sjeff error = uiomove(mtod(m, void *), len - hlen, uio); 231219820Sjeff if (!error) 232219820Sjeff return (0); 233219820Sjeffbad: 234219820Sjeff m_freem(m); 235219820Sjeff return (error); 236219820Sjeff} 237219820Sjeff 238219820Sjeff/* 239219820Sjeff * Attach file to the bpf interface, i.e. make d listen on bp. 240219820Sjeff */ 241219820Sjeffstatic void 242219820Sjeffbpf_attachd(d, bp) 243219820Sjeff struct bpf_d *d; 244219820Sjeff struct bpf_if *bp; 245219820Sjeff{ 246219820Sjeff /* 247219820Sjeff * Point d at bp, and add d to the interface's list of listeners. 248219820Sjeff * Finally, point the driver's bpf cookie at the interface so 249219820Sjeff * it will divert packets to bpf. 250219820Sjeff */ 251219820Sjeff BPFIF_LOCK(bp); 252219820Sjeff d->bd_bif = bp; 253219820Sjeff d->bd_next = bp->bif_dlist; 254219820Sjeff bp->bif_dlist = d; 255219820Sjeff 256219820Sjeff *bp->bif_driverp = bp; 257219820Sjeff BPFIF_UNLOCK(bp); 258219820Sjeff} 259219820Sjeff 260219820Sjeff/* 261219820Sjeff * Detach a file from its interface. 262219820Sjeff */ 263219820Sjeffstatic void 264219820Sjeffbpf_detachd(d) 265219820Sjeff struct bpf_d *d; 266219820Sjeff{ 267219820Sjeff int error; 268219820Sjeff struct bpf_d **p; 269219820Sjeff struct bpf_if *bp; 270219820Sjeff 271219820Sjeff bp = d->bd_bif; 272219820Sjeff /* 273219820Sjeff * Check if this descriptor had requested promiscuous mode. 274219820Sjeff * If so, turn it off. 275219820Sjeff */ 276219820Sjeff if (d->bd_promisc) { 277219820Sjeff d->bd_promisc = 0; 278219820Sjeff error = ifpromisc(bp->bif_ifp, 0); 279219820Sjeff if (error != 0 && error != ENXIO) { 280219820Sjeff /* 281219820Sjeff * ENXIO can happen if a pccard is unplugged 282219820Sjeff * Something is really wrong if we were able to put 283219820Sjeff * the driver into promiscuous mode, but can't 284219820Sjeff * take it out. 285219820Sjeff */ 286219820Sjeff if_printf(bp->bif_ifp, 287219820Sjeff "bpf_detach: ifpromisc failed (%d)\n", error); 288219820Sjeff } 289219820Sjeff } 290219820Sjeff /* Remove d from the interface's descriptor list. */ 291219820Sjeff BPFIF_LOCK(bp); 292219820Sjeff p = &bp->bif_dlist; 293219820Sjeff while (*p != d) { 294219820Sjeff p = &(*p)->bd_next; 295219820Sjeff if (*p == 0) 296219820Sjeff panic("bpf_detachd: descriptor not in list"); 297219820Sjeff } 298219820Sjeff *p = (*p)->bd_next; 299219820Sjeff if (bp->bif_dlist == 0) 300219820Sjeff /* 301219820Sjeff * Let the driver know that there are no more listeners. 302219820Sjeff */ 303219820Sjeff *d->bd_bif->bif_driverp = 0; 304219820Sjeff BPFIF_UNLOCK(bp); 305219820Sjeff d->bd_bif = 0; 306219820Sjeff} 307219820Sjeff 308219820Sjeff/* 309219820Sjeff * Open ethernet device. Returns ENXIO for illegal minor device number, 310219820Sjeff * EBUSY if file is open by another process. 311219820Sjeff */ 312219820Sjeff/* ARGSUSED */ 313219820Sjeffstatic int 314219820Sjeffbpfopen(dev, flags, fmt, td) 315219820Sjeff dev_t dev; 316219820Sjeff int flags; 317219820Sjeff int fmt; 318219820Sjeff struct thread *td; 319219820Sjeff{ 320219820Sjeff struct bpf_d *d; 321219820Sjeff 322219820Sjeff mtx_lock(&bpf_mtx); 323219820Sjeff d = dev->si_drv1; 324219820Sjeff /* 325219820Sjeff * Each minor can be opened by only one process. If the requested 326219820Sjeff * minor is in use, return EBUSY. 327219820Sjeff */ 328219820Sjeff if (d) { 329219820Sjeff mtx_unlock(&bpf_mtx); 330219820Sjeff return (EBUSY); 331219820Sjeff } 332219820Sjeff dev->si_drv1 = (struct bpf_d *)~0; /* mark device in use */ 333219820Sjeff mtx_unlock(&bpf_mtx); 334219820Sjeff 335219820Sjeff if ((dev->si_flags & SI_NAMED) == 0) 336219820Sjeff make_dev(&bpf_cdevsw, minor(dev), UID_ROOT, GID_WHEEL, 0600, 337219820Sjeff "bpf%d", dev2unit(dev)); 338219820Sjeff MALLOC(d, struct bpf_d *, sizeof(*d), M_BPF, M_WAITOK | M_ZERO); 339219820Sjeff dev->si_drv1 = d; 340219820Sjeff d->bd_bufsize = bpf_bufsize; 341219820Sjeff d->bd_sig = SIGIO; 342219820Sjeff d->bd_seesent = 1; 343219820Sjeff#ifdef MAC 344219820Sjeff mac_init_bpfdesc(d); 345219820Sjeff mac_create_bpfdesc(td->td_ucred, d); 346219820Sjeff#endif 347219820Sjeff mtx_init(&d->bd_mtx, devtoname(dev), "bpf cdev lock", MTX_DEF); 348219820Sjeff callout_init(&d->bd_callout, 1); 349219820Sjeff 350219820Sjeff return (0); 351219820Sjeff} 352219820Sjeff 353219820Sjeff/* 354219820Sjeff * Close the descriptor by detaching it from its interface, 355219820Sjeff * deallocating its buffers, and marking it free. 356219820Sjeff */ 357219820Sjeff/* ARGSUSED */ 358219820Sjeffstatic int 359219820Sjeffbpfclose(dev, flags, fmt, td) 360219820Sjeff dev_t dev; 361219820Sjeff int flags; 362219820Sjeff int fmt; 363219820Sjeff struct thread *td; 364219820Sjeff{ 365219820Sjeff struct bpf_d *d = dev->si_drv1; 366219820Sjeff 367219820Sjeff BPFD_LOCK(d); 368219820Sjeff if (d->bd_state == BPF_WAITING) 369219820Sjeff callout_stop(&d->bd_callout); 370219820Sjeff d->bd_state = BPF_IDLE; 371219820Sjeff BPFD_UNLOCK(d); 372219820Sjeff funsetown(&d->bd_sigio); 373219820Sjeff mtx_lock(&bpf_mtx); 374219820Sjeff if (d->bd_bif) 375219820Sjeff bpf_detachd(d); 376219820Sjeff mtx_unlock(&bpf_mtx); 377219820Sjeff#ifdef MAC 378219820Sjeff mac_destroy_bpfdesc(d); 379219820Sjeff#endif /* MAC */ 380219820Sjeff bpf_freed(d); 381219820Sjeff dev->si_drv1 = 0; 382219820Sjeff free(d, M_BPF); 383219820Sjeff 384219820Sjeff return (0); 385219820Sjeff} 386219820Sjeff 387219820Sjeff 388219820Sjeff/* 389219820Sjeff * Rotate the packet buffers in descriptor d. Move the store buffer 390219820Sjeff * into the hold slot, and the free buffer into the store slot. 391219820Sjeff * Zero the length of the new store buffer. 392219820Sjeff */ 393219820Sjeff#define ROTATE_BUFFERS(d) \ 394219820Sjeff (d)->bd_hbuf = (d)->bd_sbuf; \ 395219820Sjeff (d)->bd_hlen = (d)->bd_slen; \ 396219820Sjeff (d)->bd_sbuf = (d)->bd_fbuf; \ 397219820Sjeff (d)->bd_slen = 0; \ 398219820Sjeff (d)->bd_fbuf = 0; 399219820Sjeff/* 400219820Sjeff * bpfread - read next chunk of packets from buffers 401219820Sjeff */ 402219820Sjeffstatic int 403219820Sjeffbpfread(dev, uio, ioflag) 404219820Sjeff dev_t dev; 405219820Sjeff struct uio *uio; 406219820Sjeff int ioflag; 407219820Sjeff{ 408219820Sjeff struct bpf_d *d = dev->si_drv1; 409219820Sjeff int timed_out; 410219820Sjeff int error; 411219820Sjeff 412219820Sjeff /* 413219820Sjeff * Restrict application to use a buffer the same size as 414219820Sjeff * as kernel buffers. 415219820Sjeff */ 416219820Sjeff if (uio->uio_resid != d->bd_bufsize) 417219820Sjeff return (EINVAL); 418219820Sjeff 419219820Sjeff BPFD_LOCK(d); 420219820Sjeff if (d->bd_state == BPF_WAITING) 421219820Sjeff callout_stop(&d->bd_callout); 422219820Sjeff timed_out = (d->bd_state == BPF_TIMED_OUT); 423219820Sjeff d->bd_state = BPF_IDLE; 424219820Sjeff /* 425219820Sjeff * If the hold buffer is empty, then do a timed sleep, which 426219820Sjeff * ends when the timeout expires or when enough packets 427219820Sjeff * have arrived to fill the store buffer. 428219820Sjeff */ 429219820Sjeff while (d->bd_hbuf == 0) { 430219820Sjeff if ((d->bd_immediate || timed_out) && d->bd_slen != 0) { 431219820Sjeff /* 432219820Sjeff * A packet(s) either arrived since the previous 433219820Sjeff * read or arrived while we were asleep. 434219820Sjeff * Rotate the buffers and return what's here. 435219820Sjeff */ 436219820Sjeff ROTATE_BUFFERS(d); 437219820Sjeff break; 438219820Sjeff } 439219820Sjeff 440219820Sjeff /* 441219820Sjeff * No data is available, check to see if the bpf device 442219820Sjeff * is still pointed at a real interface. If not, return 443219820Sjeff * ENXIO so that the userland process knows to rebind 444219820Sjeff * it before using it again. 445219820Sjeff */ 446219820Sjeff if (d->bd_bif == NULL) { 447219820Sjeff BPFD_UNLOCK(d); 448219820Sjeff return (ENXIO); 449219820Sjeff } 450219820Sjeff 451219820Sjeff if (ioflag & IO_NDELAY) { 452219820Sjeff BPFD_UNLOCK(d); 453219820Sjeff return (EWOULDBLOCK); 454219820Sjeff } 455219820Sjeff error = msleep(d, &d->bd_mtx, PRINET|PCATCH, 456219820Sjeff "bpf", d->bd_rtout); 457219820Sjeff if (error == EINTR || error == ERESTART) { 458219820Sjeff BPFD_UNLOCK(d); 459219820Sjeff return (error); 460219820Sjeff } 461219820Sjeff if (error == EWOULDBLOCK) { 462219820Sjeff /* 463219820Sjeff * On a timeout, return what's in the buffer, 464219820Sjeff * which may be nothing. If there is something 465219820Sjeff * in the store buffer, we can rotate the buffers. 466219820Sjeff */ 467219820Sjeff if (d->bd_hbuf) 468219820Sjeff /* 469219820Sjeff * We filled up the buffer in between 470219820Sjeff * getting the timeout and arriving 471219820Sjeff * here, so we don't need to rotate. 472219820Sjeff */ 473219820Sjeff break; 474219820Sjeff 475219820Sjeff if (d->bd_slen == 0) { 476219820Sjeff BPFD_UNLOCK(d); 477219820Sjeff return (0); 478219820Sjeff } 479219820Sjeff ROTATE_BUFFERS(d); 480219820Sjeff break; 481219820Sjeff } 482219820Sjeff } 483219820Sjeff /* 484219820Sjeff * At this point, we know we have something in the hold slot. 485219820Sjeff */ 486219820Sjeff BPFD_UNLOCK(d); 487219820Sjeff 488219820Sjeff /* 489219820Sjeff * Move data from hold buffer into user space. 490219820Sjeff * We know the entire buffer is transferred since 491219820Sjeff * we checked above that the read buffer is bpf_bufsize bytes. 492219820Sjeff */ 493219820Sjeff error = uiomove(d->bd_hbuf, d->bd_hlen, uio); 494219820Sjeff 495219820Sjeff BPFD_LOCK(d); 496219820Sjeff d->bd_fbuf = d->bd_hbuf; 497219820Sjeff d->bd_hbuf = 0; 498219820Sjeff d->bd_hlen = 0; 499219820Sjeff BPFD_UNLOCK(d); 500219820Sjeff 501219820Sjeff return (error); 502219820Sjeff} 503219820Sjeff 504219820Sjeff 505219820Sjeff/* 506219820Sjeff * If there are processes sleeping on this descriptor, wake them up. 507219820Sjeff */ 508219820Sjeffstatic __inline void 509219820Sjeffbpf_wakeup(d) 510219820Sjeff struct bpf_d *d; 511219820Sjeff{ 512219820Sjeff if (d->bd_state == BPF_WAITING) { 513219820Sjeff callout_stop(&d->bd_callout); 514219820Sjeff d->bd_state = BPF_IDLE; 515219820Sjeff } 516219820Sjeff wakeup(d); 517219820Sjeff if (d->bd_async && d->bd_sig && d->bd_sigio) 518219820Sjeff pgsigio(&d->bd_sigio, d->bd_sig, 0); 519219820Sjeff 520219820Sjeff selwakeup(&d->bd_sel); 521219820Sjeff} 522219820Sjeff 523219820Sjeffstatic void 524219820Sjeffbpf_timed_out(arg) 525219820Sjeff void *arg; 526219820Sjeff{ 527219820Sjeff struct bpf_d *d = (struct bpf_d *)arg; 528219820Sjeff 529219820Sjeff BPFD_LOCK(d); 530219820Sjeff if (d->bd_state == BPF_WAITING) { 531219820Sjeff d->bd_state = BPF_TIMED_OUT; 532219820Sjeff if (d->bd_slen != 0) 533219820Sjeff bpf_wakeup(d); 534219820Sjeff } 535219820Sjeff BPFD_UNLOCK(d); 536219820Sjeff} 537219820Sjeff 538219820Sjeffstatic int 539219820Sjeffbpfwrite(dev, uio, ioflag) 540219820Sjeff dev_t dev; 541219820Sjeff struct uio *uio; 542219820Sjeff int ioflag; 543219820Sjeff{ 544219820Sjeff struct bpf_d *d = dev->si_drv1; 545219820Sjeff struct ifnet *ifp; 546219820Sjeff struct mbuf *m; 547219820Sjeff int error; 548219820Sjeff static struct sockaddr dst; 549219820Sjeff int datlen; 550219820Sjeff 551219820Sjeff if (d->bd_bif == 0) 552219820Sjeff return (ENXIO); 553219820Sjeff 554219820Sjeff ifp = d->bd_bif->bif_ifp; 555219820Sjeff 556219820Sjeff if (uio->uio_resid == 0) 557219820Sjeff return (0); 558219820Sjeff 559219820Sjeff error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen); 560219820Sjeff if (error) 561219820Sjeff return (error); 562219820Sjeff 563219820Sjeff if (datlen > ifp->if_mtu) 564219820Sjeff return (EMSGSIZE); 565219820Sjeff 566219820Sjeff if (d->bd_hdrcmplt) 567219820Sjeff dst.sa_family = pseudo_AF_HDRCMPLT; 568219820Sjeff 569219820Sjeff mtx_lock(&Giant); 570219820Sjeff#ifdef MAC 571219820Sjeff mac_create_mbuf_from_bpfdesc(d, m); 572219820Sjeff#endif 573219820Sjeff error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0); 574219820Sjeff mtx_unlock(&Giant); 575219820Sjeff /* 576219820Sjeff * The driver frees the mbuf. 577219820Sjeff */ 578219820Sjeff return (error); 579219820Sjeff} 580219820Sjeff 581219820Sjeff/* 582219820Sjeff * Reset a descriptor by flushing its packet buffer and clearing the 583219820Sjeff * receive and drop counts. 584219820Sjeff */ 585219820Sjeffstatic void 586219820Sjeffreset_d(d) 587219820Sjeff struct bpf_d *d; 588219820Sjeff{ 589219820Sjeff 590219820Sjeff mtx_assert(&d->bd_mtx, MA_OWNED); 591219820Sjeff if (d->bd_hbuf) { 592219820Sjeff /* Free the hold buffer. */ 593219820Sjeff d->bd_fbuf = d->bd_hbuf; 594219820Sjeff d->bd_hbuf = 0; 595219820Sjeff } 596219820Sjeff d->bd_slen = 0; 597219820Sjeff d->bd_hlen = 0; 598219820Sjeff d->bd_rcount = 0; 599219820Sjeff d->bd_dcount = 0; 600219820Sjeff} 601219820Sjeff 602219820Sjeff/* 603219820Sjeff * FIONREAD Check for read packet available. 604219820Sjeff * SIOCGIFADDR Get interface address - convenient hook to driver. 605219820Sjeff * BIOCGBLEN Get buffer len [for read()]. 606219820Sjeff * BIOCSETF Set ethernet read filter. 607219820Sjeff * BIOCFLUSH Flush read packet buffer. 608219820Sjeff * BIOCPROMISC Put interface into promiscuous mode. 609219820Sjeff * BIOCGDLT Get link layer type. 610219820Sjeff * BIOCGETIF Get interface name. 611219820Sjeff * BIOCSETIF Set interface. 612219820Sjeff * BIOCSRTIMEOUT Set read timeout. 613219820Sjeff * BIOCGRTIMEOUT Get read timeout. 614219820Sjeff * BIOCGSTATS Get packet stats. 615219820Sjeff * BIOCIMMEDIATE Set immediate mode. 616219820Sjeff * BIOCVERSION Get filter language version. 617219820Sjeff * BIOCGHDRCMPLT Get "header already complete" flag 618219820Sjeff * BIOCSHDRCMPLT Set "header already complete" flag 619219820Sjeff * BIOCGSEESENT Get "see packets sent" flag 620219820Sjeff * BIOCSSEESENT Set "see packets sent" flag 621219820Sjeff */ 622219820Sjeff/* ARGSUSED */ 623219820Sjeffstatic int 624219820Sjeffbpfioctl(dev, cmd, addr, flags, td) 625219820Sjeff dev_t dev; 626219820Sjeff u_long cmd; 627219820Sjeff caddr_t addr; 628219820Sjeff int flags; 629219820Sjeff struct thread *td; 630219820Sjeff{ 631219820Sjeff struct bpf_d *d = dev->si_drv1; 632219820Sjeff int error = 0; 633219820Sjeff 634219820Sjeff BPFD_LOCK(d); 635219820Sjeff if (d->bd_state == BPF_WAITING) 636219820Sjeff callout_stop(&d->bd_callout); 637219820Sjeff d->bd_state = BPF_IDLE; 638219820Sjeff BPFD_UNLOCK(d); 639219820Sjeff 640219820Sjeff switch (cmd) { 641219820Sjeff 642219820Sjeff default: 643219820Sjeff error = EINVAL; 644219820Sjeff break; 645219820Sjeff 646219820Sjeff /* 647219820Sjeff * Check for read packet available. 648219820Sjeff */ 649219820Sjeff case FIONREAD: 650219820Sjeff { 651219820Sjeff int n; 652219820Sjeff 653219820Sjeff BPFD_LOCK(d); 654219820Sjeff n = d->bd_slen; 655219820Sjeff if (d->bd_hbuf) 656219820Sjeff n += d->bd_hlen; 657219820Sjeff BPFD_UNLOCK(d); 658219820Sjeff 659219820Sjeff *(int *)addr = n; 660219820Sjeff break; 661219820Sjeff } 662219820Sjeff 663219820Sjeff case SIOCGIFADDR: 664219820Sjeff { 665219820Sjeff struct ifnet *ifp; 666219820Sjeff 667219820Sjeff if (d->bd_bif == 0) 668219820Sjeff error = EINVAL; 669219820Sjeff else { 670219820Sjeff ifp = d->bd_bif->bif_ifp; 671219820Sjeff error = (*ifp->if_ioctl)(ifp, cmd, addr); 672219820Sjeff } 673219820Sjeff break; 674219820Sjeff } 675219820Sjeff 676219820Sjeff /* 677219820Sjeff * Get buffer len [for read()]. 678219820Sjeff */ 679219820Sjeff case BIOCGBLEN: 680219820Sjeff *(u_int *)addr = d->bd_bufsize; 681219820Sjeff break; 682219820Sjeff 683219820Sjeff /* 684219820Sjeff * Set buffer length. 685219820Sjeff */ 686219820Sjeff case BIOCSBLEN: 687219820Sjeff if (d->bd_bif != 0) 688219820Sjeff error = EINVAL; 689219820Sjeff else { 690219820Sjeff u_int size = *(u_int *)addr; 691219820Sjeff 692219820Sjeff if (size > bpf_maxbufsize) 693219820Sjeff *(u_int *)addr = size = bpf_maxbufsize; 694219820Sjeff else if (size < BPF_MINBUFSIZE) 695219820Sjeff *(u_int *)addr = size = BPF_MINBUFSIZE; 696219820Sjeff d->bd_bufsize = size; 697219820Sjeff } 698219820Sjeff break; 699219820Sjeff 700219820Sjeff /* 701219820Sjeff * Set link layer read filter. 702219820Sjeff */ 703219820Sjeff case BIOCSETF: 704219820Sjeff error = bpf_setf(d, (struct bpf_program *)addr); 705219820Sjeff break; 706219820Sjeff 707219820Sjeff /* 708219820Sjeff * Flush read packet buffer. 709219820Sjeff */ 710219820Sjeff case BIOCFLUSH: 711219820Sjeff BPFD_LOCK(d); 712219820Sjeff reset_d(d); 713219820Sjeff BPFD_UNLOCK(d); 714219820Sjeff break; 715219820Sjeff 716219820Sjeff /* 717219820Sjeff * Put interface into promiscuous mode. 718219820Sjeff */ 719219820Sjeff case BIOCPROMISC: 720219820Sjeff if (d->bd_bif == 0) { 721219820Sjeff /* 722219820Sjeff * No interface attached yet. 723219820Sjeff */ 724219820Sjeff error = EINVAL; 725219820Sjeff break; 726219820Sjeff } 727219820Sjeff if (d->bd_promisc == 0) { 728219820Sjeff mtx_lock(&Giant); 729219820Sjeff error = ifpromisc(d->bd_bif->bif_ifp, 1); 730219820Sjeff mtx_unlock(&Giant); 731219820Sjeff if (error == 0) 732219820Sjeff d->bd_promisc = 1; 733219820Sjeff } 734219820Sjeff break; 735219820Sjeff 736219820Sjeff /* 737219820Sjeff * Get current data link type. 738219820Sjeff */ 739219820Sjeff case BIOCGDLT: 740219820Sjeff if (d->bd_bif == 0) 741219820Sjeff error = EINVAL; 742219820Sjeff else 743219820Sjeff *(u_int *)addr = d->bd_bif->bif_dlt; 744219820Sjeff break; 745219820Sjeff 746219820Sjeff /* 747219820Sjeff * Get a list of supported data link types. 748219820Sjeff */ 749219820Sjeff case BIOCGDLTLIST: 750219820Sjeff if (d->bd_bif == 0) 751219820Sjeff error = EINVAL; 752219820Sjeff else 753219820Sjeff error = bpf_getdltlist(d, (struct bpf_dltlist *)addr); 754219820Sjeff break; 755219820Sjeff 756219820Sjeff /* 757219820Sjeff * Set data link type. 758219820Sjeff */ 759219820Sjeff case BIOCSDLT: 760219820Sjeff if (d->bd_bif == 0) 761219820Sjeff error = EINVAL; 762219820Sjeff else 763219820Sjeff error = bpf_setdlt(d, *(u_int *)addr); 764219820Sjeff break; 765219820Sjeff 766219820Sjeff /* 767219820Sjeff * Get interface name. 768219820Sjeff */ 769219820Sjeff case BIOCGETIF: 770219820Sjeff if (d->bd_bif == 0) 771219820Sjeff error = EINVAL; 772219820Sjeff else { 773219820Sjeff struct ifnet *const ifp = d->bd_bif->bif_ifp; 774219820Sjeff struct ifreq *const ifr = (struct ifreq *)addr; 775219820Sjeff 776219820Sjeff snprintf(ifr->ifr_name, sizeof(ifr->ifr_name), 777219820Sjeff "%s%d", ifp->if_name, ifp->if_unit); 778219820Sjeff } 779219820Sjeff break; 780219820Sjeff 781219820Sjeff /* 782219820Sjeff * Set interface. 783219820Sjeff */ 784219820Sjeff case BIOCSETIF: 785219820Sjeff error = bpf_setif(d, (struct ifreq *)addr); 786219820Sjeff break; 787219820Sjeff 788219820Sjeff /* 789219820Sjeff * Set read timeout. 790219820Sjeff */ 791219820Sjeff case BIOCSRTIMEOUT: 792219820Sjeff { 793219820Sjeff struct timeval *tv = (struct timeval *)addr; 794219820Sjeff 795219820Sjeff /* 796219820Sjeff * Subtract 1 tick from tvtohz() since this isn't 797219820Sjeff * a one-shot timer. 798219820Sjeff */ 799219820Sjeff if ((error = itimerfix(tv)) == 0) 800219820Sjeff d->bd_rtout = tvtohz(tv) - 1; 801219820Sjeff break; 802219820Sjeff } 803219820Sjeff 804219820Sjeff /* 805219820Sjeff * Get read timeout. 806219820Sjeff */ 807219820Sjeff case BIOCGRTIMEOUT: 808219820Sjeff { 809219820Sjeff struct timeval *tv = (struct timeval *)addr; 810219820Sjeff 811219820Sjeff tv->tv_sec = d->bd_rtout / hz; 812219820Sjeff tv->tv_usec = (d->bd_rtout % hz) * tick; 813219820Sjeff break; 814219820Sjeff } 815219820Sjeff 816219820Sjeff /* 817219820Sjeff * Get packet stats. 818219820Sjeff */ 819219820Sjeff case BIOCGSTATS: 820219820Sjeff { 821219820Sjeff struct bpf_stat *bs = (struct bpf_stat *)addr; 822219820Sjeff 823219820Sjeff bs->bs_recv = d->bd_rcount; 824219820Sjeff bs->bs_drop = d->bd_dcount; 825219820Sjeff break; 826219820Sjeff } 827219820Sjeff 828219820Sjeff /* 829219820Sjeff * Set immediate mode. 830219820Sjeff */ 831219820Sjeff case BIOCIMMEDIATE: 832219820Sjeff d->bd_immediate = *(u_int *)addr; 833219820Sjeff break; 834219820Sjeff 835219820Sjeff case BIOCVERSION: 836219820Sjeff { 837219820Sjeff struct bpf_version *bv = (struct bpf_version *)addr; 838219820Sjeff 839219820Sjeff bv->bv_major = BPF_MAJOR_VERSION; 840219820Sjeff bv->bv_minor = BPF_MINOR_VERSION; 841219820Sjeff break; 842219820Sjeff } 843219820Sjeff 844219820Sjeff /* 845219820Sjeff * Get "header already complete" flag 846219820Sjeff */ 847219820Sjeff case BIOCGHDRCMPLT: 848219820Sjeff *(u_int *)addr = d->bd_hdrcmplt; 849219820Sjeff break; 850219820Sjeff 851219820Sjeff /* 852219820Sjeff * Set "header already complete" flag 853219820Sjeff */ 854219820Sjeff case BIOCSHDRCMPLT: 855219820Sjeff d->bd_hdrcmplt = *(u_int *)addr ? 1 : 0; 856219820Sjeff break; 857219820Sjeff 858219820Sjeff /* 859219820Sjeff * Get "see sent packets" flag 860219820Sjeff */ 861219820Sjeff case BIOCGSEESENT: 862219820Sjeff *(u_int *)addr = d->bd_seesent; 863219820Sjeff break; 864219820Sjeff 865219820Sjeff /* 866219820Sjeff * Set "see sent packets" flag 867219820Sjeff */ 868219820Sjeff case BIOCSSEESENT: 869219820Sjeff d->bd_seesent = *(u_int *)addr; 870219820Sjeff break; 871219820Sjeff 872219820Sjeff case FIONBIO: /* Non-blocking I/O */ 873219820Sjeff break; 874219820Sjeff 875219820Sjeff case FIOASYNC: /* Send signal on receive packets */ 876219820Sjeff d->bd_async = *(int *)addr; 877219820Sjeff break; 878219820Sjeff 879219820Sjeff case FIOSETOWN: 880219820Sjeff error = fsetown(*(int *)addr, &d->bd_sigio); 881219820Sjeff break; 882219820Sjeff 883219820Sjeff case FIOGETOWN: 884219820Sjeff *(int *)addr = fgetown(&d->bd_sigio); 885219820Sjeff break; 886219820Sjeff 887219820Sjeff /* This is deprecated, FIOSETOWN should be used instead. */ 888219820Sjeff case TIOCSPGRP: 889219820Sjeff error = fsetown(-(*(int *)addr), &d->bd_sigio); 890219820Sjeff break; 891219820Sjeff 892219820Sjeff /* This is deprecated, FIOGETOWN should be used instead. */ 893219820Sjeff case TIOCGPGRP: 894219820Sjeff *(int *)addr = -fgetown(&d->bd_sigio); 895219820Sjeff break; 896219820Sjeff 897219820Sjeff case BIOCSRSIG: /* Set receive signal */ 898219820Sjeff { 899219820Sjeff u_int sig; 900219820Sjeff 901219820Sjeff sig = *(u_int *)addr; 902219820Sjeff 903219820Sjeff if (sig >= NSIG) 904219820Sjeff error = EINVAL; 905219820Sjeff else 906219820Sjeff d->bd_sig = sig; 907219820Sjeff break; 908219820Sjeff } 909219820Sjeff case BIOCGRSIG: 910219820Sjeff *(u_int *)addr = d->bd_sig; 911219820Sjeff break; 912219820Sjeff } 913219820Sjeff return (error); 914219820Sjeff} 915219820Sjeff 916219820Sjeff/* 917219820Sjeff * Set d's packet filter program to fp. If this file already has a filter, 918219820Sjeff * free it and replace it. Returns EINVAL for bogus requests. 919219820Sjeff */ 920219820Sjeffstatic int 921219820Sjeffbpf_setf(d, fp) 922219820Sjeff struct bpf_d *d; 923219820Sjeff struct bpf_program *fp; 924219820Sjeff{ 925219820Sjeff struct bpf_insn *fcode, *old; 926219820Sjeff u_int flen, size; 927219820Sjeff 928219820Sjeff old = d->bd_filter; 929219820Sjeff if (fp->bf_insns == 0) { 930219820Sjeff if (fp->bf_len != 0) 931219820Sjeff return (EINVAL); 932219820Sjeff BPFD_LOCK(d); 933219820Sjeff d->bd_filter = 0; 934219820Sjeff reset_d(d); 935219820Sjeff BPFD_UNLOCK(d); 936219820Sjeff if (old != 0) 937219820Sjeff free((caddr_t)old, M_BPF); 938219820Sjeff return (0); 939219820Sjeff } 940219820Sjeff flen = fp->bf_len; 941219820Sjeff if (flen > BPF_MAXINSNS) 942219820Sjeff return (EINVAL); 943219820Sjeff 944219820Sjeff size = flen * sizeof(*fp->bf_insns); 945219820Sjeff fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK); 946219820Sjeff if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && 947219820Sjeff bpf_validate(fcode, (int)flen)) { 948219820Sjeff BPFD_LOCK(d); 949219820Sjeff d->bd_filter = fcode; 950219820Sjeff reset_d(d); 951219820Sjeff BPFD_UNLOCK(d); 952219820Sjeff if (old != 0) 953219820Sjeff free((caddr_t)old, M_BPF); 954219820Sjeff 955219820Sjeff return (0); 956219820Sjeff } 957219820Sjeff free((caddr_t)fcode, M_BPF); 958219820Sjeff return (EINVAL); 959219820Sjeff} 960219820Sjeff 961219820Sjeff/* 962219820Sjeff * Detach a file from its current interface (if attached at all) and attach 963219820Sjeff * to the interface indicated by the name stored in ifr. 964219820Sjeff * Return an errno or 0. 965219820Sjeff */ 966219820Sjeffstatic int 967219820Sjeffbpf_setif(d, ifr) 968219820Sjeff struct bpf_d *d; 969219820Sjeff struct ifreq *ifr; 970219820Sjeff{ 971219820Sjeff struct bpf_if *bp; 972219820Sjeff int error; 973219820Sjeff struct ifnet *theywant; 974219820Sjeff 975219820Sjeff theywant = ifunit(ifr->ifr_name); 976219820Sjeff if (theywant == 0) 977219820Sjeff return ENXIO; 978219820Sjeff 979219820Sjeff /* 980219820Sjeff * Look through attached interfaces for the named one. 981219820Sjeff */ 982219820Sjeff mtx_lock(&bpf_mtx); 983219820Sjeff for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { 984219820Sjeff struct ifnet *ifp = bp->bif_ifp; 985219820Sjeff 986219820Sjeff if (ifp == 0 || ifp != theywant) 987219820Sjeff continue; 988219820Sjeff /* skip additional entry */ 989219820Sjeff if (bp->bif_driverp != (struct bpf_if **)&ifp->if_bpf) 990219820Sjeff continue; 991219820Sjeff 992219820Sjeff mtx_unlock(&bpf_mtx); 993219820Sjeff /* 994219820Sjeff * We found the requested interface. 995219820Sjeff * If it's not up, return an error. 996219820Sjeff * Allocate the packet buffers if we need to. 997219820Sjeff * If we're already attached to requested interface, 998219820Sjeff * just flush the buffer. 999219820Sjeff */ 1000219820Sjeff if ((ifp->if_flags & IFF_UP) == 0) 1001219820Sjeff return (ENETDOWN); 1002219820Sjeff 1003219820Sjeff if (d->bd_sbuf == 0) { 1004219820Sjeff error = bpf_allocbufs(d); 1005219820Sjeff if (error != 0) 1006219820Sjeff return (error); 1007219820Sjeff } 1008219820Sjeff if (bp != d->bd_bif) { 1009219820Sjeff if (d->bd_bif) 1010219820Sjeff /* 1011219820Sjeff * Detach if attached to something else. 1012219820Sjeff */ 1013219820Sjeff bpf_detachd(d); 1014219820Sjeff 1015219820Sjeff bpf_attachd(d, bp); 1016219820Sjeff } 1017219820Sjeff BPFD_LOCK(d); 1018219820Sjeff reset_d(d); 1019219820Sjeff BPFD_UNLOCK(d); 1020219820Sjeff return (0); 1021219820Sjeff } 1022219820Sjeff mtx_unlock(&bpf_mtx); 1023219820Sjeff /* Not found. */ 1024219820Sjeff return (ENXIO); 1025219820Sjeff} 1026219820Sjeff 1027219820Sjeff/* 1028219820Sjeff * Support for select() and poll() system calls 1029219820Sjeff * 1030219820Sjeff * Return true iff the specific operation will not block indefinitely. 1031219820Sjeff * Otherwise, return false but make a note that a selwakeup() must be done. 1032219820Sjeff */ 1033219820Sjeffstatic int 1034219820Sjeffbpfpoll(dev, events, td) 1035219820Sjeff dev_t dev; 1036219820Sjeff int events; 1037219820Sjeff struct thread *td; 1038219820Sjeff{ 1039219820Sjeff struct bpf_d *d; 1040219820Sjeff int revents; 1041219820Sjeff 1042219820Sjeff d = dev->si_drv1; 1043219820Sjeff if (d->bd_bif == NULL) 1044219820Sjeff return (ENXIO); 1045219820Sjeff 1046219820Sjeff revents = events & (POLLOUT | POLLWRNORM); 1047219820Sjeff BPFD_LOCK(d); 1048219820Sjeff if (events & (POLLIN | POLLRDNORM)) { 1049219820Sjeff /* 1050219820Sjeff * An imitation of the FIONREAD ioctl code. 1051219820Sjeff * XXX not quite. An exact imitation: 1052219820Sjeff * if (d->b_slen != 0 || 1053219820Sjeff * (d->bd_hbuf != NULL && d->bd_hlen != 0) 1054219820Sjeff */ 1055219820Sjeff if (d->bd_hlen != 0 || 1056219820Sjeff ((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) && 1057219820Sjeff d->bd_slen != 0)) 1058219820Sjeff revents |= events & (POLLIN | POLLRDNORM); 1059219820Sjeff else { 1060219820Sjeff selrecord(td, &d->bd_sel); 1061219820Sjeff /* Start the read timeout if necessary. */ 1062219820Sjeff if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) { 1063219820Sjeff callout_reset(&d->bd_callout, d->bd_rtout, 1064219820Sjeff bpf_timed_out, d); 1065219820Sjeff d->bd_state = BPF_WAITING; 1066219820Sjeff } 1067219820Sjeff } 1068219820Sjeff } 1069219820Sjeff BPFD_UNLOCK(d); 1070219820Sjeff return (revents); 1071219820Sjeff} 1072219820Sjeff 1073219820Sjeff/* 1074219820Sjeff * Incoming linkage from device drivers. Process the packet pkt, of length 1075219820Sjeff * pktlen, which is stored in a contiguous buffer. The packet is parsed 1076219820Sjeff * by each process' filter, and if accepted, stashed into the corresponding 1077219820Sjeff * buffer. 1078219820Sjeff */ 1079219820Sjeffvoid 1080219820Sjeffbpf_tap(bp, pkt, pktlen) 1081219820Sjeff struct bpf_if *bp; 1082219820Sjeff u_char *pkt; 1083219820Sjeff u_int pktlen; 1084219820Sjeff{ 1085219820Sjeff struct bpf_d *d; 1086219820Sjeff u_int slen; 1087219820Sjeff 1088219820Sjeff BPFIF_LOCK(bp); 1089219820Sjeff for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 1090219820Sjeff BPFD_LOCK(d); 1091219820Sjeff ++d->bd_rcount; 1092219820Sjeff slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 1093219820Sjeff if (slen != 0) { 1094219820Sjeff#ifdef MAC 1095219820Sjeff if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0) 1096219820Sjeff#endif 1097219820Sjeff catchpacket(d, pkt, pktlen, slen, bcopy); 1098219820Sjeff } 1099219820Sjeff BPFD_UNLOCK(d); 1100219820Sjeff } 1101219820Sjeff BPFIF_UNLOCK(bp); 1102219820Sjeff} 1103219820Sjeff 1104219820Sjeff/* 1105219820Sjeff * Copy data from an mbuf chain into a buffer. This code is derived 1106219820Sjeff * from m_copydata in sys/uipc_mbuf.c. 1107219820Sjeff */ 1108219820Sjeffstatic void 1109219820Sjeffbpf_mcopy(src_arg, dst_arg, len) 1110219820Sjeff const void *src_arg; 1111219820Sjeff void *dst_arg; 1112219820Sjeff size_t len; 1113219820Sjeff{ 1114219820Sjeff const struct mbuf *m; 1115219820Sjeff u_int count; 1116219820Sjeff u_char *dst; 1117219820Sjeff 1118219820Sjeff m = src_arg; 1119219820Sjeff dst = dst_arg; 1120219820Sjeff while (len > 0) { 1121219820Sjeff if (m == 0) 1122219820Sjeff panic("bpf_mcopy"); 1123219820Sjeff count = min(m->m_len, len); 1124219820Sjeff bcopy(mtod(m, void *), dst, count); 1125219820Sjeff m = m->m_next; 1126219820Sjeff dst += count; 1127219820Sjeff len -= count; 1128219820Sjeff } 1129219820Sjeff} 1130219820Sjeff 1131219820Sjeff/* 1132219820Sjeff * Incoming linkage from device drivers, when packet is in an mbuf chain. 1133219820Sjeff */ 1134219820Sjeffvoid 1135219820Sjeffbpf_mtap(bp, m) 1136219820Sjeff struct bpf_if *bp; 1137219820Sjeff struct mbuf *m; 1138219820Sjeff{ 1139219820Sjeff struct bpf_d *d; 1140219820Sjeff u_int pktlen, slen; 1141219820Sjeff 1142219820Sjeff pktlen = m_length(m, NULL); 1143219820Sjeff if (pktlen == m->m_len) { 1144219820Sjeff bpf_tap(bp, mtod(m, u_char *), pktlen); 1145219820Sjeff return; 1146219820Sjeff } 1147219820Sjeff 1148219820Sjeff BPFIF_LOCK(bp); 1149219820Sjeff for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 1150219820Sjeff if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL)) 1151219820Sjeff continue; 1152219820Sjeff BPFD_LOCK(d); 1153219820Sjeff ++d->bd_rcount; 1154219820Sjeff slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); 1155219820Sjeff if (slen != 0) 1156219820Sjeff#ifdef MAC 1157219820Sjeff if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0) 1158219820Sjeff#endif 1159219820Sjeff catchpacket(d, (u_char *)m, pktlen, slen, 1160219820Sjeff bpf_mcopy); 1161219820Sjeff BPFD_UNLOCK(d); 1162219820Sjeff } 1163219820Sjeff BPFIF_UNLOCK(bp); 1164219820Sjeff} 1165219820Sjeff 1166219820Sjeff/* 1167219820Sjeff * Move the packet data from interface memory (pkt) into the 1168219820Sjeff * store buffer. Return 1 if it's time to wakeup a listener (buffer full), 1169219820Sjeff * otherwise 0. "copy" is the routine called to do the actual data 1170219820Sjeff * transfer. bcopy is passed in to copy contiguous chunks, while 1171219820Sjeff * bpf_mcopy is passed in to copy mbuf chains. In the latter case, 1172219820Sjeff * pkt is really an mbuf. 1173219820Sjeff */ 1174219820Sjeffstatic void 1175219820Sjeffcatchpacket(d, pkt, pktlen, snaplen, cpfn) 1176219820Sjeff struct bpf_d *d; 1177219820Sjeff u_char *pkt; 1178219820Sjeff u_int pktlen, snaplen; 1179219820Sjeff void (*cpfn)(const void *, void *, size_t); 1180219820Sjeff{ 1181219820Sjeff struct bpf_hdr *hp; 1182219820Sjeff int totlen, curlen; 1183219820Sjeff int hdrlen = d->bd_bif->bif_hdrlen; 1184219820Sjeff /* 1185219820Sjeff * Figure out how many bytes to move. If the packet is 1186219820Sjeff * greater or equal to the snapshot length, transfer that 1187219820Sjeff * much. Otherwise, transfer the whole packet (unless 1188219820Sjeff * we hit the buffer size limit). 1189219820Sjeff */ 1190219820Sjeff totlen = hdrlen + min(snaplen, pktlen); 1191219820Sjeff if (totlen > d->bd_bufsize) 1192219820Sjeff totlen = d->bd_bufsize; 1193219820Sjeff 1194219820Sjeff /* 1195219820Sjeff * Round up the end of the previous packet to the next longword. 1196219820Sjeff */ 1197219820Sjeff curlen = BPF_WORDALIGN(d->bd_slen); 1198219820Sjeff if (curlen + totlen > d->bd_bufsize) { 1199219820Sjeff /* 1200219820Sjeff * This packet will overflow the storage buffer. 1201219820Sjeff * Rotate the buffers if we can, then wakeup any 1202219820Sjeff * pending reads. 1203219820Sjeff */ 1204219820Sjeff if (d->bd_fbuf == 0) { 1205219820Sjeff /* 1206219820Sjeff * We haven't completed the previous read yet, 1207219820Sjeff * so drop the packet. 1208219820Sjeff */ 1209219820Sjeff ++d->bd_dcount; 1210219820Sjeff return; 1211219820Sjeff } 1212219820Sjeff ROTATE_BUFFERS(d); 1213219820Sjeff bpf_wakeup(d); 1214219820Sjeff curlen = 0; 1215219820Sjeff } 1216219820Sjeff else if (d->bd_immediate || d->bd_state == BPF_TIMED_OUT) 1217219820Sjeff /* 1218219820Sjeff * Immediate mode is set, or the read timeout has 1219219820Sjeff * already expired during a select call. A packet 1220219820Sjeff * arrived, so the reader should be woken up. 1221219820Sjeff */ 1222219820Sjeff bpf_wakeup(d); 1223219820Sjeff 1224219820Sjeff /* 1225219820Sjeff * Append the bpf header. 1226219820Sjeff */ 1227219820Sjeff hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); 1228219820Sjeff microtime(&hp->bh_tstamp); 1229219820Sjeff hp->bh_datalen = pktlen; 1230219820Sjeff hp->bh_hdrlen = hdrlen; 1231219820Sjeff /* 1232219820Sjeff * Copy the packet data into the store buffer and update its length. 1233219820Sjeff */ 1234219820Sjeff (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); 1235219820Sjeff d->bd_slen = curlen + totlen; 1236219820Sjeff} 1237219820Sjeff 1238219820Sjeff/* 1239219820Sjeff * Initialize all nonzero fields of a descriptor. 1240219820Sjeff */ 1241219820Sjeffstatic int 1242219820Sjeffbpf_allocbufs(d) 1243219820Sjeff struct bpf_d *d; 1244219820Sjeff{ 1245219820Sjeff d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_BPF, M_WAITOK); 1246219820Sjeff if (d->bd_fbuf == 0) 1247219820Sjeff return (ENOBUFS); 1248219820Sjeff 1249219820Sjeff d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_BPF, M_WAITOK); 1250219820Sjeff if (d->bd_sbuf == 0) { 1251219820Sjeff free(d->bd_fbuf, M_BPF); 1252219820Sjeff return (ENOBUFS); 1253219820Sjeff } 1254219820Sjeff d->bd_slen = 0; 1255219820Sjeff d->bd_hlen = 0; 1256219820Sjeff return (0); 1257219820Sjeff} 1258219820Sjeff 1259219820Sjeff/* 1260219820Sjeff * Free buffers currently in use by a descriptor. 1261219820Sjeff * Called on close. 1262219820Sjeff */ 1263219820Sjeffstatic void 1264219820Sjeffbpf_freed(d) 1265219820Sjeff struct bpf_d *d; 1266219820Sjeff{ 1267219820Sjeff /* 1268219820Sjeff * We don't need to lock out interrupts since this descriptor has 1269219820Sjeff * been detached from its interface and it yet hasn't been marked 1270219820Sjeff * free. 1271219820Sjeff */ 1272219820Sjeff if (d->bd_sbuf != 0) { 1273219820Sjeff free(d->bd_sbuf, M_BPF); 1274219820Sjeff if (d->bd_hbuf != 0) 1275219820Sjeff free(d->bd_hbuf, M_BPF); 1276219820Sjeff if (d->bd_fbuf != 0) 1277219820Sjeff free(d->bd_fbuf, M_BPF); 1278219820Sjeff } 1279219820Sjeff if (d->bd_filter) 1280219820Sjeff free((caddr_t)d->bd_filter, M_BPF); 1281219820Sjeff mtx_destroy(&d->bd_mtx); 1282219820Sjeff} 1283219820Sjeff 1284219820Sjeff/* 1285219820Sjeff * Attach an interface to bpf. dlt is the link layer type; hdrlen is the 1286219820Sjeff * fixed size of the link header (variable length headers not yet supported). 1287219820Sjeff */ 1288219820Sjeffvoid 1289219820Sjeffbpfattach(ifp, dlt, hdrlen) 1290219820Sjeff struct ifnet *ifp; 1291219820Sjeff u_int dlt, hdrlen; 1292219820Sjeff{ 1293219820Sjeff 1294219820Sjeff bpfattach2(ifp, dlt, hdrlen, &ifp->if_bpf); 1295219820Sjeff} 1296219820Sjeff 1297219820Sjeff/* 1298219820Sjeff * Attach an interface to bpf. ifp is a pointer to the structure 1299219820Sjeff * defining the interface to be attached, dlt is the link layer type, 1300219820Sjeff * and hdrlen is the fixed size of the link header (variable length 1301219820Sjeff * headers are not yet supporrted). 1302219820Sjeff */ 1303219820Sjeffvoid 1304219820Sjeffbpfattach2(ifp, dlt, hdrlen, driverp) 1305219820Sjeff struct ifnet *ifp; 1306219820Sjeff u_int dlt, hdrlen; 1307219820Sjeff struct bpf_if **driverp; 1308219820Sjeff{ 1309219820Sjeff struct bpf_if *bp; 1310219820Sjeff bp = (struct bpf_if *)malloc(sizeof(*bp), M_BPF, M_NOWAIT | M_ZERO); 1311219820Sjeff if (bp == 0) 1312219820Sjeff panic("bpfattach"); 1313219820Sjeff 1314219820Sjeff bp->bif_dlist = 0; 1315219820Sjeff bp->bif_driverp = driverp; 1316219820Sjeff bp->bif_ifp = ifp; 1317219820Sjeff bp->bif_dlt = dlt; 1318219820Sjeff mtx_init(&bp->bif_mtx, "bpf interface lock", NULL, MTX_DEF); 1319219820Sjeff 1320219820Sjeff mtx_lock(&bpf_mtx); 1321219820Sjeff bp->bif_next = bpf_iflist; 1322219820Sjeff bpf_iflist = bp; 1323219820Sjeff mtx_unlock(&bpf_mtx); 1324219820Sjeff 1325219820Sjeff *bp->bif_driverp = 0; 1326219820Sjeff 1327219820Sjeff /* 1328219820Sjeff * Compute the length of the bpf header. This is not necessarily 1329219820Sjeff * equal to SIZEOF_BPF_HDR because we want to insert spacing such 1330219820Sjeff * that the network layer header begins on a longword boundary (for 1331219820Sjeff * performance reasons and to alleviate alignment restrictions). 1332219820Sjeff */ 1333219820Sjeff bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; 1334219820Sjeff 1335219820Sjeff if (bootverbose) 1336219820Sjeff if_printf(ifp, "bpf attached\n"); 1337219820Sjeff} 1338219820Sjeff 1339219820Sjeff/* 1340219820Sjeff * Detach bpf from an interface. This involves detaching each descriptor 1341219820Sjeff * associated with the interface, and leaving bd_bif NULL. Notify each 1342219820Sjeff * descriptor as it's detached so that any sleepers wake up and get 1343219820Sjeff * ENXIO. 1344219820Sjeff */ 1345219820Sjeffvoid 1346219820Sjeffbpfdetach(ifp) 1347219820Sjeff struct ifnet *ifp; 1348219820Sjeff{ 1349219820Sjeff struct bpf_if *bp, *bp_prev; 1350219820Sjeff struct bpf_d *d; 1351219820Sjeff 1352219820Sjeff /* Locate BPF interface information */ 1353219820Sjeff bp_prev = NULL; 1354219820Sjeff 1355219820Sjeff mtx_lock(&bpf_mtx); 1356219820Sjeff for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) { 1357219820Sjeff if (ifp == bp->bif_ifp) 1358219820Sjeff break; 1359219820Sjeff bp_prev = bp; 1360219820Sjeff } 1361219820Sjeff 1362219820Sjeff /* Interface wasn't attached */ 1363219820Sjeff if ((bp == NULL) || (bp->bif_ifp == NULL)) { 1364219820Sjeff mtx_unlock(&bpf_mtx); 1365219820Sjeff printf("bpfdetach: %s%d was not attached\n", ifp->if_name, 1366219820Sjeff ifp->if_unit); 1367219820Sjeff return; 1368219820Sjeff } 1369219820Sjeff 1370219820Sjeff if (bp_prev) { 1371219820Sjeff bp_prev->bif_next = bp->bif_next; 1372219820Sjeff } else { 1373219820Sjeff bpf_iflist = bp->bif_next; 1374219820Sjeff } 1375219820Sjeff mtx_unlock(&bpf_mtx); 1376219820Sjeff 1377219820Sjeff while ((d = bp->bif_dlist) != NULL) { 1378219820Sjeff bpf_detachd(d); 1379219820Sjeff BPFD_LOCK(d); 1380219820Sjeff bpf_wakeup(d); 1381219820Sjeff BPFD_UNLOCK(d); 1382219820Sjeff } 1383219820Sjeff 1384219820Sjeff mtx_destroy(&bp->bif_mtx); 1385219820Sjeff free(bp, M_BPF); 1386219820Sjeff} 1387219820Sjeff 1388219820Sjeff/* 1389219820Sjeff * Get a list of available data link type of the interface. 1390219820Sjeff */ 1391219820Sjeffstatic int 1392219820Sjeffbpf_getdltlist(d, bfl) 1393219820Sjeff struct bpf_d *d; 1394219820Sjeff struct bpf_dltlist *bfl; 1395219820Sjeff{ 1396219820Sjeff int n, error; 1397219820Sjeff struct ifnet *ifp; 1398219820Sjeff struct bpf_if *bp; 1399219820Sjeff 1400219820Sjeff ifp = d->bd_bif->bif_ifp; 1401219820Sjeff n = 0; 1402219820Sjeff error = 0; 1403219820Sjeff mtx_lock(&bpf_mtx); 1404219820Sjeff for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) { 1405219820Sjeff if (bp->bif_ifp != ifp) 1406219820Sjeff continue; 1407219820Sjeff if (bfl->bfl_list != NULL) { 1408219820Sjeff if (n >= bfl->bfl_len) { 1409219820Sjeff mtx_unlock(&bpf_mtx); 1410219820Sjeff return (ENOMEM); 1411219820Sjeff } 1412219820Sjeff error = copyout(&bp->bif_dlt, 1413219820Sjeff bfl->bfl_list + n, sizeof(u_int)); 1414219820Sjeff } 1415219820Sjeff n++; 1416219820Sjeff } 1417219820Sjeff mtx_unlock(&bpf_mtx); 1418219820Sjeff bfl->bfl_len = n; 1419219820Sjeff return (error); 1420219820Sjeff} 1421219820Sjeff 1422219820Sjeff/* 1423219820Sjeff * Set the data link type of a BPF instance. 1424219820Sjeff */ 1425219820Sjeffstatic int 1426219820Sjeffbpf_setdlt(d, dlt) 1427219820Sjeff struct bpf_d *d; 1428219820Sjeff u_int dlt; 1429219820Sjeff{ 1430219820Sjeff int error, opromisc; 1431219820Sjeff struct ifnet *ifp; 1432219820Sjeff struct bpf_if *bp; 1433219820Sjeff 1434219820Sjeff if (d->bd_bif->bif_dlt == dlt) 1435219820Sjeff return (0); 1436219820Sjeff ifp = d->bd_bif->bif_ifp; 1437219820Sjeff mtx_lock(&bpf_mtx); 1438219820Sjeff for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) { 1439219820Sjeff if (bp->bif_ifp == ifp && bp->bif_dlt == dlt) 1440219820Sjeff break; 1441219820Sjeff } 1442219820Sjeff mtx_unlock(&bpf_mtx); 1443219820Sjeff if (bp != NULL) { 1444219820Sjeff BPFD_LOCK(d); 1445219820Sjeff opromisc = d->bd_promisc; 1446219820Sjeff bpf_detachd(d); 1447219820Sjeff bpf_attachd(d, bp); 1448219820Sjeff reset_d(d); 1449219820Sjeff BPFD_UNLOCK(d); 1450219820Sjeff if (opromisc) { 1451219820Sjeff error = ifpromisc(bp->bif_ifp, 1); 1452219820Sjeff if (error) 1453219820Sjeff if_printf(bp->bif_ifp, 1454219820Sjeff "bpf_setdlt: ifpromisc failed (%d)\n", 1455219820Sjeff error); 1456219820Sjeff else 1457219820Sjeff d->bd_promisc = 1; 1458219820Sjeff } 1459219820Sjeff } 1460219820Sjeff return (bp == NULL ? EINVAL : 0); 1461219820Sjeff} 1462219820Sjeff 1463219820Sjeffstatic void bpf_drvinit(void *unused); 1464219820Sjeff 1465219820Sjeffstatic void bpf_clone(void *arg, char *name, int namelen, dev_t *dev); 1466219820Sjeff 1467219820Sjeffstatic void 1468219820Sjeffbpf_clone(arg, name, namelen, dev) 1469219820Sjeff void *arg; 1470219820Sjeff char *name; 1471219820Sjeff int namelen; 1472219820Sjeff dev_t *dev; 1473219820Sjeff{ 1474219820Sjeff int u; 1475219820Sjeff 1476219820Sjeff if (*dev != NODEV) 1477219820Sjeff return; 1478219820Sjeff if (dev_stdclone(name, NULL, "bpf", &u) != 1) 1479219820Sjeff return; 1480219820Sjeff *dev = make_dev(&bpf_cdevsw, unit2minor(u), UID_ROOT, GID_WHEEL, 0600, 1481219820Sjeff "bpf%d", u); 1482219820Sjeff (*dev)->si_flags |= SI_CHEAPCLONE; 1483219820Sjeff return; 1484219820Sjeff} 1485219820Sjeff 1486219820Sjeffstatic void 1487219820Sjeffbpf_drvinit(unused) 1488219820Sjeff void *unused; 1489219820Sjeff{ 1490219820Sjeff 1491219820Sjeff mtx_init(&bpf_mtx, "bpf global lock", NULL, MTX_DEF); 1492219820Sjeff EVENTHANDLER_REGISTER(dev_clone, bpf_clone, 0, 1000); 1493219820Sjeff} 1494219820Sjeff 1495219820SjeffSYSINIT(bpfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bpf_drvinit,NULL) 1496219820Sjeff 1497219820Sjeff#else /* !DEV_BPF && !NETGRAPH_BPF */ 1498219820Sjeff/* 1499219820Sjeff * NOP stubs to allow bpf-using drivers to load and function. 1500219820Sjeff * 1501219820Sjeff * A 'better' implementation would allow the core bpf functionality 1502219820Sjeff * to be loaded at runtime. 1503219820Sjeff */ 1504219820Sjeff 1505219820Sjeffvoid 1506219820Sjeffbpf_tap(bp, pkt, pktlen) 1507219820Sjeff struct bpf_if *bp; 1508219820Sjeff u_char *pkt; 1509219820Sjeff u_int pktlen; 1510219820Sjeff{ 1511219820Sjeff} 1512219820Sjeff 1513219820Sjeffvoid 1514219820Sjeffbpf_mtap(bp, m) 1515219820Sjeff struct bpf_if *bp; 1516219820Sjeff struct mbuf *m; 1517219820Sjeff{ 1518219820Sjeff} 1519219820Sjeff 1520219820Sjeffvoid 1521219820Sjeffbpfattach(ifp, dlt, hdrlen) 1522219820Sjeff struct ifnet *ifp; 1523219820Sjeff u_int dlt, hdrlen; 1524219820Sjeff{ 1525219820Sjeff} 1526219820Sjeff 1527219820Sjeffvoid 1528219820Sjeffbpfdetach(ifp) 1529219820Sjeff struct ifnet *ifp; 1530219820Sjeff{ 1531219820Sjeff} 1532219820Sjeff 1533219820Sjeffu_int 1534219820Sjeffbpf_filter(pc, p, wirelen, buflen) 1535219820Sjeff const struct bpf_insn *pc; 1536219820Sjeff u_char *p; 1537219820Sjeff u_int wirelen; 1538219820Sjeff u_int buflen; 1539219820Sjeff{ 1540219820Sjeff return -1; /* "no filter" behaviour */ 1541219820Sjeff} 1542219820Sjeff 1543219820Sjeffint 1544219820Sjeffbpf_validate(f, len) 1545219820Sjeff const struct bpf_insn *f; 1546219820Sjeff int len; 1547219820Sjeff{ 1548219820Sjeff return 0; /* false */ 1549219820Sjeff} 1550219820Sjeff 1551219820Sjeff#endif /* !DEV_BPF && !NETGRAPH_BPF */ 1552219820Sjeff