Ignore:
Timestamp:
02/13/19 10:32:17 (2 years ago)
Author:
GitHub <noreply@…>
Branches:
develop
Children:
33c9a91, fc85f33
Parents:
1c3f8d2 (diff), 4e5a51f (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.
git-author:
Shane Alcock <salcock@…> (02/13/19 10:32:17)
git-committer:
GitHub <noreply@…> (02/13/19 10:32:17)
Message:

Merge pull request #101 from jacobvw/meta-api

Meta API

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_pcapng.c

    r063d5dd r5cdb37d  
    2929#include "libtrace_int.h"
    3030#include "format_helper.h"
     31#include "format_pcapng.h"
    3132
    3233#include <sys/stat.h>
     
    3839#include <stdbool.h>
    3940#include <math.h>
    40 
    41 #define PCAPNG_SECTION_TYPE 0x0A0D0D0A
    42 #define PCAPNG_INTERFACE_TYPE 0x00000001
    43 #define PCAPNG_OLD_PACKET_TYPE 0x00000002
    44 #define PCAPNG_SIMPLE_PACKET_TYPE 0x00000003
    45 #define PCAPNG_NAME_RESOLUTION_TYPE 0x00000004
    46 #define PCAPNG_INTERFACE_STATS_TYPE 0x00000005
    47 #define PCAPNG_ENHANCED_PACKET_TYPE 0x00000006
    48 #define PCAPNG_CUSTOM_TYPE 0x00000BAD
    49 #define PCAPNG_CUSTOM_NONCOPY_TYPE 0x40000BAD
    50 #define PCAPNG_DECRYPTION_SECRETS_TYPE 0x0000000A
    51 
    52 #define PCAPNG_NRB_RECORD_END 0x0000
    53 #define PCAPNG_NRB_RECORD_IP4 0x0001
    54 #define PCAPNG_NRB_RECORD_IP6 0x0002
    55 
    56 #define PCAPNG_CUSTOM_OPTION_UTF8 0xBAC
    57 #define PCAPNG_CUSTOM_OPTION_BIN 0xBAD
    58 #define PCAPNG_CUSTOM_OPTION_UTF8_NONCOPY 0x4BAC
    59 #define PCAPNG_CUSTOM_OPTION_BIN_NONCOPY 0x4BAD
    60 
    61 #define PCAPNG_OPTION_END 0x0000
    62 
    63 #define PACKET_IS_ENHANCED (pcapng_get_record_type(packet) == PCAPNG_ENHANCED_PACKET_TYPE)
    64 
    65 #define PACKET_IS_SIMPLE (pcapng_get_record_type(packet) == PCAPNG_SIMPLE_PACKET_TYPE)
    66 
    67 #define PACKET_IS_OLD (pcapng_get_record_type(packet) == PCAPNG_OLD_PACKET_TYPE)
    68 
    69 #define PCAPNG_IFOPT_TSRESOL 9
    70 
    71 #define PCAPNG_PKTOPT_DROPCOUNT 4
    72 
    73 #define PCAPNG_STATOPT_START 2
    74 #define PCAPNG_STATOPT_END 3
    75 #define PCAPNG_STATOPT_IFRECV 4
    76 #define PCAPNG_STATOPT_IFDROP 5
    77 #define PCAPNG_STATOPT_FILTERACCEPT 6
    78 #define PCAPNG_STATOPT_OSDROP 7
    79 #define PCAPNG_STATOPT_USRDELIV 8
    80 
    81 typedef struct pcagng_section_header_t {
    82         uint32_t blocktype;
    83         uint32_t blocklen;
    84         uint32_t ordering;
    85         uint16_t majorversion;
    86         uint16_t minorversion;
    87         uint64_t sectionlen;
    88 } pcapng_sec_t;
    89 
    90 typedef struct pcapng_interface_header_t {
    91         uint32_t blocktype;
    92         uint32_t blocklen;
    93         uint16_t linktype;
    94         uint16_t reserved;
    95         uint32_t snaplen;
    96 } pcapng_int_t;
    97 
    98 typedef struct pcapng_nrb_header_t {
    99         uint32_t blocktype;
    100         uint32_t blocklen;
    101 } pcapng_nrb_t;
    102 
    103 typedef struct pcapng_enhanced_packet_t {
    104         uint32_t blocktype;
    105         uint32_t blocklen;
    106         uint32_t interfaceid;
    107         uint32_t timestamp_high;
    108         uint32_t timestamp_low;
    109         uint32_t caplen;
    110         uint32_t wlen;
    111 } pcapng_epkt_t;
    112 
    113 typedef struct pcapng_simple_packet_t {
    114         uint32_t blocktype;
    115         uint32_t blocklen;
    116         uint32_t wlen;
    117 } pcapng_spkt_t;
    118 
    119 typedef struct pcapng_old_packet_t {
    120         uint32_t blocktype;
    121         uint32_t blocklen;
    122         uint16_t interfaceid;
    123         uint16_t drops;
    124         uint32_t timestamp_high;
    125         uint32_t timestamp_low;
    126         uint32_t caplen;
    127         uint32_t wlen;
    128 } pcapng_opkt_t;
    129 
    130 typedef struct pcapng_stats_header_t {
    131         uint32_t blocktype;
    132         uint32_t blocklen;
    133         uint32_t interfaceid;
    134         uint32_t timestamp_high;
    135         uint32_t timestamp_low;
    136 } pcapng_stats_t;
    137 
    138 typedef struct pcapng_custom_header_t {
    139         uint32_t blocktype;
    140         uint32_t blocklen;
    141         uint32_t pen;
    142 } pcapng_custom_t;
    143 
    144 typedef struct pcapng_interface_t pcapng_interface_t;
    145 
    146 struct pcapng_timestamp {
    147         uint32_t timehigh;
    148         uint32_t timelow;
    149 };
    150 
    151 struct pcapng_interface_t {
    152 
    153         uint16_t id;
    154         libtrace_dlt_t linktype;
    155         uint32_t snaplen;
    156         uint32_t tsresol;
    157 
    158         uint64_t received;
    159         uint64_t dropped;       /* as reported by interface stats */
    160         uint64_t dropcounter;   /* as reported by packet records */
    161         uint64_t accepted;
    162         uint64_t osdropped;
    163         uint64_t laststats;
    164 
    165 };
    166 
    167 struct pcapng_format_data_t {
    168         bool started;
    169         bool realtime;
    170 
    171         /* Section data */
    172         bool byteswapped;
    173 
    174         /* Interface data */
    175         pcapng_interface_t **interfaces;
    176         uint16_t allocatedinterfaces;
    177         uint16_t nextintid;
    178 
    179 };
    180 
    181 struct pcapng_format_data_out_t {
    182         iow_t *file;
    183         int compress_level;
    184         int compress_type;
    185         int flag;
    186 
    187         /* Section data */
    188         uint16_t sechdr_count;
    189         bool byteswapped;
    190 
    191         /* Interface data */
    192         uint16_t nextintid;
    193         libtrace_linktype_t lastdlt;
    194 };
    195 
    196 struct pcapng_optheader {
    197         uint16_t optcode;
    198         uint16_t optlen;
    199 };
    200 
    201 struct pcapng_custom_optheader {
    202         uint16_t optcode;
    203         uint16_t optlen;
    204         uint32_t pen;
    205 };
    206 struct pcapng_nrb_record {
    207         uint16_t recordtype;
    208         uint16_t recordlen;
    209 };
    210 struct pcapng_peeker {
    211         uint32_t blocktype;
    212         uint32_t blocklen;
    213 };
    214 
    215 typedef struct pcapng_peeker pcapng_hdr_t;
    216 
    217 #define DATA(x) ((struct pcapng_format_data_t *)((x)->format_data))
    218 #define DATAOUT(x) ((struct pcapng_format_data_out_t*)((x)->format_data))
    21941
    22042static char *pcapng_parse_next_option(libtrace_t *libtrace, char **pktbuf,
     
    656478}
    657479
     480static void pcapng_create_output_sectionheader_packet(libtrace_out_t *libtrace) {
     481        /* Create section block */
     482        pcapng_sec_t sechdr;
     483        sechdr.blocktype = pcapng_swap32(libtrace, PCAPNG_SECTION_TYPE);
     484        sechdr.blocklen = pcapng_swap32(libtrace, 28);
     485        sechdr.ordering = pcapng_swap32(libtrace, 0x1A2B3C4D);
     486        sechdr.majorversion = pcapng_swap16(libtrace, 1);
     487        sechdr.minorversion = 0;
     488        sechdr.sectionlen = 0xFFFFFFFFFFFFFFFF;
     489
     490        wandio_wwrite(DATAOUT(libtrace)->file, &sechdr, sizeof(sechdr));
     491        wandio_wwrite(DATAOUT(libtrace)->file, &sechdr.blocklen, sizeof(sechdr.blocklen));
     492
     493        DATAOUT(libtrace)->sechdr_count += 1;
     494}
     495
     496static void pcapng_create_output_interface_packet(libtrace_out_t *libtrace, libtrace_linktype_t linktype) {
     497        /* Create interface block*/
     498        pcapng_int_t inthdr;
     499        inthdr.blocktype = pcapng_swap32(libtrace, PCAPNG_INTERFACE_TYPE);
     500        inthdr.blocklen = pcapng_swap32(libtrace, 20);
     501        inthdr.linktype = pcapng_swap16(libtrace, libtrace_to_pcap_dlt(linktype));
     502        inthdr.reserved = 0;
     503        inthdr.snaplen = 0;
     504
     505        wandio_wwrite(DATAOUT(libtrace)->file, &inthdr, sizeof(inthdr));
     506        wandio_wwrite(DATAOUT(libtrace)->file, &inthdr.blocklen, sizeof(inthdr.blocklen));
     507
     508        /* increment the interface counter */
     509        DATAOUT(libtrace)->nextintid += 1;
     510        /* update the last linktype */
     511        DATAOUT(libtrace)->lastdlt = linktype;
     512}
     513
    658514static int pcapng_probe_magic(io_t *io) {
    659515
     
    694550        DATA(libtrace)->started = false;
    695551        DATA(libtrace)->realtime = false;
     552        DATA(libtrace)->discard_meta = false;
    696553        DATA(libtrace)->byteswapped = true;
    697554        DATA(libtrace)->interfaces = (pcapng_interface_t **)calloc(10, \
     
    754611                case TRACE_OPTION_CONSTANT_ERF_FRAMING:
    755612                        break;
     613                case TRACE_OPTION_DISCARD_META:
     614                        if (*(int *)data > 0) {
     615                                DATA(libtrace)->discard_meta = true;
     616                        } else {
     617                                DATA(libtrace)->discard_meta = false;
     618                        }
     619                        return 0;
    756620        }
    757621
     
    886750static int pcapng_get_framing_length(const libtrace_packet_t *packet) {
    887751
    888         switch(pcapng_get_record_type(packet)) {
     752        switch(pcapng_get_record_type(packet)) {
    889753                case PCAPNG_SECTION_TYPE:
    890754                        return sizeof(pcapng_sec_t);
     
    902766                        return sizeof(pcapng_nrb_t);
    903767                case PCAPNG_CUSTOM_TYPE:
     768                        return sizeof(pcapng_custom_t);
    904769                case PCAPNG_CUSTOM_NONCOPY_TYPE:
    905770                        return sizeof(pcapng_custom_t);
    906         }
     771                case PCAPNG_DECRYPTION_SECRETS_TYPE:
     772                        return sizeof(pcapng_secrets_t);
     773        }
    907774
    908775        /* If we get here, we aren't a valid pcapng packet */
     
    1003870                }
    1004871                case PCAPNG_SIMPLE_PACKET_TYPE: {
     872                        /* If no section header or interface packets have been received create and
     873                         * output them. This can occur when discard meta is enabled and the input
     874                         * format is also pcapng */
     875                        if (DATAOUT(libtrace)->sechdr_count == 0) {
     876                                pcapng_create_output_sectionheader_packet(libtrace);
     877                        }
    1005878                        if (DATAOUT(libtrace)->nextintid == 0) {
    1006                                 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET,
    1007                                         "Cannot output simple packet before a interface "
    1008                                         "block has been output in pcapng_write_packet()\n");
    1009                                 return -1;
     879                                pcapng_create_output_interface_packet(libtrace, linktype);
    1010880                        }
    1011881                        return pcapng_output_simple_packet(libtrace, packet);
     
    1015885                }
    1016886                case PCAPNG_INTERFACE_STATS_TYPE: {
    1017                         if (DATAOUT(libtrace)->nextintid == 0) {
    1018                                 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET,
    1019                                         "Cannot output a interface statistics block before a "
    1020                                         "interface block has been output in pcapng_write_packet()\n");
    1021                                 return -1;
    1022                         }
     887                        /* If no section header or interface packets have been received create and
     888                         * output them. This can occur when discard meta is enabled and the input
     889                         * format is also pcapng */
     890                        if (DATAOUT(libtrace)->sechdr_count == 0) {
     891                                pcapng_create_output_sectionheader_packet(libtrace);
     892                        }
     893                        if (DATAOUT(libtrace)->nextintid == 0) {
     894                                pcapng_create_output_interface_packet(libtrace, linktype);
     895                        }
    1023896                        return pcapng_output_interfacestats_packet(libtrace, packet);
    1024897                }
    1025898                case PCAPNG_ENHANCED_PACKET_TYPE: {
    1026                         if (DATAOUT(libtrace)->nextintid == 0) {
    1027                                 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET,
    1028                                         "Cannot output enhanced packet before a interface "
    1029                                         "block has been output in pcapng_write_packet()\n");
    1030                                 return -1;
    1031                         }
     899                        /* If no section header or interface packets have been received create and
     900                         * output them. This can occur when discard meta is enabled and the input
     901                         * format is also pcapng */
     902                        if (DATAOUT(libtrace)->sechdr_count == 0) {
     903                                pcapng_create_output_sectionheader_packet(libtrace);
     904                        }
     905                        if (DATAOUT(libtrace)->nextintid == 0) {
     906                                pcapng_create_output_interface_packet(libtrace, linktype);
     907                        }
    1032908                        return pcapng_output_enhanced_packet(libtrace, packet);
    1033909                }
     
    1044920                default: {
    1045921
    1046                         /* create section header if not already */
     922                        /* create and output section header if none have occured yet */
    1047923                        if (DATAOUT(libtrace)->sechdr_count == 0) {
    1048                                 /* Create section block */
    1049                                 pcapng_sec_t sechdr;
    1050                                 sechdr.blocktype = pcapng_swap32(libtrace, PCAPNG_SECTION_TYPE);
    1051                                 sechdr.blocklen = pcapng_swap32(libtrace, 28);
    1052                                 sechdr.ordering = pcapng_swap32(libtrace, 0x1A2B3C4D);
    1053                                 sechdr.majorversion = pcapng_swap16(libtrace, 1);
    1054                                 sechdr.minorversion = 0;
    1055                                 sechdr.sectionlen = 0xFFFFFFFFFFFFFFFF;
    1056 
    1057                                 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr, sizeof(sechdr));
    1058                                 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr.blocklen, sizeof(sechdr.blocklen));
    1059 
    1060                                 DATAOUT(libtrace)->sechdr_count += 1;
     924                                pcapng_create_output_sectionheader_packet(libtrace);
    1061925                        }
    1062926
    1063                         /* create interface header if not already or if the linktype has changed */
     927                        /* create and output interface header if not already or if the
     928                         * linktype has changed */
    1064929                        if (DATAOUT(libtrace)->nextintid == 0
    1065930                                || DATAOUT(libtrace)->lastdlt != linktype) {
    1066                                 /* Create interface block*/
    1067                                 pcapng_int_t inthdr;
    1068                                 inthdr.blocktype = pcapng_swap32(libtrace, PCAPNG_INTERFACE_TYPE);
    1069                                 inthdr.blocklen = pcapng_swap32(libtrace, 20);
    1070                                 inthdr.linktype = pcapng_swap16(libtrace, libtrace_to_pcap_dlt(linktype));
    1071                                 inthdr.reserved = 0;
    1072                                 inthdr.snaplen = 0;
    1073 
    1074                                 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr, sizeof(inthdr));
    1075                                 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr.blocklen, sizeof(inthdr.blocklen));
    1076 
    1077                                 /* increment the interface counter */
    1078                                 DATAOUT(libtrace)->nextintid += 1;
    1079                                 /* update the last linktype */
    1080                                 DATAOUT(libtrace)->lastdlt = linktype;
     931
     932                                pcapng_create_output_interface_packet(libtrace, linktype);
    1081933                        }
    1082934
     
    17691621                        /* Section Header */
    17701622                        case PCAPNG_SECTION_TYPE:
    1771                                 err = pcapng_read_section(libtrace, packet, flags);
    1772                                 gotpacket = 1;
     1623                                /* Section header packets are required for PCAPNG so even if discard_meta
     1624                                 * option is set it still needs to be processed. Not setting gotpacket will
     1625                                 * prevent triggering the meta callback */
     1626                                err = pcapng_read_section(libtrace, packet, flags);
     1627                                if (!DATA(libtrace)->discard_meta) {
     1628                                        gotpacket = 1;
     1629                                }
     1630
    17731631                                break;
    17741632
    17751633                        /* Interface Header */
    17761634                        case PCAPNG_INTERFACE_TYPE:
     1635                                /* Same applies here for Interface packets */
    17771636                                err = pcapng_read_interface(libtrace, packet, to_read, flags);
    1778                                 gotpacket = 1;
     1637                                if (!DATA(libtrace)->discard_meta) {
     1638                                        gotpacket = 1;
     1639                                }
    17791640                                break;
    17801641
     
    17921653
    17931654                        case PCAPNG_INTERFACE_STATS_TYPE:
    1794                                 err = pcapng_read_stats(libtrace, packet, to_read, flags);
    1795                                 gotpacket = 1;
     1655                                /* If discard_meta is set ignore this packet type */
     1656                                if (!DATA(libtrace)->discard_meta) {
     1657                                        err = pcapng_read_stats(libtrace, packet, to_read, flags);
     1658                                        gotpacket = 1;
     1659                                }
    17961660                                break;
    17971661
    17981662                        case PCAPNG_NAME_RESOLUTION_TYPE:
    1799                                 err = pcapng_read_nrb(libtrace, packet, to_read, flags);
    1800                                 gotpacket = 1;
     1663                                /* If discard meta is set ignore this packet type */
     1664                                if (!DATA(libtrace)->discard_meta) {
     1665                                        err = pcapng_read_nrb(libtrace, packet, to_read, flags);
     1666                                        gotpacket = 1;
     1667                                }
    18011668                                break;
    18021669
    18031670                        case PCAPNG_CUSTOM_TYPE:
    18041671                        case PCAPNG_CUSTOM_NONCOPY_TYPE:
    1805                                 err = pcapng_read_custom(libtrace, packet, to_read, flags);
    1806                                 gotpacket = 1;
     1672                                /* If discard meta is set ignore this packet type */
     1673                                if (!DATA(libtrace)->discard_meta) {
     1674                                        err = pcapng_read_custom(libtrace, packet, to_read, flags);
     1675                                        gotpacket = 1;
     1676                                }
    18071677                                break;
    18081678
     
    18381708static libtrace_direction_t pcapng_get_direction(const libtrace_packet_t
    18391709                *packet) {
     1710        libtrace_direction_t direction = -1;
    18401711
    18411712        /* Defined in format_helper.c */
    1842         return pcap_get_direction(packet);
     1713        if (PACKET_IS_ENHANCED || PACKET_IS_SIMPLE || PACKET_IS_OLD) {
     1714                direction = pcap_get_direction(packet);
     1715        }
     1716
     1717        return direction;
    18431718}
    18441719
     
    19421817                        return ohdr->wlen;
    19431818                }
    1944         }
     1819        } else if (PACKET_IS_SECTION || PACKET_IS_INTERFACE || PACKET_IS_NAME_RESOLUTION
     1820                || PACKET_IS_INTERFACE_STATS || PACKET_IS_CUSTOM ||
     1821                PACKET_IS_CUSTOM_NONCOPY || PACKET_IS_DECRYPTION_SECRETS) {
     1822                /* meta packet are not transmitted on the wire hence the 0 wirelen */
     1823                return 0;
     1824        }
    19451825
    19461826        /* If we get here, we aren't a valid pcapng packet */
     
    19581838        if (baselen == -1)
    19591839                return -1;
     1840
     1841        /* if packet was a meta packet baselen should be zero so return it */
     1842        if (baselen == 0) {
     1843                return 0;
     1844        }
    19601845
    19611846        /* Then, account for the vagaries of different DLTs */
     
    20231908                        return ohdr->caplen;
    20241909                }
    2025         }
     1910        } else if (PACKET_IS_SECTION || PACKET_IS_INTERFACE || PACKET_IS_NAME_RESOLUTION
     1911                || PACKET_IS_INTERFACE_STATS || PACKET_IS_CUSTOM ||
     1912                PACKET_IS_CUSTOM_NONCOPY || PACKET_IS_DECRYPTION_SECRETS) {
     1913
     1914                struct pcapng_peeker *hdr = (struct pcapng_peeker *)packet->header;
     1915                if (DATA(packet->trace)->byteswapped) {
     1916                        return byteswap32(hdr->blocklen) - trace_get_framing_length(packet);
     1917                } else {
     1918                        return hdr->blocklen - trace_get_framing_length(packet);
     1919                }
     1920        }
    20261921
    20271922        /* If we get here, we aren't a valid pcapng packet */
     
    21522047        stat->captured_valid = 1;
    21532048
     2049
     2050}
     2051
     2052static libtrace_meta_datatype_t pcapng_get_datatype(uint32_t section, uint32_t option) {
     2053        switch(section) {
     2054                case(PCAPNG_SECTION_TYPE):
     2055                        return TRACE_META_STRING;
     2056                case(PCAPNG_INTERFACE_TYPE):
     2057                        switch(option) {
     2058                                case(PCAPNG_META_IF_NAME): return TRACE_META_STRING;
     2059                                case(PCAPNG_META_IF_DESCR): return TRACE_META_STRING;
     2060                                case(PCAPNG_META_IF_IP4): return TRACE_META_IPV4;
     2061                                case(PCAPNG_META_IF_IP6): return TRACE_META_IPV6;
     2062                                case(PCAPNG_META_IF_MAC): return TRACE_META_MAC;
     2063                                case(PCAPNG_META_IF_EUI): return TRACE_META_UINT64;
     2064                                case(PCAPNG_META_IF_SPEED): return PCAPNG_META_IF_SPEED;
     2065                                case(PCAPNG_META_IF_TSRESOL): return TRACE_META_UINT8;
     2066                                case(PCAPNG_META_IF_TZONE): return TRACE_META_UINT32;
     2067                                case(PCAPNG_META_IF_FILTER): return TRACE_META_STRING;
     2068                                case(PCAPNG_META_IF_OS): return TRACE_META_STRING;
     2069                                case(PCAPNG_META_IF_FCSLEN): return TRACE_META_UINT8;
     2070                                case(PCAPNG_META_IF_TSOFFSET): return TRACE_META_UINT64;
     2071                                case(PCAPNG_META_IF_HARDWARE): return TRACE_META_STRING;
     2072                        }
     2073                case(PCAPNG_OLD_PACKET_TYPE):
     2074                        switch(option) {
     2075                                case(PCAPNG_META_OLD_FLAGS): return TRACE_META_UINT32;
     2076                                case(PCAPNG_META_OLD_HASH): return TRACE_META_STRING;
     2077                        }
     2078                case(PCAPNG_SIMPLE_PACKET_TYPE):
     2079                        /* simple packets should not contain any options */
     2080                        return TRACE_META_UNKNOWN;
     2081                case(PCAPNG_NAME_RESOLUTION_TYPE):
     2082                        /* todo - needs to handle name resolution options along with
     2083                         * normal options */
     2084                        return TRACE_META_UNKNOWN;
     2085                case(PCAPNG_INTERFACE_STATS_TYPE):
     2086                        return TRACE_META_UINT64;
     2087                case(PCAPNG_ENHANCED_PACKET_TYPE):
     2088                        switch(option) {
     2089                                case(PCAPNG_META_EPB_FLAGS): return TRACE_META_UINT32;
     2090                                case(PCAPNG_META_EPB_HASH): return TRACE_META_STRING;
     2091                                case(PCAPNG_META_EPB_DROPCOUNT): return TRACE_META_UINT64;
     2092                        }
     2093                case(PCAPNG_DECRYPTION_SECRETS_TYPE):
     2094                        /* todo - needs to handle decryption secrets options along with
     2095                         * normal options */
     2096                        return TRACE_META_UNKNOWN;
     2097                default:
     2098                        return TRACE_META_UNKNOWN;
     2099        }
     2100}
     2101
     2102static void *pcapng_jump_to_options(libtrace_packet_t *packet) {
     2103
     2104        struct pcapng_peeker *hdr = (struct pcapng_peeker *)packet->buffer;
     2105        void *ptr = packet->buffer;
     2106        uint32_t blocktype;
     2107
     2108        if (DATA(packet->trace)->byteswapped) {
     2109                blocktype = byteswap32(hdr->blocktype);
     2110        } else {
     2111                blocktype = hdr->blocktype;
     2112        }
     2113
     2114        /* Skip x bytes to the options depending on what kind of packet this is */
     2115        if (blocktype == PCAPNG_SECTION_TYPE) { ptr += sizeof(pcapng_sec_t); }
     2116        else if (blocktype == PCAPNG_INTERFACE_TYPE) { ptr += sizeof(pcapng_int_t); }
     2117        else if (blocktype == PCAPNG_OLD_PACKET_TYPE) { ptr += sizeof(pcapng_opkt_t); }
     2118        else if (blocktype == PCAPNG_NAME_RESOLUTION_TYPE) { ptr += sizeof(pcapng_nrb_t); }
     2119        else if (blocktype == PCAPNG_INTERFACE_STATS_TYPE) { ptr += sizeof(pcapng_stats_t); }
     2120        else if (blocktype == PCAPNG_ENHANCED_PACKET_TYPE) {
     2121                /* jump over the the enchanced packet header and data to the options */
     2122                pcapng_epkt_t *epkthdr = (pcapng_epkt_t *)ptr;
     2123                uint32_t seclen;
     2124                if (DATA(packet->trace)->byteswapped) {
     2125                        seclen = byteswap32(epkthdr->caplen);
     2126                } else {
     2127                        seclen = epkthdr->caplen;
     2128                }
     2129                if ((seclen % 4) != 0) {
     2130                        ptr += seclen + (4 -(seclen % 4)) + sizeof(pcapng_secrets_t);
     2131                } else {
     2132                        ptr += seclen + sizeof(pcapng_secrets_t);
     2133                }
     2134        }
     2135        else if (blocktype == PCAPNG_DECRYPTION_SECRETS_TYPE) {
     2136                /* jump over the decryption secrets header and data to the options */
     2137                pcapng_secrets_t *sechdr = (pcapng_secrets_t *)ptr;
     2138                uint32_t seclen;
     2139                if (DATA(packet->trace)->byteswapped) {
     2140                        seclen = byteswap32(sechdr->secrets_len);
     2141                } else {
     2142                        seclen = sechdr->secrets_len;
     2143                }
     2144                if ((seclen % 4) != 0) {
     2145                        ptr += seclen + (4 -(seclen % 4)) + sizeof(pcapng_secrets_t);
     2146                } else {
     2147                        ptr += seclen + sizeof(pcapng_secrets_t);
     2148                }
     2149        }
     2150        else { return NULL; }
     2151
     2152        return ptr;
     2153}
     2154
     2155void *pcapng_get_meta_section(libtrace_packet_t *packet, uint32_t section) {
     2156
     2157        struct pcapng_peeker *hdr;
     2158        uint32_t remaining;
     2159        void *ptr;
     2160        uint32_t blocktype;
     2161        uint16_t optcode;
     2162        uint16_t len;
     2163        uint16_t tmp;
     2164
     2165        if (packet == NULL) {
     2166                fprintf(stderr, "NULL packet passed into pcapng_get_meta_section()\n");
     2167                return NULL;
     2168        }
     2169        if (packet->buffer == NULL) { return NULL; }
     2170
     2171        hdr = (struct pcapng_peeker *)packet->buffer;
     2172        ptr = pcapng_jump_to_options(packet);
     2173
     2174        if (DATA(packet->trace)->byteswapped) {
     2175                blocktype = byteswap32(hdr->blocktype);
     2176                remaining = byteswap32(hdr->blocklen);
     2177        } else {
     2178                blocktype = hdr->blocktype;
     2179                remaining = hdr->blocklen;
     2180        }
     2181
     2182        /* If the data we want is not within this blocktype */
     2183        if (blocktype != section) {
     2184                return NULL;
     2185        }
     2186
     2187        /* update remaining to account for header and any payload */
     2188        remaining -= (ptr - packet->buffer);
     2189
     2190        struct pcapng_optheader *opthdr = ptr;
     2191        if (DATA(packet->trace)->byteswapped) {
     2192                optcode = byteswap16(opthdr->optcode);
     2193                len  = byteswap16(opthdr->optlen);
     2194        } else {
     2195                optcode = opthdr->optcode;
     2196                len = opthdr->optlen;
     2197        }
     2198
     2199        /* setup structure to hold the result */
     2200        libtrace_meta_t *result = malloc(sizeof(libtrace_meta_t));
     2201        result->section = section;
     2202        result->num = 0;
     2203
     2204        while (optcode != PCAPNG_OPTION_END && remaining > sizeof(struct pcapng_optheader)) {
     2205
     2206                result->num += 1;
     2207                if (result->num == 1) {
     2208                        result->items = malloc(sizeof(libtrace_meta_item_t));
     2209                } else {
     2210                        result->items = realloc(result->items,
     2211                                result->num*sizeof(libtrace_meta_item_t));
     2212                }
     2213                result->items[result->num-1].option = optcode;
     2214                result->items[result->num-1].len = len;
     2215                result->items[result->num-1].datatype =
     2216                        pcapng_get_datatype(section, optcode);
     2217
     2218                /* If the datatype is a string allow for a null terminator */
     2219                if (result->items[result->num-1].datatype == TRACE_META_STRING) {
     2220                        result->items[result->num-1].data =
     2221                                calloc(1, len+1);
     2222                        ((char *)result->items[result->num-1].data)[len] = '\0';
     2223                        /* and copy the utf8 string */
     2224                        memcpy(result->items[result->num-1].data,
     2225                                ptr+sizeof(struct pcapng_optheader), len);
     2226                } else {
     2227                        result->items[result->num-1].data =
     2228                                calloc(1, len);
     2229                        /* depending on the datatype we need to ensure the data is
     2230                         * in host byte ordering */
     2231                        if (result->items[result->num-1].datatype == TRACE_META_UINT32) {
     2232                                uint32_t t = *(uint32_t *)(ptr+sizeof(struct pcapng_optheader));
     2233                                t = ntohl(t);
     2234                                memcpy(result->items[result->num-1].data,
     2235                                        &t, sizeof(uint32_t));
     2236                        } else if(result->items[result->num-1].datatype == TRACE_META_UINT64) {
     2237                                uint64_t t = *(uint64_t *)(ptr+sizeof(struct pcapng_optheader));
     2238                                t = bswap_be_to_host64(t);
     2239                                memcpy(result->items[result->num-1].data,
     2240                                        &t, sizeof(uint64_t));
     2241                        } else {
     2242                                memcpy(result->items[result->num-1].data,
     2243                                        ptr+sizeof(struct pcapng_optheader), len);
     2244                        }
     2245
     2246                }
     2247
     2248                /* work out any padding */
     2249                if ((len % 4) != 0) {
     2250                        tmp = len + (4 - (len % 4)) + sizeof(struct pcapng_optheader);
     2251                } else {
     2252                        tmp = len + sizeof(struct pcapng_optheader);
     2253                }
     2254                ptr += tmp;
     2255                remaining -= tmp;
     2256
     2257                /* get the next option */
     2258                opthdr = (struct pcapng_optheader *)ptr;
     2259                if (DATA(packet->trace)->byteswapped) {
     2260                        optcode = byteswap16(opthdr->optcode);
     2261                        len = byteswap16(opthdr->optlen);
     2262                } else {
     2263                        optcode = opthdr->optcode;
     2264                        len = opthdr->optlen;
     2265                }
     2266        }
     2267
     2268        /* if any data was found result->num will be greater than 0 */
     2269        if (result->num > 0) {
     2270                return (void *)result;
     2271        } else {
     2272                free(result);
     2273                return NULL;
     2274        }
    21542275
    21552276}
     
    21922313        pcapng_get_timespec,            /* get_timespec */
    21932314        NULL,                           /* get_seconds */
     2315        pcapng_get_meta_section,        /* get_meta_section */
    21942316        NULL,                           /* seek_erf */
    21952317        NULL,                           /* seek_timeval */
Note: See TracChangeset for help on using the changeset viewer.