source: lib/format_erf.c @ 5511c14

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 5511c14 was 5511c14, checked in by Shane Alcock <salcock@…>, 12 years ago
  • Tidied up the format data structures in format_erf. In particular, removed unnecessary unions.
  • Updated licensing and documentation for format_duck and format_erf
  • Property mode set to 100644
File size: 20.3 KB
Line 
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
35#define _GNU_SOURCE
36
37#include "config.h"
38#include "common.h"
39#include "libtrace.h"
40#include "libtrace_int.h"
41#include "format_helper.h"
42#include "format_erf.h"
43#include "wandio.h"
44
45#include <assert.h>
46#include <errno.h>
47#include <fcntl.h>
48#include <stdio.h>
49#include <string.h>
50#include <stdlib.h>
51
52#ifdef WIN32
53#  include <io.h>
54#  include <share.h>
55#  define PATH_MAX _MAX_PATH
56#else
57#  include <netdb.h>
58#  ifndef PATH_MAX
59#       define PATH_MAX 4096
60#  endif
61#  include <sys/ioctl.h>
62#endif
63
64/* This format module deals with reading and writing ERF traces. ERF is the
65 * trace format developed by Endace for use by DAG hardware capture cards.
66 *
67 * ERF is not a live capture format.
68 *
69 */
70
71
72static struct libtrace_format_t erfformat;
73
74#define DATA(x) ((struct erf_format_data_t *)x->format_data)
75#define DATAOUT(x) ((struct erf_format_data_out_t *)x->format_data)
76
77#define IN_OPTIONS DATA(libtrace)->options
78#define OUTPUT DATAOUT(libtrace)
79#define OUT_OPTIONS DATAOUT(libtrace)->options
80
81/* "Global" data that is stored for each ERF input trace */
82struct erf_format_data_t {
83       
84        /* Index used for seeking within a trace */
85        struct {
86                /* The index itself */
87                io_t *index;
88                /* The offset of the index */
89                off_t index_len;
90                /* Indicates the existence of an index */
91                enum { INDEX_UNKNOWN=0, INDEX_NONE, INDEX_EXISTS } exists;
92        } seek;
93
94        /* Number of packets that were dropped during the capture */
95        uint64_t drops;
96
97        /* Config options for the input trace */
98        struct {
99                /* Flag indicating whether the event API should replicate the
100                 * time gaps between each packet or return a PACKET event for
101                 * each packet */
102                int real_time;
103        } options;
104};
105
106/* "Global" data that is stored for each ERF output trace */
107struct erf_format_data_out_t {
108
109        /* Config options for the output trace */
110        struct {
111                /* Compression level for the output file */
112                int level;
113                /* File flags used to open the file, e.g. O_CREATE */
114                int fileflag;
115        } options;
116
117        /* The output file itself */
118        iow_t *file;
119       
120};
121
122typedef struct erf_index_t {
123        uint64_t timestamp;
124        uint64_t offset; 
125} erf_index_t;
126
127
128/* Ethernet packets have a 2 byte padding before the packet
129 * so that the IP header is aligned on a 32 bit boundary.
130 */
131static int erf_get_padding(const libtrace_packet_t *packet)
132{
133        if (packet->trace->format->type==TRACE_FORMAT_ERF) {
134                dag_record_t *erfptr = (dag_record_t *)packet->header;
135                switch(erfptr->type) {
136                        case TYPE_ETH:         
137                        case TYPE_DSM_COLOR_ETH:
138                                return 2;
139                        default:                return 0;
140                }
141        }
142        else {
143                switch(trace_get_link_type(packet)) {
144                        case TRACE_TYPE_ETH:    return 2;
145                        default:                return 0;
146                }
147        }
148}
149
150int erf_get_framing_length(const libtrace_packet_t *packet)
151{
152        return dag_record_size + erf_get_padding(packet);
153}
154
155/* Attempts to determine whether a given trace file is using the ERF format
156 *
157 * Returns 1 if the trace is probably ERF, 0 otherwise
158 */
159static int erf_probe_magic(io_t *io)
160{
161        char buffer[4096];
162        int len;
163        dag_record_t *erf;
164        len = wandio_peek(io, buffer, sizeof(buffer));
165        if (len < (int)dag_record_size) {
166                return 0; /* False */
167        }
168        erf = (dag_record_t *) buffer;
169        /* If the record is too short */
170        if (ntohs(erf->rlen) < dag_record_size) {
171                return 0;
172        }
173        /* There aren't any erf traces before 1995-01-01 */
174        if (bswap_le_to_host64(erf->ts) < 0x2f0539b000000000ULL) {
175                return 0;
176        }
177        /* And not pcap! */
178        if (bswap_le_to_host64(erf->ts) >>32 == 0xa1b2c3d4) {
179                return 0;
180        }
181        /* And not the other pcap! */
182        if (bswap_le_to_host64(erf->ts) >>32 == 0xd4c3b2a1) {
183                return 0;
184        }
185        /* Is this a proper typed packet */
186        if (erf->type > TYPE_AAL2) {
187                return 0;
188        }
189        /* We should put some more tests in here. */
190        /* Yeah, this is probably ERF */
191        return 1;
192}
193
194static int erf_init_input(libtrace_t *libtrace) 
195{
196        libtrace->format_data = malloc(sizeof(struct erf_format_data_t));
197       
198        IN_OPTIONS.real_time = 0;
199        DATA(libtrace)->drops = 0;
200       
201        return 0; /* success */
202}
203
204static int erf_config_input(libtrace_t *libtrace, trace_option_t option,
205                void *value) {
206
207        switch (option) {
208                case TRACE_OPTION_EVENT_REALTIME:
209                        IN_OPTIONS.real_time = *(int *)value;
210                        return 0;
211                case TRACE_OPTION_SNAPLEN:
212                case TRACE_OPTION_PROMISC:
213                case TRACE_OPTION_FILTER:
214                case TRACE_OPTION_META_FREQ:
215                        trace_set_err(libtrace, TRACE_ERR_OPTION_UNAVAIL,
216                                        "Unsupported option");
217                        return -1;
218                default:
219                        /* Unknown option */
220                        trace_set_err(libtrace,TRACE_ERR_UNKNOWN_OPTION,
221                                        "Unknown option");
222                        return -1;
223        }
224}
225
226static int erf_start_input(libtrace_t *libtrace)
227{
228        if (libtrace->io)
229                return 0; /* Success -- already done. */
230
231        libtrace->io = trace_open_file(libtrace);
232
233        if (!libtrace->io)
234                return -1;
235
236        DATA(libtrace)->drops = 0;
237
238        return 0; /* success */
239}
240
241/* Binary search through the index to find the closest point before
242 * the packet.  Consider in future having a btree index perhaps?
243 */
244static int erf_fast_seek_start(libtrace_t *libtrace,uint64_t erfts)
245{
246        size_t max_off = DATA(libtrace)->seek.index_len/sizeof(erf_index_t);
247        size_t min_off = 0;
248        off_t current;
249        erf_index_t record;
250        do {
251                current=(max_off+min_off)>>2;
252
253                wandio_seek(DATA(libtrace)->seek.index,
254                                (int64_t)(current*sizeof(record)),
255                                SEEK_SET);
256                wandio_read(DATA(libtrace)->seek.index,
257                                &record,sizeof(record));
258                if (record.timestamp < erfts) {
259                        min_off=current;
260                }
261                if (record.timestamp > erfts) {
262                        max_off=current;
263                }
264                if (record.timestamp == erfts)
265                        break;
266        } while(min_off<max_off);
267
268        /* If we've passed it, seek backwards.  This loop shouldn't
269         * execute more than twice.
270         */
271        do {
272                wandio_seek(DATA(libtrace)->seek.index,
273                                (int64_t)(current*sizeof(record)),SEEK_SET);
274                wandio_read(DATA(libtrace)->seek.index,
275                                &record,sizeof(record));
276                current--;
277        } while(record.timestamp>erfts);
278
279        /* We've found our location in the trace, now use it. */
280        wandio_seek(libtrace->io,(int64_t) record.offset,SEEK_SET);
281
282        return 0; /* success */
283}
284
285/* There is no index.  Seek through the entire trace from the start, nice
286 * and slowly.
287 */
288static int erf_slow_seek_start(libtrace_t *libtrace,uint64_t erfts UNUSED)
289{
290        if (libtrace->io) {
291                wandio_destroy(libtrace->io);
292        }
293        libtrace->io = trace_open_file(libtrace);
294        if (!libtrace->io)
295                return -1;
296        return 0;
297}
298
299/* Seek within an ERF trace based on an ERF timestamp */
300static int erf_seek_erf(libtrace_t *libtrace,uint64_t erfts)
301{
302        libtrace_packet_t *packet;
303        off_t off = 0;
304
305        if (DATA(libtrace)->seek.exists==INDEX_UNKNOWN) {
306                char buffer[PATH_MAX];
307                snprintf(buffer,sizeof(buffer),"%s.idx",libtrace->uridata);
308                DATA(libtrace)->seek.index=wandio_create(buffer);
309                if (DATA(libtrace)->seek.index) {
310                        DATA(libtrace)->seek.exists=INDEX_EXISTS;
311                }
312                else {
313                        DATA(libtrace)->seek.exists=INDEX_NONE;
314                }
315        }
316
317        /* If theres an index, use it to find the nearest packet that isn't
318         * after the time we're looking for.  If there is no index we need
319         * to seek slowly through the trace from the beginning.  Sigh.
320         */
321        switch(DATA(libtrace)->seek.exists) {
322                case INDEX_EXISTS:
323                        erf_fast_seek_start(libtrace,erfts);
324                        break;
325                case INDEX_NONE:
326                        erf_slow_seek_start(libtrace,erfts);
327                        break;
328                case INDEX_UNKNOWN:
329                        assert(0);
330                        break;
331        }
332
333        /* Now seek forward looking for the correct timestamp */
334        packet=trace_create_packet();
335        do {
336                trace_read_packet(libtrace,packet);
337                if (trace_get_erf_timestamp(packet)==erfts)
338                        break;
339                off=wandio_tell(libtrace->io);
340        } while(trace_get_erf_timestamp(packet)<erfts);
341
342        wandio_seek(libtrace->io,off,SEEK_SET);
343
344        return 0;
345}
346
347static int erf_init_output(libtrace_out_t *libtrace) {
348        libtrace->format_data = malloc(sizeof(struct erf_format_data_out_t));
349
350        OUT_OPTIONS.level = 0;
351        OUT_OPTIONS.fileflag = O_CREAT | O_WRONLY;
352        OUTPUT->file = 0;
353
354        return 0;
355}
356
357static int erf_config_output(libtrace_out_t *libtrace, 
358                trace_option_output_t option, void *value) {
359
360        switch (option) {
361                case TRACE_OPTION_OUTPUT_COMPRESS:
362                        OUT_OPTIONS.level = *(int*)value;
363                        return 0;
364                case TRACE_OPTION_OUTPUT_FILEFLAGS:
365                        OUT_OPTIONS.fileflag = *(int*)value;
366                        return 0;
367                default:
368                        /* Unknown option */
369                        trace_set_err_out(libtrace,TRACE_ERR_UNKNOWN_OPTION,
370                                        "Unknown option");
371                        return -1;
372        }
373}
374
375
376
377static int erf_fin_input(libtrace_t *libtrace) {
378        if (libtrace->io)
379                wandio_destroy(libtrace->io);
380        free(libtrace->format_data);
381        return 0;
382}
383
384static int erf_fin_output(libtrace_out_t *libtrace) {
385        if (OUTPUT->file)
386                wandio_wdestroy(OUTPUT->file);
387        free(libtrace->format_data);
388        return 0;
389}
390 
391static int erf_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
392                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
393       
394        dag_record_t *erfptr;
395       
396        if (packet->buffer != buffer && 
397                packet->buf_control == TRACE_CTRL_PACKET) {
398                free(packet->buffer);
399        }
400
401        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
402                packet->buf_control = TRACE_CTRL_PACKET;
403        } else
404                packet->buf_control = TRACE_CTRL_EXTERNAL;
405       
406       
407        packet->type = rt_type;
408        packet->buffer = buffer;
409        packet->header = buffer;
410        erfptr = (dag_record_t *)packet->buffer;
411        if (erfptr->flags.rxerror == 1) {
412                packet->payload = NULL;
413        } else {
414                packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
415        }
416       
417        if (libtrace->format_data == NULL) {
418                /* Allocates the format_data structure */
419                if (erf_init_input(libtrace)) 
420                        return -1;
421        }
422
423        /* Check for loss */
424        if (erfptr->type == TYPE_DSM_COLOR_ETH) {
425                /* No idea how we get this yet */
426
427        } else {
428                DATA(libtrace)->drops += ntohs(erfptr->lctr);
429        }
430
431        return 0;
432}
433
434static int erf_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
435        int numbytes;
436        unsigned int size;
437        void *buffer2 = packet->buffer;
438        unsigned int rlen;
439        uint32_t flags = 0;
440       
441       
442        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
443                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
444                if (!packet->buffer) {
445                        trace_set_err(libtrace, errno, 
446                                        "Cannot allocate memory");
447                        return -1;
448                }
449        }
450
451        flags |= TRACE_PREP_OWN_BUFFER; 
452       
453        if ((numbytes=wandio_read(libtrace->io,
454                                        packet->buffer,
455                                        (size_t)dag_record_size)) == -1) {
456                trace_set_err(libtrace,errno,"read(%s)",
457                                libtrace->uridata);
458                return -1;
459        }
460        /* EOF */
461        if (numbytes == 0) {
462                return 0;
463        }
464
465        rlen = ntohs(((dag_record_t *)packet->buffer)->rlen);
466        buffer2 = (char*)packet->buffer + dag_record_size;
467        size = rlen - dag_record_size;
468
469        if (size >= LIBTRACE_PACKET_BUFSIZE) {
470                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 
471                                "Packet size %u larger than supported by libtrace - packet is probably corrupt", 
472                                size);
473                return -1;
474        }
475
476        /* Unknown/corrupt */
477        if (((dag_record_t *)packet->buffer)->type >= TYPE_RAW_LINK) {
478                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 
479                                "Corrupt or Unknown ERF type");
480                return -1;
481        }
482       
483        /* read in the rest of the packet */
484        if ((numbytes=wandio_read(libtrace->io,
485                                        buffer2,
486                                        (size_t)size)) != (int)size) {
487                if (numbytes==-1) {
488                        trace_set_err(libtrace,errno, "read(%s)", 
489                                        libtrace->uridata);
490                        return -1;
491                }
492                trace_set_err(libtrace,EIO,
493                                "Truncated packet (wanted %d, got %d)", 
494                                size, numbytes);
495                /* Failed to read the full packet?  must be EOF */
496                return -1;
497        }
498       
499        if (erf_prepare_packet(libtrace, packet, packet->buffer, 
500                                TRACE_RT_DATA_ERF, flags))
501                return -1;
502       
503        return rlen;
504}
505
506static int erf_dump_packet(libtrace_out_t *libtrace,
507                dag_record_t *erfptr, unsigned int pad, void *buffer) {
508        int numbytes = 0;
509        int size;
510
511        if ((numbytes = 
512                wandio_wwrite(OUTPUT->file, 
513                                erfptr,
514                                (size_t)(dag_record_size + pad))) 
515                        != (int)(dag_record_size+pad)) {
516                trace_set_err_out(libtrace,errno,
517                                "write(%s)",libtrace->uridata);
518                return -1;
519        }
520
521        size=ntohs(erfptr->rlen)-(dag_record_size+pad);
522        numbytes=wandio_wwrite(OUTPUT->file, buffer, (size_t)size);
523        if (numbytes != size) {
524                trace_set_err_out(libtrace,errno,
525                                "write(%s)",libtrace->uridata);
526                return -1;
527        }
528        return numbytes + pad + dag_record_size;
529}
530
531static int erf_start_output(libtrace_out_t *libtrace)
532{
533        OUTPUT->file = trace_open_file_out(libtrace,
534                        OUT_OPTIONS.level,
535                        OUT_OPTIONS.fileflag);
536        if (!OUTPUT->file) {
537                return -1;
538        }
539        return 0;
540}
541
542static bool find_compatible_linktype(libtrace_out_t *libtrace,
543                                libtrace_packet_t *packet)
544{
545        /* Keep trying to simplify the packet until we can find
546         * something we can do with it */
547        do {
548                char type=libtrace_to_erf_type(trace_get_link_type(packet));
549
550                /* Success */
551                if (type != (char)-1)
552                        return true;
553
554                if (!demote_packet(packet)) {
555                        trace_set_err_out(libtrace,
556                                        TRACE_ERR_NO_CONVERSION,
557                                        "No erf type for packet (%i)",
558                                        trace_get_link_type(packet));
559                        return false;
560                }
561
562        } while(1);
563
564        return true;
565}
566               
567static int erf_write_packet(libtrace_out_t *libtrace, 
568                libtrace_packet_t *packet) 
569{
570        int numbytes = 0;
571        unsigned int pad = 0;
572        dag_record_t *dag_hdr = (dag_record_t *)packet->header;
573        void *payload = packet->payload;
574
575        assert(OUTPUT->file);
576
577        if (!packet->header) {
578                /*trace_set_err_output(libtrace, TRACE_ERR_BAD_PACKET,
579                                "Packet has no header - probably an RT packet");
580                */
581                return -1;
582        }
583       
584        pad = erf_get_padding(packet);
585
586        /* If we've had an rxerror, we have no payload to write - fix
587         * rlen to be the correct length
588         */
589        /* I Think this is bogus, we should somehow figure out
590         * a way to write out the payload even if it is gibberish -- Perry */
591        if (payload == NULL) {
592                dag_hdr->rlen = htons(dag_record_size + pad);
593               
594        } 
595       
596        if (packet->type == TRACE_RT_DATA_ERF) {
597                        numbytes = erf_dump_packet(libtrace,
598                                (dag_record_t *)packet->header,
599                                pad,
600                                payload
601                                );
602        } else {
603                dag_record_t erfhdr;
604                int rlen;
605                /* convert format - build up a new erf header */
606                /* Timestamp */
607                erfhdr.ts = bswap_host_to_le64(trace_get_erf_timestamp(packet));
608
609                /* Flags. Can't do this */
610                memset(&erfhdr.flags,1,sizeof(erfhdr.flags));
611                if (trace_get_direction(packet)!=~0U)
612                        erfhdr.flags.iface = trace_get_direction(packet);
613
614                if (!find_compatible_linktype(libtrace,packet))
615                        return -1;
616
617                payload=packet->payload;
618                pad = erf_get_padding(packet);
619
620                erfhdr.type = libtrace_to_erf_type(trace_get_link_type(packet));
621
622                /* Packet length (rlen includes format overhead) */
623                assert(trace_get_capture_length(packet)>0 
624                                && trace_get_capture_length(packet)<=65536);
625                assert(erf_get_framing_length(packet)>0 
626                                && trace_get_framing_length(packet)<=65536);
627
628                rlen = trace_get_capture_length(packet) + 
629                                erf_get_framing_length(packet);
630                assert(rlen > 0 && rlen <= 65536);
631                erfhdr.rlen = htons(rlen);
632                /* loss counter. Can't do this */
633                erfhdr.lctr = 0;
634                /* Wire length, does not include padding! */
635                erfhdr.wlen = htons(trace_get_wire_length(packet));
636
637                /* Write it out */
638                numbytes = erf_dump_packet(libtrace,
639                                &erfhdr,
640                                pad,
641                                payload);
642        }
643        return numbytes;
644}
645
646libtrace_linktype_t erf_get_link_type(const libtrace_packet_t *packet) {
647        dag_record_t *erfptr = 0;
648        erfptr = (dag_record_t *)packet->header;
649        if (erfptr->type != TYPE_LEGACY)
650                return erf_type_to_libtrace(erfptr->type);
651        else {
652                /* Sigh, lets start wildly guessing */
653                if (((char*)packet->payload)[4]==0x45)
654                        return TRACE_TYPE_PPP;
655                return ~0;
656        }
657}
658
659libtrace_direction_t erf_get_direction(const libtrace_packet_t *packet) {
660        dag_record_t *erfptr = 0;
661        erfptr = (dag_record_t *)packet->header;
662        return erfptr->flags.iface;
663}
664
665libtrace_direction_t erf_set_direction(libtrace_packet_t *packet, libtrace_direction_t direction) {
666        dag_record_t *erfptr = 0;
667        erfptr = (dag_record_t *)packet->header;
668        erfptr->flags.iface = direction;
669        return erfptr->flags.iface;
670}
671
672uint64_t erf_get_erf_timestamp(const libtrace_packet_t *packet) {
673        dag_record_t *erfptr = 0;
674        erfptr = (dag_record_t *)packet->header;
675        return bswap_le_to_host64(erfptr->ts);
676}
677
678int erf_get_capture_length(const libtrace_packet_t *packet) {
679        dag_record_t *erfptr = 0;
680        int caplen;
681        if (packet->payload == NULL)
682                return 0; 
683       
684        erfptr = (dag_record_t *)packet->header;
685        caplen = ntohs(erfptr->rlen) - erf_get_framing_length(packet);
686        if (ntohs(erfptr->wlen) < caplen)
687                return ntohs(erfptr->wlen);
688
689        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
690}
691
692int erf_get_wire_length(const libtrace_packet_t *packet) {
693        dag_record_t *erfptr = 0;
694        erfptr = (dag_record_t *)packet->header;
695        return ntohs(erfptr->wlen);
696}
697
698size_t erf_set_capture_length(libtrace_packet_t *packet, size_t size) {
699        dag_record_t *erfptr = 0;
700        assert(packet);
701        if(size  > trace_get_capture_length(packet)) {
702                /* Can't make a packet larger */
703                return trace_get_capture_length(packet);
704        }
705        /* Reset cached capture length - otherwise we will both return the
706         * wrong value here and subsequent get_capture_length() calls will
707         * return the wrong value. */
708        packet->capture_length = -1;
709        erfptr = (dag_record_t *)packet->header;
710        erfptr->rlen = htons(size + erf_get_framing_length(packet));
711        return trace_get_capture_length(packet);
712}
713
714static struct libtrace_eventobj_t erf_event(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
715        struct libtrace_eventobj_t event = {0,0,0.0,0};
716       
717        /* If we are being told to replay packets as fast as possible, then
718         * we just need to read and return the next packet in the trace */
719        if (IN_OPTIONS.real_time) {
720                event.size = erf_read_packet(libtrace, packet);
721                if (event.size < 1)
722                        event.type = TRACE_EVENT_TERMINATE;
723                else
724                        event.type = TRACE_EVENT_PACKET;
725                return event;
726               
727        } else {
728                /* Otherwise, use the generic event function */
729                return trace_event_trace(libtrace, packet);
730        }
731       
732}
733
734static uint64_t erf_get_dropped_packets(libtrace_t *trace)
735{
736        if (trace->format_data == NULL)
737                return (uint64_t)-1;
738        return DATA(trace)->drops;
739}
740
741static void erf_help(void) {
742        printf("erf format module: $Revision$\n");
743        printf("Supported input URIs:\n");
744        printf("\terf:/path/to/file\t(uncompressed)\n");
745        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
746        printf("\terf:-\t(stdin, either compressed or not)\n");
747        printf("\terf:/path/to/socket\n");
748        printf("\n");
749        printf("\te.g.: erf:/tmp/trace\n");
750        printf("\n");
751        printf("Supported output URIs:\n");
752        printf("\terf:path/to/file\t(uncompressed)\n");
753        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
754        printf("\terf:-\t(stdout, either compressed or not)\n");
755        printf("\n");
756        printf("\te.g.: erf:/tmp/trace\n");
757        printf("\n");
758
759       
760}
761
762static struct libtrace_format_t erfformat = {
763        "erf",
764        "$Id$",
765        TRACE_FORMAT_ERF,
766        NULL,                           /* probe filename */
767        erf_probe_magic,                /* probe magic */
768        erf_init_input,                 /* init_input */       
769        erf_config_input,               /* config_input */
770        erf_start_input,                /* start_input */
771        NULL,                           /* pause_input */
772        erf_init_output,                /* init_output */
773        erf_config_output,              /* config_output */
774        erf_start_output,               /* start_output */
775        erf_fin_input,                  /* fin_input */
776        erf_fin_output,                 /* fin_output */
777        erf_read_packet,                /* read_packet */
778        erf_prepare_packet,             /* prepare_packet */
779        NULL,                           /* fin_packet */
780        erf_write_packet,               /* write_packet */
781        erf_get_link_type,              /* get_link_type */
782        erf_get_direction,              /* get_direction */
783        erf_set_direction,              /* set_direction */
784        erf_get_erf_timestamp,          /* get_erf_timestamp */
785        NULL,                           /* get_timeval */
786        NULL,                           /* get_timespec */
787        NULL,                           /* get_seconds */
788        erf_seek_erf,                   /* seek_erf */
789        NULL,                           /* seek_timeval */
790        NULL,                           /* seek_seconds */
791        erf_get_capture_length,         /* get_capture_length */
792        erf_get_wire_length,            /* get_wire_length */
793        erf_get_framing_length,         /* get_framing_length */
794        erf_set_capture_length,         /* set_capture_length */
795        NULL,                           /* get_received_packets */
796        NULL,                           /* get_filtered_packets */
797        erf_get_dropped_packets,        /* get_dropped_packets */
798        NULL,                           /* get_captured_packets */
799        NULL,                           /* get_fd */
800        erf_event,                      /* trace_event */
801        erf_help,                       /* help */
802        NULL                            /* next pointer */
803};
804
805
806void erf_constructor(void) {
807        register_format(&erfformat);
808}
Note: See TracBrowser for help on using the repository browser.