Changeset 5952ff0 for lib/format_dag24.c


Ignore:
Timestamp:
02/04/10 10:36:53 (11 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:
43c00e5
Parents:
2c743a7
Message:
  • Updated internal documentation and licensing for several format modules
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_dag24.c

    r5778738 r5952ff0  
    22 * This file is part of libtrace
    33 *
    4  * Copyright (c) 2007,2008 The University of Waikato, Hamilton, New Zealand.
    5  * Authors: Daniel Lawson
     4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
     5 * New Zealand.
     6 *
     7 * Authors: Daniel Lawson
    68 *          Perry Lorier
    7  *          Shane Alcock
    8  *
     9 *          Shane Alcock 
     10 *         
    911 * All rights reserved.
    1012 *
    11  * This code has been developed by the University of Waikato WAND
     13 * This code has been developed by the University of Waikato WAND 
    1214 * research group. For further information please see http://www.wand.net.nz/
    1315 *
     
    2931 *
    3032 */
     33
    3134#define _GNU_SOURCE
    3235
     
    5962#endif
    6063
     64/* This format deals with DAG cards that are using drivers from the 2.4.X
     65 * versions.
     66 *
     67 * DAG is a LIVE capture format.
     68 *
     69 * We do not support writing using this format, as transmit support was not
     70 * added until a subsequent version of the DAG software (see format_dag25.c).
     71 * Instead, you should write the packets read using this format as ERF traces.
     72 */
    6173
    6274static struct libtrace_format_t dag;
     
    6678#define FORMAT_DATA DATA(libtrace)
    6779
     80/* "Global" data that is stored for each DAG input trace */
    6881struct dag_format_data_t {
     82
     83        /* Data required for regular DUCK reporting */
    6984        struct {
     85                /* Timestamp of the last DUCK report */
    7086                uint32_t last_duck;
     87                /* The number of seconds between each DUCK report */
    7188                uint32_t duck_freq;
     89                /* Timestamp of the last packet read from the DAG card */
    7290                uint32_t last_pkt;
     91                /* Dummy trace to ensure DUCK packets are dealt with using
     92                 * the DUCK format functions */
    7393                libtrace_t *dummy_duck;
    7494        } duck;
    7595       
     96        /* File descriptor for the DAG card */
    7697        int fd;
     98        /* Pointer to DAG memory hole */
    7799        void *buf;
     100        /* Difference between the top and bottom pointers in the DAG memory
     101         * hole, i.e. the amount of available data to read */
    78102        uint32_t diff;
     103        /* The amount of data read thus far from the start of the bottom
     104         * pointer */
    79105        uint32_t offset;
     106        /* The offset for the first unread byte in the DAG memory hole */
    80107        uint32_t bottom;
     108        /* The offset for the last unread byte in the DAG memory hole */
    81109        uint32_t top;
     110        /* The number of packets that have been dropped */
    82111        uint64_t drops;
    83112};
    84113
     114/* Determines if a given filename refers to a DAG device */
    85115static void dag_probe_filename(const char *filename)
    86116{
     
    98128}
    99129
     130/* Initialises the DAG "global" variables */
    100131static void dag_init_format_data(libtrace_t *libtrace) {
    101132        libtrace->format_data = (struct dag_format_data_t *)
     
    115146}
    116147
     148/* Determines how much data is available for reading on the DAG card and
     149 * updates the various offsets accordingly */
    117150static int dag_available(libtrace_t *libtrace) {
    118151
     
    130163}
    131164
     165/* Initialises a DAG input trace */
    132166static int dag_init_input(libtrace_t *libtrace) {
    133167        struct stat buf;
     
    145179        }
    146180
    147        
     181
     182        /* Make sure a DAG device with the right name exists */
    148183        if (stat(dag_dev_name, &buf) == -1) {
    149184                trace_set_err(libtrace,errno,"stat(%s)",dag_dev_name);
     
    161196                        return -1;
    162197                }
     198
     199                /* Memory-map ourselves a pointer to the DAG memory hole */
    163200                if((FORMAT_DATA->buf = (void *)dag_mmap(FORMAT_DATA->fd)) == MAP_FAILED) {
    164201                        trace_set_err(libtrace,errno,"Cannot mmap DAG %s",
     
    179216}
    180217
     218/* Configures a DAG input trace */
    181219static int dag_config_input(libtrace_t *libtrace, trace_option_t option,
    182220                                void *data) {
    183221        switch(option) {
    184222                case TRACE_OPTION_META_FREQ:
     223                        /* We use this option to specify the frequency of
     224                         * DUCK updates */
    185225                        DUCK.duck_freq = *(int *)data;
    186226                        return 0;
     
    192232                        return -1;
    193233                case TRACE_OPTION_FILTER:
     234                        /* Cards that use the older drivers don't do
     235                         * filtering */
    194236                        return -1;
    195237                case TRACE_OPTION_EVENT_REALTIME:
     238                        /* Live capture is always going to be realtime */
    196239                        return -1;
    197240        }
     
    199242}
    200243
     244/* Starts a DAG input trace */
    201245static int dag_start_input(libtrace_t *libtrace) {     
    202246        if(dag_start(FORMAT_DATA->fd) < 0) {
     
    213257}
    214258
     259/* Pauses a DAG input trace */
    215260static int dag_pause_input(libtrace_t *libtrace) {
    216261        dag_stop(FORMAT_DATA->fd);
     
    218263}
    219264
     265/* Destroys a DAG input trace */
    220266static int dag_fin_input(libtrace_t *libtrace) {
    221267        dag_close(FORMAT_DATA->fd);
     
    226272}
    227273
     274/* Extracts DUCK information from the DAG card and produces a DUCK packet */
    228275static int dag_get_duckinfo(libtrace_t *libtrace,
    229276                                libtrace_packet_t *packet) {
    230277        dag_inf lt_dag_inf;
    231278
     279        /* Allocate memory for the DUCK data */
    232280        if (packet->buf_control == TRACE_CTRL_EXTERNAL ||
    233281                        !packet->buffer) {
     
    241289        }
    242290
     291        /* DUCK doesn't actually have a format header, as such */
    243292        packet->header = 0;
    244293        packet->payload = packet->buffer;
    245294
     295        /* Check that the DAG card supports DUCK */
    246296        if ((ioctl(FORMAT_DATA->fd, DAG_IOINF, &lt_dag_inf) < 0)) {
    247297                trace_set_err(libtrace, errno,
     
    254304        }
    255305
     306        /* Get the DUCK information from the card */
    256307        if ((ioctl(FORMAT_DATA->fd, DAG_IOGETDUCK, (duck_inf *)packet->payload)
    257308                                < 0)) {
     
    260311        }
    261312
     313        /* Set the type */
    262314        packet->type = TRACE_RT_DUCK_2_4;
     315
     316        /* Set the packet's trace to point at a DUCK trace, so that the
     317         * DUCK format functions will be called on the packet rather than the
     318         * DAG ones */
    263319        if (!DUCK.dummy_duck)
    264320                DUCK.dummy_duck = trace_create_dead("duck:dummy");
     
    267323}
    268324
    269 
     325/* Reads the next ERF record from the DAG memory hole */
    270326static dag_record_t *dag_get_record(libtrace_t *libtrace) {
    271327        dag_record_t *erfptr = NULL;
     
    283339}
    284340
     341/* Converts a buffer containing a recently read DAG packet record into a
     342 * libtrace packet */
    285343static int dag_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
    286344                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
    287345
    288346        dag_record_t *erfptr;
     347        /* If the packet previously owned a buffer that is not the buffer
     348         * that contains the new packet data, we're going to need to free the
     349         * old one to avoid memory leaks */
    289350        if (packet->buffer != buffer &&
    290351                        packet->buf_control == TRACE_CTRL_PACKET) {
     
    292353        }
    293354
     355        /* Set the buffer owner appropriately */
    294356        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
    295357                packet->buf_control = TRACE_CTRL_PACKET;
     
    297359                packet->buf_control = TRACE_CTRL_EXTERNAL;
    298360       
     361        /* Update packet pointers and type appropriately */
    299362        erfptr = (dag_record_t *)buffer;
    300363        packet->buffer = erfptr;
     
    303366
    304367        if (erfptr->flags.rxerror == 1) {
    305                 /* rxerror means the payload is corrupt - drop it
     368                /* rxerror means the payload is corrupt - drop the payload
    306369                 * by tweaking rlen */
    307370                packet->payload = NULL;
     
    316379        }
    317380
     381        /* Update the dropped packets counter, using the value of the ERF
     382         * loss counter */
    318383        DATA(libtrace)->drops += ntohs(erfptr->lctr);
    319384
     
    322387}
    323388
     389/* Reads the next available packet from a DAG card, in a BLOCKING fashion
     390 *
     391 * If DUCK reporting is enabled, the packet returned may be a DUCK update */
    324392static int dag_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
    325393        int numbytes;
     
    329397        dag_record_t *erfptr = NULL;
    330398
     399        /* Check if we're due for a DUCK report */
    331400        if (DUCK.last_pkt - DUCK.last_duck > DUCK.duck_freq &&
    332401                        DUCK.duck_freq != 0) {
     
    340409        }
    341410
     411        /* Don't let anyone try to free our DAG memory hole */
    342412        flags |= TRACE_PREP_DO_NOT_OWN_BUFFER;
    343413       
    344         if (packet->buf_control == TRACE_CTRL_PACKET) {
     414        /* If the packet buffer is currently owned by libtrace, free it so
     415         * that we can set the packet to point into the DAG memory hole */
     416        if (packet->buf_control == TRACE_CTRL_PACKET) {
    345417                packet->buf_control = TRACE_CTRL_EXTERNAL;
    346418                free(packet->buffer);
     
    348420        }
    349421
    350 
     422        /* Grab a full ERF record */
    351423        do {
    352424                numbytes = dag_available(libtrace);
     
    358430        } while (erfptr == NULL);
    359431       
    360        
     432        /* Prepare the libtrace packet */
    361433        if (dag_prepare_packet(libtrace, packet, erfptr, TRACE_RT_DATA_ERF,
    362434                                flags))
    363435                return -1;
     436       
     437        /* Update the DUCK timer */
    364438        tv = trace_get_timeval(packet);
    365439        DUCK.last_pkt = tv.tv_sec;
     
    367441}
    368442
     443/* Attempts to read a packet from a DAG card in a NON-BLOCKING fashion. If
     444 * a packet is available, we will return a packet event. Otherwise we will
     445 * return a SLEEP event (as we cannot select on the DAG file descriptor).
     446 */
    369447static libtrace_eventobj_t trace_event_dag(libtrace_t *trace,
    370448                                        libtrace_packet_t *packet) {
     
    375453                data = dag_available(trace);
    376454
     455                /* If no data is available, drop out and return a sleep event */
    377456                if (data <= 0)
    378457                        break;
    379458
     459                /* Data is available, so we can call the blocking read because
     460                 * we know that we will get a packet straight away */
    380461                event.size = dag_read_packet(trace,packet);
    381462                //DATA(trace)->dag.diff -= event.size;
     463               
     464                /* XXX trace_read_packet() normally applies the following
     465                 * config options for us, but this function is called via
     466                 * trace_event() so we have to do it ourselves */
     467
     468                /* Check that the packet matches any pre-existing filter */
    382469                if (trace->filter) {
    383470                        if (trace_apply_filter(trace->filter, packet)) {
     
    390477                        event.type = TRACE_EVENT_PACKET;
    391478                }
     479
     480                /* If the user has specified a snap length, apply that too */
    392481                if (trace->snaplen > 0) {
    393482                        trace_set_capture_length(packet, trace->snaplen);
     
    397486        } while (1);
    398487
     488
     489        /* We only want to sleep for a very short time */
    399490        assert(data == 0);
    400491        event.type = TRACE_EVENT_SLEEP;
     
    404495}
    405496
     497/* Gets the number of dropped packets */
    406498static uint64_t dag_get_dropped_packets(libtrace_t *trace)
    407499{
     
    411503}
    412504
     505/* Prints some semi-useful help text about the DAG format module */
    413506static void dag_help(void) {
    414507        printf("dag format module: $Revision$\n");
Note: See TracChangeset for help on using the changeset viewer.