source: lib/format_pcapfile.c @ 11041eb

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