1 /* 2 * Copyright (c) 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * sf-pcap.c - libpcap-file-format-specific code from savefile.c 22 * Extraction/creation by Jeffrey Mogul, DECWRL 23 * Modified by Steve McCanne, LBL. 24 * 25 * Used to save the received packet headers, after filtering, to 26 * a file, and then read them later. 27 * The first record in the file contains saved values for the machine 28 * dependent values so we can print the dump file on any architecture. 29 */ 30 31 #ifdef HAVE_CONFIG_H 32 #include <config.h> 33 #endif 34 35 #include <pcap-types.h> 36 #ifdef _WIN32 37 #include <io.h> 38 #include <fcntl.h> 39 #endif /* _WIN32 */ 40 41 #include <errno.h> 42 #include <memory.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <limits.h> /* for INT_MAX */ 47 48 #include "pcap-int.h" 49 50 #include "pcap-common.h" 51 52 #ifdef HAVE_OS_PROTO_H 53 #include "os-proto.h" 54 #endif 55 56 #include "sf-pcap.h" 57 58 /* 59 * Setting O_BINARY on DOS/Windows is a bit tricky 60 */ 61 #if defined(_WIN32) 62 #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY) 63 #elif defined(MSDOS) 64 #if defined(__HIGHC__) 65 #define SET_BINMODE(f) setmode(f, O_BINARY) 66 #else 67 #define SET_BINMODE(f) setmode(fileno(f), O_BINARY) 68 #endif 69 #endif 70 71 /* 72 * Standard libpcap format. 73 */ 74 #define TCPDUMP_MAGIC 0xa1b2c3d4 75 76 /* 77 * Alexey Kuznetzov's modified libpcap format. 78 */ 79 #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34 80 81 /* 82 * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt> 83 * for another modified format. 84 */ 85 #define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd 86 87 /* 88 * Navtel Communcations' format, with nanosecond timestamps, 89 * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>. 90 */ 91 #define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d 92 93 /* 94 * Normal libpcap format, except for seconds/nanoseconds timestamps, 95 * as per a request by Ulf Lamping <ulf.lamping@web.de> 96 */ 97 #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d 98 99 /* 100 * Mechanism for storing information about a capture in the upper 101 * 6 bits of a linktype value in a capture file. 102 * 103 * LT_LINKTYPE_EXT(x) extracts the additional information. 104 * 105 * The rest of the bits are for a value describing the link-layer 106 * value. LT_LINKTYPE(x) extracts that value. 107 */ 108 #define LT_LINKTYPE(x) ((x) & 0x03FFFFFF) 109 #define LT_LINKTYPE_EXT(x) ((x) & 0xFC000000) 110 111 static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap); 112 113 #ifdef _WIN32 114 /* 115 * This isn't exported on Windows, because it would only work if both 116 * libpcap and the code using it were using the same C runtime; otherwise they 117 * would be using different definitions of a FILE structure. 118 * 119 * Instead we define this as a macro in pcap/pcap.h that wraps the hopen 120 * version that we do export, passing it a raw OS HANDLE, as defined by the 121 * Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle() 122 * functions of the appropriate CRT. 123 */ 124 static pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *f); 125 #endif /* _WIN32 */ 126 127 /* 128 * Private data for reading pcap savefiles. 129 */ 130 typedef enum { 131 NOT_SWAPPED, 132 SWAPPED, 133 MAYBE_SWAPPED 134 } swapped_type_t; 135 136 typedef enum { 137 PASS_THROUGH, 138 SCALE_UP, 139 SCALE_DOWN 140 } tstamp_scale_type_t; 141 142 struct pcap_sf { 143 size_t hdrsize; 144 swapped_type_t lengths_swapped; 145 tstamp_scale_type_t scale_type; 146 }; 147 148 /* 149 * Check whether this is a pcap savefile and, if it is, extract the 150 * relevant information from the header. 151 */ 152 pcap_t * 153 pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf, 154 int *err) 155 { 156 bpf_u_int32 magic_int; 157 struct pcap_file_header hdr; 158 size_t amt_read; 159 pcap_t *p; 160 int swapped = 0; 161 struct pcap_sf *ps; 162 163 /* 164 * Assume no read errors. 165 */ 166 *err = 0; 167 168 /* 169 * Check whether the first 4 bytes of the file are the magic 170 * number for a pcap savefile, or for a byte-swapped pcap 171 * savefile. 172 */ 173 memcpy(&magic_int, magic, sizeof(magic_int)); 174 if (magic_int != TCPDUMP_MAGIC && 175 magic_int != KUZNETZOV_TCPDUMP_MAGIC && 176 magic_int != NSEC_TCPDUMP_MAGIC) { 177 magic_int = SWAPLONG(magic_int); 178 if (magic_int != TCPDUMP_MAGIC && 179 magic_int != KUZNETZOV_TCPDUMP_MAGIC && 180 magic_int != NSEC_TCPDUMP_MAGIC) 181 return (NULL); /* nope */ 182 swapped = 1; 183 } 184 185 /* 186 * They are. Put the magic number in the header, and read 187 * the rest of the header. 188 */ 189 hdr.magic = magic_int; 190 amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1, 191 sizeof(hdr) - sizeof(hdr.magic), fp); 192 if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) { 193 if (ferror(fp)) { 194 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 195 errno, "error reading dump file"); 196 } else { 197 snprintf(errbuf, PCAP_ERRBUF_SIZE, 198 "truncated dump file; tried to read %zu file header bytes, only got %zu", 199 sizeof(hdr), amt_read); 200 } 201 *err = 1; 202 return (NULL); 203 } 204 205 /* 206 * If it's a byte-swapped capture file, byte-swap the header. 207 */ 208 if (swapped) { 209 hdr.version_major = SWAPSHORT(hdr.version_major); 210 hdr.version_minor = SWAPSHORT(hdr.version_minor); 211 hdr.thiszone = SWAPLONG(hdr.thiszone); 212 hdr.sigfigs = SWAPLONG(hdr.sigfigs); 213 hdr.snaplen = SWAPLONG(hdr.snaplen); 214 hdr.linktype = SWAPLONG(hdr.linktype); 215 } 216 217 if (hdr.version_major < PCAP_VERSION_MAJOR) { 218 snprintf(errbuf, PCAP_ERRBUF_SIZE, 219 "archaic pcap savefile format"); 220 *err = 1; 221 return (NULL); 222 } 223 224 /* 225 * currently only versions 2.[0-4] are supported with 226 * the exception of 543.0 for DG/UX tcpdump. 227 */ 228 if (! ((hdr.version_major == PCAP_VERSION_MAJOR && 229 hdr.version_minor <= PCAP_VERSION_MINOR) || 230 (hdr.version_major == 543 && 231 hdr.version_minor == 0))) { 232 snprintf(errbuf, PCAP_ERRBUF_SIZE, 233 "unsupported pcap savefile version %u.%u", 234 hdr.version_major, hdr.version_minor); 235 *err = 1; 236 return NULL; 237 } 238 239 /* 240 * OK, this is a good pcap file. 241 * Allocate a pcap_t for it. 242 */ 243 p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf); 244 if (p == NULL) { 245 /* Allocation failed. */ 246 *err = 1; 247 return (NULL); 248 } 249 p->swapped = swapped; 250 p->version_major = hdr.version_major; 251 p->version_minor = hdr.version_minor; 252 p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype)); 253 p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype); 254 p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen); 255 256 p->next_packet_op = pcap_next_packet; 257 258 ps = p->priv; 259 260 p->opt.tstamp_precision = precision; 261 262 /* 263 * Will we need to scale the timestamps to match what the 264 * user wants? 265 */ 266 switch (precision) { 267 268 case PCAP_TSTAMP_PRECISION_MICRO: 269 if (magic_int == NSEC_TCPDUMP_MAGIC) { 270 /* 271 * The file has nanoseconds, the user 272 * wants microseconds; scale the 273 * precision down. 274 */ 275 ps->scale_type = SCALE_DOWN; 276 } else { 277 /* 278 * The file has microseconds, the 279 * user wants microseconds; nothing to do. 280 */ 281 ps->scale_type = PASS_THROUGH; 282 } 283 break; 284 285 case PCAP_TSTAMP_PRECISION_NANO: 286 if (magic_int == NSEC_TCPDUMP_MAGIC) { 287 /* 288 * The file has nanoseconds, the 289 * user wants nanoseconds; nothing to do. 290 */ 291 ps->scale_type = PASS_THROUGH; 292 } else { 293 /* 294 * The file has microseconds, the user 295 * wants nanoseconds; scale the 296 * precision up. 297 */ 298 ps->scale_type = SCALE_UP; 299 } 300 break; 301 302 default: 303 snprintf(errbuf, PCAP_ERRBUF_SIZE, 304 "unknown time stamp resolution %u", precision); 305 free(p); 306 *err = 1; 307 return (NULL); 308 } 309 310 /* 311 * We interchanged the caplen and len fields at version 2.3, 312 * in order to match the bpf header layout. But unfortunately 313 * some files were written with version 2.3 in their headers 314 * but without the interchanged fields. 315 * 316 * In addition, DG/UX tcpdump writes out files with a version 317 * number of 543.0, and with the caplen and len fields in the 318 * pre-2.3 order. 319 */ 320 switch (hdr.version_major) { 321 322 case 2: 323 if (hdr.version_minor < 3) 324 ps->lengths_swapped = SWAPPED; 325 else if (hdr.version_minor == 3) 326 ps->lengths_swapped = MAYBE_SWAPPED; 327 else 328 ps->lengths_swapped = NOT_SWAPPED; 329 break; 330 331 case 543: 332 ps->lengths_swapped = SWAPPED; 333 break; 334 335 default: 336 ps->lengths_swapped = NOT_SWAPPED; 337 break; 338 } 339 340 if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) { 341 /* 342 * XXX - the patch that's in some versions of libpcap 343 * changes the packet header but not the magic number, 344 * and some other versions with this magic number have 345 * some extra debugging information in the packet header; 346 * we'd have to use some hacks^H^H^H^H^Hheuristics to 347 * detect those variants. 348 * 349 * Ethereal does that, but it does so by trying to read 350 * the first two packets of the file with each of the 351 * record header formats. That currently means it seeks 352 * backwards and retries the reads, which doesn't work 353 * on pipes. We want to be able to read from a pipe, so 354 * that strategy won't work; we'd have to buffer some 355 * data ourselves and read from that buffer in order to 356 * make that work. 357 */ 358 ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 359 360 if (p->linktype == DLT_EN10MB) { 361 /* 362 * This capture might have been done in raw mode 363 * or cooked mode. 364 * 365 * If it was done in cooked mode, p->snapshot was 366 * passed to recvfrom() as the buffer size, meaning 367 * that the most packet data that would be copied 368 * would be p->snapshot. However, a faked Ethernet 369 * header would then have been added to it, so the 370 * most data that would be in a packet in the file 371 * would be p->snapshot + 14. 372 * 373 * We can't easily tell whether the capture was done 374 * in raw mode or cooked mode, so we'll assume it was 375 * cooked mode, and add 14 to the snapshot length. 376 * That means that, for a raw capture, the snapshot 377 * length will be misleading if you use it to figure 378 * out why a capture doesn't have all the packet data, 379 * but there's not much we can do to avoid that. 380 * 381 * But don't grow the snapshot length past the 382 * maximum value of an int. 383 */ 384 if (p->snapshot <= INT_MAX - 14) 385 p->snapshot += 14; 386 else 387 p->snapshot = INT_MAX; 388 } 389 } else 390 ps->hdrsize = sizeof(struct pcap_sf_pkthdr); 391 392 /* 393 * Allocate a buffer for the packet data. 394 * Choose the minimum of the file's snapshot length and 2K bytes; 395 * that should be enough for most network packets - we'll grow it 396 * if necessary. That way, we don't allocate a huge chunk of 397 * memory just because there's a huge snapshot length, as the 398 * snapshot length might be larger than the size of the largest 399 * packet. 400 */ 401 p->bufsize = p->snapshot; 402 if (p->bufsize > 2048) 403 p->bufsize = 2048; 404 p->buffer = malloc(p->bufsize); 405 if (p->buffer == NULL) { 406 snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 407 free(p); 408 *err = 1; 409 return (NULL); 410 } 411 412 p->cleanup_op = sf_cleanup; 413 414 return (p); 415 } 416 417 /* 418 * Grow the packet buffer to the specified size. 419 */ 420 static int 421 grow_buffer(pcap_t *p, u_int bufsize) 422 { 423 void *bigger_buffer; 424 425 bigger_buffer = realloc(p->buffer, bufsize); 426 if (bigger_buffer == NULL) { 427 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 428 return (0); 429 } 430 p->buffer = bigger_buffer; 431 p->bufsize = bufsize; 432 return (1); 433 } 434 435 /* 436 * Read and return the next packet from the savefile. Return the header 437 * in hdr and a pointer to the contents in data. Return 0 on success, 1 438 * if there were no more packets, and -1 on an error. 439 */ 440 static int 441 pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) 442 { 443 struct pcap_sf *ps = p->priv; 444 struct pcap_sf_patched_pkthdr sf_hdr; 445 FILE *fp = p->rfile; 446 size_t amt_read; 447 bpf_u_int32 t; 448 449 /* 450 * Read the packet header; the structure we use as a buffer 451 * is the longer structure for files generated by the patched 452 * libpcap, but if the file has the magic number for an 453 * unpatched libpcap we only read as many bytes as the regular 454 * header has. 455 */ 456 amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp); 457 if (amt_read != ps->hdrsize) { 458 if (ferror(fp)) { 459 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 460 errno, "error reading dump file"); 461 return (-1); 462 } else { 463 if (amt_read != 0) { 464 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 465 "truncated dump file; tried to read %zu header bytes, only got %zu", 466 ps->hdrsize, amt_read); 467 return (-1); 468 } 469 /* EOF */ 470 return (1); 471 } 472 } 473 474 if (p->swapped) { 475 /* these were written in opposite byte order */ 476 hdr->caplen = SWAPLONG(sf_hdr.caplen); 477 hdr->len = SWAPLONG(sf_hdr.len); 478 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 479 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 480 } else { 481 hdr->caplen = sf_hdr.caplen; 482 hdr->len = sf_hdr.len; 483 hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 484 hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 485 } 486 487 switch (ps->scale_type) { 488 489 case PASS_THROUGH: 490 /* 491 * Just pass the time stamp through. 492 */ 493 break; 494 495 case SCALE_UP: 496 /* 497 * File has microseconds, user wants nanoseconds; convert 498 * it. 499 */ 500 hdr->ts.tv_usec = hdr->ts.tv_usec * 1000; 501 break; 502 503 case SCALE_DOWN: 504 /* 505 * File has nanoseconds, user wants microseconds; convert 506 * it. 507 */ 508 hdr->ts.tv_usec = hdr->ts.tv_usec / 1000; 509 break; 510 } 511 512 /* Swap the caplen and len fields, if necessary. */ 513 switch (ps->lengths_swapped) { 514 515 case NOT_SWAPPED: 516 break; 517 518 case MAYBE_SWAPPED: 519 if (hdr->caplen <= hdr->len) { 520 /* 521 * The captured length is <= the actual length, 522 * so presumably they weren't swapped. 523 */ 524 break; 525 } 526 /* FALLTHROUGH */ 527 528 case SWAPPED: 529 t = hdr->caplen; 530 hdr->caplen = hdr->len; 531 hdr->len = t; 532 break; 533 } 534 535 /* 536 * Is the packet bigger than we consider sane? 537 */ 538 if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) { 539 /* 540 * Yes. This may be a damaged or fuzzed file. 541 * 542 * Is it bigger than the snapshot length? 543 * (We don't treat that as an error if it's not 544 * bigger than the maximum we consider sane; see 545 * below.) 546 */ 547 if (hdr->caplen > (bpf_u_int32)p->snapshot) { 548 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 549 "invalid packet capture length %u, bigger than " 550 "snaplen of %d", hdr->caplen, p->snapshot); 551 } else { 552 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 553 "invalid packet capture length %u, bigger than " 554 "maximum of %u", hdr->caplen, 555 max_snaplen_for_dlt(p->linktype)); 556 } 557 return (-1); 558 } 559 560 if (hdr->caplen > (bpf_u_int32)p->snapshot) { 561 /* 562 * The packet is bigger than the snapshot length 563 * for this file. 564 * 565 * This can happen due to Solaris 2.3 systems tripping 566 * over the BUFMOD problem and not setting the snapshot 567 * length correctly in the savefile header. 568 * 569 * libpcap 0.4 and later on Solaris 2.3 should set the 570 * snapshot length correctly in the pcap file header, 571 * even though they don't set a snapshot length in bufmod 572 * (the buggy bufmod chops off the *beginning* of the 573 * packet if a snapshot length is specified); they should 574 * also reduce the captured length, as supplied to the 575 * per-packet callback, to the snapshot length if it's 576 * greater than the snapshot length, so the code using 577 * libpcap should see the packet cut off at the snapshot 578 * length, even though the full packet is copied up to 579 * userland. 580 * 581 * However, perhaps some versions of libpcap failed to 582 * set the snapshot length currectly in the file header 583 * or the per-packet header, or perhaps this is a 584 * corrupted safefile or a savefile built/modified by a 585 * fuzz tester, so we check anyway. We grow the buffer 586 * to be big enough for the snapshot length, read up 587 * to the snapshot length, discard the rest of the 588 * packet, and report the snapshot length as the captured 589 * length; we don't want to hand our caller a packet 590 * bigger than the snapshot length, because they might 591 * be assuming they'll never be handed such a packet, 592 * and might copy the packet into a snapshot-length- 593 * sized buffer, assuming it'll fit. 594 */ 595 size_t bytes_to_discard; 596 size_t bytes_to_read, bytes_read; 597 char discard_buf[4096]; 598 599 if (hdr->caplen > p->bufsize) { 600 /* 601 * Grow the buffer to the snapshot length. 602 */ 603 if (!grow_buffer(p, p->snapshot)) 604 return (-1); 605 } 606 607 /* 608 * Read the first p->snapshot bytes into the buffer. 609 */ 610 amt_read = fread(p->buffer, 1, p->snapshot, fp); 611 if (amt_read != (bpf_u_int32)p->snapshot) { 612 if (ferror(fp)) { 613 pcap_fmt_errmsg_for_errno(p->errbuf, 614 PCAP_ERRBUF_SIZE, errno, 615 "error reading dump file"); 616 } else { 617 /* 618 * Yes, this uses hdr->caplen; technically, 619 * it's true, because we would try to read 620 * and discard the rest of those bytes, and 621 * that would fail because we got EOF before 622 * the read finished. 623 */ 624 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 625 "truncated dump file; tried to read %u captured bytes, only got %zu", 626 p->snapshot, amt_read); 627 } 628 return (-1); 629 } 630 631 /* 632 * Now read and discard what's left. 633 */ 634 bytes_to_discard = hdr->caplen - p->snapshot; 635 bytes_read = amt_read; 636 while (bytes_to_discard != 0) { 637 bytes_to_read = bytes_to_discard; 638 if (bytes_to_read > sizeof (discard_buf)) 639 bytes_to_read = sizeof (discard_buf); 640 amt_read = fread(discard_buf, 1, bytes_to_read, fp); 641 bytes_read += amt_read; 642 if (amt_read != bytes_to_read) { 643 if (ferror(fp)) { 644 pcap_fmt_errmsg_for_errno(p->errbuf, 645 PCAP_ERRBUF_SIZE, errno, 646 "error reading dump file"); 647 } else { 648 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 649 "truncated dump file; tried to read %u captured bytes, only got %zu", 650 hdr->caplen, bytes_read); 651 } 652 return (-1); 653 } 654 bytes_to_discard -= amt_read; 655 } 656 657 /* 658 * Adjust caplen accordingly, so we don't get confused later 659 * as to how many bytes we have to play with. 660 */ 661 hdr->caplen = p->snapshot; 662 } else { 663 /* 664 * The packet is within the snapshot length for this file. 665 */ 666 if (hdr->caplen > p->bufsize) { 667 /* 668 * Grow the buffer to the next power of 2, or 669 * the snaplen, whichever is lower. 670 */ 671 u_int new_bufsize; 672 673 new_bufsize = hdr->caplen; 674 /* 675 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 676 */ 677 new_bufsize--; 678 new_bufsize |= new_bufsize >> 1; 679 new_bufsize |= new_bufsize >> 2; 680 new_bufsize |= new_bufsize >> 4; 681 new_bufsize |= new_bufsize >> 8; 682 new_bufsize |= new_bufsize >> 16; 683 new_bufsize++; 684 685 if (new_bufsize > (u_int)p->snapshot) 686 new_bufsize = p->snapshot; 687 688 if (!grow_buffer(p, new_bufsize)) 689 return (-1); 690 } 691 692 /* read the packet itself */ 693 amt_read = fread(p->buffer, 1, hdr->caplen, fp); 694 if (amt_read != hdr->caplen) { 695 if (ferror(fp)) { 696 pcap_fmt_errmsg_for_errno(p->errbuf, 697 PCAP_ERRBUF_SIZE, errno, 698 "error reading dump file"); 699 } else { 700 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 701 "truncated dump file; tried to read %u captured bytes, only got %zu", 702 hdr->caplen, amt_read); 703 } 704 return (-1); 705 } 706 } 707 *data = p->buffer; 708 709 if (p->swapped) 710 swap_pseudo_headers(p->linktype, hdr, *data); 711 712 return (0); 713 } 714 715 static int 716 sf_write_header(pcap_t *p, FILE *fp, int linktype, int snaplen) 717 { 718 struct pcap_file_header hdr; 719 720 hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC; 721 hdr.version_major = PCAP_VERSION_MAJOR; 722 hdr.version_minor = PCAP_VERSION_MINOR; 723 724 /* 725 * https://www.tcpdump.org/manpages/pcap-savefile.5.txt states: 726 * thiszone: 4-byte time zone offset; this is always 0. 727 * sigfigs: 4-byte number giving the accuracy of time stamps 728 * in the file; this is always 0. 729 */ 730 hdr.thiszone = 0; 731 hdr.sigfigs = 0; 732 hdr.snaplen = snaplen; 733 hdr.linktype = linktype; 734 735 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 736 return (-1); 737 738 return (0); 739 } 740 741 /* 742 * Output a packet to the initialized dump file. 743 */ 744 void 745 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 746 { 747 register FILE *f; 748 struct pcap_sf_pkthdr sf_hdr; 749 750 f = (FILE *)user; 751 /* 752 * Better not try writing pcap files after 753 * 2038-01-19 03:14:07 UTC; switch to pcapng. 754 */ 755 sf_hdr.ts.tv_sec = (bpf_int32)h->ts.tv_sec; 756 sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec; 757 sf_hdr.caplen = h->caplen; 758 sf_hdr.len = h->len; 759 /* XXX we should check the return status */ 760 (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 761 (void)fwrite(sp, h->caplen, 1, f); 762 } 763 764 static pcap_dumper_t * 765 pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname) 766 { 767 768 #if defined(_WIN32) || defined(MSDOS) 769 /* 770 * If we're writing to the standard output, put it in binary 771 * mode, as savefiles are binary files. 772 * 773 * Otherwise, we turn off buffering. 774 * XXX - why? And why not on the standard output? 775 */ 776 if (f == stdout) 777 SET_BINMODE(f); 778 else 779 setvbuf(f, NULL, _IONBF, 0); 780 #endif 781 if (sf_write_header(p, f, linktype, p->snapshot) == -1) { 782 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 783 errno, "Can't write to %s", fname); 784 if (f != stdout) 785 (void)fclose(f); 786 return (NULL); 787 } 788 return ((pcap_dumper_t *)f); 789 } 790 791 /* 792 * Initialize so that sf_write() will output to the file named 'fname'. 793 */ 794 pcap_dumper_t * 795 pcap_dump_open(pcap_t *p, const char *fname) 796 { 797 FILE *f; 798 int linktype; 799 800 /* 801 * If this pcap_t hasn't been activated, it doesn't have a 802 * link-layer type, so we can't use it. 803 */ 804 if (!p->activated) { 805 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 806 "%s: not-yet-activated pcap_t passed to pcap_dump_open", 807 fname); 808 return (NULL); 809 } 810 linktype = dlt_to_linktype(p->linktype); 811 if (linktype == -1) { 812 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 813 "%s: link-layer type %d isn't supported in savefiles", 814 fname, p->linktype); 815 return (NULL); 816 } 817 linktype |= p->linktype_ext; 818 819 if (fname == NULL) { 820 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 821 "A null pointer was supplied as the file name"); 822 return NULL; 823 } 824 if (fname[0] == '-' && fname[1] == '\0') { 825 f = stdout; 826 fname = "standard output"; 827 } else { 828 /* 829 * "b" is supported as of C90, so *all* UN*Xes should 830 * support it, even though it does nothing. It's 831 * required on Windows, as the file is a binary file 832 * and must be written in binary mode. 833 */ 834 f = charset_fopen(fname, "wb"); 835 if (f == NULL) { 836 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 837 errno, "%s", fname); 838 return (NULL); 839 } 840 } 841 return (pcap_setup_dump(p, linktype, f, fname)); 842 } 843 844 #ifdef _WIN32 845 /* 846 * Initialize so that sf_write() will output to a stream wrapping the given raw 847 * OS file HANDLE. 848 */ 849 pcap_dumper_t * 850 pcap_dump_hopen(pcap_t *p, intptr_t osfd) 851 { 852 int fd; 853 FILE *file; 854 855 fd = _open_osfhandle(osfd, _O_APPEND); 856 if (fd < 0) { 857 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 858 errno, "_open_osfhandle"); 859 return NULL; 860 } 861 862 file = _fdopen(fd, "wb"); 863 if (file == NULL) { 864 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 865 errno, "_fdopen"); 866 _close(fd); 867 return NULL; 868 } 869 870 return pcap_dump_fopen(p, file); 871 } 872 #endif /* _WIN32 */ 873 874 /* 875 * Initialize so that sf_write() will output to the given stream. 876 */ 877 #ifdef _WIN32 878 static 879 #endif /* _WIN32 */ 880 pcap_dumper_t * 881 pcap_dump_fopen(pcap_t *p, FILE *f) 882 { 883 int linktype; 884 885 linktype = dlt_to_linktype(p->linktype); 886 if (linktype == -1) { 887 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 888 "stream: link-layer type %d isn't supported in savefiles", 889 p->linktype); 890 return (NULL); 891 } 892 linktype |= p->linktype_ext; 893 894 return (pcap_setup_dump(p, linktype, f, "stream")); 895 } 896 897 pcap_dumper_t * 898 pcap_dump_open_append(pcap_t *p, const char *fname) 899 { 900 FILE *f; 901 int linktype; 902 size_t amt_read; 903 struct pcap_file_header ph; 904 905 linktype = dlt_to_linktype(p->linktype); 906 if (linktype == -1) { 907 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 908 "%s: link-layer type %d isn't supported in savefiles", 909 fname, linktype); 910 return (NULL); 911 } 912 913 if (fname == NULL) { 914 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 915 "A null pointer was supplied as the file name"); 916 return NULL; 917 } 918 if (fname[0] == '-' && fname[1] == '\0') 919 return (pcap_setup_dump(p, linktype, stdout, "standard output")); 920 921 /* 922 * "a" will cause the file *not* to be truncated if it exists 923 * but will cause it to be created if it doesn't. It will 924 * also cause all writes to be done at the end of the file, 925 * but will allow reads to be done anywhere in the file. This 926 * is what we need, because we need to read from the beginning 927 * of the file to see if it already has a header and packets 928 * or if it doesn't. 929 * 930 * "b" is supported as of C90, so *all* UN*Xes should support it, 931 * even though it does nothing. It's required on Windows, as the 932 * file is a binary file and must be read in binary mode. 933 */ 934 f = charset_fopen(fname, "ab+"); 935 if (f == NULL) { 936 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 937 errno, "%s", fname); 938 return (NULL); 939 } 940 941 /* 942 * Try to read a pcap header. 943 * 944 * We do not assume that the file will be positioned at the 945 * beginning immediately after we've opened it - we seek to 946 * the beginning. ISO C says it's implementation-defined 947 * whether the file position indicator is at the beginning 948 * or the end of the file after an append-mode open, and 949 * it wasn't obvious from the Single UNIX Specification 950 * or the Microsoft documentation how that works on SUS- 951 * compliant systems or on Windows. 952 */ 953 if (fseek(f, 0, SEEK_SET) == -1) { 954 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 955 errno, "Can't seek to the beginning of %s", fname); 956 (void)fclose(f); 957 return (NULL); 958 } 959 amt_read = fread(&ph, 1, sizeof (ph), f); 960 if (amt_read != sizeof (ph)) { 961 if (ferror(f)) { 962 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 963 errno, "%s", fname); 964 (void)fclose(f); 965 return (NULL); 966 } else if (feof(f) && amt_read > 0) { 967 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 968 "%s: truncated pcap file header", fname); 969 (void)fclose(f); 970 return (NULL); 971 } 972 } 973 974 #if defined(_WIN32) || defined(MSDOS) 975 /* 976 * We turn off buffering. 977 * XXX - why? And why not on the standard output? 978 */ 979 setvbuf(f, NULL, _IONBF, 0); 980 #endif 981 982 /* 983 * If a header is already present and: 984 * 985 * it's not for a pcap file of the appropriate resolution 986 * and the right byte order for this machine; 987 * 988 * the link-layer header types don't match; 989 * 990 * the snapshot lengths don't match; 991 * 992 * return an error. 993 */ 994 if (amt_read > 0) { 995 /* 996 * A header is already present. 997 * Do the checks. 998 */ 999 switch (ph.magic) { 1000 1001 case TCPDUMP_MAGIC: 1002 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) { 1003 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1004 "%s: different time stamp precision, cannot append to file", fname); 1005 (void)fclose(f); 1006 return (NULL); 1007 } 1008 break; 1009 1010 case NSEC_TCPDUMP_MAGIC: 1011 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) { 1012 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1013 "%s: different time stamp precision, cannot append to file", fname); 1014 (void)fclose(f); 1015 return (NULL); 1016 } 1017 break; 1018 1019 case SWAPLONG(TCPDUMP_MAGIC): 1020 case SWAPLONG(NSEC_TCPDUMP_MAGIC): 1021 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1022 "%s: different byte order, cannot append to file", fname); 1023 (void)fclose(f); 1024 return (NULL); 1025 1026 case KUZNETZOV_TCPDUMP_MAGIC: 1027 case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC): 1028 case NAVTEL_TCPDUMP_MAGIC: 1029 case SWAPLONG(NAVTEL_TCPDUMP_MAGIC): 1030 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1031 "%s: not a pcap file to which we can append", fname); 1032 (void)fclose(f); 1033 return (NULL); 1034 1035 default: 1036 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1037 "%s: not a pcap file", fname); 1038 (void)fclose(f); 1039 return (NULL); 1040 } 1041 1042 /* 1043 * Good version? 1044 */ 1045 if (ph.version_major != PCAP_VERSION_MAJOR || 1046 ph.version_minor != PCAP_VERSION_MINOR) { 1047 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1048 "%s: version is %u.%u, cannot append to file", fname, 1049 ph.version_major, ph.version_minor); 1050 (void)fclose(f); 1051 return (NULL); 1052 } 1053 if ((bpf_u_int32)linktype != ph.linktype) { 1054 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1055 "%s: different linktype, cannot append to file", fname); 1056 (void)fclose(f); 1057 return (NULL); 1058 } 1059 if ((bpf_u_int32)p->snapshot != ph.snaplen) { 1060 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1061 "%s: different snaplen, cannot append to file", fname); 1062 (void)fclose(f); 1063 return (NULL); 1064 } 1065 } else { 1066 /* 1067 * A header isn't present; attempt to write it. 1068 */ 1069 if (sf_write_header(p, f, linktype, p->snapshot) == -1) { 1070 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1071 errno, "Can't write to %s", fname); 1072 (void)fclose(f); 1073 return (NULL); 1074 } 1075 } 1076 1077 /* 1078 * Start writing at the end of the file. 1079 * 1080 * XXX - this shouldn't be necessary, given that we're opening 1081 * the file in append mode, and ISO C specifies that all writes 1082 * are done at the end of the file in that mode. 1083 */ 1084 if (fseek(f, 0, SEEK_END) == -1) { 1085 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1086 errno, "Can't seek to the end of %s", fname); 1087 (void)fclose(f); 1088 return (NULL); 1089 } 1090 return ((pcap_dumper_t *)f); 1091 } 1092 1093 FILE * 1094 pcap_dump_file(pcap_dumper_t *p) 1095 { 1096 return ((FILE *)p); 1097 } 1098 1099 long 1100 pcap_dump_ftell(pcap_dumper_t *p) 1101 { 1102 return (ftell((FILE *)p)); 1103 } 1104 1105 #if defined(HAVE_FSEEKO) 1106 /* 1107 * We have fseeko(), so we have ftello(). 1108 * If we have large file support (files larger than 2^31-1 bytes), 1109 * ftello() will give us a current file position with more than 32 1110 * bits. 1111 */ 1112 int64_t 1113 pcap_dump_ftell64(pcap_dumper_t *p) 1114 { 1115 return (ftello((FILE *)p)); 1116 } 1117 #elif defined(_MSC_VER) 1118 /* 1119 * We have Visual Studio; we support only 2005 and later, so we have 1120 * _ftelli64(). 1121 */ 1122 int64_t 1123 pcap_dump_ftell64(pcap_dumper_t *p) 1124 { 1125 return (_ftelli64((FILE *)p)); 1126 } 1127 #else 1128 /* 1129 * We don't have ftello() or _ftelli64(), so fall back on ftell(). 1130 * Either long is 64 bits, in which case ftell() should suffice, 1131 * or this is probably an older 32-bit UN*X without large file 1132 * support, which means you'll probably get errors trying to 1133 * write files > 2^31-1, so it won't matter anyway. 1134 * 1135 * XXX - what about MinGW? 1136 */ 1137 int64_t 1138 pcap_dump_ftell64(pcap_dumper_t *p) 1139 { 1140 return (ftell((FILE *)p)); 1141 } 1142 #endif 1143 1144 int 1145 pcap_dump_flush(pcap_dumper_t *p) 1146 { 1147 1148 if (fflush((FILE *)p) == EOF) 1149 return (-1); 1150 else 1151 return (0); 1152 } 1153 1154 void 1155 pcap_dump_close(pcap_dumper_t *p) 1156 { 1157 1158 #ifdef notyet 1159 if (ferror((FILE *)p)) 1160 return-an-error; 1161 /* XXX should check return from fclose() too */ 1162 #endif 1163 (void)fclose((FILE *)p); 1164 } 1165