Changeset b663d33 for lib


Ignore:
Timestamp:
05/18/18 11:39:59 (3 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
cachetimestamps, develop, etsilive, master, rc-4.0.4, ringdecrementfix, ringperformance
Children:
00365c6
Parents:
df87f00
git-author:
Shane Alcock <salcock@…> (12/18/17 18:10:37)
git-committer:
Shane Alcock <salcock@…> (05/18/18 11:39:59)
Message:

etsilive format is now functional (for single-threaded only).

Packets are decoded using libwandder. The ETSI headers are treated
as a meta-data layer.

Libpacketdump support has also been added for all fields and
structures that libwandder understands.

Location:
lib
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • lib/Makefile.am

    rdf87f00 rb663d33  
    5252endif
    5353
     54if HAVE_WANDDER
     55ETSISOURCES=format_etsilive.c
     56else
     57ETSISOURCES=
     58endif
     59
    5460libtrace_la_SOURCES = trace.c trace_parallel.c common.h \
    5561                format_erf.c format_pcap.c format_legacy.c \
    5662                format_rt.c format_helper.c format_helper.h format_pcapfile.c \
    5763                format_duck.c format_tsh.c $(NATIVEFORMATS) $(BPFFORMATS) \
    58                 format_atmhdr.c format_pcapng.c format_etsilive.c \
     64                format_atmhdr.c format_pcapng.c \
    5965                libtrace_int.h lt_inttypes.h lt_bswap.h \
    6066                linktypes.c link_wireless.c byteswap.c \
     
    6470                protocols_application.c \
    6571                $(DAGSOURCE) format_erf.h format_ndag.c format_ndag.h \
    66                 $(BPFJITSOURCE) \
     72                $(BPFJITSOURCE) $(ETSISOURCES) \
    6773                libtrace_arphrd.h \
    6874                data-struct/ring_buffer.c data-struct/vector.c \
  • lib/format_etsilive.c

    rdf87f00 rb663d33  
    3434#include "data-struct/simple_circular_buffer.h"
    3535
    36 #include "etsiasn1tab.h"
     36#include <libwandder.h>
     37#include <libwandder_etsili.h>
    3738
    3839#include <assert.h>
     
    4344#include <stdlib.h>
    4445#include <unistd.h>
    45 #include <libtasn1.h>
    4646#include <sys/socket.h>
    4747#include <sys/types.h>
     
    5555
    5656        uint64_t timestamp;
    57         uint8_t *ccptr;
    58         uint8_t *iriptr;
    5957        uint16_t length;
    6058
     
    8482        etsithread_t *receivers;
    8583        int nextthreadid;
    86         ASN1_TYPE etsidef;
    8784} etsilive_format_data_t;
    8885
     
    210207static int etsilive_init_input(libtrace_t *libtrace) {
    211208        char *scan = NULL;
    212         char errordesc[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    213 
    214209        libtrace->format_data = (etsilive_format_data_t *)malloc(
    215210                        sizeof(etsilive_format_data_t));
     
    230225        FORMAT_DATA->listenport = strdup(scan + 1);
    231226
    232         if (asn1_array2tree(etsili_asn1tab, &(FORMAT_DATA->etsidef),
    233                                 errordesc) != ASN1_SUCCESS) {
    234                 trace_set_err(libtrace, TRACE_ERR_BAD_FORMAT,
    235                         "Failed to parse ETSI ASN.1 array: %s", errordesc);
    236                 return -1;
    237         }
    238 
    239227        return 0;
    240228}
     
    251239                free(FORMAT_DATA->listenport);
    252240        }
    253         asn1_delete_structure(&(FORMAT_DATA->etsidef));
    254241        free(libtrace->format_data);
    255242        return 0;
     
    339326                esock->cached.timestamp = 0;
    340327                esock->cached.length = 0;
    341                 esock->cached.iriptr = NULL;
    342                 esock->cached.ccptr = NULL;
    343328
    344329                et->sourcecount += 1;
     
    406391static etsisocket_t *select_next_packet(etsithread_t *et, libtrace_t *libtrace) {
    407392
    408         int i, asnret;
     393        int i;
    409394        etsisocket_t *esock = NULL;
    410         char errordesc[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    411         char readstring[100];
    412395        uint64_t earliest = 0;
    413         uint64_t currentts = 0;
     396        uint64_t current;
     397        struct timeval tv;
    414398        uint32_t available;
    415399        uint8_t *ptr = NULL;
    416         ASN1_TYPE psheader;
    417         int ider_len;
    418         int readlen;
     400        wandder_decoder_t dec;
     401        uint32_t reclen = 0;
    419402
    420403        for (i = 0; i < et->sourcecount; i++) {
     
    426409                 */
    427410                if (et->sources[i].cached.timestamp != 0) {
    428                         currentts = et->sources[i].cached.timestamp;
    429 
    430                         if (earliest == 0 || earliest > currentts) {
    431                                 earliest = currentts;
     411                        current = et->sources[i].cached.timestamp;
     412
     413                        if (earliest == 0 || earliest > current) {
     414                                earliest = current;
    432415                                esock = &(et->sources[i]);
    433416                        }
     
    438421                                &available);
    439422
    440                 if (available == 0) {
     423                if (available == 0 || ptr == NULL) {
    441424                        continue;
    442425                }
    443426
    444                 /* Try to decode whatever is at the front of the buffer. */
    445                 asnret = asn1_create_element(FORMAT_DATA->etsidef,
    446                                 "LI-PS-PDU.PSHeader", &psheader);
    447                 if (asnret != ASN1_SUCCESS) {
    448                         fprintf(stderr, "failed to create asn1 element\n");
    449                         asn1_delete_structure(&psheader);
    450                         continue;
    451                 }
    452 
    453                 ider_len = (int)available;
    454                 asnret = asn1_der_decoding2(&psheader, ptr, &ider_len, 0, errordesc);
    455 
    456                 /* Failed? Must not have the whole packet... */
    457                 if (asnret != ASN1_SUCCESS) {
    458                         int j;
    459                         for (j = 0; j < available; j++) {
    460                                 printf("%02x ", ptr[j]);
    461                                 if (j % 16 == 15 && j > 0) {
    462                                         printf("\n");
    463                                 }
    464                                 if (j >= 16 * 16)
    465                                         break;
    466                         }
    467                         fprintf(stderr, "%d failed to decode asn1 content: %s\n",
    468                                         available, errordesc);
    469                         assert(0);
    470                         asn1_delete_structure(&psheader);
    471                         continue;
    472                 }
    473 
    474                 readlen = sizeof(readstring);
    475                 asnret = asn1_read_value(psheader, "timeStamp", readstring, &readlen);
    476 
    477                 if (asnret == ASN1_SUCCESS) {
    478                         fprintf(stderr, "timeStamp=%s\n", readstring);
    479                         /* TODO turn to 64 bit timestamp */
     427                init_wandder_decoder(&dec, ptr, available, false);
     428                if (et->sources[i].cached.length != 0) {
     429                        reclen = et->sources[i].cached.length;
    480430                } else {
    481                         int msts_sec;
    482                         int msts_ms;
    483 
    484                         readlen = sizeof(int);
    485                         asnret = asn1_read_value(psheader, "microSecondTimeStamp.seconds", &msts_sec, &readlen);
    486 
    487                         if (asnret != ASN1_SUCCESS) {
    488                                 fprintf(stderr, "no microSecondTimeStamp.seconds\n");
     431                        reclen = wandder_etsili_get_pdu_length(&dec);
     432
     433                        if (reclen == 0) {
     434                                free_wandder_decoder(&dec);
    489435                                continue;
    490436                        }
    491 
    492                         readlen = sizeof(int);
    493                         asnret = asn1_read_value(psheader, "microSecondTimeStamp.microSeconds", &msts_ms, &readlen);
    494 
    495                         if (asnret != ASN1_SUCCESS) {
    496                                 fprintf(stderr, "no microSecondTimeStamp.microSeconds?\n");
    497                                 continue;
    498                         }
    499                         fprintf(stderr, "microSecondTimeStamp=%d.%d\n", msts_sec, msts_ms);
    500                 }
    501                 assert(0);
     437                }
     438
     439                if (available < reclen) {
     440                        /* Don't have the whole PDU yet */
     441                        free_wandder_decoder(&dec);
     442                        continue;
     443                }
     444
     445                /* Get the timestamp */
     446
     447                tv = wandder_etsili_get_header_timestamp(&dec);
     448                if (tv.tv_sec == 0) {
     449                        free_wandder_decoder(&dec);
     450                        continue;
     451                }
     452                current = ((((uint64_t)tv.tv_sec) << 32) +
     453                                (((uint64_t)tv.tv_usec << 32)/1000000));
     454
    502455                /* Success, cache everything we used so we don't have to
    503456                 * decode this packet again.
    504457                 */
    505 
    506                 /* Advance the read pointer for this buffer */
     458                et->sources[i].cached.timestamp = current;
     459                et->sources[i].cached.length = reclen;
     460
    507461
    508462                /* Don't forget to update earliest and esock... */
     463                if (current < earliest || earliest == 0) {
     464                        esock = &(et->sources[i]);
     465                        earliest = current;
     466                }
    509467
    510468        }
     
    514472static int etsilive_prepare_received(libtrace_t *libtrace, etsithread_t *et,
    515473                etsisocket_t *esock, libtrace_packet_t *packet) {
     474
     475        uint32_t available = 0;
     476
     477        packet->trace = libtrace;
     478        packet->buffer = libtrace_scb_get_read(&(esock->recvbuffer),
     479                                        &available);
     480        packet->buf_control = TRACE_CTRL_EXTERNAL;
     481        packet->header = NULL;          // Check this is ok to do
     482        packet->payload = packet->buffer;
     483        packet->type = TRACE_RT_DATA_ETSILI;
     484        packet->order = esock->cached.timestamp;
     485        packet->error = esock->cached.length;
     486
     487        packet->wire_length = esock->cached.length;
     488        packet->capture_length = esock->cached.length;
     489
     490        /* Advance the read pointer for this buffer
     491         * TODO should really do this in fin_packet, but will need a ref
     492         * to esock to do this properly */
     493        libtrace_scb_advance_read(&(esock->recvbuffer), esock->cached.length);
     494        esock->cached.length = 0;
     495        esock->cached.timestamp = 0;
     496
     497
    516498        return 1;
    517499}
     
    562544}
    563545
    564 
    565 
     546static int etsilive_get_pdu_length(const libtrace_packet_t *packet) {
     547
     548        /* Should never get here because cache is set when packet is read */
     549        wandder_decoder_t dec;
     550        size_t reclen;
     551
     552        /* 0 should be ok here for quickly evaluating the first length
     553         * field... */
     554        init_wandder_decoder(&dec, packet->buffer, 0, false);
     555        reclen = (size_t)wandder_etsili_get_pdu_length(&dec);
     556
     557        free_wandder_decoder(&dec);
     558
     559        return reclen;
     560}
     561
     562static int etsilive_get_framing_length(const libtrace_packet_t *packet) {
     563
     564        return 0;
     565}
     566
     567static struct timeval etsilive_get_timeval(const libtrace_packet_t *packet) {
     568        /* TODO add cached timestamps to libtrace so we don't have to look
     569         * this up again. */
     570        struct timeval tv;
     571        wandder_decoder_t dec;
     572
     573        tv.tv_sec = 0;
     574        tv.tv_usec = 0;
     575
     576        init_wandder_decoder(&dec, packet->buffer, 0, false);
     577        tv = wandder_etsili_get_header_timestamp(&dec);
     578        free_wandder_decoder(&dec);
     579        return tv;
     580}
     581
     582static libtrace_linktype_t etsilive_get_link_type(
     583                const libtrace_packet_t *packet) {
     584        return TRACE_TYPE_ETSILI;
     585}
    566586
    567587static struct libtrace_format_t etsilive = {
     
    584604        NULL,                           /* fin_packet */
    585605        NULL,                           /* write_packet */
    586         NULL, //etsilive_get_link_type,         /* get_link_type */
     606        etsilive_get_link_type,         /* get_link_type */
    587607        NULL,                           /* get_direction */
    588608        NULL,                           /* set_direction */
    589609        NULL,                           /* get_erf_timestamp */
    590         NULL,                           /* get_timeval */
     610        etsilive_get_timeval,           /* get_timeval */
    591611        NULL,                           /* get_timespec */
    592612        NULL,                           /* get_seconds */
     
    594614        NULL,                           /* seek_timeval */
    595615        NULL,                           /* seek_seconds */
    596         NULL, //etsilive_get_capture_length,    /* get_capture_length */
    597         NULL, //etsilive_get_wire_length,       /* get_wire_length */
    598         NULL, //etsilive_get_framing_length,    /* get_framing_length */
     616        etsilive_get_pdu_length,       /* get_capture_length */
     617        etsilive_get_pdu_length,       /* get_wire_length */
     618        etsilive_get_framing_length,    /* get_framing_length */
    599619        NULL,                           /* set_capture_length */
    600620        NULL,                           /* get_received_packets */
  • lib/linktypes.c

    ra857389 rb663d33  
    109109                case TRACE_TYPE_METADATA:
    110110                case TRACE_TYPE_NONDATA:
     111                case TRACE_TYPE_ETSILI:
    111112                        break;
    112113                case TRACE_TYPE_UNKNOWN:
     
    211212                case TRACE_TYPE_NONDATA:
    212213                case TRACE_TYPE_OPENBSD_LOOP:
     214                case TRACE_TYPE_ETSILI:
    213215                case TRACE_TYPE_UNKNOWN:
    214216                        break;
  • lib/protocols_l2.c

    ra857389 rb663d33  
    483483                case TRACE_TYPE_PFLOG:
    484484                case TRACE_TYPE_ERF_META:
     485                case TRACE_TYPE_ETSILI:
    485486                        break;
    486487                case TRACE_TYPE_UNKNOWN:
     
    518519                                case TRACE_TYPE_80211_PRISM:
    519520                                case TRACE_TYPE_PFLOG:
     521<<<<<<< HEAD
    520522                                case TRACE_TYPE_ERF_META:
     523=======
     524                                case TRACE_TYPE_ETSILI:
     525>>>>>>> etsilive format is now functional (for single-threaded only).
    521526                                        break;
    522527                                case TRACE_TYPE_UNKNOWN:
     
    574579                case TRACE_TYPE_PFLOG:
    575580                case TRACE_TYPE_LINUX_SLL:
     581                case TRACE_TYPE_ETSILI:
    576582                        return NULL;
    577583
     
    696702                case TRACE_TYPE_80211_PRISM:
    697703                case TRACE_TYPE_80211_RADIO:
     704                case TRACE_TYPE_ETSILI:
    698705                        assert(!"Metadata headers should already be skipped");
    699706                        break;
     
    746753                case TRACE_TYPE_80211_PRISM:
    747754                case TRACE_TYPE_80211_RADIO:
     755                case TRACE_TYPE_ETSILI:
    748756                        assert(!"Metadata headers should already be skipped");
    749757                        break;
  • lib/protocols_pktmeta.c

    ra857389 rb663d33  
    2828#include "protocols.h"
    2929#include <assert.h>
     30
     31#ifdef HAVE_WANDDER
     32#include <libwandder_etsili.h>
     33#endif
    3034
    3135/* This file contains all the protocol decoding functions for the meta-data
     
    121125}
    122126
     127static void *trace_get_payload_from_etsili(const void *link,
     128                libtrace_linktype_t *type, uint32_t *remaining) {
     129
     130#ifdef HAVE_WANDDER
     131        wandder_decoder_t dec;
     132        uint8_t *ccptr;
     133
     134        init_wandder_decoder(&dec, (uint8_t *)link, *remaining, false);
     135        ccptr = wandder_etsili_get_cc_contents(&dec, remaining);
     136        /* Assuming all CCs are IP for now */
     137        *type = TRACE_TYPE_NONE;
     138        return ccptr;
     139
     140#else
     141        *remaining = NULL;
     142        return NULL;
     143#endif
     144
     145}
     146
    123147DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet,
    124148                libtrace_linktype_t *linktype,
     
    139163                case TRACE_TYPE_80211_PRISM:
    140164                case TRACE_TYPE_ERF_META:
     165                case TRACE_TYPE_ETSILI:
    141166                        return pktbuf;
    142167                /* Non metadata packets */
     
    199224                                        linktype, remaining);
    200225                        return nexthdr;
     226                case TRACE_TYPE_ETSILI:
     227                        nexthdr = trace_get_payload_from_etsili(meta,
     228                                        linktype, remaining);
     229                        return nexthdr;
     230
    201231                case TRACE_TYPE_HDLC_POS:
    202232                case TRACE_TYPE_ETH:
  • lib/trace.c

    rdf87f00 rb663d33  
    148148                rt_constructor();
    149149                ndag_constructor();
     150#ifdef HAVE_WANDDER
    150151                etsilive_constructor();
     152#endif
    151153#ifdef HAVE_DAG
    152154                dag_constructor();
Note: See TracChangeset for help on using the changeset viewer.