Changeset 5952ff0 for lib/format_bpf.c


Ignore:
Timestamp:
02/04/10 10:36:53 (11 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
43c00e5
Parents:
2c743a7
Message:
  • Updated internal documentation and licensing for several format modules
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_bpf.c

    r099c35e r5952ff0  
    22 * This file is part of libtrace
    33 *
    4  * Copyright (c) 2007,2008 The University of Waikato, Hamilton, New Zealand.
    5  * Authors: Perry Lorier
     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
    610 *         
    711 * All rights reserved.
     
    5256#include <fcntl.h>
    5357
    54 
     58/* This format deals with the BSD Native capture format, perhaps better
     59 * known as BPF, which is the equivalent of the Linux Native format for
     60 * *BSD systems.
     61 *
     62 * This is a LIVE capture format - we're always dealing with reading from an
     63 * interface.
     64 *
     65 * This format does not support writing, but BPF packet records can be easily
     66 * converted to PCAP or ERF.
     67 */
     68
     69/* "Global" data that is stored for each BPF input trace */
    5570struct libtrace_format_data_t {
    56         int fd;
     71        /* The file descriptor that is being captured from */
     72        int fd;
     73        /* The snap length for the capture */
    5774        int snaplen;
     75        /* A boolean flag indicating whether the capture interface should be
     76         * in promiscuous mode */
    5877        int promisc;
     78        /* A buffer to write captured data into */
    5979        void *buffer;
     80        /* The current read location in the capture buffer */
    6081        void *bufptr;
     82        /* The total size of the capture buffer */
    6183        unsigned int buffersize;
     84        /* The amount of space remaining before the capture buffer is full */
    6285        int remaining;
     86        /* The linktype of the capture interface */
    6387        unsigned int linktype;
     88        /* Statistics about how many packets have been dropped, received etc. */
    6489        struct bpf_stat stats;
     90        /* A boolean flag indicating whether the statistics are up-to-date */
    6591        int stats_valid;
    6692};
     
    7096#define BPFHDR(x) ((struct bpf_hdr *)((x)->header))
    7197
     98/* Attempts to determine if a given filename could refer to a BPF interface */
    7299static int bpf_probe_filename(const char *filename)
    73100{
     
    75102}
    76103
     104/* XXX This function doesn't appear to be used anywhere - nor does it do
     105 * anything particularly useful :) */
    77106static int bpf_start_filename(const char *filename)
    78107{
     
    80109}
    81110
     111/* Initialises a BPF input trace */
    82112static int bpf_init_input(libtrace_t *libtrace)
    83113{
    84114        libtrace->format_data = (struct libtrace_format_data_t *)
    85115                malloc(sizeof(struct libtrace_format_data_t));
     116       
     117        /* Throw some default values into the format data */
    86118        FORMATIN(libtrace)->fd = -1;
    87119        FORMATIN(libtrace)->promisc = 0;
     
    92124}
    93125
     126/* Starts a BPF input trace */
    94127static int bpf_start_input(libtrace_t *libtrace)
    95128{
     
    155188        FORMATIN(libtrace)->remaining = 0;
    156189
    157         /* attach to the device */
     190        /* Attach to the device */
    158191        strncpy(ifr.ifr_name, libtrace->uridata, sizeof(ifr.ifr_name));
    159192        if (ioctl(FORMATIN(libtrace)->fd, BIOCSETIF, &ifr) == -1) {
     
    163196        }
    164197
     198        /* Set the link type */
    165199        if (ioctl(FORMATIN(libtrace)->fd, BIOCGDLT,
    166200                         &FORMATIN(libtrace)->linktype) == -1) {
     
    185219         * pray the kernel is smart enough that if a another packet arrives
    186220         * while we're processing this one that it will buffer them into it's
    187          * kernel buffer so we can recieve packets later. (It'll need to do this
     221         * kernel buffer so we can receive packets later. (It'll need to do this
    188222         * to deal with us spending time processing the last 'n' packets anyway)
    189223         */
     
    196230        }
    197231
     232        /* Set promiscous mode, if the user has asked us to do so */
    198233        if (FORMATIN(libtrace)->promisc) {
    199234                if (ioctl(FORMATIN(libtrace)->fd, BIOCPROMISC, NULL) == -1) {
     
    214249}
    215250
     251/* Gets a count of the number of packets received on the BPF interface */
    216252static uint64_t bpf_get_received_packets(libtrace_t *trace)
    217253{
     
    237273}
    238274
     275/* Gets a count of the number of packets dropped on the BPF interface */
    239276static uint64_t bpf_get_dropped_packets(libtrace_t *trace)
    240277{
     
    260297}
    261298
     299/* Pauses a BPF input trace */
    262300static int bpf_pause_input(libtrace_t *libtrace)
    263301{
     
    268306}
    269307
     308/* Closes a BPF input trace */
    270309static int bpf_fin_input(libtrace_t *libtrace)
    271310{
     
    274313}
    275314
     315/* Configures a BPF input trace */
    276316static int bpf_config_input(libtrace_t *libtrace,
    277317                trace_option_t option,
     
    295335                        break;
    296336                case TRACE_OPTION_EVENT_REALTIME:
    297                         /* captures are always realtime */
     337                        /* Captures are always realtime */
    298338                        break;
    299339
     
    308348}
    309349
     350/* Converts a buffer containing a recently read BPF packet record into a
     351 * libtrace packet */
    310352static int bpf_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
    311353                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
    312         if (packet->buffer != buffer &&
     354       
     355        /* If the packet previously owned a buffer that is not the buffer
     356         * that contains the new packet data, we're going to need to free the
     357         * old one to avoid memory leaks */
     358        if (packet->buffer != buffer &&
    313359                        packet->buf_control == TRACE_CTRL_PACKET) {
    314360                free(packet->buffer);
    315361        }
    316362
     363        /* Set the buffer owner appropriately */
    317364        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
    318365                packet->buf_control = TRACE_CTRL_PACKET;
     
    320367                packet->buf_control = TRACE_CTRL_EXTERNAL;
    321368
    322 
     369        /* Update the packet pointers and type appropriately */
    323370        packet->buffer = buffer;
    324371        packet->header = buffer;
     
    336383        return 0;
    337384}
    338        
     385
     386/* Reads the next packet record from a BPF interface and writes it into a
     387 * libtrace packet */   
    339388static int bpf_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet)
    340389{
    341390        uint32_t flags = 0;
    342391       
    343         /* Fill the buffer */
     392        /* Read from the BPF interface into our capture buffer */
    344393        if (FORMATIN(libtrace)->remaining<=0) {
    345394                int ret;
     
    363412                                FORMATIN(libtrace)->buffer;
    364413        }
     414
     415        /* We do NOT want anything trying to free the memory the packet is
     416         * stored in */
    365417        flags |= TRACE_PREP_DO_NOT_OWN_BUFFER;
    366         /* Read one packet out */
    367        
     418
    368419        if (packet->buf_control == TRACE_CTRL_PACKET)
    369420                free(packet->buffer);
    370421
     422        /* Update 'packet' to point to the first packet in our capture
     423         * buffer */
    371424        if (bpf_prepare_packet(libtrace, packet, FORMATIN(libtrace)->bufptr,
    372425                TRACE_RT_DATA_BPF, flags)) {
     
    375428       
    376429
    377         /* Now deal with any padding */
     430        /* Skip past the packet record we're going to return, making sure
     431         * that we deal with padding correctly */
    378432        FORMATIN(libtrace)->bufptr+=
    379433                BPF_WORDALIGN(BPFHDR(packet)->bh_hdrlen
     
    386440}
    387441
     442/* Returns the linktype for the interface that we are capturing from */
    388443static libtrace_linktype_t bpf_get_link_type(const libtrace_packet_t *packet) {
     444        /* Convert the linktype that we recorded when we started the trace
     445         * into a suitable libtrace linktype */
    389446        return pcap_linktype_to_libtrace(FORMATIN(packet->trace)->linktype);
    390447}
    391448
     449/* Returns the direction for a given BPF packet record */
    392450static libtrace_direction_t bpf_get_direction(const libtrace_packet_t *packet) {
    393         /* BPF Sadly can't do direction tagging */
     451        /* BPF sadly can't do direction tagging */
    394452        return ~0;
    395453}
    396454
     455/* Returns the timestamp for a given BPF packet record, in the form of a
     456 * struct timeval */
    397457static struct timeval bpf_get_timeval(const libtrace_packet_t *packet)
    398458{
     
    407467}
    408468
     469/* Returns the capture length for a given BPF packet record */
    409470static int bpf_get_capture_length(const libtrace_packet_t *packet)
    410471{
    411         /* BPF Doesn't include the FCS, we do. */
     472        /* BPF doesn't include the FCS in its caplen field, but libtrace
     473         * does so we need to add this extra 4 bytes */
    412474        return BPFHDR(packet)->bh_caplen+4;
    413475}
    414476
     477/* Returns the wire length for a given BPF packet record */
    415478static int bpf_get_wire_length(const libtrace_packet_t *packet)
    416479{
     480
     481        /* BPF doesn't include the FCS in its datalen field, but libtrace
     482         * does so we need to add this extra 4 bytes */
    417483        return BPFHDR(packet)->bh_datalen+4;
    418484}
    419485
     486/* Returns the framing length for a given BPF packet record */
    420487static int bpf_get_framing_length(UNUSED
    421488                const libtrace_packet_t *packet)
     
    424491}
    425492
     493/* Returns the file descriptor that the capture interface is operating on */
    426494static int bpf_get_fd(const libtrace_t *trace) {
    427495        return FORMATIN(trace)->fd;
    428496}
    429497
     498/* Prints some slightly useful help text for the BPF capture format */
    430499static void bpf_help() {
    431500        printf("bpf format module: $Revision$\n");
Note: See TracChangeset for help on using the changeset viewer.