pcap-pf.c revision 190225
183828Sdfr/* 283828Sdfr * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 3164010Smarcel * The Regents of the University of California. All rights reserved. 483828Sdfr * 583828Sdfr * Redistribution and use in source and binary forms, with or without 683828Sdfr * modification, are permitted provided that: (1) source code distributions 783828Sdfr * retain the above copyright notice and this paragraph in its entirety, (2) 883828Sdfr * distributions including binary code include the above copyright notice and 983828Sdfr * this paragraph in its entirety in the documentation or other materials 1083828Sdfr * provided with the distribution, and (3) all advertising materials mentioning 1183828Sdfr * features or use of this software display the following acknowledgement: 1283828Sdfr * ``This product includes software developed by the University of California, 1383828Sdfr * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1483828Sdfr * the University nor the names of its contributors may be used to endorse 1583828Sdfr * or promote products derived from this software without specific prior 1683828Sdfr * written permission. 1783828Sdfr * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1883828Sdfr * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1983828Sdfr * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2083828Sdfr * 2183828Sdfr * packet filter subroutines for tcpdump 2283828Sdfr * Extraction/creation by Jeffrey Mogul, DECWRL 2383828Sdfr */ 2483828Sdfr 2583828Sdfr#ifndef lint 2683828Sdfrstatic const char rcsid[] _U_ = 2783828Sdfr "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.94.2.3 2008-04-14 20:41:52 guy Exp $ (LBL)"; 28124140Sobrien#endif 29124140Sobrien 30124140Sobrien#ifdef HAVE_CONFIG_H 3183828Sdfr#include "config.h" 3283828Sdfr#endif 3383828Sdfr 3483828Sdfr#include <sys/types.h> 3583828Sdfr#include <sys/time.h> 3683828Sdfr#include <sys/timeb.h> 3783828Sdfr#include <sys/socket.h> 3883828Sdfr#include <sys/file.h> 39164010Smarcel#include <sys/ioctl.h> 40164010Smarcel#include <net/pfilt.h> 4183828Sdfr 4283828Sdfrstruct mbuf; 4383828Sdfrstruct rtentry; 44164010Smarcel#include <net/if.h> 4583828Sdfr 46164010Smarcel#include <netinet/in.h> 47164010Smarcel#include <netinet/in_systm.h> 48164010Smarcel#include <netinet/ip.h> 49164010Smarcel#include <netinet/if_ether.h> 50164010Smarcel#include <netinet/ip_var.h> 51164010Smarcel#include <netinet/udp.h> 52164010Smarcel#include <netinet/udp_var.h> 53292625Semaste#include <netinet/tcp.h> 54164010Smarcel#include <netinet/tcpip.h> 55164010Smarcel 56164010Smarcel#include <ctype.h> 57164010Smarcel#include <errno.h> 58164010Smarcel#include <netdb.h> 59164010Smarcel#include <stdio.h> 60164010Smarcel#include <stdlib.h> 61164010Smarcel#include <string.h> 62164010Smarcel#include <unistd.h> 63164010Smarcel 64164010Smarcel/* 6593409Smarcel * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the 6693409Smarcel * native OS version, as we need various BPF ioctls from it. 6793409Smarcel */ 6893409Smarcel#define PCAP_DONT_INCLUDE_PCAP_BPF_H 6993409Smarcel#include <net/bpf.h> 7093409Smarcel 7193409Smarcel#include "pcap-int.h" 7293409Smarcel 7393409Smarcel#ifdef HAVE_OS_PROTO_H 7493409Smarcel#include "os-proto.h" 7593409Smarcel#endif 7693409Smarcel 7793409Smarcelstatic int pcap_setfilter_pf(pcap_t *, struct bpf_program *); 7893409Smarcel 7993409Smarcel/* 8093409Smarcel * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump 8193409Smarcel * applications aren't going to need more than 200 bytes of packet header 8293409Smarcel * and the read shouldn't return more packets than packetfilter's internal 8393409Smarcel * queue limit (bounded at 256). 8493409Smarcel */ 8593409Smarcel#define BUFSPACE (200 * 256) 8693409Smarcel 8793409Smarcelstatic int 8893409Smarcelpcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) 8993409Smarcel{ 9093409Smarcel register u_char *p, *bp; 9193409Smarcel register int cc, n, buflen, inc; 9293409Smarcel register struct enstamp *sp; 9393409Smarcel#ifdef LBL_ALIGN 9493409Smarcel struct enstamp stamp; 9593409Smarcel#endif 9693409Smarcel#ifdef PCAP_FDDIPAD 9793409Smarcel register int pad; 9893409Smarcel#endif 99164010Smarcel 10083828Sdfr again: 10183828Sdfr cc = pc->cc; 102277943Sambrisko if (cc == 0) { 10383828Sdfr cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); 104300810Sjhb if (cc < 0) { 105277943Sambrisko if (errno == EWOULDBLOCK) 106277943Sambrisko return (0); 10783828Sdfr if (errno == EINVAL && 10883828Sdfr lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { 109164010Smarcel /* 11083828Sdfr * Due to a kernel bug, after 2^31 bytes, 11183828Sdfr * the kernel file offset overflows and 11283828Sdfr * read fails with EINVAL. The lseek() 11383828Sdfr * to 0 will fix things. 11483828Sdfr */ 11583828Sdfr (void)lseek(pc->fd, 0L, SEEK_SET); 116164010Smarcel goto again; 11783828Sdfr } 11883828Sdfr snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", 11993403Smarcel pcap_strerror(errno)); 12093403Smarcel return (-1); 12183828Sdfr } 12293403Smarcel bp = pc->buffer + pc->offset; 12383828Sdfr } else 12493403Smarcel bp = pc->bp; 125300791Sjhb /* 126300791Sjhb * Loop through each packet. 12793403Smarcel */ 12883828Sdfr n = 0; 12993403Smarcel#ifdef PCAP_FDDIPAD 130164010Smarcel pad = pc->fddipad; 13193403Smarcel#endif 13293403Smarcel while (cc > 0) { 13393403Smarcel /* 134100389Speter * Has "pcap_breakloop()" been called? 13593403Smarcel * If so, return immediately - if we haven't read any 136100389Speter * packets, clear the flag and return -2 to indicate 137292625Semaste * that we were told to break out of the loop, otherwise 138100389Speter * leave the flag set, so that the *next* call will break 139100389Speter * out of the loop without having read any packets, and 140100389Speter * return the number of packets we've processed so far. 14193403Smarcel */ 14293403Smarcel if (pc->break_loop) { 143164010Smarcel if (n == 0) { 14483828Sdfr pc->break_loop = 0; 14583828Sdfr return (-2); 146164010Smarcel } else { 14783828Sdfr pc->cc = cc; 14883828Sdfr pc->bp = bp; 14993403Smarcel return (n); 15093403Smarcel } 15183828Sdfr } 15283828Sdfr if (cc < sizeof(*sp)) { 15383828Sdfr snprintf(pc->errbuf, sizeof(pc->errbuf), 154100389Speter "pf short read (%d)", cc); 15583828Sdfr return (-1); 15693403Smarcel } 157300791Sjhb#ifdef LBL_ALIGN 158300791Sjhb if ((long)bp & 3) { 15993403Smarcel sp = &stamp; 16083828Sdfr memcpy((char *)sp, (char *)bp, sizeof(*sp)); 16183828Sdfr } else 162100389Speter#endif 163100389Speter sp = (struct enstamp *)bp; 164100389Speter if (sp->ens_stamplen != sizeof(*sp)) { 165100389Speter snprintf(pc->errbuf, sizeof(pc->errbuf), 166100389Speter "pf short stamplen (%d)", 167100389Speter sp->ens_stamplen); 168100389Speter return (-1); 169100389Speter } 170100389Speter 171100389Speter p = bp + sp->ens_stamplen; 172100389Speter buflen = sp->ens_count; 173100389Speter if (buflen > pc->snapshot) 174164010Smarcel buflen = pc->snapshot; 175100389Speter 17683828Sdfr /* Calculate inc before possible pad update */ 177164010Smarcel inc = ENALIGN(buflen + sp->ens_stamplen); 17883828Sdfr cc -= inc; 17983828Sdfr bp += inc; 180164010Smarcel pc->md.TotPkts++; 18183828Sdfr pc->md.TotDrops += sp->ens_dropped; 18283828Sdfr pc->md.TotMissed = sp->ens_ifoverflows; 183164010Smarcel if (pc->md.OrigMissed < 0) 18483828Sdfr pc->md.OrigMissed = pc->md.TotMissed; 18583828Sdfr 18693403Smarcel /* 18793403Smarcel * Short-circuit evaluation: if using BPF filter 188164010Smarcel * in kernel, no need to do it now - we already know 18993409Smarcel * the packet passed the filter. 19083828Sdfr * 191295144Sandrew#ifdef PCAP_FDDIPAD 192295144Sandrew * Note: the filter code was generated assuming 193295144Sandrew * that pc->fddipad was the amount of padding 194295144Sandrew * before the header, as that's what's required 195295144Sandrew * in the kernel, so we run the filter before 196164010Smarcel * skipping that padding. 197164010Smarcel#endif 198164010Smarcel */ 199300791Sjhb if (pc->md.use_bpf || 200295144Sandrew bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { 201164010Smarcel struct pcap_pkthdr h; 202164010Smarcel pc->md.TotAccepted++; 20383828Sdfr h.ts = sp->ens_tstamp; 204164010Smarcel#ifdef PCAP_FDDIPAD 20593409Smarcel h.len = sp->ens_count - pad; 20693409Smarcel#else 20793409Smarcel h.len = sp->ens_count; 208100390Speter#endif 209164010Smarcel#ifdef PCAP_FDDIPAD 21093409Smarcel p += pad; 21193409Smarcel buflen -= pad; 21293409Smarcel#endif 21383828Sdfr h.caplen = buflen; 21493409Smarcel (*callback)(user, &h, p); 21593409Smarcel if (++n >= cnt && cnt > 0) { 21693409Smarcel pc->cc = cc; 217100390Speter pc->bp = bp; 218164010Smarcel return (n); 21993409Smarcel } 22093409Smarcel } 22193409Smarcel } 22293409Smarcel pc->cc = 0; 22393409Smarcel return (n); 22493409Smarcel} 22593409Smarcel 22693409Smarcelstatic int 22793409Smarcelpcap_inject_pf(pcap_t *p, const void *buf, size_t size) 22893409Smarcel{ 229100390Speter int ret; 230164010Smarcel 23193409Smarcel ret = write(p->fd, buf, size); 23293409Smarcel if (ret == -1) { 23393409Smarcel snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 23493409Smarcel pcap_strerror(errno)); 23593409Smarcel return (-1); 23693409Smarcel } 23793409Smarcel return (ret); 23893409Smarcel} 23983828Sdfr 24083828Sdfrstatic int 241164010Smarcelpcap_stats_pf(pcap_t *p, struct pcap_stat *ps) 24283828Sdfr{ 243164010Smarcel 244164010Smarcel /* 245164010Smarcel * If packet filtering is being done in the kernel: 246292625Semaste * 247164010Smarcel * "ps_recv" counts only packets that passed the filter. 248300791Sjhb * This does not include packets dropped because we 249300791Sjhb * ran out of buffer space. (XXX - perhaps it should, 250300791Sjhb * by adding "ps_drop" to "ps_recv", for compatibility 251164010Smarcel * with some other platforms. On the other hand, on 25283828Sdfr * some platforms "ps_recv" counts only packets that 25383828Sdfr * passed the filter, and on others it counts packets 254164010Smarcel * that didn't pass the filter....) 255164010Smarcel * 256164010Smarcel * "ps_drop" counts packets that passed the kernel filter 257164010Smarcel * (if any) but were dropped because the input queue was 258164010Smarcel * full. 259164010Smarcel * 260164010Smarcel * "ps_ifdrop" counts packets dropped by the network 261164010Smarcel * inteface (regardless of whether they would have passed 262164010Smarcel * the input filter, of course). 263164010Smarcel * 264164010Smarcel * If packet filtering is not being done in the kernel: 265164010Smarcel * 266164010Smarcel * "ps_recv" counts only packets that passed the filter. 267164010Smarcel * 268164010Smarcel * "ps_drop" counts packets that were dropped because the 269164010Smarcel * input queue was full, regardless of whether they passed 270164010Smarcel * the userland filter. 27183828Sdfr * 272164010Smarcel * "ps_ifdrop" counts packets dropped by the network 273164010Smarcel * inteface (regardless of whether they would have passed 274300810Sjhb * the input filter, of course). 275300810Sjhb * 276300810Sjhb * These statistics don't include packets not yet read from 277164010Smarcel * the kernel by libpcap, but they may include packets not 278164010Smarcel * yet read from libpcap by the application. 279164010Smarcel */ 28083828Sdfr ps->ps_recv = p->md.TotAccepted; 28183828Sdfr ps->ps_drop = p->md.TotDrops; 282217067Smarcel ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed; 283164010Smarcel return (0); 284164010Smarcel} 285164010Smarcel 286164010Smarcel/* 287164010Smarcel * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably 288164010Smarcel * don't get DLT_DOCSIS defined. 289164010Smarcel */ 29083828Sdfr#ifndef DLT_DOCSIS 291164010Smarcel#define DLT_DOCSIS 143 292164010Smarcel#endif 293300810Sjhb 294300810Sjhbstatic int 295300810Sjhbpcap_activate_pf(pcap_t *p) 296300810Sjhb{ 297300810Sjhb short enmode; 298300810Sjhb int backlog = -1; /* request the most */ 299300810Sjhb struct enfilter Filter; 300300810Sjhb struct endevp devparams; 301300810Sjhb 302300810Sjhb /* 303300810Sjhb * Initially try a read/write open (to allow the inject 304300810Sjhb * method to work). If that fails due to permission 305300810Sjhb * issues, fall back to read-only. This allows a 306300810Sjhb * non-root user to be granted specific access to pcap 307300810Sjhb * capabilities via file permissions. 308300810Sjhb * 309300810Sjhb * XXX - we should have an API that has a flag that 310300810Sjhb * controls whether to open read-only or read-write, 311300810Sjhb * so that denial of permission to send (or inability 312300810Sjhb * to send, if sending packets isn't supported on 313300810Sjhb * the device in question) can be indicated at open 314300810Sjhb * time. 315300810Sjhb * 316300810Sjhb * XXX - we assume here that "pfopen()" does not, in fact, modify 317300810Sjhb * its argument, even though it takes a "char *" rather than a 318300810Sjhb * "const char *" as its first argument. That appears to be 319164010Smarcel * the case, at least on Digital UNIX 4.0. 320300810Sjhb */ 321300810Sjhb p->fd = pfopen(p->opt.source, O_RDWR); 322300810Sjhb if (p->fd == -1 && errno == EACCES) 323300810Sjhb p->fd = pfopen(p->opt.source, O_RDONLY); 324300810Sjhb if (p->fd < 0) { 325300810Sjhb snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ 326300810Sjhbyour system may not be properly configured; see the packetfilter(4) man page\n", 327300810Sjhb p->opt.source, pcap_strerror(errno)); 328164010Smarcel goto bad; 329300810Sjhb } 33083828Sdfr p->md.OrigMissed = -1; 331164010Smarcel enmode = ENTSTAMP|ENBATCH|ENNONEXCL; 332164010Smarcel if (p->opt.promisc) 33383828Sdfr enmode |= ENPROMISC; 334164010Smarcel if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { 335164010Smarcel snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", 33683828Sdfr pcap_strerror(errno)); 337295144Sandrew goto bad; 338164010Smarcel } 33983828Sdfr#ifdef ENCOPYALL 34083828Sdfr /* Try to set COPYALL mode so that we see packets to ourself */ 34183828Sdfr enmode = ENCOPYALL; 342300810Sjhb (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ 34383828Sdfr#endif 344300810Sjhb /* set the backlog */ 34583828Sdfr if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { 346164010Smarcel snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", 34783828Sdfr pcap_strerror(errno)); 34883828Sdfr goto bad; 349164010Smarcel } 350164010Smarcel /* discover interface type */ 35183828Sdfr if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { 352300782Sjhb snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", 353164010Smarcel pcap_strerror(errno)); 354164010Smarcel goto bad; 35583828Sdfr } 356300117Simp /* HACK: to compile prior to Ultrix 4.2 */ 357164010Smarcel#ifndef ENDT_FDDI 358164010Smarcel#define ENDT_FDDI 4 359300782Sjhb#endif 360300782Sjhb switch (devparams.end_dev_type) { 361300782Sjhb 362300782Sjhb case ENDT_10MB: 363300782Sjhb p->linktype = DLT_EN10MB; 364300782Sjhb p->offset = 2; 365300782Sjhb /* 366300117Simp * This is (presumably) a real Ethernet capture; give it a 367164010Smarcel * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 368300117Simp * that an application can let you choose it, in case you're 36983828Sdfr * capturing DOCSIS traffic that a Cisco Cable Modem 370 * Termination System is putting out onto an Ethernet (it 371 * doesn't put an Ethernet header onto the wire, it puts raw 372 * DOCSIS frames out on the wire inside the low-level 373 * Ethernet framing). 374 */ 375 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 376 /* 377 * If that fails, just leave the list empty. 378 */ 379 if (p->dlt_list != NULL) { 380 p->dlt_list[0] = DLT_EN10MB; 381 p->dlt_list[1] = DLT_DOCSIS; 382 p->dlt_count = 2; 383 } 384 break; 385 386 case ENDT_FDDI: 387 p->linktype = DLT_FDDI; 388 break; 389 390#ifdef ENDT_SLIP 391 case ENDT_SLIP: 392 p->linktype = DLT_SLIP; 393 break; 394#endif 395 396#ifdef ENDT_PPP 397 case ENDT_PPP: 398 p->linktype = DLT_PPP; 399 break; 400#endif 401 402#ifdef ENDT_LOOPBACK 403 case ENDT_LOOPBACK: 404 /* 405 * It appears to use Ethernet framing, at least on 406 * Digital UNIX 4.0. 407 */ 408 p->linktype = DLT_EN10MB; 409 p->offset = 2; 410 break; 411#endif 412 413#ifdef ENDT_TRN 414 case ENDT_TRN: 415 p->linktype = DLT_IEEE802; 416 break; 417#endif 418 419 default: 420 /* 421 * XXX - what about ENDT_IEEE802? The pfilt.h header 422 * file calls this "IEEE 802 networks (non-Ethernet)", 423 * but that doesn't specify a specific link layer type; 424 * it could be 802.4, or 802.5 (except that 802.5 is 425 * ENDT_TRN), or 802.6, or 802.11, or.... That's why 426 * DLT_IEEE802 was hijacked to mean Token Ring in various 427 * BSDs, and why we went along with that hijacking. 428 * 429 * XXX - what about ENDT_HDLC and ENDT_NULL? 430 * Presumably, as ENDT_OTHER is just "Miscellaneous 431 * framing", there's not much we can do, as that 432 * doesn't specify a particular type of header. 433 */ 434 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 435 "unknown data-link type %u", devparams.end_dev_type); 436 goto bad; 437 } 438 /* set truncation */ 439#ifdef PCAP_FDDIPAD 440 if (p->linktype == DLT_FDDI) { 441 p->fddipad = PCAP_FDDIPAD; 442 443 /* packetfilter includes the padding in the snapshot */ 444 p->snapshot += PCAP_FDDIPAD; 445 } else 446 p->fddipad = 0; 447#endif 448 if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) { 449 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", 450 pcap_strerror(errno)); 451 goto bad; 452 } 453 /* accept all packets */ 454 memset(&Filter, 0, sizeof(Filter)); 455 Filter.enf_Priority = 37; /* anything > 2 */ 456 Filter.enf_FilterLen = 0; /* means "always true" */ 457 if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { 458 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", 459 pcap_strerror(errno)); 460 goto bad; 461 } 462 463 if (p->md.timeout != 0) { 464 struct timeval timeout; 465 timeout.tv_sec = p->md.timeout / 1000; 466 timeout.tv_usec = (p->md.timeout * 1000) % 1000000; 467 if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { 468 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", 469 pcap_strerror(errno)); 470 goto bad; 471 } 472 } 473 474 p->bufsize = BUFSPACE; 475 p->buffer = (u_char*)malloc(p->bufsize + p->offset); 476 if (p->buffer == NULL) { 477 strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 478 goto bad; 479 } 480 481 /* 482 * "select()" and "poll()" work on packetfilter devices. 483 */ 484 p->selectable_fd = p->fd; 485 486 p->read_op = pcap_read_pf; 487 p->inject_op = pcap_inject_pf; 488 p->setfilter_op = pcap_setfilter_pf; 489 p->setdirection_op = NULL; /* Not implemented. */ 490 p->set_datalink_op = NULL; /* can't change data link type */ 491 p->getnonblock_op = pcap_getnonblock_fd; 492 p->setnonblock_op = pcap_setnonblock_fd; 493 p->stats_op = pcap_stats_pf; 494 495 return (0); 496 bad: 497 return (PCAP_ERROR); 498} 499 500pcap_t * 501pcap_create(const char *device, char *ebuf) 502{ 503 pcap_t *p; 504 505 p = pcap_create_common(device, ebuf); 506 if (p == NULL) 507 return (NULL); 508 509 p->activate_op = pcap_activate_pf; 510 return (p); 511} 512 513int 514pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 515{ 516 return (0); 517} 518 519static int 520pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) 521{ 522 struct bpf_version bv; 523 524 /* 525 * See if BIOCVERSION works. If not, we assume the kernel doesn't 526 * support BPF-style filters (it's not documented in the bpf(7) 527 * or packetfiler(7) man pages, but the code used to fail if 528 * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do 529 * kernel filtering in DU 4.0, so presumably BIOCVERSION works 530 * there, at least). 531 */ 532 if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { 533 /* 534 * OK, we have the version of the BPF interpreter; 535 * is it the same major version as us, and the same 536 * or better minor version? 537 */ 538 if (bv.bv_major == BPF_MAJOR_VERSION && 539 bv.bv_minor >= BPF_MINOR_VERSION) { 540 /* 541 * Yes. Try to install the filter. 542 */ 543 if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { 544 snprintf(p->errbuf, sizeof(p->errbuf), 545 "BIOCSETF: %s", pcap_strerror(errno)); 546 return (-1); 547 } 548 549 /* 550 * OK, that succeeded. We're doing filtering in 551 * the kernel. (We assume we don't have a 552 * userland filter installed - that'd require 553 * a previous version check to have failed but 554 * this one to succeed.) 555 * 556 * XXX - this message should be supplied to the 557 * application as a warning of some sort, 558 * except that if it's a GUI application, it's 559 * not clear that it should be displayed in 560 * a window to annoy the user. 561 */ 562 fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); 563 p->md.use_bpf = 1; 564 565 /* 566 * Discard any previously-received packets, 567 * as they might have passed whatever filter 568 * was formerly in effect, but might not pass 569 * this filter (BIOCSETF discards packets buffered 570 * in the kernel, so you can lose packets in any 571 * case). 572 */ 573 p->cc = 0; 574 return (0); 575 } 576 577 /* 578 * We can't use the kernel's BPF interpreter; don't give 579 * up, just log a message and be inefficient. 580 * 581 * XXX - this should really be supplied to the application 582 * as a warning of some sort. 583 */ 584 fprintf(stderr, 585 "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", 586 BPF_MAJOR_VERSION, BPF_MINOR_VERSION, 587 bv.bv_major, bv.bv_minor); 588 } 589 590 /* 591 * We couldn't do filtering in the kernel; do it in userland. 592 */ 593 if (install_bpf_program(p, fp) < 0) 594 return (-1); 595 596 /* 597 * XXX - this message should be supplied by the application as 598 * a warning of some sort. 599 */ 600 fprintf(stderr, "tcpdump: Filtering in user process\n"); 601 p->md.use_bpf = 0; 602 return (0); 603} 604