|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1991 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from the Stanford/CMU enet packet filter, ! 6: * (net/enet.c) distributed as part of 4.3BSD, and code contributed ! 7: * to Berkeley by Steven McCanne of Lawrence Berkeley Laboratory. ! 8: * ! 9: * Redistribution and use in source and binary forms, with or without ! 10: * modification, are permitted provided that the following conditions ! 11: * are met: ! 12: * 1. Redistributions of source code must retain the above copyright ! 13: * notice, this list of conditions and the following disclaimer. ! 14: * 2. Redistributions in binary form must reproduce the above copyright ! 15: * notice, this list of conditions and the following disclaimer in the ! 16: * documentation and/or other materials provided with the distribution. ! 17: * 3. All advertising materials mentioning features or use of this software ! 18: * must display the following acknowledgement: ! 19: * This product includes software developed by the University of ! 20: * California, Berkeley and its contributors. ! 21: * 4. Neither the name of the University nor the names of its contributors ! 22: * may be used to endorse or promote products derived from this software ! 23: * without specific prior written permission. ! 24: * ! 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 35: * SUCH DAMAGE. ! 36: * ! 37: * @(#)bpf.c 7.4 (Berkeley) 6/17/91 ! 38: * ! 39: * static char rcsid[] = ! 40: * "$Header: bpf.c,v 1.23 91/01/30 18:22:13 mccanne Exp $"; ! 41: */ ! 42: ! 43: #include "bpfilter.h" ! 44: ! 45: #if (NBPFILTER > 0) ! 46: ! 47: #include <sys/param.h> ! 48: #include <sys/systm.h> ! 49: #include <sys/mbuf.h> ! 50: #include <sys/buf.h> ! 51: #include <sys/dir.h> ! 52: #include <sys/proc.h> ! 53: #include <sys/user.h> ! 54: #include <sys/ioctl.h> ! 55: #include <sys/map.h> ! 56: ! 57: #include <sys/file.h> ! 58: #ifdef sparc ! 59: #include <sys/stream.h> ! 60: #endif ! 61: #include <sys/tty.h> ! 62: #include <sys/uio.h> ! 63: ! 64: #include <sys/protosw.h> ! 65: #include <sys/socket.h> ! 66: #include <net/if.h> ! 67: ! 68: #include <net/bpf.h> ! 69: #include <net/bpfdesc.h> ! 70: ! 71: #include <sys/errno.h> ! 72: ! 73: #include <netinet/in.h> ! 74: #include <netinet/if_ether.h> ! 75: #include <sys/kernel.h> ! 76: ! 77: #define PRINET 26 /* interruptible */ ! 78: ! 79: /* ! 80: * The default read buffer size is patchable. ! 81: */ ! 82: int bpf_bufsize = MCLBYTES; ! 83: ! 84: /* ! 85: * bpf_iflist is the list of interfaces; each corresponds to an ifnet ! 86: * bpf_dtab holds the descriptors, indexed by minor device # ! 87: * ! 88: * We really don't need NBPFILTER bpf_if entries, but this eliminates ! 89: * the need to account for all possible drivers here. ! 90: * This problem will go away when these structures are allocated dynamically. ! 91: */ ! 92: static struct bpf_if *bpf_iflist; ! 93: static struct bpf_d bpf_dtab[NBPFILTER]; ! 94: ! 95: static void bpf_ifname(); ! 96: static void catchpacket(); ! 97: static int bpf_setif(); ! 98: static int bpf_initd(); ! 99: ! 100: static int ! 101: bpf_movein(uio, linktype, mp, sockp) ! 102: register struct uio *uio; ! 103: int linktype; ! 104: register struct mbuf **mp; ! 105: register struct sockaddr *sockp; ! 106: { ! 107: struct mbuf *m; ! 108: int error; ! 109: int len; ! 110: int hlen; ! 111: ! 112: /* ! 113: * Build a sockaddr based on the data link layer type. ! 114: * We do this at this level because the ethernet header ! 115: * is copied directly into the data field of the sockaddr. ! 116: * In the case of SLIP, there is no header and the packet ! 117: * is forwarded as is. ! 118: * Also, we are careful to leave room at the front of the mbuf ! 119: * for the link level header. ! 120: */ ! 121: switch (linktype) { ! 122: case DLT_SLIP: ! 123: sockp->sa_family = AF_INET; ! 124: hlen = 0; ! 125: break; ! 126: ! 127: case DLT_EN10MB: ! 128: sockp->sa_family = AF_UNSPEC; ! 129: /* XXX Would MAXLINKHDR be better? */ ! 130: hlen = sizeof(struct ether_header); ! 131: break; ! 132: ! 133: case DLT_FDDI: ! 134: sockp->sa_family = AF_UNSPEC; ! 135: /* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */ ! 136: hlen = 24; ! 137: break; ! 138: ! 139: default: ! 140: return (EIO); ! 141: } ! 142: ! 143: len = uio->uio_resid; ! 144: if ((unsigned)len > MCLBYTES) ! 145: return (EIO); ! 146: ! 147: MGET(m, M_WAIT, MT_DATA); ! 148: if (m == 0) ! 149: return (ENOBUFS); ! 150: if (len > MLEN) { ! 151: MCLGET(m, M_WAIT); ! 152: if ((m->m_flags & M_EXT) == 0) { ! 153: error = ENOBUFS; ! 154: goto bad; ! 155: } ! 156: } ! 157: m->m_len = len; ! 158: *mp = m; ! 159: /* ! 160: * Make room for link header. ! 161: */ ! 162: if (hlen) { ! 163: m->m_len -= hlen; ! 164: m->m_data += hlen; /* XXX */ ! 165: ! 166: error = uiomove((caddr_t)sockp->sa_data, hlen, uio); ! 167: if (error) ! 168: goto bad; ! 169: } ! 170: error = uiomove(mtod(m, caddr_t), len - hlen, uio); ! 171: if (!error) ! 172: return (0); ! 173: bad: ! 174: m_freem(m); ! 175: return (error); ! 176: } ! 177: ! 178: /* ! 179: * Attach 'd' to the bpf interface 'bp', i.e. make 'd' listen on 'bp'. ! 180: * Must be called at splimp. ! 181: */ ! 182: static void ! 183: bpf_attachd(d, bp) ! 184: struct bpf_d *d; ! 185: struct bpf_if *bp; ! 186: { ! 187: /* Point d at bp. */ ! 188: d->bd_bif = bp; ! 189: ! 190: /* Add d to bp's list of listeners. */ ! 191: d->bd_next = bp->bif_dlist; ! 192: bp->bif_dlist = d; ! 193: ! 194: /* ! 195: * Let the driver know we're here (if it doesn't already). ! 196: */ ! 197: *bp->bif_driverp = bp; ! 198: } ! 199: ! 200: static void ! 201: bpf_detachd(d) ! 202: struct bpf_d *d; ! 203: { ! 204: struct bpf_d **p; ! 205: struct bpf_if *bp; ! 206: ! 207: bp = d->bd_bif; ! 208: /* ! 209: * Check if this descriptor had requested promiscuous mode. ! 210: * If so, turn it off. ! 211: */ ! 212: if (d->bd_promisc) { ! 213: d->bd_promisc = 0; ! 214: if (ifpromisc(bp->bif_ifp, 0)) ! 215: /* ! 216: * Something is really wrong if we were able to put ! 217: * the driver into promiscuous mode, but can't ! 218: * take it out. ! 219: */ ! 220: panic("bpf_detachd: ifpromisc failed"); ! 221: } ! 222: /* Remove 'd' from the interface's descriptor list. */ ! 223: p = &bp->bif_dlist; ! 224: while (*p != d) { ! 225: p = &(*p)->bd_next; ! 226: if (*p == 0) ! 227: panic("bpf_detachd: descriptor not in list"); ! 228: } ! 229: *p = (*p)->bd_next; ! 230: if (bp->bif_dlist == 0) ! 231: /* ! 232: * Let the driver know that there are no more listeners. ! 233: */ ! 234: *d->bd_bif->bif_driverp = 0; ! 235: d->bd_bif = 0; ! 236: } ! 237: ! 238: ! 239: /* ! 240: * Mark a descriptor free by making it point to itself. ! 241: * This is probably cheaper than marking with a constant since ! 242: * the address should be in a register anyway. ! 243: */ ! 244: #define D_ISFREE(d) ((d) == (d)->bd_next) ! 245: #define D_MARKFREE(d) ((d)->bd_next = (d)) ! 246: #define D_MARKUSED(d) ((d)->bd_next = 0) ! 247: ! 248: /* ! 249: * bpfopen - open ethernet device ! 250: * ! 251: * Errors: ENXIO - illegal minor device number ! 252: * EBUSY - too many files open ! 253: */ ! 254: /* ARGSUSED */ ! 255: int ! 256: bpfopen(dev, flag) ! 257: dev_t dev; ! 258: int flag; ! 259: { ! 260: int error, s; ! 261: register struct bpf_d *d; ! 262: ! 263: if (minor(dev) >= NBPFILTER) ! 264: return (ENXIO); ! 265: ! 266: /* ! 267: * Each minor can be opened by only one process. If the requested ! 268: * minor is in use, return EBUSY. ! 269: */ ! 270: s = splimp(); ! 271: d = &bpf_dtab[minor(dev)]; ! 272: if (!D_ISFREE(d)) { ! 273: splx(s); ! 274: return (EBUSY); ! 275: } else ! 276: /* Mark "free" and do most initialization. */ ! 277: bzero((char *)d, sizeof(*d)); ! 278: splx(s); ! 279: ! 280: error = bpf_initd(d); ! 281: if (error) { ! 282: D_MARKFREE(d); ! 283: return (error); ! 284: } ! 285: return (0); ! 286: } ! 287: ! 288: /* ! 289: * Close the descriptor by detaching it from its interface, ! 290: * deallocating its buffers, and marking it free. ! 291: */ ! 292: /* ARGSUSED */ ! 293: bpfclose(dev, flag) ! 294: dev_t dev; ! 295: int flag; ! 296: { ! 297: register struct bpf_d *d = &bpf_dtab[minor(dev)]; ! 298: int s; ! 299: ! 300: s = splimp(); ! 301: if (d->bd_bif) ! 302: bpf_detachd(d); ! 303: splx(s); ! 304: ! 305: /* Free the buffer space. */ ! 306: if (d->bd_hbuf) ! 307: free(d->bd_hbuf, M_DEVBUF); ! 308: if (d->bd_fbuf) ! 309: free(d->bd_fbuf, M_DEVBUF); ! 310: free(d->bd_sbuf, M_DEVBUF); ! 311: if (d->bd_filter) ! 312: free((caddr_t)d->bd_filter, M_DEVBUF); ! 313: ! 314: D_MARKFREE(d); ! 315: } ! 316: ! 317: /* ! 318: * Rotate the packet buffers in descriptor d. Move the store buffer ! 319: * into the hold slot, and the free buffer into the store slot. ! 320: * Zero the length of the new store buffer. ! 321: */ ! 322: #define ROTATE_BUFFERS(d) \ ! 323: (d)->bd_hbuf = (d)->bd_sbuf; \ ! 324: (d)->bd_hlen = (d)->bd_slen; \ ! 325: (d)->bd_sbuf = (d)->bd_fbuf; \ ! 326: (d)->bd_slen = 0; \ ! 327: (d)->bd_fbuf = 0; ! 328: /* ! 329: * bpfread - read next chunk of packets from buffers ! 330: */ ! 331: int ! 332: bpfread(dev, uio) ! 333: dev_t dev; ! 334: register struct uio *uio; ! 335: { ! 336: register struct bpf_d *d = &bpf_dtab[minor(dev)]; ! 337: int error; ! 338: int s; ! 339: ! 340: /* ! 341: * Restrict application to use a buffer the same size as ! 342: * as kernel buffers. ! 343: */ ! 344: if (uio->uio_resid != d->bd_bufsize) ! 345: return (EINVAL); ! 346: ! 347: s = splimp(); ! 348: /* ! 349: * If the hold buffer is empty, then set a timer and sleep ! 350: * until either the timeout has occurred or enough packets have ! 351: * arrived to fill the store buffer. ! 352: */ ! 353: while (d->bd_hbuf == 0) { ! 354: if (d->bd_immediate && d->bd_slen != 0) { ! 355: /* ! 356: * A packet(s) either arrived since the previous ! 357: * read or arrived while we were asleep. ! 358: * Rotate the buffers and return what's here. ! 359: */ ! 360: ROTATE_BUFFERS(d); ! 361: break; ! 362: } ! 363: error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf", d->bd_rtout); ! 364: if (error == EINTR || error == ERESTART) { ! 365: splx(s); ! 366: return (error); ! 367: } ! 368: if (error == EWOULDBLOCK) { ! 369: /* ! 370: * On a timeout, return what's in the buffer, ! 371: * which may be nothing. If there is something ! 372: * in the store buffer, we can rotate the buffers. ! 373: */ ! 374: if (d->bd_hbuf) ! 375: /* ! 376: * We filled up the buffer in between ! 377: * getting the timeout and arriving ! 378: * here, so we don't need to rotate. ! 379: */ ! 380: break; ! 381: ! 382: if (d->bd_slen == 0) { ! 383: splx(s); ! 384: return (0); ! 385: } ! 386: ROTATE_BUFFERS(d); ! 387: break; ! 388: } ! 389: } ! 390: /* ! 391: * At this point, we know we have something in the hold slot. ! 392: */ ! 393: splx(s); ! 394: ! 395: /* ! 396: * Move data from hold buffer into user space. ! 397: * We know the entire buffer is transferred since ! 398: * we checked above that the read buffer is bpf_bufsize bytes. ! 399: */ ! 400: error = uiomove(d->bd_hbuf, d->bd_hlen, uio); ! 401: ! 402: s = splimp(); ! 403: d->bd_fbuf = d->bd_hbuf; ! 404: d->bd_hbuf = 0; ! 405: splx(s); ! 406: ! 407: return (error); ! 408: } ! 409: ! 410: ! 411: /* ! 412: * If there are processes sleeping on this descriptor, wake them up. ! 413: */ ! 414: static inline void ! 415: bpf_wakeup(d) ! 416: register struct bpf_d *d; ! 417: { ! 418: wakeup((caddr_t)d); ! 419: if (d->bd_selproc) { ! 420: selwakeup(d->bd_selproc, (int)d->bd_selcoll); ! 421: d->bd_selcoll = 0; ! 422: d->bd_selproc = 0; ! 423: } ! 424: } ! 425: ! 426: int ! 427: bpfwrite(dev, uio) ! 428: dev_t dev; ! 429: struct uio *uio; ! 430: { ! 431: register struct bpf_d *d = &bpf_dtab[minor(dev)]; ! 432: struct ifnet *ifp; ! 433: struct mbuf *m; ! 434: int error, s; ! 435: static struct sockaddr dst; ! 436: ! 437: if (d->bd_bif == 0) ! 438: return (ENXIO); ! 439: ! 440: ifp = d->bd_bif->bif_ifp; ! 441: ! 442: if (uio->uio_resid == 0) ! 443: return (0); ! 444: if (uio->uio_resid > ifp->if_mtu) ! 445: return (EMSGSIZE); ! 446: ! 447: error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst); ! 448: if (error) ! 449: return (error); ! 450: ! 451: s = splnet(); ! 452: error = (*ifp->if_output)(ifp, m, &dst); ! 453: splx(s); ! 454: /* ! 455: * The driver frees the mbuf. ! 456: */ ! 457: return (error); ! 458: } ! 459: ! 460: /* ! 461: * Reset a descriptor by flushing its packet bufferand clearing the receive ! 462: * and drop counts. Should be called at splimp. ! 463: */ ! 464: static void ! 465: reset_d(d) ! 466: struct bpf_d *d; ! 467: { ! 468: if (d->bd_hbuf) { ! 469: /* Free the hold buffer. */ ! 470: d->bd_fbuf = d->bd_hbuf; ! 471: d->bd_hbuf = 0; ! 472: } ! 473: d->bd_slen = 0; ! 474: d->bd_rcount = 0; ! 475: d->bd_dcount = 0; ! 476: } ! 477: ! 478: /* ! 479: * FIONREAD Check for read packet available. ! 480: * SIOCGIFADDR Get interface address - convenient hook to driver. ! 481: * BIOCGFLEN Get max filter len. ! 482: * BIOCGBLEN Get buffer len [for read()]. ! 483: * BIOCSETF Set ethernet read filter. ! 484: * BIOCFLUSH Flush read packet buffer. ! 485: * BIOCPROMISC Put interface into promiscuous mode. ! 486: * BIOCGDLT Get link layer type. ! 487: * BIOCGETIF Get interface name. ! 488: * BIOCSETIF Set interface. ! 489: * BIOCSRTIMEOUT Set read timeout. ! 490: * BIOCGRTIMEOUT Get read timeout. ! 491: * BIOCGSTATS Get packet stats. ! 492: * BIOCIMMEDIATE Set immediate mode. ! 493: */ ! 494: /* ARGSUSED */ ! 495: int ! 496: bpfioctl(dev, cmd, addr, flag) ! 497: dev_t dev; ! 498: int cmd; ! 499: caddr_t addr; ! 500: int flag; ! 501: { ! 502: register struct bpf_d *d = &bpf_dtab[minor(dev)]; ! 503: int s, error = 0; ! 504: ! 505: switch (cmd) { ! 506: ! 507: default: ! 508: error = EINVAL; ! 509: break; ! 510: ! 511: /* ! 512: * Check for read packet available. ! 513: */ ! 514: case FIONREAD: ! 515: { ! 516: int n; ! 517: ! 518: s = splimp(); ! 519: n = d->bd_slen; ! 520: if (d->bd_hbuf) ! 521: n += d->bd_hlen; ! 522: splx(s); ! 523: ! 524: *(int *)addr = n; ! 525: break; ! 526: } ! 527: ! 528: case SIOCGIFADDR: ! 529: { ! 530: struct ifnet *ifp; ! 531: ! 532: if (d->bd_bif == 0) ! 533: error = EINVAL; ! 534: else { ! 535: ifp = d->bd_bif->bif_ifp; ! 536: error = (*ifp->if_ioctl)(ifp, cmd, addr); ! 537: } ! 538: break; ! 539: } ! 540: ! 541: /* ! 542: * Get max filter len. ! 543: */ ! 544: case BIOCGFLEN: ! 545: *(u_int *)addr = BPF_MAXINSNS; ! 546: break; ! 547: /* ! 548: * Get buffer len [for read()]. ! 549: */ ! 550: case BIOCGBLEN: ! 551: *(u_int *)addr = d->bd_bufsize; ! 552: break; ! 553: ! 554: /* ! 555: * Set ethernet read filter. ! 556: */ ! 557: case BIOCSETF: ! 558: error = bpf_setf(d, (struct bpf_program *)addr); ! 559: break; ! 560: ! 561: /* ! 562: * Flush read packet buffer. ! 563: */ ! 564: case BIOCFLUSH: ! 565: s = splimp(); ! 566: reset_d(d); ! 567: splx(s); ! 568: break; ! 569: ! 570: /* ! 571: * Put interface into promiscuous mode. ! 572: */ ! 573: case BIOCPROMISC: ! 574: if (d->bd_bif == 0) { ! 575: /* ! 576: * No interface attached yet. ! 577: */ ! 578: error = EINVAL; ! 579: break; ! 580: } ! 581: s = splimp(); ! 582: if (d->bd_promisc == 0) { ! 583: d->bd_promisc = 1; ! 584: error = ifpromisc(d->bd_bif->bif_ifp, 1); ! 585: } ! 586: splx(s); ! 587: break; ! 588: ! 589: /* ! 590: * Get device parameters. ! 591: */ ! 592: case BIOCGDLT: ! 593: if (d->bd_bif == 0) ! 594: error = EINVAL; ! 595: else ! 596: *(u_int *)addr = d->bd_bif->bif_dlt; ! 597: break; ! 598: ! 599: /* ! 600: * Set interface name. ! 601: */ ! 602: case BIOCGETIF: ! 603: if (d->bd_bif == 0) ! 604: error = EINVAL; ! 605: else ! 606: bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr); ! 607: break; ! 608: ! 609: /* ! 610: * Set interface. ! 611: */ ! 612: case BIOCSETIF: ! 613: error = bpf_setif(d, (struct ifreq *)addr); ! 614: break; ! 615: ! 616: /* ! 617: * Set read timeout. ! 618: */ ! 619: case BIOCSRTIMEOUT: ! 620: { ! 621: struct timeval *tv = (struct timeval *)addr; ! 622: u_long msec; ! 623: ! 624: /* Compute number of milliseconds. */ ! 625: msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; ! 626: /* Scale milliseconds to ticks. Assume hard ! 627: clock has millisecond or greater resolution ! 628: (i.e. tick >= 1000). For 10ms hardclock, ! 629: tick/1000 = 10, so rtout<-msec/10. */ ! 630: d->bd_rtout = msec / (tick / 1000); ! 631: break; ! 632: } ! 633: ! 634: /* ! 635: * Get read timeout. ! 636: */ ! 637: case BIOCGRTIMEOUT: ! 638: { ! 639: struct timeval *tv = (struct timeval *)addr; ! 640: u_long msec = d->bd_rtout; ! 641: ! 642: msec *= tick / 1000; ! 643: tv->tv_sec = msec / 1000; ! 644: tv->tv_usec = msec % 1000; ! 645: break; ! 646: } ! 647: ! 648: /* ! 649: * Get packet stats. ! 650: */ ! 651: case BIOCGSTATS: ! 652: { ! 653: struct bpf_stat *bs = (struct bpf_stat *)addr; ! 654: ! 655: bs->bs_recv = d->bd_rcount; ! 656: bs->bs_drop = d->bd_dcount; ! 657: break; ! 658: } ! 659: ! 660: /* ! 661: * Set immediate mode. ! 662: */ ! 663: case BIOCIMMEDIATE: ! 664: d->bd_immediate = *(u_int *)addr; ! 665: break; ! 666: } ! 667: return (error); ! 668: } ! 669: ! 670: /* ! 671: * Set d's packet filter program to 'fp'. If 'd' already has a filter, ! 672: * free it and replace it. Returns EINVAL for bogus requests. ! 673: */ ! 674: int ! 675: bpf_setf(d, fp) ! 676: struct bpf_d *d; ! 677: struct bpf_program *fp; ! 678: { ! 679: struct bpf_insn *fcode, *old; ! 680: u_int flen, size; ! 681: int s; ! 682: ! 683: old = d->bd_filter; ! 684: if (fp->bf_insns == 0) { ! 685: if (fp->bf_len != 0) ! 686: return (EINVAL); ! 687: s = splimp(); ! 688: d->bd_filter = 0; ! 689: reset_d(d); ! 690: splx(s); ! 691: if (old != 0) ! 692: free((caddr_t)old, M_DEVBUF); ! 693: return (0); ! 694: } ! 695: flen = fp->bf_len; ! 696: if (flen > BPF_MAXINSNS) ! 697: return (EINVAL); ! 698: ! 699: size = flen * sizeof(*fp->bf_insns); ! 700: fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK); ! 701: if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size)) ! 702: return (EINVAL); ! 703: ! 704: if (bpf_validate(fcode, (int)flen)) { ! 705: s = splimp(); ! 706: d->bd_filter = fcode; ! 707: reset_d(d); ! 708: splx(s); ! 709: if (old != 0) ! 710: free((caddr_t)old, M_DEVBUF); ! 711: ! 712: return (0); ! 713: } ! 714: free((caddr_t)fcode, M_DEVBUF); ! 715: return (EINVAL); ! 716: } ! 717: ! 718: /* ! 719: * Detach 'd' from its current interface (if attached at all) and attach to ! 720: * the interface named 'name'. Return ioctl error code or 0. ! 721: */ ! 722: static int ! 723: bpf_setif(d, ifr) ! 724: struct bpf_d *d; ! 725: struct ifreq *ifr; ! 726: { ! 727: struct bpf_if *bp; ! 728: char *cp; ! 729: int unit, s; ! 730: ! 731: /* ! 732: * Separate string into name part and unit number. Put a null ! 733: * byte at the end of the name part, and compute the number. ! 734: * If the a unit number is unspecified, the default is 0, ! 735: * as initialized above. XXX This should be common code. ! 736: */ ! 737: unit = 0; ! 738: cp = ifr->ifr_name; ! 739: cp[sizeof(ifr->ifr_name) - 1] = '\0'; ! 740: while (*cp++) { ! 741: if (*cp >= '0' && *cp <= '9') { ! 742: unit = *cp - '0'; ! 743: *cp++ = '\0'; ! 744: while (*cp) ! 745: unit = 10 * unit + *cp++ - '0'; ! 746: break; ! 747: } ! 748: } ! 749: /* ! 750: * Look through attached interfaces for the named one. ! 751: */ ! 752: for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { ! 753: struct ifnet *ifp = bp->bif_ifp; ! 754: ! 755: if (ifp == 0 || unit != ifp->if_unit ! 756: || strcmp(ifp->if_name, ifr->ifr_name) != 0) ! 757: continue; ! 758: /* ! 759: * We found the requested interface. If we're ! 760: * already attached to it, just flush the buffer. ! 761: * If it's not up, return an error. ! 762: */ ! 763: if ((ifp->if_flags & IFF_UP) == 0) ! 764: return (ENETDOWN); ! 765: s = splimp(); ! 766: if (bp != d->bd_bif) { ! 767: if (d->bd_bif) ! 768: /* ! 769: * Detach if attached to something else. ! 770: */ ! 771: bpf_detachd(d); ! 772: ! 773: bpf_attachd(d, bp); ! 774: } ! 775: reset_d(d); ! 776: splx(s); ! 777: return (0); ! 778: } ! 779: /* Not found. */ ! 780: return (ENXIO); ! 781: } ! 782: ! 783: /* ! 784: * Lookup the name of the 'ifp' interface and return it in 'ifr->ifr_name'. ! 785: * We augment the ifp's base name with its unit number. ! 786: */ ! 787: static void ! 788: bpf_ifname(ifp, ifr) ! 789: struct ifnet *ifp; ! 790: struct ifreq *ifr; ! 791: { ! 792: char *s = ifp->if_name; ! 793: char *d = ifr->ifr_name; ! 794: ! 795: while (*d++ = *s++) ! 796: ; ! 797: /* XXX Assume that unit number is less than 10. */ ! 798: *d++ = ifp->if_unit + '0'; ! 799: *d = '\0'; ! 800: } ! 801: ! 802: /* ! 803: * Support for select() system call ! 804: * Inspired by the code in tty.c for the same purpose. ! 805: * ! 806: * bpfselect - returns true iff the specific operation ! 807: * will not block indefinitely. Otherwise, return ! 808: * false but make a note that a selwakeup() must be done. ! 809: */ ! 810: int ! 811: bpfselect(dev, rw, p) ! 812: register dev_t dev; ! 813: int rw; ! 814: struct proc *p; ! 815: { ! 816: register struct bpf_d *d; ! 817: register int s; ! 818: ! 819: if (rw != FREAD) ! 820: return (0); ! 821: /* ! 822: * An imitation of the FIONREAD ioctl code. ! 823: */ ! 824: d = &bpf_dtab[minor(dev)]; ! 825: ! 826: s = splimp(); ! 827: if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) { ! 828: /* ! 829: * There is data waiting. ! 830: */ ! 831: splx(s); ! 832: return (1); ! 833: } ! 834: /* ! 835: * No data ready. If there's already a select() waiting on this ! 836: * minor device then this is a collision. This shouldn't happen ! 837: * because minors really should not be shared, but if a process ! 838: * forks while one of these is open, it is possible that both ! 839: * processes could select on the same descriptor. ! 840: */ ! 841: if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait) ! 842: d->bd_selcoll = 1; ! 843: else ! 844: d->bd_selproc = p; ! 845: ! 846: splx(s); ! 847: return (0); ! 848: } ! 849: ! 850: /* ! 851: * bpf_tap - incoming linkage from device drivers ! 852: */ ! 853: void ! 854: bpf_tap(arg, pkt, pktlen) ! 855: caddr_t arg; ! 856: register u_char *pkt; ! 857: register u_int pktlen; ! 858: { ! 859: struct bpf_if *bp; ! 860: register struct bpf_d *d; ! 861: register u_int slen; ! 862: /* ! 863: * Note that the ipl does not have to be raised at this point. ! 864: * The only problem that could arise here is that if two different ! 865: * interfaces shared any data. This is not the case. ! 866: */ ! 867: bp = (struct bpf_if *)arg; ! 868: for (d = bp->bif_dlist; d != 0; d = d->bd_next) { ! 869: ++d->bd_rcount; ! 870: slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); ! 871: if (slen != 0) ! 872: catchpacket(d, pkt, pktlen, slen, bcopy); ! 873: } ! 874: } ! 875: ! 876: /* ! 877: * Copy data from an mbuf chain into a buffer. This code is derived ! 878: * from m_copydata in sys/uipc_mbuf.c. ! 879: */ ! 880: static void ! 881: bpf_mcopy(src, dst, len) ! 882: u_char *src; ! 883: u_char *dst; ! 884: register int len; ! 885: { ! 886: register struct mbuf *m = (struct mbuf *)src; ! 887: register unsigned count; ! 888: ! 889: while (len > 0) { ! 890: if (m == 0) ! 891: panic("bpf_mcopy"); ! 892: count = MIN(m->m_len, len); ! 893: bcopy(mtod(m, caddr_t), (caddr_t)dst, count); ! 894: m = m->m_next; ! 895: dst += count; ! 896: len -= count; ! 897: } ! 898: } ! 899: ! 900: /* ! 901: * bpf_mtap - incoming linkage from device drivers, when packet ! 902: * is in an mbuf chain ! 903: */ ! 904: void ! 905: bpf_mtap(arg, m) ! 906: caddr_t arg; ! 907: struct mbuf *m; ! 908: { ! 909: struct bpf_if *bp = (struct bpf_if *)arg; ! 910: struct bpf_d *d; ! 911: u_int pktlen, slen; ! 912: struct mbuf *m0; ! 913: ! 914: pktlen = 0; ! 915: for (m0 = m; m0 != m; m0 = m0->m_next) ! 916: pktlen += m0->m_len; ! 917: ! 918: for (d = bp->bif_dlist; d != 0; d = d->bd_next) { ! 919: ++d->bd_rcount; ! 920: slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); ! 921: if (slen != 0) ! 922: catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); ! 923: } ! 924: } ! 925: ! 926: /* ! 927: * Move the packet data from interface memory (pkt) into the ! 928: * store buffer. Return 1 if it's time to wakeup a listener (buffer full), ! 929: * otherwise 0. 'copy' is the routine called to do the actual data ! 930: * transfer. 'bcopy' is passed in to copy contiguous chunks, while ! 931: * 'bpf_mcopy' is passed in to copy mbuf chains. In the latter ! 932: * case, 'pkt' is really an mbuf. ! 933: */ ! 934: static void ! 935: catchpacket(d, pkt, pktlen, snaplen, cpfn) ! 936: register struct bpf_d *d; ! 937: register u_char *pkt; ! 938: register u_int pktlen, snaplen; ! 939: register void (*cpfn)(); ! 940: { ! 941: register struct bpf_hdr *hp; ! 942: register int totlen, curlen; ! 943: register int hdrlen = d->bd_bif->bif_hdrlen; ! 944: /* ! 945: * Figure out how many bytes to move. If the packet is ! 946: * greater or equal to the snapshot length, transfer that ! 947: * much. Otherwise, transfer the whole packet (unless ! 948: * we hit the buffer size limit). ! 949: */ ! 950: totlen = hdrlen + MIN(snaplen, pktlen); ! 951: if (totlen > d->bd_bufsize) ! 952: totlen = d->bd_bufsize; ! 953: ! 954: /* ! 955: * Round up the end of the previous packet to the next longword. ! 956: */ ! 957: curlen = BPF_WORDALIGN(d->bd_slen); ! 958: if (curlen + totlen > d->bd_bufsize) { ! 959: /* ! 960: * This packet will overflow the storage buffer. ! 961: * Rotate the buffers if we can, then wakeup any ! 962: * pending reads. ! 963: */ ! 964: if (d->bd_fbuf == 0) { ! 965: /* ! 966: * We haven't completed the previous read yet, ! 967: * so drop the packet. ! 968: */ ! 969: ++d->bd_dcount; ! 970: return; ! 971: } ! 972: ROTATE_BUFFERS(d); ! 973: bpf_wakeup(d); ! 974: curlen = 0; ! 975: } ! 976: else if (d->bd_immediate) ! 977: /* ! 978: * Immediate mode is set. A packet arrived so any ! 979: * reads should be woken up. ! 980: */ ! 981: bpf_wakeup(d); ! 982: ! 983: /* ! 984: * Append the bpf header. ! 985: */ ! 986: hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); ! 987: #ifdef sun ! 988: uniqtime(&hp->bh_tstamp); ! 989: #else ! 990: #ifdef hp300 ! 991: microtime(&hp->bh_tstamp); ! 992: #else ! 993: hp->bh_tstamp = time; ! 994: #endif ! 995: #endif ! 996: hp->bh_datalen = pktlen; ! 997: hp->bh_hdrlen = hdrlen; ! 998: /* ! 999: * Copy the packet data into the store buffer and update its length. ! 1000: */ ! 1001: (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); ! 1002: d->bd_slen = curlen + totlen; ! 1003: } ! 1004: ! 1005: /* ! 1006: * Initialize all nonzero fields of a descriptor. ! 1007: */ ! 1008: static int ! 1009: bpf_initd(d) ! 1010: register struct bpf_d *d; ! 1011: { ! 1012: d->bd_bufsize = bpf_bufsize; ! 1013: d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); ! 1014: if (d->bd_fbuf == 0) ! 1015: return (ENOBUFS); ! 1016: ! 1017: d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); ! 1018: if (d->bd_sbuf == 0) { ! 1019: free(d->bd_fbuf, M_DEVBUF); ! 1020: return (ENOBUFS); ! 1021: } ! 1022: d->bd_slen = 0; ! 1023: d->bd_hlen = 0; ! 1024: return (0); ! 1025: } ! 1026: ! 1027: /* ! 1028: * Register 'ifp' with bpf. XXX ! 1029: * and 'driverp' is a pointer to the 'struct bpf_if *' in the driver's softc. ! 1030: */ ! 1031: void ! 1032: bpfattach(driverp, ifp, dlt, hdrlen) ! 1033: caddr_t *driverp; ! 1034: struct ifnet *ifp; ! 1035: u_int dlt, hdrlen; ! 1036: { ! 1037: struct bpf_if *bp; ! 1038: int i; ! 1039: ! 1040: bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT); ! 1041: if (bp == 0) ! 1042: panic("bpfattach"); ! 1043: ! 1044: bp->bif_dlist = 0; ! 1045: bp->bif_driverp = (struct bpf_if **)driverp; ! 1046: bp->bif_ifp = ifp; ! 1047: bp->bif_dlt = dlt; ! 1048: ! 1049: bp->bif_next = bpf_iflist; ! 1050: bpf_iflist = bp; ! 1051: ! 1052: *bp->bif_driverp = 0; ! 1053: ! 1054: /* ! 1055: * Compute the length of the bpf header. This is not necessarily ! 1056: * equal to SIZEOF_BPF_HDR because we want to insert spacing such ! 1057: * that the network layer header begins on a longword boundary (for ! 1058: * performance reasons and to alleviate alignment restrictions). ! 1059: */ ! 1060: bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; ! 1061: ! 1062: /* ! 1063: * Mark all the descriptors free if this hasn't been done. ! 1064: */ ! 1065: if (!D_ISFREE(&bpf_dtab[0])) ! 1066: for (i = 0; i < NBPFILTER; ++i) ! 1067: D_MARKFREE(&bpf_dtab[i]); ! 1068: ! 1069: printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); ! 1070: } ! 1071: ! 1072: /* XXX This routine belongs in net/if.c. */ ! 1073: /* ! 1074: * Set/clear promiscuous mode on interface ifp based on the truth value` ! 1075: * of pswitch. The calls are reference counted so that only the first ! 1076: * on request actually has an effect, as does the final off request. ! 1077: * Results are undefined if the off and on requests are not matched. ! 1078: */ ! 1079: int ! 1080: ifpromisc(ifp, pswitch) ! 1081: struct ifnet *ifp; ! 1082: int pswitch; ! 1083: { ! 1084: struct ifreq ifr; ! 1085: /* ! 1086: * If the device is not configured up, we cannot put it in ! 1087: * promiscuous mode. ! 1088: */ ! 1089: if ((ifp->if_flags & IFF_UP) == 0) ! 1090: return (ENETDOWN); ! 1091: ! 1092: if (pswitch) { ! 1093: if (ifp->if_pcount++ != 0) ! 1094: return (0); ! 1095: ifp->if_flags |= IFF_PROMISC; ! 1096: } else { ! 1097: if (--ifp->if_pcount > 0) ! 1098: return (0); ! 1099: ifp->if_flags &= ~IFF_PROMISC; ! 1100: } ! 1101: ifr.ifr_flags = ifp->if_flags; ! 1102: return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); ! 1103: } ! 1104: ! 1105: #endif (NBPFILTER > 0)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.