Annotation of Net2/net/bpf.c, revision 1.1.1.1

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)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.