Changeset 238d50a for lib/format_linux.c


Ignore:
Timestamp:
02/08/10 16:43:43 (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:
d026488
Parents:
5511c14
Message:
  • Updated licensing and documentation for several format modules and the format_helper code
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_linux.c

    r7fa118f r238d50a  
    22 * This file is part of libtrace
    33 *
    4  * Copyright (c) 2007,2008 The University of Waikato, Hamilton, New Zealand.
     4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
     5 * New Zealand.
     6 *
    57 * Authors: Daniel Lawson
    6  *          Perry Lorier
     8 *          Perry Lorier
     9 *          Shane Alcock
    710 *         
    811 * All rights reserved.
     
    2831 *
    2932 */
     33
    3034
    3135#include "libtrace.h"
     
    5458#include <assert.h>
    5559
     60/* This format module deals with using the Linux Native capture format.
     61 *
     62 * Linux Native is a LIVE capture format.
     63 *
     64 * This format also supports writing which will write packets out to the
     65 * network as a form of packet replay. This should not be confused with the
     66 * RT protocol which is intended to transfer captured packet records between
     67 * RT-speaking programs.
     68 */
     69
    5670/* Declared in linux/if_arp.h but not in net/if_arp.h sigh */
    5771#ifndef ARPHRD_NONE
     
    6680typedef enum { TS_NONE, TS_TIMEVAL, TS_TIMESPEC } timestamptype_t;
    6781
    68 struct libtrace_format_data_t {
     82struct linux_format_data_t {
     83        /* The file descriptor being used for the capture */
    6984        int fd;
     85        /* The snap length for the capture */
    7086        int snaplen;
     87        /* Flag indicating whether the interface should be placed in
     88         * promiscuous mode */
    7189        int promisc;
     90        /* The timestamp format used by the capture */
    7291        timestamptype_t timestamptype;
     92        /* A BPF filter that is applied to every captured packet */
    7393        libtrace_filter_t *filter;
     94        /* Statistics for the capture process, e.g. dropped packet counts */
    7495        struct tpacket_stats stats;
     96        /* Flag indicating whether the statistics are current or not */
    7597        int stats_valid;
    7698};
    7799
    78100
    79 /* Note that this structure is passed over the wire in rt encapsulation, and thus we need to be
    80  * careful with data sizes.  timeval's and timespec's change their size on 32/64 machines
     101/* Note that this structure is passed over the wire in rt encapsulation, and
     102 * thus we need to be careful with data sizes.  timeval's and timespec's
     103 * can also change their size on 32/64 machines.
    81104 */
     105
     106/* Format header for encapsulating packets captured using linux native */
    82107struct libtrace_linuxnative_header {
     108        /* Timestamp of the packet, as a timeval */
    83109        struct {
    84110                uint32_t tv_sec;
    85111                uint32_t tv_usec;
    86112        } tv;
     113        /* Timestamp of the packet, as a timespec */
    87114        struct {
    88115                uint32_t tv_sec;
    89116                uint32_t tv_nsec;
    90117        } ts;
     118        /* The timestamp format used by the process that captured this packet */
    91119        uint8_t timestamptype;
     120        /* Wire length */
    92121        uint32_t wirelen;
     122        /* Capture length */
    93123        uint32_t caplen;
     124        /* The linux native header itself */
    94125        struct sockaddr_ll hdr;
    95126};
    96127
    97 struct libtrace_linuxnative_format_data_t {
     128struct linux_output_format_data_t {
     129        /* The file descriptor used to write the packets */
    98130        int fd;
    99131};
    100132
    101 #define FORMAT(x) ((struct libtrace_format_data_t*)(x))
    102 #define DATAOUT(x) ((struct libtrace_linuxnative_format_data_t*)((x)->format_data))
     133#define FORMAT(x) ((struct linux_format_data_t*)(x))
     134#define DATAOUT(x) ((struct linux_output_format_data_t*)((x)->format_data))
    103135
    104136static int linuxnative_probe_filename(const char *filename)
     
    110142static int linuxnative_init_input(libtrace_t *libtrace)
    111143{
    112         libtrace->format_data = (struct libtrace_format_data_t *)
    113                 malloc(sizeof(struct libtrace_format_data_t));
     144        libtrace->format_data = (struct linux_format_data_t *)
     145                malloc(sizeof(struct linux_format_data_t));
    114146        FORMAT(libtrace->format_data)->fd = -1;
    115147        FORMAT(libtrace->format_data)->promisc = -1;
     
    123155static int linuxnative_init_output(libtrace_out_t *libtrace)
    124156{
    125         libtrace->format_data = (struct libtrace_linuxnative_format_data_t*)
    126                 malloc(sizeof(struct libtrace_linuxnative_format_data_t));
     157        libtrace->format_data = (struct linux_output_format_data_t*)
     158                malloc(sizeof(struct linux_output_format_data_t));
    127159        DATAOUT(libtrace)->fd = -1;
    128160
     
    136168        memset(&addr,0,sizeof(addr));
    137169        libtrace_filter_t *filter = FORMAT(libtrace->format_data)->filter;
     170       
     171        /* Create a raw socket for reading packets on */
    138172        FORMAT(libtrace->format_data)->fd =
    139173                                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
     
    143177                return -1;
    144178        }
     179
     180        /* Bind to the capture interface */
    145181        addr.sll_family = AF_PACKET;
    146182        addr.sll_protocol = htons(ETH_P_ALL);
     
    175211                        FORMAT(libtrace->format_data)->promisc=0;
    176212        }
    177                                
     213       
     214        /* Enable promiscuous mode, if requested */                     
    178215        if (FORMAT(libtrace->format_data)->promisc) {
    179216                struct packet_mreq mreq;
     
    190227                }
    191228        }
     229
     230        /* Set the timestamp option on the socket - aim for the most detailed
     231         * clock resolution possible */
    192232#ifdef SO_TIMESTAMPNS
    193233        if (setsockopt(FORMAT(libtrace->format_data)->fd,
     
    281321}
    282322
     323/* Compiles a libtrace BPF filter for use with a linux native socket */
    283324static int linuxnative_configure_bpf(libtrace_t *libtrace,
    284325                libtrace_filter_t *filter) {
     
    361402                        break;
    362403                case TRACE_OPTION_EVENT_REALTIME:
     404                        /* Live captures are always going to be in trace time */
    363405                        break;
    364406                /* Avoid default: so that future options will cause a warning
     
    434476                        (int)FORMAT(libtrace->format_data)->snaplen);
    435477
     478        /* Prepare the msghdr and iovec for the kernel to write the
     479         * captured packet into. The msghdr will point to the part of our
     480         * buffer reserved for sll header, while the iovec will point at
     481         * the buffer following the sll header. */
     482
    436483        msghdr.msg_name = &hdr->hdr;
    437484        msghdr.msg_namelen = sizeof(struct sockaddr_ll);
     
    455502
    456503        hdr->caplen=LIBTRACE_MIN(snaplen,hdr->wirelen);
     504
     505        /* Extract the timestamps from the msghdr and store them in our
     506         * linux native encapsulation, so that we can preserve the formatting
     507         * across multiple architectures */
    457508
    458509        for (cmsg = CMSG_FIRSTHDR(&msghdr);
     
    479530        }
    480531
    481         /* Did we not get given a timestamp? */
     532        /* Did we not get given a timestamp? Try to get one from the
     533         * file descriptor directly */
    482534        if (cmsg == NULL) {
    483535                struct timeval tv;
     
    493545        }
    494546
     547        /* Buffer contains all of our packet (including our custom header) so
     548         * we just need to get prepare_packet to set all our packet pointers
     549         * appropriately */
     550       
    495551        if (linuxnative_prepare_packet(libtrace, packet, packet->buffer,
    496552                                packet->type, flags))
     
    513569        memcpy(hdr.sll_addr,packet->payload,(size_t)ntohs(hdr.sll_halen));
    514570
     571        /* This is pretty easy, just send the payload using sendto() (after
     572         * setting up the sll header properly, of course) */
    515573        return sendto(DATAOUT(trace)->fd,
    516574                        packet->payload,
     
    524582        int linktype=(((struct libtrace_linuxnative_header*)(packet->buffer))
    525583                                ->hdr.sll_hatype);
     584        /* Convert the ARPHRD type into an appropriate libtrace link type */
     585
    526586        switch (linktype) {
    527587                case ARPHRD_ETHER:
     
    657717}
    658718
    659 /* Number of packets that past filtering */
     719/* Number of packets that passed filtering */
    660720static uint64_t linuxnative_get_captured_packets(libtrace_t *trace) {
    661721        if (trace->format_data == NULL)
     
    710770        printf("linuxnative format module: $Revision$\n");
    711771        printf("Supported input URIs:\n");
    712         printf("\tint:\n");
     772        printf("\tint:eth0\n");
    713773        printf("\n");
    714774        printf("Supported output URIs:\n");
    715         printf("\tnone\n");
     775        printf("\tint:eth0\n");
    716776        printf("\n");
    717777        return;
Note: See TracChangeset for help on using the changeset viewer.