source: lib/format_pcapfile.c @ cc9c9de

cachetimestampsdevelopetsiliverc-4.0.4ringdecrementfixringperformance
Last change on this file since cc9c9de was cc9c9de, checked in by Shane Alcock <salcock@…>, 3 years ago

Add new config option for trace_event() -- REPLAY_SPEEDUP

This allows users to specify a "speedup factor" when using
trace_event() to replay trace files, i.e. all inter-packet
gaps will be divided by the speedup factor. This allows traces
to be replayed faster, while still preserving the same relative
gaps between packets.

  • Property mode set to 100644
File size: 20.1 KB
Line 
1/*
2 *
3 * Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
4 * All rights reserved.
5 *
6 * This file is part of libtrace.
7 *
8 * This code has been developed by the University of Waikato WAND
9 * research group. For further information please see http://www.wand.net.nz/
10 *
11 * libtrace is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * libtrace is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 *
24 *
25 */
26#include "common.h"
27#include "config.h"
28#include "libtrace.h"
29#include "libtrace_int.h"
30#include "format_helper.h"
31
32#include <sys/stat.h>
33#include <assert.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <stdbool.h>
40
41/* This format module implements our own, more efficient, version of the PCAP
42 * file format. This should always be used in preference to the "pcap" format
43 * provided in format_pcap.c.
44 *
45 * This is a trace file format and does not implement any live interface
46 * capture. This is covered by "pcapint" in format_pcap.c.
47 *
48 * This format supports both reading and writing, regardless of the version
49 * of your PCAP library.
50 */
51
52#define DATA(x) ((struct pcapfile_format_data_t*)((x)->format_data))
53#define DATAOUT(x) ((struct pcapfile_format_data_out_t*)((x)->format_data))
54#define IN_OPTIONS DATA(libtrace)->options
55
56typedef struct pcapfile_header_t {
57                uint32_t magic_number;   /* magic number */
58                uint16_t version_major;  /* major version number */
59                uint16_t version_minor;  /* minor version number */
60                int32_t  thiszone;       /* GMT to local correction */
61                uint32_t sigfigs;        /* timestamp accuracy */
62                uint32_t snaplen;        /* aka "wirelen" */
63                uint32_t network;        /* data link type */
64} pcapfile_header_t;
65
66#define MAGIC1      0xa1b2c3d4  /* Original */
67#define MAGIC2      0xa1b23c4d  /* Newer nanosecond format */
68#define MAGIC1_REV  0xd4c3b2a1  /* Reversed byteorder detection */
69#define MAGIC2_REV  0x4d3cb2a1
70
71static inline int header_is_backwards_magic(pcapfile_header_t *header) {
72        return (header->magic_number == MAGIC1_REV || header->magic_number == MAGIC2_REV);
73}
74
75static inline int header_is_magic(pcapfile_header_t *header) {
76        return (header->magic_number == MAGIC1 || header->magic_number == MAGIC2 ||
77                header_is_backwards_magic(header));
78}
79
80static inline int trace_in_nanoseconds(pcapfile_header_t *header) {
81        return (header->magic_number == MAGIC2 || header->magic_number == MAGIC2_REV);
82}
83
84struct pcapfile_format_data_t {
85        struct {
86                /* Indicates whether the event API should replicate the pauses
87                 * between packets */
88                int real_time;
89        } options;
90
91        /* The PCAP meta-header that should be written at the start of each
92         * trace */
93        pcapfile_header_t header;
94        /* Indicates whether the input trace is started */
95        bool started;
96};
97
98struct pcapfile_format_data_out_t {
99        iow_t *file;
100        int compress_type;
101        int level;
102        int flag;
103
104};
105
106static int pcapfile_probe_magic(io_t *io)
107{
108        pcapfile_header_t header;
109        int len;
110        len = wandio_peek(io, &header, sizeof(header));
111
112        /* Is this long enough? */
113        if (len < (int)sizeof(header)) {
114                return 0;
115        }
116        /* Pcap magic? */
117        if (header_is_magic(&header)) {
118                return 1;
119        }
120        /* Nope, not pcap */
121        return 0;
122}
123
124
125static int pcapfile_init_input(libtrace_t *libtrace) {
126        libtrace->format_data = malloc(sizeof(struct pcapfile_format_data_t));
127
128        if (libtrace->format_data == NULL) {
129                trace_set_err(libtrace,ENOMEM,"Out of memory");
130                return -1;
131        }
132
133        IN_OPTIONS.real_time = 0;
134        DATA(libtrace)->started = false;
135        return 0;
136}
137
138static int pcapfile_init_output(libtrace_out_t *libtrace) {
139        libtrace->format_data = 
140                malloc(sizeof(struct pcapfile_format_data_out_t));
141
142        DATAOUT(libtrace)->file=NULL;
143        DATAOUT(libtrace)->compress_type=TRACE_OPTION_COMPRESSTYPE_NONE;
144        DATAOUT(libtrace)->level=0;
145        DATAOUT(libtrace)->flag=O_CREAT|O_WRONLY;
146
147        return 0;
148}
149
150
151static inline uint16_t swaps(libtrace_t *libtrace, uint16_t num)
152{
153        /* To deal with open_dead traces that might try and use this
154         * if we don't have any per trace data, assume host byte order
155         */
156        if (!DATA(libtrace))
157                return num;
158       
159        /* We can use the PCAP magic number to determine the byte order */
160        if (header_is_backwards_magic(&(DATA(libtrace)->header)))
161                return byteswap16(num);
162
163        return num;
164}
165
166static inline uint32_t swapl(libtrace_t *libtrace, uint32_t num)
167{
168        /* To deal with open_dead traces that might try and use this
169         * if we don't have any per trace data, assume host byte order
170         */
171        if (!DATA(libtrace))
172                return num;
173       
174        /* We can use the PCAP magic number to determine the byte order */
175        if (header_is_backwards_magic(&(DATA(libtrace)->header)))
176                return byteswap32(num);
177
178        return num;
179}
180
181
182static int pcapfile_start_input(libtrace_t *libtrace) 
183{
184        int err;
185
186        if (!libtrace->io) {
187                libtrace->io=trace_open_file(libtrace);
188                DATA(libtrace)->started=false;
189        }
190
191        if (!DATA(libtrace)->started) {
192
193                if (!libtrace->io)
194                        return -1;
195
196                err=wandio_read(libtrace->io,
197                                &DATA(libtrace)->header,
198                                sizeof(DATA(libtrace)->header));
199
200                DATA(libtrace)->started = true;
201                assert(sizeof(DATA(libtrace)->header) > 0);
202               
203                if (err<1) {
204                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
205                                "Error while reading pcap file header\n");
206                        return -1;
207                }
208       
209                if (err != (int)sizeof(DATA(libtrace)->header)) {
210                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
211                                "Incomplete pcap file header");
212                        return -1;
213                }
214               
215                if (!header_is_magic(&(DATA(libtrace)->header))) {
216                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
217                                        "Not a pcap tracefile (magic=%08x)\n",swapl(libtrace,DATA(libtrace)->header.magic_number));
218                        return -1; /* Not a pcap file */
219                }
220
221                if (swaps(libtrace,DATA(libtrace)->header.version_major)!=2
222                        && swaps(libtrace,DATA(libtrace)->header.version_minor)!=4) {
223                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
224                                        "Unknown pcap tracefile version %d.%d\n",
225                                        swaps(libtrace,
226                                                DATA(libtrace)->header.version_major),
227                                        swaps(libtrace,
228                                                DATA(libtrace)->header.version_minor));
229                        return -1;
230                }
231
232        }
233
234        return 0;
235}
236
237static int pcapfile_start_output(libtrace_out_t *libtrace UNUSED)
238{
239        /* We can't open the output file until we've seen the first packet.
240         * This is because we need to know the DLT to set the "network"
241         * value in the meta-header */
242       
243        return 0;
244}
245
246static int pcapfile_config_input(libtrace_t *libtrace,
247                trace_option_t option,
248                void *data)
249{
250        switch(option) {
251                case TRACE_OPTION_EVENT_REALTIME:
252                        IN_OPTIONS.real_time = *(int *)data;
253                        return 0;
254                case TRACE_OPTION_META_FREQ:
255                case TRACE_OPTION_SNAPLEN:
256                case TRACE_OPTION_PROMISC:
257                case TRACE_OPTION_FILTER:
258                case TRACE_OPTION_HASHER:
259                case TRACE_OPTION_REPLAY_SPEEDUP:
260                        /* All these are either unsupported or handled
261                         * by trace_config */
262                        break;
263        }
264       
265        trace_set_err(libtrace,TRACE_ERR_UNKNOWN_OPTION,
266                        "Unknown option %i", option);
267        return -1;
268}
269
270static int pcapfile_fin_input(libtrace_t *libtrace) 
271{
272        if (libtrace->io)
273                wandio_destroy(libtrace->io);
274        free(libtrace->format_data);
275        return 0; /* success */
276}
277
278static int pcapfile_fin_output(libtrace_out_t *libtrace)
279{
280        if (DATAOUT(libtrace)->file)
281                wandio_wdestroy(DATAOUT(libtrace)->file);
282        free(libtrace->format_data);
283        libtrace->format_data=NULL;
284        return 0; /* success */
285}
286
287static int pcapfile_config_output(libtrace_out_t *libtrace,
288                trace_option_output_t option,
289                void *value)
290{
291        switch (option) {
292                case TRACE_OPTION_OUTPUT_COMPRESS:
293                        DATAOUT(libtrace)->level = *(int*)value;
294                        return 0;
295                case TRACE_OPTION_OUTPUT_COMPRESSTYPE:
296                        DATAOUT(libtrace)->compress_type = *(int*)value;
297                        return 0;
298                case TRACE_OPTION_OUTPUT_FILEFLAGS:
299                        DATAOUT(libtrace)->flag = *(int*)value;
300                        return 0;
301                default:
302                        /* Unknown option */
303                        trace_set_err_out(libtrace,TRACE_ERR_UNKNOWN_OPTION,
304                                        "Unknown option");
305                        return -1;
306        }
307        return -1;
308}
309
310static int pcapfile_prepare_packet(libtrace_t *libtrace, 
311                libtrace_packet_t *packet, void *buffer, 
312                libtrace_rt_types_t rt_type, uint32_t flags) {
313
314        if (packet->buffer != buffer && 
315                        packet->buf_control == TRACE_CTRL_PACKET) {
316                free(packet->buffer);
317        }
318
319        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
320                packet->buf_control = TRACE_CTRL_PACKET;
321        } else
322                packet->buf_control = TRACE_CTRL_EXTERNAL;
323       
324       
325        packet->buffer = buffer;
326        packet->header = buffer;
327        packet->payload = (char*)packet->buffer
328                + sizeof(libtrace_pcapfile_pkt_hdr_t);
329        packet->type = rt_type; 
330
331        if (libtrace->format_data == NULL) {
332                if (pcapfile_init_input(libtrace))
333                        return -1;
334        }
335       
336        return 0;
337}
338
339static int pcapfile_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet)
340{
341        int err;
342        uint32_t flags = 0;
343        size_t bytes_to_read = 0;
344
345        assert(libtrace->format_data);
346
347        packet->type = pcap_linktype_to_rt(swapl(libtrace,
348                                DATA(libtrace)->header.network));
349
350        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
351                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
352        }
353
354        flags |= TRACE_PREP_OWN_BUFFER;
355       
356        err=wandio_read(libtrace->io,
357                        packet->buffer,
358                        sizeof(libtrace_pcapfile_pkt_hdr_t));
359        if (err<0) {
360                trace_set_err(libtrace,TRACE_ERR_WANDIO_FAILED,"reading packet");
361                return -1;
362        }
363        if (err==0) {
364                /* EOF */
365                return 0;
366        }
367
368        if (err < (int)sizeof(libtrace_pcapfile_pkt_hdr_t)) {
369                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Incomplete pcap packet header");
370                return -1;
371        }
372
373        bytes_to_read = swapl(libtrace,((libtrace_pcapfile_pkt_hdr_t*)packet->buffer)->caplen);
374
375        if (bytes_to_read >= LIBTRACE_PACKET_BUFSIZE) {
376                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Invalid caplen in pcap header (%u) - trace may be corrupt", (uint32_t)bytes_to_read);
377                return -1;
378        }
379
380        assert(bytes_to_read < LIBTRACE_PACKET_BUFSIZE);
381
382        /* If there is no payload to read, do not ask wandio_read to try and
383         * read zero bytes - we'll just get back a zero that we will
384         * misinterpret as EOF! */
385        if (bytes_to_read == 0) {
386                packet->header = packet->buffer;
387                return sizeof(libtrace_pcapfile_pkt_hdr_t);
388        }
389
390        err=wandio_read(libtrace->io,
391                        (char*)packet->buffer+sizeof(libtrace_pcapfile_pkt_hdr_t),
392                        (size_t)swapl(libtrace,((libtrace_pcapfile_pkt_hdr_t*)packet->buffer)->caplen)
393                        );
394
395        if (err<0) {
396                trace_set_err(libtrace,TRACE_ERR_WANDIO_FAILED,"reading packet");
397                return -1;
398        }
399        if (err==0) {
400                return 0;
401        }
402
403        if (err < (int)bytes_to_read) {
404                trace_set_err(libtrace, TRACE_ERR_WANDIO_FAILED, "Incomplete pcap packet body");
405                return -1;
406        }
407
408        if (pcapfile_prepare_packet(libtrace, packet, packet->buffer,
409                                packet->type, flags)) {
410                return -1;
411        }
412
413        /* We may as well cache this value now, seeing as we already had to
414         * look it up */
415        packet->capture_length = bytes_to_read; 
416        return sizeof(libtrace_pcapfile_pkt_hdr_t) + bytes_to_read;
417}
418
419static int pcapfile_write_packet(libtrace_out_t *out,
420                libtrace_packet_t *packet)
421{
422        struct libtrace_pcapfile_pkt_hdr_t hdr;
423        struct timeval tv = trace_get_timeval(packet);
424        int numbytes;
425        int ret;
426        void *ptr;
427        uint32_t remaining;
428        libtrace_linktype_t linktype;
429
430        ptr = trace_get_packet_buffer(packet,&linktype,&remaining);
431       
432        /* Silently discard RT metadata packets and packets with an
433         * unknown linktype. */
434        if (linktype == TRACE_TYPE_NONDATA || linktype == TRACE_TYPE_UNKNOWN || linktype == TRACE_TYPE_ERF_META) {
435                return 0;
436        }
437
438        /* If this packet cannot be converted to a pcap linktype then
439         * pop off the top header until it can be converted
440         */
441        while (libtrace_to_pcap_linktype(linktype)==TRACE_DLT_ERROR) {
442                if (!demote_packet(packet)) {
443                        trace_set_err_out(out, 
444                                TRACE_ERR_NO_CONVERSION,
445                                "pcap does not support this format");
446                        assert(0);
447                        return -1;
448                }
449
450                ptr = trace_get_packet_buffer(packet,&linktype,&remaining);
451        }
452
453
454        /* Now we know the link type write out a header if we've not done
455         * so already
456         */
457        if (!DATAOUT(out)->file) {
458                struct pcapfile_header_t pcaphdr;
459
460                DATAOUT(out)->file=trace_open_file_out(out,
461                                DATAOUT(out)->compress_type,
462                                DATAOUT(out)->level,
463                                DATAOUT(out)->flag);
464
465                if (!DATAOUT(out)->file) {
466                        trace_set_err_out(out,errno,"Unable to open file");
467                        return -1;
468                }
469
470                pcaphdr.magic_number = 0xa1b2c3d4;
471                pcaphdr.version_major = 2;
472                pcaphdr.version_minor = 4;
473                pcaphdr.thiszone = 0;
474                pcaphdr.sigfigs = 0;
475                pcaphdr.snaplen = 65536;
476                pcaphdr.network = 
477                        libtrace_to_pcap_linktype(linktype);
478
479                wandio_wwrite(DATAOUT(out)->file, 
480                                &pcaphdr, sizeof(pcaphdr));
481        }
482
483
484        hdr.ts_sec = (uint32_t)tv.tv_sec;
485        hdr.ts_usec = (uint32_t)tv.tv_usec;
486        hdr.caplen = trace_get_capture_length(packet);
487        assert(hdr.caplen < LIBTRACE_PACKET_BUFSIZE);
488        /* PCAP doesn't include the FCS in its wire length value, but we do */
489        if (linktype==TRACE_TYPE_ETH) {
490                if (trace_get_wire_length(packet) >= 4) {
491                        hdr.wirelen = trace_get_wire_length(packet)-4;
492                }
493                else {
494                        hdr.wirelen = 0;
495                }
496        }
497        else
498                hdr.wirelen = trace_get_wire_length(packet);
499
500        /* Reason for removing this assert:
501         *
502         * There exist some packets, e.g. in IPLS II, where the wire length
503         * is clearly corrupt. When converting to pcap, we *could* try to
504         * adjust the wire length to something sane but for now, I'll just let
505         * the broken length persist through the conversion.
506         *
507         * XXX Is setting the wire length to zero the best solution in such
508         * cases?
509         */
510
511        /* assert(hdr.wirelen < LIBTRACE_PACKET_BUFSIZE); */
512
513        /* Ensure we have a valid capture length, especially if we're going
514         * to "remove" the FCS from the wire length */
515        if (hdr.caplen > hdr.wirelen)
516                hdr.caplen = hdr.wirelen;
517
518        /* Write the packet header */
519        numbytes=wandio_wwrite(DATAOUT(out)->file,
520                        &hdr, sizeof(hdr));
521
522        if (numbytes!=sizeof(hdr)) 
523                return -1;
524
525        /* Write the rest of the packet now */
526        ret=wandio_wwrite(DATAOUT(out)->file,
527                        ptr,
528                        hdr.caplen);
529
530        if (ret!=(int)hdr.caplen)
531                return -1;
532
533        return numbytes+ret;
534}
535
536static libtrace_linktype_t pcapfile_get_link_type(
537                const libtrace_packet_t *packet) 
538{
539        return pcap_linktype_to_libtrace(rt_to_pcap_linktype(packet->type));
540}
541
542static libtrace_direction_t pcapfile_get_direction(const libtrace_packet_t *packet) 
543{
544        /* This function can be found in format_helper.c */
545        return pcap_get_direction(packet);
546}
547
548
549static struct timeval pcapfile_get_timeval(
550                const libtrace_packet_t *packet) 
551{
552        libtrace_pcapfile_pkt_hdr_t *hdr;
553        struct timeval ts;
554       
555        assert(packet->header);
556       
557        hdr = (libtrace_pcapfile_pkt_hdr_t*)packet->header;
558        ts.tv_sec = swapl(packet->trace,hdr->ts_sec);
559        /* Check trace is not a dummy calling trace_in_nanoseconds */
560        if (DATA(packet->trace) && trace_in_nanoseconds(&DATA(packet->trace)->header))
561                ts.tv_usec = swapl(packet->trace, hdr->ts_usec) / 1000;
562        else
563                ts.tv_usec = swapl(packet->trace,hdr->ts_usec);
564        return ts;
565}
566
567static struct timespec pcapfile_get_timespec(
568                const libtrace_packet_t *packet) 
569{
570        libtrace_pcapfile_pkt_hdr_t *hdr;
571        struct timespec ts;
572       
573        assert(packet->header);
574       
575        hdr = (libtrace_pcapfile_pkt_hdr_t*)packet->header;
576        ts.tv_sec = swapl(packet->trace,hdr->ts_sec);
577        /* Check trace is not a dummy calling trace_in_nanoseconds */
578        if (DATA(packet->trace) && trace_in_nanoseconds(&DATA(packet->trace)->header))
579                ts.tv_nsec = swapl(packet->trace, hdr->ts_usec);
580        else
581                ts.tv_nsec = swapl(packet->trace, hdr->ts_usec) * 1000;
582        return ts;
583}
584
585
586static int pcapfile_get_capture_length(const libtrace_packet_t *packet) {
587        libtrace_pcapfile_pkt_hdr_t *pcapptr; 
588
589        assert(packet->header);
590        pcapptr = (libtrace_pcapfile_pkt_hdr_t *)packet->header;
591
592        return swapl(packet->trace,pcapptr->caplen);
593}
594
595static int pcapfile_get_wire_length(const libtrace_packet_t *packet) {
596        libtrace_pcapfile_pkt_hdr_t *pcapptr;
597
598        assert(packet->header); 
599
600        pcapptr = (libtrace_pcapfile_pkt_hdr_t *)packet->header;
601        if (packet->type==pcap_linktype_to_rt(TRACE_DLT_EN10MB))
602                /* Include the missing FCS */
603                return swapl(packet->trace,pcapptr->wirelen)+4; 
604        else if (packet->type==pcap_linktype_to_rt(TRACE_DLT_IEEE802_11_RADIO)){
605                /* If the packet is Radiotap and the flags field indicates
606                 * that the FCS is not included in the 802.11 frame, then
607                 * we need to add 4 to the wire-length to account for it.
608                 */
609                uint8_t flags;
610                void *link;
611                libtrace_linktype_t linktype;
612                link = trace_get_packet_buffer(packet, &linktype, NULL);
613                trace_get_wireless_flags(link, linktype, &flags);
614                if ((flags & TRACE_RADIOTAP_F_FCS) == 0)
615                        return swapl(packet->trace,pcapptr->wirelen)+4;
616        } else if (packet->type == pcap_linktype_to_rt(TRACE_DLT_LINUX_SLL)) {
617                libtrace_sll_header_t *sll;
618                sll = (libtrace_sll_header_t *)packet->payload;
619
620                /* Account for FCS when dealing with Ethernet packets that are
621                 * encapsulated in Linux SLL. This should fix the problem
622                 * where the wire lengths differ if we convert the packet to
623                 * ERF */
624                if (ntohs(sll->protocol) == TRACE_ETHERTYPE_LOOPBACK)
625                        return swapl(packet->trace,pcapptr->wirelen)+4;
626        }
627
628        return swapl(packet->trace,pcapptr->wirelen);
629}
630
631static int pcapfile_get_framing_length(const libtrace_packet_t *packet UNUSED) {
632        return sizeof(libtrace_pcapfile_pkt_hdr_t);
633}
634
635static size_t pcapfile_set_capture_length(libtrace_packet_t *packet,size_t size) {
636        libtrace_pcapfile_pkt_hdr_t *pcapptr = 0;
637        assert(packet);
638        assert(packet->header);
639        if (size > trace_get_capture_length(packet)) {
640                /* Can't make a packet larger */
641                return trace_get_capture_length(packet);
642        }
643        /* Reset the cached capture length */
644        packet->capture_length = -1;
645        pcapptr = (libtrace_pcapfile_pkt_hdr_t *)packet->header;
646        pcapptr->caplen = swapl(packet->trace,(uint32_t)size);
647        return trace_get_capture_length(packet);
648}
649
650static struct libtrace_eventobj_t pcapfile_event(libtrace_t *libtrace, libtrace_packet_t *packet) {
651       
652        libtrace_eventobj_t event = {0,0,0.0,0};
653       
654        /* If we are being told to replay packets as fast as possible, then
655         * we just need to read and return the next packet in the trace */
656
657        if (IN_OPTIONS.real_time) {
658                event.size = trace_read_packet(libtrace, packet);
659                if (event.size < 1)
660                        event.type = TRACE_EVENT_TERMINATE;
661                else
662                        event.type = TRACE_EVENT_PACKET;
663                return event;
664        } else {
665                return trace_event_trace(libtrace, packet);
666        }
667}
668
669static void pcapfile_help(void) {
670        printf("pcapfile format module: $Revision: 1768 $\n");
671        printf("Supported input URIs:\n");
672        printf("\tpcapfile:/path/to/file\n");
673        printf("\tpcapfile:/path/to/file.gz\n");
674        printf("\n");
675        printf("\te.g.: pcapfile:/tmp/trace.pcap\n");
676        printf("\n");
677}
678
679static struct libtrace_format_t pcapfile = {
680        "pcapfile",
681        "$Id$",
682        TRACE_FORMAT_PCAPFILE,
683        NULL,                           /* probe filename */
684        pcapfile_probe_magic,           /* probe magic */
685        pcapfile_init_input,            /* init_input */
686        pcapfile_config_input,          /* config_input */
687        pcapfile_start_input,           /* start_input */
688        NULL,                           /* pause_input */
689        pcapfile_init_output,           /* init_output */
690        pcapfile_config_output,         /* config_output */
691        pcapfile_start_output,          /* start_output */
692        pcapfile_fin_input,             /* fin_input */
693        pcapfile_fin_output,            /* fin_output */
694        pcapfile_read_packet,           /* read_packet */
695        pcapfile_prepare_packet,        /* prepare_packet */
696        NULL,                           /* fin_packet */
697        pcapfile_write_packet,          /* write_packet */
698        pcapfile_get_link_type,         /* get_link_type */
699        pcapfile_get_direction,         /* get_direction */
700        NULL,                           /* set_direction */
701        NULL,                           /* get_erf_timestamp */
702        pcapfile_get_timeval,           /* get_timeval */
703        pcapfile_get_timespec,          /* get_timespec */
704        NULL,                           /* get_seconds */
705        NULL,                           /* seek_erf */
706        NULL,                           /* seek_timeval */
707        NULL,                           /* seek_seconds */
708        pcapfile_get_capture_length,    /* get_capture_length */
709        pcapfile_get_wire_length,       /* get_wire_length */
710        pcapfile_get_framing_length,    /* get_framing_length */
711        pcapfile_set_capture_length,    /* set_capture_length */
712        NULL,                           /* get_received_packets */
713        NULL,                           /* get_filtered_packets */
714        NULL,                           /* get_dropped_packets */
715        NULL,                           /* get_statistics */
716        NULL,                           /* get_fd */
717        pcapfile_event,         /* trace_event */
718        pcapfile_help,                  /* help */
719        NULL,                   /* next pointer */
720        NON_PARALLEL(false)
721};
722
723
724void pcapfile_constructor(void) {
725        register_format(&pcapfile);
726}
727
728
Note: See TracBrowser for help on using the repository browser.