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 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 198 "truncated dump file; tried to read %" PRIsize " file header bytes, only got %" PRIsize, 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 pcap_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 pcap_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, sizeof (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->tzoff = hdr.thiszone; 253 p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype)); 254 p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype); 255 p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen); 256 257 p->next_packet_op = pcap_next_packet; 258 259 ps = p->priv; 260 261 p->opt.tstamp_precision = precision; 262 263 /* 264 * Will we need to scale the timestamps to match what the 265 * user wants? 266 */ 267 switch (precision) { 268 269 case PCAP_TSTAMP_PRECISION_MICRO: 270 if (magic_int == NSEC_TCPDUMP_MAGIC) { 271 /* 272 * The file has nanoseconds, the user 273 * wants microseconds; scale the 274 * precision down. 275 */ 276 ps->scale_type = SCALE_DOWN; 277 } else { 278 /* 279 * The file has microseconds, the 280 * user wants microseconds; nothing to do. 281 */ 282 ps->scale_type = PASS_THROUGH; 283 } 284 break; 285 286 case PCAP_TSTAMP_PRECISION_NANO: 287 if (magic_int == NSEC_TCPDUMP_MAGIC) { 288 /* 289 * The file has nanoseconds, the 290 * user wants nanoseconds; nothing to do. 291 */ 292 ps->scale_type = PASS_THROUGH; 293 } else { 294 /* 295 * The file has microoseconds, the user 296 * wants nanoseconds; scale the 297 * precision up. 298 */ 299 ps->scale_type = SCALE_UP; 300 } 301 break; 302 303 default: 304 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 305 "unknown time stamp resolution %u", precision); 306 free(p); 307 *err = 1; 308 return (NULL); 309 } 310 311 /* 312 * We interchanged the caplen and len fields at version 2.3, 313 * in order to match the bpf header layout. But unfortunately 314 * some files were written with version 2.3 in their headers 315 * but without the interchanged fields. 316 * 317 * In addition, DG/UX tcpdump writes out files with a version 318 * number of 543.0, and with the caplen and len fields in the 319 * pre-2.3 order. 320 */ 321 switch (hdr.version_major) { 322 323 case 2: 324 if (hdr.version_minor < 3) 325 ps->lengths_swapped = SWAPPED; 326 else if (hdr.version_minor == 3) 327 ps->lengths_swapped = MAYBE_SWAPPED; 328 else 329 ps->lengths_swapped = NOT_SWAPPED; 330 break; 331 332 case 543: 333 ps->lengths_swapped = SWAPPED; 334 break; 335 336 default: 337 ps->lengths_swapped = NOT_SWAPPED; 338 break; 339 } 340 341 if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) { 342 /* 343 * XXX - the patch that's in some versions of libpcap 344 * changes the packet header but not the magic number, 345 * and some other versions with this magic number have 346 * some extra debugging information in the packet header; 347 * we'd have to use some hacks^H^H^H^H^Hheuristics to 348 * detect those variants. 349 * 350 * Ethereal does that, but it does so by trying to read 351 * the first two packets of the file with each of the 352 * record header formats. That currently means it seeks 353 * backwards and retries the reads, which doesn't work 354 * on pipes. We want to be able to read from a pipe, so 355 * that strategy won't work; we'd have to buffer some 356 * data ourselves and read from that buffer in order to 357 * make that work. 358 */ 359 ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 360 361 if (p->linktype == DLT_EN10MB) { 362 /* 363 * This capture might have been done in raw mode 364 * or cooked mode. 365 * 366 * If it was done in cooked mode, p->snapshot was 367 * passed to recvfrom() as the buffer size, meaning 368 * that the most packet data that would be copied 369 * would be p->snapshot. However, a faked Ethernet 370 * header would then have been added to it, so the 371 * most data that would be in a packet in the file 372 * would be p->snapshot + 14. 373 * 374 * We can't easily tell whether the capture was done 375 * in raw mode or cooked mode, so we'll assume it was 376 * cooked mode, and add 14 to the snapshot length. 377 * That means that, for a raw capture, the snapshot 378 * length will be misleading if you use it to figure 379 * out why a capture doesn't have all the packet data, 380 * but there's not much we can do to avoid that. 381 * 382 * But don't grow the snapshot length past the 383 * maximum value of an int. 384 */ 385 if (p->snapshot <= INT_MAX - 14) 386 p->snapshot += 14; 387 else 388 p->snapshot = INT_MAX; 389 } 390 } else 391 ps->hdrsize = sizeof(struct pcap_sf_pkthdr); 392 393 /* 394 * Allocate a buffer for the packet data. 395 * Choose the minimum of the file's snapshot length and 2K bytes; 396 * that should be enough for most network packets - we'll grow it 397 * if necessary. That way, we don't allocate a huge chunk of 398 * memory just because there's a huge snapshot length, as the 399 * snapshot length might be larger than the size of the largest 400 * packet. 401 */ 402 p->bufsize = p->snapshot; 403 if (p->bufsize > 2048) 404 p->bufsize = 2048; 405 p->buffer = malloc(p->bufsize); 406 if (p->buffer == NULL) { 407 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 408 free(p); 409 *err = 1; 410 return (NULL); 411 } 412 413 p->cleanup_op = sf_cleanup; 414 415 return (p); 416 } 417 418 /* 419 * Grow the packet buffer to the specified size. 420 */ 421 static int 422 grow_buffer(pcap_t *p, u_int bufsize) 423 { 424 void *bigger_buffer; 425 426 bigger_buffer = realloc(p->buffer, bufsize); 427 if (bigger_buffer == NULL) { 428 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 429 return (0); 430 } 431 p->buffer = bigger_buffer; 432 p->bufsize = bufsize; 433 return (1); 434 } 435 436 /* 437 * Read and return the next packet from the savefile. Return the header 438 * in hdr and a pointer to the contents in data. Return 0 on success, 1 439 * if there were no more packets, and -1 on an error. 440 */ 441 static int 442 pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) 443 { 444 struct pcap_sf *ps = p->priv; 445 struct pcap_sf_patched_pkthdr sf_hdr; 446 FILE *fp = p->rfile; 447 size_t amt_read; 448 bpf_u_int32 t; 449 450 /* 451 * Read the packet header; the structure we use as a buffer 452 * is the longer structure for files generated by the patched 453 * libpcap, but if the file has the magic number for an 454 * unpatched libpcap we only read as many bytes as the regular 455 * header has. 456 */ 457 amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp); 458 if (amt_read != ps->hdrsize) { 459 if (ferror(fp)) { 460 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 461 errno, "error reading dump file"); 462 return (-1); 463 } else { 464 if (amt_read != 0) { 465 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 466 "truncated dump file; tried to read %" PRIsize " header bytes, only got %" PRIsize, 467 ps->hdrsize, amt_read); 468 return (-1); 469 } 470 /* EOF */ 471 return (1); 472 } 473 } 474 475 if (p->swapped) { 476 /* these were written in opposite byte order */ 477 hdr->caplen = SWAPLONG(sf_hdr.caplen); 478 hdr->len = SWAPLONG(sf_hdr.len); 479 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 480 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 481 } else { 482 hdr->caplen = sf_hdr.caplen; 483 hdr->len = sf_hdr.len; 484 hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 485 hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 486 } 487 488 switch (ps->scale_type) { 489 490 case PASS_THROUGH: 491 /* 492 * Just pass the time stamp through. 493 */ 494 break; 495 496 case SCALE_UP: 497 /* 498 * File has microseconds, user wants nanoseconds; convert 499 * it. 500 */ 501 hdr->ts.tv_usec = hdr->ts.tv_usec * 1000; 502 break; 503 504 case SCALE_DOWN: 505 /* 506 * File has nanoseconds, user wants microseconds; convert 507 * it. 508 */ 509 hdr->ts.tv_usec = hdr->ts.tv_usec / 1000; 510 break; 511 } 512 513 /* Swap the caplen and len fields, if necessary. */ 514 switch (ps->lengths_swapped) { 515 516 case NOT_SWAPPED: 517 break; 518 519 case MAYBE_SWAPPED: 520 if (hdr->caplen <= hdr->len) { 521 /* 522 * The captured length is <= the actual length, 523 * so presumably they weren't swapped. 524 */ 525 break; 526 } 527 /* FALLTHROUGH */ 528 529 case SWAPPED: 530 t = hdr->caplen; 531 hdr->caplen = hdr->len; 532 hdr->len = t; 533 break; 534 } 535 536 /* 537 * Is the packet bigger than we consider sane? 538 */ 539 if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) { 540 /* 541 * Yes. This may be a damaged or fuzzed file. 542 * 543 * Is it bigger than the snapshot length? 544 * (We don't treat that as an error if it's not 545 * bigger than the maximum we consider sane; see 546 * below.) 547 */ 548 if (hdr->caplen > (bpf_u_int32)p->snapshot) { 549 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 550 "invalid packet capture length %u, bigger than " 551 "snaplen of %d", hdr->caplen, p->snapshot); 552 } else { 553 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 554 "invalid packet capture length %u, bigger than " 555 "maximum of %u", hdr->caplen, 556 max_snaplen_for_dlt(p->linktype)); 557 } 558 return (-1); 559 } 560 561 if (hdr->caplen > (bpf_u_int32)p->snapshot) { 562 /* 563 * The packet is bigger than the snapshot length 564 * for this file. 565 * 566 * This can happen due to Solaris 2.3 systems tripping 567 * over the BUFMOD problem and not setting the snapshot 568 * length correctly in the savefile header. 569 * 570 * libpcap 0.4 and later on Solaris 2.3 should set the 571 * snapshot length correctly in the pcap file header, 572 * even though they don't set a snapshot length in bufmod 573 * (the buggy bufmod chops off the *beginning* of the 574 * packet if a snapshot length is specified); they should 575 * also reduce the captured length, as supplied to the 576 * per-packet callback, to the snapshot length if it's 577 * greater than the snapshot length, so the code using 578 * libpcap should see the packet cut off at the snapshot 579 * length, even though the full packet is copied up to 580 * userland. 581 * 582 * However, perhaps some versions of libpcap failed to 583 * set the snapshot length currectly in the file header 584 * or the per-packet header, or perhaps this is a 585 * corrupted safefile or a savefile built/modified by a 586 * fuzz tester, so we check anyway. We grow the buffer 587 * to be big enough for the snapshot length, read up 588 * to the snapshot length, discard the rest of the 589 * packet, and report the snapshot length as the captured 590 * length; we don't want to hand our caller a packet 591 * bigger than the snapshot length, because they might 592 * be assuming they'll never be handed such a packet, 593 * and might copy the packet into a snapshot-length- 594 * sized buffer, assuming it'll fit. 595 */ 596 size_t bytes_to_discard; 597 size_t bytes_to_read, bytes_read; 598 char discard_buf[4096]; 599 600 if (hdr->caplen > p->bufsize) { 601 /* 602 * Grow the buffer to the snapshot length. 603 */ 604 if (!grow_buffer(p, p->snapshot)) 605 return (-1); 606 } 607 608 /* 609 * Read the first p->snapshot bytes into the buffer. 610 */ 611 amt_read = fread(p->buffer, 1, p->snapshot, fp); 612 if (amt_read != (bpf_u_int32)p->snapshot) { 613 if (ferror(fp)) { 614 pcap_fmt_errmsg_for_errno(p->errbuf, 615 PCAP_ERRBUF_SIZE, errno, 616 "error reading dump file"); 617 } else { 618 /* 619 * Yes, this uses hdr->caplen; technically, 620 * it's true, because we would try to read 621 * and discard the rest of those bytes, and 622 * that would fail because we got EOF before 623 * the read finished. 624 */ 625 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 626 "truncated dump file; tried to read %u captured bytes, only got %" PRIsize, 627 p->snapshot, amt_read); 628 } 629 return (-1); 630 } 631 632 /* 633 * Now read and discard what's left. 634 */ 635 bytes_to_discard = hdr->caplen - p->snapshot; 636 bytes_read = amt_read; 637 while (bytes_to_discard != 0) { 638 bytes_to_read = bytes_to_discard; 639 if (bytes_to_read > sizeof (discard_buf)) 640 bytes_to_read = sizeof (discard_buf); 641 amt_read = fread(discard_buf, 1, bytes_to_read, fp); 642 bytes_read += amt_read; 643 if (amt_read != bytes_to_read) { 644 if (ferror(fp)) { 645 pcap_fmt_errmsg_for_errno(p->errbuf, 646 PCAP_ERRBUF_SIZE, errno, 647 "error reading dump file"); 648 } else { 649 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 650 "truncated dump file; tried to read %u captured bytes, only got %" PRIsize, 651 hdr->caplen, bytes_read); 652 } 653 return (-1); 654 } 655 bytes_to_discard -= amt_read; 656 } 657 658 /* 659 * Adjust caplen accordingly, so we don't get confused later 660 * as to how many bytes we have to play with. 661 */ 662 hdr->caplen = p->snapshot; 663 } else { 664 /* 665 * The packet is within the snapshot length for this file. 666 */ 667 if (hdr->caplen > p->bufsize) { 668 /* 669 * Grow the buffer to the next power of 2, or 670 * the snaplen, whichever is lower. 671 */ 672 u_int new_bufsize; 673 674 new_bufsize = hdr->caplen; 675 /* 676 * http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 677 */ 678 new_bufsize--; 679 new_bufsize |= new_bufsize >> 1; 680 new_bufsize |= new_bufsize >> 2; 681 new_bufsize |= new_bufsize >> 4; 682 new_bufsize |= new_bufsize >> 8; 683 new_bufsize |= new_bufsize >> 16; 684 new_bufsize++; 685 686 if (new_bufsize > (u_int)p->snapshot) 687 new_bufsize = p->snapshot; 688 689 if (!grow_buffer(p, new_bufsize)) 690 return (-1); 691 } 692 693 /* read the packet itself */ 694 amt_read = fread(p->buffer, 1, hdr->caplen, fp); 695 if (amt_read != hdr->caplen) { 696 if (ferror(fp)) { 697 pcap_fmt_errmsg_for_errno(p->errbuf, 698 PCAP_ERRBUF_SIZE, errno, 699 "error reading dump file"); 700 } else { 701 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 702 "truncated dump file; tried to read %u captured bytes, only got %" PRIsize, 703 hdr->caplen, amt_read); 704 } 705 return (-1); 706 } 707 } 708 *data = p->buffer; 709 710 if (p->swapped) 711 swap_pseudo_headers(p->linktype, hdr, *data); 712 713 return (0); 714 } 715 716 static int 717 sf_write_header(pcap_t *p, FILE *fp, int linktype, int thiszone, int snaplen) 718 { 719 struct pcap_file_header hdr; 720 721 hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC; 722 hdr.version_major = PCAP_VERSION_MAJOR; 723 hdr.version_minor = PCAP_VERSION_MINOR; 724 725 hdr.thiszone = thiszone; 726 hdr.snaplen = snaplen; 727 hdr.sigfigs = 0; 728 hdr.linktype = linktype; 729 730 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 731 return (-1); 732 733 return (0); 734 } 735 736 /* 737 * Output a packet to the initialized dump file. 738 */ 739 void 740 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 741 { 742 register FILE *f; 743 struct pcap_sf_pkthdr sf_hdr; 744 745 f = (FILE *)user; 746 sf_hdr.ts.tv_sec = h->ts.tv_sec; 747 sf_hdr.ts.tv_usec = h->ts.tv_usec; 748 sf_hdr.caplen = h->caplen; 749 sf_hdr.len = h->len; 750 /* XXX we should check the return status */ 751 (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 752 (void)fwrite(sp, h->caplen, 1, f); 753 } 754 755 static pcap_dumper_t * 756 pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname) 757 { 758 759 #if defined(_WIN32) || defined(MSDOS) 760 /* 761 * If we're writing to the standard output, put it in binary 762 * mode, as savefiles are binary files. 763 * 764 * Otherwise, we turn off buffering. 765 * XXX - why? And why not on the standard output? 766 */ 767 if (f == stdout) 768 SET_BINMODE(f); 769 else 770 setvbuf(f, NULL, _IONBF, 0); 771 #endif 772 if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) { 773 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 774 errno, "Can't write to %s", fname); 775 if (f != stdout) 776 (void)fclose(f); 777 return (NULL); 778 } 779 return ((pcap_dumper_t *)f); 780 } 781 782 /* 783 * Initialize so that sf_write() will output to the file named 'fname'. 784 */ 785 pcap_dumper_t * 786 pcap_dump_open(pcap_t *p, const char *fname) 787 { 788 FILE *f; 789 int linktype; 790 791 /* 792 * If this pcap_t hasn't been activated, it doesn't have a 793 * link-layer type, so we can't use it. 794 */ 795 if (!p->activated) { 796 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 797 "%s: not-yet-activated pcap_t passed to pcap_dump_open", 798 fname); 799 return (NULL); 800 } 801 linktype = dlt_to_linktype(p->linktype); 802 if (linktype == -1) { 803 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 804 "%s: link-layer type %d isn't supported in savefiles", 805 fname, p->linktype); 806 return (NULL); 807 } 808 linktype |= p->linktype_ext; 809 810 if (fname == NULL) { 811 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 812 "A null pointer was supplied as the file name"); 813 return NULL; 814 } 815 if (fname[0] == '-' && fname[1] == '\0') { 816 f = stdout; 817 fname = "standard output"; 818 } else { 819 /* 820 * "b" is supported as of C90, so *all* UN*Xes should 821 * support it, even though it does nothing. It's 822 * required on Windows, as the file is a binary file 823 * and must be written in binary mode. 824 */ 825 f = fopen(fname, "wb"); 826 if (f == NULL) { 827 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 828 errno, "%s", fname); 829 return (NULL); 830 } 831 } 832 return (pcap_setup_dump(p, linktype, f, fname)); 833 } 834 835 #ifdef _WIN32 836 /* 837 * Initialize so that sf_write() will output to a stream wrapping the given raw 838 * OS file HANDLE. 839 */ 840 pcap_dumper_t * 841 pcap_dump_hopen(pcap_t *p, intptr_t osfd) 842 { 843 int fd; 844 FILE *file; 845 846 fd = _open_osfhandle(osfd, _O_APPEND); 847 if (fd < 0) { 848 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 849 errno, "_open_osfhandle"); 850 return NULL; 851 } 852 853 file = _fdopen(fd, "wb"); 854 if (file == NULL) { 855 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 856 errno, "_fdopen"); 857 _close(fd); 858 return NULL; 859 } 860 861 return pcap_dump_fopen(p, file); 862 } 863 #endif /* _WIN32 */ 864 865 /* 866 * Initialize so that sf_write() will output to the given stream. 867 */ 868 #ifdef _WIN32 869 static 870 #endif /* _WIN32 */ 871 pcap_dumper_t * 872 pcap_dump_fopen(pcap_t *p, FILE *f) 873 { 874 int linktype; 875 876 linktype = dlt_to_linktype(p->linktype); 877 if (linktype == -1) { 878 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 879 "stream: link-layer type %d isn't supported in savefiles", 880 p->linktype); 881 return (NULL); 882 } 883 linktype |= p->linktype_ext; 884 885 return (pcap_setup_dump(p, linktype, f, "stream")); 886 } 887 888 pcap_dumper_t * 889 pcap_dump_open_append(pcap_t *p, const char *fname) 890 { 891 FILE *f; 892 int linktype; 893 size_t amt_read; 894 struct pcap_file_header ph; 895 896 linktype = dlt_to_linktype(p->linktype); 897 if (linktype == -1) { 898 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 899 "%s: link-layer type %d isn't supported in savefiles", 900 fname, linktype); 901 return (NULL); 902 } 903 904 if (fname == NULL) { 905 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 906 "A null pointer was supplied as the file name"); 907 return NULL; 908 } 909 if (fname[0] == '-' && fname[1] == '\0') 910 return (pcap_setup_dump(p, linktype, stdout, "standard output")); 911 912 /* 913 * "a" will cause the file *not* to be truncated if it exists 914 * but will cause it to be created if it doesn't. It will 915 * also cause all writes to be done at the end of the file, 916 * but will allow reads to be done anywhere in the file. This 917 * is what we need, because we need to read from the beginning 918 * of the file to see if it already has a header and packets 919 * or if it doesn't. 920 * 921 * "b" is supported as of C90, so *all* UN*Xes should support it, 922 * even though it does nothing. It's required on Windows, as the 923 * file is a binary file and must be read in binary mode. 924 */ 925 f = fopen(fname, "ab+"); 926 if (f == NULL) { 927 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 928 errno, "%s", fname); 929 return (NULL); 930 } 931 932 /* 933 * Try to read a pcap header. 934 * 935 * We do not assume that the file will be positioned at the 936 * beginning immediately after we've opened it - we seek to 937 * the beginning. ISO C says it's implementation-defined 938 * whether the file position indicator is at the beginning 939 * or the end of the file after an append-mode open, and 940 * it wasn't obvious from the Single UNIX Specification 941 * or the Microsoft documentation how that works on SUS- 942 * compliant systems or on Windows. 943 */ 944 if (fseek(f, 0, SEEK_SET) == -1) { 945 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 946 errno, "Can't seek to the beginning of %s", fname); 947 (void)fclose(f); 948 return (NULL); 949 } 950 amt_read = fread(&ph, 1, sizeof (ph), f); 951 if (amt_read != sizeof (ph)) { 952 if (ferror(f)) { 953 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 954 errno, "%s", fname); 955 (void)fclose(f); 956 return (NULL); 957 } else if (feof(f) && amt_read > 0) { 958 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 959 "%s: truncated pcap file header", fname); 960 (void)fclose(f); 961 return (NULL); 962 } 963 } 964 965 #if defined(_WIN32) || defined(MSDOS) 966 /* 967 * We turn off buffering. 968 * XXX - why? And why not on the standard output? 969 */ 970 setvbuf(f, NULL, _IONBF, 0); 971 #endif 972 973 /* 974 * If a header is already present and: 975 * 976 * it's not for a pcap file of the appropriate resolution 977 * and the right byte order for this machine; 978 * 979 * the link-layer header types don't match; 980 * 981 * the snapshot lengths don't match; 982 * 983 * return an error. 984 */ 985 if (amt_read > 0) { 986 /* 987 * A header is already present. 988 * Do the checks. 989 */ 990 switch (ph.magic) { 991 992 case TCPDUMP_MAGIC: 993 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) { 994 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 995 "%s: different time stamp precision, cannot append to file", fname); 996 (void)fclose(f); 997 return (NULL); 998 } 999 break; 1000 1001 case NSEC_TCPDUMP_MAGIC: 1002 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) { 1003 pcap_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 SWAPLONG(TCPDUMP_MAGIC): 1011 case SWAPLONG(NSEC_TCPDUMP_MAGIC): 1012 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1013 "%s: different byte order, cannot append to file", fname); 1014 (void)fclose(f); 1015 return (NULL); 1016 1017 case KUZNETZOV_TCPDUMP_MAGIC: 1018 case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC): 1019 case NAVTEL_TCPDUMP_MAGIC: 1020 case SWAPLONG(NAVTEL_TCPDUMP_MAGIC): 1021 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1022 "%s: not a pcap file to which we can append", fname); 1023 (void)fclose(f); 1024 return (NULL); 1025 1026 default: 1027 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1028 "%s: not a pcap file", fname); 1029 (void)fclose(f); 1030 return (NULL); 1031 } 1032 1033 /* 1034 * Good version? 1035 */ 1036 if (ph.version_major != PCAP_VERSION_MAJOR || 1037 ph.version_minor != PCAP_VERSION_MINOR) { 1038 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1039 "%s: version is %u.%u, cannot append to file", fname, 1040 ph.version_major, ph.version_minor); 1041 (void)fclose(f); 1042 return (NULL); 1043 } 1044 if ((bpf_u_int32)linktype != ph.linktype) { 1045 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1046 "%s: different linktype, cannot append to file", fname); 1047 (void)fclose(f); 1048 return (NULL); 1049 } 1050 if ((bpf_u_int32)p->snapshot != ph.snaplen) { 1051 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1052 "%s: different snaplen, cannot append to file", fname); 1053 (void)fclose(f); 1054 return (NULL); 1055 } 1056 } else { 1057 /* 1058 * A header isn't present; attempt to write it. 1059 */ 1060 if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) { 1061 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1062 errno, "Can't write to %s", fname); 1063 (void)fclose(f); 1064 return (NULL); 1065 } 1066 } 1067 1068 /* 1069 * Start writing at the end of the file. 1070 * 1071 * XXX - this shouldn't be necessary, given that we're opening 1072 * the file in append mode, and ISO C specifies that all writes 1073 * are done at the end of the file in that mode. 1074 */ 1075 if (fseek(f, 0, SEEK_END) == -1) { 1076 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1077 errno, "Can't seek to the end of %s", fname); 1078 (void)fclose(f); 1079 return (NULL); 1080 } 1081 return ((pcap_dumper_t *)f); 1082 } 1083 1084 FILE * 1085 pcap_dump_file(pcap_dumper_t *p) 1086 { 1087 return ((FILE *)p); 1088 } 1089 1090 long 1091 pcap_dump_ftell(pcap_dumper_t *p) 1092 { 1093 return (ftell((FILE *)p)); 1094 } 1095 1096 #if defined(HAVE_FSEEKO) 1097 /* 1098 * We have fseeko(), so we have ftello(). 1099 * If we have large file support (files larger than 2^31-1 bytes), 1100 * ftello() will give us a current file position with more than 32 1101 * bits. 1102 */ 1103 int64_t 1104 pcap_dump_ftell64(pcap_dumper_t *p) 1105 { 1106 return (ftello((FILE *)p)); 1107 } 1108 #elif defined(_MSC_VER) 1109 /* 1110 * We have Visual Studio; we support only 2005 and later, so we have 1111 * _ftelli64(). 1112 */ 1113 int64_t 1114 pcap_dump_ftell64(pcap_dumper_t *p) 1115 { 1116 return (_ftelli64((FILE *)p)); 1117 } 1118 #else 1119 /* 1120 * We don't have ftello() or _ftelli64(), so fall back on ftell(). 1121 * Either long is 64 bits, in which case ftell() should suffice, 1122 * or this is probably an older 32-bit UN*X without large file 1123 * support, which means you'll probably get errors trying to 1124 * write files > 2^31-1, so it won't matter anyway. 1125 * 1126 * XXX - what about MinGW? 1127 */ 1128 int64_t 1129 pcap_dump_ftell64(pcap_dumper_t *p) 1130 { 1131 return (ftell((FILE *)p)); 1132 } 1133 #endif 1134 1135 int 1136 pcap_dump_flush(pcap_dumper_t *p) 1137 { 1138 1139 if (fflush((FILE *)p) == EOF) 1140 return (-1); 1141 else 1142 return (0); 1143 } 1144 1145 void 1146 pcap_dump_close(pcap_dumper_t *p) 1147 { 1148 1149 #ifdef notyet 1150 if (ferror((FILE *)p)) 1151 return-an-error; 1152 /* XXX should check return from fclose() too */ 1153 #endif 1154 (void)fclose((FILE *)p); 1155 } 1156