Changeset 8f5d454
- Timestamp:
- 07/02/18 12:01:08 (3 years ago)
- Branches:
- cachetimestamps, develop, master, rc-4.0.4, ringdecrementfix, ringperformance
- Children:
- 47d64ce, c7a320a
- Parents:
- c95ef4a (diff), e9da777 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/format_pcapng.c
r32ee9b2 re9da777 173 173 }; 174 174 175 typedef struct pcapng_peeker pcapng_hdr_t; 176 175 177 176 178 #define DATA(x) ((struct pcapng_format_data_t *)((x)->format_data)) … … 287 289 288 290 static char *pcapng_parse_next_option(libtrace_t *libtrace, char **pktbuf, 289 uint16_t *code, uint16_t *length ) {291 uint16_t *code, uint16_t *length, pcapng_hdr_t *blockhdr) { 290 292 291 293 struct pcapng_optheader *opthdr = (struct pcapng_optheader *)*pktbuf; 292 294 int to_skip; 293 295 int padding = 0; 296 char *eob; //end of block 294 297 char *optval; 298 if (DATA(libtrace)->byteswapped) { 299 eob = ((char *) blockhdr) + byteswap32(blockhdr->blocklen); 300 } else { 301 eob = ((char *) blockhdr) + blockhdr->blocklen; 302 } 303 304 assert((char *)blockhdr < *pktbuf); 305 // Check if we have reached the end of the block, +4 for trailing block-size 306 // We cannot assume a endofopt, so we add one 307 if (eob == (*pktbuf) + 4) { 308 *code = 0; 309 *length = 0; 310 return *pktbuf; 311 } 312 // If there is not enough space for another header we've encountered an error 313 if (eob < (*pktbuf) + 4 + sizeof(struct pcapng_optheader)) { 314 return NULL; 315 } 295 316 296 317 if (DATA(libtrace)->byteswapped) { … … 311 332 312 333 to_skip = (*length) + padding; 334 // Check the value we return is within the block length 335 if (eob < optval + to_skip + 4) { 336 return NULL; 337 } 313 338 *pktbuf = optval + to_skip; 314 339 315 340 return optval; 316 }317 318 static inline int skip_block(libtrace_t *libtrace, uint32_t toread) {319 int err;320 321 while (toread > 0) {322 char buf[4096];323 int nextread;324 325 if (toread < 4096) {326 nextread = toread;327 } else {328 nextread = 4096;329 }330 331 err = wandio_read(libtrace->io, buf, nextread);332 if (err < 0) {333 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED,334 "Reading section header options");335 return -1;336 }337 if (err == 0) {338 return 0;339 }340 toread -= err;341 }342 343 return 1;344 345 341 } 346 342 … … 353 349 if (err < 0) { 354 350 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, 355 "Failed to read pcapng interface options");351 "Failed reading pcapng block"); 356 352 return err; 357 353 } … … 363 359 if (err < (int)to_read) { 364 360 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 365 "Incomplete pcapng interface headerblock");361 "Incomplete pcapng block"); 366 362 return -1; 367 363 } … … 454 450 } 455 451 456 if (err < (int)(sizeof( sechdr))) {452 if (err < (int)(sizeof(pcapng_sec_t))) { 457 453 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 458 454 "Incomplete pcapng section header block"); … … 491 487 /* Read all of the options etc. -- we don't need them for now, but 492 488 * we have to skip forward to the next useful header. */ 493 bodyptr = packet->buffer + sizeof(pcapng_sec_t);489 bodyptr = (char *) packet->buffer + sizeof(pcapng_sec_t); 494 490 err = pcapng_read_body(libtrace, bodyptr, to_read); 495 491 if (err <= 0) { … … 507 503 508 504 static int pcapng_read_interface(libtrace_t *libtrace, 509 libtrace_packet_t *packet, uint32_t flags) {505 libtrace_packet_t *packet, uint32_t blocklen, uint32_t flags) { 510 506 511 507 pcapng_int_t *inthdr; 512 int err;513 uint32_t to_read;514 508 pcapng_interface_t *newint; 515 509 uint16_t optcode, optlen; … … 517 511 char *bodyptr = NULL; 518 512 519 err = wandio_read(libtrace->io, packet->buffer, sizeof(pcapng_int_t)); 520 521 if (err < 0) { 522 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, 523 "Reading pcapng interface header block"); 524 return -1; 525 } 526 527 if (err == 0) { 528 return 0; 529 } 530 531 if (err < (int)sizeof(inthdr)) { 513 if (blocklen < sizeof(pcapng_int_t) + 4) { 532 514 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 533 515 "Incomplete pcapng interface header block"); … … 552 534 newint->snaplen = byteswap32(inthdr->snaplen); 553 535 newint->linktype = byteswap16(inthdr->linktype); 554 to_read = byteswap32(inthdr->blocklen) - sizeof(pcapng_int_t);555 536 } else { 556 537 assert(inthdr->blocktype == PCAPNG_INTERFACE_TYPE); 557 538 newint->snaplen = inthdr->snaplen; 558 539 newint->linktype = inthdr->linktype; 559 to_read = inthdr->blocklen - sizeof(pcapng_int_t);560 540 } 561 541 … … 566 546 DATA(libtrace)->allocatedinterfaces * sizeof( 567 547 pcapng_interface_t *)); 568 569 /* Could memset the new memory to zero, if required */ 548 memset(&DATA(libtrace)->interfaces[DATA(libtrace)->nextintid], 0, sizeof(void *) * 10); 570 549 } 571 550 … … 573 552 DATA(libtrace)->nextintid += 1; 574 553 575 bodyptr = packet->buffer + sizeof(pcapng_int_t); 576 err = pcapng_read_body(libtrace, bodyptr, to_read); 577 if (err <= 0) { 578 return err; 579 } 554 bodyptr = (char *) packet->buffer + sizeof(pcapng_int_t); 580 555 581 556 packet->type = TRACE_RT_PCAPNG_META; … … 588 563 do { 589 564 optval = pcapng_parse_next_option(libtrace, &bodyptr, 590 &optcode, &optlen );565 &optcode, &optlen, (pcapng_hdr_t *) packet->buffer); 591 566 if (optval == NULL) { 592 567 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, … … 608 583 } while (optcode != 0); 609 584 610 return 1;585 return (int) blocklen; 611 586 612 587 } 613 588 614 589 static int pcapng_read_nrb(libtrace_t *libtrace, libtrace_packet_t *packet, 615 uint32_t flags) {590 uint32_t blocklen, uint32_t flags) { 616 591 617 592 /* Just read the NR records and pass them off to the caller. If … … 620 595 */ 621 596 pcapng_nrb_t *hdr = NULL; 622 int err; 623 uint32_t to_read; 624 char *bodyptr; 625 626 err = wandio_read(libtrace->io, packet->buffer, sizeof(pcapng_nrb_t)); 627 628 if (err < 0) { 629 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, "reading pcapng name resolution block"); 630 return -1; 631 } 632 633 if (err == 0) { 634 return 0; 635 } 636 637 if (err < (int)sizeof(pcapng_nrb_t)) { 597 598 if (blocklen < sizeof(pcapng_nrb_t) + 4) { 638 599 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 639 600 "Incomplete pcapng name resolution block"); … … 646 607 if (DATA(libtrace)->byteswapped) { 647 608 assert(byteswap32(hdr->blocktype) == PCAPNG_NAME_RESOLUTION_TYPE); 648 to_read = byteswap32(hdr->blocklen) - sizeof(pcapng_nrb_t);649 609 } else { 650 610 assert(hdr->blocktype == PCAPNG_NAME_RESOLUTION_TYPE); 651 to_read = hdr->blocklen - sizeof(pcapng_nrb_t);652 }653 654 bodyptr = packet->buffer + sizeof(pcapng_nrb_t);655 err = pcapng_read_body(libtrace, bodyptr, to_read);656 if (err <= 0) {657 return err;658 611 } 659 612 … … 664 617 } 665 618 666 return sizeof(pcapng_nrb_t) + to_read;619 return (int) blocklen; 667 620 668 621 } 669 622 670 623 static int pcapng_read_custom(libtrace_t *libtrace, libtrace_packet_t *packet, 671 uint32_t flags) {624 uint32_t blocklen, uint32_t flags) { 672 625 673 626 /* Just read the custom records and pass them off to the caller. If … … 676 629 */ 677 630 pcapng_custom_t *hdr = NULL; 678 int err; 679 uint32_t to_read; 680 char *bodyptr; 681 682 err = wandio_read(libtrace->io, packet->buffer, sizeof(pcapng_custom_t)); 683 684 if (err < 0) { 685 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, "reading pcapng custom block"); 686 return -1; 687 } 688 689 if (err == 0) { 690 return 0; 691 } 692 693 if (err < (int)sizeof(pcapng_custom_t)) { 631 632 if (blocklen < sizeof(pcapng_custom_t) + 4) { 694 633 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 695 634 "Incomplete pcapng custom block"); … … 703 642 assert(byteswap32(hdr->blocktype) == PCAPNG_CUSTOM_TYPE || 704 643 byteswap32(hdr->blocktype) == PCAPNG_CUSTOM_NONCOPY_TYPE); 705 to_read = byteswap32(hdr->blocklen) - sizeof(pcapng_custom_t); 706 } else { 707 assert(hdr->blocktype == PCAPNG_NAME_RESOLUTION_TYPE || 644 } else { 645 assert(hdr->blocktype == PCAPNG_CUSTOM_TYPE || 708 646 hdr->blocktype == PCAPNG_CUSTOM_NONCOPY_TYPE); 709 to_read = hdr->blocklen - sizeof(pcapng_custom_t);710 }711 712 bodyptr = packet->buffer + sizeof(pcapng_custom_t);713 err = pcapng_read_body(libtrace, bodyptr, to_read);714 if (err <= 0) {715 return err;716 647 } 717 648 … … 722 653 } 723 654 724 return sizeof(pcapng_custom_t) + to_read;655 return (int) blocklen; 725 656 726 657 } 727 658 728 659 static int pcapng_read_stats(libtrace_t *libtrace, libtrace_packet_t *packet, 729 uint32_t flags) {660 uint32_t blocklen, uint32_t flags) { 730 661 pcapng_stats_t *hdr = NULL; 731 int err;732 uint32_t to_read;733 662 uint32_t ifaceid; 734 663 uint64_t timestamp; … … 738 667 char *bodyptr; 739 668 740 err = wandio_read(libtrace->io, packet->buffer, sizeof(pcapng_stats_t)); 741 742 if (err < 0) { 743 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, "reading pcapng interface stats"); 744 return -1; 745 } 746 747 if (err == 0) { 748 return 0; 749 } 750 751 if (err < (int)sizeof(pcapng_stats_t)) { 669 if (blocklen < sizeof(pcapng_stats_t) + 4) { 752 670 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 753 671 "Incomplete pcapng interface stats header"); … … 760 678 if (DATA(libtrace)->byteswapped) { 761 679 assert(byteswap32(hdr->blocktype) == PCAPNG_INTERFACE_STATS_TYPE); 762 to_read = byteswap32(hdr->blocklen) - sizeof(pcapng_stats_t);763 680 ifaceid = byteswap32(hdr->interfaceid); 764 681 timestamp = ((uint64_t)(byteswap32(hdr->timestamp_high)) << 32) + byteswap32(hdr->timestamp_low); 765 682 } else { 766 683 assert(hdr->blocktype == PCAPNG_INTERFACE_STATS_TYPE); 767 to_read = hdr->blocklen - sizeof(pcapng_stats_t);768 684 ifaceid = hdr->interfaceid; 769 685 timestamp = ((uint64_t)(hdr->timestamp_high) << 32) + 770 686 hdr->timestamp_low; 771 }772 773 bodyptr = packet->buffer + sizeof(pcapng_stats_t);774 err = pcapng_read_body(libtrace, bodyptr, to_read);775 if (err <= 0) {776 return err;777 687 } 778 688 … … 791 701 792 702 if (timestamp < interface->laststats) { 793 return sizeof(pcapng_stats_t) + to_read;703 return (int) blocklen; 794 704 } 795 705 … … 799 709 do { 800 710 optval = pcapng_parse_next_option(packet->trace, &bodyptr, 801 &optcode, &optlen );711 &optcode, &optlen, (pcapng_hdr_t *) packet->buffer); 802 712 if (optval == NULL) { 803 713 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 804 "Failed to read options for pcapng enhanced packet");714 "Failed to read options for pcapng interface stats"); 805 715 return -1; 806 716 } … … 845 755 interface->laststats = timestamp; 846 756 847 return sizeof(pcapng_stats_t) + to_read;757 return (int) blocklen; 848 758 849 759 } 850 760 851 761 static int pcapng_read_simple(libtrace_t *libtrace, libtrace_packet_t *packet, 852 uint32_t flags) { 853 854 int err; 855 uint32_t to_read; 762 uint32_t blocklen, uint32_t flags) { 763 856 764 uint32_t caplen; 857 765 pcapng_spkt_t *hdr = NULL; 858 766 pcapng_interface_t *interface; 859 char *bodyptr; 860 861 err = wandio_read(libtrace->io, packet->buffer, sizeof(pcapng_spkt_t)); 862 863 if (err < 0) { 864 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, "reading pcapng simple packet"); 865 return -1; 866 } 867 868 if (err == 0) { 869 return 0; 870 } 871 872 if (err < (int)sizeof(pcapng_spkt_t)) { 767 768 if (blocklen < sizeof(pcapng_spkt_t) + 4) { 873 769 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 874 770 "Incomplete pcapng simple packet header"); … … 881 777 if (DATA(libtrace)->byteswapped) { 882 778 assert(byteswap32(hdr->blocktype) == PCAPNG_SIMPLE_PACKET_TYPE); 883 to_read = byteswap32(hdr->blocklen) - sizeof(pcapng_spkt_t);884 caplen = to_read - 4;/* account for trailing length field */779 caplen = byteswap32(hdr->blocklen) - sizeof(pcapng_spkt_t) - 4; 780 /* account for trailing length field */ 885 781 } else { 886 782 assert(hdr->blocktype == PCAPNG_SIMPLE_PACKET_TYPE); 887 to_read = hdr->blocklen - sizeof(pcapng_spkt_t); 888 caplen = to_read - 4; /* account for trailing length field */ 889 } 890 891 bodyptr = packet->buffer + sizeof(pcapng_spkt_t); 892 err = pcapng_read_body(libtrace, bodyptr, to_read); 893 if (err <= 0) { 894 return err; 783 caplen = hdr->blocklen - sizeof(pcapng_spkt_t) - 4; 784 /* account for trailing length field */ 895 785 } 896 786 … … 912 802 return -1; 913 803 } 914 return sizeof(pcapng_spkt_t) + to_read;804 return (int) blocklen; 915 805 916 806 } 917 807 918 808 static int pcapng_read_enhanced(libtrace_t *libtrace, libtrace_packet_t *packet, 919 uint32_t flags) {809 uint32_t blocklen, uint32_t flags) { 920 810 pcapng_epkt_t *hdr = NULL; 921 int err;922 uint32_t to_read;923 811 uint32_t caplen; 924 812 uint32_t ifaceid; … … 928 816 char *bodyptr; 929 817 930 err = wandio_read(libtrace->io, packet->buffer, sizeof(pcapng_epkt_t)); 931 932 if (err < 0) { 933 trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, "reading pcapng enhanced packet"); 934 return -1; 935 } 936 937 if (err == 0) { 938 return 0; 939 } 940 941 if (err < (int)sizeof(pcapng_epkt_t)) { 818 if (blocklen < (int)sizeof(pcapng_epkt_t) + 4) { 942 819 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 943 820 "Incomplete pcapng enhanced packet header"); … … 951 828 assert(byteswap32(hdr->blocktype) == PCAPNG_ENHANCED_PACKET_TYPE); 952 829 caplen = byteswap32(hdr->caplen); 953 to_read = byteswap32(hdr->blocklen) - sizeof(pcapng_epkt_t);954 830 ifaceid = byteswap32(hdr->interfaceid); 955 831 } else { 956 832 assert(hdr->blocktype == PCAPNG_ENHANCED_PACKET_TYPE); 957 833 caplen = hdr->caplen; 958 to_read = hdr->blocklen - sizeof(pcapng_epkt_t);959 834 ifaceid = hdr->interfaceid; 960 835 } 961 836 962 bodyptr = packet->buffer + sizeof(pcapng_epkt_t); 963 err = pcapng_read_body(libtrace, bodyptr, to_read); 964 if (err <= 0) { 965 return err; 966 } 837 bodyptr = (char *) packet->buffer + sizeof(pcapng_epkt_t); 967 838 968 839 /* Set packet type based on interface linktype */ … … 985 856 /* Make sure to parse any useful options */ 986 857 if ((caplen % 4) == 0) { 987 bodyptr = packet->payload + caplen; 988 } else { 989 bodyptr = packet->payload + caplen + (4 - (caplen % 4)); 858 bodyptr = (char *) packet->payload + caplen; 859 } else { 860 bodyptr = (char *) packet->payload + caplen + (4 - (caplen % 4)); 861 } 862 // Check the packet caplen actually fits within the block we read 863 if ((char *) packet->buffer + blocklen < bodyptr + 4) { 864 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 865 "Incomplete pcapng enhanced packet header"); 866 return -1; 990 867 } 991 868 992 869 do { 993 870 optval = pcapng_parse_next_option(packet->trace, &bodyptr, 994 &optcode, &optlen );871 &optcode, &optlen, (pcapng_hdr_t *) packet->buffer); 995 872 if (optval == NULL) { 996 873 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, … … 1009 886 1010 887 } while (optcode != 0); 1011 return sizeof(pcapng_epkt_t) + to_read;888 return (int) blocklen; 1012 889 1013 890 } … … 1053 930 } 1054 931 932 // Warning: the byteorder might not be set yet, the section header sets this 1055 933 if (DATA(libtrace)->byteswapped) { 1056 934 btype = byteswap32(peeker.blocktype); 935 to_read = byteswap32(peeker.blocklen); 1057 936 } else { 1058 937 btype = peeker.blocktype; 938 to_read = peeker.blocklen; 939 } 940 941 // Check we won't read off the end of the packet buffer. Assuming corruption. 942 // Exclude the SECTION header, as this is used to identify the byteorder 943 if (to_read > LIBTRACE_PACKET_BUFSIZE && btype != PCAPNG_SECTION_TYPE) { 944 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 945 "Oversized pcapng block found, is the trace corrupted?"); 946 return -1; 947 } 948 if (btype != PCAPNG_SECTION_TYPE) { 949 // Read the entire block, unless it is a section as our byte ordering has 950 // not been set yet. 951 err = pcapng_read_body(libtrace, packet->buffer, to_read); 952 if (err <= 0) { 953 return err; 954 } 955 if (*((uint32_t *)((char *)packet->buffer+to_read-4)) != peeker.blocklen) { 956 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 957 "Mismatched pcapng block sizes found, trace is invalid."); 958 return -1; 959 } 1059 960 } 1060 961 … … 1068 969 /* Interface Header */ 1069 970 case PCAPNG_INTERFACE_TYPE: 1070 err = pcapng_read_interface(libtrace, packet, flags);971 err = pcapng_read_interface(libtrace, packet, to_read, flags); 1071 972 gotpacket = 1; 1072 973 break; … … 1075 976 case PCAPNG_ENHANCED_PACKET_TYPE: 1076 977 err = pcapng_read_enhanced(libtrace, packet, 1077 flags);978 to_read, flags); 1078 979 gotpacket = 1; 1079 980 break; 1080 981 1081 982 case PCAPNG_SIMPLE_PACKET_TYPE: 1082 err = pcapng_read_simple(libtrace, packet, flags);983 err = pcapng_read_simple(libtrace, packet, to_read, flags); 1083 984 gotpacket = 1; 1084 985 break; 1085 986 1086 987 case PCAPNG_INTERFACE_STATS_TYPE: 1087 err = pcapng_read_stats(libtrace, packet, flags);988 err = pcapng_read_stats(libtrace, packet, to_read, flags); 1088 989 gotpacket = 1; 1089 990 break; 1090 991 1091 992 case PCAPNG_NAME_RESOLUTION_TYPE: 1092 err = pcapng_read_nrb(libtrace, packet, flags);993 err = pcapng_read_nrb(libtrace, packet, to_read, flags); 1093 994 gotpacket = 1; 1094 995 break; … … 1096 997 case PCAPNG_CUSTOM_TYPE: 1097 998 case PCAPNG_CUSTOM_NONCOPY_TYPE: 1098 err = pcapng_read_custom(libtrace, packet, flags);999 err = pcapng_read_custom(libtrace, packet, to_read, flags); 1099 1000 gotpacket = 1; 1100 1001 break; … … 1106 1007 /* Everything else -- don't care, skip it */ 1107 1008 default: 1108 if (DATA(libtrace)->byteswapped) {1109 to_read = byteswap32(peeker.blocklen);1110 } else {1111 to_read = peeker.blocklen;1112 }1113 err = skip_block(libtrace, to_read);1114 1009 break; 1115 1010 }
Note: See TracChangeset
for help on using the changeset viewer.