Changeset ebd6275
- Timestamp:
- 01/07/19 10:32:03 (2 years ago)
- Branches:
- develop
- Children:
- 49f8ceb
- Parents:
- d9ca546
- git-author:
- Jacob Van Walraven <jcv9@…> (12/12/18 14:46:30)
- git-committer:
- Jacob Van Walraven <jcv9@…> (01/07/19 10:32:03)
- Location:
- lib
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/format_pcapng.c
rd9ca546 rebd6275 175 175 176 176 /* Section data */ 177 uint16_t sechdr_count; 177 178 bool byteswapped; 178 179 179 180 /* Interface data */ 180 181 uint16_t nextintid; 181 libtrace_ dlt_t lastdlt;182 libtrace_linktype_t lastdlt; 182 183 }; 183 184 … … 220 221 static inline uint32_t pcapng_get_header_type(const libtrace_packet_t *packet) { 221 222 uint32_t *type = (uint32_t *)packet->buffer; 222 if (DATAOUT(packet->trace)->byteswapped) 223 return byteswap32(*type); 224 return *type; 223 224 /* Section blocks, interface blocks, name resolution blocks, stats blocks and 225 * Custom blocks are all of type trace_type_pcapng_meta */ 226 if (trace_get_link_type(packet) == TRACE_TYPE_PCAPNG_META) { 227 if (DATAOUT(packet->trace)->byteswapped) { 228 return byteswap32(*type); 229 } else { 230 return *type; 231 } 232 /* Only check for enhanced or simple packet blocks */ 233 } else { 234 if (DATAOUT(packet->trace)->byteswapped) { 235 *type = byteswap32(*type); 236 } 237 if (*type == 0x00000006 || *type == 0x00000003) { 238 return *type; 239 } 240 } 241 /* not a pcapng header type */ 242 return 0; 225 243 } 226 244 static inline uint32_t pcapng_get_blocklen(const libtrace_packet_t *packet) { … … 347 365 DATAOUT(libtrace)->flag = O_CREAT|O_WRONLY; 348 366 367 DATAOUT(libtrace)->sechdr_count = 0; 349 368 DATAOUT(libtrace)->byteswapped = false; 350 369 351 370 DATAOUT(libtrace)->nextintid = 0; 352 DATAOUT(libtrace)->lastdlt = 0;353 371 354 372 return 0; … … 536 554 } 537 555 538 uint32_t blocklen;539 556 libtrace_linktype_t linktype; 540 uint32_t remaining; 541 void *link; 542 543 /* If the file is not open, open it. First item must be SBH header */ 557 558 linktype = trace_get_link_type(packet); 559 /* discard meta packets from other capture types and unknown packets */ 560 if (linktype == TRACE_TYPE_NONDATA || linktype == TRACE_TYPE_UNKNOWN 561 || linktype == TRACE_TYPE_ERF_META || linktype == TRACE_TYPE_CONTENT_INVALID) { 562 return 0; 563 } 564 565 /* If the file is not open, open it */ 544 566 if (!DATAOUT(libtrace)->file) { 545 /* open output file */546 567 DATAOUT(libtrace)->file = trace_open_file_out(libtrace, 547 DATAOUT(libtrace)->compress_type, 548 DATAOUT(libtrace)->compress_level, 549 DATAOUT(libtrace)->flag); 550 551 /* If packet is a section block header just output it */ 552 pcapng_sec_t *hdr = (pcapng_sec_t *)packet->buffer; 553 if (hdr->blocktype == PCAPNG_SECTION_TYPE) { 554 568 DATAOUT(libtrace)->compress_type, 569 DATAOUT(libtrace)->compress_level, 570 DATAOUT(libtrace)->flag); 571 } 572 573 /* If the packet is already encapsulated in a pcapng frame just output it */ 574 switch (pcapng_get_header_type(packet)) { 575 case PCAPNG_SECTION_TYPE: { 576 /* If we get a section header we need to calculate the 577 * the byte ordering */ 555 578 pcapng_sec_t *sechdr = (pcapng_sec_t *)packet->buffer; 556 557 /* now we need to determine the byte ordering so we know558 * how much to write out */559 579 if (sechdr->ordering == 0x1A2B3C4D) { 560 580 DATAOUT(libtrace)->byteswapped = false; … … 566 586 pcapng_get_blocklen(packet)); 567 587 568 return 0; 569 } 570 571 /* Create section block */ 572 pcapng_sec_t sechdr; 573 sechdr.blocktype = PCAPNG_SECTION_TYPE; 574 sechdr.blocklen = 28; 575 sechdr.ordering = 0x1A2B3C4D; 576 sechdr.majorversion = 1; 577 sechdr.minorversion = 0; 578 sechdr.sectionlen = 0xFFFFFFFFFFFFFFFF; 579 580 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr, sizeof(sechdr)); 581 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr.blocklen, sizeof(sechdr.blocklen)); 582 583 } 584 585 /* Output interface type if we have not already */ 586 if (DATAOUT(libtrace)->nextintid == 0) { 587 588 if (pcapng_get_header_type(packet) == PCAPNG_INTERFACE_TYPE) { 588 DATAOUT(libtrace)->sechdr_count += 1; 589 590 return pcapng_get_blocklen(packet); 591 } 592 case PCAPNG_INTERFACE_TYPE: { 589 593 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 590 594 pcapng_get_blocklen(packet)); 591 /* increment the interface counter */ 592 DATAOUT(libtrace)->nextintid += 1; 593 return 0; 594 } 595 596 /* Create interface block*/ 597 pcapng_int_t inthdr; 598 inthdr.blocktype = PCAPNG_INTERFACE_TYPE; 599 inthdr.blocklen = 20; 600 inthdr.linktype = libtrace_to_pcap_dlt(trace_get_link_type(packet)); 601 inthdr.reserved = 0; 602 inthdr.snaplen = 0; 603 604 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr, sizeof(inthdr)); 605 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr.blocklen, sizeof(inthdr.blocklen)); 606 607 /* increment the interface counter */ 608 DATAOUT(libtrace)->nextintid += 1; 609 } 610 611 switch (pcapng_get_header_type(packet)) { 595 596 /* increment the interface id */ 597 DATAOUT(libtrace)->nextintid += 1; 598 599 return pcapng_get_blocklen(packet); 600 } 612 601 case PCAPNG_OLD_PACKET_TYPE: { 613 602 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 614 603 pcapng_get_blocklen(packet)); 615 return 0; 604 605 return pcapng_get_blocklen(packet); 616 606 } 617 607 case PCAPNG_SIMPLE_PACKET_TYPE: { 608 if (DATAOUT(libtrace)->nextintid == 0) { 609 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET, 610 "Cannot output simple packet before a interface " 611 "block has been output in pcapng_write_packet()\n"); 612 return -1; 613 } 618 614 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 619 615 pcapng_get_blocklen(packet)); 620 return 0; 616 617 return pcapng_get_blocklen(packet); 621 618 } 622 619 case PCAPNG_NAME_RESOLUTION_TYPE: { 623 620 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 624 621 pcapng_get_blocklen(packet)); 625 return 0; 622 623 return pcapng_get_blocklen(packet); 626 624 } 627 625 case PCAPNG_INTERFACE_STATS_TYPE: { 626 if (DATAOUT(libtrace)->nextintid == 0) { 627 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET, 628 "Cannot output a interface statistics block before a " 629 "interface block has been output in pcapng_write_packet()\n"); 630 return -1; 631 } 628 632 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 629 633 pcapng_get_blocklen(packet)); 630 return 0; 634 635 return pcapng_get_blocklen(packet); 631 636 } 632 637 case PCAPNG_ENHANCED_PACKET_TYPE: { 638 if (DATAOUT(libtrace)->nextintid == 0) { 639 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET, 640 "Cannot output enhanced packet before a interface " 641 "block has been output in pcapng_write_packet()\n"); 642 return -1; 643 } 633 644 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 634 645 pcapng_get_blocklen(packet)); 635 return 0; 646 647 return pcapng_get_blocklen(packet); 636 648 } 637 649 case PCAPNG_CUSTOM_TYPE: { 638 650 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 639 651 pcapng_get_blocklen(packet)); 640 return 0; 652 653 return pcapng_get_blocklen(packet); 641 654 } 642 655 default: { 643 /* not a pcapng format libtrace knows */ 656 657 /* create section header if not already */ 658 if (DATAOUT(libtrace)->sechdr_count == 0) { 659 /* Create section block */ 660 pcapng_sec_t sechdr; 661 sechdr.blocktype = PCAPNG_SECTION_TYPE; 662 sechdr.blocklen = 28; 663 sechdr.ordering = 0x1A2B3C4D; 664 sechdr.majorversion = 1; 665 sechdr.minorversion = 0; 666 sechdr.sectionlen = 0xFFFFFFFFFFFFFFFF; 667 668 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr, sizeof(sechdr)); 669 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr.blocklen, sizeof(sechdr.blocklen)); 670 671 DATAOUT(libtrace)->sechdr_count += 1; 672 } 673 674 /* create interface header if not already or if the linktype has changed */ 675 if (DATAOUT(libtrace)->nextintid == 0 676 || DATAOUT(libtrace)->lastdlt != linktype) { 677 /* Create interface block*/ 678 pcapng_int_t inthdr; 679 inthdr.blocktype = PCAPNG_INTERFACE_TYPE; 680 inthdr.blocklen = 20; 681 inthdr.linktype = libtrace_to_pcap_dlt(linktype); 682 inthdr.reserved = 0; 683 inthdr.snaplen = 0; 684 685 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr, sizeof(inthdr)); 686 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr.blocklen, sizeof(inthdr.blocklen)); 687 688 /* increment the interface counter */ 689 DATAOUT(libtrace)->nextintid += 1; 690 /* update the last linktype */ 691 DATAOUT(libtrace)->lastdlt = linktype; 692 } 644 693 break; 645 694 } 646 695 } 647 696 648 /* If we made it this far constuct a enhanced packet */ 697 /* If we get this far the packet is not a pcapng type so we need to encapsulate it 698 * within a enhanced pcapng packet */ 699 uint32_t remaining; 700 void *link; 701 uint32_t blocklen; 702 uint32_t padding; 703 void *padding_data; 704 pcapng_epkt_t epkthdr; 705 649 706 link = trace_get_packet_buffer(packet, &linktype, &remaining); 650 651 /* convert packet into enhanced packet */652 pcapng_epkt_t epkthdr;653 707 654 708 epkthdr.wlen = trace_get_wire_length(packet); … … 661 715 662 716 /* calculate padding to 32bits */ 663 uint32_tpadding = epkthdr.caplen % 4;717 padding = epkthdr.caplen % 4; 664 718 if (padding) { padding = 4 - padding; } 665 void *padding_data = calloc(1, padding);719 padding_data = calloc(1, padding); 666 720 667 721 /* calculate the block length */ … … 689 743 free(padding_data); 690 744 691 return 0;745 return blocklen; 692 746 } 693 747 … … 763 817 } 764 818 765 packet->type = TRACE_RT_PCAPNG_META;819 packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META); 766 820 if (pcapng_prepare_packet(libtrace, packet, packet->buffer, 767 821 packet->type, flags)) { … … 830 884 bodyptr = (char *) packet->buffer + sizeof(pcapng_int_t); 831 885 832 packet->type = TRACE_RT_PCAPNG_META;886 packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META); 833 887 834 888 if (pcapng_prepare_packet(libtrace, packet, packet->buffer, … … 895 949 } 896 950 897 packet->type = TRACE_RT_PCAPNG_META;951 packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META); 898 952 if (pcapng_prepare_packet(libtrace, packet, packet->buffer, 899 953 packet->type, flags)) { … … 939 993 } 940 994 941 packet->type = TRACE_RT_PCAPNG_META;995 packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META); 942 996 if (pcapng_prepare_packet(libtrace, packet, packet->buffer, 943 997 packet->type, flags)) { … … 1356 1410 } 1357 1411 1358 static libtrace_linktype_t pcapng_get_link_type(const libtrace_packet_t *packet) 1359 { 1412 static libtrace_linktype_t pcapng_get_link_type(const libtrace_packet_t *packet) { 1413 1414 struct pcapng_peeker *hdr = (struct pcapng_peeker *)packet->buffer; 1415 1416 if (hdr->blocktype == PCAPNG_SECTION_TYPE 1417 || hdr->blocktype == PCAPNG_INTERFACE_TYPE 1418 || hdr->blocktype == PCAPNG_NAME_RESOLUTION_TYPE 1419 || hdr->blocktype == PCAPNG_INTERFACE_STATS_TYPE 1420 || hdr->blocktype == PCAPNG_CUSTOM_TYPE) { 1421 return TRACE_TYPE_PCAPNG_META; 1422 } 1360 1423 1361 1424 return pcap_linktype_to_libtrace(rt_to_pcap_linktype(packet->type)); 1362 1363 1425 } 1364 1426 -
lib/libtrace.h.in
rd9ca546 rebd6275 412 412 TRACE_TYPE_OPENBSD_LOOP = 20, /**< OpenBSD loopback */ 413 413 TRACE_TYPE_ERF_META = 21, /**< ERF Provenance metadata record */ 414 TRACE_TYPE_ETSILI = 22 /**< ETSI Lawful Intercept */ 414 TRACE_TYPE_ETSILI = 22, /**< ETSI Lawful Intercept */ 415 TRACE_TYPE_PCAPNG_META = 22, /** PCAPNG meta packet */ 415 416 } libtrace_linktype_t; 416 417
Note: See TracChangeset
for help on using the changeset viewer.