Changeset 5e85c23 for lib/format_erf.c


Ignore:
Timestamp:
12/19/06 16:04:52 (15 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
5d56d34
Parents:
8cecc7c
Message:

Split DAG format into it's own source files - one for DAG2.4 and another for DAG2.5.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_erf.c

    r8cecc7c r5e85c23  
    3535#include "libtrace_int.h"
    3636#include "format_helper.h"
     37#include "format_erf.h"
    3738
    3839#include <assert.h>
     
    4243#include <string.h>
    4344#include <stdlib.h>
    44 
    45 #ifdef HAVE_DAG
    46 #include <sys/mman.h>
    47 #endif
    4845
    4946#ifdef WIN32
     
    6461
    6562static struct libtrace_format_t erf;
    66 #ifdef HAVE_DAG
    67 static struct libtrace_format_t dag;
    68 #endif
    6963
    7064#define DATA(x) ((struct erf_format_data_t *)x->format_data)
    7165#define DATAOUT(x) ((struct erf_format_data_out_t *)x->format_data)
    7266
    73 #define CONNINFO DATA(libtrace)->conn_info
    7467#define INPUT DATA(libtrace)->input
    7568#define OUTPUT DATAOUT(libtrace)->output
    76 #ifdef HAVE_DAG
    77 #define DAG DATA(libtrace)->dag
    78 #define DUCK DATA(libtrace)->duck
    79 #endif
    8069#define OPTIONS DATAOUT(libtrace)->options
    8170struct erf_format_data_t {
    82         union {
    83                 struct {
    84                         char *hostname;
    85                         short port;
    86                 } rt;
    87         } conn_info;
    8871       
    8972        union {
     
    9881        } seek;
    9982
    100 #ifdef HAVE_DAG
    101         struct {
    102                 uint32_t last_duck;     
    103                 uint32_t duck_freq;
    104                 uint32_t last_pkt;
    105                 libtrace_t *dummy_duck;
    106         } duck;
    107        
    108         struct {
    109                 void *buf;
    110                 uint32_t diff;
    111                 uint32_t offset;
    112 #ifdef DAG_VERSION_2_4
    113                 uint32_t bottom;
    114                 uint32_t top;
    115 #else
    116                 uint8_t *bottom;
    117                 uint8_t *top;
    118                 unsigned int dagstream;
    119 #endif
    120         } dag;
    121 #endif
    12283};
    12384
    12485struct erf_format_data_out_t {
    125         union {
    126                 struct {
    127                         char *hostname;
    128                         short port;
    129                 } rt;
    130                 char *path;
    131         } conn_info;
    132 
    13386        union {
    13487                struct {
     
    158111} erf_index_t;
    159112
    160 #ifdef HAVE_DAG
    161 static int dag_init_input(libtrace_t *libtrace) {
    162         struct stat buf;
    163 
    164         libtrace->format_data = (struct erf_format_data_t *)
    165                 malloc(sizeof(struct erf_format_data_t));
    166         if (stat(libtrace->uridata, &buf) == -1) {
    167                 trace_set_err(libtrace,errno,"stat(%s)",libtrace->uridata);
    168                 return -1;
    169         }
    170 #ifdef DAG_VERSION_2_4
    171         DAG.top = 0;
    172         DAG.bottom = 0;
    173 #else
    174         DAG.top = NULL;
    175         DAG.bottom = NULL;
    176         DAG.dagstream = 0;
    177 #endif 
    178         if (S_ISCHR(buf.st_mode)) {
    179                 /* DEVICE */
    180                 if((INPUT.fd = dag_open(libtrace->uridata)) < 0) {
    181                         trace_set_err(libtrace,errno,"Cannot open DAG %s",
    182                                         libtrace->uridata);
    183                         return -1;
    184                 }
    185                 if((DAG.buf = (void *)dag_mmap(INPUT.fd)) == MAP_FAILED) {
    186                         trace_set_err(libtrace,errno,"Cannot mmap DAG %s",
    187                                         libtrace->uridata);
    188                         return -1;
    189                 }
    190         } else {
    191                 trace_set_err(libtrace,errno,"Not a valid dag device: %s",
    192                                 libtrace->uridata);
    193                 return -1;
    194         }
    195 
    196         DUCK.last_duck = 0;
    197         DUCK.duck_freq = 0; 
    198         DUCK.last_pkt = 0;
    199         DUCK.dummy_duck = NULL;
    200        
    201         return 0;
    202 }
    203 
    204 static int dag_config_input(libtrace_t *libtrace, trace_option_t option,
    205                                 void *data) {
    206         switch(option) {
    207                 case TRACE_META_FREQ:
    208                         DUCK.duck_freq = *(int *)data;
    209                         return 0;
    210                 case TRACE_OPTION_SNAPLEN:
    211                         /* Surely we can set this?? Fall through for now*/
    212                         return -1;
    213                 case TRACE_OPTION_PROMISC:
    214                         /* DAG already operates in a promisc fashion */
    215                         return -1;
    216                 case TRACE_OPTION_FILTER:
    217                         return -1;
    218                 default:
    219                         trace_set_err(libtrace, TRACE_ERR_UNKNOWN_OPTION,
    220                                         "Unknown or unsupported option: %i",
    221                                         option);
    222                         return -1;
    223         }
    224         assert (0);
    225 }
    226 #endif
    227113
    228114/* Dag erf ether packets have a 2 byte padding before the packet
     
    246132}
    247133
    248 static int erf_get_framing_length(const libtrace_packet_t *packet)
     134int erf_get_framing_length(const libtrace_packet_t *packet)
    249135{
    250136        return dag_record_size + erf_get_padding(packet);
     
    321207 * and slowly.
    322208 */
    323 static int erf_slow_seek_start(libtrace_t *libtrace,uint64_t erfts)
     209static int erf_slow_seek_start(libtrace_t *libtrace,uint64_t erfts UNUSED)
    324210{
    325211        if (INPUT.file) {
     
    408294
    409295
    410 #ifdef HAVE_DAG
    411 static int dag_pause_input(libtrace_t *libtrace) {
    412 #ifdef DAG_VERSION_2_4
    413         dag_stop(INPUT.fd);
    414 #else
    415         if (dag_stop_stream(INPUT.fd, DAG.dagstream) < 0) {
    416                 trace_set_err(libtrace, errno, "Could not stop DAG stream");
    417                 return -1;
    418         }
    419         /*
    420         if (dag_detach_stream(INPUT.fd, DAG.dagstream) < 0) {
    421                 trace_set_err(libtrace, errno, "Could not detach DAG stream");
    422                 return -1;
    423         }
    424         */
    425 #endif
    426         return 0; /* success */
    427 }
    428 
    429 static int dag_fin_input(libtrace_t *libtrace) {
    430         /* dag pause input implicitly called to cleanup before this */
    431        
    432         dag_close(INPUT.fd);
    433         if (DUCK.dummy_duck)
    434                 trace_destroy_dead(DUCK.dummy_duck);
    435         free(libtrace->format_data);
    436         return 0; /* success */
    437 }
    438 #endif
    439296
    440297static int erf_fin_input(libtrace_t *libtrace) {
     
    451308}
    452309 
    453 #ifdef HAVE_DAG
    454 #ifdef DAG_VERSION_2_4
    455 static int dag_get_duckinfo(libtrace_t *libtrace,
    456                                 libtrace_packet_t *packet) {
    457         dag_inf lt_dag_inf;
    458        
    459         if (packet->buf_control == TRACE_CTRL_EXTERNAL ||
    460                         !packet->buffer) {
    461                 packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
    462                 packet->buf_control = TRACE_CTRL_PACKET;
    463                 if (!packet->buffer) {
    464                         trace_set_err(libtrace, errno,
    465                                         "Cannot allocate packet buffer");
    466                         return -1;
    467                 }
    468         }
    469        
    470         packet->header = 0;
    471         packet->payload = packet->buffer;
    472        
    473         if ((ioctl(INPUT.fd, DAG_IOINF, &lt_dag_inf) < 0)) {
    474                 trace_set_err(libtrace, errno,
    475                                 "Error using DAG_IOINF");
    476                 return -1;
    477         }
    478         if (!IsDUCK(&lt_dag_inf)) {
    479                 printf("WARNING: %s does not have modern clock support - No DUCK information will be gathered\n", libtrace->uridata);
    480                 return 0;
    481         }
    482 
    483         if ((ioctl(INPUT.fd, DAG_IOGETDUCK, (duck_inf *)packet->payload)
    484                                 < 0)) {
    485                 trace_set_err(libtrace, errno, "Error using DAG_IOGETDUCK");
    486                 return -1;
    487         }
    488 
    489         packet->type = TRACE_RT_DUCK_2_4;
    490         if (!DUCK.dummy_duck)
    491                 DUCK.dummy_duck = trace_create_dead("duck:dummy");
    492         packet->trace = DUCK.dummy_duck;
    493         return sizeof(duck_inf);
    494 }       
    495 #else
    496 static int dag_get_duckinfo(libtrace_t *libtrace,
    497                                 libtrace_packet_t *packet) {
    498         daginf_t lt_dag_inf;
    499        
    500         if (packet->buf_control == TRACE_CTRL_EXTERNAL ||
    501                         !packet->buffer) {
    502                 packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
    503                 packet->buf_control = TRACE_CTRL_PACKET;
    504                 if (!packet->buffer) {
    505                         trace_set_err(libtrace, errno,
    506                                         "Cannot allocate packet buffer");
    507                         return -1;
    508                 }
    509         }
    510        
    511         packet->header = 0;
    512         packet->payload = packet->buffer;
    513        
    514         /* No need to check if we can get DUCK or not - we're modern
    515          * enough */
    516         if ((ioctl(INPUT.fd, DAGIOCDUCK, (duckinf_t *)packet->payload)
    517                                 < 0)) {
    518                 trace_set_err(libtrace, errno, "Error using DAGIOCDUCK");
    519                 return -1;
    520         }
    521 
    522         packet->type = TRACE_RT_DUCK_2_5;
    523         if (!DUCK.dummy_duck)
    524                 DUCK.dummy_duck = trace_create_dead("rt:localhost:3434");
    525         packet->trace = DUCK.dummy_duck;       
    526         return sizeof(duckinf_t);
    527 }       
    528 #endif
    529 
    530 static int dag_available(libtrace_t *libtrace) {
    531 
    532         if (DAG.diff != 0)
    533                 return DAG.diff;
    534 
    535         DAG.bottom = DAG.top;
    536 #ifdef DAG_VERSION_2_4
    537         DAG.top = dag_offset(
    538                         INPUT.fd,
    539                         &(DAG.bottom),
    540                         DAGF_NONBLOCK);
    541 
    542 #else
    543         DAG.top = dag_advance_stream(INPUT.fd, DAG.dagstream, &(DAG.bottom));
    544 #endif
    545         DAG.diff = DAG.top - DAG.bottom;
    546 
    547         DAG.offset = 0;
    548         return DAG.diff;
    549 }
    550 
    551 dag_record_t *dag_get_record(libtrace_t *libtrace) {
    552         dag_record_t *erfptr = NULL;
    553         uint16_t size;
    554 #ifdef DAG_VERSION_2_4
    555         erfptr = (dag_record_t *) ((char *)DAG.buf + (DAG.bottom + DAG.offset));
    556 #else
    557         erfptr = (dag_record_t *) dag_rx_stream_next_record(INPUT.fd,
    558                         DAG.dagstream);
    559 #endif
    560         if (!erfptr)
    561                 return NULL;
    562         size = ntohs(erfptr->rlen);
    563         assert( size >= dag_record_size );
    564         DAG.offset += size;
    565         DAG.diff -= size;
    566         return erfptr;
    567 }
    568 
    569 void dag_form_packet(dag_record_t *erfptr, libtrace_packet_t *packet) {
    570         packet->buffer = erfptr;
    571         packet->header = erfptr;
    572         if (erfptr->flags.rxerror == 1) {
    573                 /* rxerror means the payload is corrupt - drop it
    574                  * by tweaking rlen */
    575                 packet->payload = NULL;
    576                 erfptr->rlen = htons(erf_get_framing_length(packet));
    577         } else {
    578                 packet->payload = (char*)packet->buffer
    579                         + erf_get_framing_length(packet);
    580         }
    581 
    582 }
    583 
    584 /* FIXME: dag_read_packet shouldn't update the pointers, dag_fin_packet
    585  * should do that.
    586  */
    587 static int dag_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
    588         int numbytes;
    589         int size = 0;
    590         struct timeval tv;
    591         dag_record_t *erfptr = NULL;
    592 
    593         if (DUCK.last_pkt - DUCK.last_duck > DUCK.duck_freq &&
    594                         DUCK.duck_freq != 0) {
    595                 size = dag_get_duckinfo(libtrace, packet);
    596                 DUCK.last_duck = DUCK.last_pkt;
    597                 if (size != 0) {
    598                         return size;
    599                 }
    600                 /* No DUCK support, so don't waste our time anymore */
    601                 DUCK.duck_freq = 0;
    602         }
    603        
    604         if (packet->buf_control == TRACE_CTRL_PACKET) {
    605                 packet->buf_control = TRACE_CTRL_EXTERNAL;
    606                 free(packet->buffer);
    607                 packet->buffer = 0;
    608         }
    609        
    610         packet->type = TRACE_RT_DATA_ERF;
    611 
    612         do {
    613                 numbytes = dag_available(libtrace);
    614                 if (numbytes < 0)
    615                         return numbytes;
    616                 if (numbytes == 0)
    617                         continue;
    618                 erfptr = dag_get_record(libtrace);
    619                
    620         } while (erfptr == NULL);
    621 
    622         dag_form_packet(erfptr, packet);
    623        
    624         tv = trace_get_timeval(packet);
    625         DUCK.last_pkt = tv.tv_sec;
    626         return packet->payload ? ntohs(erfptr->rlen) : erf_get_framing_length(packet);
    627 }
    628        
    629 static int dag_start_input(libtrace_t *libtrace) {
    630         struct timeval zero, nopoll;
    631         zero.tv_sec = 0;
    632         zero.tv_usec = 0;
    633         nopoll = zero;
    634 
    635 #ifdef DAG_VERSION_2_4
    636         if(dag_start(INPUT.fd) < 0) {
    637                 trace_set_err(libtrace,errno,"Cannot start DAG %s",
    638                                 libtrace->uridata);
    639                 return -1;
    640         }
    641 #else
    642         if (dag_attach_stream(INPUT.fd, DAG.dagstream, 0, 0) < 0) {
    643                 trace_set_err(libtrace, errno, "Cannot attach DAG stream");
    644                 return -1;
    645         }
    646         if (dag_start_stream(INPUT.fd, DAG.dagstream) < 0) {
    647                 trace_set_err(libtrace, errno, "Cannot start DAG stream");
    648                 return -1;
    649         }
    650         dag_set_stream_poll(INPUT.fd, DAG.dagstream, 0, &zero, &nopoll);
    651 #endif
    652         /* dags appear to have a bug where if you call dag_start after
    653          * calling dag_stop, and at least one packet has arrived, bad things
    654          * happen.  flush the memory hole
    655          */
    656         while(dag_available(libtrace)!=0)
    657                 DAG.diff=0;
    658         return 0;
    659 }
    660 #endif
    661310
    662311static int erf_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
     
    810459        }
    811460       
    812         if (packet->trace->format == &erf 
    813 #ifdef HAVE_DAG
    814                         || packet->trace->format == &dag
    815 #endif
    816                         ) {
    817                 numbytes = erf_dump_packet(libtrace,
     461        if (packet->type == TRACE_RT_DATA_ERF) {
     462                        numbytes = erf_dump_packet(libtrace,
    818463                                (dag_record_t *)packet->header,
    819464                                pad,
     
    863508}
    864509
    865 static libtrace_linktype_t erf_get_link_type(const libtrace_packet_t *packet) {
     510libtrace_linktype_t erf_get_link_type(const libtrace_packet_t *packet) {
    866511        dag_record_t *erfptr = 0;
    867512        erfptr = (dag_record_t *)packet->header;
     
    869514}
    870515
    871 static libtrace_direction_t erf_get_direction(const libtrace_packet_t *packet) {
     516libtrace_direction_t erf_get_direction(const libtrace_packet_t *packet) {
    872517        dag_record_t *erfptr = 0;
    873518        erfptr = (dag_record_t *)packet->header;
     
    875520}
    876521
    877 static libtrace_direction_t erf_set_direction(libtrace_packet_t *packet, libtrace_direction_t direction) {
     522libtrace_direction_t erf_set_direction(libtrace_packet_t *packet, libtrace_direction_t direction) {
    878523        dag_record_t *erfptr = 0;
    879524        erfptr = (dag_record_t *)packet->header;
     
    882527}
    883528
    884 static uint64_t erf_get_erf_timestamp(const libtrace_packet_t *packet) {
     529uint64_t erf_get_erf_timestamp(const libtrace_packet_t *packet) {
    885530        dag_record_t *erfptr = 0;
    886531        erfptr = (dag_record_t *)packet->header;
     
    888533}
    889534
    890 static int erf_get_capture_length(const libtrace_packet_t *packet) {
     535int erf_get_capture_length(const libtrace_packet_t *packet) {
    891536        dag_record_t *erfptr = 0;
    892537        int caplen;
     
    902547}
    903548
    904 static int erf_get_wire_length(const libtrace_packet_t *packet) {
     549int erf_get_wire_length(const libtrace_packet_t *packet) {
    905550        dag_record_t *erfptr = 0;
    906551        erfptr = (dag_record_t *)packet->header;
     
    908553}
    909554
    910 static size_t erf_set_capture_length(libtrace_packet_t *packet, size_t size) {
     555size_t erf_set_capture_length(libtrace_packet_t *packet, size_t size) {
    911556        dag_record_t *erfptr = 0;
    912557        assert(packet);
     
    919564        return trace_get_capture_length(packet);
    920565}
    921 
    922 #ifdef HAVE_DAG
    923 static libtrace_eventobj_t trace_event_dag(libtrace_t *trace,
    924                                         libtrace_packet_t *packet) {
    925         libtrace_eventobj_t event = {0,0,0.0,0};
    926         int dag_fd;
    927         int data;
    928 
    929         if (trace->format->get_fd) {
    930                 dag_fd = trace->format->get_fd(trace);
    931         } else {
    932                 dag_fd = 0;
    933         }
    934        
    935         data = dag_available(trace);
    936 
    937         if (data > 0) {
    938                 event.size = dag_read_packet(trace,packet);
    939                 //DATA(trace)->dag.diff -= event.size;
    940                 if (trace->filter) {
    941                         if (trace_apply_filter(trace->filter, packet)) {
    942                                 event.type = TRACE_EVENT_PACKET;
    943                         } else {
    944                                 event.type = TRACE_EVENT_SLEEP;
    945                                 event.seconds = 0.000001;
    946                                 return event;
    947                         }
    948                 } else {
    949                         event.type = TRACE_EVENT_PACKET;
    950                 }
    951                 if (trace->snaplen > 0) {
    952                         trace_set_capture_length(packet, trace->snaplen);
    953                 }
    954 
    955                 return event;
    956         }
    957         event.type = TRACE_EVENT_SLEEP;
    958         event.seconds = 0.0001;
    959         return event;
    960 }
    961 #endif
    962 
    963 #ifdef HAVE_DAG
    964 static void dag_help(void) {
    965         printf("dag format module: $Revision$\n");
    966         printf("Supported input URIs:\n");
    967         printf("\tdag:/dev/dagn\n");
    968         printf("\n");
    969         printf("\te.g.: dag:/dev/dag0\n");
    970         printf("\n");
    971         printf("Supported output URIs:\n");
    972         printf("\tnone\n");
    973         printf("\n");
    974 }
    975 #endif
    976566
    977567static void erf_help(void) {
     
    1034624};
    1035625
    1036 #ifdef HAVE_DAG
    1037 static struct libtrace_format_t dag = {
    1038         "dag",
    1039         "$Id$",
    1040         TRACE_FORMAT_ERF,
    1041         dag_init_input,                 /* init_input */       
    1042         dag_config_input,               /* config_input */
    1043         dag_start_input,                /* start_input */
    1044         dag_pause_input,                /* pause_input */
    1045         NULL,                           /* init_output */
    1046         NULL,                           /* config_output */
    1047         NULL,                           /* start_output */
    1048         dag_fin_input,                  /* fin_input */
    1049         NULL,                           /* fin_output */
    1050         dag_read_packet,                /* read_packet */
    1051         NULL,                           /* fin_packet */
    1052         NULL,                           /* write_packet */
    1053         erf_get_link_type,              /* get_link_type */
    1054         erf_get_direction,              /* get_direction */
    1055         erf_set_direction,              /* set_direction */
    1056         erf_get_erf_timestamp,          /* get_erf_timestamp */
    1057         NULL,                           /* get_timeval */
    1058         NULL,                           /* get_seconds */
    1059         NULL,                           /* seek_erf */
    1060         NULL,                           /* seek_timeval */
    1061         NULL,                           /* seek_seconds */
    1062         erf_get_capture_length,         /* get_capture_length */
    1063         erf_get_wire_length,            /* get_wire_length */
    1064         erf_get_framing_length,         /* get_framing_length */
    1065         erf_set_capture_length,         /* set_capture_length */
    1066         NULL,                           /* get_fd */
    1067         trace_event_dag,                /* trace_event */
    1068         dag_help,                       /* help */
    1069         NULL                            /* next pointer */
    1070 };
    1071 #endif
    1072626
    1073627void erf_constructor(void) {
    1074628        register_format(&erf);
    1075 #ifdef HAVE_DAG
    1076         register_format(&dag);
    1077 #endif
    1078 }
     629}
Note: See TracChangeset for help on using the changeset viewer.