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