1 /* $OpenBSD: pcap.c,v 1.24 2018/06/03 10:29:28 sthen Exp $ */ 2 3 /* 4 * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 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 the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the Computer Systems 18 * Engineering Group at Lawrence Berkeley Laboratory. 19 * 4. Neither the name of the University nor of the Laboratory may be used 20 * to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/types.h> 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 #include <errno.h> 43 #include <fcntl.h> 44 45 #ifdef HAVE_OS_PROTO_H 46 #include "os-proto.h" 47 #endif 48 49 #include "pcap-int.h" 50 51 static const char pcap_version_string[] = "OpenBSD libpcap"; 52 53 int 54 pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 55 { 56 57 if (p->sf.rfile != NULL) 58 return (pcap_offline_read(p, cnt, callback, user)); 59 return (pcap_read(p, cnt, callback, user)); 60 } 61 62 int 63 pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 64 { 65 int n; 66 67 for (;;) { 68 if (p->sf.rfile != NULL) 69 n = pcap_offline_read(p, cnt, callback, user); 70 else { 71 /* 72 * XXX keep reading until we get something 73 * (or an error occurs) 74 */ 75 do { 76 n = pcap_read(p, cnt, callback, user); 77 } while (n == 0); 78 } 79 if (n <= 0) 80 return (n); 81 if (cnt > 0) { 82 cnt -= n; 83 if (cnt <= 0) 84 return (0); 85 } 86 } 87 } 88 89 struct singleton { 90 struct pcap_pkthdr *hdr; 91 const u_char *pkt; 92 }; 93 94 95 static void 96 pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt) 97 { 98 struct singleton *sp = (struct singleton *)userData; 99 *sp->hdr = *h; 100 sp->pkt = pkt; 101 } 102 103 const u_char * 104 pcap_next(pcap_t *p, struct pcap_pkthdr *h) 105 { 106 struct singleton s; 107 108 s.hdr = h; 109 if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) 110 return (0); 111 return (s.pkt); 112 } 113 114 struct pkt_for_fakecallback { 115 struct pcap_pkthdr *hdr; 116 const u_char **pkt; 117 }; 118 119 static void 120 pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h, 121 const u_char *pkt) 122 { 123 struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData; 124 125 *sp->hdr = *h; 126 *sp->pkt = pkt; 127 } 128 129 int 130 pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, 131 const u_char **pkt_data) 132 { 133 struct pkt_for_fakecallback s; 134 135 s.hdr = &p->pcap_header; 136 s.pkt = pkt_data; 137 138 /* Saves a pointer to the packet headers */ 139 *pkt_header= &p->pcap_header; 140 141 if (p->sf.rfile != NULL) { 142 int status; 143 144 /* We are on an offline capture */ 145 status = pcap_offline_read(p, 1, pcap_fakecallback, 146 (u_char *)&s); 147 148 /* 149 * Return codes for pcap_offline_read() are: 150 * - 0: EOF 151 * - -1: error 152 * - >1: OK 153 * The first one ('0') conflicts with the return code of 154 * 0 from pcap_read() meaning "no packets arrived before 155 * the timeout expired", so we map it to -2 so you can 156 * distinguish between an EOF from a savefile and a 157 * "no packets arrived before the timeout expired, try 158 * again" from a live capture. 159 */ 160 if (status == 0) 161 return (-2); 162 else 163 return (status); 164 } 165 166 /* 167 * Return codes for pcap_read() are: 168 * - 0: timeout 169 * - -1: error 170 * - -2: loop was broken out of with pcap_breakloop() 171 * - >1: OK 172 * The first one ('0') conflicts with the return code of 0 from 173 * pcap_offline_read() meaning "end of file". 174 */ 175 return (pcap_read(p, 1, pcap_fakecallback, (u_char *)&s)); 176 } 177 178 int 179 pcap_check_activated(pcap_t *p) 180 { 181 if (p->activated) { 182 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform " 183 " operation on activated capture"); 184 return -1; 185 } 186 return 0; 187 } 188 189 int 190 pcap_set_snaplen(pcap_t *p, int snaplen) 191 { 192 if (pcap_check_activated(p)) 193 return PCAP_ERROR_ACTIVATED; 194 p->snapshot = snaplen; 195 return 0; 196 } 197 198 int 199 pcap_set_promisc(pcap_t *p, int promisc) 200 { 201 if (pcap_check_activated(p)) 202 return PCAP_ERROR_ACTIVATED; 203 p->opt.promisc = promisc; 204 return 0; 205 } 206 207 int 208 pcap_set_rfmon(pcap_t *p, int rfmon) 209 { 210 if (pcap_check_activated(p)) 211 return PCAP_ERROR_ACTIVATED; 212 p->opt.rfmon = rfmon; 213 return 0; 214 } 215 216 int 217 pcap_set_timeout(pcap_t *p, int timeout_ms) 218 { 219 if (pcap_check_activated(p)) 220 return PCAP_ERROR_ACTIVATED; 221 p->md.timeout = timeout_ms; 222 return 0; 223 } 224 225 int 226 pcap_set_immediate_mode(pcap_t *p, int immediate) 227 { 228 if (pcap_check_activated(p)) 229 return PCAP_ERROR_ACTIVATED; 230 p->opt.immediate = immediate; 231 return 0; 232 } 233 234 int 235 pcap_set_buffer_size(pcap_t *p, int buffer_size) 236 { 237 if (pcap_check_activated(p)) 238 return PCAP_ERROR_ACTIVATED; 239 p->opt.buffer_size = buffer_size; 240 return 0; 241 } 242 243 /* 244 * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. 245 */ 246 void 247 pcap_breakloop(pcap_t *p) 248 { 249 p->break_loop = 1; 250 } 251 252 int 253 pcap_datalink(pcap_t *p) 254 { 255 return (p->linktype); 256 } 257 258 int 259 pcap_list_datalinks(pcap_t *p, int **dlt_buffer) 260 { 261 if (p->dlt_count == 0) { 262 /* 263 * We couldn't fetch the list of DLTs, which means 264 * this platform doesn't support changing the 265 * DLT for an interface. Return a list of DLTs 266 * containing only the DLT this device supports. 267 */ 268 *dlt_buffer = malloc(sizeof(**dlt_buffer)); 269 if (*dlt_buffer == NULL) { 270 (void)snprintf(p->errbuf, sizeof(p->errbuf), 271 "malloc: %s", pcap_strerror(errno)); 272 return (-1); 273 } 274 **dlt_buffer = p->linktype; 275 return (1); 276 } else { 277 *dlt_buffer = reallocarray(NULL, sizeof(**dlt_buffer), 278 p->dlt_count); 279 if (*dlt_buffer == NULL) { 280 (void)snprintf(p->errbuf, sizeof(p->errbuf), 281 "malloc: %s", pcap_strerror(errno)); 282 return (-1); 283 } 284 (void)memcpy(*dlt_buffer, p->dlt_list, 285 sizeof(**dlt_buffer) * p->dlt_count); 286 return (p->dlt_count); 287 } 288 } 289 290 /* 291 * In Windows, you might have a library built with one version of the 292 * C runtime library and an application built with another version of 293 * the C runtime library, which means that the library might use one 294 * version of malloc() and free() and the application might use another 295 * version of malloc() and free(). If so, that means something 296 * allocated by the library cannot be freed by the application, so we 297 * need to have a pcap_free_datalinks() routine to free up the list 298 * allocated by pcap_list_datalinks(), even though it's just a wrapper 299 * around free(). 300 */ 301 void 302 pcap_free_datalinks(int *dlt_list) 303 { 304 free(dlt_list); 305 } 306 307 struct dlt_choice { 308 const char *name; 309 const char *description; 310 int dlt; 311 }; 312 313 static struct dlt_choice dlts[] = { 314 #define DLT_CHOICE(code, description) { #code, description, code } 315 DLT_CHOICE(DLT_NULL, "no link-layer encapsulation"), 316 DLT_CHOICE(DLT_EN10MB, "Ethernet (10Mb)"), 317 DLT_CHOICE(DLT_EN3MB, "Experimental Ethernet (3Mb)"), 318 DLT_CHOICE(DLT_AX25, "Amateur Radio AX.25"), 319 DLT_CHOICE(DLT_PRONET, "Proteon ProNET Token Ring"), 320 DLT_CHOICE(DLT_CHAOS, "Chaos"), 321 DLT_CHOICE(DLT_IEEE802, "IEEE 802 Networks"), 322 DLT_CHOICE(DLT_ARCNET, "ARCNET"), 323 DLT_CHOICE(DLT_SLIP, "Serial Line IP"), 324 DLT_CHOICE(DLT_PPP, "Point-to-point Protocol"), 325 DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), 326 DLT_CHOICE(DLT_FDDI, "FDDI"), 327 DLT_CHOICE(DLT_ATM_RFC1483, "LLC/SNAP encapsulated atm"), 328 DLT_CHOICE(DLT_LOOP, "loopback type (af header)"), 329 DLT_CHOICE(DLT_ENC, "IPSEC enc type (af header, spi, flags)"), 330 DLT_CHOICE(DLT_RAW, "raw IP"), 331 DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS Serial Line IP"), 332 DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS Point-to-point Protocol"), 333 DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"), 334 DLT_CHOICE(DLT_PPP_ETHER, "PPP over Ethernet; session only w/o ether header"), 335 DLT_CHOICE(DLT_IEEE802_11, "IEEE 802.11 wireless"), 336 DLT_CHOICE(DLT_PFLOG, "Packet filter logging, by pcap people"), 337 DLT_CHOICE(DLT_IEEE802_11_RADIO, "IEEE 802.11 plus WLAN header"), 338 DLT_CHOICE(DLT_OPENFLOW, "OpenFlow"), 339 DLT_CHOICE(DLT_USBPCAP, "USB"), 340 #undef DLT_CHOICE 341 { NULL, NULL, -1} 342 }; 343 344 int 345 pcap_datalink_name_to_val(const char *name) 346 { 347 int i; 348 349 for (i = 0; dlts[i].name != NULL; i++) { 350 /* Skip leading "DLT_" */ 351 if (strcasecmp(dlts[i].name + 4, name) == 0) 352 return (dlts[i].dlt); 353 } 354 return (-1); 355 } 356 357 const char * 358 pcap_datalink_val_to_name(int dlt) 359 { 360 int i; 361 362 for (i = 0; dlts[i].name != NULL; i++) { 363 if (dlts[i].dlt == dlt) 364 return (dlts[i].name + 4); /* Skip leading "DLT_" */ 365 } 366 return (NULL); 367 } 368 369 const char * 370 pcap_datalink_val_to_description(int dlt) 371 { 372 int i; 373 374 for (i = 0; dlts[i].name != NULL; i++) { 375 if (dlts[i].dlt == dlt) 376 return (dlts[i].description); 377 } 378 return (NULL); 379 } 380 381 int 382 pcap_snapshot(pcap_t *p) 383 { 384 return (p->snapshot); 385 } 386 387 int 388 pcap_is_swapped(pcap_t *p) 389 { 390 return (p->sf.swapped); 391 } 392 393 int 394 pcap_major_version(pcap_t *p) 395 { 396 return (p->sf.version_major); 397 } 398 399 int 400 pcap_minor_version(pcap_t *p) 401 { 402 return (p->sf.version_minor); 403 } 404 405 FILE * 406 pcap_file(pcap_t *p) 407 { 408 return (p->sf.rfile); 409 } 410 411 int 412 pcap_fileno(pcap_t *p) 413 { 414 return (p->fd); 415 } 416 417 void 418 pcap_perror(pcap_t *p, const char *prefix) 419 { 420 fprintf(stderr, "%s: %s\n", prefix, p->errbuf); 421 } 422 423 int 424 pcap_get_selectable_fd(pcap_t *p) 425 { 426 return (p->fd); 427 } 428 429 char * 430 pcap_geterr(pcap_t *p) 431 { 432 return (p->errbuf); 433 } 434 435 int 436 pcap_getnonblock(pcap_t *p, char *errbuf) 437 { 438 int fdflags; 439 440 fdflags = fcntl(p->fd, F_GETFL); 441 if (fdflags == -1) { 442 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 443 pcap_strerror(errno)); 444 return (-1); 445 } 446 if (fdflags & O_NONBLOCK) 447 return (1); 448 else 449 return (0); 450 } 451 452 int 453 pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) 454 { 455 int fdflags; 456 457 fdflags = fcntl(p->fd, F_GETFL); 458 if (fdflags == -1) { 459 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 460 pcap_strerror(errno)); 461 return (-1); 462 } 463 if (nonblock) 464 fdflags |= O_NONBLOCK; 465 else 466 fdflags &= ~O_NONBLOCK; 467 if (fcntl(p->fd, F_SETFL, fdflags) == -1) { 468 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", 469 pcap_strerror(errno)); 470 return (-1); 471 } 472 return (0); 473 } 474 475 /* 476 * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. 477 */ 478 const char * 479 pcap_statustostr(int errnum) 480 { 481 static char ebuf[15+10+1]; 482 483 switch (errnum) { 484 485 case PCAP_WARNING: 486 return("Generic warning"); 487 488 case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: 489 return ("That type of time stamp is not supported by that device"); 490 491 case PCAP_WARNING_PROMISC_NOTSUP: 492 return ("That device doesn't support promiscuous mode"); 493 494 case PCAP_ERROR: 495 return("Generic error"); 496 497 case PCAP_ERROR_BREAK: 498 return("Loop terminated by pcap_breakloop"); 499 500 case PCAP_ERROR_NOT_ACTIVATED: 501 return("The pcap_t has not been activated"); 502 503 case PCAP_ERROR_ACTIVATED: 504 return ("The setting can't be changed after the pcap_t is activated"); 505 506 case PCAP_ERROR_NO_SUCH_DEVICE: 507 return ("No such device exists"); 508 509 case PCAP_ERROR_RFMON_NOTSUP: 510 return ("That device doesn't support monitor mode"); 511 512 case PCAP_ERROR_NOT_RFMON: 513 return ("That operation is supported only in monitor mode"); 514 515 case PCAP_ERROR_PERM_DENIED: 516 return ("You don't have permission to capture on that device"); 517 518 case PCAP_ERROR_IFACE_NOT_UP: 519 return ("That device is not up"); 520 521 case PCAP_ERROR_CANTSET_TSTAMP_TYPE: 522 return ("That device doesn't support setting the time stamp type"); 523 524 case PCAP_ERROR_PROMISC_PERM_DENIED: 525 return ("You don't have permission to capture in promiscuous mode on that device"); 526 } 527 (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 528 return(ebuf); 529 } 530 531 /* 532 * Not all systems have strerror(). 533 */ 534 const char * 535 pcap_strerror(int errnum) 536 { 537 #ifdef HAVE_STRERROR 538 return (strerror(errnum)); 539 #else 540 extern int sys_nerr; 541 extern const char *const sys_errlist[]; 542 static char ebuf[20]; 543 544 if ((unsigned int)errnum < sys_nerr) 545 return ((char *)sys_errlist[errnum]); 546 (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 547 return(ebuf); 548 #endif 549 } 550 551 /* 552 * On some platforms, we need to clean up promiscuous or monitor mode 553 * when we close a device - and we want that to happen even if the 554 * application just exits without explicitl closing devices. 555 * On those platforms, we need to register a "close all the pcaps" 556 * routine to be called when we exit, and need to maintain a list of 557 * pcaps that need to be closed to clean up modes. 558 * 559 * XXX - not thread-safe. 560 */ 561 562 /* 563 * List of pcaps on which we've done something that needs to be 564 * cleaned up. 565 * If there are any such pcaps, we arrange to call "pcap_close_all()" 566 * when we exit, and have it close all of them. 567 */ 568 static struct pcap *pcaps_to_close; 569 570 /* 571 * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to 572 * be called on exit. 573 */ 574 static int did_atexit; 575 576 static void 577 pcap_close_all(void) 578 { 579 struct pcap *handle; 580 581 while ((handle = pcaps_to_close) != NULL) 582 pcap_close(handle); 583 } 584 585 int 586 pcap_do_addexit(pcap_t *p) 587 { 588 /* 589 * If we haven't already done so, arrange to have 590 * "pcap_close_all()" called when we exit. 591 */ 592 if (!did_atexit) { 593 if (atexit(pcap_close_all) == -1) { 594 /* 595 * "atexit()" failed; let our caller know. 596 */ 597 (void)strlcpy(p->errbuf, "atexit failed", 598 PCAP_ERRBUF_SIZE); 599 return (0); 600 } 601 did_atexit = 1; 602 } 603 return (1); 604 } 605 606 void 607 pcap_add_to_pcaps_to_close(pcap_t *p) 608 { 609 p->md.next = pcaps_to_close; 610 pcaps_to_close = p; 611 } 612 613 void 614 pcap_remove_from_pcaps_to_close(pcap_t *p) 615 { 616 pcap_t *pc, *prevpc; 617 618 for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; 619 prevpc = pc, pc = pc->md.next) { 620 if (pc == p) { 621 /* 622 * Found it. Remove it from the list. 623 */ 624 if (prevpc == NULL) { 625 /* 626 * It was at the head of the list. 627 */ 628 pcaps_to_close = pc->md.next; 629 } else { 630 /* 631 * It was in the middle of the list. 632 */ 633 prevpc->md.next = pc->md.next; 634 } 635 break; 636 } 637 } 638 } 639 640 pcap_t * 641 pcap_open_dead(int linktype, int snaplen) 642 { 643 pcap_t *p; 644 645 p = calloc(1, sizeof(*p)); 646 if (p == NULL) 647 return NULL; 648 p->snapshot = snaplen; 649 p->linktype = linktype; 650 p->fd = -1; 651 return p; 652 } 653 654 /* 655 * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw 656 * data for the packet, check whether the packet passes the filter. 657 * Returns the return value of the filter program, which will be zero if 658 * the packet doesn't pass and non-zero if the packet does pass. 659 */ 660 int 661 pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, 662 const u_char *pkt) 663 { 664 struct bpf_insn *fcode = fp->bf_insns; 665 666 if (fcode != NULL) 667 return (bpf_filter(fcode, pkt, h->len, h->caplen)); 668 else 669 return (0); 670 } 671 672 const char * 673 pcap_lib_version(void) 674 { 675 return (pcap_version_string); 676 } 677 678