source: lib/format_pcapfile.c @ bf7e954

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since bf7e954 was b5af22c, checked in by Perry Lorier <perry@…>, 11 years ago

Split compression type out from fileflags

  • Property mode set to 100644
File size: 18.1 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 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 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                if (err<1)
189                        return -1;
190               
191                if (swapl(libtrace,DATA(libtrace)->header.magic_number) != 
192                                        0xa1b2c3d4) {
193                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
194                                        "Not a pcap tracefile\n");
195                        return -1; /* Not a pcap file */
196                }
197
198                if (swaps(libtrace,DATA(libtrace)->header.version_major)!=2
199                        && swaps(libtrace,DATA(libtrace)->header.version_minor)!=4) {
200                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
201                                        "Unknown pcap tracefile version %d.%d\n",
202                                        swaps(libtrace,
203                                                DATA(libtrace)->header.version_major),
204                                        swaps(libtrace,
205                                                DATA(libtrace)->header.version_minor));
206                        return -1;
207                }
208
209        }
210
211        return 0;
212}
213
214static int pcapfile_start_output(libtrace_out_t *libtrace UNUSED)
215{
216        /* We can't open the output file until we've seen the first packet.
217         * This is because we need to know the DLT to set the "network"
218         * value in the meta-header */
219       
220        return 0;
221}
222
223static int pcapfile_config_input(libtrace_t *libtrace,
224                trace_option_t option,
225                void *data)
226{
227        switch(option) {
228                case TRACE_OPTION_EVENT_REALTIME:
229                        IN_OPTIONS.real_time = *(int *)data;
230                        return 0;
231                case TRACE_OPTION_META_FREQ:
232                case TRACE_OPTION_SNAPLEN:
233                case TRACE_OPTION_PROMISC:
234                case TRACE_OPTION_FILTER:
235                        /* All these are either unsupported or handled
236                         * by trace_config */
237                        break;
238        }
239       
240        trace_set_err(libtrace,TRACE_ERR_UNKNOWN_OPTION,
241                        "Unknown option %i", option);
242        return -1;
243}
244
245static int pcapfile_fin_input(libtrace_t *libtrace) 
246{
247        if (libtrace->io)
248                wandio_destroy(libtrace->io);
249        free(libtrace->format_data);
250        return 0; /* success */
251}
252
253static int pcapfile_fin_output(libtrace_out_t *libtrace)
254{
255        if (DATAOUT(libtrace)->file)
256                wandio_wdestroy(DATAOUT(libtrace)->file);
257        free(libtrace->format_data);
258        libtrace->format_data=NULL;
259        return 0; /* success */
260}
261
262static int pcapfile_config_output(libtrace_out_t *libtrace,
263                trace_option_output_t option,
264                void *value)
265{
266        switch (option) {
267                case TRACE_OPTION_OUTPUT_COMPRESS:
268                        DATAOUT(libtrace)->level = *(int*)value;
269                        return 0;
270                case TRACE_OPTION_OUTPUT_COMPRESSTYPE:
271                        DATAOUT(libtrace)->compress_type = *(int*)value;
272                        return 0;
273                case TRACE_OPTION_OUTPUT_FILEFLAGS:
274                        DATAOUT(libtrace)->flag = *(int*)value;
275                        return 0;
276                default:
277                        /* Unknown option */
278                        trace_set_err_out(libtrace,TRACE_ERR_UNKNOWN_OPTION,
279                                        "Unknown option");
280                        return -1;
281        }
282        return -1;
283}
284
285static int pcapfile_prepare_packet(libtrace_t *libtrace, 
286                libtrace_packet_t *packet, void *buffer, 
287                libtrace_rt_types_t rt_type, uint32_t flags) {
288
289        if (packet->buffer != buffer && 
290                        packet->buf_control == TRACE_CTRL_PACKET) {
291                free(packet->buffer);
292        }
293
294        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
295                packet->buf_control = TRACE_CTRL_PACKET;
296        } else
297                packet->buf_control = TRACE_CTRL_EXTERNAL;
298       
299       
300        packet->buffer = buffer;
301        packet->header = buffer;
302        packet->payload = (char*)packet->buffer
303                + sizeof(libtrace_pcapfile_pkt_hdr_t);
304        packet->type = rt_type; 
305
306        if (libtrace->format_data == NULL) {
307                if (pcapfile_init_input(libtrace))
308                        return -1;
309        }
310       
311        return 0;
312}
313
314static int pcapfile_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet)
315{
316        int err;
317        uint32_t flags = 0;
318        size_t bytes_to_read = 0;
319
320        assert(libtrace->format_data);
321
322        packet->type = pcap_linktype_to_rt(swapl(libtrace,
323                                DATA(libtrace)->header.network));
324
325        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
326                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
327        }
328
329        flags |= TRACE_PREP_OWN_BUFFER;
330       
331        err=wandio_read(libtrace->io,
332                        packet->buffer,
333                        sizeof(libtrace_pcapfile_pkt_hdr_t));
334
335        if (err<0) {
336                trace_set_err(libtrace,errno,"reading packet");
337                return -1;
338        }
339        if (err==0) {
340                /* EOF */
341                return 0;
342        }
343
344        bytes_to_read = swapl(libtrace,((libtrace_pcapfile_pkt_hdr_t*)packet->buffer)->caplen);
345
346        assert(bytes_to_read < LIBTRACE_PACKET_BUFSIZE);
347
348        /* If there is no payload to read, do not ask wandio_read to try and
349         * read zero bytes - we'll just get back a zero that we will
350         * misinterpret as EOF! */
351        if (bytes_to_read == 0) {
352                packet->header = packet->buffer;
353                return sizeof(libtrace_pcapfile_pkt_hdr_t);
354        }
355
356        err=wandio_read(libtrace->io,
357                        (char*)packet->buffer+sizeof(libtrace_pcapfile_pkt_hdr_t),
358                        (size_t)swapl(libtrace,((libtrace_pcapfile_pkt_hdr_t*)packet->buffer)->caplen)
359                        );
360
361       
362        if (err<0) {
363                trace_set_err(libtrace,errno,"reading packet");
364                return -1;
365        }
366        if (err==0) {
367                return 0;
368        }
369
370        if (pcapfile_prepare_packet(libtrace, packet, packet->buffer,
371                                packet->type, flags)) {
372                return -1;
373        }
374       
375        return sizeof(libtrace_pcapfile_pkt_hdr_t) + bytes_to_read;
376}
377
378static int pcapfile_write_packet(libtrace_out_t *out,
379                libtrace_packet_t *packet)
380{
381        struct libtrace_pcapfile_pkt_hdr_t hdr;
382        struct timeval tv = trace_get_timeval(packet);
383        int numbytes;
384        int ret;
385        void *ptr;
386        uint32_t remaining;
387        libtrace_linktype_t linktype;
388
389        ptr = trace_get_packet_buffer(packet,&linktype,&remaining);
390       
391        /* Silently discard RT metadata packets and packets with an
392         * unknown linktype. */
393        if (linktype == TRACE_TYPE_METADATA || linktype == ~0U) {
394                return 0;
395        }
396
397        /* If this packet cannot be converted to a pcap linktype then
398         * pop off the top header until it can be converted
399         */
400        while (libtrace_to_pcap_linktype(linktype)==~0U) {
401                if (!demote_packet(packet)) {
402                        trace_set_err_out(out, 
403                                TRACE_ERR_NO_CONVERSION,
404                                "pcap does not support this format");
405                        return -1;
406                }
407
408                ptr = trace_get_packet_buffer(packet,&linktype,&remaining);
409        }
410
411
412        /* Now we know the link type write out a header if we've not done
413         * so already
414         */
415        if (!DATAOUT(out)->file) {
416                struct pcapfile_header_t pcaphdr;
417
418                DATAOUT(out)->file=trace_open_file_out(out,
419                                DATAOUT(out)->compress_type,
420                                DATAOUT(out)->level,
421                                DATAOUT(out)->flag);
422                if (!DATAOUT(out)->file)
423                        return -1;
424
425                pcaphdr.magic_number = 0xa1b2c3d4;
426                pcaphdr.version_major = 2;
427                pcaphdr.version_minor = 4;
428                pcaphdr.thiszone = 0;
429                pcaphdr.sigfigs = 0;
430                pcaphdr.snaplen = 65536;
431                pcaphdr.network = 
432                        libtrace_to_pcap_linktype(linktype);
433
434                wandio_wwrite(DATAOUT(out)->file, 
435                                &pcaphdr, sizeof(pcaphdr));
436        }
437
438        hdr.ts_sec = tv.tv_sec;
439        hdr.ts_usec = tv.tv_usec;
440        hdr.caplen = trace_get_capture_length(packet);
441        assert(hdr.caplen < LIBTRACE_PACKET_BUFSIZE);
442        /* PCAP doesn't include the FCS in its wire length value, but we do */
443        if (linktype==TRACE_TYPE_ETH) {
444                if (trace_get_wire_length(packet) >= 4) {
445                        hdr.wirelen = trace_get_wire_length(packet)-4;
446
447                }
448                else {
449                        hdr.wirelen = 0;
450                }
451        }
452        else
453                hdr.wirelen = trace_get_wire_length(packet);
454
455        assert(hdr.wirelen < LIBTRACE_PACKET_BUFSIZE);
456
457        /* Ensure we have a valid capture length, especially if we're going
458         * to "remove" the FCS from the wire length */
459        if (hdr.caplen > hdr.wirelen)
460                hdr.caplen = hdr.wirelen;
461
462        /* Write the packet header */
463        numbytes=wandio_wwrite(DATAOUT(out)->file,
464                        &hdr, sizeof(hdr));
465
466        if (numbytes!=sizeof(hdr)) 
467                return -1;
468
469        /* Write the rest of the packet now */
470        ret=wandio_wwrite(DATAOUT(out)->file,
471                        ptr,
472                        hdr.caplen);
473
474        if (ret!=(int)hdr.caplen)
475                return -1;
476
477        return numbytes+ret;
478}
479
480static libtrace_linktype_t pcapfile_get_link_type(
481                const libtrace_packet_t *packet) 
482{
483        return pcap_linktype_to_libtrace(rt_to_pcap_linktype(packet->type));
484}
485
486static libtrace_direction_t pcapfile_get_direction(const libtrace_packet_t *packet) 
487{
488        libtrace_direction_t direction  = -1;
489        switch(pcapfile_get_link_type(packet)) {
490                /* We can only get the direction for PCAP packets that have
491                 * been encapsulated in Linux SLL or PFLOG */
492                case TRACE_TYPE_LINUX_SLL:
493                {
494                        libtrace_sll_header_t *sll;
495                        libtrace_linktype_t linktype;
496
497                        sll = (libtrace_sll_header_t*)trace_get_packet_buffer(
498                                        packet,
499                                        &linktype,
500                                        NULL);
501                        if (!sll) {
502                                trace_set_err(packet->trace,
503                                        TRACE_ERR_BAD_PACKET,
504                                                "Bad or missing packet");
505                                return -1;
506                        }
507                        /* 0 == LINUX_SLL_HOST */
508                        /* the Waikato Capture point defines "packets
509                         * originating locally" (ie, outbound), with a
510                         * direction of 0, and "packets destined locally"
511                         * (ie, inbound), with a direction of 1.
512                         * This is kind-of-opposite to LINUX_SLL.
513                         * We return consistent values here, however
514                         *
515                         * Note that in recent versions of pcap, you can
516                         * use "inbound" and "outbound" on ppp in linux
517                         */
518                        if (ntohs(sll->pkttype == 0)) {
519                                direction = TRACE_DIR_INCOMING;
520                        } else {
521                                direction = TRACE_DIR_OUTGOING;
522                        }
523                        break;
524
525                }
526                case TRACE_TYPE_PFLOG:
527                {
528                        libtrace_pflog_header_t *pflog;
529                        libtrace_linktype_t linktype;
530
531                        pflog=(libtrace_pflog_header_t*)trace_get_packet_buffer(
532                                        packet,&linktype,NULL);
533                        if (!pflog) {
534                                trace_set_err(packet->trace,
535                                                TRACE_ERR_BAD_PACKET,
536                                                "Bad or missing packet");
537                                return -1;
538                        }
539                        /* enum    { PF_IN=0, PF_OUT=1 }; */
540                        if (ntohs(pflog->dir==0)) {
541
542                                direction = TRACE_DIR_INCOMING;
543                        }
544                        else {
545                                direction = TRACE_DIR_OUTGOING;
546                        }
547                        break;
548                }
549                default:
550                        break;
551        }       
552        return direction;
553}
554
555
556static struct timeval pcapfile_get_timeval(
557                const libtrace_packet_t *packet) 
558{
559        libtrace_pcapfile_pkt_hdr_t *hdr;
560        struct timeval ts;
561       
562        assert(packet->header);
563       
564        hdr = (libtrace_pcapfile_pkt_hdr_t*)packet->header;
565        ts.tv_sec = swapl(packet->trace,hdr->ts_sec);
566        ts.tv_usec = swapl(packet->trace,hdr->ts_usec);
567        return ts;
568}
569
570
571static int pcapfile_get_capture_length(const libtrace_packet_t *packet) {
572        libtrace_pcapfile_pkt_hdr_t *pcapptr; 
573
574        assert(packet->header);
575        pcapptr = (libtrace_pcapfile_pkt_hdr_t *)packet->header;
576
577        return swapl(packet->trace,pcapptr->caplen);
578}
579
580static int pcapfile_get_wire_length(const libtrace_packet_t *packet) {
581        libtrace_pcapfile_pkt_hdr_t *pcapptr;
582         
583        assert(packet->header); 
584
585        pcapptr = (libtrace_pcapfile_pkt_hdr_t *)packet->header;
586        if (packet->type==pcap_linktype_to_rt(TRACE_DLT_EN10MB))
587                /* Include the missing FCS */
588                return swapl(packet->trace,pcapptr->wirelen)+4; 
589        else if (packet->type==pcap_linktype_to_rt(TRACE_DLT_IEEE802_11_RADIO)){
590                /* If the packet is Radiotap and the flags field indicates
591                 * that the FCS is not included in the 802.11 frame, then
592                 * we need to add 4 to the wire-length to account for it.
593                 */
594                uint8_t flags;
595                void *link;
596                libtrace_linktype_t linktype;
597                link = trace_get_packet_buffer(packet, &linktype, NULL);
598                trace_get_wireless_flags(link, linktype, &flags);
599                if ((flags & TRACE_RADIOTAP_F_FCS) == 0)
600                        return swapl(packet->trace,pcapptr->wirelen)+4;
601        }
602        return swapl(packet->trace,pcapptr->wirelen);
603}
604
605static int pcapfile_get_framing_length(const libtrace_packet_t *packet UNUSED) {
606        return sizeof(libtrace_pcapfile_pkt_hdr_t);
607}
608
609static size_t pcapfile_set_capture_length(libtrace_packet_t *packet,size_t size) {
610        libtrace_pcapfile_pkt_hdr_t *pcapptr = 0;
611        assert(packet);
612        assert(packet->header);
613        if (size > trace_get_capture_length(packet)) {
614                /* Can't make a packet larger */
615                return trace_get_capture_length(packet);
616        }
617        /* Reset the cached capture length */
618        packet->capture_length = -1;
619        pcapptr = (libtrace_pcapfile_pkt_hdr_t *)packet->header;
620        pcapptr->caplen = swapl(packet->trace,(uint32_t)size);
621        return trace_get_capture_length(packet);
622}
623
624static struct libtrace_eventobj_t pcapfile_event(libtrace_t *libtrace, libtrace_packet_t *packet) {
625       
626        libtrace_eventobj_t event = {0,0,0.0,0};
627       
628        /* If we are being told to replay packets as fast as possible, then
629         * we just need to read and return the next packet in the trace */
630
631        if (IN_OPTIONS.real_time) {
632                event.size = pcapfile_read_packet(libtrace, packet);
633                if (event.size < 1)
634                        event.type = TRACE_EVENT_TERMINATE;
635                else
636                        event.type = TRACE_EVENT_PACKET;
637                return event;
638        } else {
639                return trace_event_trace(libtrace, packet);
640        }
641}
642
643static void pcapfile_help(void) {
644        printf("pcapfile format module: $Revision$\n");
645        printf("Supported input URIs:\n");
646        printf("\tpcapfile:/path/to/file\n");
647        printf("\tpcapfile:/path/to/file.gz\n");
648        printf("\n");
649        printf("\te.g.: pcapfile:/tmp/trace.pcap\n");
650        printf("\n");
651}
652
653static struct libtrace_format_t pcapfile = {
654        "pcapfile",
655        "$Id$",
656        TRACE_FORMAT_PCAPFILE,
657        NULL,                           /* probe filename */
658        pcapfile_probe_magic,           /* probe magic */
659        pcapfile_init_input,            /* init_input */
660        pcapfile_config_input,          /* config_input */
661        pcapfile_start_input,           /* start_input */
662        NULL,                           /* pause_input */
663        pcapfile_init_output,           /* init_output */
664        pcapfile_config_output,         /* config_output */
665        pcapfile_start_output,          /* start_output */
666        pcapfile_fin_input,             /* fin_input */
667        pcapfile_fin_output,            /* fin_output */
668        pcapfile_read_packet,           /* read_packet */
669        pcapfile_prepare_packet,        /* prepare_packet */
670        NULL,                           /* fin_packet */
671        pcapfile_write_packet,          /* write_packet */
672        pcapfile_get_link_type,         /* get_link_type */
673        pcapfile_get_direction,         /* get_direction */
674        NULL,                           /* set_direction */
675        NULL,                           /* get_erf_timestamp */
676        pcapfile_get_timeval,           /* get_timeval */
677        NULL,                           /* get_timespec */
678        NULL,                           /* get_seconds */
679        NULL,                           /* seek_erf */
680        NULL,                           /* seek_timeval */
681        NULL,                           /* seek_seconds */
682        pcapfile_get_capture_length,    /* get_capture_length */
683        pcapfile_get_wire_length,       /* get_wire_length */
684        pcapfile_get_framing_length,    /* get_framing_length */
685        pcapfile_set_capture_length,    /* set_capture_length */
686        NULL,                           /* get_received_packets */
687        NULL,                           /* get_filtered_packets */
688        NULL,                           /* get_dropped_packets */
689        NULL,                           /* get_captured_packets */
690        NULL,                           /* get_fd */
691        pcapfile_event,         /* trace_event */
692        pcapfile_help,                  /* help */
693        NULL                            /* next pointer */
694};
695
696
697void pcapfile_constructor(void) {
698        register_format(&pcapfile);
699}
700
701
Note: See TracBrowser for help on using the repository browser.