source: lib/format_bpf.c @ 259c314

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 259c314 was 259c314, checked in by Shane Alcock <salcock@…>, 6 years ago

Use correct "buffersize" in format_bpf.c

  • Property mode set to 100644
File size: 20.3 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 "libtrace.h"
35#include "libtrace_int.h"
36#include "format_helper.h"
37#include "config.h"
38#include "stdlib.h"
39
40#ifdef HAVE_INTTYPES_H
41#  include <inttypes.h>
42#else
43# error "Can't find inttypes.h"
44#endif
45
46#include <sys/socket.h>
47
48#include <sys/types.h>
49#include <sys/time.h>
50#include <sys/ioctl.h>
51
52#include <string.h>
53#include <net/if.h>
54#include <sys/ioctl.h>
55#include <errno.h>
56#include <fcntl.h>
57#include <unistd.h>
58
59/* This format deals with the BSD Native capture format, perhaps better
60 * known as BPF, which is the equivalent of the Linux Native format for
61 * *BSD systems.
62 *
63 * This is a LIVE capture format - we're always dealing with reading from an
64 * interface.
65 *
66 * This format does not support writing, but BPF packet records can be easily
67 * converted to PCAP or ERF.
68 */ 
69
70struct lt_bpf_timeval {
71        uint32_t tv_sec;
72        uint32_t tv_usec;
73};
74
75struct libtrace_bpf_hdr {
76        struct lt_bpf_timeval bh_tstamp;        /* timestamp */
77        uint32_t bh_caplen;             /* capture length */
78        uint32_t bh_datalen;            /* wire length */
79        uint16_t bh_hdrlen;             /* header length (incl padding) */
80};
81
82#ifndef BPF_TIMEVAL
83#define BPF_TIMEVAL timeval
84#endif
85
86struct local_bpf_hdr {
87        struct BPF_TIMEVAL bh_tstamp;
88        uint32_t bh_caplen;
89        uint32_t bh_datalen;
90        uint16_t bh_hdrlen;
91};
92
93#define BPFHDR(x) ((struct libtrace_bpf_hdr *)((x)->header))
94
95#if HAVE_DECL_BIOCSETIF
96/* "Global" data that is stored for each BPF input trace */
97struct libtrace_format_data_t {
98        /* The file descriptor that is being captured from */
99        int fd; 
100        /* The snap length for the capture */
101        int snaplen;
102        /* A boolean flag indicating whether the capture interface should be
103         * in promiscuous mode */ 
104        int promisc;
105        /* A buffer to write captured data into */
106        void *buffer;
107        /* The current read location in the capture buffer */
108        void *bufptr;
109        /* The total size of the capture buffer */
110        unsigned int buffersize;
111        /* The amount of space remaining before the capture buffer is full */
112        int remaining;
113        /* The linktype of the capture interface */ 
114        unsigned int linktype;
115        /* Statistics about how many packets have been dropped, received etc. */
116        struct bpf_stat stats;
117        /* A boolean flag indicating whether the statistics are up-to-date */
118        int stats_valid;
119        /* Bucket data structure for safely storing buffers of packets */
120        libtrace_bucket_t *bucket;
121};
122
123#define FORMATIN(x) ((struct libtrace_format_data_t*)((x->format_data)))
124
125
126/* Attempts to determine if a given filename could refer to a BPF interface */
127static int bpf_probe_filename(const char *filename)
128{
129        return (if_nametoindex(filename) != 0);
130}
131
132/* Initialises a BPF input trace */
133static int bpf_init_input(libtrace_t *libtrace) 
134{
135        libtrace->format_data = (struct libtrace_format_data_t *)
136                malloc(sizeof(struct libtrace_format_data_t));
137       
138        /* Throw some default values into the format data */
139        FORMATIN(libtrace)->fd = -1;
140        FORMATIN(libtrace)->promisc = 0;
141        FORMATIN(libtrace)->snaplen = 65536;
142        FORMATIN(libtrace)->stats_valid = 0;
143        FORMATIN(libtrace)->bucket = libtrace_bucket_init();
144
145        return 0;
146}
147
148/* Starts a BPF input trace */
149static int bpf_start_input(libtrace_t *libtrace)
150{
151        int bpfid=0;
152        struct bpf_version bv;
153        struct ifreq ifr;
154        unsigned int v;
155
156        /* Find and open a bpf device */
157        do {
158                char buffer[64];
159                snprintf(buffer,sizeof(buffer),"/dev/bpf%d", bpfid);
160                bpfid++;
161               
162                FORMATIN(libtrace)->fd = open(buffer, O_RDONLY);
163        } while(FORMATIN(libtrace)->fd == -1 && errno == EBUSY);
164
165        if (FORMATIN(libtrace)->fd == -1) {
166                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
167                                "No free bpf devices");
168                return -1;
169        }
170
171        /* Check the BPF Version is ok */
172        if (ioctl(FORMATIN(libtrace)->fd, BIOCVERSION, &bv) == -1) {
173                trace_set_err(libtrace,errno,
174                                "Failed to read the bpf version");
175                close(FORMATIN(libtrace)->fd);
176                return -1;
177        }
178
179        if (bv.bv_major != BPF_MAJOR_VERSION) {
180                trace_set_err(libtrace,errno, 
181                        "Unknown kernel BPF version (%d.%d, libtrace requires at least %d.%d)",
182                        bv.bv_major,
183                        bv.bv_minor,
184                        BPF_MAJOR_VERSION,
185                        BPF_MINOR_VERSION);
186                close(FORMATIN(libtrace)->fd);
187                return -1;
188        }
189
190        if (bv.bv_minor < BPF_MINOR_VERSION) {
191                trace_set_err(libtrace,errno, "Kernel version too old (%d.%d, libtrace requires at least %d.%d)",
192                        bv.bv_major,
193                        bv.bv_minor,
194                        BPF_MAJOR_VERSION,
195                        BPF_MINOR_VERSION);
196                close(FORMATIN(libtrace)->fd);
197                return -1;
198        }
199
200        /* We assume the default kernel buffer size is sufficient. */
201        if (ioctl(FORMATIN(libtrace)->fd, BIOCGBLEN,
202                        &FORMATIN(libtrace)->buffersize)==-1) {
203                trace_set_err(libtrace,errno,"Failed to find buffer length");
204                close(FORMATIN(libtrace)->fd);
205                return -1;
206        }
207
208        FORMATIN(libtrace)->buffer = NULL;
209        FORMATIN(libtrace)->bufptr = NULL;
210        FORMATIN(libtrace)->remaining = 0;
211
212        /* Attach to the device */
213        strncpy(ifr.ifr_name, libtrace->uridata, sizeof(ifr.ifr_name));
214        if (ioctl(FORMATIN(libtrace)->fd, BIOCSETIF, &ifr) == -1) {
215                trace_set_err(libtrace,errno,"Failed to attach");
216                close(FORMATIN(libtrace)->fd);
217                return -1;
218        }
219
220        /* Set the link type */
221        if (ioctl(FORMATIN(libtrace)->fd, BIOCGDLT,
222                         &FORMATIN(libtrace)->linktype) == -1) {
223                trace_set_err(libtrace,errno,"Failed to retrieve link type");
224                close(FORMATIN(libtrace)->fd);
225                return -1;
226        }
227       
228        /* TODO: If BIOCGDLTLIST exists then we should perhaps do something
229         *       with it.  We don't have the same concept of multiple DLT's
230         *       as pcap does.  We grab the rawest possible thing and then
231         *       decode packets by understanding the protocols.  So perhaps
232         *       we should setup a rating of DLT's that we'll prefer in order.
233         *       For example we should try and get 802.11 frames rather than
234         *       802.3 frames.  The general rule should be "whatever actually
235         *       went over the air", although of course if we don't support
236         *       what went over the air we should fall back to something we
237         *       /do/ support.
238         */
239       
240        /* Using timeouts seems sucky.  We'll always use immediate mode.  We
241         * pray the kernel is smart enough that if a another packet arrives
242         * while we're processing this one that it will buffer them into it's
243         * kernel buffer so we can receive packets later. (It'll need to do this
244         * to deal with us spending time processing the last 'n' packets anyway)
245         */
246       
247        v=1;
248        if (ioctl(FORMATIN(libtrace)->fd, BIOCIMMEDIATE, &v) == -1) {
249                trace_set_err(libtrace,errno,"Failed to set immediate mode");
250                close(FORMATIN(libtrace)->fd);
251                return -1;
252        }
253
254        /* Set promiscous mode, if the user has asked us to do so */
255        if (FORMATIN(libtrace)->promisc) {
256                if (ioctl(FORMATIN(libtrace)->fd, BIOCPROMISC, NULL) == -1) {
257                        trace_set_err(libtrace,errno,
258                                "Failed to set promisc mode");
259                        close(FORMATIN(libtrace)->fd);
260                        return -1;
261
262                }
263        }
264
265        FORMATIN(libtrace)->stats_valid = 0;
266
267        /* TODO: we should always set a bpf filter for snapping */
268
269        /* We're done! */
270        return 0;
271}
272
273/* Gets a count of the number of packets received on the BPF interface */
274static uint64_t bpf_get_received_packets(libtrace_t *trace)
275{
276        if (trace->format_data == NULL)
277                return (uint64_t)-1;
278
279        if (FORMATIN(trace)->fd == -1) {
280                /* Almost certainly a 'dead' trace so there is no socket
281                 * for us to query */
282                return (uint64_t) -1;
283        }
284        /* If we're called with stats_valid == 0, or we're called again
285         * then refresh the stats.  Don't refresh the stats if we're called
286         * immediately after get_dropped_packets
287         */
288        if ((FORMATIN(trace)->stats_valid & 1)
289                || (FORMATIN(trace)->stats_valid == 0)) {
290                ioctl(FORMATIN(trace)->fd, BIOCGSTATS, &FORMATIN(trace)->stats);
291                FORMATIN(trace)->stats_valid |= 1;
292        }
293
294        return FORMATIN(trace)->stats.bs_recv;
295}
296
297/* Gets a count of the number of packets dropped on the BPF interface */
298static uint64_t bpf_get_dropped_packets(libtrace_t *trace)
299{
300        if (trace->format_data == NULL)
301                return (uint64_t)-1;
302
303        if (FORMATIN(trace)->fd == -1) {
304                /* Almost certainly a 'dead' trace so there is no socket
305                 * for us to query */
306                return (uint64_t) -1;
307        }
308        /* If we're called with stats_valid == 0, or we're called again
309         * then refresh the stats.  Don't refresh the stats if we're called
310         * immediately after get_received_packets
311         */
312        if ((FORMATIN(trace)->stats_valid & 2) 
313                || (FORMATIN(trace)->stats_valid == 0)) {
314                ioctl(FORMATIN(trace)->fd, BIOCGSTATS, &FORMATIN(trace)->stats);
315                FORMATIN(trace)->stats_valid |= 2;
316        }
317
318        return FORMATIN(trace)->stats.bs_drop;
319}
320
321static void bpf_get_statistics(libtrace_t *trace, libtrace_stat_t *stat) {
322        uint64_t dropped = bpf_get_dropped_packets(trace);
323        uint64_t received = bpf_get_received_packets(trace);
324
325        if (dropped != (uint64_t)-1) {
326                stat->dropped_valid = 1;
327                stat->dropped = dropped;
328        }
329
330        if (received != (uint64_t) -1) {
331                stat->received_valid = 1;
332                stat->received = received;
333        }
334
335}
336
337/* Pauses a BPF input trace */
338static int bpf_pause_input(libtrace_t *libtrace)
339{
340        close(FORMATIN(libtrace)->fd);
341        FORMATIN(libtrace)->fd=-1;
342
343        return 0;
344}
345
346/* Closes a BPF input trace */
347static int bpf_fin_input(libtrace_t *libtrace) 
348{
349        libtrace_bucket_destroy(FORMATIN(libtrace)->bucket);
350        free(libtrace->format_data);
351        return 0;
352}
353
354/* Configures a BPF input trace */
355static int bpf_config_input(libtrace_t *libtrace,
356                trace_option_t option,
357                void *data)
358{
359        switch(option) {
360                case TRACE_OPTION_SNAPLEN:
361                        FORMATIN(libtrace)->snaplen=*(int*)data;
362                        return 0;
363                case TRACE_OPTION_PROMISC:
364                        FORMATIN(libtrace)->promisc=*(int*)data;
365                        return 0;
366                case TRACE_OPTION_FILTER:
367                        /* We don't support bpf filters in any special way
368                         * so return an error and let libtrace deal with
369                         * emulating it
370                         */
371                        break;
372                case TRACE_OPTION_META_FREQ:
373                        /* No meta-data for this format */
374                        break;
375                case TRACE_OPTION_EVENT_REALTIME:
376                        /* Captures are always realtime */
377                        break;
378                case TRACE_OPTION_HASHER:
379                        /* TODO investigate hashing in BSD? */
380                        break;
381
382                /* Avoid default: so that future options will cause a warning
383                 * here to remind us to implement it, or flag it as
384                 * unimplementable
385                 */
386        }
387        return -1;
388}
389
390#endif  /* HAVE_DECL_BIOCSETIF */
391
392/* Converts a buffer containing a recently read BPF packet record into a
393 * libtrace packet */
394static int bpf_prepare_packet(libtrace_t *libtrace UNUSED, 
395                libtrace_packet_t *packet,
396                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
397       
398        struct local_bpf_hdr orig;
399        struct local_bpf_hdr *ptr;
400        struct libtrace_bpf_hdr *replace;
401
402        /* If the packet previously owned a buffer that is not the buffer
403         * that contains the new packet data, we're going to need to free the
404         * old one to avoid memory leaks */
405        if (packet->buffer != buffer &&
406                        packet->buf_control == TRACE_CTRL_PACKET) {
407                free(packet->buffer);
408        }
409
410        /* Set the buffer owner appropriately */
411        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
412                packet->buf_control = TRACE_CTRL_PACKET;
413        } else
414                packet->buf_control = TRACE_CTRL_EXTERNAL;
415
416        /* Update the packet pointers and type appropriately */
417        packet->buffer = buffer;
418        packet->header = buffer;
419        packet->type = rt_type;
420
421        /* FreeBSD is stupid and uses a timeval in the bpf header
422         * structure. This means that sometimes our timestamp consumes
423         * 8 bytes and sometimes it consumes 16 bytes.
424         *
425         * Let's try to standardise our header a bit, hopefully without
426         * overwriting anything else important */
427
428        if (sizeof(struct BPF_TIMEVAL) != sizeof(struct lt_bpf_timeval)) {     
429               
430                ptr = ((struct local_bpf_hdr *)(packet->header));
431                replace = ((struct libtrace_bpf_hdr *)(packet->header));
432                orig = *ptr;
433
434                replace->bh_tstamp.tv_sec = (uint32_t) (orig.bh_tstamp.tv_sec & 0xffffffff);
435                replace->bh_tstamp.tv_usec = (uint32_t) (orig.bh_tstamp.tv_usec & 0xffffffff);
436                replace->bh_caplen = orig.bh_caplen;
437                replace->bh_datalen = orig.bh_datalen;
438                replace->bh_hdrlen = orig.bh_hdrlen;
439
440
441        }
442
443        /* Find the payload */
444        /* TODO: Pcap deals with a padded FDDI linktype here */
445        packet->payload=(char *)buffer + BPFHDR(packet)->bh_hdrlen;
446
447        return 0;
448}
449
450#if HAVE_DECL_BIOCSETIF
451
452/* Reads the next packet record from a BPF interface and writes it into a
453 * libtrace packet */   
454static int bpf_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) 
455{
456        uint32_t flags = 0;
457        fd_set readfds;
458        struct timeval tout;
459        int ret;
460
461        packet->type = bpf_linktype_to_rt(FORMATIN(libtrace)->linktype);
462
463        if (FORMATIN(libtrace)->remaining <= 0) {
464                FORMATIN(libtrace)->buffer = malloc(FORMATIN(libtrace)->buffersize);
465                libtrace_create_new_bucket(FORMATIN(libtrace)->bucket, FORMATIN(libtrace)->buffer);
466        }
467
468        while (FORMATIN(libtrace)->remaining <= 0) {
469
470                tout.tv_sec = 0;
471                tout.tv_usec = 500000;
472                FD_ZERO(&readfds);
473                FD_SET(FORMATIN(libtrace)->fd, &readfds);
474
475                ret = select(FORMATIN(libtrace)->fd + 1, &readfds, NULL,
476                                NULL, &tout);
477                if (ret < 0 && errno != EINTR) {
478                        trace_set_err(libtrace, errno, "select");
479                        return -1;
480                } else if (ret < 0) {
481                        continue;
482                }
483
484                if (FD_ISSET(FORMATIN(libtrace)->fd, &readfds)) {
485                        /* Packets are available, read into buffer */
486                        ret=read(FORMATIN(libtrace)->fd,
487                                FORMATIN(libtrace)->buffer,
488                                FORMATIN(libtrace)->buffersize);
489
490                        if (ret == -1) {
491                                trace_set_err(libtrace,errno,"Failed to read");
492                                return -1;
493                        }
494
495                        if (ret == 0) {
496                                /* EOF */
497                                return 0;
498                        }
499
500                        FORMATIN(libtrace)->remaining=ret;
501                        FORMATIN(libtrace)->bufptr=
502                                        FORMATIN(libtrace)->buffer;
503                        break;
504                }
505
506                /* Timed out -- check if we should halt */
507                if (libtrace_halt)
508                        return 0;
509        }
510       
511        /* We do NOT want anything trying to free the memory the packet is
512         * stored in */
513        flags |= TRACE_PREP_DO_NOT_OWN_BUFFER;
514
515        if (packet->buffer && packet->buf_control == TRACE_CTRL_PACKET)
516                free(packet->buffer);
517
518        /* Update 'packet' to point to the first packet in our capture
519         * buffer */
520        if (bpf_prepare_packet(libtrace, packet, FORMATIN(libtrace)->bufptr,
521                        packet->type, flags)) {
522                return -1;
523        }
524
525        packet->internalid = libtrace_push_into_bucket(FORMATIN(libtrace)->bucket);
526        packet->srcbucket = FORMATIN(libtrace)->bucket;
527
528        /* Skip past the packet record we're going to return, making sure
529         * that we deal with padding correctly */
530        FORMATIN(libtrace)->bufptr+=
531                BPF_WORDALIGN(BPFHDR(packet)->bh_hdrlen
532                +BPFHDR(packet)->bh_caplen);
533        FORMATIN(libtrace)->remaining-=
534                BPF_WORDALIGN(BPFHDR(packet)->bh_hdrlen
535                +BPFHDR(packet)->bh_caplen);
536
537        return BPFHDR(packet)->bh_datalen+BPFHDR(packet)->bh_hdrlen;
538}
539
540#endif  /* HAVE_DECL_BIOCSETIF */
541
542/* Returns the linktype for the interface that we are capturing from */
543static libtrace_linktype_t bpf_get_link_type(const libtrace_packet_t *packet) {
544        /* Convert the linktype that we recorded when we started the trace
545         * into a suitable libtrace linktype */
546        return pcap_linktype_to_libtrace(rt_to_pcap_linktype(packet->type));
547}
548
549/* Returns the direction for a given BPF packet record */
550static libtrace_direction_t bpf_get_direction(const libtrace_packet_t *packet UNUSED) {
551        /* BPF sadly can't do direction tagging */
552        return ~0;
553}
554
555/* Returns the timestamp for a given BPF packet record, in the form of a
556 * struct timeval */
557static struct timeval bpf_get_timeval(const libtrace_packet_t *packet) 
558{
559        struct timeval tv;
560        /* OpenBSD uses a bpf_timeval rather than a timeval so we must copy
561         * each timeval element individually rather than doing a structure
562         * assignment */
563        tv.tv_sec = BPFHDR(packet)->bh_tstamp.tv_sec;
564        tv.tv_usec = BPFHDR(packet)->bh_tstamp.tv_usec;
565
566        return tv;
567}
568
569/* Returns the capture length for a given BPF packet record */
570static int bpf_get_capture_length(const libtrace_packet_t *packet)
571{
572        /* BPF doesn't include the FCS in its caplen field, but libtrace
573         * does so we need to add this extra 4 bytes */
574        return BPFHDR(packet)->bh_caplen+4;
575}
576
577/* Returns the wire length for a given BPF packet record */
578static int bpf_get_wire_length(const libtrace_packet_t *packet) 
579{
580
581        /* BPF doesn't include the FCS in its datalen field, but libtrace
582         * does so we need to add this extra 4 bytes */
583        return BPFHDR(packet)->bh_datalen+4;
584}
585
586/* Returns the framing length for a given BPF packet record */
587static int bpf_get_framing_length(UNUSED
588                const libtrace_packet_t *packet) 
589{
590        return BPFHDR(packet)->bh_hdrlen;
591}
592
593#if HAVE_DECL_BIOCSETIF
594/* Returns the file descriptor that the capture interface is operating on */
595static int bpf_get_fd(const libtrace_t *trace) {
596        return FORMATIN(trace)->fd;
597}
598
599/* Prints some slightly useful help text for the BPF capture format */
600static void bpf_help() {
601        printf("bpf format module: $Revision: 1782 $\n");
602        printf("Supported input URIs:\n");
603        printf("\tbpf:\n");
604        printf("\n");
605        return;
606}
607static struct libtrace_format_t bpf = {
608        "bpf",
609        "$Id$",
610        TRACE_FORMAT_BPF,
611        bpf_probe_filename,     /* probe filename */
612        NULL,                   /* probe magic */
613        bpf_init_input,         /* init_input */
614        bpf_config_input,       /* config_input */
615        bpf_start_input,        /* start_input */
616        bpf_pause_input,        /* pause_input */
617        NULL,                   /* init_output */
618        NULL,                   /* config_output */
619        NULL,                   /* start_ouput */
620        bpf_fin_input,          /* fin_input */
621        NULL,                   /* fin_output */
622        bpf_read_packet,        /* read_packet */
623        bpf_prepare_packet,     /* prepare_packet */
624        NULL,                   /* fin_packet */
625        NULL,                   /* write_packet */
626        bpf_get_link_type,      /* get_link_type */
627        bpf_get_direction,      /* get_direction */
628        NULL,                   /* set_direction */
629        NULL,                   /* get_erf_timestamp */
630        bpf_get_timeval,        /* get_timeval */
631        NULL,                   /* get_timespec */
632        NULL,                   /* get_seconds */
633        NULL,                   /* seek_erf */
634        NULL,                   /* seek_timeval */
635        NULL,                   /* seek_seconds */
636        bpf_get_capture_length, /* get_capture_length */
637        bpf_get_wire_length,    /* get_wire_length */
638        bpf_get_framing_length, /* get_framing_length */
639        NULL,                   /* set_capture_length */
640        NULL,                   /* get_received_packets */
641        NULL,                   /* get_filtered_packets */
642        NULL,                   /* get_dropped_packets */
643        bpf_get_statistics,     /* get_statistics */
644        bpf_get_fd,             /* get_fd */
645        trace_event_device,     /* trace_event */
646        bpf_help,               /* help */
647        NULL,                   /* next pointer */
648        NON_PARALLEL(true)
649};
650#else   /* HAVE_DECL_BIOCSETIF */
651/* Prints some slightly useful help text for the BPF capture format */
652static void bpf_help() {
653        printf("bpf format module: $Revision: 1782 $\n");
654        printf("Not supported on this host\n");
655        return;
656}
657static struct libtrace_format_t bpf = {
658        "bpf",
659        "$Id$",
660        TRACE_FORMAT_BPF,
661        NULL,                   /* probe filename */
662        NULL,                   /* probe magic */
663        NULL,                   /* init_input */
664        NULL,                   /* config_input */
665        NULL,                   /* start_input */
666        NULL,                   /* pause_input */
667        NULL,                   /* init_output */
668        NULL,                   /* config_output */
669        NULL,                   /* start_ouput */
670        NULL,                   /* fin_input */
671        NULL,                   /* fin_output */
672        NULL,                   /* read_packet */
673        bpf_prepare_packet,     /* prepare_packet */
674        NULL,                   /* fin_packet */
675        NULL,                   /* write_packet */
676        bpf_get_link_type,      /* get_link_type */
677        bpf_get_direction,      /* get_direction */
678        NULL,                   /* set_direction */
679        NULL,                   /* get_erf_timestamp */
680        bpf_get_timeval,        /* get_timeval */
681        NULL,                   /* get_timespec */
682        NULL,                   /* get_seconds */
683        NULL,                   /* seek_erf */
684        NULL,                   /* seek_timeval */
685        NULL,                   /* seek_seconds */
686        bpf_get_capture_length, /* get_capture_length */
687        bpf_get_wire_length,    /* get_wire_length */
688        bpf_get_framing_length, /* get_framing_length */
689        NULL,                   /* set_capture_length */
690        NULL,                   /* get_received_packets */
691        NULL,                   /* get_filtered_packets */
692        NULL,                   /* get_dropped_packets */
693        NULL,                   /* get_statistics */
694        NULL,                   /* get_fd */
695        NULL,                   /* trace_event */
696        bpf_help,               /* help */
697        NULL,                   /* next pointer */
698        NON_PARALLEL(true)
699};
700#endif  /* HAVE_DECL_BIOCSETIF */
701
702void bpf_constructor() {
703        register_format(&bpf);
704}
Note: See TracBrowser for help on using the repository browser.