source: lib/format_bpf.c @ 2725318

develop
Last change on this file since 2725318 was 2725318, checked in by Jacob Van Walraven <jcv9@…>, 2 years ago

Cleanup some of the assertions

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