source: lib/format_linux.c @ 50ce607

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

Adds per thread storage to for the format to use against libtrace_threads.
Passes threads as arguments to reads to save overhead of looking these up.
Various changes to the DPDK system including registering a thread to allow our threads to be start with different DPDK thread numbers for thread local memory caches.

  • Property mode set to 100644
File size: 60.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 *          Richard Sanger
11 *         
12 * All rights reserved.
13 *
14 * This code has been developed by the University of Waikato WAND
15 * research group. For further information please see http://www.wand.net.nz/
16 *
17 * libtrace is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * libtrace is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with libtrace; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30 *
31 * $Id$
32 *
33 */
34
35/* This format module deals with using the Linux Native capture format.
36 *
37 * Linux Native is a LIVE capture format.
38 *
39 * This format also supports writing which will write packets out to the
40 * network as a form of packet replay. This should not be confused with the
41 * RT protocol which is intended to transfer captured packet records between
42 * RT-speaking programs.
43 */
44
45#include "config.h"
46#include "libtrace.h"
47#include "libtrace_int.h"
48#include "format_helper.h"
49#include "libtrace_arphrd.h"
50#include <stdlib.h>
51#include <errno.h>
52#include <unistd.h>
53#include <string.h>
54#include <assert.h>
55
56#ifdef HAVE_INTTYPES_H
57#  include <inttypes.h>
58#else
59# error "Can't find inttypes.h"
60#endif
61
62#ifdef HAVE_NETPACKET_PACKET_H
63
64#include <sys/socket.h>
65#include <netpacket/packet.h>
66#include <net/ethernet.h>
67#include <net/if_arp.h>
68
69#include <net/if.h>
70#include <sys/ioctl.h>
71#include <poll.h>
72#include <sys/mman.h>
73
74#include <fcntl.h>
75
76/* MAX_ORDER is defined in linux/mmzone.h. 10 is default for 2.4 kernel.
77 * max_order will be decreased by one if the ring buffer fails to allocate.
78 * Used to get correct sized buffers from the kernel.
79 */
80#define MAX_ORDER 10
81
82/* Cached page size, the page size shouldn't be changing */
83static int pagesize = 0;
84
85/* Number of frames in the ring used by both TX and TR rings. More frames
86 * hopefully means less packet loss, especially if traffic comes in bursts.
87 */
88#define CONF_RING_FRAMES        0x100
89
90/* The maximum frames allowed to be waiting in the TX_RING before the kernel is
91 * notified to write them out. Make sure this is less than CONF_RING_FRAMES.
92 * Performance doesn't seem to increase any more when setting this above 10.
93 */
94#define TX_MAX_QUEUE            10
95
96/* Get current frame in the ring buffer*/
97#define GET_CURRENT_BUFFER(libtrace) ((void *) FORMAT(libtrace->format_data)->rx_ring + \
98        (FORMAT(libtrace->format_data)->rxring_offset * FORMAT(libtrace->format_data)->req.tp_frame_size))
99
100
101#else   /* HAVE_NETPACKET_PACKET_H */
102/* Need to know what a sockaddr_ll looks like */
103struct sockaddr_ll {
104        uint16_t sll_family;
105        uint16_t sll_protocol;
106        int32_t  sll_ifindex;
107        uint16_t sll_hatype;
108        uint8_t  sll_pkttype;
109        uint8_t  sll_halen;
110        uint8_t  sll_addr[8];
111};
112
113/* Packet types.  */
114
115#define PACKET_HOST             0               /* To us.  */
116#define PACKET_BROADCAST        1               /* To all.  */
117#define PACKET_MULTICAST        2               /* To group.  */
118#define PACKET_OTHERHOST        3               /* To someone else.  */
119#define PACKET_OUTGOING         4               /* Originated by us . */
120#define PACKET_LOOPBACK         5
121#define PACKET_FASTROUTE        6
122
123/* Packet socket options.  */
124
125#define PACKET_ADD_MEMBERSHIP           1
126#define PACKET_DROP_MEMBERSHIP          2
127#define PACKET_RECV_OUTPUT              3
128#define PACKET_RX_RING                  5
129#define PACKET_STATISTICS               6
130
131
132#endif /* HAVE_NETPACKET_PACKET_H */
133
134struct tpacket_stats {
135        unsigned int tp_packets;
136        unsigned int tp_drops;
137};
138
139typedef enum { TS_NONE, TS_TIMEVAL, TS_TIMESPEC } timestamptype_t;
140
141/* linux/if_packet.h defines. They are here rather than including the header
142 * this means that we can interpret a ring frame on a kernel that doesn't
143 * support the format directly.
144 */
145
146
147#define PACKET_RX_RING  5
148#define PACKET_VERSION  10
149#define PACKET_HDRLEN   11
150#define PACKET_TX_RING  13
151#define PACKET_FANOUT   18
152#define TP_STATUS_USER  0x1
153#define TP_STATUS_SEND_REQUEST  0x1
154#define TP_STATUS_AVAILABLE     0x0
155#define TO_TP_HDR(x)    ((struct tpacket2_hdr *) (x))
156#define TPACKET_ALIGNMENT       16
157#define TPACKET_ALIGN(x)        (((x)+TPACKET_ALIGNMENT-1)&~(TPACKET_ALIGNMENT-1))
158#define TPACKET_HDRLEN         (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
159
160/* Since 3.1 kernel we have packet_fanout support */
161// schedule to socket by skb's rxhash - the implementation is bi-directional
162#define PACKET_FANOUT_HASH              0
163// schedule round robin
164#define PACKET_FANOUT_LB                1
165// schedule to the same socket that received the packet
166#define PACKET_FANOUT_CPU               2
167// Something to do with fragmented packets and hashing problems !! TODO figure out if this needs to be on
168#define PACKET_FANOUT_FLAG_DEFRAG       0x8000
169/* Included but unused by libtrace since 3.10 */
170// if one socket if full roll over to the next
171#define PACKET_FANOUT_ROLLOVER          3
172// This flag makes any other system roll over
173#define PACKET_FANOUT_FLAG_ROLLOVER     0x1000
174/* Included but unused by libtrace since 3.12 */
175// schedule random
176#define PACKET_FANOUT_RND               4
177
178
179enum tpacket_versions {
180        TPACKET_V1,
181        TPACKET_V2
182};
183
184struct tpacket2_hdr {
185        /* Frame status - in use by kernel or libtrace etc. */
186        uint32_t        tp_status;
187        /* Wire length */
188        uint32_t        tp_len;
189        /* Captured length */
190        uint32_t        tp_snaplen;
191        /* Offset in bytes from frame start to the mac (link layer) header */
192        uint16_t        tp_mac;
193        /* Offset in bytes from frame start to the net (network layer) header */
194        uint16_t        tp_net;
195        /* Timestamp */
196        uint32_t        tp_sec;
197        uint32_t        tp_nsec;
198        /* Not used VLAN tag control information */
199        uint16_t        tp_vlan_tci;
200        uint16_t        tp_padding;
201};
202
203struct tpacket_req {
204        unsigned int tp_block_size;  /* Minimal size of contiguous block */
205        unsigned int tp_block_nr;    /* Number of blocks */
206        unsigned int tp_frame_size;  /* Size of frame */
207        unsigned int tp_frame_nr;    /* Total number of frames */
208};
209
210struct linux_per_thread_t {
211        char *rx_ring;
212        int rxring_offset;
213        int fd;
214        // The flag layout should be the same for all (I Hope)
215        // max_order
216} ALIGN_STRUCT(CACHE_LINE_SIZE);
217
218struct linux_format_data_t {
219        /* The file descriptor being used for the capture */
220        int fd;
221        /* The snap length for the capture */
222        int snaplen;
223        /* Flag indicating whether the interface should be placed in
224         * promiscuous mode */
225        int promisc;
226        /* The timestamp format used by the capture */ 
227        timestamptype_t timestamptype;
228        /* A BPF filter that is applied to every captured packet */
229        libtrace_filter_t *filter;
230        /* Statistics for the capture process, e.g. dropped packet counts */
231        struct tpacket_stats stats;
232        /* Flag indicating whether the statistics are current or not */
233        int stats_valid;
234        /* The rx ring mmap location*/
235        char * rx_ring;
236        /* The current frame number within the rx ring */       
237        int rxring_offset;
238        /* The actual format being used - ring vs int */
239        libtrace_rt_types_t format;
240        /* The current ring buffer layout */
241        struct tpacket_req req;
242        /* Used to determine buffer size for the ring buffer */ 
243        uint32_t max_order;
244        /* Used for the parallel case, fanout is the mode */
245        uint16_t fanout_flags;
246        /* The group lets Linux know which sockets to group together
247         * so we use a random here to try avoid collisions */
248        uint16_t fanout_group;
249        /* When running in parallel mode this is malloc'd with an array
250         * file descriptors from packet fanout will use, here we assume/hope
251         * that every ring can get setup the same */
252        struct linux_per_thread_t *per_thread;
253};
254
255
256/* Note that this structure is passed over the wire in rt encapsulation, and
257 * thus we need to be careful with data sizes.  timeval's and timespec's
258 * can also change their size on 32/64 machines.
259 */
260
261/* Format header for encapsulating packets captured using linux native */
262struct libtrace_linuxnative_header {
263        /* Timestamp of the packet, as a timeval */
264        struct {
265                uint32_t tv_sec;
266                uint32_t tv_usec;
267        } tv;
268        /* Timestamp of the packet, as a timespec */
269        struct {
270                uint32_t tv_sec;
271                uint32_t tv_nsec;
272        } ts;
273        /* The timestamp format used by the process that captured this packet */
274        uint8_t timestamptype;
275        /* Wire length */
276        uint32_t wirelen;
277        /* Capture length */
278        uint32_t caplen;
279        /* The linux native header itself */
280        struct sockaddr_ll hdr;
281};
282
283struct linux_output_format_data_t {
284        /* The file descriptor used to write the packets */
285        int fd;
286        /* The tx ring mmap location */
287        char * tx_ring;
288        /* The current frame number within the tx ring */       
289        int txring_offset;
290        /* The current ring buffer layout */
291        struct tpacket_req req;
292        /* Our sockaddr structure, here so we can cache the interface number */
293        struct sockaddr_ll sock_hdr;
294        /* The (maximum) number of packets that haven't been written */
295        int queue;
296        /* The format this trace is using linuxring or linuxnative */
297        libtrace_rt_types_t format;
298        /* Used to determine buffer size for the ring buffer */ 
299        uint32_t max_order;
300};
301
302/* Get the sockaddr_ll structure from a frame */
303#define GET_SOCKADDR_HDR(x)  ((struct sockaddr_ll *) (((char *) (x))\
304        + TPACKET_ALIGN(sizeof(struct tpacket2_hdr))))
305
306#define FORMAT(x) ((struct linux_format_data_t*)(x))
307#define PERPKT_FORMAT(x) ((struct linux_per_thread_t*)(x->format_data))
308#define DATAOUT(x) ((struct linux_output_format_data_t*)((x)->format_data))
309
310/* Get the start of the captured data. I'm not sure if tp_mac (link layer) is
311 * always guaranteed. If it's not there then just use tp_net.
312 */
313#define TP_TRACE_START(mac, net, hdrend) \
314        ((mac) > (hdrend) && (mac) < (net) ? (mac) : (net))
315
316
317#ifdef HAVE_NETPACKET_PACKET_H
318/*
319 * Try figure out the best sizes for the ring buffer. Ensure that:
320 * - max(Block_size) == page_size << max_order
321 * - Frame_size == page_size << x (so that block_size%frame_size == 0)
322 *   This means that there will be no wasted space between blocks
323 * - Frame_size < block_size
324 * - Frame_size is as close as possible to LIBTRACE_PACKET_BUFSIZE, but not
325 *   bigger
326 * - Frame_nr = Block_nr * (frames per block)
327 * - CONF_RING_FRAMES is used a minimum number of frames to hold
328 * - Calculates based on max_order and buf_min
329 */
330static void calculate_buffers(struct tpacket_req * req, int fd, char * uri,
331                uint32_t max_order){
332       
333        struct ifreq ifr;
334        unsigned max_frame = LIBTRACE_PACKET_BUFSIZE;
335        pagesize = getpagesize();
336
337        strcpy(ifr.ifr_name, uri);
338        /* Don't bother trying to set frame size above mtu linux will drop
339         * these anyway.
340         *
341         * Remember, that our frame also has to include a TPACKET header!
342         */
343        if (ioctl(fd, SIOCGIFMTU, (caddr_t) &ifr) >= 0) 
344                max_frame = ifr.ifr_mtu + TPACKET_ALIGN(TPACKET_HDRLEN);
345        if (max_frame > LIBTRACE_PACKET_BUFSIZE)
346                max_frame = LIBTRACE_PACKET_BUFSIZE;
347
348        /* Calculate frame size */
349        req->tp_frame_size = pagesize;
350        while(req->tp_frame_size < max_frame && 
351                        req->tp_frame_size < LIBTRACE_PACKET_BUFSIZE){
352                req->tp_frame_size <<= 1;
353        }
354        if(req->tp_frame_size > LIBTRACE_PACKET_BUFSIZE)
355                req->tp_frame_size >>= 1;
356
357        /* Calculate block size */
358        req->tp_block_size = pagesize << max_order;
359        do{
360                req->tp_block_size >>= 1;
361        } while((CONF_RING_FRAMES * req->tp_frame_size) <= req->tp_block_size);
362        req->tp_block_size <<= 1;
363       
364        /* Calculate number of blocks */
365        req->tp_block_nr = (CONF_RING_FRAMES * req->tp_frame_size) 
366                        / req->tp_block_size;
367        if((CONF_RING_FRAMES * req->tp_frame_size) % req->tp_block_size != 0)
368                req->tp_block_nr++;
369
370        /* Calculate packets such that we use all the space we have to allocated */
371        req->tp_frame_nr = req->tp_block_nr * 
372                        (req->tp_block_size / req->tp_frame_size);
373
374        /*
375        printf("MaxO 0x%x BS 0x%x BN 0x%x FS 0x%x FN 0x%x\n",
376                max_order,
377                req->tp_block_size,
378                req->tp_block_nr,
379                req->tp_frame_size,
380                req->tp_frame_nr);
381        */
382       
383        /* In case we have some silly values*/
384        assert(req->tp_block_size);
385        assert(req->tp_block_nr);
386        assert(req->tp_frame_size);
387        assert(req->tp_frame_nr);
388        assert(req->tp_block_size % req->tp_frame_size == 0);
389}
390
391
392static int linuxnative_probe_filename(const char *filename)
393{
394        /* Is this an interface? */
395        return (if_nametoindex(filename) != 0);
396}
397
398static inline void init_input(libtrace_t *libtrace){
399        libtrace->format_data = (struct linux_format_data_t *)
400                malloc(sizeof(struct linux_format_data_t));
401        FORMAT(libtrace->format_data)->fd = -1;
402        FORMAT(libtrace->format_data)->promisc = -1;
403        FORMAT(libtrace->format_data)->snaplen = LIBTRACE_PACKET_BUFSIZE;
404        FORMAT(libtrace->format_data)->filter = NULL;
405        FORMAT(libtrace->format_data)->stats_valid = 0;
406        FORMAT(libtrace->format_data)->rx_ring = NULL;
407        FORMAT(libtrace->format_data)->rxring_offset = 0;
408        FORMAT(libtrace->format_data)->max_order = MAX_ORDER;
409        FORMAT(libtrace->format_data)->fanout_flags = PACKET_FANOUT_LB; // This might be best or alternatively PACKET_FANOUT_LB
410        // Some examples use pid for the group however that would limit a single
411        // application to use only int/ring format, instead using rand
412        FORMAT(libtrace->format_data)->fanout_group = (uint16_t) rand();
413        FORMAT(libtrace->format_data)->per_thread = NULL;
414}
415static int linuxring_init_input(libtrace_t *libtrace) 
416{       
417        init_input(libtrace);
418        FORMAT(libtrace->format_data)->format = TRACE_RT_DATA_LINUX_RING;
419        return 0;
420}
421static int linuxnative_init_input(libtrace_t *libtrace) 
422{
423        init_input(libtrace);
424        FORMAT(libtrace->format_data)->format = TRACE_RT_DATA_LINUX_NATIVE;
425        return 0;
426}
427
428static inline void init_output(libtrace_out_t *libtrace)
429{
430        libtrace->format_data = (struct linux_output_format_data_t*)
431                malloc(sizeof(struct linux_output_format_data_t));
432        DATAOUT(libtrace)->fd = -1;
433        DATAOUT(libtrace)->tx_ring = NULL;
434        DATAOUT(libtrace)->txring_offset = 0;
435        DATAOUT(libtrace)->queue = 0;
436        DATAOUT(libtrace)->max_order = MAX_ORDER;
437}
438static int linuxnative_init_output(libtrace_out_t *libtrace)
439{
440        init_output(libtrace);
441        DATAOUT(libtrace)->format = TRACE_FORMAT_LINUX_NATIVE;
442        return 0;
443}
444static int linuxring_init_output(libtrace_out_t *libtrace)
445{
446        init_output(libtrace);
447        DATAOUT(libtrace)->format = TRACE_FORMAT_LINUX_RING;
448        return 0;
449}
450
451static int linuxnative_start_input(libtrace_t *libtrace)
452{
453        struct sockaddr_ll addr;
454        int one = 1;
455        memset(&addr,0,sizeof(addr));
456        libtrace_filter_t *filter = FORMAT(libtrace->format_data)->filter;
457       
458        /* Create a raw socket for reading packets on */
459        FORMAT(libtrace->format_data)->fd = 
460                                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
461        if (FORMAT(libtrace->format_data)->fd==-1) {
462                trace_set_err(libtrace, errno, "Could not create raw socket");
463                free(libtrace->format_data);
464                libtrace->format_data = NULL;
465                return -1;
466        }
467
468        /* Bind to the capture interface */
469        addr.sll_family = AF_PACKET;
470        addr.sll_protocol = htons(ETH_P_ALL);
471        if (strlen(libtrace->uridata)) {
472                addr.sll_ifindex = if_nametoindex(libtrace->uridata);
473                if (addr.sll_ifindex == 0) {
474                        close(FORMAT(libtrace->format_data)->fd);
475                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Failed to find interface %s", libtrace->uridata);
476                        free(libtrace->format_data);
477                        libtrace->format_data = NULL;
478                        return -1;
479                }
480        }
481        else {
482                addr.sll_ifindex = 0;
483        }
484        if (bind(FORMAT(libtrace->format_data)->fd,
485                                (struct sockaddr*)&addr,
486                                (socklen_t)sizeof(addr))==-1) {
487                free(libtrace->format_data);
488                libtrace->format_data = NULL;
489                trace_set_err(libtrace, errno, "Failed to bind to interface %s", libtrace->uridata);
490                return -1;
491        }
492
493        /* If promisc hasn't been specified, set it to "true" if we're
494         * capturing on one interface, or "false" if we're capturing on
495         * all interfaces.
496         */ 
497        if (FORMAT(libtrace->format_data)->promisc==-1) {
498                if (addr.sll_ifindex!=0)
499                        FORMAT(libtrace->format_data)->promisc=1;
500                else
501                        FORMAT(libtrace->format_data)->promisc=0;
502        }
503       
504        /* Enable promiscuous mode, if requested */                     
505        if (FORMAT(libtrace->format_data)->promisc) {
506                struct packet_mreq mreq;
507                socklen_t socklen = sizeof(mreq);
508                memset(&mreq,0,sizeof(mreq));
509                mreq.mr_ifindex = addr.sll_ifindex;
510                mreq.mr_type = PACKET_MR_PROMISC;
511                if (setsockopt(FORMAT(libtrace->format_data)->fd,
512                                SOL_PACKET,
513                                PACKET_ADD_MEMBERSHIP,
514                                &mreq,
515                                socklen)==-1) {
516                        perror("setsockopt(PROMISC)");
517                }
518        }
519
520        /* Set the timestamp option on the socket - aim for the most detailed
521         * clock resolution possible */
522#ifdef SO_TIMESTAMPNS
523        if (setsockopt(FORMAT(libtrace->format_data)->fd,
524                        SOL_SOCKET,
525                        SO_TIMESTAMPNS,
526                        &one,
527                        (socklen_t)sizeof(one))!=-1) {
528                FORMAT(libtrace->format_data)->timestamptype = TS_TIMESPEC;
529        }
530        else
531        /* DANGER: This is a dangling else to only do the next setsockopt() if we fail the first! */
532#endif
533        if (setsockopt(FORMAT(libtrace->format_data)->fd,
534                        SOL_SOCKET,
535                        SO_TIMESTAMP,
536                        &one,
537                        (socklen_t)sizeof(one))!=-1) {
538                FORMAT(libtrace->format_data)->timestamptype = TS_TIMEVAL;
539        }
540        else 
541                FORMAT(libtrace->format_data)->timestamptype = TS_NONE;
542
543        /* Push BPF filter into the kernel. At this stage we can safely assume
544         * that the filterstring has been compiled, or the filter was supplied
545         * pre-compiled.
546         */
547        if (filter != NULL) {
548                assert(filter->flag == 1);
549                if (setsockopt(FORMAT(libtrace->format_data)->fd,
550                                        SOL_SOCKET,
551                                        SO_ATTACH_FILTER,
552                                        &filter->filter,
553                                        sizeof(filter->filter)) == -1) {
554                        perror("setsockopt(SO_ATTACH_FILTER)");
555                } else { 
556                        /* The socket accepted the filter, so we need to
557                         * consume any buffered packets that were received
558                         * between opening the socket and applying the filter.
559                         */
560                        void *buf = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
561                        while(recv(FORMAT(libtrace->format_data)->fd,
562                                        buf,
563                                        (size_t) LIBTRACE_PACKET_BUFSIZE,
564                                        MSG_DONTWAIT) != -1) { }
565                        free(buf);
566                }
567        }
568
569        FORMAT(libtrace->format_data)->stats_valid=0;
570                                       
571        return 0;
572}
573static inline int socket_to_packetmmap( char * uridata, int ring_type, 
574                                        int fd, 
575                                        struct tpacket_req * req,
576                                        char ** ring_location,
577                                        uint32_t *max_order,
578                                        char *error){
579        int val;
580
581        /* Switch to TPACKET header version 2, we only try support v2 because v1 had problems */
582
583        val = TPACKET_V2;
584        if (setsockopt(fd, 
585                        SOL_PACKET, 
586                        PACKET_VERSION, 
587                        &val, 
588                        sizeof(val)) == -1){
589                strncpy(error, "TPACKET2 not supported", 2048);
590                return -1;
591        }
592
593        /* Try switch to a ring buffer. If it fails we assume the the kernel 
594         * cannot allocate a block of that size, so decrease max_block and retry.
595         */
596        while(1) {     
597                if (*max_order <= 0) {
598                        strncpy(error,"Cannot allocate enough memory for ring buffer", 2048);
599                        return -1;
600                }
601                calculate_buffers(req, fd, uridata, *max_order);
602                if (setsockopt(fd, 
603                                SOL_PACKET, 
604                                ring_type, 
605                                req, 
606                                sizeof(struct tpacket_req)) == -1) {
607                        if(errno == ENOMEM){
608                                (*max_order)--;
609                        } else {
610                                strncpy(error, "Error setting the ring buffer size", 2048);
611                                return -1;
612                        }
613
614                } else break;
615        }
616       
617        /* Map the ring buffer into userspace */
618        *ring_location = mmap(NULL, 
619                                        req->tp_block_size * req->tp_block_nr, 
620                                        PROT_READ | PROT_WRITE, 
621                                        MAP_SHARED, 
622                                        fd, 0);
623        if(*ring_location == MAP_FAILED){
624                strncpy(error, "Failed to map memory for ring buffer", 2048);
625                return -1;
626        }
627        return 0;
628}
629
630/**
631 * Converts a socket, either packet_mmap or standard raw socket into a
632 * fanout socket.
633 * NOTE: This means we can read from the socket with multiple queues,
634 * each must be setup (identically) and then this called upon them
635 *
636 * @return 0 success, -1 error
637 */
638static inline int socket_to_packet_fanout(int fd, 
639                                        uint16_t fanout_flags,
640                                        uint16_t fanout_group) {
641        int fanout_opt = ((int)fanout_flags << 16) | (int)fanout_group;
642        if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT,
643                        &fanout_opt, sizeof(fanout_opt)) == -1) {
644                return -1;
645        }
646        return 0;
647}
648
649static int linuxnative_ppause_input(libtrace_t *libtrace)
650{
651        int i;
652        int tot = libtrace->perpkt_thread_count;
653        printf("CAlling native pause packet\n");
654       
655        for (i = 0; i < tot; i++) {
656                close(FORMAT(libtrace->format_data)->per_thread[i].fd);
657        }
658       
659        free(FORMAT(libtrace->format_data)->per_thread);
660        FORMAT(libtrace->format_data)->per_thread = NULL;
661        return 0;
662}
663
664static int linuxring_start_input(libtrace_t *libtrace)
665{
666        char error[2048];
667
668        /* We set the socket up the same and then convert it to PACKET_MMAP */
669        if(linuxnative_start_input(libtrace) != 0)
670                return -1;
671
672        strncpy(error, "No known error", 2048);
673
674        /* Make it a packetmmap */
675        if(socket_to_packetmmap(libtrace->uridata, PACKET_RX_RING, 
676                        FORMAT(libtrace->format_data)->fd,
677                        &FORMAT(libtrace->format_data)->req, 
678                        &FORMAT(libtrace->format_data)->rx_ring,
679                        &FORMAT(libtrace->format_data)->max_order,
680                        error) != 0){
681                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Initialisation of packet MMAP failed: %s", error);
682                close(DATAOUT(libtrace)->fd);
683                free(libtrace->format_data);
684                libtrace->format_data = NULL;
685                return -1;
686        }
687
688        return 0;
689}
690
691static int linuxnative_pstart_input(libtrace_t *libtrace) {
692        int i = 0;
693        int tot = libtrace->perpkt_thread_count;
694        int iserror = 0;
695        // We store this here otherwise it will be leaked if the memory doesn't know
696        struct linux_per_thread_t *per_thread = NULL;
697       
698        if (!FORMAT(libtrace->format_data)->per_thread) {
699                //per_thread = calloc(tot, sizeof(struct linux_per_thread_t));
700                posix_memalign((void **)&per_thread, CACHE_LINE_SIZE, tot*sizeof(struct linux_per_thread_t));
701                FORMAT(libtrace->format_data)->per_thread = per_thread;
702        } else {
703                // Whats going on this might not work 100%
704                // We assume all sockets have been closed ;)
705                printf("Pause and then start called again lets hope that perpkt_thread_count hasn't changed\n");
706        }
707       
708        printf("Calling native pstart packet\n");
709        for (i = 0; i < tot; ++i)
710        {
711                if (FORMAT(libtrace->format_data)->format == TRACE_RT_DATA_LINUX_NATIVE) {
712                        if (linuxnative_start_input(libtrace) != 0) {
713                                iserror = 1;
714                                break;
715                        }
716                } else {
717                        // This must be ring
718                        if (linuxring_start_input(libtrace) != 0) {
719                                iserror = 1;
720                                break;
721                        }
722                }
723                if (socket_to_packet_fanout(FORMAT(libtrace->format_data)->fd, FORMAT(libtrace->format_data)->fanout_flags, FORMAT(libtrace->format_data)->fanout_group) != 0)
724                {
725                        iserror = 1;
726                        // Clean up here to keep consistent with every one else
727                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Converting the fd to a socket fanout failed");
728                        close(FORMAT(libtrace->format_data)->fd);
729                        free(libtrace->format_data);
730                        libtrace->format_data = NULL;
731                        break;
732                }
733                per_thread[i].fd = FORMAT(libtrace->format_data)->fd;
734                if (FORMAT(libtrace->format_data)->format == TRACE_RT_DATA_LINUX_RING) {
735                        per_thread[i].rxring_offset = FORMAT(libtrace->format_data)->rxring_offset;
736                        per_thread[i].rx_ring = FORMAT(libtrace->format_data)->rx_ring;
737                }
738        }
739       
740        // Roll back those that failed - by this point in time the format_data
741        // has been freed
742        if (iserror) {
743                for (i = i - 1; i >= 0; i--) {
744                        close(per_thread[i].fd);
745                }
746                free(per_thread);
747                per_thread = NULL;
748                return -1;
749        }
750       
751        return 0;
752}
753
754static int linux_pregister_thread(libtrace_t *libtrace, libtrace_thread_t *t, bool reading) {
755        fprintf(stderr, "registering thread %d!!\n", t->perpkt_num);
756    if (reading) {
757        if(t->type == THREAD_PERPKT) {
758            t->format_data = &FORMAT(libtrace->format_data)->per_thread[t->perpkt_num];
759        } else {
760            t->format_data = &FORMAT(libtrace->format_data)->per_thread[0];
761        }
762    }
763    return 0;
764}
765
766static int linuxnative_start_output(libtrace_out_t *libtrace)
767{
768        DATAOUT(libtrace)->fd = socket(PF_PACKET, SOCK_RAW, 0);
769        if (DATAOUT(libtrace)->fd==-1) {
770                free(DATAOUT(libtrace));
771                return -1;
772        }
773
774        return 0;
775}
776
777static int linuxring_start_output(libtrace_out_t *libtrace)
778{
779        char error[2048];       
780        /* We set the socket up the same and then convert it to PACKET_MMAP */
781        if(linuxnative_start_output(libtrace) != 0)
782                return -1;
783
784        /* Make it a packetmmap */
785        if(socket_to_packetmmap(libtrace->uridata, PACKET_TX_RING, 
786                        DATAOUT(libtrace)->fd,
787                        &DATAOUT(libtrace)->req, 
788                        &DATAOUT(libtrace)->tx_ring,
789                        &DATAOUT(libtrace)->max_order,
790                        error) != 0){
791                trace_set_err_out(libtrace, TRACE_ERR_INIT_FAILED, "Initialisation of packet MMAP failed: %s", error);
792                close(DATAOUT(libtrace)->fd);
793                free(libtrace->format_data);
794                libtrace->format_data = NULL;
795                return -1;
796        }
797       
798        DATAOUT(libtrace)->sock_hdr.sll_family = AF_PACKET;
799        DATAOUT(libtrace)->sock_hdr.sll_protocol = 0;
800        DATAOUT(libtrace)->sock_hdr.sll_ifindex = 
801                                        if_nametoindex(libtrace->uridata);
802        DATAOUT(libtrace)->sock_hdr.sll_hatype = 0;
803        DATAOUT(libtrace)->sock_hdr.sll_pkttype = 0;
804        DATAOUT(libtrace)->sock_hdr.sll_halen = 0;
805        DATAOUT(libtrace)->queue = 0;   
806
807        return 0;
808}
809
810static int linuxnative_pause_input(libtrace_t *libtrace)
811{
812        close(FORMAT(libtrace->format_data)->fd);
813        FORMAT(libtrace->format_data)->fd=-1;
814
815        return 0;
816}
817
818static int linuxring_pause_input(libtrace_t *libtrace)
819{
820        munmap(FORMAT(libtrace->format_data)->rx_ring, 
821                FORMAT(libtrace->format_data)->req.tp_block_size *
822                        FORMAT(libtrace->format_data)->req.tp_block_nr);
823        FORMAT(libtrace->format_data)->rx_ring = NULL;
824        return linuxnative_pause_input(libtrace);
825}
826
827static int linuxnative_fin_input(libtrace_t *libtrace) 
828{
829        if (libtrace->format_data) {
830                if (FORMAT(libtrace->format_data)->filter != NULL)
831                        free(FORMAT(libtrace->format_data)->filter);
832                free(libtrace->format_data);
833        }
834       
835        return 0;
836}
837
838static int linuxnative_fin_output(libtrace_out_t *libtrace)
839{
840        close(DATAOUT(libtrace)->fd);
841        DATAOUT(libtrace)->fd=-1;
842        free(libtrace->format_data);
843        return 0;
844}
845static int linuxring_fin_output(libtrace_out_t *libtrace)
846{
847        /* Make sure any remaining frames get sent */
848        sendto(DATAOUT(libtrace)->fd, 
849                NULL, 
850                0, 
851                0, 
852                (void *) &DATAOUT(libtrace)->sock_hdr, 
853                sizeof(DATAOUT(libtrace)->sock_hdr));
854
855        /* Unmap our data area */
856        munmap(DATAOUT(libtrace)->tx_ring,
857                DATAOUT(libtrace)->req.tp_block_size * 
858                        DATAOUT(libtrace)->req.tp_block_nr);
859
860        return linuxnative_fin_output(libtrace);
861}
862
863/* Compiles a libtrace BPF filter for use with a linux native socket */
864static int linuxnative_configure_bpf(libtrace_t *libtrace, 
865                libtrace_filter_t *filter) {
866#ifdef HAVE_LIBPCAP
867        struct ifreq ifr;
868        unsigned int arphrd;
869        libtrace_dlt_t dlt;
870        libtrace_filter_t *f;
871        int sock;
872        pcap_t *pcap;
873
874        /* Take a copy of the filter object as it was passed in */
875        f = (libtrace_filter_t *) malloc(sizeof(libtrace_filter_t));
876        memcpy(f, filter, sizeof(libtrace_filter_t));
877       
878        /* If we are passed a filter with "flag" set to zero, then we must
879         * compile the filterstring before continuing. This involves
880         * determining the linktype, passing the filterstring to libpcap to
881         * compile, and saving the result for trace_start() to push into the
882         * kernel.
883         * If flag is set to one, then the filter was probably generated using
884         * trace_create_filter_from_bytecode() and so we don't need to do
885         * anything (we've just copied it above).
886         */
887        if (f->flag == 0) {
888                sock = socket(PF_INET, SOCK_STREAM, 0);
889                memset(&ifr, 0, sizeof(struct ifreq));
890                strncpy(ifr.ifr_name, libtrace->uridata, IF_NAMESIZE);
891                if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {
892                        perror("Can't get HWADDR for interface");
893                        return -1;
894                }
895                close(sock);
896
897                arphrd = ifr.ifr_hwaddr.sa_family;
898                dlt = libtrace_to_pcap_dlt(arphrd_type_to_libtrace(arphrd));
899
900                pcap = pcap_open_dead(dlt, 
901                                FORMAT(libtrace->format_data)->snaplen);
902
903                if (pcap_compile(pcap, &f->filter, f->filterstring, 0, 0) == -1) {
904                        perror("PCAP failed to compile the filterstring");
905                        return -1;
906                }
907
908                pcap_close(pcap);
909               
910                /* Set the "flag" to indicate that the filterstring has been
911                 * compiled
912                 */
913                f->flag = 1;
914        }
915       
916        if (FORMAT(libtrace->format_data)->filter != NULL)
917                free(FORMAT(libtrace->format_data)->filter);
918       
919        FORMAT(libtrace->format_data)->filter = f;
920       
921        return 0;
922#else
923        return -1
924#endif
925}
926static int linuxnative_config_input(libtrace_t *libtrace,
927                trace_option_t option,
928                void *data)
929{
930        switch(option) {
931                case TRACE_OPTION_SNAPLEN:
932                        FORMAT(libtrace->format_data)->snaplen=*(int*)data;
933                        return 0;
934                case TRACE_OPTION_PROMISC:
935                        FORMAT(libtrace->format_data)->promisc=*(int*)data;
936                        return 0;
937                case TRACE_OPTION_FILTER:
938                        return linuxnative_configure_bpf(libtrace, 
939                                        (libtrace_filter_t *) data);
940                case TRACE_OPTION_META_FREQ:
941                        /* No meta-data for this format */
942                        break;
943                case TRACE_OPTION_EVENT_REALTIME:
944                        /* Live captures are always going to be in trace time */
945                        break;
946                /* Avoid default: so that future options will cause a warning
947                 * here to remind us to implement it, or flag it as
948                 * unimplementable
949                 */
950        }
951       
952        /* Don't set an error - trace_config will try to deal with the
953         * option and will set an error if it fails */
954        return -1;
955}
956#endif /* HAVE_NETPACKET_PACKET_H */
957
958
959static int linuxnative_pconfig_input(libtrace_t *libtrace,
960                trace_parallel_option_t option,
961                void *data)
962{
963        switch(option) {
964                case TRACE_OPTION_SET_HASHER:
965                        switch (*((enum hasher_types *)data)) {
966                                case HASHER_BALANCE:
967                                        // Do fanout
968                                        FORMAT(libtrace->format_data)->fanout_flags = PACKET_FANOUT_LB;
969                                        // Or we could balance to the CPU
970                                        return 0;
971                                case HASHER_BIDIRECTIONAL:
972                                case HASHER_UNIDIRECTIONAL:
973                                        FORMAT(libtrace->format_data)->fanout_flags = PACKET_FANOUT_HASH;
974                                        return 0;
975                                case HASHER_CUSTOM:
976                                case HASHER_HARDWARE:
977                                        return -1;
978                        }
979                        break;
980                /* Avoid default: so that future options will cause a warning
981                 * here to remind us to implement it, or flag it as
982                 * unimplementable
983                 */
984        }
985       
986        /* Don't set an error - trace_config will try to deal with the
987         * option and will set an error if it fails */
988        return -1;
989}
990
991
992static int linuxnative_prepare_packet(libtrace_t *libtrace UNUSED, 
993                libtrace_packet_t *packet, void *buffer, 
994                libtrace_rt_types_t rt_type, uint32_t flags) {
995
996        if (packet->buffer != buffer &&
997                        packet->buf_control == TRACE_CTRL_PACKET) {
998                free(packet->buffer);
999        }
1000
1001        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
1002                packet->buf_control = TRACE_CTRL_PACKET;
1003        } else
1004                packet->buf_control = TRACE_CTRL_EXTERNAL;
1005
1006
1007        packet->buffer = buffer;
1008        packet->header = buffer;
1009        packet->payload = (char *)buffer + 
1010                sizeof(struct libtrace_linuxnative_header);
1011        packet->type = rt_type;
1012
1013        /*
1014        if (libtrace->format_data == NULL) {
1015                if (linuxnative_init_input(libtrace))
1016                        return -1;
1017        }
1018        */
1019        return 0;
1020       
1021}
1022
1023static int linuxring_prepare_packet(libtrace_t *libtrace UNUSED, 
1024                libtrace_packet_t *packet, void *buffer, 
1025                libtrace_rt_types_t rt_type, uint32_t flags) {
1026
1027        if (packet->buffer != buffer &&
1028                        packet->buf_control == TRACE_CTRL_PACKET) {
1029                free(packet->buffer);
1030        }
1031
1032        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
1033                packet->buf_control = TRACE_CTRL_PACKET;
1034        } else
1035                packet->buf_control = TRACE_CTRL_EXTERNAL;
1036
1037
1038        packet->buffer = buffer;
1039        packet->header = buffer;
1040        packet->payload = (char *)buffer + 
1041                                        TP_TRACE_START(
1042                                        TO_TP_HDR(packet->header)->tp_mac, 
1043                                        TO_TP_HDR(packet->header)->tp_net, 
1044                                        TPACKET_HDRLEN);
1045        packet->type = rt_type;
1046
1047        /*
1048        if (libtrace->format_data == NULL) {
1049                if (linuxnative_init_input(libtrace))
1050                        return -1;
1051        }
1052        */
1053        return 0;
1054       
1055}
1056
1057#define LIBTRACE_MIN(a,b) ((a)<(b) ? (a) : (b))
1058
1059/* 20 isn't enough on x86_64 */
1060#define CMSG_BUF_SIZE 128
1061
1062#ifdef HAVE_NETPACKET_PACKET_H
1063libtrace_thread_t * get_thread_table(libtrace_t *libtrace) ;
1064inline static int linuxnative_read_packet_fd(libtrace_t *libtrace, libtrace_packet_t *packet, int fd, const int check_queue) 
1065{
1066        struct libtrace_linuxnative_header *hdr;
1067        struct msghdr msghdr;
1068        struct iovec iovec;
1069        unsigned char controlbuf[CMSG_BUF_SIZE];
1070        struct cmsghdr *cmsg;
1071        int snaplen;
1072
1073        uint32_t flags = 0;
1074       
1075        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
1076                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
1077                if (!packet->buffer) {
1078                        perror("Cannot allocate buffer");
1079                }
1080        }
1081
1082        flags |= TRACE_PREP_OWN_BUFFER;
1083       
1084        packet->type = TRACE_RT_DATA_LINUX_NATIVE;
1085
1086        hdr=(struct libtrace_linuxnative_header*)packet->buffer;
1087        snaplen=LIBTRACE_MIN(
1088                        (int)LIBTRACE_PACKET_BUFSIZE-(int)sizeof(*hdr),
1089                        (int)FORMAT(libtrace->format_data)->snaplen);
1090
1091        /* Prepare the msghdr and iovec for the kernel to write the
1092         * captured packet into. The msghdr will point to the part of our
1093         * buffer reserved for sll header, while the iovec will point at
1094         * the buffer following the sll header. */
1095
1096        msghdr.msg_name = &hdr->hdr;
1097        msghdr.msg_namelen = sizeof(struct sockaddr_ll);
1098
1099        msghdr.msg_iov = &iovec;
1100        msghdr.msg_iovlen = 1;
1101
1102        msghdr.msg_control = &controlbuf;
1103        msghdr.msg_controllen = CMSG_BUF_SIZE;
1104        msghdr.msg_flags = 0;
1105
1106        iovec.iov_base = (void*)(packet->buffer+sizeof(*hdr));
1107        iovec.iov_len = snaplen;
1108       
1109        if (check_queue) {
1110                // Check for a packet - TODO only Linux has MSG_DONTWAIT should use fctl O_NONBLOCK
1111                hdr->wirelen = recvmsg(fd, &msghdr, MSG_DONTWAIT);
1112                if ((int) hdr->wirelen == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
1113                        // Do message queue check or select
1114                        int ret;
1115                        fd_set rfds;
1116                        FD_ZERO(&rfds);
1117                        FD_SET(fd, &rfds);
1118                        FD_SET(get_thread_table(libtrace)->messages.pipefd[0], &rfds);
1119                        int largestfd = fd > get_thread_table(libtrace)->messages.pipefd[0] ? fd : get_thread_table(libtrace)->messages.pipefd[0];
1120                       
1121                        do {
1122                                ret = select(largestfd+1, &rfds, NULL, NULL, NULL);
1123                                if (ret == -1 && errno != EINTR)
1124                                        perror("Select() failed");
1125                        }
1126                        while (ret == -1);
1127                       
1128                        assert (ret == 1 || ret == 2); // No timeout 0 is not an option
1129                       
1130                        if (FD_ISSET(get_thread_table(libtrace)->messages.pipefd[0], &rfds)) {
1131                                // Not an error but check the message queue we have something
1132                                return -2;
1133                        }
1134                        // Otherwise we must have a packet
1135                        hdr->wirelen = recvmsg(fd, &msghdr, 0);
1136                }
1137        } else {
1138                hdr->wirelen = recvmsg(fd, &msghdr, 0);
1139        }
1140       
1141        if (hdr->wirelen==~0U) {
1142                trace_set_err(libtrace,errno,"recvmsg");
1143                return -1;
1144        }
1145
1146        hdr->caplen=LIBTRACE_MIN((unsigned int)snaplen,(unsigned int)hdr->wirelen);
1147
1148        /* Extract the timestamps from the msghdr and store them in our
1149         * linux native encapsulation, so that we can preserve the formatting
1150         * across multiple architectures */
1151
1152        for (cmsg = CMSG_FIRSTHDR(&msghdr);
1153                        cmsg != NULL;
1154                        cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
1155                if (cmsg->cmsg_level == SOL_SOCKET
1156                        && cmsg->cmsg_type == SO_TIMESTAMP
1157                        && cmsg->cmsg_len <= CMSG_LEN(sizeof(struct timeval))) {
1158                       
1159                        struct timeval *tv;
1160                        tv = (struct timeval *)CMSG_DATA(cmsg);
1161                       
1162                       
1163                        hdr->tv.tv_sec = tv->tv_sec;
1164                        hdr->tv.tv_usec = tv->tv_usec;
1165                        hdr->timestamptype = TS_TIMEVAL;
1166                        break;
1167                } 
1168#ifdef SO_TIMESTAMPNS
1169                else if (cmsg->cmsg_level == SOL_SOCKET
1170                        && cmsg->cmsg_type == SO_TIMESTAMPNS
1171                        && cmsg->cmsg_len <= CMSG_LEN(sizeof(struct timespec))) {
1172
1173                        struct timespec *tv;
1174                        tv = (struct timespec *)CMSG_DATA(cmsg);
1175
1176                        hdr->ts.tv_sec = tv->tv_sec;
1177                        hdr->ts.tv_nsec = tv->tv_nsec;
1178                        hdr->timestamptype = TS_TIMESPEC;
1179                        break;
1180                }
1181#endif
1182        }
1183
1184        /* Did we not get given a timestamp? Try to get one from the
1185         * file descriptor directly */
1186        if (cmsg == NULL) {
1187                struct timeval tv;
1188                if (ioctl(fd, SIOCGSTAMP,&tv)==0) {
1189                        hdr->tv.tv_sec = tv.tv_sec;
1190                        hdr->tv.tv_usec = tv.tv_usec;
1191                        hdr->timestamptype = TS_TIMEVAL;
1192                }
1193                else {
1194                        hdr->timestamptype = TS_NONE;
1195                }
1196        }
1197
1198        /* Buffer contains all of our packet (including our custom header) so
1199         * we just need to get prepare_packet to set all our packet pointers
1200         * appropriately */
1201       
1202        if (linuxnative_prepare_packet(libtrace, packet, packet->buffer,
1203                                packet->type, flags))
1204                return -1;
1205       
1206        return hdr->wirelen+sizeof(*hdr);
1207}
1208
1209static int linuxnative_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) 
1210{
1211        int fd = FORMAT(libtrace->format_data)->fd;
1212        return linuxnative_read_packet_fd(libtrace, packet, fd, 0);
1213}
1214
1215static int linuxnative_pread_packet(libtrace_t *libtrace, libtrace_thread_t *t, libtrace_packet_t *packet)
1216{
1217        int fd = FORMAT(libtrace->format_data)->fd;
1218        fprintf(stderr, "Thread number is #%d\n", t->perpkt_num);
1219        return linuxnative_read_packet_fd(libtrace, packet, fd, 1);
1220}
1221
1222#define LIBTRACE_BETWEEN(test,a,b) ((test) >= (a) && (test) < (b))
1223static int linuxring_get_capture_length(const libtrace_packet_t *packet);
1224static int linuxring_get_framing_length(const libtrace_packet_t *packet);
1225
1226/* Release a frame back to the kernel or free() if it's a malloc'd buffer
1227 */
1228inline static void ring_release_frame(libtrace_t *libtrace, libtrace_packet_t *packet){
1229        /* Free the old packet */
1230        if(packet->buffer == NULL)
1231                return;
1232
1233        if(packet->buf_control == TRACE_CTRL_PACKET){
1234                free(packet->buffer);
1235                packet->buffer = NULL;
1236        }
1237        if(packet->buf_control == TRACE_CTRL_EXTERNAL) {
1238                struct linux_format_data_t *ftd = FORMAT(libtrace->format_data);
1239               
1240                /* Check it's within our buffer first - consider the pause resume case it might have already been free'd lets hope we get another buffer */
1241                // For now let any one free anything
1242                /*if(LIBTRACE_BETWEEN((char *) packet->buffer,
1243                                (char *) ftd->rx_ring,
1244                                ftd->rx_ring
1245                                + ftd->req.tp_block_size * ftd->req.tp_block_nr)){*/
1246                        TO_TP_HDR(packet->buffer)->tp_status = 0;
1247                        packet->buffer = NULL;
1248                /*}*/
1249        }
1250}
1251
1252/**
1253 * Free any resources being kept for this packet, Note: libtrace
1254 * will ensure all fields are zeroed correctly.
1255 */
1256static void linuxring_fin_packet(libtrace_packet_t *packet)
1257{
1258        assert(packet->trace);
1259       
1260        // Started should always match the existence of the rx_ring
1261        assert(!!FORMAT(packet->trace->format_data)->rx_ring == !!packet->trace->started);
1262       
1263        // Our packets are always under our control
1264        assert(packet->buf_control == TRACE_CTRL_EXTERNAL);
1265       
1266        if (FORMAT(packet->trace->format_data)->rx_ring) // If we don't have a ring its already been destroyed or paused
1267                ring_release_frame(packet->trace, packet);
1268        else
1269                packet->buffer = NULL;
1270}
1271
1272inline static int linuxring_read_packet_fd(libtrace_t *libtrace, libtrace_packet_t *packet, int fd, int *rxring_offset, char *rx_ring, int message) {
1273
1274        struct tpacket2_hdr *header;
1275        int ret;
1276        unsigned int snaplen;
1277       
1278        ring_release_frame(libtrace, packet);
1279       
1280        packet->buf_control = TRACE_CTRL_EXTERNAL;
1281        packet->type = TRACE_RT_DATA_LINUX_RING;
1282       
1283        /* Fetch the current frame */
1284        header = ((void*) rx_ring) + *rxring_offset * FORMAT(libtrace->format_data)->req.tp_frame_size; // GET_CURRENT_BUFFER(libtrace);
1285        assert((((unsigned long) header) & (pagesize - 1)) == 0);
1286
1287        /* TP_STATUS_USER means that we can use the frame.
1288         * When a slot does not have this flag set, the frame is not
1289         * ready for consumption.
1290         */
1291        while (!(header->tp_status & TP_STATUS_USER)) {
1292                if (message) {
1293                        struct pollfd pollset[2];
1294                        pollset[0].fd = fd;
1295                        pollset[0].events = POLLIN;
1296                        pollset[0].revents = 0;
1297                        pollset[1].fd = libtrace_message_queue_get_fd(&get_thread_table(libtrace)->messages);
1298                        pollset[1].events = POLLIN;
1299                        pollset[1].revents = 0;
1300                        /* Wait for more data or a message*/
1301                        ret = poll(pollset, 2, -1);
1302                        if (ret < 0) {
1303                                if (errno != EINTR)
1304                                        trace_set_err(libtrace,errno,"poll()");
1305                                return -1;
1306                        }
1307                        // Check for a message otherwise loop
1308                        if (pollset[1].revents)
1309                                return -2;
1310                } else {
1311                        struct pollfd pollset;
1312                        pollset.fd = fd;
1313                        pollset.events = POLLIN;
1314                        pollset.revents = 0;
1315
1316                        /* Wait for more data or a message*/
1317                        ret = poll(&pollset, 1, -1);
1318                        if (ret < 0) {
1319                                if (errno != EINTR)
1320                                        trace_set_err(libtrace,errno,"poll()");
1321                                return -1;
1322                        }
1323                }
1324        }
1325
1326        packet->buffer = header;
1327
1328        /* If a snaplen was configured, automatically truncate the packet to
1329         * the desired length.
1330         */
1331        snaplen=LIBTRACE_MIN(
1332                        (int)LIBTRACE_PACKET_BUFSIZE-(int)sizeof(*header),
1333                        (int)FORMAT(libtrace->format_data)->snaplen);
1334       
1335        TO_TP_HDR(packet->buffer)->tp_snaplen = LIBTRACE_MIN((unsigned int)snaplen, TO_TP_HDR(packet->buffer)->tp_len);
1336
1337        /* Move to next buffer */
1338        (*rxring_offset)++;
1339        *rxring_offset %= FORMAT(libtrace->format_data)->req.tp_frame_nr;
1340
1341        /* We just need to get prepare_packet to set all our packet pointers
1342         * appropriately */
1343        if (linuxring_prepare_packet(libtrace, packet, packet->buffer,
1344                                packet->type, 0))
1345                return -1;
1346        return  linuxring_get_framing_length(packet) + 
1347                                linuxring_get_capture_length(packet);
1348
1349}
1350
1351static int linuxring_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
1352        int fd = FORMAT(libtrace->format_data)->fd;
1353        int *rxring_offset = &FORMAT(libtrace->format_data)->rxring_offset;
1354        char *rx_ring = FORMAT(libtrace->format_data)->rx_ring;
1355        return linuxring_read_packet_fd(libtrace, packet, fd, rxring_offset, rx_ring, 0);
1356}
1357
1358static int linuxring_pread_packet(libtrace_t *libtrace, libtrace_thread_t *t, libtrace_packet_t *packet) {
1359        fprintf(stderr, "Thread number is #%d\n", t->perpkt_num);
1360        int fd = PERPKT_FORMAT(t)->fd;
1361        int *rxring_offset = &PERPKT_FORMAT(t)->rxring_offset;
1362        char *rx_ring = PERPKT_FORMAT(t)->rx_ring;
1363        return linuxring_read_packet_fd(libtrace, packet, fd, rxring_offset, rx_ring, 1);
1364}
1365
1366/* Non-blocking read */
1367static libtrace_eventobj_t linuxring_event(libtrace_t *libtrace, libtrace_packet_t *packet) {
1368        struct tpacket2_hdr *header;
1369        libtrace_eventobj_t event = {0,0,0.0,0};
1370
1371        /* We must free the old packet, otherwise select() will instantly return
1372         */
1373        ring_release_frame(libtrace, packet);
1374
1375        /* Fetch the current frame */
1376        header = GET_CURRENT_BUFFER(libtrace);
1377        if(header->tp_status & TP_STATUS_USER){
1378                /* We have a frame waiting */
1379                event.size = linuxring_read_packet(libtrace, packet);
1380                event.type = TRACE_EVENT_PACKET;
1381        } else {
1382                /* Ok we don't have a packet waiting */
1383                event.type = TRACE_EVENT_IOWAIT;
1384                event.fd = FORMAT(libtrace->format_data)->fd;
1385        }
1386
1387        return event;
1388}
1389
1390
1391static int linuxnative_write_packet(libtrace_out_t *trace, 
1392                libtrace_packet_t *packet) 
1393{
1394        struct sockaddr_ll hdr;
1395        int ret = 0;
1396
1397        if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
1398                return 0;
1399
1400        hdr.sll_family = AF_PACKET;
1401        hdr.sll_protocol = 0;
1402        hdr.sll_ifindex = if_nametoindex(trace->uridata);
1403        hdr.sll_hatype = 0;
1404        hdr.sll_pkttype = 0;
1405        hdr.sll_halen = htons(6); /* FIXME */
1406        memcpy(hdr.sll_addr,packet->payload,(size_t)ntohs(hdr.sll_halen));
1407
1408        /* This is pretty easy, just send the payload using sendto() (after
1409         * setting up the sll header properly, of course) */
1410        ret = sendto(DATAOUT(trace)->fd,
1411                        packet->payload,
1412                        trace_get_capture_length(packet),
1413                        0,
1414                        (struct sockaddr*)&hdr, (socklen_t)sizeof(hdr));
1415
1416        if (ret < 0) {
1417                trace_set_err_out(trace, errno, "sendto failed");
1418        }
1419
1420        return ret;
1421}
1422
1423static int linuxring_write_packet(libtrace_out_t *trace, 
1424                libtrace_packet_t *packet)
1425{
1426        struct tpacket2_hdr *header;
1427        struct pollfd pollset;
1428        struct socket_addr;
1429        int ret; 
1430        unsigned max_size;
1431        void * off;
1432
1433        if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
1434                return 0;
1435
1436        max_size = DATAOUT(trace)->req.tp_frame_size - 
1437                 - TPACKET_HDRLEN + sizeof(struct sockaddr_ll);
1438
1439        header = (void *) DATAOUT(trace)->tx_ring + 
1440        (DATAOUT(trace)->txring_offset * DATAOUT(trace)->req.tp_frame_size);
1441
1442        while(header->tp_status != TP_STATUS_AVAILABLE){
1443                /* if none available: wait on more data */
1444                pollset.fd = DATAOUT(trace)->fd;
1445                pollset.events = POLLOUT;
1446                pollset.revents = 0;
1447                ret = poll(&pollset, 1, 1000);
1448                if (ret < 0 && errno != EINTR) {
1449                        perror("poll");
1450                        return -1;
1451                }
1452                if(ret == 0) 
1453                        /* Timeout something has gone wrong - maybe the queue is
1454                         * to large so try issue another send command
1455                         */
1456                        ret = sendto(DATAOUT(trace)->fd, 
1457                                NULL, 
1458                                0, 
1459                                0, 
1460                                (void *) &DATAOUT(trace)->sock_hdr, 
1461                                sizeof(DATAOUT(trace)->sock_hdr));
1462                        if (ret < 0) {
1463                                trace_set_err_out(trace, errno, 
1464                                                "sendto after timeout failed");
1465                                return -1;
1466                        }
1467        }
1468       
1469        header->tp_len = trace_get_capture_length(packet);
1470
1471        /* We cannot write the whole packet so just write part of it */
1472        if (header->tp_len > max_size)
1473                header->tp_len = max_size;
1474
1475        /* Fill packet - no sockaddr_ll in header when writing to the TX_RING */
1476        off = ((void *) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll));
1477        memcpy(off, 
1478                (char *) packet->payload, 
1479                header->tp_len);
1480       
1481        /* 'Send it' and increase ring pointer to the next frame */
1482        header->tp_status = TP_STATUS_SEND_REQUEST;
1483        DATAOUT(trace)->txring_offset = (DATAOUT(trace)->txring_offset + 1) % 
1484                                                DATAOUT(trace)->req.tp_frame_nr;
1485
1486        /* Notify kernel there are frames to send */
1487        DATAOUT(trace)->queue ++;
1488        DATAOUT(trace)->queue %= TX_MAX_QUEUE;
1489        if(DATAOUT(trace)->queue == 0){
1490                ret = sendto(DATAOUT(trace)->fd, 
1491                                NULL, 
1492                                0, 
1493                                MSG_DONTWAIT, 
1494                                (void *) &DATAOUT(trace)->sock_hdr, 
1495                                sizeof(DATAOUT(trace)->sock_hdr));
1496                if (ret < 0) {
1497                        trace_set_err_out(trace, errno, "sendto failed");
1498                        return -1;
1499                }
1500        }
1501        return header->tp_len;
1502
1503}
1504#endif /* HAVE_NETPACKET_PACKET_H */
1505
1506static inline libtrace_linktype_t get_libtrace_link_type(uint16_t linktype){
1507        /* Convert the ARPHRD type into an appropriate libtrace link type */
1508        switch (linktype) {
1509                case LIBTRACE_ARPHRD_ETHER:
1510                case LIBTRACE_ARPHRD_LOOPBACK:
1511                        return TRACE_TYPE_ETH;
1512                case LIBTRACE_ARPHRD_PPP:
1513                        return TRACE_TYPE_NONE;
1514                case LIBTRACE_ARPHRD_IEEE80211_RADIOTAP:
1515                        return TRACE_TYPE_80211_RADIO;
1516                case LIBTRACE_ARPHRD_IEEE80211:
1517                        return TRACE_TYPE_80211;
1518                case LIBTRACE_ARPHRD_SIT:
1519                case LIBTRACE_ARPHRD_NONE:
1520                        return TRACE_TYPE_NONE;
1521                default: /* shrug, beyond me! */
1522                        printf("unknown Linux ARPHRD type 0x%04x\n",linktype);
1523                        return (libtrace_linktype_t)~0U;
1524        }
1525}
1526static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
1527        uint16_t linktype=(((struct libtrace_linuxnative_header*)(packet->buffer))
1528                                ->hdr.sll_hatype);
1529        return get_libtrace_link_type(linktype);
1530}
1531static libtrace_linktype_t linuxring_get_link_type(const struct libtrace_packet_t *packet) {
1532        uint16_t linktype= GET_SOCKADDR_HDR(packet->buffer)->sll_hatype;
1533        return get_libtrace_link_type(linktype);
1534}
1535
1536static inline libtrace_direction_t get_libtrace_direction(uint8_t pkttype){
1537        switch (pkttype) {
1538                case PACKET_OUTGOING:
1539                case PACKET_LOOPBACK:
1540                        return TRACE_DIR_OUTGOING;
1541                case PACKET_OTHERHOST:
1542                        return TRACE_DIR_OTHER;
1543                default:
1544                        return TRACE_DIR_INCOMING;
1545        }
1546}
1547static libtrace_direction_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
1548        return get_libtrace_direction(((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype);
1549}
1550static libtrace_direction_t linuxring_get_direction(const struct libtrace_packet_t *packet) {
1551        return get_libtrace_direction(GET_SOCKADDR_HDR(packet->buffer)->sll_pkttype);
1552}
1553
1554static libtrace_direction_t set_direction(struct sockaddr_ll * skadr, libtrace_direction_t direction){
1555        switch (direction) {
1556                case TRACE_DIR_OUTGOING:
1557                        skadr->sll_pkttype = PACKET_OUTGOING;
1558                        return TRACE_DIR_OUTGOING;
1559                case TRACE_DIR_INCOMING:
1560                        skadr->sll_pkttype = PACKET_HOST;
1561                        return TRACE_DIR_INCOMING;
1562                case TRACE_DIR_OTHER:
1563                        skadr->sll_pkttype = PACKET_OTHERHOST;
1564                        return TRACE_DIR_OTHER;
1565                default:
1566                        return -1;
1567        }
1568}
1569static libtrace_direction_t linuxnative_set_direction(
1570                libtrace_packet_t *packet,
1571                libtrace_direction_t direction) {
1572        return set_direction(&((struct libtrace_linuxnative_header*)(packet->buffer))->hdr, direction);
1573}
1574static libtrace_direction_t linuxring_set_direction(
1575                libtrace_packet_t *packet,
1576                libtrace_direction_t direction) {
1577        return set_direction(GET_SOCKADDR_HDR(packet->buffer), direction);
1578}
1579
1580static struct timespec linuxnative_get_timespec(const libtrace_packet_t *packet) 
1581{
1582        struct libtrace_linuxnative_header *hdr = 
1583                (struct libtrace_linuxnative_header*) packet->buffer;
1584        /* We have to upconvert from timeval to timespec */
1585        if (hdr->timestamptype == TS_TIMEVAL) {
1586                struct timespec ts;
1587                ts.tv_sec = hdr->tv.tv_sec;
1588                ts.tv_nsec = hdr->tv.tv_usec*1000;
1589                return ts;
1590        }
1591        else {
1592                struct timespec ts;
1593                ts.tv_sec = hdr->ts.tv_sec;
1594                ts.tv_nsec = hdr->ts.tv_nsec;
1595                return ts;
1596        }
1597}
1598static struct timespec linuxring_get_timespec(const libtrace_packet_t *packet) 
1599{
1600        struct timespec ts;
1601        ts.tv_sec = TO_TP_HDR(packet->buffer)->tp_sec;
1602        ts.tv_nsec = TO_TP_HDR(packet->buffer)->tp_nsec;
1603        return ts;
1604}
1605
1606
1607static struct timeval linuxnative_get_timeval(const libtrace_packet_t *packet) 
1608{
1609        struct libtrace_linuxnative_header *hdr = 
1610                (struct libtrace_linuxnative_header*) packet->buffer;
1611        /* We have to downconvert from timespec to timeval */
1612        if (hdr->timestamptype == TS_TIMESPEC) {
1613                struct timeval tv;
1614                tv.tv_sec = hdr->ts.tv_sec;
1615                tv.tv_usec = hdr->ts.tv_nsec/1000;
1616                return tv;
1617        }
1618        else {
1619                struct timeval tv;
1620                tv.tv_sec = hdr->tv.tv_sec;
1621                tv.tv_usec = hdr->tv.tv_usec;
1622                return tv;
1623        }
1624}
1625static struct timeval linuxring_get_timeval(const libtrace_packet_t *packet) 
1626{
1627        struct timeval tv;
1628        tv.tv_sec = TO_TP_HDR(packet->buffer)->tp_sec;
1629        tv.tv_usec = TO_TP_HDR(packet->buffer)->tp_nsec / 1000;
1630        return tv;
1631}
1632
1633static int linuxnative_get_capture_length(const libtrace_packet_t *packet)
1634{
1635        return ((struct libtrace_linuxnative_header*)(packet->buffer))->caplen;
1636}
1637
1638static int linuxring_get_capture_length(const libtrace_packet_t *packet)
1639{
1640        return TO_TP_HDR(packet->buffer)->tp_snaplen;
1641}
1642
1643static int linuxnative_get_wire_length(const libtrace_packet_t *packet) 
1644{
1645
1646        int wirelen = ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
1647
1648        /* Include the missing FCS */
1649        if (trace_get_link_type(packet) == TRACE_TYPE_ETH)
1650                wirelen += 4;
1651
1652        return wirelen;
1653}
1654
1655static int linuxring_get_wire_length(const libtrace_packet_t *packet) 
1656{
1657        int wirelen = TO_TP_HDR(packet->buffer)->tp_len;
1658
1659        /* Include the missing FCS */
1660        if (trace_get_link_type(packet) == TRACE_TYPE_ETH)
1661                wirelen += 4;
1662
1663        return wirelen;
1664}
1665
1666static int linuxnative_get_framing_length(UNUSED
1667                const libtrace_packet_t *packet) 
1668{
1669        return sizeof(struct libtrace_linuxnative_header);
1670}
1671
1672static int linuxring_get_framing_length(const libtrace_packet_t *packet)
1673{       
1674        /*
1675         * Need to make frame_length + capture_length = complete capture length
1676         * so include alligment whitespace. So reverse calculate from packet.
1677         */
1678        return (char *) packet->payload - (char *) packet->buffer;
1679}
1680
1681static size_t linuxnative_set_capture_length(libtrace_packet_t *packet, 
1682                size_t size) {
1683
1684        struct libtrace_linuxnative_header *linux_hdr = NULL;
1685        assert(packet);
1686        if (size > trace_get_capture_length(packet)) {
1687                /* We should avoid making a packet larger */
1688                return trace_get_capture_length(packet);
1689        }
1690       
1691        /* Reset the cached capture length */
1692        packet->capture_length = -1;
1693
1694        linux_hdr = (struct libtrace_linuxnative_header *)packet->header;
1695        linux_hdr->caplen = size;
1696        return trace_get_capture_length(packet);
1697}
1698
1699static size_t linuxring_set_capture_length(libtrace_packet_t *packet, 
1700                size_t size) {
1701        assert(packet);
1702        if (size > trace_get_capture_length(packet)) {
1703                /* We should avoid making a packet larger */
1704                return trace_get_capture_length(packet);
1705        }
1706       
1707        /* Reset the cached capture length */
1708        packet->capture_length = -1;
1709
1710        TO_TP_HDR(packet->buffer)->tp_snaplen = size;
1711
1712        return trace_get_capture_length(packet);
1713}
1714
1715static int linuxnative_get_fd(const libtrace_t *trace) {
1716        if (trace->format_data == NULL)
1717                return -1;
1718        return FORMAT(trace->format_data)->fd;
1719}
1720
1721/* Linux doesn't keep track how many packets were seen before filtering
1722 * so we can't tell how many packets were filtered.  Bugger.  So annoying.
1723 *
1724 * Since we tell libtrace that we do support filtering, if we don't declare
1725 * this here as failing, libtrace will happily report for us that it didn't
1726 * filter any packets, so don't lie -- return that we don't know.
1727 */
1728static uint64_t linuxnative_get_filtered_packets(libtrace_t *trace UNUSED) {
1729        return UINT64_MAX;
1730}
1731
1732/* Number of packets that passed filtering */
1733static uint64_t linuxnative_get_captured_packets(libtrace_t *trace) {
1734        if (trace->format_data == NULL)
1735                return UINT64_MAX;
1736        if (FORMAT(trace->format_data)->fd == -1) {
1737                /* This is probably a 'dead' trace so obviously we can't query
1738                 * the socket for capture counts, can we? */
1739                return UINT64_MAX;
1740        }
1741
1742#ifdef HAVE_NETPACKET_PACKET_H 
1743        if ((FORMAT(trace->format_data)->stats_valid & 1) 
1744                        || FORMAT(trace->format_data)->stats_valid == 0) {
1745                socklen_t len = sizeof(FORMAT(trace->format_data)->stats);
1746                getsockopt(FORMAT(trace->format_data)->fd, 
1747                                SOL_PACKET,
1748                                PACKET_STATISTICS,
1749                                &FORMAT(trace->format_data)->stats,
1750                                &len);
1751                FORMAT(trace->format_data)->stats_valid |= 1;
1752        }
1753
1754        return FORMAT(trace->format_data)->stats.tp_packets;
1755#else
1756        return UINT64_MAX;
1757#endif
1758}
1759
1760/* Number of packets that got past filtering and were then dropped because
1761 * of lack of space
1762 */
1763static uint64_t linuxnative_get_dropped_packets(libtrace_t *trace) {
1764        if (trace->format_data == NULL)
1765                return UINT64_MAX;
1766        if (FORMAT(trace->format_data)->fd == -1) {
1767                /* This is probably a 'dead' trace so obviously we can't query
1768                 * the socket for drop counts, can we? */
1769                return UINT64_MAX;
1770        }
1771       
1772#ifdef HAVE_NETPACKET_PACKET_H 
1773        if ((FORMAT(trace->format_data)->stats_valid & 2)
1774                        || (FORMAT(trace->format_data)->stats_valid==0)) {
1775                socklen_t len = sizeof(FORMAT(trace->format_data)->stats);
1776                getsockopt(FORMAT(trace->format_data)->fd, 
1777                                SOL_PACKET,
1778                                PACKET_STATISTICS,
1779                                &FORMAT(trace->format_data)->stats,
1780                                &len);
1781                FORMAT(trace->format_data)->stats_valid |= 2;
1782        }
1783
1784        return FORMAT(trace->format_data)->stats.tp_drops;
1785#else
1786        return UINT64_MAX;
1787#endif
1788}
1789
1790#ifdef HAVE_NETPACKET_PACKET_H
1791static void linuxnative_help(void) {
1792        printf("linuxnative format module: $Revision: 1793 $\n");
1793        printf("Supported input URIs:\n");
1794        printf("\tint:eth0\n");
1795        printf("\n");
1796        printf("Supported output URIs:\n");
1797        printf("\tint:eth0\n");
1798        printf("\n");
1799        return;
1800}
1801
1802static void linuxring_help(void) {
1803        printf("linuxring format module: $Revision: 1793 $\n");
1804        printf("Supported input URIs:\n");
1805        printf("\tring:eth0\n");
1806        printf("\n");
1807        printf("Supported output URIs:\n");
1808        printf("\tring:eth0\n");
1809        printf("\n");
1810        return;
1811}
1812
1813static struct libtrace_format_t linuxnative = {
1814        "int",
1815        "$Id$",
1816        TRACE_FORMAT_LINUX_NATIVE,
1817        linuxnative_probe_filename,     /* probe filename */
1818        NULL,                           /* probe magic */
1819        linuxnative_init_input,         /* init_input */
1820        linuxnative_config_input,       /* config_input */
1821        linuxnative_start_input,        /* start_input */
1822        linuxnative_pause_input,        /* pause_input */
1823        linuxnative_init_output,        /* init_output */
1824        NULL,                           /* config_output */
1825        linuxnative_start_output,       /* start_ouput */
1826        linuxnative_fin_input,          /* fin_input */
1827        linuxnative_fin_output,         /* fin_output */
1828        linuxnative_read_packet,        /* read_packet */
1829        linuxnative_prepare_packet,     /* prepare_packet */
1830        NULL,                           /* fin_packet */
1831        linuxnative_write_packet,       /* write_packet */
1832        linuxnative_get_link_type,      /* get_link_type */
1833        linuxnative_get_direction,      /* get_direction */
1834        linuxnative_set_direction,      /* set_direction */
1835        NULL,                           /* get_erf_timestamp */
1836        linuxnative_get_timeval,        /* get_timeval */
1837        linuxnative_get_timespec,       /* get_timespec */
1838        NULL,                           /* get_seconds */
1839        NULL,                           /* seek_erf */
1840        NULL,                           /* seek_timeval */
1841        NULL,                           /* seek_seconds */
1842        linuxnative_get_capture_length, /* get_capture_length */
1843        linuxnative_get_wire_length,    /* get_wire_length */
1844        linuxnative_get_framing_length, /* get_framing_length */
1845        linuxnative_set_capture_length, /* set_capture_length */
1846        NULL,                           /* get_received_packets */
1847        linuxnative_get_filtered_packets,/* get_filtered_packets */
1848        linuxnative_get_dropped_packets,/* get_dropped_packets */
1849        linuxnative_get_captured_packets,/* get_captured_packets */
1850        linuxnative_get_fd,             /* get_fd */
1851        trace_event_device,             /* trace_event */
1852        linuxnative_help,               /* help */
1853        NULL,                                   /* next pointer */
1854        {true, -1},              /* Live, no thread limit */
1855        linuxnative_pstart_input,                       /* pstart_input */
1856        linuxnative_pread_packet,                       /* pread_packet */
1857        linuxnative_ppause_input,                       /* ppause */
1858        linuxnative_fin_input,                          /* p_fin */
1859        linuxnative_pconfig_input,                      /* pconfig input */
1860        linux_pregister_thread,
1861        NULL
1862};
1863
1864static struct libtrace_format_t linuxring = {
1865        "ring",
1866        "$Id$",
1867        TRACE_FORMAT_LINUX_RING,
1868        linuxnative_probe_filename,     /* probe filename */
1869        NULL,                           /* probe magic */
1870        linuxring_init_input,           /* init_input */
1871        linuxnative_config_input,       /* config_input */
1872        linuxring_start_input,  /* start_input */
1873        linuxring_pause_input,  /* pause_input */
1874        linuxring_init_output,  /* init_output */
1875        NULL,                           /* config_output */
1876        linuxring_start_output, /* start_ouput */
1877        linuxnative_fin_input,          /* fin_input */
1878        linuxring_fin_output,           /* fin_output */
1879        linuxring_read_packet,  /* read_packet */
1880        linuxring_prepare_packet,       /* prepare_packet */
1881        linuxring_fin_packet,                           /* fin_packet */
1882        linuxring_write_packet, /* write_packet */
1883        linuxring_get_link_type,        /* get_link_type */
1884        linuxring_get_direction,        /* get_direction */
1885        linuxring_set_direction,        /* set_direction */
1886        NULL,                           /* get_erf_timestamp */
1887        linuxring_get_timeval,  /* get_timeval */
1888        linuxring_get_timespec, /* get_timespec */
1889        NULL,                           /* get_seconds */
1890        NULL,                           /* seek_erf */
1891        NULL,                           /* seek_timeval */
1892        NULL,                           /* seek_seconds */
1893        linuxring_get_capture_length,   /* get_capture_length */
1894        linuxring_get_wire_length,      /* get_wire_length */
1895        linuxring_get_framing_length,   /* get_framing_length */
1896        linuxring_set_capture_length,   /* set_capture_length */
1897        NULL,                           /* get_received_packets */
1898        linuxnative_get_filtered_packets,/* get_filtered_packets */
1899        linuxnative_get_dropped_packets,/* get_dropped_packets */
1900        linuxnative_get_captured_packets,/* get_captured_packets */
1901        linuxnative_get_fd,             /* get_fd */
1902        linuxring_event,                /* trace_event */
1903        linuxring_help,         /* help */
1904        NULL,                           /* next pointer */
1905        {true, -1},              /* Live, no thread limit */
1906        linuxnative_pstart_input,                       /* pstart_input */
1907        linuxring_pread_packet,                 /* pread_packet */
1908        linuxnative_ppause_input,                       /* ppause */
1909        linuxnative_fin_input,                          /* p_fin */
1910        linuxnative_pconfig_input,
1911        linux_pregister_thread,
1912        NULL
1913};
1914#else
1915static void linuxnative_help(void) {
1916        printf("linuxnative format module: $Revision: 1793 $\n");
1917        printf("Not supported on this host\n");
1918}
1919static void linuxring_help(void) {
1920        printf("linuxring format module: $Revision: 1793 $\n");
1921        printf("Not supported on this host\n");
1922}
1923
1924static struct libtrace_format_t linuxnative = {
1925        "int",
1926        "$Id$",
1927        TRACE_FORMAT_LINUX_NATIVE,
1928        NULL,                           /* probe filename */
1929        NULL,                           /* probe magic */
1930        NULL,                           /* init_input */
1931        NULL,                           /* config_input */
1932        NULL,                           /* start_input */
1933        NULL,                           /* pause_input */
1934        NULL,                           /* init_output */
1935        NULL,                           /* config_output */
1936        NULL,                           /* start_ouput */
1937        NULL,                           /* fin_input */
1938        NULL,                           /* fin_output */
1939        NULL,                           /* read_packet */
1940        linuxnative_prepare_packet,     /* prepare_packet */
1941        NULL,                           /* fin_packet */
1942        NULL,                           /* write_packet */
1943        linuxnative_get_link_type,      /* get_link_type */
1944        linuxnative_get_direction,      /* get_direction */
1945        linuxnative_set_direction,      /* set_direction */
1946        NULL,                           /* get_erf_timestamp */
1947        linuxnative_get_timeval,        /* get_timeval */
1948        linuxnative_get_timespec,       /* get_timespec */
1949        NULL,                           /* get_seconds */
1950        NULL,                           /* seek_erf */
1951        NULL,                           /* seek_timeval */
1952        NULL,                           /* seek_seconds */
1953        linuxnative_get_capture_length, /* get_capture_length */
1954        linuxnative_get_wire_length,    /* get_wire_length */
1955        linuxnative_get_framing_length, /* get_framing_length */
1956        linuxnative_set_capture_length, /* set_capture_length */
1957        NULL,                           /* get_received_packets */
1958        linuxnative_get_filtered_packets,/* get_filtered_packets */
1959        linuxnative_get_dropped_packets,/* get_dropped_packets */
1960        linuxnative_get_captured_packets,/* get_captured_packets */
1961        linuxnative_get_fd,             /* get_fd */
1962        trace_event_device,             /* trace_event */
1963        linuxnative_help,               /* help */
1964        NULL,                   /* next pointer */
1965        NON_PARALLEL(true)
1966};
1967
1968static struct libtrace_format_t linuxring = {
1969        "ring",
1970        "$Id$",
1971        TRACE_FORMAT_LINUX_RING,
1972        NULL,                           /* probe filename */
1973        NULL,                           /* probe magic */
1974        NULL,                           /* init_input */
1975        NULL,                           /* config_input */
1976        NULL,                           /* start_input */
1977        NULL,                           /* pause_input */
1978        NULL,                           /* init_output */
1979        NULL,                           /* config_output */
1980        NULL,                           /* start_ouput */
1981        NULL,                           /* fin_input */
1982        NULL,                           /* fin_output */
1983        NULL,                           /* read_packet */
1984        linuxring_prepare_packet,       /* prepare_packet */
1985        NULL,                           /* fin_packet */
1986        NULL,                           /* write_packet */
1987        linuxring_get_link_type,        /* get_link_type */
1988        linuxring_get_direction,        /* get_direction */
1989        linuxring_set_direction,        /* set_direction */
1990        NULL,                           /* get_erf_timestamp */
1991        linuxring_get_timeval,          /* get_timeval */
1992        linuxring_get_timespec,         /* get_timespec */
1993        NULL,                           /* get_seconds */
1994        NULL,                           /* seek_erf */
1995        NULL,                           /* seek_timeval */
1996        NULL,                           /* seek_seconds */
1997        linuxring_get_capture_length,   /* get_capture_length */
1998        linuxring_get_wire_length,      /* get_wire_length */
1999        linuxring_get_framing_length,   /* get_framing_length */
2000        linuxring_set_capture_length,   /* set_capture_length */
2001        NULL,                           /* get_received_packets */
2002        linuxnative_get_filtered_packets,/* get_filtered_packets */
2003        linuxnative_get_dropped_packets,/* get_dropped_packets */
2004        linuxnative_get_captured_packets,/* get_captured_packets */
2005        linuxnative_get_fd,             /* get_fd */
2006        NULL,                           /* trace_event */
2007        linuxring_help,                 /* help */
2008        NULL,                   /* next pointer */
2009        NON_PARALLEL(true)
2010};
2011
2012#endif /* HAVE_NETPACKET_PACKET_H */
2013
2014
2015void linuxnative_constructor(void) {
2016        /* TODO: once we're happy with ring:, it would be a good idea to
2017         * swap the order of these calls so that ring: is preferred over
2018         * int: if the user just gives an interface name as an input without
2019         * explicitly choosing a format.
2020         */
2021        register_format(&linuxnative);
2022        register_format(&linuxring);
2023}
Note: See TracBrowser for help on using the repository browser.