Changeset ed5b2ce


Ignore:
Timestamp:
07/03/17 16:31:57 (4 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
cachetimestamps, develop, dpdk-ndag, etsilive, master, ndag_format, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance
Children:
8e11beb
Parents:
4578626
Message:

Add support for reading pcapng traces

Also added special macro: IS_LIBTRACE_META_PACKET()
This macro can be used to easily recognise if a "packet" is a
genuine packet record or a meta record (such as a pcapng interface
block or an RT control message).

Location:
lib
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • lib/Makefile.am

    r4db5b98 red5b2ce  
    5555                format_rt.c format_helper.c format_helper.h format_pcapfile.c \
    5656                format_duck.c format_tsh.c $(NATIVEFORMATS) $(BPFFORMATS) \
    57                 format_atmhdr.c \
     57                format_atmhdr.c format_pcapng.c \
    5858                libtrace_int.h lt_inttypes.h lt_bswap.h \
    5959                linktypes.c link_wireless.c byteswap.c \
  • lib/libtrace.h.in

    r317e903 red5b2ce  
    391391        TRACE_FORMAT_LINUX_RING   =15,  /**< Linux native interface capture PACKET_MMAP */
    392392        TRACE_FORMAT_RAWERF       =16,  /**< Special format for reading uncompressed ERF traces without checking for compression */
    393     TRACE_FORMAT_DPDK     =17, /**< The Intel Data Plane Development Kit format */
     393        TRACE_FORMAT_DPDK     =17, /**< The Intel Data Plane Development Kit format */
     394        TRACE_FORMAT_PCAPNG     =18,    /**< PCAP-NG trace file */
    394395};
    395396
     
    417418        TRACE_RT_METADATA       =18,/**< Packet contains server meta-data */
    418419        TRACE_RT_DUCK_5_0       =19,/**< Dag 5.0 Duck */
     420        TRACE_RT_PCAPNG_META    =20,/**< Metadata for a PCAP NG input source */
    419421
    420422        /** Not actually used - all DATA types begin from this value */
     
    480482
    481483        TRACE_RT_DATA_BPF_END           = 3999,
     484
     485        TRACE_RT_DATA_PCAPNG            = 4000,
     486        TRACE_RT_DATA_PCAPNG_END        = 4499,
    482487        /** Unused value marking the end of the valid range for all RT packet
    483488         * types */
    484         TRACE_RT_LAST                   = 4000
     489        TRACE_RT_LAST                   = 4500
    485490} libtrace_rt_types_t;
    486491
     
    551556        void *srcbucket;
    552557} libtrace_packet_t;
     558
     559#define IS_LIBTRACE_META_PACKET(packet) (packet->type < TRACE_RT_DATA_SIMPLE)
    553560
    554561
  • lib/libtrace_int.h

    r5e3f16c red5b2ce  
    10811081libtrace_rt_types_t pcap_linktype_to_rt(libtrace_dlt_t linktype);
    10821082
     1083/** Converts a PCAP-NG DLT into an RT protocol type.
     1084 *
     1085 * @param linktype      The PCAP DLT to be converted
     1086 * @return The RT type that is equivalent to the provided DLT
     1087 */
     1088libtrace_rt_types_t pcapng_linktype_to_rt(libtrace_dlt_t linktype);
     1089
    10831090/** Converts a libtrace link type into a PCAP linktype.
    10841091 *
     
    12611268/** Constructor for the PCAP File format module */
    12621269void pcapfile_constructor(void);
     1270/** Constructor for the PCAP-NG File format module */
     1271void pcapng_constructor(void);
    12631272/** Constructor for the RT format module */
    12641273void rt_constructor(void);
  • lib/linktypes.c

    r4b64a045 red5b2ce  
    139139}
    140140
     141libtrace_rt_types_t pcapng_linktype_to_rt(libtrace_dlt_t linktype) {
     142
     143        return TRACE_RT_DATA_PCAPNG + pcap_dlt_to_pcap_linktype(linktype);
     144}
     145
    141146libtrace_dlt_t rt_to_pcap_linktype(libtrace_rt_types_t rt_type)
    142147{
    143        
     148
    144149        if (rt_type >= TRACE_RT_DATA_DLT && rt_type < TRACE_RT_DATA_DLT_END) {
    145150                /* RT type is in the pcap range */
    146151                return rt_type - TRACE_RT_DATA_DLT;
    147         } 
     152        }
    148153        else if (rt_type >= TRACE_RT_DATA_BPF && rt_type < TRACE_RT_DATA_BPF_END) {
    149154                return rt_type - TRACE_RT_DATA_BPF;
    150         }
    151        
     155        } else if (rt_type >= TRACE_RT_DATA_PCAPNG && rt_type < TRACE_RT_DATA_PCAPNG_END) {
     156                return rt_type - TRACE_RT_DATA_PCAPNG;
     157        }
     158
    152159        fprintf(stderr, "Error: RT type %u cannot be converted to a pcap DLT\n", rt_type);
    153         assert(rt_type >= TRACE_RT_DATA_DLT && rt_type < TRACE_RT_DATA_BPF_END);
     160        assert(false);
    154161        return 0;       /* satisfy warnings */
    155162}
  • lib/trace.c

    rd47ca18 red5b2ce  
    145145                bpf_constructor();
    146146                pcapfile_constructor();
    147                 rt_constructor();
     147                pcapng_constructor();
     148                rt_constructor();
    148149#ifdef HAVE_DAG
    149150                dag_constructor();
     
    957958                                                libtrace->snaplen);
    958959                        }
     960                        if (!IS_LIBTRACE_META_PACKET(packet)) {
     961                                ++libtrace->accepted_packets;
     962                        }
    959963                        trace_packet_set_order(packet, libtrace->sequence_number);
    960                         ++libtrace->accepted_packets;
    961                         ++libtrace->sequence_number;
     964                        ++libtrace->sequence_number;
    962965                        if (!libtrace_parallel && packet->trace == libtrace)
    963966                                libtrace->last_packet = packet;
     
    10331036                return -1;
    10341037        }
     1038
     1039        /* Don't try to convert meta-packets across formats */
     1040        if (strcmp(libtrace->format->name, packet->trace->format->name) != 0 &&
     1041                        IS_LIBTRACE_META_PACKET(packet)) {
     1042                return 0;
     1043        }
    10351044
    10361045        if (libtrace->format->write_packet) {
  • lib/trace_parallel.c

    rb606855 red5b2ce  
    343343                        (int) t->tid, prev_state, t->state);
    344344
    345         if (trace->perpkt_thread_states[THREAD_FINISHED] == trace->perpkt_thread_count)
     345        if (trace->perpkt_thread_states[THREAD_FINISHED] == trace->perpkt_thread_count) {
     346                /* Make sure we save our final stats in case someone wants
     347                 * them at the end of their program.
     348                 */
     349
     350                trace_get_statistics(trace, NULL);
    346351                libtrace_change_state(trace, STATE_FINISHED, false);
     352        }
    347353
    348354        pthread_cond_broadcast(&trace->perpkt_cond);
     
    473479                                return READ_MESSAGE;
    474480                }
    475                 t->accepted_packets++;
     481                if (!IS_LIBTRACE_META_PACKET((*packet))) {
     482                        t->accepted_packets++;
     483                }
    476484                if (trace->perpkt_cbs->message_packet)
    477485                        *packet = (*trace->perpkt_cbs->message_packet)(trace, t, trace->global_blob, t->user_data, *packet);
     
    608616        /* The offset to the first NULL packet upto offset */
    609617        int empty = 0;
     618        int j;
    610619
    611620        /* Wait until trace_pstart has been completed */
     
    692701                /* Handle error/message cases */
    693702                if (nb_packets > 0) {
    694                         /* Store the first packet */
    695                         if (packets[0]->error > 0) {
    696                                 store_first_packet(trace, packets[0], t);
     703                        /* Store the first non-meta packet */
     704                        for (j = 0; j < nb_packets; j++) {
     705                                if (t->recorded_first)
     706                                        break;
     707                                if (packets[j]->error > 0) {
     708                                        store_first_packet(trace, packets[j], t);
     709                                }
    697710                        }
    698711                        dispatch_packets(trace, t, packets, nb_packets, &empty,
     
    918931                        tick_hit = true;
    919932                }*/
    920         }
    921         // Doing this inside the lock ensures the first packet is always
    922         // recorded first
    923         if (packets[0]->error > 0) {
    924                 store_first_packet(libtrace, packets[0], t);
     933
     934                // Doing this inside the lock ensures the first packet is
     935                // always recorded first
     936                if (!t->recorded_first && packets[0]->error > 0) {
     937                        store_first_packet(libtrace, packets[0], t);
     938                }
    925939        }
    926940        ASSERT_RET(pthread_mutex_unlock(&libtrace->read_packet_lock), == 0);
     
    9941008void store_first_packet(libtrace_t *libtrace, libtrace_packet_t *packet, libtrace_thread_t *t)
    9951009{
    996         if (!t->recorded_first) {
    997                 libtrace_message_t mesg = {0, {.uint64=0}, NULL};
    998                 struct timeval tv;
    999                 libtrace_packet_t * dup;
    1000 
    1001                 /* We mark system time against a copy of the packet */
    1002                 gettimeofday(&tv, NULL);
    1003                 dup = trace_copy_packet(packet);
    1004 
    1005                 ASSERT_RET(pthread_spin_lock(&libtrace->first_packets.lock), == 0);
    1006                 libtrace->first_packets.packets[t->perpkt_num].packet = dup;
    1007                 memcpy(&libtrace->first_packets.packets[t->perpkt_num].tv, &tv, sizeof(tv));
    1008                 libtrace->first_packets.count++;
    1009 
    1010                 /* Now update the first */
    1011                 if (libtrace->first_packets.count == 1) {
    1012                         /* We the first entry hence also the first known packet */
    1013                         libtrace->first_packets.first = t->perpkt_num;
    1014                 } else {
    1015                         /* Check if we are newer than the previous 'first' packet */
    1016                         size_t first = libtrace->first_packets.first;
    1017                         struct timeval cur_ts = trace_get_timeval(dup);
    1018                         struct timeval first_ts = trace_get_timeval(libtrace->first_packets.packets[first].packet);
    1019                         if (timercmp(&cur_ts, &first_ts, <))
    1020                                 libtrace->first_packets.first = t->perpkt_num;
    1021                 }
    1022                 ASSERT_RET(pthread_spin_unlock(&libtrace->first_packets.lock), == 0);
    1023 
    1024                 mesg.code = MESSAGE_FIRST_PACKET;
    1025                 trace_message_reporter(libtrace, &mesg);
    1026                 trace_message_perpkts(libtrace, &mesg);
    1027                 t->recorded_first = true;
    1028         }
     1010
     1011        libtrace_message_t mesg = {0, {.uint64=0}, NULL};
     1012        struct timeval tv;
     1013        libtrace_packet_t * dup;
     1014
     1015        if (t->recorded_first) {
     1016                return;
     1017        }
     1018
     1019        if (IS_LIBTRACE_META_PACKET(packet)) {
     1020                return;
     1021        }
     1022
     1023        /* We mark system time against a copy of the packet */
     1024        gettimeofday(&tv, NULL);
     1025        dup = trace_copy_packet(packet);
     1026
     1027        ASSERT_RET(pthread_spin_lock(&libtrace->first_packets.lock), == 0);
     1028        libtrace->first_packets.packets[t->perpkt_num].packet = dup;
     1029        memcpy(&libtrace->first_packets.packets[t->perpkt_num].tv, &tv, sizeof(tv));
     1030        libtrace->first_packets.count++;
     1031
     1032        /* Now update the first */
     1033        if (libtrace->first_packets.count == 1) {
     1034                /* We the first entry hence also the first known packet */
     1035                libtrace->first_packets.first = t->perpkt_num;
     1036        } else {
     1037                /* Check if we are newer than the previous 'first' packet */
     1038                size_t first = libtrace->first_packets.first;
     1039                struct timeval cur_ts = trace_get_timeval(dup);
     1040                struct timeval first_ts = trace_get_timeval(libtrace->first_packets.packets[first].packet);
     1041                if (timercmp(&cur_ts, &first_ts, <))
     1042                        libtrace->first_packets.first = t->perpkt_num;
     1043        }
     1044        ASSERT_RET(pthread_spin_unlock(&libtrace->first_packets.lock), == 0);
     1045
     1046        mesg.code = MESSAGE_FIRST_PACKET;
     1047        trace_message_reporter(libtrace, &mesg);
     1048        trace_message_perpkts(libtrace, &mesg);
     1049        t->recorded_first = true;
    10291050}
    10301051
     
    12211242                int64_t initial_offset;
    12221243                int stable = trace_get_first_packet(libtrace, NULL, &first_pkt, &sys_tv);
    1223                 assert(first_pkt);
     1244                if (!first_pkt)
     1245                        return 0;
    12241246                pkt_tv = trace_get_timeval(first_pkt);
    12251247                initial_offset = (int64_t)tv_to_usec(sys_tv) - (int64_t)tv_to_usec(&pkt_tv);
Note: See TracChangeset for help on using the changeset viewer.