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

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

unix.superglobalmegacorp.com

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