1 /* $NetBSD: pcap-pf.c,v 1.1.1.3 2013/04/06 15:57:49 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 #ifndef lint 28 static const char rcsid[] _U_ = 29 "@(#) Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.97 2008-04-14 20:40:58 guy Exp (LBL)"; 30 #endif 31 32 #ifdef HAVE_CONFIG_H 33 #include "config.h" 34 #endif 35 36 #include <sys/types.h> 37 #include <sys/time.h> 38 #include <sys/timeb.h> 39 #include <sys/socket.h> 40 #include <sys/file.h> 41 #include <sys/ioctl.h> 42 #include <net/pfilt.h> 43 44 struct mbuf; 45 struct rtentry; 46 #include <net/if.h> 47 48 #include <netinet/in.h> 49 #include <netinet/in_systm.h> 50 #include <netinet/ip.h> 51 #include <netinet/if_ether.h> 52 #include <netinet/ip_var.h> 53 #include <netinet/udp.h> 54 #include <netinet/udp_var.h> 55 #include <netinet/tcp.h> 56 #include <netinet/tcpip.h> 57 58 #include <ctype.h> 59 #include <errno.h> 60 #include <netdb.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 #include <unistd.h> 65 66 /* 67 * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the 68 * native OS version, as we need various BPF ioctls from it. 69 */ 70 #define PCAP_DONT_INCLUDE_PCAP_BPF_H 71 #include <net/bpf.h> 72 73 #include "pcap-int.h" 74 75 #ifdef HAVE_OS_PROTO_H 76 #include "os-proto.h" 77 #endif 78 79 static int pcap_setfilter_pf(pcap_t *, struct bpf_program *); 80 81 /* 82 * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump 83 * applications aren't going to need more than 200 bytes of packet header 84 * and the read shouldn't return more packets than packetfilter's internal 85 * queue limit (bounded at 256). 86 */ 87 #define BUFSPACE (200 * 256) 88 89 static int 90 pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) 91 { 92 register u_char *p, *bp; 93 register int cc, n, buflen, inc; 94 register struct enstamp *sp; 95 #ifdef LBL_ALIGN 96 struct enstamp stamp; 97 #endif 98 #ifdef PCAP_FDDIPAD 99 register int pad; 100 #endif 101 102 again: 103 cc = pc->cc; 104 if (cc == 0) { 105 cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); 106 if (cc < 0) { 107 if (errno == EWOULDBLOCK) 108 return (0); 109 if (errno == EINVAL && 110 lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { 111 /* 112 * Due to a kernel bug, after 2^31 bytes, 113 * the kernel file offset overflows and 114 * read fails with EINVAL. The lseek() 115 * to 0 will fix things. 116 */ 117 (void)lseek(pc->fd, 0L, SEEK_SET); 118 goto again; 119 } 120 snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", 121 pcap_strerror(errno)); 122 return (-1); 123 } 124 bp = pc->buffer + pc->offset; 125 } else 126 bp = pc->bp; 127 /* 128 * Loop through each packet. 129 */ 130 n = 0; 131 #ifdef PCAP_FDDIPAD 132 pad = pc->fddipad; 133 #endif 134 while (cc > 0) { 135 /* 136 * Has "pcap_breakloop()" been called? 137 * If so, return immediately - if we haven't read any 138 * packets, clear the flag and return -2 to indicate 139 * that we were told to break out of the loop, otherwise 140 * leave the flag set, so that the *next* call will break 141 * out of the loop without having read any packets, and 142 * return the number of packets we've processed so far. 143 */ 144 if (pc->break_loop) { 145 if (n == 0) { 146 pc->break_loop = 0; 147 return (-2); 148 } else { 149 pc->cc = cc; 150 pc->bp = bp; 151 return (n); 152 } 153 } 154 if (cc < sizeof(*sp)) { 155 snprintf(pc->errbuf, sizeof(pc->errbuf), 156 "pf short read (%d)", cc); 157 return (-1); 158 } 159 #ifdef LBL_ALIGN 160 if ((long)bp & 3) { 161 sp = &stamp; 162 memcpy((char *)sp, (char *)bp, sizeof(*sp)); 163 } else 164 #endif 165 sp = (struct enstamp *)bp; 166 if (sp->ens_stamplen != sizeof(*sp)) { 167 snprintf(pc->errbuf, sizeof(pc->errbuf), 168 "pf short stamplen (%d)", 169 sp->ens_stamplen); 170 return (-1); 171 } 172 173 p = bp + sp->ens_stamplen; 174 buflen = sp->ens_count; 175 if (buflen > pc->snapshot) 176 buflen = pc->snapshot; 177 178 /* Calculate inc before possible pad update */ 179 inc = ENALIGN(buflen + sp->ens_stamplen); 180 cc -= inc; 181 bp += inc; 182 pc->md.TotPkts++; 183 pc->md.TotDrops += sp->ens_dropped; 184 pc->md.TotMissed = sp->ens_ifoverflows; 185 if (pc->md.OrigMissed < 0) 186 pc->md.OrigMissed = pc->md.TotMissed; 187 188 /* 189 * Short-circuit evaluation: if using BPF filter 190 * in kernel, no need to do it now - we already know 191 * the packet passed the filter. 192 * 193 #ifdef PCAP_FDDIPAD 194 * Note: the filter code was generated assuming 195 * that pc->fddipad was the amount of padding 196 * before the header, as that's what's required 197 * in the kernel, so we run the filter before 198 * skipping that padding. 199 #endif 200 */ 201 if (pc->md.use_bpf || 202 bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { 203 struct pcap_pkthdr h; 204 pc->md.TotAccepted++; 205 h.ts = sp->ens_tstamp; 206 #ifdef PCAP_FDDIPAD 207 h.len = sp->ens_count - pad; 208 #else 209 h.len = sp->ens_count; 210 #endif 211 #ifdef PCAP_FDDIPAD 212 p += pad; 213 buflen -= pad; 214 #endif 215 h.caplen = buflen; 216 (*callback)(user, &h, p); 217 if (++n >= cnt && cnt > 0) { 218 pc->cc = cc; 219 pc->bp = bp; 220 return (n); 221 } 222 } 223 } 224 pc->cc = 0; 225 return (n); 226 } 227 228 static int 229 pcap_inject_pf(pcap_t *p, const void *buf, size_t size) 230 { 231 int ret; 232 233 ret = write(p->fd, buf, size); 234 if (ret == -1) { 235 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 236 pcap_strerror(errno)); 237 return (-1); 238 } 239 return (ret); 240 } 241 242 static int 243 pcap_stats_pf(pcap_t *p, struct pcap_stat *ps) 244 { 245 246 /* 247 * If packet filtering is being done in the kernel: 248 * 249 * "ps_recv" counts only packets that passed the filter. 250 * This does not include packets dropped because we 251 * ran out of buffer space. (XXX - perhaps it should, 252 * by adding "ps_drop" to "ps_recv", for compatibility 253 * with some other platforms. On the other hand, on 254 * some platforms "ps_recv" counts only packets that 255 * passed the filter, and on others it counts packets 256 * that didn't pass the filter....) 257 * 258 * "ps_drop" counts packets that passed the kernel filter 259 * (if any) but were dropped because the input queue was 260 * full. 261 * 262 * "ps_ifdrop" counts packets dropped by the network 263 * inteface (regardless of whether they would have passed 264 * the input filter, of course). 265 * 266 * If packet filtering is not being done in the kernel: 267 * 268 * "ps_recv" counts only packets that passed the filter. 269 * 270 * "ps_drop" counts packets that were dropped because the 271 * input queue was full, regardless of whether they passed 272 * the userland filter. 273 * 274 * "ps_ifdrop" counts packets dropped by the network 275 * inteface (regardless of whether they would have passed 276 * the input filter, of course). 277 * 278 * These statistics don't include packets not yet read from 279 * the kernel by libpcap, but they may include packets not 280 * yet read from libpcap by the application. 281 */ 282 ps->ps_recv = p->md.TotAccepted; 283 ps->ps_drop = p->md.TotDrops; 284 ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed; 285 return (0); 286 } 287 288 /* 289 * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably 290 * don't get DLT_DOCSIS defined. 291 */ 292 #ifndef DLT_DOCSIS 293 #define DLT_DOCSIS 143 294 #endif 295 296 static int 297 pcap_activate_pf(pcap_t *p) 298 { 299 short enmode; 300 int backlog = -1; /* request the most */ 301 struct enfilter Filter; 302 struct endevp devparams; 303 304 /* 305 * Initially try a read/write open (to allow the inject 306 * method to work). If that fails due to permission 307 * issues, fall back to read-only. This allows a 308 * non-root user to be granted specific access to pcap 309 * capabilities via file permissions. 310 * 311 * XXX - we should have an API that has a flag that 312 * controls whether to open read-only or read-write, 313 * so that denial of permission to send (or inability 314 * to send, if sending packets isn't supported on 315 * the device in question) can be indicated at open 316 * time. 317 * 318 * XXX - we assume here that "pfopen()" does not, in fact, modify 319 * its argument, even though it takes a "char *" rather than a 320 * "const char *" as its first argument. That appears to be 321 * the case, at least on Digital UNIX 4.0. 322 */ 323 p->fd = pfopen(p->opt.source, O_RDWR); 324 if (p->fd == -1 && errno == EACCES) 325 p->fd = pfopen(p->opt.source, O_RDONLY); 326 if (p->fd < 0) { 327 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ 328 your system may not be properly configured; see the packetfilter(4) man page\n", 329 p->opt.source, pcap_strerror(errno)); 330 goto bad; 331 } 332 p->md.OrigMissed = -1; 333 enmode = ENTSTAMP|ENBATCH|ENNONEXCL; 334 if (p->opt.promisc) 335 enmode |= ENPROMISC; 336 if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { 337 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", 338 pcap_strerror(errno)); 339 goto bad; 340 } 341 #ifdef ENCOPYALL 342 /* Try to set COPYALL mode so that we see packets to ourself */ 343 enmode = ENCOPYALL; 344 (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ 345 #endif 346 /* set the backlog */ 347 if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { 348 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", 349 pcap_strerror(errno)); 350 goto bad; 351 } 352 /* discover interface type */ 353 if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { 354 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", 355 pcap_strerror(errno)); 356 goto bad; 357 } 358 /* HACK: to compile prior to Ultrix 4.2 */ 359 #ifndef ENDT_FDDI 360 #define ENDT_FDDI 4 361 #endif 362 switch (devparams.end_dev_type) { 363 364 case ENDT_10MB: 365 p->linktype = DLT_EN10MB; 366 p->offset = 2; 367 /* 368 * This is (presumably) a real Ethernet capture; give it a 369 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 370 * that an application can let you choose it, in case you're 371 * capturing DOCSIS traffic that a Cisco Cable Modem 372 * Termination System is putting out onto an Ethernet (it 373 * doesn't put an Ethernet header onto the wire, it puts raw 374 * DOCSIS frames out on the wire inside the low-level 375 * Ethernet framing). 376 */ 377 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 378 /* 379 * If that fails, just leave the list empty. 380 */ 381 if (p->dlt_list != NULL) { 382 p->dlt_list[0] = DLT_EN10MB; 383 p->dlt_list[1] = DLT_DOCSIS; 384 p->dlt_count = 2; 385 } 386 break; 387 388 case ENDT_FDDI: 389 p->linktype = DLT_FDDI; 390 break; 391 392 #ifdef ENDT_SLIP 393 case ENDT_SLIP: 394 p->linktype = DLT_SLIP; 395 break; 396 #endif 397 398 #ifdef ENDT_PPP 399 case ENDT_PPP: 400 p->linktype = DLT_PPP; 401 break; 402 #endif 403 404 #ifdef ENDT_LOOPBACK 405 case ENDT_LOOPBACK: 406 /* 407 * It appears to use Ethernet framing, at least on 408 * Digital UNIX 4.0. 409 */ 410 p->linktype = DLT_EN10MB; 411 p->offset = 2; 412 break; 413 #endif 414 415 #ifdef ENDT_TRN 416 case ENDT_TRN: 417 p->linktype = DLT_IEEE802; 418 break; 419 #endif 420 421 default: 422 /* 423 * XXX - what about ENDT_IEEE802? The pfilt.h header 424 * file calls this "IEEE 802 networks (non-Ethernet)", 425 * but that doesn't specify a specific link layer type; 426 * it could be 802.4, or 802.5 (except that 802.5 is 427 * ENDT_TRN), or 802.6, or 802.11, or.... That's why 428 * DLT_IEEE802 was hijacked to mean Token Ring in various 429 * BSDs, and why we went along with that hijacking. 430 * 431 * XXX - what about ENDT_HDLC and ENDT_NULL? 432 * Presumably, as ENDT_OTHER is just "Miscellaneous 433 * framing", there's not much we can do, as that 434 * doesn't specify a particular type of header. 435 */ 436 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 437 "unknown data-link type %u", devparams.end_dev_type); 438 goto bad; 439 } 440 /* set truncation */ 441 #ifdef PCAP_FDDIPAD 442 if (p->linktype == DLT_FDDI) { 443 p->fddipad = PCAP_FDDIPAD; 444 445 /* packetfilter includes the padding in the snapshot */ 446 p->snapshot += PCAP_FDDIPAD; 447 } else 448 p->fddipad = 0; 449 #endif 450 if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) { 451 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", 452 pcap_strerror(errno)); 453 goto bad; 454 } 455 /* accept all packets */ 456 memset(&Filter, 0, sizeof(Filter)); 457 Filter.enf_Priority = 37; /* anything > 2 */ 458 Filter.enf_FilterLen = 0; /* means "always true" */ 459 if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { 460 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", 461 pcap_strerror(errno)); 462 goto bad; 463 } 464 465 if (p->md.timeout != 0) { 466 struct timeval timeout; 467 timeout.tv_sec = p->md.timeout / 1000; 468 timeout.tv_usec = (p->md.timeout * 1000) % 1000000; 469 if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { 470 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", 471 pcap_strerror(errno)); 472 goto bad; 473 } 474 } 475 476 p->bufsize = BUFSPACE; 477 p->buffer = (u_char*)malloc(p->bufsize + p->offset); 478 if (p->buffer == NULL) { 479 strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 480 goto bad; 481 } 482 483 /* 484 * "select()" and "poll()" work on packetfilter devices. 485 */ 486 p->selectable_fd = p->fd; 487 488 p->read_op = pcap_read_pf; 489 p->inject_op = pcap_inject_pf; 490 p->setfilter_op = pcap_setfilter_pf; 491 p->setdirection_op = NULL; /* Not implemented. */ 492 p->set_datalink_op = NULL; /* can't change data link type */ 493 p->getnonblock_op = pcap_getnonblock_fd; 494 p->setnonblock_op = pcap_setnonblock_fd; 495 p->stats_op = pcap_stats_pf; 496 497 return (0); 498 bad: 499 pcap_cleanup_live_common(p); 500 return (PCAP_ERROR); 501 } 502 503 pcap_t * 504 pcap_create(const char *device, char *ebuf) 505 { 506 pcap_t *p; 507 508 p = pcap_create_common(device, ebuf); 509 if (p == NULL) 510 return (NULL); 511 512 p->activate_op = pcap_activate_pf; 513 return (p); 514 } 515 516 int 517 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 518 { 519 return (0); 520 } 521 522 static int 523 pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) 524 { 525 struct bpf_version bv; 526 527 /* 528 * See if BIOCVERSION works. If not, we assume the kernel doesn't 529 * support BPF-style filters (it's not documented in the bpf(7) 530 * or packetfiler(7) man pages, but the code used to fail if 531 * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do 532 * kernel filtering in DU 4.0, so presumably BIOCVERSION works 533 * there, at least). 534 */ 535 if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { 536 /* 537 * OK, we have the version of the BPF interpreter; 538 * is it the same major version as us, and the same 539 * or better minor version? 540 */ 541 if (bv.bv_major == BPF_MAJOR_VERSION && 542 bv.bv_minor >= BPF_MINOR_VERSION) { 543 /* 544 * Yes. Try to install the filter. 545 */ 546 if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { 547 snprintf(p->errbuf, sizeof(p->errbuf), 548 "BIOCSETF: %s", pcap_strerror(errno)); 549 return (-1); 550 } 551 552 /* 553 * OK, that succeeded. We're doing filtering in 554 * the kernel. (We assume we don't have a 555 * userland filter installed - that'd require 556 * a previous version check to have failed but 557 * this one to succeed.) 558 * 559 * XXX - this message should be supplied to the 560 * application as a warning of some sort, 561 * except that if it's a GUI application, it's 562 * not clear that it should be displayed in 563 * a window to annoy the user. 564 */ 565 fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); 566 p->md.use_bpf = 1; 567 568 /* 569 * Discard any previously-received packets, 570 * as they might have passed whatever filter 571 * was formerly in effect, but might not pass 572 * this filter (BIOCSETF discards packets buffered 573 * in the kernel, so you can lose packets in any 574 * case). 575 */ 576 p->cc = 0; 577 return (0); 578 } 579 580 /* 581 * We can't use the kernel's BPF interpreter; don't give 582 * up, just log a message and be inefficient. 583 * 584 * XXX - this should really be supplied to the application 585 * as a warning of some sort. 586 */ 587 fprintf(stderr, 588 "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", 589 BPF_MAJOR_VERSION, BPF_MINOR_VERSION, 590 bv.bv_major, bv.bv_minor); 591 } 592 593 /* 594 * We couldn't do filtering in the kernel; do it in userland. 595 */ 596 if (install_bpf_program(p, fp) < 0) 597 return (-1); 598 599 /* 600 * XXX - this message should be supplied by the application as 601 * a warning of some sort. 602 */ 603 fprintf(stderr, "tcpdump: Filtering in user process\n"); 604 p->md.use_bpf = 0; 605 return (0); 606 } 607