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

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