source: lib/format_pcap.c @ a81d2fc

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since a81d2fc was 3a14f3b, checked in by Scott Raynel <smr26@…>, 14 years ago

Allow libtrace applications to create filters based on pre-compiled BPF
bytecode as well as filterstrings. See trace_create_filter_from_bytecode()

  • Property mode set to 100644
File size: 17.6 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30
31#include "common.h"
32#include "config.h"
33#include "libtrace.h"
34#include "libtrace_int.h"
35#include "format_helper.h"
36
37#include <sys/stat.h>
38#include <assert.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <errno.h>
43
44#ifdef HAVE_PCAP_H
45#  include <pcap.h>
46#  ifdef HAVE_PCAP_INT_H
47#    include <pcap-int.h>
48#  endif
49#endif
50
51#ifdef HAVE_LIBPCAP
52static struct libtrace_format_t pcap;
53static struct libtrace_format_t pcapint;
54
55#define DATA(x) ((struct pcap_format_data_t*)((x)->format_data))
56#define DATAOUT(x) ((struct pcap_format_data_out_t*)((x)->format_data))
57
58#define INPUT DATA(libtrace)->input
59#define OUTPUT DATAOUT(libtrace)->output
60struct pcap_format_data_t {
61        /** Information about the current state of the input device */
62        union {
63                pcap_t *pcap;
64        } input;
65        int snaplen;
66        libtrace_filter_t *filter;
67        int promisc;
68};
69
70struct pcap_format_data_out_t {
71        union {
72                struct {
73                        pcap_t *pcap;
74                        pcap_dumper_t *dump;
75                } trace;
76
77        } output;
78};
79
80static int pcap_init_input(libtrace_t *libtrace) {
81        libtrace->format_data = malloc(sizeof(struct pcap_format_data_t));
82
83        INPUT.pcap = NULL;
84        DATA(libtrace)->filter = NULL;
85        DATA(libtrace)->snaplen = LIBTRACE_PACKET_BUFSIZE;
86        DATA(libtrace)->promisc = 0;
87
88        return 0;
89}
90
91static int pcap_start_input(libtrace_t *libtrace) {
92        char errbuf[PCAP_ERRBUF_SIZE];
93
94        /* if the file is already open */
95        if (INPUT.pcap)
96                return 0; /* success */
97
98        if ((INPUT.pcap = 
99                pcap_open_offline(libtrace->uridata,
100                        errbuf)) == NULL) {
101                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
102                                errbuf);
103                return -1;
104        }
105        if (DATA(libtrace)->filter) {
106                if (DATA(libtrace)->filter->flag == 0) {
107                        pcap_compile(INPUT.pcap, 
108                                        &DATA(libtrace)->filter->filter,
109                                        DATA(libtrace)->filter->filterstring, 
110                                        1, 0);
111                        DATA(libtrace)->filter->flag = 1;
112                }
113                if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter) 
114                                == -1) {
115                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
116                                        pcap_geterr(INPUT.pcap));
117                        return -1;
118                }
119        }
120        return 0;
121}
122
123static int pcap_config_input(libtrace_t *libtrace,
124                trace_option_t option,
125                void *data)
126{
127        switch(option) {
128                case TRACE_OPTION_FILTER:
129                        DATA(libtrace)->filter=data;
130                        return 0;
131                case TRACE_OPTION_SNAPLEN:
132                        /* Snapping isn't supported directly, so fall thru
133                         * and let libtrace deal with it
134                         */
135                case TRACE_OPTION_PROMISC:
136                        /* can't do promisc on a trace! fall thru */
137                case TRACE_OPTION_META_FREQ:
138                        /* No meta data for this format */
139                case TRACE_OPTION_EVENT_REALTIME:
140                default:
141                        return -1;
142        }
143        assert(0);
144}
145
146static int pcap_init_output(libtrace_out_t *libtrace) {
147        libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t));
148        OUTPUT.trace.pcap = NULL;
149        OUTPUT.trace.dump = NULL;
150        return 0;
151}
152
153static int pcapint_init_output(libtrace_out_t *libtrace) {
154#ifdef HAVE_PCAP_INJECT
155        libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t));
156        OUTPUT.trace.pcap = NULL;
157        OUTPUT.trace.dump = NULL;
158        return 0;
159#else
160#ifdef HAVE_PCAP_SENDPACKET
161        libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t));
162        OUTPUT.trace.pcap = NULL;
163        OUTPUT.trace.dump = NULL;
164        return 0;
165#else
166        trace_set_err_out(libtrace,TRACE_ERR_UNSUPPORTED,
167                        "writing not supported by this version of pcap");
168        return -1;
169#endif
170#endif
171}
172
173static int pcapint_init_input(libtrace_t *libtrace) {
174        libtrace->format_data = malloc(sizeof(struct pcap_format_data_t));
175        DATA(libtrace)->filter = NULL;
176        DATA(libtrace)->snaplen = LIBTRACE_PACKET_BUFSIZE;
177        DATA(libtrace)->promisc = 0;
178        return 0; /* success */
179}
180
181static int pcapint_config_input(libtrace_t *libtrace,
182                trace_option_t option,
183                void *data)
184{
185        switch(option) {
186                case TRACE_OPTION_FILTER:
187                        DATA(libtrace)->filter=(libtrace_filter_t*)data;
188                        return 0;
189                case TRACE_OPTION_SNAPLEN:
190                        DATA(libtrace)->snaplen=*(int*)data;
191                        return 0;
192                case TRACE_OPTION_PROMISC:
193                        DATA(libtrace)->promisc=*(int*)data;
194                        return 0;
195                case TRACE_OPTION_META_FREQ:
196                        /* No meta-data for this format */
197                case TRACE_OPTION_EVENT_REALTIME:
198                        /* live interface is always real-time! */
199                default:
200                        /* Don't set an error here - trace_config will try
201                         * to handle the option when we return. If it can't
202                         * deal with it, then it will do the necessary
203                         * error-setting. */
204                        return -1;
205        }
206        assert(0);
207}
208
209static int pcapint_start_input(libtrace_t *libtrace) {
210        char errbuf[PCAP_ERRBUF_SIZE];
211        if ((INPUT.pcap = 
212                        pcap_open_live(libtrace->uridata,
213                        DATA(libtrace)->snaplen,
214                        DATA(libtrace)->promisc,
215                        1,
216                        errbuf)) == NULL) {
217                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
218                return -1; /* failure */
219        }
220        /* Set a filter if one is defined */
221        if (DATA(libtrace)->filter) {
222                if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter)
223                        == -1) {
224                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
225                                        pcap_geterr(INPUT.pcap));
226                        return -1; /* failure */
227                }
228        }
229#ifdef HAVE_PCAP_SETNONBLOCK
230        pcap_setnonblock(INPUT.pcap,0,errbuf);
231#endif
232        return 0; /* success */
233}
234
235static int pcap_pause_input(libtrace_t *libtrace)
236{
237        pcap_close(INPUT.pcap);
238        INPUT.pcap=NULL;
239        return 0; /* success */
240}
241
242
243static int pcap_fin_input(libtrace_t *libtrace) 
244{
245        free(libtrace->format_data);
246        return 0; /* success */
247}
248
249static int pcap_fin_output(libtrace_out_t *libtrace) 
250{
251        if (OUTPUT.trace.dump) {
252                pcap_dump_flush(OUTPUT.trace.dump);
253                pcap_dump_close(OUTPUT.trace.dump);
254        }
255        pcap_close(OUTPUT.trace.pcap);
256        free(libtrace->format_data);
257        return 0;
258}
259
260static int pcapint_fin_output(libtrace_out_t *libtrace)
261{
262        pcap_close(OUTPUT.trace.pcap);
263        free(libtrace->format_data);
264        return 0;
265}
266
267
268static int pcap_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
269        int ret = 0;
270        int linktype;
271
272        assert(libtrace->format_data);
273        linktype = pcap_datalink(DATA(libtrace)->input.pcap);
274        packet->type = pcap_linktype_to_rt(linktype);
275
276        packet->buf_control = TRACE_CTRL_PACKET;
277
278        /* If we're using the replacement pcap_next_ex() we need to
279         * make sure we have a buffer to *shudder* memcpy into
280         */
281        if (!packet->buffer) {
282                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
283                if (!packet->buffer) {
284                        trace_set_err(libtrace, errno, 
285                                        "Cannot allocate memory");
286                        return -1;
287                }
288                       
289                packet->header = packet->buffer;
290                packet->payload = (char *)packet->buffer + 
291                                        sizeof(struct pcap_pkthdr);
292        }
293       
294        for(;;) {
295
296                ret=pcap_next_ex(INPUT.pcap, 
297                                (struct pcap_pkthdr **)&packet->header,
298                                (const u_char **)&packet->payload);
299
300                switch(ret) {
301                        case 1: break; /* no error */
302                        case 0: continue; /* timeout expired */
303                        case -1:
304                                trace_set_err(libtrace,TRACE_ERR_BAD_PACKET,
305                                                "%s",pcap_geterr(INPUT.pcap));
306                                return -1; /* Error */
307                        case -2:
308                                return 0; /* EOF */
309                }
310
311                return ((struct pcap_pkthdr*)packet->header)->len
312                        +sizeof(struct pcap_pkthdr);
313        }
314}
315
316static int pcap_write_packet(libtrace_out_t *libtrace, 
317                libtrace_packet_t *packet) 
318{
319        struct pcap_pkthdr pcap_pkt_hdr;
320        void *link;
321        libtrace_linktype_t linktype;
322        uint32_t remaining;
323
324        link = trace_get_packet_buffer(packet,&linktype,&remaining);
325
326        /* If this packet cannot be converted to a pcap linktype then
327         * pop off the top header until it can be converted
328         */
329        while (libtrace_to_pcap_linktype(linktype)==~0U) {
330                if (!demote_packet(packet)) {
331                        trace_set_err_out(libtrace, 
332                                TRACE_ERR_NO_CONVERSION,
333                                "pcap does not support this format");
334                        return -1;
335                }
336
337                link = trace_get_packet_buffer(packet,&linktype,&remaining);
338        }
339
340
341        if (!OUTPUT.trace.pcap) {
342                int linktype=libtrace_to_pcap_dlt(trace_get_link_type(packet));
343                OUTPUT.trace.pcap = pcap_open_dead(linktype,65536);
344                if (!OUTPUT.trace.pcap) {
345                        trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,
346                                        "Failed to open dead trace: %s\n",
347                                        pcap_geterr(OUTPUT.trace.pcap));
348                }
349                OUTPUT.trace.dump = pcap_dump_open(OUTPUT.trace.pcap,
350                                libtrace->uridata);
351                if (!OUTPUT.trace.dump) {
352                        char *errmsg = pcap_geterr(OUTPUT.trace.pcap);
353                        trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,"Failed to open output file: %s\n",
354                                        errmsg ? errmsg : "Unknown error");
355                        return -1;
356                }
357        }
358
359        /* Corrupt packet, or other "non data" packet, so skip it */
360        if (link == NULL) {
361                /* Return "success", but nothing written */
362                return 0;
363        }
364
365        if (packet->trace->format == &pcap || 
366                        packet->trace->format == &pcapint) {
367                pcap_dump((u_char*)OUTPUT.trace.dump,
368                                (struct pcap_pkthdr *)packet->header,
369                                packet->payload);
370        } else {
371                /* Leave the manual copy as it is, as it gets around
372                 * some OS's having different structures in pcap_pkt_hdr
373                 */
374                struct timeval ts = trace_get_timeval(packet);
375                pcap_pkt_hdr.ts.tv_sec = ts.tv_sec;
376                pcap_pkt_hdr.ts.tv_usec = ts.tv_usec;
377                pcap_pkt_hdr.caplen = remaining;
378                /* trace_get_wire_length includes FCS, while pcap doesn't */
379                if (trace_get_link_type(packet)==TRACE_TYPE_ETH)
380                        if (trace_get_wire_length(packet) >= 4) { 
381                                pcap_pkt_hdr.len = 
382                                        trace_get_wire_length(packet)-4;
383                        }
384                        else {
385                                pcap_pkt_hdr.len = 0;
386                        }
387                else
388                        pcap_pkt_hdr.len = trace_get_wire_length(packet);
389
390                assert(pcap_pkt_hdr.caplen<65536);
391                assert(pcap_pkt_hdr.len<65536);
392
393                pcap_dump((u_char*)OUTPUT.trace.dump, &pcap_pkt_hdr, packet->payload);
394        }
395        return 0;
396}
397
398static int pcapint_write_packet(libtrace_out_t *libtrace,
399                libtrace_packet_t *packet) 
400{
401        int err;
402
403        if (!OUTPUT.trace.pcap) {
404                OUTPUT.trace.pcap = (pcap_t *)pcap_open_live(
405                        libtrace->uridata,65536,0,0,NULL);
406        }
407#ifdef HAVE_PCAP_INJECT
408        err=pcap_inject(OUTPUT.trace.pcap,
409                        packet->payload,
410                        trace_get_capture_length(packet));
411        if (err!=(int)trace_get_capture_length(packet))
412                err=-1;
413#else
414#ifdef HAVE_PCAP_SENDPACKET
415        err=pcap_sendpacket(OUTPUT.trace.pcap,
416                        packet->payload,
417                        trace_get_capture_length(packet));
418#else
419    trace_set_err(packet->trace,TRACE_ERR_UNSUPPORTED,"writing is not supported on this platform");
420        return -1;
421#endif
422#endif
423        return err;
424}
425
426static libtrace_linktype_t pcap_get_link_type(const libtrace_packet_t *packet) {
427        /* pcap doesn't store linktype in the framing header so we need
428         * rt to do it for us
429         */
430        int linktype = rt_to_pcap_linktype(packet->type);
431        return pcap_linktype_to_libtrace(linktype);
432}
433
434static libtrace_direction_t pcap_set_direction(libtrace_packet_t *packet,
435                libtrace_direction_t dir) {
436        libtrace_sll_header_t *sll;
437        promote_packet(packet);
438        sll=packet->payload;
439        /* sll->pkttype should be in the endianness of the host that the
440         * trace was taken on.  this is impossible to achieve
441         * so we assume host endianness
442         */
443        if(dir==TRACE_DIR_OUTGOING)
444                sll->pkttype=TRACE_SLL_OUTGOING;
445        else
446                sll->pkttype=TRACE_SLL_HOST;
447        return dir;
448}
449
450static libtrace_direction_t pcap_get_direction(const libtrace_packet_t *packet) {
451        libtrace_direction_t direction  = -1;
452        switch(pcap_get_link_type(packet)) {
453                case TRACE_TYPE_LINUX_SLL:
454                {
455                        libtrace_sll_header_t *sll;
456                        sll = trace_get_packet_buffer(packet, NULL, NULL);
457                        /* TODO: should check remaining>=sizeof(*sll) */
458                        if (!sll) {
459                                trace_set_err(packet->trace,
460                                        TRACE_ERR_BAD_PACKET,
461                                                "Bad or missing packet");
462                                return -1;
463                        }
464                        /* 0 == LINUX_SLL_HOST */
465                        /* the Waikato Capture point defines "packets
466                         * originating locally" (ie, outbound), with a
467                         * direction of 0, and "packets destined locally"
468                         * (ie, inbound), with a direction of 1.
469                         * This is kind-of-opposite to LINUX_SLL.
470                         * We return consistent values here, however
471                         *
472                         * Note that in recent versions of pcap, you can
473                         * use "inbound" and "outbound" on ppp in linux
474                         */
475                        if (sll->pkttype == TRACE_SLL_OUTGOING) {
476                                direction = TRACE_DIR_OUTGOING;
477                        } else {
478                                direction = TRACE_DIR_INCOMING;
479                        }
480                        break;
481
482                }
483                case TRACE_TYPE_PFLOG:
484                {
485                        libtrace_pflog_header_t *pflog;
486                        pflog = trace_get_packet_buffer(packet, NULL, NULL);
487                        /* TODO: should check remaining >= sizeof(*pflog) */
488                        if (!pflog) {
489                                trace_set_err(packet->trace,
490                                                TRACE_ERR_BAD_PACKET,
491                                                "Bad or missing packet");
492                                return -1;
493                        }
494                        /* enum    { PF_IN=0, PF_OUT=1 }; */
495                        if (ntohs(pflog->dir==0)) {
496
497                                direction = TRACE_DIR_INCOMING;
498                        }
499                        else {
500                                direction = TRACE_DIR_OUTGOING;
501                        }
502                        break;
503                }
504                default:
505                        break;
506        }       
507        return direction;
508}
509
510
511static struct timeval pcap_get_timeval(const libtrace_packet_t *packet) {
512        struct pcap_pkthdr *pcapptr = (struct pcap_pkthdr *)packet->header;
513        struct timeval ts;
514        ts.tv_sec = pcapptr->ts.tv_sec;
515        ts.tv_usec = pcapptr->ts.tv_usec;
516        return ts;
517}
518
519
520static int pcap_get_capture_length(const libtrace_packet_t *packet) {
521        struct pcap_pkthdr *pcapptr = 0;
522        pcapptr = (struct pcap_pkthdr *)packet->header;
523        assert(pcapptr->caplen<=65536);
524
525        return pcapptr->caplen;
526}
527
528static int pcap_get_wire_length(const libtrace_packet_t *packet) {
529        struct pcap_pkthdr *pcapptr = 0;
530        pcapptr = (struct pcap_pkthdr *)packet->header;
531        if (packet->type==pcap_linktype_to_rt(TRACE_DLT_EN10MB))
532                return pcapptr->len+4; /* Include the missing FCS */
533        else if (packet->type==pcap_linktype_to_rt(TRACE_DLT_IEEE802_11_RADIO)) {
534                libtrace_linktype_t linktype;
535                void *link = trace_get_packet_buffer(packet,&linktype,NULL);
536                /* If the packet is Radiotap and the flags field indicates
537                 * that the FCS is not included in the 802.11 frame, then
538                 * we need to add 4 to the wire-length to account for it.
539                 */
540                uint8_t flags;
541                trace_get_wireless_flags(link, 
542                                linktype, &flags);
543                if ((flags & TRACE_RADIOTAP_F_FCS) == 0)
544                        return pcapptr->len + 4;
545        }
546        return pcapptr->len;
547}
548
549static int pcap_get_framing_length(UNUSED const libtrace_packet_t *packet) {
550        return sizeof(struct pcap_pkthdr);
551}
552
553static size_t pcap_set_capture_length(libtrace_packet_t *packet,size_t size) {
554        struct pcap_pkthdr *pcapptr = 0;
555        assert(packet);
556        if (size > trace_get_capture_length(packet)) {
557                /* can't make a packet larger */
558                return trace_get_capture_length(packet);
559        }
560        pcapptr = (struct pcap_pkthdr *)packet->header;
561        pcapptr->caplen = size;
562        return trace_get_capture_length(packet);
563}
564
565static int pcap_get_fd(const libtrace_t *trace) {
566
567        assert(trace->format_data);
568        return pcap_fileno(DATA(trace)->input.pcap);
569}
570
571static void pcap_help(void) {
572        printf("pcap format module: $Revision$\n");
573        printf("Supported input URIs:\n");
574        printf("\tpcap:/path/to/file\n");
575        printf("\n");
576        printf("\te.g.: pcap:/tmp/trace.pcap\n");
577        printf("\n");
578        printf("Supported output URIs:\n");
579        printf("\tnone\n");
580        printf("\n");
581}
582
583static void pcapint_help(void) {
584        printf("pcapint format module: $Revision$\n");
585        printf("Supported input URIs:\n");
586        printf("\tpcapint:interface\n");
587        printf("\n");
588        printf("\te.g.: pcapint:eth0\n");
589        printf("\n");
590        printf("Supported output URIs:\n");
591        printf("\tnone\n");
592        printf("\n");
593}
594
595
596static struct libtrace_format_t pcap = {
597        "pcap",
598        "$Id$",
599        TRACE_FORMAT_PCAP,
600        pcap_init_input,                /* init_input */
601        pcap_config_input,              /* config_input */
602        pcap_start_input,               /* start_input */
603        NULL,                           /* pause_input */
604        pcap_init_output,               /* init_output */
605        NULL,                           /* config_output */
606        NULL,                           /* start_output */
607        pcap_fin_input,                 /* fin_input */
608        pcap_fin_output,                /* fin_output */
609        pcap_read_packet,               /* read_packet */
610        NULL,                           /* fin_packet */
611        pcap_write_packet,              /* write_packet */
612        pcap_get_link_type,             /* get_link_type */
613        pcap_get_direction,             /* get_direction */
614        pcap_set_direction,             /* set_direction */
615        NULL,                           /* get_erf_timestamp */
616        pcap_get_timeval,               /* get_timeval */
617        NULL,                           /* get_seconds */
618        NULL,                           /* seek_erf */
619        NULL,                           /* seek_timeval */
620        NULL,                           /* seek_seconds */
621        pcap_get_capture_length,        /* get_capture_length */
622        pcap_get_wire_length,           /* get_wire_length */
623        pcap_get_framing_length,        /* get_framing_length */
624        pcap_set_capture_length,        /* set_capture_length */
625        NULL,                           /* get_fd */
626        trace_event_trace,              /* trace_event */
627        pcap_help,                      /* help */
628        NULL                            /* next pointer */
629};
630
631static struct libtrace_format_t pcapint = {
632        "pcapint",
633        "$Id$",
634        TRACE_FORMAT_PCAP,
635        pcapint_init_input,             /* init_input */
636        pcapint_config_input,           /* config_input */
637        pcapint_start_input,            /* start_input */
638        pcap_pause_input,               /* pause_input */
639        pcapint_init_output,            /* init_output */
640        NULL,                           /* config_output */
641        NULL,                           /* start_output */
642        pcap_fin_input,                 /* fin_input */
643        pcapint_fin_output,             /* fin_output */
644        pcap_read_packet,               /* read_packet */
645        NULL,                           /* fin_packet */
646        pcapint_write_packet,           /* write_packet */
647        pcap_get_link_type,             /* get_link_type */
648        pcap_get_direction,             /* get_direction */
649        pcap_set_direction,             /* set_direction */
650        NULL,                           /* get_erf_timestamp */
651        pcap_get_timeval,               /* get_timeval */
652        NULL,                           /* get_seconds */
653        NULL,                           /* seek_erf */
654        NULL,                           /* seek_timeval */
655        NULL,                           /* seek_seconds */
656        pcap_get_capture_length,        /* get_capture_length */
657        pcap_get_wire_length,           /* get_wire_length */
658        pcap_get_framing_length,        /* get_framing_length */
659        pcap_set_capture_length,        /* set_capture_length */
660        pcap_get_fd,                    /* get_fd */
661        trace_event_device,             /* trace_event */
662        pcapint_help,                   /* help */
663        NULL                            /* next pointer */
664};
665
666void pcap_constructor(void) {
667        register_format(&pcap);
668        register_format(&pcapint);
669}
670
671
672#endif
Note: See TracBrowser for help on using the repository browser.