source: lib/format_pcap.c @ f0fb38f

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since f0fb38f was f0fb38f, checked in by Shane Alcock <salcock@…>, 14 years ago
  • Added prepare_packet functions to all formats, primarily to support translating RT packets into the appropriate format. These functions are all used internally as well, as most formats still need to "prepare" packets that have been read by setting pointers, updating loss counters etc.
  • Also added a trace_prepare_packet function, but this is not made available externally at this stage
  • Added init_format_data functions to some formats to initialise format data structures in cases where the init_trace function does more than just that
  • Refactored rt packet reading code to use the new trace_prepare_packet functionality - also did a lot of tidying of the code
  • Added missing RT type for BPF format
  • Property mode set to 100644
File size: 19.7 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008 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
95        /* if the file is already open */
96        if (INPUT.pcap)
97                return 0; /* success */
98
99        if ((INPUT.pcap = 
100                pcap_open_offline(libtrace->uridata,
101                        errbuf)) == NULL) {
102                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
103                                errbuf);
104                return -1;
105        }
106        if (DATA(libtrace)->filter) {
107                if (DATA(libtrace)->filter->flag == 0) {
108                        pcap_compile(INPUT.pcap, 
109                                        &DATA(libtrace)->filter->filter,
110                                        DATA(libtrace)->filter->filterstring, 
111                                        1, 0);
112                        DATA(libtrace)->filter->flag = 1;
113                }
114                if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter) 
115                                == -1) {
116                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
117                                        pcap_geterr(INPUT.pcap));
118                        return -1;
119                }
120        }
121        return 0;
122}
123
124static int pcap_config_input(libtrace_t *libtrace,
125                trace_option_t option,
126                void *data)
127{
128        switch(option) {
129                case TRACE_OPTION_FILTER:
130                        DATA(libtrace)->filter=data;
131                        return 0;
132                case TRACE_OPTION_SNAPLEN:
133                        /* Snapping isn't supported directly, so fall thru
134                         * and let libtrace deal with it
135                         */
136                case TRACE_OPTION_PROMISC:
137                        /* can't do promisc on a trace! fall thru */
138                case TRACE_OPTION_META_FREQ:
139                        /* No meta data for this format */
140                case TRACE_OPTION_EVENT_REALTIME:
141                default:
142                        return -1;
143        }
144        assert(0);
145}
146
147static int pcap_init_output(libtrace_out_t *libtrace) {
148        libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t));
149        OUTPUT.trace.pcap = NULL;
150        OUTPUT.trace.dump = NULL;
151        return 0;
152}
153
154static int pcapint_init_output(libtrace_out_t *libtrace) {
155#ifdef HAVE_PCAP_INJECT
156        libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t));
157        OUTPUT.trace.pcap = NULL;
158        OUTPUT.trace.dump = NULL;
159        return 0;
160#else
161#ifdef HAVE_PCAP_SENDPACKET
162        libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t));
163        OUTPUT.trace.pcap = NULL;
164        OUTPUT.trace.dump = NULL;
165        return 0;
166#else
167        trace_set_err_out(libtrace,TRACE_ERR_UNSUPPORTED,
168                        "writing not supported by this version of pcap");
169        return -1;
170#endif
171#endif
172}
173
174static int pcapint_init_input(libtrace_t *libtrace) {
175        libtrace->format_data = malloc(sizeof(struct pcap_format_data_t));
176        DATA(libtrace)->filter = NULL;
177        DATA(libtrace)->snaplen = LIBTRACE_PACKET_BUFSIZE;
178        DATA(libtrace)->promisc = 0;
179        return 0; /* success */
180}
181
182static int pcapint_config_input(libtrace_t *libtrace,
183                trace_option_t option,
184                void *data)
185{
186        switch(option) {
187                case TRACE_OPTION_FILTER:
188                        DATA(libtrace)->filter=(libtrace_filter_t*)data;
189                        return 0;
190                case TRACE_OPTION_SNAPLEN:
191                        DATA(libtrace)->snaplen=*(int*)data;
192                        return 0;
193                case TRACE_OPTION_PROMISC:
194                        DATA(libtrace)->promisc=*(int*)data;
195                        return 0;
196                case TRACE_OPTION_META_FREQ:
197                        /* No meta-data for this format */
198                case TRACE_OPTION_EVENT_REALTIME:
199                        /* live interface is always real-time! */
200                default:
201                        /* Don't set an error here - trace_config will try
202                         * to handle the option when we return. If it can't
203                         * deal with it, then it will do the necessary
204                         * error-setting. */
205                        return -1;
206        }
207        assert(0);
208}
209
210static int pcapint_start_input(libtrace_t *libtrace) {
211        char errbuf[PCAP_ERRBUF_SIZE];
212        if ((INPUT.pcap = 
213                        pcap_open_live(libtrace->uridata,
214                        DATA(libtrace)->snaplen,
215                        DATA(libtrace)->promisc,
216                        1,
217                        errbuf)) == NULL) {
218                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
219                return -1; /* failure */
220        }
221        /* Set a filter if one is defined */
222        if (DATA(libtrace)->filter) {
223                if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter)
224                        == -1) {
225                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
226                                        pcap_geterr(INPUT.pcap));
227                        return -1; /* failure */
228                }
229        }
230#ifdef HAVE_PCAP_SETNONBLOCK
231        pcap_setnonblock(INPUT.pcap,0,errbuf);
232#endif
233        return 0; /* success */
234}
235
236static int pcap_pause_input(libtrace_t *libtrace)
237{
238        pcap_close(INPUT.pcap);
239        INPUT.pcap=NULL;
240        return 0; /* success */
241}
242
243
244static int pcap_fin_input(libtrace_t *libtrace) 
245{
246        free(libtrace->format_data);
247        return 0; /* success */
248}
249
250static int pcap_fin_output(libtrace_out_t *libtrace) 
251{
252        if (OUTPUT.trace.dump) {
253                pcap_dump_flush(OUTPUT.trace.dump);
254                pcap_dump_close(OUTPUT.trace.dump);
255        }
256        pcap_close(OUTPUT.trace.pcap);
257        free(libtrace->format_data);
258        return 0;
259}
260
261static int pcapint_fin_output(libtrace_out_t *libtrace)
262{
263        pcap_close(OUTPUT.trace.pcap);
264        free(libtrace->format_data);
265        return 0;
266}
267
268static int pcap_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
269                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
270       
271        if (packet->buffer != buffer &&
272                        packet->buf_control == TRACE_CTRL_PACKET) {
273                        free(packet->buffer);
274        }
275
276        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
277                packet->buf_control = TRACE_CTRL_PACKET;
278        } else
279                packet->buf_control = TRACE_CTRL_EXTERNAL;
280       
281       
282        packet->buffer = buffer;
283        packet->header = buffer;
284        packet->type = rt_type;
285
286        /* Assuming header and payload are sequential in the buffer -
287         * regular pcap often doesn't work like this though, so hopefully
288         * we're not called by something that is reading genuine pcap! */
289        packet->payload = (char *)packet->header + sizeof(struct pcap_pkthdr);
290
291        if (libtrace->format_data == NULL) {
292                if (pcap_init_input(libtrace))
293                        return -1;
294        }
295        return 0;
296}
297
298static int pcap_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
299        int ret = 0;
300        int linktype;
301        uint32_t flags = 0;
302       
303        assert(libtrace->format_data);
304        linktype = pcap_datalink(DATA(libtrace)->input.pcap);
305        packet->type = pcap_linktype_to_rt(linktype);
306
307        /* If we're using the replacement pcap_next_ex() we need to
308         * make sure we have a buffer to *shudder* memcpy into
309         */
310        if (!packet->buffer) {
311                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
312                if (!packet->buffer) {
313                        trace_set_err(libtrace, errno, 
314                                        "Cannot allocate memory");
315                        return -1;
316                }
317                packet->header = packet->buffer;
318                packet->payload = (char *)packet->buffer+sizeof(struct pcap_pkthdr);
319                       
320        }
321
322        flags |= TRACE_PREP_OWN_BUFFER;
323       
324        for(;;) {
325
326                ret=pcap_next_ex(INPUT.pcap, 
327                                (struct pcap_pkthdr **)&packet->header,
328                                (const u_char **)&packet->payload);
329
330                switch(ret) {
331                        case 1: break; /* no error */
332                        case 0: continue; /* timeout expired */
333                        case -1:
334                                trace_set_err(libtrace,TRACE_ERR_BAD_PACKET,
335                                                "%s",pcap_geterr(INPUT.pcap));
336                                return -1; /* Error */
337                        case -2:
338                                return 0; /* EOF */
339                }
340
341                /*
342                 * pcap is nasty in that the header and payload aren't
343                 * necessarily located sequentially in memory, but most
344                 * sensible uses of pcap_prepare_packet will involve a
345                 * buffer where header and payload are sequential.
346                 *
347                 * Basically, don't call pcap_prepare_packet here!
348                 *
349                if (pcap_prepare_packet(libtrace, packet, packet->buffer,
350                                packet->type, flags)) {
351                        return -1;
352                }
353                */
354                return ((struct pcap_pkthdr*)packet->header)->len
355                        +sizeof(struct pcap_pkthdr);
356        }
357}
358
359static int pcap_write_packet(libtrace_out_t *libtrace, 
360                libtrace_packet_t *packet) 
361{
362        struct pcap_pkthdr pcap_pkt_hdr;
363        void *link;
364        libtrace_linktype_t linktype;
365        uint32_t remaining;
366
367        link = trace_get_packet_buffer(packet,&linktype,&remaining);
368
369        /* If this packet cannot be converted to a pcap linktype then
370         * pop off the top header until it can be converted
371         */
372        while (libtrace_to_pcap_linktype(linktype)==~0U) {
373                if (!demote_packet(packet)) {
374                        trace_set_err_out(libtrace, 
375                                TRACE_ERR_NO_CONVERSION,
376                                "pcap does not support this format");
377                        return -1;
378                }
379
380                link = trace_get_packet_buffer(packet,&linktype,&remaining);
381        }
382
383
384        if (!OUTPUT.trace.pcap) {
385                int linktype=libtrace_to_pcap_dlt(trace_get_link_type(packet));
386                OUTPUT.trace.pcap = pcap_open_dead(linktype,65536);
387                if (!OUTPUT.trace.pcap) {
388                        trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,
389                                        "Failed to open dead trace: %s\n",
390                                        pcap_geterr(OUTPUT.trace.pcap));
391                }
392                OUTPUT.trace.dump = pcap_dump_open(OUTPUT.trace.pcap,
393                                libtrace->uridata);
394                if (!OUTPUT.trace.dump) {
395                        char *errmsg = pcap_geterr(OUTPUT.trace.pcap);
396                        trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,"Failed to open output file: %s\n",
397                                        errmsg ? errmsg : "Unknown error");
398                        return -1;
399                }
400        }
401
402        /* Corrupt packet, or other "non data" packet, so skip it */
403        if (link == NULL) {
404                /* Return "success", but nothing written */
405                return 0;
406        }
407
408        if (packet->trace->format == &pcap || 
409                        packet->trace->format == &pcapint) {
410                pcap_dump((u_char*)OUTPUT.trace.dump,
411                                (struct pcap_pkthdr *)packet->header,
412                                packet->payload);
413        } else {
414                /* Leave the manual copy as it is, as it gets around
415                 * some OS's having different structures in pcap_pkt_hdr
416                 */
417                struct timeval ts = trace_get_timeval(packet);
418                pcap_pkt_hdr.ts.tv_sec = ts.tv_sec;
419                pcap_pkt_hdr.ts.tv_usec = ts.tv_usec;
420                pcap_pkt_hdr.caplen = remaining;
421                /* trace_get_wire_length includes FCS, while pcap doesn't */
422                if (trace_get_link_type(packet)==TRACE_TYPE_ETH)
423                        if (trace_get_wire_length(packet) >= 4) { 
424                                pcap_pkt_hdr.len = 
425                                        trace_get_wire_length(packet)-4;
426                        }
427                        else {
428                                pcap_pkt_hdr.len = 0;
429                        }
430                else
431                        pcap_pkt_hdr.len = trace_get_wire_length(packet);
432
433                assert(pcap_pkt_hdr.caplen<65536);
434                assert(pcap_pkt_hdr.len<65536);
435
436                pcap_dump((u_char*)OUTPUT.trace.dump, &pcap_pkt_hdr, packet->payload);
437        }
438        return 0;
439}
440
441static int pcapint_write_packet(libtrace_out_t *libtrace,
442                libtrace_packet_t *packet) 
443{
444        int err;
445
446        if (!OUTPUT.trace.pcap) {
447                OUTPUT.trace.pcap = (pcap_t *)pcap_open_live(
448                        libtrace->uridata,65536,0,0,NULL);
449        }
450#ifdef HAVE_PCAP_INJECT
451        err=pcap_inject(OUTPUT.trace.pcap,
452                        packet->payload,
453                        trace_get_capture_length(packet));
454        if (err!=(int)trace_get_capture_length(packet))
455                err=-1;
456#else
457#ifdef HAVE_PCAP_SENDPACKET
458        err=pcap_sendpacket(OUTPUT.trace.pcap,
459                        packet->payload,
460                        trace_get_capture_length(packet));
461#else
462    trace_set_err(packet->trace,TRACE_ERR_UNSUPPORTED,"writing is not supported on this platform");
463        return -1;
464#endif
465#endif
466        return err;
467}
468
469static libtrace_linktype_t pcap_get_link_type(const libtrace_packet_t *packet) {
470        /* pcap doesn't store linktype in the framing header so we need
471         * rt to do it for us
472         */
473        int linktype = rt_to_pcap_linktype(packet->type);
474        return pcap_linktype_to_libtrace(linktype);
475}
476
477static libtrace_direction_t pcap_set_direction(libtrace_packet_t *packet,
478                libtrace_direction_t dir) {
479        libtrace_sll_header_t *sll;
480        promote_packet(packet);
481        sll=packet->payload;
482        /* sll->pkttype should be in the endianness of the host that the
483         * trace was taken on.  this is impossible to achieve
484         * so we assume host endianness
485         */
486        if(dir==TRACE_DIR_OUTGOING)
487                sll->pkttype=TRACE_SLL_OUTGOING;
488        else
489                sll->pkttype=TRACE_SLL_HOST;
490        return dir;
491}
492
493static libtrace_direction_t pcap_get_direction(const libtrace_packet_t *packet) {
494        libtrace_direction_t direction  = -1;
495        switch(pcap_get_link_type(packet)) {
496                case TRACE_TYPE_LINUX_SLL:
497                {
498                        libtrace_sll_header_t *sll;
499                        sll = trace_get_packet_buffer(packet, NULL, NULL);
500                        /* TODO: should check remaining>=sizeof(*sll) */
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 (sll->pkttype == TRACE_SLL_OUTGOING) {
519                                direction = TRACE_DIR_OUTGOING;
520                        } else {
521                                direction = TRACE_DIR_INCOMING;
522                        }
523                        break;
524
525                }
526                case TRACE_TYPE_PFLOG:
527                {
528                        libtrace_pflog_header_t *pflog;
529                        pflog = trace_get_packet_buffer(packet, NULL, NULL);
530                        /* TODO: should check remaining >= sizeof(*pflog) */
531                        if (!pflog) {
532                                trace_set_err(packet->trace,
533                                                TRACE_ERR_BAD_PACKET,
534                                                "Bad or missing packet");
535                                return -1;
536                        }
537                        /* enum    { PF_IN=0, PF_OUT=1 }; */
538                        if (ntohs(pflog->dir==0)) {
539
540                                direction = TRACE_DIR_INCOMING;
541                        }
542                        else {
543                                direction = TRACE_DIR_OUTGOING;
544                        }
545                        break;
546                }
547                default:
548                        break;
549        }       
550        return direction;
551}
552
553
554static struct timeval pcap_get_timeval(const libtrace_packet_t *packet) {
555        struct pcap_pkthdr *pcapptr = (struct pcap_pkthdr *)packet->header;
556        struct timeval ts;
557        ts.tv_sec = pcapptr->ts.tv_sec;
558        ts.tv_usec = pcapptr->ts.tv_usec;
559        return ts;
560}
561
562
563static int pcap_get_capture_length(const libtrace_packet_t *packet) {
564        struct pcap_pkthdr *pcapptr = 0;
565        pcapptr = (struct pcap_pkthdr *)packet->header;
566        assert(pcapptr->caplen<=65536);
567
568        return pcapptr->caplen;
569}
570
571static int pcap_get_wire_length(const libtrace_packet_t *packet) {
572        struct pcap_pkthdr *pcapptr = 0;
573        pcapptr = (struct pcap_pkthdr *)packet->header;
574        if (packet->type==pcap_linktype_to_rt(TRACE_DLT_EN10MB))
575                return pcapptr->len+4; /* Include the missing FCS */
576        else if (packet->type==pcap_linktype_to_rt(TRACE_DLT_IEEE802_11_RADIO)) {
577                libtrace_linktype_t linktype;
578                void *link = trace_get_packet_buffer(packet,&linktype,NULL);
579                /* If the packet is Radiotap and the flags field indicates
580                 * that the FCS is not included in the 802.11 frame, then
581                 * we need to add 4 to the wire-length to account for it.
582                 */
583                uint8_t flags;
584                trace_get_wireless_flags(link, 
585                                linktype, &flags);
586                if ((flags & TRACE_RADIOTAP_F_FCS) == 0)
587                        return pcapptr->len + 4;
588        }
589        return pcapptr->len;
590}
591
592static int pcap_get_framing_length(UNUSED const libtrace_packet_t *packet) {
593        return sizeof(struct pcap_pkthdr);
594}
595
596static size_t pcap_set_capture_length(libtrace_packet_t *packet,size_t size) {
597        struct pcap_pkthdr *pcapptr = 0;
598        assert(packet);
599        if (size > trace_get_capture_length(packet)) {
600                /* can't make a packet larger */
601                return trace_get_capture_length(packet);
602        }
603        /* Reset the cached capture length */
604        packet->capture_length = -1;
605        pcapptr = (struct pcap_pkthdr *)packet->header;
606        pcapptr->caplen = size;
607        return trace_get_capture_length(packet);
608}
609
610static int pcap_get_fd(const libtrace_t *trace) {
611
612        assert(trace->format_data);
613        return pcap_fileno(DATA(trace)->input.pcap);
614}
615
616static uint64_t pcap_get_dropped_packets(libtrace_t *trace)
617{
618        struct pcap_stat stats;
619        if (pcap_stats(DATA(trace)->input.pcap,&stats)==-1) {
620                char *errmsg = pcap_geterr(DATA(trace)->input.pcap);
621                trace_set_err(trace,TRACE_ERR_UNSUPPORTED,
622                                "Failed to retreive stats: %s\n",
623                                errmsg ? errmsg : "Unknown pcap error");
624                return ~0;
625        }
626
627        return stats.ps_drop;
628}
629
630static void pcap_help(void) {
631        printf("pcap format module: $Revision$\n");
632        printf("Supported input URIs:\n");
633        printf("\tpcap:/path/to/file\n");
634        printf("\n");
635        printf("\te.g.: pcap:/tmp/trace.pcap\n");
636        printf("\n");
637        printf("Supported output URIs:\n");
638        printf("\tnone\n");
639        printf("\n");
640}
641
642static void pcapint_help(void) {
643        printf("pcapint format module: $Revision$\n");
644        printf("Supported input URIs:\n");
645        printf("\tpcapint:interface\n");
646        printf("\n");
647        printf("\te.g.: pcapint:eth0\n");
648        printf("\n");
649        printf("Supported output URIs:\n");
650        printf("\tnone\n");
651        printf("\n");
652}
653
654
655static struct libtrace_format_t pcap = {
656        "pcap",
657        "$Id$",
658        TRACE_FORMAT_PCAP,
659        pcap_init_input,                /* init_input */
660        pcap_config_input,              /* config_input */
661        pcap_start_input,               /* start_input */
662        NULL,                           /* pause_input */
663        pcap_init_output,               /* init_output */
664        NULL,                           /* config_output */
665        NULL,                           /* start_output */
666        pcap_fin_input,                 /* fin_input */
667        pcap_fin_output,                /* fin_output */
668        pcap_read_packet,               /* read_packet */
669        pcap_prepare_packet,            /* prepare_packet */
670        NULL,                           /* fin_packet */
671        pcap_write_packet,              /* write_packet */
672        pcap_get_link_type,             /* get_link_type */
673        pcap_get_direction,             /* get_direction */
674        pcap_set_direction,             /* set_direction */
675        NULL,                           /* get_erf_timestamp */
676        pcap_get_timeval,               /* get_timeval */
677        NULL,                           /* get_seconds */
678        NULL,                           /* seek_erf */
679        NULL,                           /* seek_timeval */
680        NULL,                           /* seek_seconds */
681        pcap_get_capture_length,        /* get_capture_length */
682        pcap_get_wire_length,           /* get_wire_length */
683        pcap_get_framing_length,        /* get_framing_length */
684        pcap_set_capture_length,        /* set_capture_length */
685        NULL,                           /* get_received_packets */
686        NULL,                           /* get_filtered_packets */
687        NULL,                           /* get_dropped_packets */
688        NULL,                           /* get_captured_packets */
689        NULL,                           /* get_fd */
690        trace_event_trace,              /* trace_event */
691        pcap_help,                      /* help */
692        NULL                            /* next pointer */
693};
694
695static struct libtrace_format_t pcapint = {
696        "pcapint",
697        "$Id$",
698        TRACE_FORMAT_PCAP,
699        pcapint_init_input,             /* init_input */
700        pcapint_config_input,           /* config_input */
701        pcapint_start_input,            /* start_input */
702        pcap_pause_input,               /* pause_input */
703        pcapint_init_output,            /* init_output */
704        NULL,                           /* config_output */
705        NULL,                           /* start_output */
706        pcap_fin_input,                 /* fin_input */
707        pcapint_fin_output,             /* fin_output */
708        pcap_read_packet,               /* read_packet */
709        pcap_prepare_packet,            /* prepare_packet */
710        NULL,                           /* fin_packet */
711        pcapint_write_packet,           /* write_packet */
712        pcap_get_link_type,             /* get_link_type */
713        pcap_get_direction,             /* get_direction */
714        pcap_set_direction,             /* set_direction */
715        NULL,                           /* get_erf_timestamp */
716        pcap_get_timeval,               /* get_timeval */
717        NULL,                           /* get_seconds */
718        NULL,                           /* seek_erf */
719        NULL,                           /* seek_timeval */
720        NULL,                           /* seek_seconds */
721        pcap_get_capture_length,        /* get_capture_length */
722        pcap_get_wire_length,           /* get_wire_length */
723        pcap_get_framing_length,        /* get_framing_length */
724        pcap_set_capture_length,        /* set_capture_length */
725        NULL,                           /* get_received_packets */
726        NULL,                           /* get_filtered_packets */
727        pcap_get_dropped_packets,       /* get_dropped_packets */
728        NULL,                           /* get_captured_packets */
729        pcap_get_fd,                    /* get_fd */
730        trace_event_device,             /* trace_event */
731        pcapint_help,                   /* help */
732        NULL                            /* next pointer */
733};
734
735void pcap_constructor(void) {
736        register_format(&pcap);
737        register_format(&pcapint);
738}
739
740
741#endif
Note: See TracBrowser for help on using the repository browser.