source: lib/format_bpf.c @ 9e429e8

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 9e429e8 was 9e429e8, checked in by Richard Sanger <rsangerarj@…>, 7 years ago

Merge remote-tracking branch 'upsteam/master' into develop

Conflicts:

README
lib/format_dpdk.c
lib/format_linux.c
lib/trace.c

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