Changeset ebd6275


Ignore:
Timestamp:
01/07/19 10:32:03 (21 months ago)
Author:
Jacob Van Walraven <jcv9@…>
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)
Message:

pcapng do not try to write unknown and meta packets, cleanup the code

Location:
lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • lib/format_pcapng.c

    rd9ca546 rebd6275  
    175175
    176176        /* Section data */
     177        uint16_t sechdr_count;
    177178        bool byteswapped;
    178179
    179180        /* Interface data */
    180181        uint16_t nextintid;
    181         libtrace_dlt_t lastdlt;
     182        libtrace_linktype_t lastdlt;
    182183};
    183184
     
    220221static inline uint32_t pcapng_get_header_type(const libtrace_packet_t *packet) {
    221222        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;
    225243}
    226244static inline uint32_t pcapng_get_blocklen(const libtrace_packet_t *packet) {
     
    347365        DATAOUT(libtrace)->flag = O_CREAT|O_WRONLY;
    348366
     367        DATAOUT(libtrace)->sechdr_count = 0;
    349368        DATAOUT(libtrace)->byteswapped = false;
    350369
    351370        DATAOUT(libtrace)->nextintid = 0;
    352         DATAOUT(libtrace)->lastdlt = 0;
    353371
    354372        return 0;
     
    536554        }
    537555
    538         uint32_t blocklen;
    539556        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 */
    544566        if (!DATAOUT(libtrace)->file) {
    545                 /* open output file */
    546567                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 */
    555578                        pcapng_sec_t *sechdr = (pcapng_sec_t *)packet->buffer;
    556 
    557                         /* now we need to determine the byte ordering so we know
    558                          * how much to write out */
    559579                        if (sechdr->ordering == 0x1A2B3C4D) {
    560580                                DATAOUT(libtrace)->byteswapped = false;
     
    566586                                pcapng_get_blocklen(packet));
    567587
    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: {
    589593                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    590594                                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                }
    612601                case PCAPNG_OLD_PACKET_TYPE: {
    613602                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    614603                                pcapng_get_blocklen(packet));
    615                         return 0;
     604
     605                        return pcapng_get_blocklen(packet);
    616606                }
    617607                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                        }
    618614                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    619615                                pcapng_get_blocklen(packet));
    620                         return 0;
     616
     617                        return pcapng_get_blocklen(packet);
    621618                }
    622619                case PCAPNG_NAME_RESOLUTION_TYPE: {
    623620                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    624621                                pcapng_get_blocklen(packet));
    625                         return 0;
     622
     623                        return pcapng_get_blocklen(packet);
    626624                }
    627625                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                        }
    628632                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    629633                                pcapng_get_blocklen(packet));
    630                         return 0;
     634
     635                        return pcapng_get_blocklen(packet);
    631636                }
    632637                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                        }
    633644                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    634645                                pcapng_get_blocklen(packet));
    635                         return 0;
     646
     647                        return pcapng_get_blocklen(packet);
    636648                }
    637649                case PCAPNG_CUSTOM_TYPE: {
    638650                        wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer,
    639651                                pcapng_get_blocklen(packet));
    640                         return 0;
     652
     653                        return pcapng_get_blocklen(packet);
    641654                }
    642655                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                        }
    644693                        break;
    645694                }
    646695        }
    647696
    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
    649706        link = trace_get_packet_buffer(packet, &linktype, &remaining);
    650 
    651         /* convert packet into enhanced packet */
    652         pcapng_epkt_t epkthdr;
    653707
    654708        epkthdr.wlen = trace_get_wire_length(packet);
     
    661715
    662716        /* calculate padding to 32bits */
    663         uint32_t padding = epkthdr.caplen % 4;
     717        padding = epkthdr.caplen % 4;
    664718        if (padding) { padding = 4 - padding; }
    665         void *padding_data = calloc(1, padding);
     719        padding_data = calloc(1, padding);
    666720
    667721        /* calculate the block length */
     
    689743        free(padding_data);
    690744
    691         return 0;
     745        return blocklen;
    692746}
    693747
     
    763817        }
    764818
    765         packet->type = TRACE_RT_PCAPNG_META;
     819        packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META);
    766820        if (pcapng_prepare_packet(libtrace, packet, packet->buffer,
    767821                        packet->type, flags)) {
     
    830884        bodyptr = (char *) packet->buffer + sizeof(pcapng_int_t);
    831885
    832         packet->type = TRACE_RT_PCAPNG_META;
     886        packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META);
    833887
    834888        if (pcapng_prepare_packet(libtrace, packet, packet->buffer,
     
    895949        }
    896950
    897         packet->type = TRACE_RT_PCAPNG_META;
     951        packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META);
    898952        if (pcapng_prepare_packet(libtrace, packet, packet->buffer,
    899953                        packet->type, flags)) {
     
    939993        }
    940994
    941         packet->type = TRACE_RT_PCAPNG_META;
     995        packet->type = pcapng_linktype_to_rt(TRACE_RT_PCAPNG_META);
    942996        if (pcapng_prepare_packet(libtrace, packet, packet->buffer,
    943997                        packet->type, flags)) {
     
    13561410}
    13571411
    1358 static libtrace_linktype_t pcapng_get_link_type(const libtrace_packet_t *packet)
    1359 {
     1412static 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        }
    13601423
    13611424        return pcap_linktype_to_libtrace(rt_to_pcap_linktype(packet->type));
    1362 
    13631425}
    13641426
  • lib/libtrace.h.in

    rd9ca546 rebd6275  
    412412       TRACE_TYPE_OPENBSD_LOOP = 20,    /**< OpenBSD loopback */
    413413       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 */
    415416} libtrace_linktype_t;
    416417
Note: See TracChangeset for help on using the changeset viewer.