Changeset eda2def for lib


Ignore:
Timestamp:
02/09/10 15:14:34 (12 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:
66649b4
Parents:
ebf8071
Message:
  • Documented and licensed the last two source files in lib/
  • Moved the untidy register_format function to the bottom of trace.c where it is less annoying
Location:
lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • lib/trace.c

    r0bb3004 reda2def  
    22 * This file is part of libtrace
    33 *
    4  * Copyright (c) 2007,2008 The University of Waikato, Hamilton, New Zealand.
     4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
     5 * New Zealand.
     6 *
    57 * Authors: Daniel Lawson
    6  *          Perry Lorier
     8 *          Perry Lorier
     9 *          Shane Alcock
    710 *         
    811 * All rights reserved.
     
    3033
    3134
    32 /* @file
    33  *
    34  * @brief Trace file processing library
    35  *
    36  * @author Daniel Lawson
    37  * @author Perry Lorier
    38  *
    39  * @internal
    40  */
    4135#define _GNU_SOURCE
    4236#include "common.h"
     
    106100#define MAXOPTS 1024
    107101
     102/* This file contains much of the implementation of the libtrace API itself. */
    108103
    109104static struct libtrace_format_t *formats_list = NULL;
     
    129124}
    130125
    131 void register_format(struct libtrace_format_t *f) {
    132         assert(f->next==NULL); /* Can't register a format twice */
    133         f->next=formats_list;
    134         formats_list=f;
    135         /* Now, verify things
    136          * This #if can be changed to a 1 to output warnings about inconsistant
    137          * functions being provided by format modules.  This generally is very
    138          * noisy, as almost all modules don't implement one or more functions
    139          * for various reasons.  This is very useful when checking a new
    140          * format module is sane.
    141          */
    142 #if 0
    143         if (f->init_input) {
    144 #define REQUIRE(x) \
    145                 if (!f->x) \
    146                         fprintf(stderr,"%s: Input format should provide " #x "\n",f->name)
    147                 REQUIRE(read_packet);
    148                 REQUIRE(start_input);
    149                 REQUIRE(fin_input);
    150                 REQUIRE(get_link_type);
    151                 REQUIRE(get_capture_length);
    152                 REQUIRE(get_wire_length);
    153                 REQUIRE(get_framing_length);
    154                 REQUIRE(trace_event);
    155                 if (!f->get_erf_timestamp
    156                         && !f->get_seconds
    157                         && !f->get_timeval) {
    158                         fprintf(stderr,"%s: A trace format capable of input, should provide at least one of\n"
    159 "get_erf_timestamp, get_seconds or trace_timeval\n",f->name);
    160                 }
    161                 if (f->trace_event!=trace_event_trace) {
    162                         /* Theres nothing that a trace file could optimise with
    163                          * config_input
    164                          */
    165                         REQUIRE(pause_input);
    166                         REQUIRE(config_input);
    167                         REQUIRE(get_fd);
    168                 }
    169                 else {
    170                         if (f->get_fd) {
    171                                 fprintf(stderr,"%s: Unnecessary get_fd\n",
    172                                                 f->name);
    173                         }
    174                 }
    175 #undef REQUIRE
    176         }
    177         else {
    178 #define REQUIRE(x) \
    179                 if (f->x) \
    180                         fprintf(stderr,"%s: Non Input format shouldn't need " #x "\n",f->name)
    181                 REQUIRE(read_packet);
    182                 REQUIRE(start_input);
    183                 REQUIRE(pause_input);
    184                 REQUIRE(fin_input);
    185                 REQUIRE(get_link_type);
    186                 REQUIRE(get_capture_length);
    187                 REQUIRE(get_wire_length);
    188                 REQUIRE(get_framing_length);
    189                 REQUIRE(trace_event);
    190                 REQUIRE(get_seconds);
    191                 REQUIRE(get_timeval);
    192                 REQUIRE(get_erf_timestamp);
    193 #undef REQUIRE
    194         }
    195         if (f->init_output) {
    196 #define REQUIRE(x) \
    197                 if (!f->x) \
    198                         fprintf(stderr,"%s: Output format should provide " #x "\n",f->name)
    199                 REQUIRE(write_packet);
    200                 REQUIRE(start_output);
    201                 REQUIRE(config_output);
    202                 REQUIRE(fin_output);
    203 #undef REQUIRE
    204         }
    205         else {
    206 #define REQUIRE(x) \
    207                 if (f->x) \
    208                         fprintf(stderr,"%s: Non Output format shouldn't need " #x "\n",f->name)
    209                 REQUIRE(write_packet);
    210                 REQUIRE(start_output);
    211                 REQUIRE(config_output);
    212                 REQUIRE(fin_output);
    213 #undef REQUIRE
    214         }
    215 #endif
    216 }
    217126
    218127/* call all the constructors if they haven't yet all been called */
     
    260169#define URI_PROTO_LINE 16U
    261170
    262 /* Try to guess which format module */
     171/* Try to guess which format module is appropriate for a given trace file or
     172 * device */
    263173static void guess_format(libtrace_t *libtrace, const char *filename)
    264174{
     
    291201}
    292202
    293 /* Create a trace file from a URI
     203/* Creates an input trace from a URI
    294204 *
    295205 * @params char * containing a valid libtrace URI
    296206 * @returns opaque pointer to a libtrace_t
    297207 *
    298  * Valid URI's are:
     208 * Some valid URI's are:
    299209 *  erf:/path/to/erf/file
    300210 *  erf:/path/to/erf/file.gz
    301  *  erf:/path/to/rtclient/socket
    302211 *  erf:-                       (stdin)
    303212 *  dag:/dev/dagcard
    304213 *  pcapint:pcapinterface               (eg: pcapint:eth0)
    305  *  pcap:/path/to/pcap/file
    306  *  pcap:-
    307  *  rtclient:hostname
    308  *  rtclient:hostname:port
     214 *  pcapfile:/path/to/pcap/file
     215 *  pcapfile:-
     216 *  int:interface                       (eg: int:eth0) only on Linux
     217 *  rt:hostname
     218 *  rt:hostname:port
    309219 *
    310220 * If an error occured when attempting to open a trace, NULL is returned
     
    340250        libtrace->filtered_packets = 0;
    341251
    342         /* parse the URI to determine what sort of event we are dealing with */
     252        /* Parse the URI to determine what sort of trace we are dealing with */
    343253        if ((uridata = trace_parse_uri(uri, &scan)) == 0) {
     254                /* Could not parse the URI nicely */
    344255                guess_format(libtrace,uri);
    345256                if (!libtrace->format) {
     
    351262                struct libtrace_format_t *tmp;
    352263
     264                /* Find a format that matches the first part of the URI */
    353265                for (tmp=formats_list;tmp;tmp=tmp->next) {
    354266                        if (strlen(scan) == strlen(tmp->name) &&
     
    359271                        }
    360272                }
     273
    361274                if (libtrace->format == 0) {
    362275                        trace_set_err(libtrace, TRACE_ERR_BAD_FORMAT,
     
    370283         * libtrace->uridata contains the appropriate data for this
    371284         */
    372        
     285       
     286        /* Call the init_input function for the matching capture format */
    373287        if (libtrace->format->init_input) {
    374288                int err=libtrace->format->init_input(libtrace);
     
    451365}
    452366
    453 /* Creates a trace output file from a URI.
     367/* Creates an output trace from a URI.
    454368 *
    455369 * @param uri   the uri string describing the output format and destination
     
    475389        libtrace->uridata = NULL;
    476390       
    477         /* parse the URI to determine what sort of event we are dealing with */
     391        /* Parse the URI to determine what capture format we want to write */
    478392
    479393        if ((uridata = trace_parse_uri(uri, &scan)) == 0) {
     
    483397        }
    484398       
     399        /* Attempt to find the format in the list of supported formats */
    485400        for(tmp=formats_list;tmp;tmp=tmp->next) {
    486401                if (strlen(scan) == strlen(tmp->name) &&
     
    526441}
    527442
    528 /* Start a trace
     443/* Start an input trace
    529444 * @param libtrace      the input trace to start
    530445 * @returns 0 on success
     
    549464}
    550465
     466/* Start an output trace */
    551467DLLEXPORT int trace_start_output(libtrace_out_t *libtrace)
    552468{
     
    587503        }
    588504       
     505        /* If the capture format supports configuration, try using their
     506         * native configuration first */
    589507        if (libtrace->format->config_input) {
    590508                ret=libtrace->format->config_input(libtrace,option,value);
     
    592510                        return 0;
    593511        }
     512
     513        /* If we get here, either the native configuration failed or the
     514         * format did not support configuration. However, libtrace can
     515         * deal with some options itself, so give that a go */
    594516        switch(option) {
    595517                case TRACE_OPTION_SNAPLEN:
     
    641563}
    642564
    643 /* Parses an output options string and calls the appropriate function to deal with output options.
    644  *
    645  * @param libtrace      the output trace object to apply the options to
    646  * @param options       the options string
    647  * @returns -1 if option configuration failed, 0 otherwise
    648  *
    649  * @author Shane Alcock
    650  */
    651565DLLEXPORT int trace_config_output(libtrace_out_t *libtrace,
    652566                trace_option_output_t option,
    653567                void *value) {
     568       
     569        /* Unlike the input options, libtrace does not natively support any of
     570         * the output options - the format module must be able to deal with
     571         * them. */
    654572        if (libtrace->format->config_output) {
    655573                return libtrace->format->config_output(libtrace, option, value);
     
    658576}
    659577
    660 /* Close a trace file, freeing up any resources it may have been using
     578/* Close an input trace file, freeing up any resources it may have been using
    661579 *
    662580 */
     
    668586                libtrace->format->fin_input(libtrace);
    669587        }
    670         /* need to free things! */
     588        /* Need to free things! */
    671589        if (libtrace->uridata)
    672590                free(libtrace->uridata);
     
    677595DLLEXPORT void trace_destroy_dead(libtrace_t *libtrace) {
    678596        assert(libtrace);
     597
     598        /* Don't call pause_input or fin_input, because we should never have
     599         * used this trace to do any reading anyway. Do make sure we free
     600         * any format_data that has been created, though. */
    679601        if (libtrace->format_data)
    680602                free(libtrace->format_data);
     
    684606 *
    685607 * @param libtrace      the output trace file to be destroyed
    686  *
    687  * @author Shane Alcock
    688  * */
     608 */
    689609DLLEXPORT void trace_destroy_output(libtrace_out_t *libtrace)
    690610{
     
    711631                (libtrace_packet_t *)malloc(sizeof(libtrace_packet_t));
    712632        if (!dest) {
    713                 printf("out of memory constructing packet\n");
     633                printf("Out of memory constructing packet\n");
    714634                abort();
    715635        }
     
    717637        dest->buffer=malloc(65536);
    718638        if (!dest->buffer) {
    719                 printf("out of memory allocating buffer memory\n");
     639                printf("Out of memory allocating buffer memory\n");
    720640                abort();
    721641        }
     
    730650        dest->l3_header = NULL;
    731651        dest->l3_ethertype = 0;
     652       
     653        /* Ooooh nasty memcpys! This is why we want to avoid copying packets
     654         * as much as possible */
    732655        memcpy(dest->header,packet->header,trace_get_framing_length(packet));
    733656        memcpy(dest->payload,packet->payload,trace_get_capture_length(packet));
     
    737660
    738661/** Destroy a packet object
    739  *
    740  * sideeffect: sets packet to NULL
    741662 */
    742663DLLEXPORT void trace_destroy_packet(libtrace_packet_t *packet) {
     
    745666        }
    746667        packet->buf_control=(buf_control_t)'\0';
    747                                 /* an "bad" value to force an assert
     668                                /* A "bad" value to force an assert
    748669                                 * if this packet is ever reused
    749670                                 */
     
    751672}       
    752673
    753 /* Read one packet from the trace into buffer
     674/* Read one packet from the trace into buffer. Note that this function will
     675 * block until a packet is read (or EOF is reached).
    754676 *
    755677 * @param libtrace      the libtrace opaque pointer
     
    819741}
    820742
     743/* Converts the provided buffer into a libtrace packet of the given type.
     744 *
     745 * Unlike trace_construct_packet, the buffer is expected to begin with the
     746 * appropriate capture format header for the format type that the packet is
     747 * being converted to. This also allows for a packet to be converted into
     748 * just about capture format that is supported by libtrace, provided the
     749 * format header is present in the buffer.
     750 *
     751 * This function is primarily used to convert packets received via the RT
     752 * protocol back into their original capture format. The RT header encapsulates
     753 * the original capture format header, so after removing it the packet must
     754 * have it's header and payload pointers updated and the packet format and type
     755 * changed, amongst other things.
     756 *
     757 * Intended only for internal use at this point - this function is not
     758 * available through the external libtrace API.
     759 */
    821760int trace_prepare_packet(libtrace_t *trace, libtrace_packet_t *packet,
    822761                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
     
    851790}
    852791
    853 /* Writes a packet to the specified output
     792/* Writes a packet to the specified output trace
    854793 *
    855794 * @param libtrace      describes the output format, destination, etc.
    856795 * @param packet        the packet to be written out
    857796 * @returns the number of bytes written, -1 if write failed
    858  *
    859  * @author Shane Alcock
    860  * */
     797 */
    861798DLLEXPORT int trace_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) {
    862799        assert(libtrace);
     
    877814}
    878815
     816/* Get a pointer to the first byte of the packet payload */
    879817DLLEXPORT void *trace_get_packet_buffer(const libtrace_packet_t *packet,
    880818                libtrace_linktype_t *linktype, uint32_t *remaining) {
     
    885823}
    886824
     825
     826/* Get a pointer to the first byte of the packet payload
     827 *
     828 * DEPRECATED - use trace_get_packet_buffer() instead */
    887829DLLEXPORT void *trace_get_link(const libtrace_packet_t *packet) {
    888830        return (void *)packet->payload;
     
    893835 * @returns a 64 bit timestamp in DAG ERF format (upper 32 bits are the seconds
    894836 * past 1970-01-01, the lower 32bits are partial seconds)
    895  * @author Daniel Lawson
    896837 */
    897838DLLEXPORT uint64_t trace_get_erf_timestamp(const libtrace_packet_t *packet) {
     
    1014955 * @param packet        a pointer to a libtrace_packet structure
    1015956 * @returns time that this packet was seen in 64bit floating point seconds
    1016  * @author Perry Lorier
    1017957 */
    1018958DLLEXPORT double trace_get_seconds(const libtrace_packet_t *packet) {
     
    10621002 *
    10631003 * @returns the size of the packet as it was on the wire.
    1064  * @author Perry Lorier
    1065  * @author Daniel Lawson
    10661004 * @note Due to the trace being a header capture, or anonymisation this may
    10671005 * not be the same as the Capture Len.
     
    10781016 * @param packet        the packet opaque pointer
    10791017 * @returns the size of the packet as it was on the wire.
    1080  * @author Perry Lorier
    1081  * @author Daniel Lawson
    10821018 * @note this length corresponds to the difference between the size of a
    10831019 * captured packet in memory, and the captured length of the packet
     
    10951031 * @param packet        a pointer to a libtrace_packet structure
    10961032 * @returns libtrace_linktype_t
    1097  * @author Perry Lorier
    1098  * @author Daniel Lawson
    10991033 */
    11001034DLLEXPORT libtrace_linktype_t trace_get_link_type(const libtrace_packet_t *packet ) {
     
    11151049 * FIXME currently keeps a copy of the packet inside the trace pointer,
    11161050 * which in turn is stored inside the new packet object...
    1117  * @author Perry Lorier
    11181051 */
    11191052DLLEXPORT libtrace_eventobj_t trace_event(libtrace_t *trace,
     
    11771110}
    11781111
    1179 /* setup a BPF filter
     1112/* Create a BPF filter
    11801113 * @param filterstring a char * containing the bpf filter string
    11811114 * @returns opaque pointer pointer to a libtrace_filter_t object
    1182  * @author Daniel Lawson
    11831115 */
    11841116DLLEXPORT libtrace_filter_t *trace_create_filter(const char *filterstring) {
     
    12071139}
    12081140
    1209 /* compile a bpf filter, now we know what trace it's on
     1141/* Compile a bpf filter, now we know the link type for the trace that we're
     1142 * applying it to.
     1143 *
    12101144 * @internal
    12111145 *
     
    12591193        return 0;
    12601194#else
    1261         assert(!"Internal bug: This never be called when BPF not enabled");
     1195        assert(!"Internal bug: This should never be called when BPF not enabled");
    12621196        trace_set_err(packet->trace,TRACE_ERR_OPTION_UNAVAIL,
    12631197                                "Feature unavailable");
     
    12791213
    12801214        if (libtrace_to_pcap_dlt(trace_get_link_type(packet))==~0U) {
     1215               
     1216                /* If we cannot get a suitable DLT for the packet, it may
     1217                 * be because the packet is encapsulated in a link type that
     1218                 * does not correspond to a DLT. Therefore, we should try
     1219                 * popping off headers until we either can find a suitable
     1220                 * link type or we can't do any more sensible decapsulation. */
     1221               
    12811222                /* Copy the packet, as we don't want to trash the one we
    1282                  * were passed in
    1283                  */
     1223                 * were passed in */
    12841224                packet_copy=trace_copy_packet(packet);
    12851225                free_packet_needed=true;
     1226
    12861227                while (libtrace_to_pcap_dlt(trace_get_link_type(packet_copy))==
    12871228                                ~0U) {
     
    13061247        }
    13071248
    1308         /* We need to compile it now, because before we didn't know what the
    1309          * link type was
     1249        /* We need to compile the filter now, because before we didn't know
     1250         * what the link type was
    13101251         */
    13111252        if (trace_bpf_compile(filter,packet_copy)==-1) {
     
    13181259        assert(filter->flag);
    13191260        ret=bpf_filter(filter->filter.bf_insns,(u_char*)linkptr,(unsigned int)clen,(unsigned int)clen);
     1261
     1262        /* If we copied the packet earlier, make sure that we free it */
    13201263        if (free_packet_needed) {
    13211264                trace_destroy_packet(packet_copy);
     
    13501293 * Other values are possible, which might be overloaded to mean special things
    13511294 * for a special trace.
    1352  * @author Daniel Lawson
    13531295 */
    13541296DLLEXPORT libtrace_direction_t trace_get_direction(const libtrace_packet_t *packet)
     
    14861428 * @note If the original network-level payload is smaller than size, then the
    14871429 * original size is returned and the packet is left unchanged.
    1488  * @author Daniel Lawson
    14891430 */
    14901431DLLEXPORT size_t trace_set_capture_length(libtrace_packet_t *packet, size_t size) {
     
    14981439}
    14991440
     1441/* Splits a URI into two components - the format component which is seen before
     1442 * the ':', and the uridata which follows the ':'.
     1443 *
     1444 * Returns a pointer to the URI data, but updates the format parameter to
     1445 * point to a copy of the format component.
     1446 */
     1447
    15001448DLLEXPORT const char * trace_parse_uri(const char *uri, char **format) {
    15011449        const char *uridata = 0;
    15021450       
    15031451        if((uridata = strchr(uri,':')) == NULL) {
    1504                 /* badly formed URI - needs a : */
     1452                /* Badly formed URI - needs a : */
    15051453                return 0;
    15061454        }
    15071455
    15081456        if ((unsigned)(uridata - uri) > URI_PROTO_LINE) {
    1509                 /* badly formed URI - uri type is too long */
     1457                /* Badly formed URI - uri type is too long */
    15101458                return 0;
    15111459        }
    15121460
     1461        /* NOTE: this is allocated memory - it should be freed by the caller
     1462         * once they are done with it */
    15131463        *format=xstrndup(uri, (size_t)(uridata - uri));
    15141464
    1515         /* push uridata past the delimiter */
     1465        /* Push uridata past the delimiter */
    15161466        uridata++;
    15171467       
     
    15391489}
    15401490
     1491/* Prints the input error status to standard error and clears the error state */
    15411492DLLEXPORT void trace_perror(libtrace_t *trace,const char *msg,...)
    15421493{
     
    15771528}
    15781529
     1530/* Prints the output error status to standard error and clears the error state
     1531 */
    15791532DLLEXPORT void trace_perror_output(libtrace_out_t *trace,const char *msg,...)
    15801533{
     
    16771630}
    16781631
     1632/* Converts a binary ethernet MAC address into a printable string */
    16791633DLLEXPORT char *trace_ether_ntoa(const uint8_t *addr, char *buf)
    16801634{
     
    16881642}
    16891643
     1644/* Converts a printable ethernet MAC address into a binary format */
    16901645DLLEXPORT uint8_t *trace_ether_aton(const char *buf, uint8_t *addr)
    16911646{
     
    17031658}
    17041659
     1660
     1661/* Creates a libtrace packet from scratch using the contents of the provided
     1662 * buffer as the packet payload.
     1663 *
     1664 * Unlike trace_prepare_packet(), the buffer should not contain any capture
     1665 * format headers; instead this function will add the PCAP header to the
     1666 * packet record. This also means only PCAP packets can be constructed using
     1667 * this function.
     1668 *
     1669 */
    17051670DLLEXPORT
    17061671void trace_construct_packet(libtrace_packet_t *packet,
     
    17181683#endif
    17191684
     1685        /* We need a trace to attach the constructed packet to (and it needs
     1686         * to be PCAP) */
    17201687        if (NULL == deadtrace)
    17211688                deadtrace=trace_create_dead("pcapfile");
    17221689
     1690        /* Fill in the new PCAP header */
    17231691#ifdef WIN32
    17241692        _ftime(&tstruct);
     
    17341702        hdr.wirelen=len;
    17351703
     1704        /* Now fill in the libtrace packet itself */
    17361705        packet->trace=deadtrace;
    17371706        size=len+sizeof(hdr);
     
    17451714        packet->header=packet->buffer;
    17461715        packet->payload=(void*)((char*)packet->buffer+sizeof(hdr));
     1716       
     1717        /* Ugh, memcpy - sadly necessary */
    17471718        memcpy(packet->header,&hdr,sizeof(hdr));
    17481719        memcpy(packet->payload,data,(size_t)len);
     
    17931764}
    17941765
     1766void register_format(struct libtrace_format_t *f) {
     1767        assert(f->next==NULL); /* Can't register a format twice */
     1768        f->next=formats_list;
     1769        formats_list=f;
     1770
     1771        /* Now, verify that the format has at least the minimum functionality.
     1772         *
     1773         * This #if can be changed to a 1 to output warnings about inconsistent
     1774         * functions being provided by format modules.  This generally is very
     1775         * noisy, as almost all modules don't implement one or more functions
     1776         * for various reasons.  This is very useful when checking a new
     1777         * format module is sane.
     1778         */
     1779#if 0
     1780        if (f->init_input) {
     1781#define REQUIRE(x) \
     1782                if (!f->x) \
     1783                        fprintf(stderr,"%s: Input format should provide " #x "\n",f->name)
     1784                REQUIRE(read_packet);
     1785                REQUIRE(start_input);
     1786                REQUIRE(fin_input);
     1787                REQUIRE(get_link_type);
     1788                REQUIRE(get_capture_length);
     1789                REQUIRE(get_wire_length);
     1790                REQUIRE(get_framing_length);
     1791                REQUIRE(trace_event);
     1792                if (!f->get_erf_timestamp
     1793                        && !f->get_seconds
     1794                        && !f->get_timeval) {
     1795                        fprintf(stderr,"%s: A trace format capable of input, should provide at least one of\n"
     1796"get_erf_timestamp, get_seconds or trace_timeval\n",f->name);
     1797                }
     1798                if (f->trace_event!=trace_event_trace) {
     1799                        /* Theres nothing that a trace file could optimise with
     1800                         * config_input
     1801                         */
     1802                        REQUIRE(pause_input);
     1803                        REQUIRE(config_input);
     1804                        REQUIRE(get_fd);
     1805                }
     1806                else {
     1807                        if (f->get_fd) {
     1808                                fprintf(stderr,"%s: Unnecessary get_fd\n",
     1809                                                f->name);
     1810                        }
     1811                }
     1812#undef REQUIRE
     1813        }
     1814        else {
     1815#define REQUIRE(x) \
     1816                if (f->x) \
     1817                        fprintf(stderr,"%s: Non Input format shouldn't need " #x "\n",f->name)
     1818                REQUIRE(read_packet);
     1819                REQUIRE(start_input);
     1820                REQUIRE(pause_input);
     1821                REQUIRE(fin_input);
     1822                REQUIRE(get_link_type);
     1823                REQUIRE(get_capture_length);
     1824                REQUIRE(get_wire_length);
     1825                REQUIRE(get_framing_length);
     1826                REQUIRE(trace_event);
     1827                REQUIRE(get_seconds);
     1828                REQUIRE(get_timeval);
     1829                REQUIRE(get_erf_timestamp);
     1830#undef REQUIRE
     1831        }
     1832        if (f->init_output) {
     1833#define REQUIRE(x) \
     1834                if (!f->x) \
     1835                        fprintf(stderr,"%s: Output format should provide " #x "\n",f->name)
     1836                REQUIRE(write_packet);
     1837                REQUIRE(start_output);
     1838                REQUIRE(config_output);
     1839                REQUIRE(fin_output);
     1840#undef REQUIRE
     1841        }
     1842        else {
     1843#define REQUIRE(x) \
     1844                if (f->x) \
     1845                        fprintf(stderr,"%s: Non Output format shouldn't need " #x "\n",f->name)
     1846                REQUIRE(write_packet);
     1847                REQUIRE(start_output);
     1848                REQUIRE(config_output);
     1849                REQUIRE(fin_output);
     1850#undef REQUIRE
     1851        }
     1852#endif
     1853}
     1854
  • lib/wandio.c

    r15e9390 reda2def  
     1/*
     2 * This file is part of libtrace
     3 *
     4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
     5 * New Zealand.
     6 *
     7 * Authors: Daniel Lawson
     8 *          Perry Lorier
     9 *          Shane Alcock
     10 *         
     11 * All rights reserved.
     12 *
     13 * This code has been developed by the University of Waikato WAND
     14 * research group. For further information please see http://www.wand.net.nz/
     15 *
     16 * libtrace is free software; you can redistribute it and/or modify
     17 * it under the terms of the GNU General Public License as published by
     18 * the Free Software Foundation; either version 2 of the License, or
     19 * (at your option) any later version.
     20 *
     21 * libtrace is distributed in the hope that it will be useful,
     22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     24 * GNU General Public License for more details.
     25 *
     26 * You should have received a copy of the GNU General Public License
     27 * along with libtrace; if not, write to the Free Software
     28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     29 *
     30 * $Id$
     31 *
     32 */
     33
     34
    135#include "wandio.h"
    236#include "config.h"
     
    438#include <assert.h>
    539#include <errno.h>
     40
     41/* This file contains the implementation of the libtrace IO API, which format
     42 * modules should use to open, read from, write to, seek and close trace files.
     43 */
    644
    745struct compression_type compression_type[]  = {
     
    1654io_t *wandio_create(const char *filename)
    1755{
     56        /* Use a peeking reader to look at the start of the trace file and
     57         * determine what type of compression may have been used to write
     58         * the file */
     59       
    1860        io_t *io = peek_open(stdio_open(filename));
    1961        char buffer[1024];
     
    2365        len = wandio_peek(io, buffer, sizeof(buffer));
    2466#if HAVE_LIBZ
    25         /* auto detect gzip compressed data */
     67        /* Auto detect gzip compressed data */
    2668        if (len>=2 && buffer[0] == '\037' && buffer[1] == '\213') {
    2769                io = zlib_open(io);
    2870        }
    29         /* auto detect compress(1) compressed data (gzip can read this) */
     71        /* Auto detect compress(1) compressed data (gzip can read this) */
    3072        if (len>=2 && buffer[0] == '\037' && buffer[1] == '\235') {
    3173                io = zlib_open(io);
     
    3375#endif
    3476#if HAVE_LIBBZ2
    35         /* auto detect bzip compressed data */
     77        /* Auto detect bzip compressed data */
    3678        if (len>=3 && buffer[0] == 'B' && buffer[1] == 'Z' && buffer[2] == 'h') {
    3779                io = bz_open(io);
    3880        }
    3981#endif
     82       
     83        /* Now open a threaded, peekable reader using the appropriate module
     84         * to read the data */
     85       
    4086        return peek_open(thread_open(io));
    4187}
     
    91137
    92138        iow=stdio_wopen(filename);
     139
     140        /* We prefer zlib if available, otherwise we'll use bzip. If neither
     141         * are present, guess we'll just have to write uncompressed */
    93142#if HAVE_LIBZ
    94143        if (compression_level != 0 &&
     
    103152        }
    104153#endif
     154        /* Open a threaded writer */
    105155        return thread_wopen(iow);
    106156}
Note: See TracChangeset for help on using the changeset viewer.