1 /* $NetBSD: pcap-pf.c,v 1.7 2024/09/02 15:33:37 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * packet filter subroutines for tcpdump 24 * Extraction/creation by Jeffrey Mogul, DECWRL 25 */ 26 27 #include <sys/cdefs.h> 28 __RCSID("$NetBSD: pcap-pf.c,v 1.7 2024/09/02 15:33:37 christos Exp $"); 29 30 #include <config.h> 31 32 #include <sys/types.h> 33 #include <sys/time.h> 34 #include <sys/timeb.h> 35 #include <sys/socket.h> 36 #include <sys/file.h> 37 #include <sys/ioctl.h> 38 #include <net/pfilt.h> 39 40 struct mbuf; 41 struct rtentry; 42 #include <net/if.h> 43 44 #include <netinet/in.h> 45 #include <netinet/in_systm.h> 46 #include <netinet/ip.h> 47 #include <netinet/if_ether.h> 48 #include <netinet/ip_var.h> 49 #include <netinet/udp.h> 50 #include <netinet/udp_var.h> 51 #include <netinet/tcp.h> 52 #include <netinet/tcpip.h> 53 54 #include <errno.h> 55 #include <netdb.h> 56 #include <stdio.h> 57 #include <stdlib.h> 58 #include <string.h> 59 #include <unistd.h> 60 61 /* 62 * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the 63 * native OS version, as we need various BPF ioctls from it. 64 */ 65 #define PCAP_DONT_INCLUDE_PCAP_BPF_H 66 #include <net/bpf.h> 67 68 #include "pcap-int.h" 69 70 #ifdef HAVE_OS_PROTO_H 71 #include "os-proto.h" 72 #endif 73 74 /* 75 * FDDI packets are padded to make everything line up on a nice boundary. 76 */ 77 #define PCAP_FDDIPAD 3 78 79 /* 80 * Private data for capturing on Ultrix and DEC OSF/1^WDigital UNIX^W^W 81 * Tru64 UNIX packetfilter devices. 82 */ 83 struct pcap_pf { 84 int filtering_in_kernel; /* using kernel filter */ 85 u_long TotPkts; /* can't overflow for 79 hrs on ether */ 86 u_long TotAccepted; /* count accepted by filter */ 87 u_long TotDrops; /* count of dropped packets */ 88 long TotMissed; /* missed by i/f during this run */ 89 long OrigMissed; /* missed by i/f before this run */ 90 }; 91 92 static int pcap_setfilter_pf(pcap_t *, struct bpf_program *); 93 94 /* 95 * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump 96 * applications aren't going to need more than 200 bytes of packet header 97 * and the read shouldn't return more packets than packetfilter's internal 98 * queue limit (bounded at 256). 99 */ 100 #define BUFSPACE (200 * 256) 101 102 static int 103 pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) 104 { 105 struct pcap_pf *pf = pc->priv; 106 register u_char *p, *bp; 107 register int cc, n, buflen, inc; 108 register struct enstamp *sp; 109 struct enstamp stamp; 110 register u_int pad; 111 112 again: 113 cc = pc->cc; 114 if (cc == 0) { 115 cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); 116 if (cc < 0) { 117 if (errno == EWOULDBLOCK) 118 return (0); 119 if (errno == EINVAL && 120 lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { 121 /* 122 * Due to a kernel bug, after 2^31 bytes, 123 * the kernel file offset overflows and 124 * read fails with EINVAL. The lseek() 125 * to 0 will fix things. 126 */ 127 (void)lseek(pc->fd, 0L, SEEK_SET); 128 goto again; 129 } 130 pcapint_fmt_errmsg_for_errno(pc->errbuf, 131 sizeof(pc->errbuf), errno, "pf read"); 132 return (-1); 133 } 134 bp = (u_char *)pc->buffer + pc->offset; 135 } else 136 bp = pc->bp; 137 /* 138 * Loop through each packet. 139 * 140 * This assumes that a single buffer of packets will have 141 * <= INT_MAX packets, so the packet count doesn't overflow. 142 */ 143 n = 0; 144 pad = pc->fddipad; 145 while (cc > 0) { 146 /* 147 * Has "pcap_breakloop()" been called? 148 * If so, return immediately - if we haven't read any 149 * packets, clear the flag and return -2 to indicate 150 * that we were told to break out of the loop, otherwise 151 * leave the flag set, so that the *next* call will break 152 * out of the loop without having read any packets, and 153 * return the number of packets we've processed so far. 154 */ 155 if (pc->break_loop) { 156 if (n == 0) { 157 pc->break_loop = 0; 158 return (-2); 159 } else { 160 pc->cc = cc; 161 pc->bp = bp; 162 return (n); 163 } 164 } 165 if (cc < sizeof(*sp)) { 166 snprintf(pc->errbuf, sizeof(pc->errbuf), 167 "pf short read (%d)", cc); 168 return (-1); 169 } 170 if ((long)bp & 3) { 171 sp = &stamp; 172 memcpy((char *)sp, (char *)bp, sizeof(*sp)); 173 } else 174 sp = (struct enstamp *)bp; 175 if (sp->ens_stamplen != sizeof(*sp)) { 176 snprintf(pc->errbuf, sizeof(pc->errbuf), 177 "pf short stamplen (%d)", 178 sp->ens_stamplen); 179 return (-1); 180 } 181 182 p = bp + sp->ens_stamplen; 183 buflen = sp->ens_count; 184 if (buflen > pc->snapshot) 185 buflen = pc->snapshot; 186 187 /* Calculate inc before possible pad update */ 188 inc = ENALIGN(buflen + sp->ens_stamplen); 189 cc -= inc; 190 bp += inc; 191 pf->TotPkts++; 192 pf->TotDrops += sp->ens_dropped; 193 pf->TotMissed = sp->ens_ifoverflows; 194 if (pf->OrigMissed < 0) 195 pf->OrigMissed = pf->TotMissed; 196 197 /* 198 * Short-circuit evaluation: if using BPF filter 199 * in kernel, no need to do it now - we already know 200 * the packet passed the filter. 201 * 202 * Note: the filter code was generated assuming 203 * that pc->fddipad was the amount of padding 204 * before the header, as that's what's required 205 * in the kernel, so we run the filter before 206 * skipping that padding. 207 */ 208 if (pf->filtering_in_kernel || 209 pcapint_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { 210 struct pcap_pkthdr h; 211 pf->TotAccepted++; 212 h.ts = sp->ens_tstamp; 213 h.len = sp->ens_count - pad; 214 p += pad; 215 buflen -= pad; 216 h.caplen = buflen; 217 (*callback)(user, &h, p); 218 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { 219 pc->cc = cc; 220 pc->bp = bp; 221 return (n); 222 } 223 } 224 } 225 pc->cc = 0; 226 return (n); 227 } 228 229 static int 230 pcap_inject_pf(pcap_t *p, const void *buf, int size) 231 { 232 int ret; 233 234 ret = write(p->fd, buf, size); 235 if (ret == -1) { 236 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 237 errno, "send"); 238 return (-1); 239 } 240 return (ret); 241 } 242 243 static int 244 pcap_stats_pf(pcap_t *p, struct pcap_stat *ps) 245 { 246 struct pcap_pf *pf = p->priv; 247 248 /* 249 * If packet filtering is being done in the kernel: 250 * 251 * "ps_recv" counts only packets that passed the filter. 252 * This does not include packets dropped because we 253 * ran out of buffer space. (XXX - perhaps it should, 254 * by adding "ps_drop" to "ps_recv", for compatibility 255 * with some other platforms. On the other hand, on 256 * some platforms "ps_recv" counts only packets that 257 * passed the filter, and on others it counts packets 258 * that didn't pass the filter....) 259 * 260 * "ps_drop" counts packets that passed the kernel filter 261 * (if any) but were dropped because the input queue was 262 * full. 263 * 264 * "ps_ifdrop" counts packets dropped by the network 265 * interface (regardless of whether they would have passed 266 * the input filter, of course). 267 * 268 * If packet filtering is not being done in the kernel: 269 * 270 * "ps_recv" counts only packets that passed the filter. 271 * 272 * "ps_drop" counts packets that were dropped because the 273 * input queue was full, regardless of whether they passed 274 * the userland filter. 275 * 276 * "ps_ifdrop" counts packets dropped by the network 277 * interface (regardless of whether they would have passed 278 * the input filter, of course). 279 * 280 * These statistics don't include packets not yet read from 281 * the kernel by libpcap, but they may include packets not 282 * yet read from libpcap by the application. 283 */ 284 ps->ps_recv = pf->TotAccepted; 285 ps->ps_drop = pf->TotDrops; 286 ps->ps_ifdrop = pf->TotMissed - pf->OrigMissed; 287 return (0); 288 } 289 290 /* 291 * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably 292 * don't get DLT_DOCSIS defined. 293 */ 294 #ifndef DLT_DOCSIS 295 #define DLT_DOCSIS 143 296 #endif 297 298 static int 299 pcap_activate_pf(pcap_t *p) 300 { 301 struct pcap_pf *pf = p->priv; 302 short enmode; 303 int backlog = -1; /* request the most */ 304 struct enfilter Filter; 305 struct endevp devparams; 306 int err; 307 308 /* 309 * Initially try a read/write open (to allow the inject 310 * method to work). If that fails due to permission 311 * issues, fall back to read-only. This allows a 312 * non-root user to be granted specific access to pcap 313 * capabilities via file permissions. 314 * 315 * XXX - we should have an API that has a flag that 316 * controls whether to open read-only or read-write, 317 * so that denial of permission to send (or inability 318 * to send, if sending packets isn't supported on 319 * the device in question) can be indicated at open 320 * time. 321 * 322 * XXX - we assume here that "pfopen()" does not, in fact, modify 323 * its argument, even though it takes a "char *" rather than a 324 * "const char *" as its first argument. That appears to be 325 * the case, at least on Digital UNIX 4.0. 326 * 327 * XXX - is there an error that means "no such device"? Is 328 * there one that means "that device doesn't support pf"? 329 */ 330 p->fd = pfopen(p->opt.device, O_RDWR); 331 if (p->fd == -1 && errno == EACCES) 332 p->fd = pfopen(p->opt.device, O_RDONLY); 333 if (p->fd < 0) { 334 if (errno == EACCES) { 335 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 336 "pf open: %s: Permission denied\n" 337 "your system may not be properly configured; see the packetfilter(4) man page", 338 p->opt.device); 339 err = PCAP_ERROR_PERM_DENIED; 340 } else { 341 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 342 errno, "pf open: %s", p->opt.device); 343 err = PCAP_ERROR; 344 } 345 goto bad; 346 } 347 348 /* 349 * Turn a negative snapshot value (invalid), a snapshot value of 350 * 0 (unspecified), or a value bigger than the normal maximum 351 * value, into the maximum allowed value. 352 * 353 * If some application really *needs* a bigger snapshot 354 * length, we should just increase MAXIMUM_SNAPLEN. 355 */ 356 if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 357 p->snapshot = MAXIMUM_SNAPLEN; 358 359 pf->OrigMissed = -1; 360 enmode = ENTSTAMP|ENNONEXCL; 361 if (!p->opt.immediate) 362 enmode |= ENBATCH; 363 if (p->opt.promisc) 364 enmode |= ENPROMISC; 365 if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { 366 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 367 errno, "EIOCMBIS"); 368 err = PCAP_ERROR; 369 goto bad; 370 } 371 #ifdef ENCOPYALL 372 /* Try to set COPYALL mode so that we see packets to ourself */ 373 enmode = ENCOPYALL; 374 (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ 375 #endif 376 /* set the backlog */ 377 if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { 378 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 379 errno, "EIOCSETW"); 380 err = PCAP_ERROR; 381 goto bad; 382 } 383 /* discover interface type */ 384 if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { 385 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 386 errno, "EIOCDEVP"); 387 err = PCAP_ERROR; 388 goto bad; 389 } 390 /* HACK: to compile prior to Ultrix 4.2 */ 391 #ifndef ENDT_FDDI 392 #define ENDT_FDDI 4 393 #endif 394 switch (devparams.end_dev_type) { 395 396 case ENDT_10MB: 397 p->linktype = DLT_EN10MB; 398 p->offset = 2; 399 /* 400 * This is (presumably) a real Ethernet capture; give it a 401 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 402 * that an application can let you choose it, in case you're 403 * capturing DOCSIS traffic that a Cisco Cable Modem 404 * Termination System is putting out onto an Ethernet (it 405 * doesn't put an Ethernet header onto the wire, it puts raw 406 * DOCSIS frames out on the wire inside the low-level 407 * Ethernet framing). 408 */ 409 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 410 if (p->dlt_list == NULL) { 411 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 412 errno, "malloc"); 413 err = PCAP_ERROR; 414 goto bad; 415 } 416 p->dlt_list[0] = DLT_EN10MB; 417 p->dlt_list[1] = DLT_DOCSIS; 418 p->dlt_count = 2; 419 break; 420 421 case ENDT_FDDI: 422 p->linktype = DLT_FDDI; 423 break; 424 425 #ifdef ENDT_SLIP 426 case ENDT_SLIP: 427 p->linktype = DLT_SLIP; 428 break; 429 #endif 430 431 #ifdef ENDT_PPP 432 case ENDT_PPP: 433 p->linktype = DLT_PPP; 434 break; 435 #endif 436 437 #ifdef ENDT_LOOPBACK 438 case ENDT_LOOPBACK: 439 /* 440 * It appears to use Ethernet framing, at least on 441 * Digital UNIX 4.0. 442 */ 443 p->linktype = DLT_EN10MB; 444 p->offset = 2; 445 break; 446 #endif 447 448 #ifdef ENDT_TRN 449 case ENDT_TRN: 450 p->linktype = DLT_IEEE802; 451 break; 452 #endif 453 454 default: 455 /* 456 * XXX - what about ENDT_IEEE802? The pfilt.h header 457 * file calls this "IEEE 802 networks (non-Ethernet)", 458 * but that doesn't specify a specific link layer type; 459 * it could be 802.4, or 802.5 (except that 802.5 is 460 * ENDT_TRN), or 802.6, or 802.11, or.... That's why 461 * DLT_IEEE802 was hijacked to mean Token Ring in various 462 * BSDs, and why we went along with that hijacking. 463 * 464 * XXX - what about ENDT_HDLC and ENDT_NULL? 465 * Presumably, as ENDT_OTHER is just "Miscellaneous 466 * framing", there's not much we can do, as that 467 * doesn't specify a particular type of header. 468 */ 469 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 470 "unknown data-link type %u", devparams.end_dev_type); 471 err = PCAP_ERROR; 472 goto bad; 473 } 474 /* set truncation */ 475 if (p->linktype == DLT_FDDI) { 476 p->fddipad = PCAP_FDDIPAD; 477 478 /* packetfilter includes the padding in the snapshot */ 479 p->snapshot += PCAP_FDDIPAD; 480 } else 481 p->fddipad = 0; 482 if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) { 483 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 484 errno, "EIOCTRUNCATE"); 485 err = PCAP_ERROR; 486 goto bad; 487 } 488 /* accept all packets */ 489 memset(&Filter, 0, sizeof(Filter)); 490 Filter.enf_Priority = 37; /* anything > 2 */ 491 Filter.enf_FilterLen = 0; /* means "always true" */ 492 if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { 493 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 494 errno, "EIOCSETF"); 495 err = PCAP_ERROR; 496 goto bad; 497 } 498 499 if (p->opt.timeout != 0) { 500 struct timeval timeout; 501 timeout.tv_sec = p->opt.timeout / 1000; 502 timeout.tv_usec = (p->opt.timeout * 1000) % 1000000; 503 if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { 504 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 505 errno, "EIOCSRTIMEOUT"); 506 err = PCAP_ERROR; 507 goto bad; 508 } 509 } 510 511 p->bufsize = BUFSPACE; 512 p->buffer = malloc(p->bufsize + p->offset); 513 if (p->buffer == NULL) { 514 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 515 errno, "malloc"); 516 err = PCAP_ERROR; 517 goto bad; 518 } 519 520 /* 521 * "select()" and "poll()" work on packetfilter devices. 522 */ 523 p->selectable_fd = p->fd; 524 525 p->read_op = pcap_read_pf; 526 p->inject_op = pcap_inject_pf; 527 p->setfilter_op = pcap_setfilter_pf; 528 p->setdirection_op = NULL; /* Not implemented. */ 529 p->set_datalink_op = NULL; /* can't change data link type */ 530 p->getnonblock_op = pcapint_getnonblock_fd; 531 p->setnonblock_op = pcapint_setnonblock_fd; 532 p->stats_op = pcap_stats_pf; 533 534 return (0); 535 bad: 536 pcapint_cleanup_live_common(p); 537 return (err); 538 } 539 540 pcap_t * 541 pcapint_create_interface(const char *device _U_, char *ebuf) 542 { 543 pcap_t *p; 544 545 p = PCAP_CREATE_COMMON(ebuf, struct pcap_pf); 546 if (p == NULL) 547 return (NULL); 548 549 p->activate_op = pcap_activate_pf; 550 return (p); 551 } 552 553 /* 554 * XXX - is there an error from pfopen() that means "no such device"? 555 * Is there one that means "that device doesn't support pf"? 556 */ 557 static int 558 can_be_bound(const char *name _U_) 559 { 560 return (1); 561 } 562 563 static int 564 get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_) 565 { 566 /* 567 * Nothing we can do other than mark loopback devices as "the 568 * connected/disconnected status doesn't apply". 569 * 570 * XXX - is there a way to find out whether an adapter has 571 * something plugged into it? 572 */ 573 if (*flags & PCAP_IF_LOOPBACK) { 574 /* 575 * Loopback devices aren't wireless, and "connected"/ 576 * "disconnected" doesn't apply to them. 577 */ 578 *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; 579 return (0); 580 } 581 return (0); 582 } 583 584 int 585 pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) 586 { 587 return (pcapint_findalldevs_interfaces(devlistp, errbuf, can_be_bound, 588 get_if_flags)); 589 } 590 591 static int 592 pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) 593 { 594 struct pcap_pf *pf = p->priv; 595 struct bpf_version bv; 596 597 /* 598 * See if BIOCVERSION works. If not, we assume the kernel doesn't 599 * support BPF-style filters (it's not documented in the bpf(7) 600 * or packetfilter(7) man pages, but the code used to fail if 601 * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do 602 * kernel filtering in DU 4.0, so presumably BIOCVERSION works 603 * there, at least). 604 */ 605 if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { 606 /* 607 * OK, we have the version of the BPF interpreter; 608 * is it the same major version as us, and the same 609 * or better minor version? 610 */ 611 if (bv.bv_major == BPF_MAJOR_VERSION && 612 bv.bv_minor >= BPF_MINOR_VERSION) { 613 /* 614 * Yes. Try to install the filter. 615 */ 616 if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { 617 pcapint_fmt_errmsg_for_errno(p->errbuf, 618 sizeof(p->errbuf), errno, "BIOCSETF"); 619 return (-1); 620 } 621 622 /* 623 * OK, that succeeded. We're doing filtering in 624 * the kernel. (We assume we don't have a 625 * userland filter installed - that'd require 626 * a previous version check to have failed but 627 * this one to succeed.) 628 * 629 * XXX - this message should be supplied to the 630 * application as a warning of some sort, 631 * except that if it's a GUI application, it's 632 * not clear that it should be displayed in 633 * a window to annoy the user. 634 */ 635 fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); 636 pf->filtering_in_kernel = 1; 637 638 /* 639 * Discard any previously-received packets, 640 * as they might have passed whatever filter 641 * was formerly in effect, but might not pass 642 * this filter (BIOCSETF discards packets buffered 643 * in the kernel, so you can lose packets in any 644 * case). 645 */ 646 p->cc = 0; 647 return (0); 648 } 649 650 /* 651 * We can't use the kernel's BPF interpreter; don't give 652 * up, just log a message and be inefficient. 653 * 654 * XXX - this should really be supplied to the application 655 * as a warning of some sort. 656 */ 657 fprintf(stderr, 658 "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", 659 BPF_MAJOR_VERSION, BPF_MINOR_VERSION, 660 bv.bv_major, bv.bv_minor); 661 } 662 663 /* 664 * We couldn't do filtering in the kernel; do it in userland. 665 */ 666 if (pcapint_install_bpf_program(p, fp) < 0) 667 return (-1); 668 669 /* 670 * XXX - this message should be supplied by the application as 671 * a warning of some sort. 672 */ 673 fprintf(stderr, "tcpdump: Filtering in user process\n"); 674 pf->filtering_in_kernel = 0; 675 return (0); 676 } 677 678 /* 679 * Libpcap version string. 680 */ 681 const char * 682 pcap_lib_version(void) 683 { 684 return (PCAP_VERSION_STRING); 685 } 686