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