source: lib/format_linux.c @ 91b72d3

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

Try to autoguess the tracetype if the format uri specify is not present

  • Property mode set to 100644
File size: 18.3 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 "libtrace.h"
32#include "libtrace_int.h"
33#include "format_helper.h"
34#include "config.h"
35#include <stdlib.h>
36
37#ifdef HAVE_INTTYPES_H
38#  include <inttypes.h>
39#else
40# error "Can't find inttypes.h"
41#endif
42
43#include <sys/socket.h>
44#include <netpacket/packet.h>
45#include <net/ethernet.h>
46#include <net/if_arp.h>
47
48#include <string.h>
49#include <net/if.h>
50#include <sys/ioctl.h>
51#include <errno.h>
52#include <unistd.h>
53
54#include <assert.h>
55
56/* Declared in linux/if_arp.h but not in net/if_arp.h sigh */
57#ifndef ARPHRD_NONE
58#define ARPHRD_NONE 0xfffe
59#endif
60
61struct tpacket_stats {
62        unsigned int tp_packets;
63        unsigned int tp_drops;
64};
65
66struct libtrace_format_data_t {
67        int fd;
68        int snaplen;
69        int promisc;
70        libtrace_filter_t *filter;
71        struct tpacket_stats stats;
72        int stats_valid;
73};
74
75struct libtrace_linuxnative_header {
76        struct timeval ts;
77        int wirelen;
78        int caplen;
79        struct sockaddr_ll hdr;
80};
81
82struct libtrace_linuxnative_format_data_t {
83        int fd;
84};
85
86#define FORMAT(x) ((struct libtrace_format_data_t*)(x))
87#define DATAOUT(x) ((struct libtrace_linuxnative_format_data_t*)((x)->format_data))
88
89static int linuxnative_probe_filename(const char *filename)
90{
91        int sock;
92
93        /* Is this an interface? */
94        return (if_nametoindex(filename) != 0);
95}
96
97static int linuxnative_init_input(libtrace_t *libtrace) 
98{
99        libtrace->format_data = (struct libtrace_format_data_t *)
100                malloc(sizeof(struct libtrace_format_data_t));
101        FORMAT(libtrace->format_data)->fd = -1;
102        FORMAT(libtrace->format_data)->promisc = -1;
103        FORMAT(libtrace->format_data)->snaplen = LIBTRACE_PACKET_BUFSIZE;
104        FORMAT(libtrace->format_data)->filter = NULL;
105        FORMAT(libtrace->format_data)->stats_valid = 0;
106
107        return 0;
108}
109
110static int linuxnative_init_output(libtrace_out_t *libtrace)
111{
112        libtrace->format_data = (struct libtrace_linuxnative_format_data_t*)
113                malloc(sizeof(struct libtrace_linuxnative_format_data_t));
114        DATAOUT(libtrace)->fd = -1;
115
116        return 0;
117}
118
119static int linuxnative_start_input(libtrace_t *libtrace)
120{
121        struct sockaddr_ll addr;
122        int one = 1;
123        memset(&addr,0,sizeof(addr));
124        libtrace_filter_t *filter = FORMAT(libtrace->format_data)->filter;
125        FORMAT(libtrace->format_data)->fd = 
126                                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
127        if (FORMAT(libtrace->format_data)->fd==-1) {
128                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Could not create raw socket");
129                free(libtrace->format_data);
130                return -1;
131        }
132        addr.sll_family = AF_PACKET;
133        addr.sll_protocol = htons(ETH_P_ALL);
134        if (strlen(libtrace->uridata)) {
135                addr.sll_ifindex = if_nametoindex(libtrace->uridata);
136                if (addr.sll_ifindex == 0) {
137                        close(FORMAT(libtrace->format_data)->fd);
138                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Failed to find interface %s", libtrace->uridata);
139                        free(libtrace->format_data);
140                        return -1;
141                }
142        }
143        else {
144                addr.sll_ifindex = 0;
145        }
146        if (bind(FORMAT(libtrace->format_data)->fd,
147                                (struct sockaddr*)&addr,
148                                (socklen_t)sizeof(addr))==-1) {
149                free(libtrace->format_data);
150                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Failed to bind to interface %s", libtrace->uridata);
151                return -1;
152        }
153
154        /* If promisc hasn't been specified, set it to "true" if we're
155         * capturing on one interface, or "false" if we're capturing on
156         * all interfaces.
157         */ 
158        if (FORMAT(libtrace->format_data)->promisc==-1) {
159                if (addr.sll_ifindex!=0)
160                        FORMAT(libtrace->format_data)->promisc=1;
161                else
162                        FORMAT(libtrace->format_data)->promisc=0;
163        }
164                               
165        if (FORMAT(libtrace->format_data)->promisc) {
166                struct packet_mreq mreq;
167                socklen_t socklen = sizeof(mreq);
168                memset(&mreq,0,sizeof(mreq));
169                mreq.mr_ifindex = addr.sll_ifindex;
170                mreq.mr_type = PACKET_MR_PROMISC;
171                if (setsockopt(FORMAT(libtrace->format_data)->fd,
172                                SOL_PACKET,
173                                PACKET_ADD_MEMBERSHIP,
174                                &mreq,
175                                socklen)==-1) {
176                        perror("setsockopt(PROMISC)");
177                }
178        }
179
180        if (setsockopt(FORMAT(libtrace->format_data)->fd,
181                        SOL_SOCKET,
182                        SO_TIMESTAMP,
183                        &one,
184                        (socklen_t)sizeof(one))==-1) {
185                perror("setsockopt(SO_TIMESTAMP)");
186        }
187
188        /* Push BPF filter into the kernel. At this stage we can safely assume
189         * that the filterstring has been compiled, or the filter was supplied
190         * pre-compiled.
191         */
192        if (filter != NULL) {
193                assert(filter->flag == 1);
194                if (setsockopt(FORMAT(libtrace->format_data)->fd,
195                                        SOL_SOCKET,
196                                        SO_ATTACH_FILTER,
197                                        &filter->filter,
198                                        sizeof(filter->filter)) == -1) {
199                        perror("setsockopt(SO_ATTACH_FILTER)");
200                } else { 
201                        /* The socket accepted the filter, so we need to
202                         * consume any buffered packets that were received
203                         * between opening the socket and applying the filter.
204                         */
205                        void *buf = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
206                        while(recv(FORMAT(libtrace->format_data)->fd,
207                                        buf,
208                                        (size_t) LIBTRACE_PACKET_BUFSIZE,
209                                        MSG_DONTWAIT) != -1) { }
210                        free(buf);
211                }
212        }
213
214        FORMAT(libtrace->format_data)->stats_valid=0;
215                                       
216        return 0;
217}
218
219static int linuxnative_start_output(libtrace_out_t *libtrace)
220{
221        FORMAT(libtrace->format_data)->fd = 
222                                socket(PF_PACKET, SOCK_RAW, 0);
223        if (FORMAT(libtrace->format_data)->fd==-1) {
224                free(libtrace->format_data);
225                return -1;
226        }
227        FORMAT(libtrace->format_data)->stats_valid=0;
228
229        return 0;
230}
231
232static int linuxnative_pause_input(libtrace_t *libtrace)
233{
234        close(FORMAT(libtrace->format_data)->fd);
235        FORMAT(libtrace->format_data)->fd=-1;
236
237        return 0;
238}
239
240static int linuxnative_fin_input(libtrace_t *libtrace) 
241{
242        if (FORMAT(libtrace->format_data)->filter != NULL)
243                free(FORMAT(libtrace->format_data)->filter);
244        free(libtrace->format_data);
245       
246        return 0;
247}
248
249static int linuxnative_fin_output(libtrace_out_t *libtrace)
250{
251        close(DATAOUT(libtrace)->fd);
252        DATAOUT(libtrace)->fd=-1;
253        free(libtrace->format_data);
254        return 0;
255}
256
257static int linuxnative_configure_bpf(libtrace_t *libtrace, 
258                libtrace_filter_t *filter) {
259#ifdef HAVE_LIBPCAP
260        struct ifreq ifr;
261        unsigned int arphrd;
262        libtrace_dlt_t dlt;
263        libtrace_filter_t *f;
264        int sock;
265        pcap_t *pcap;
266
267        /* Take a copy of the filter object as it was passed in */
268        f = (libtrace_filter_t *) malloc(sizeof(libtrace_filter_t));
269        memcpy(f, filter, sizeof(libtrace_filter_t));
270       
271        /* If we are passed a filter with "flag" set to zero, then we must
272         * compile the filterstring before continuing. This involves
273         * determining the linktype, passing the filterstring to libpcap to
274         * compile, and saving the result for trace_start() to push into the
275         * kernel.
276         * If flag is set to one, then the filter was probably generated using
277         * trace_create_filter_from_bytecode() and so we don't need to do
278         * anything (we've just copied it above).
279         */
280        if (f->flag == 0) {
281                sock = socket(PF_INET, SOCK_STREAM, 0);
282                memset(&ifr, 0, sizeof(struct ifreq));
283                strncpy(ifr.ifr_name, libtrace->uridata, IF_NAMESIZE);
284                if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {
285                        perror("Can't get HWADDR for interface");
286                        return -1;
287                }
288                close(sock);
289
290                arphrd = ifr.ifr_hwaddr.sa_family;
291                dlt = libtrace_to_pcap_dlt(arphrd_type_to_libtrace(arphrd));
292
293                pcap = pcap_open_dead(dlt, 
294                                FORMAT(libtrace->format_data)->snaplen);
295
296                if (pcap_compile(pcap, &f->filter, f->filterstring, 0, 0) == -1) {
297                        perror("PCAP failed to compile the filterstring");
298                        return -1;
299                }
300
301                pcap_close(pcap);
302               
303                /* Set the "flag" to indicate that the filterstring has been
304                 * compiled
305                 */
306                f->flag = 1;
307        }
308       
309        if (FORMAT(libtrace->format_data)->filter != NULL)
310                free(FORMAT(libtrace->format_data)->filter);
311       
312        FORMAT(libtrace->format_data)->filter = f;
313       
314        return 0;
315#else
316        return -1
317#endif
318}
319static int linuxnative_config_input(libtrace_t *libtrace,
320                trace_option_t option,
321                void *data)
322{
323        switch(option) {
324                case TRACE_OPTION_SNAPLEN:
325                        FORMAT(libtrace->format_data)->snaplen=*(int*)data;
326                        return 0;
327                case TRACE_OPTION_PROMISC:
328                        FORMAT(libtrace->format_data)->promisc=*(int*)data;
329                        return 0;
330                case TRACE_OPTION_FILTER:
331                        return linuxnative_configure_bpf(libtrace, 
332                                        (libtrace_filter_t *) data);
333                case TRACE_OPTION_META_FREQ:
334                        /* No meta-data for this format */
335                        break;
336                case TRACE_OPTION_EVENT_REALTIME:
337                        break;
338                /* Avoid default: so that future options will cause a warning
339                 * here to remind us to implement it, or flag it as
340                 * unimplementable
341                 */
342        }
343       
344        /* Don't set an error - trace_config will try to deal with the
345         * option and will set an error if it fails */
346        return -1;
347}
348
349static int linuxnative_prepare_packet(libtrace_t *libtrace, 
350                libtrace_packet_t *packet, void *buffer, 
351                libtrace_rt_types_t rt_type, uint32_t flags) {
352
353        if (packet->buffer != buffer &&
354                        packet->buf_control == TRACE_CTRL_PACKET) {
355                free(packet->buffer);
356        }
357
358        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
359                packet->buf_control = TRACE_CTRL_PACKET;
360        } else
361                packet->buf_control = TRACE_CTRL_EXTERNAL;
362
363
364        packet->buffer = buffer;
365        packet->header = buffer;
366        packet->payload = (char *)buffer + 
367                sizeof(struct libtrace_linuxnative_header);
368        packet->type = rt_type;
369
370        if (libtrace->format_data == NULL) {
371                if (linuxnative_init_input(libtrace))
372                        return -1;
373        }
374        return 0;
375       
376}
377
378#define LIBTRACE_MIN(a,b) ((a)<(b) ? (a) : (b))
379
380/* 20 isn't enough on x86_64 */
381#define CMSG_BUF_SIZE 128
382static int linuxnative_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) 
383{
384        struct libtrace_linuxnative_header *hdr;
385        struct msghdr msghdr;
386        struct iovec iovec;
387        unsigned char controlbuf[CMSG_BUF_SIZE];
388        struct cmsghdr *cmsg;
389        socklen_t socklen;
390        int snaplen;
391        uint32_t flags = 0;
392       
393        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
394                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
395                if (!packet->buffer) {
396                        perror("Cannot allocate buffer");
397                }
398        }
399
400        flags |= TRACE_PREP_OWN_BUFFER;
401       
402        packet->type = TRACE_RT_DATA_LINUX_NATIVE;
403
404        hdr=(struct libtrace_linuxnative_header*)packet->buffer;
405        socklen=sizeof(hdr->hdr);
406        snaplen=LIBTRACE_MIN(
407                        (int)LIBTRACE_PACKET_BUFSIZE-(int)sizeof(*hdr),
408                        (int)FORMAT(libtrace->format_data)->snaplen);
409
410        msghdr.msg_name = &hdr->hdr;
411        msghdr.msg_namelen = sizeof(struct sockaddr_ll);
412
413        msghdr.msg_iov = &iovec;
414        msghdr.msg_iovlen = 1;
415
416        msghdr.msg_control = &controlbuf;
417        msghdr.msg_controllen = CMSG_BUF_SIZE;
418        msghdr.msg_flags = 0;
419
420        iovec.iov_base = (void*)(packet->buffer+sizeof(*hdr));
421        iovec.iov_len = snaplen;
422
423        hdr->wirelen = recvmsg(FORMAT(libtrace->format_data)->fd, &msghdr, 0);
424
425        if (hdr->wirelen==-1) {
426                trace_set_err(libtrace,errno,"recvmsg");
427                return -1;
428        }
429
430        hdr->caplen=LIBTRACE_MIN(snaplen,hdr->wirelen);
431
432        for (cmsg = CMSG_FIRSTHDR(&msghdr);
433                        cmsg != NULL;
434                        cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
435                if (cmsg->cmsg_level == SOL_SOCKET
436                        && cmsg->cmsg_type == SO_TIMESTAMP
437                        && cmsg->cmsg_len <= CMSG_LEN(sizeof(struct timeval))) {
438                        memcpy(&hdr->ts, CMSG_DATA(cmsg),
439                                        sizeof(struct timeval));
440                        break;
441                }
442        }
443
444        if (cmsg == NULL && ioctl(FORMAT(libtrace->format_data)->fd,
445                                SIOCGSTAMP,&hdr->ts)==-1)
446                perror("ioctl(SIOCGSTAMP)");
447
448        if (linuxnative_prepare_packet(libtrace, packet, packet->buffer,
449                                packet->type, flags))
450                return -1;
451       
452        return hdr->wirelen+sizeof(*hdr);
453}
454
455static int linuxnative_write_packet(libtrace_out_t *trace, 
456                libtrace_packet_t *packet) 
457{
458        struct sockaddr_ll hdr;
459
460        hdr.sll_family = AF_PACKET;
461        hdr.sll_protocol = 0;
462        hdr.sll_ifindex = if_nametoindex(trace->uridata);
463        hdr.sll_hatype = 0;
464        hdr.sll_pkttype = 0;
465        hdr.sll_halen = htons(6); /* FIXME */
466        memcpy(hdr.sll_addr,packet->payload,(size_t)hdr.sll_halen);
467
468        return sendto(DATAOUT(trace)->fd,
469                        packet->payload,
470                        trace_get_capture_length(packet),
471                        0,
472                        (struct sockaddr*)&hdr, (socklen_t)sizeof(hdr));
473
474}
475
476static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
477        int linktype=(((struct libtrace_linuxnative_header*)(packet->buffer))
478                                ->hdr.sll_hatype);
479        switch (linktype) {
480                case ARPHRD_ETHER:
481                        return TRACE_TYPE_ETH;
482                case ARPHRD_PPP:
483                        return TRACE_TYPE_NONE;
484                case ARPHRD_80211_RADIOTAP:
485                        return TRACE_TYPE_80211_RADIO;
486                case ARPHRD_IEEE80211:
487                        return TRACE_TYPE_80211;
488                case ARPHRD_SIT:
489                case ARPHRD_NONE:
490                        return TRACE_TYPE_NONE;
491                default: /* shrug, beyond me! */
492                        printf("unknown Linux ARPHRD type 0x%04x\n",linktype);
493                        return (libtrace_linktype_t)~0U;
494        }
495}
496
497static libtrace_direction_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
498        switch (((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype) {
499                case PACKET_OUTGOING:
500                case PACKET_LOOPBACK:
501                        return TRACE_DIR_OUTGOING;
502                default:
503                        return TRACE_DIR_INCOMING;
504        }
505}
506
507static libtrace_direction_t linuxnative_set_direction(
508                libtrace_packet_t *packet,
509                libtrace_direction_t direction) {
510
511        switch (direction) {
512                case TRACE_DIR_OUTGOING:
513                        ((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype = PACKET_OUTGOING;
514                        return TRACE_DIR_OUTGOING;
515                case TRACE_DIR_INCOMING:
516                        ((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype = PACKET_HOST;
517                        return TRACE_DIR_INCOMING;
518                default:
519                        return -1;
520        }
521}
522
523static struct timeval linuxnative_get_timeval(const libtrace_packet_t *packet) 
524{
525        return ((struct libtrace_linuxnative_header*)(packet->buffer))->ts;
526}
527
528static int linuxnative_get_capture_length(const libtrace_packet_t *packet)
529{
530        return ((struct libtrace_linuxnative_header*)(packet->buffer))->caplen;
531}
532
533static int linuxnative_get_wire_length(const libtrace_packet_t *packet) 
534{
535        return ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
536}
537
538static int linuxnative_get_framing_length(UNUSED
539                const libtrace_packet_t *packet) 
540{
541        return sizeof(struct libtrace_linuxnative_header);
542}
543
544static int linuxnative_get_fd(const libtrace_t *trace) {
545        if (trace->format_data == NULL)
546                return -1;
547        return FORMAT(trace->format_data)->fd;
548}
549
550/* Linux doesn't keep track how many packets were seen before filtering
551 * so we can't tell how many packets were filtered.  Bugger.  So annoying.
552 *
553 * Since we tell libtrace that we do support filtering, if we don't declare
554 * this here as failing, libtrace will happily report for us that it didn't
555 * filter any packets, so don't lie -- return that we don't know.
556 */
557static uint64_t linuxnative_get_filtered_packets(libtrace_t *trace) {
558        return UINT64_MAX;
559}
560
561/* Number of packets that past filtering */
562static uint64_t linuxnative_get_captured_packets(libtrace_t *trace) {
563        if (trace->format_data == NULL)
564                return UINT64_MAX;
565        if (FORMAT(trace->format_data)->fd == -1) {
566                /* This is probably a 'dead' trace so obviously we can't query
567                 * the socket for capture counts, can we? */
568                return UINT64_MAX;
569        }
570       
571        if ((FORMAT(trace->format_data)->stats_valid & 1) 
572                        || FORMAT(trace->format_data)->stats_valid == 0) {
573                socklen_t len = sizeof(FORMAT(trace->format_data)->stats);
574                getsockopt(FORMAT(trace->format_data)->fd, 
575                                SOL_PACKET,
576                                PACKET_STATISTICS,
577                                &FORMAT(trace->format_data)->stats,
578                                &len);
579                FORMAT(trace->format_data)->stats_valid |= 1;
580        }
581
582        return FORMAT(trace->format_data)->stats.tp_packets;
583}
584
585/* Number of packets that got past filtering and were then dropped because
586 * of lack of space
587 */
588static uint64_t linuxnative_get_dropped_packets(libtrace_t *trace) {
589        if (trace->format_data == NULL)
590                return UINT64_MAX;
591        if (FORMAT(trace->format_data)->fd == -1) {
592                /* This is probably a 'dead' trace so obviously we can't query
593                 * the socket for drop counts, can we? */
594                return UINT64_MAX;
595        }
596       
597        if ((FORMAT(trace->format_data)->stats_valid & 2)
598                        || (FORMAT(trace->format_data)->stats_valid==0)) {
599                socklen_t len = sizeof(FORMAT(trace->format_data)->stats);
600                getsockopt(FORMAT(trace->format_data)->fd, 
601                                SOL_PACKET,
602                                PACKET_STATISTICS,
603                                &FORMAT(trace->format_data)->stats,
604                                &len);
605                FORMAT(trace->format_data)->stats_valid |= 2;
606        }
607
608        return FORMAT(trace->format_data)->stats.tp_drops;
609}
610
611static void linuxnative_help(void) {
612        printf("linuxnative format module: $Revision$\n");
613        printf("Supported input URIs:\n");
614        printf("\tint:\n");
615        printf("\n");
616        printf("Supported output URIs:\n");
617        printf("\tnone\n");
618        printf("\n");
619        return;
620}
621static struct libtrace_format_t linuxnative = {
622        "int",
623        "$Id$",
624        TRACE_FORMAT_LINUX_NATIVE,
625        linuxnative_probe_filename,     /* probe filename */
626        NULL,                           /* probe magic */
627        linuxnative_init_input,         /* init_input */
628        linuxnative_config_input,       /* config_input */
629        linuxnative_start_input,        /* start_input */
630        linuxnative_pause_input,        /* pause_input */
631        linuxnative_init_output,        /* init_output */
632        NULL,                           /* config_output */
633        linuxnative_start_output,       /* start_ouput */
634        linuxnative_fin_input,          /* fin_input */
635        linuxnative_fin_output,         /* fin_output */
636        linuxnative_read_packet,        /* read_packet */
637        linuxnative_prepare_packet,     /* prepare_packet */
638        NULL,                           /* fin_packet */
639        linuxnative_write_packet,       /* write_packet */
640        linuxnative_get_link_type,      /* get_link_type */
641        linuxnative_get_direction,      /* get_direction */
642        linuxnative_set_direction,      /* set_direction */
643        NULL,                           /* get_erf_timestamp */
644        linuxnative_get_timeval,        /* get_timeval */
645        NULL,                           /* get_seconds */
646        NULL,                           /* seek_erf */
647        NULL,                           /* seek_timeval */
648        NULL,                           /* seek_seconds */
649        linuxnative_get_capture_length, /* get_capture_length */
650        linuxnative_get_wire_length,    /* get_wire_length */
651        linuxnative_get_framing_length, /* get_framing_length */
652        NULL,                           /* set_capture_length */
653        NULL,                           /* get_received_packets */
654        linuxnative_get_filtered_packets,/* get_filtered_packets */
655        linuxnative_get_dropped_packets,/* get_dropped_packets */
656        linuxnative_get_captured_packets,/* get_captured_packets */
657        linuxnative_get_fd,             /* get_fd */
658        trace_event_device,             /* trace_event */
659        linuxnative_help,               /* help */
660        NULL
661};
662
663void linuxnative_constructor(void) {
664        register_format(&linuxnative);
665}
Note: See TracBrowser for help on using the repository browser.