source: lib/format_linux.c @ d994324

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

Refactor the combining step to allow user defined functions here.

Remove the old trace_get_results, now instead simply provide a reporter function which gets called as soon as results are ready.
The combiner function used determines the order of these results and when they are released etc.
The combiner function can be selected from those built-in or a custom version can be defined results are provided when ready.
Quickly hacked the parallel tests to work with this update, these are still a bit messy.

Also some fixes some compile warnings.

  • Property mode set to 100644
File size: 61.8 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 Linux 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 Linux 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 | MSG_TRUNC);
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, MSG_TRUNC);
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 = PERPKT_FORMAT(t)->fd;
1218        //fprintf(stderr, "Thread number is #%d fd=%d\n", t->perpkt_num, PERPKT_FORMAT(t)->fd);
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
1259        if (packet->buffer == NULL)
1260                return;
1261        assert(packet->trace);
1262       
1263        // Started should always match the existence of the rx_ring
1264        assert(!!FORMAT(packet->trace->format_data)->rx_ring == !!packet->trace->started);
1265       
1266        // Our packets are always under our control
1267        assert(packet->buf_control == TRACE_CTRL_EXTERNAL);
1268       
1269        if (FORMAT(packet->trace->format_data)->rx_ring) // If we don't have a ring its already been destroyed or paused
1270                ring_release_frame(packet->trace, packet);
1271        else
1272                packet->buffer = NULL;
1273}
1274
1275inline static int linuxring_read_packet_fd(libtrace_t *libtrace, libtrace_packet_t *packet, int fd, int *rxring_offset, char *rx_ring, int message) {
1276
1277        struct tpacket2_hdr *header;
1278        int ret;
1279        unsigned int snaplen;
1280       
1281        ring_release_frame(libtrace, packet);
1282       
1283        packet->buf_control = TRACE_CTRL_EXTERNAL;
1284        packet->type = TRACE_RT_DATA_LINUX_RING;
1285       
1286        /* Fetch the current frame */
1287        header = ((void*) rx_ring) + *rxring_offset * FORMAT(libtrace->format_data)->req.tp_frame_size; // GET_CURRENT_BUFFER(libtrace);
1288        assert((((unsigned long) header) & (pagesize - 1)) == 0);
1289
1290        /* TP_STATUS_USER means that we can use the frame.
1291         * When a slot does not have this flag set, the frame is not
1292         * ready for consumption.
1293         */
1294        while (!(header->tp_status & TP_STATUS_USER)) {
1295                if (message) {
1296                        struct pollfd pollset[2];
1297                        pollset[0].fd = fd;
1298                        pollset[0].events = POLLIN;
1299                        pollset[0].revents = 0;
1300                        pollset[1].fd = libtrace_message_queue_get_fd(&get_thread_table(libtrace)->messages);
1301                        pollset[1].events = POLLIN;
1302                        pollset[1].revents = 0;
1303                        /* Wait for more data or a message*/
1304                        ret = poll(pollset, 2, -1);
1305                        if (ret < 0) {
1306                                if (errno != EINTR)
1307                                        trace_set_err(libtrace,errno,"poll()");
1308                                return -1;
1309                        }
1310                        // Check for a message otherwise loop
1311                        if (pollset[1].revents)
1312                                return -2;
1313                } else {
1314                        struct pollfd pollset;
1315                        pollset.fd = fd;
1316                        pollset.events = POLLIN;
1317                        pollset.revents = 0;
1318
1319                        /* Wait for more data or a message*/
1320                        ret = poll(&pollset, 1, -1);
1321                        if (ret < 0) {
1322                                if (errno != EINTR)
1323                                        trace_set_err(libtrace,errno,"poll()");
1324                                return -1;
1325                        }
1326                }
1327        }
1328
1329        packet->buffer = header;
1330
1331        /* If a snaplen was configured, automatically truncate the packet to
1332         * the desired length.
1333         */
1334        snaplen=LIBTRACE_MIN(
1335                        (int)LIBTRACE_PACKET_BUFSIZE-(int)sizeof(*header),
1336                        (int)FORMAT(libtrace->format_data)->snaplen);
1337       
1338        TO_TP_HDR(packet->buffer)->tp_snaplen = LIBTRACE_MIN((unsigned int)snaplen, TO_TP_HDR(packet->buffer)->tp_len);
1339
1340        /* Move to next buffer */
1341        (*rxring_offset)++;
1342        *rxring_offset %= FORMAT(libtrace->format_data)->req.tp_frame_nr;
1343
1344        /* We just need to get prepare_packet to set all our packet pointers
1345         * appropriately */
1346        if (linuxring_prepare_packet(libtrace, packet, packet->buffer,
1347                                packet->type, 0))
1348                return -1;
1349        return  linuxring_get_framing_length(packet) + 
1350                                linuxring_get_capture_length(packet);
1351
1352}
1353
1354static int linuxring_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
1355        int fd = FORMAT(libtrace->format_data)->fd;
1356        int *rxring_offset = &FORMAT(libtrace->format_data)->rxring_offset;
1357        char *rx_ring = FORMAT(libtrace->format_data)->rx_ring;
1358        return linuxring_read_packet_fd(libtrace, packet, fd, rxring_offset, rx_ring, 0);
1359}
1360
1361static int linuxring_pread_packet(libtrace_t *libtrace, libtrace_thread_t *t, libtrace_packet_t *packet) {
1362        //fprintf(stderr, "Thread number is #%d\n", t->perpkt_num);
1363        int fd = PERPKT_FORMAT(t)->fd;
1364        int *rxring_offset = &PERPKT_FORMAT(t)->rxring_offset;
1365        char *rx_ring = PERPKT_FORMAT(t)->rx_ring;
1366        return linuxring_read_packet_fd(libtrace, packet, fd, rxring_offset, rx_ring, 1);
1367}
1368
1369/* Non-blocking read */
1370static libtrace_eventobj_t linuxring_event(libtrace_t *libtrace, libtrace_packet_t *packet) {
1371        struct tpacket2_hdr *header;
1372        libtrace_eventobj_t event = {0,0,0.0,0};
1373
1374        /* We must free the old packet, otherwise select() will instantly return
1375         */
1376        ring_release_frame(libtrace, packet);
1377
1378        /* Fetch the current frame */
1379        header = GET_CURRENT_BUFFER(libtrace);
1380        if(header->tp_status & TP_STATUS_USER){
1381                /* We have a frame waiting */
1382                event.size = linuxring_read_packet(libtrace, packet);
1383                event.type = TRACE_EVENT_PACKET;
1384        } else {
1385                /* Ok we don't have a packet waiting */
1386                event.type = TRACE_EVENT_IOWAIT;
1387                event.fd = FORMAT(libtrace->format_data)->fd;
1388        }
1389
1390        return event;
1391}
1392
1393
1394static int linuxnative_write_packet(libtrace_out_t *trace, 
1395                libtrace_packet_t *packet) 
1396{
1397        struct sockaddr_ll hdr;
1398        int ret = 0;
1399
1400        if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
1401                return 0;
1402
1403        hdr.sll_family = AF_PACKET;
1404        hdr.sll_protocol = 0;
1405        hdr.sll_ifindex = if_nametoindex(trace->uridata);
1406        hdr.sll_hatype = 0;
1407        hdr.sll_pkttype = 0;
1408        hdr.sll_halen = htons(6); /* FIXME */
1409        memcpy(hdr.sll_addr,packet->payload,(size_t)ntohs(hdr.sll_halen));
1410
1411        /* This is pretty easy, just send the payload using sendto() (after
1412         * setting up the sll header properly, of course) */
1413        ret = sendto(DATAOUT(trace)->fd,
1414                        packet->payload,
1415                        trace_get_capture_length(packet),
1416                        0,
1417                        (struct sockaddr*)&hdr, (socklen_t)sizeof(hdr));
1418
1419        if (ret < 0) {
1420                trace_set_err_out(trace, errno, "sendto failed");
1421        }
1422
1423        return ret;
1424}
1425
1426static int linuxring_write_packet(libtrace_out_t *trace, 
1427                libtrace_packet_t *packet)
1428{
1429        struct tpacket2_hdr *header;
1430        struct pollfd pollset;
1431        struct socket_addr;
1432        int ret; 
1433        unsigned max_size;
1434        void * off;
1435
1436        if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
1437                return 0;
1438
1439        max_size = DATAOUT(trace)->req.tp_frame_size - 
1440                 - TPACKET_HDRLEN + sizeof(struct sockaddr_ll);
1441
1442        header = (void *) DATAOUT(trace)->tx_ring + 
1443        (DATAOUT(trace)->txring_offset * DATAOUT(trace)->req.tp_frame_size);
1444
1445        while(header->tp_status != TP_STATUS_AVAILABLE){
1446                /* if none available: wait on more data */
1447                pollset.fd = DATAOUT(trace)->fd;
1448                pollset.events = POLLOUT;
1449                pollset.revents = 0;
1450                ret = poll(&pollset, 1, 1000);
1451                if (ret < 0 && errno != EINTR) {
1452                        perror("poll");
1453                        return -1;
1454                }
1455                if(ret == 0) 
1456                        /* Timeout something has gone wrong - maybe the queue is
1457                         * to large so try issue another send command
1458                         */
1459                        ret = sendto(DATAOUT(trace)->fd, 
1460                                NULL, 
1461                                0, 
1462                                0, 
1463                                (void *) &DATAOUT(trace)->sock_hdr, 
1464                                sizeof(DATAOUT(trace)->sock_hdr));
1465                        if (ret < 0) {
1466                                trace_set_err_out(trace, errno, 
1467                                                "sendto after timeout failed");
1468                                return -1;
1469                        }
1470        }
1471       
1472        header->tp_len = trace_get_capture_length(packet);
1473
1474        /* We cannot write the whole packet so just write part of it */
1475        if (header->tp_len > max_size)
1476                header->tp_len = max_size;
1477
1478        /* Fill packet - no sockaddr_ll in header when writing to the TX_RING */
1479        off = ((void *) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll));
1480        memcpy(off, 
1481                (char *) packet->payload, 
1482                header->tp_len);
1483       
1484        /* 'Send it' and increase ring pointer to the next frame */
1485        header->tp_status = TP_STATUS_SEND_REQUEST;
1486        DATAOUT(trace)->txring_offset = (DATAOUT(trace)->txring_offset + 1) % 
1487                                                DATAOUT(trace)->req.tp_frame_nr;
1488
1489        /* Notify kernel there are frames to send */
1490        DATAOUT(trace)->queue ++;
1491        DATAOUT(trace)->queue %= TX_MAX_QUEUE;
1492        if(DATAOUT(trace)->queue == 0){
1493                ret = sendto(DATAOUT(trace)->fd, 
1494                                NULL, 
1495                                0, 
1496                                MSG_DONTWAIT, 
1497                                (void *) &DATAOUT(trace)->sock_hdr, 
1498                                sizeof(DATAOUT(trace)->sock_hdr));
1499                if (ret < 0) {
1500                        trace_set_err_out(trace, errno, "sendto failed");
1501                        return -1;
1502                }
1503        }
1504        return header->tp_len;
1505
1506}
1507#endif /* HAVE_NETPACKET_PACKET_H */
1508
1509static inline libtrace_linktype_t get_libtrace_link_type(uint16_t linktype){
1510        /* Convert the ARPHRD type into an appropriate libtrace link type */
1511        switch (linktype) {
1512                case LIBTRACE_ARPHRD_ETHER:
1513                case LIBTRACE_ARPHRD_LOOPBACK:
1514                        return TRACE_TYPE_ETH;
1515                case LIBTRACE_ARPHRD_PPP:
1516                        return TRACE_TYPE_NONE;
1517                case LIBTRACE_ARPHRD_IEEE80211_RADIOTAP:
1518                        return TRACE_TYPE_80211_RADIO;
1519                case LIBTRACE_ARPHRD_IEEE80211:
1520                        return TRACE_TYPE_80211;
1521                case LIBTRACE_ARPHRD_SIT:
1522                case LIBTRACE_ARPHRD_NONE:
1523                        return TRACE_TYPE_NONE;
1524                default: /* shrug, beyond me! */
1525                        printf("unknown Linux ARPHRD type 0x%04x\n",linktype);
1526                        return (libtrace_linktype_t)~0U;
1527        }
1528}
1529static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
1530        uint16_t linktype=(((struct libtrace_linuxnative_header*)(packet->buffer))
1531                                ->hdr.sll_hatype);
1532        return get_libtrace_link_type(linktype);
1533}
1534static libtrace_linktype_t linuxring_get_link_type(const struct libtrace_packet_t *packet) {
1535        uint16_t linktype= GET_SOCKADDR_HDR(packet->buffer)->sll_hatype;
1536        return get_libtrace_link_type(linktype);
1537}
1538
1539static inline libtrace_direction_t get_libtrace_direction(uint8_t pkttype){
1540        switch (pkttype) {
1541                case PACKET_OUTGOING:
1542                case PACKET_LOOPBACK:
1543                        return TRACE_DIR_OUTGOING;
1544                case PACKET_OTHERHOST:
1545                        return TRACE_DIR_OTHER;
1546                default:
1547                        return TRACE_DIR_INCOMING;
1548        }
1549}
1550static libtrace_direction_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
1551        return get_libtrace_direction(((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype);
1552}
1553static libtrace_direction_t linuxring_get_direction(const struct libtrace_packet_t *packet) {
1554        return get_libtrace_direction(GET_SOCKADDR_HDR(packet->buffer)->sll_pkttype);
1555}
1556
1557static libtrace_direction_t set_direction(struct sockaddr_ll * skadr, libtrace_direction_t direction){
1558        switch (direction) {
1559                case TRACE_DIR_OUTGOING:
1560                        skadr->sll_pkttype = PACKET_OUTGOING;
1561                        return TRACE_DIR_OUTGOING;
1562                case TRACE_DIR_INCOMING:
1563                        skadr->sll_pkttype = PACKET_HOST;
1564                        return TRACE_DIR_INCOMING;
1565                case TRACE_DIR_OTHER:
1566                        skadr->sll_pkttype = PACKET_OTHERHOST;
1567                        return TRACE_DIR_OTHER;
1568                default:
1569                        return -1;
1570        }
1571}
1572static libtrace_direction_t linuxnative_set_direction(
1573                libtrace_packet_t *packet,
1574                libtrace_direction_t direction) {
1575        return set_direction(&((struct libtrace_linuxnative_header*)(packet->buffer))->hdr, direction);
1576}
1577static libtrace_direction_t linuxring_set_direction(
1578                libtrace_packet_t *packet,
1579                libtrace_direction_t direction) {
1580        return set_direction(GET_SOCKADDR_HDR(packet->buffer), direction);
1581}
1582
1583static struct timespec linuxnative_get_timespec(const libtrace_packet_t *packet) 
1584{
1585        struct libtrace_linuxnative_header *hdr = 
1586                (struct libtrace_linuxnative_header*) packet->buffer;
1587        /* We have to upconvert from timeval to timespec */
1588        if (hdr->timestamptype == TS_TIMEVAL) {
1589                struct timespec ts;
1590                ts.tv_sec = hdr->tv.tv_sec;
1591                ts.tv_nsec = hdr->tv.tv_usec*1000;
1592                return ts;
1593        }
1594        else {
1595                struct timespec ts;
1596                ts.tv_sec = hdr->ts.tv_sec;
1597                ts.tv_nsec = hdr->ts.tv_nsec;
1598                return ts;
1599        }
1600}
1601static struct timespec linuxring_get_timespec(const libtrace_packet_t *packet) 
1602{
1603        struct timespec ts;
1604        ts.tv_sec = TO_TP_HDR(packet->buffer)->tp_sec;
1605        ts.tv_nsec = TO_TP_HDR(packet->buffer)->tp_nsec;
1606        return ts;
1607}
1608
1609
1610static struct timeval linuxnative_get_timeval(const libtrace_packet_t *packet) 
1611{
1612        struct libtrace_linuxnative_header *hdr = 
1613                (struct libtrace_linuxnative_header*) packet->buffer;
1614        /* We have to downconvert from timespec to timeval */
1615        if (hdr->timestamptype == TS_TIMESPEC) {
1616                struct timeval tv;
1617                tv.tv_sec = hdr->ts.tv_sec;
1618                tv.tv_usec = hdr->ts.tv_nsec/1000;
1619                return tv;
1620        }
1621        else {
1622                struct timeval tv;
1623                tv.tv_sec = hdr->tv.tv_sec;
1624                tv.tv_usec = hdr->tv.tv_usec;
1625                return tv;
1626        }
1627}
1628static struct timeval linuxring_get_timeval(const libtrace_packet_t *packet) 
1629{
1630        struct timeval tv;
1631        tv.tv_sec = TO_TP_HDR(packet->buffer)->tp_sec;
1632        tv.tv_usec = TO_TP_HDR(packet->buffer)->tp_nsec / 1000;
1633        return tv;
1634}
1635
1636static int linuxnative_get_capture_length(const libtrace_packet_t *packet)
1637{
1638        return ((struct libtrace_linuxnative_header*)(packet->buffer))->caplen;
1639}
1640
1641static int linuxring_get_capture_length(const libtrace_packet_t *packet)
1642{
1643        return TO_TP_HDR(packet->buffer)->tp_snaplen;
1644}
1645
1646static int linuxnative_get_wire_length(const libtrace_packet_t *packet) 
1647{
1648
1649        int wirelen = ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
1650
1651        /* Include the missing FCS */
1652        if (trace_get_link_type(packet) == TRACE_TYPE_ETH)
1653                wirelen += 4;
1654
1655        return wirelen;
1656}
1657
1658static int linuxring_get_wire_length(const libtrace_packet_t *packet) 
1659{
1660        int wirelen = TO_TP_HDR(packet->buffer)->tp_len;
1661
1662        /* Include the missing FCS */
1663        if (trace_get_link_type(packet) == TRACE_TYPE_ETH)
1664                wirelen += 4;
1665
1666        return wirelen;
1667}
1668
1669static int linuxnative_get_framing_length(UNUSED
1670                const libtrace_packet_t *packet) 
1671{
1672        return sizeof(struct libtrace_linuxnative_header);
1673}
1674
1675static int linuxring_get_framing_length(const libtrace_packet_t *packet)
1676{       
1677        /*
1678         * Need to make frame_length + capture_length = complete capture length
1679         * so include alligment whitespace. So reverse calculate from packet.
1680         */
1681        return (char *) packet->payload - (char *) packet->buffer;
1682}
1683
1684static size_t linuxnative_set_capture_length(libtrace_packet_t *packet, 
1685                size_t size) {
1686
1687        struct libtrace_linuxnative_header *linux_hdr = NULL;
1688        assert(packet);
1689        if (size > trace_get_capture_length(packet)) {
1690                /* We should avoid making a packet larger */
1691                return trace_get_capture_length(packet);
1692        }
1693       
1694        /* Reset the cached capture length */
1695        packet->capture_length = -1;
1696
1697        linux_hdr = (struct libtrace_linuxnative_header *)packet->header;
1698        linux_hdr->caplen = size;
1699        return trace_get_capture_length(packet);
1700}
1701
1702static size_t linuxring_set_capture_length(libtrace_packet_t *packet, 
1703                size_t size) {
1704        assert(packet);
1705        if (size > trace_get_capture_length(packet)) {
1706                /* We should avoid making a packet larger */
1707                return trace_get_capture_length(packet);
1708        }
1709       
1710        /* Reset the cached capture length */
1711        packet->capture_length = -1;
1712
1713        TO_TP_HDR(packet->buffer)->tp_snaplen = size;
1714
1715        return trace_get_capture_length(packet);
1716}
1717
1718static int linuxnative_get_fd(const libtrace_t *trace) {
1719        if (trace->format_data == NULL)
1720                return -1;
1721        return FORMAT(trace->format_data)->fd;
1722}
1723
1724/* Linux doesn't keep track how many packets were seen before filtering
1725 * so we can't tell how many packets were filtered.  Bugger.  So annoying.
1726 *
1727 * Since we tell libtrace that we do support filtering, if we don't declare
1728 * this here as failing, libtrace will happily report for us that it didn't
1729 * filter any packets, so don't lie -- return that we don't know.
1730 */
1731static uint64_t linuxnative_get_filtered_packets(libtrace_t *trace UNUSED) {
1732        return UINT64_MAX;
1733}
1734
1735/* Number of packets that passed filtering */
1736static uint64_t linuxnative_get_captured_packets(libtrace_t *trace) {
1737        struct tpacket_stats stats;
1738
1739        if (trace->format_data == NULL)
1740                return UINT64_MAX;
1741        if (FORMAT(trace->format_data)->fd == -1) {
1742                /* This is probably a 'dead' trace so obviously we can't query
1743                 * the socket for capture counts, can we? */
1744                return UINT64_MAX;
1745        }
1746
1747#ifdef HAVE_NETPACKET_PACKET_H
1748
1749        if ((FORMAT(trace->format_data)->stats_valid & 1)
1750                || FORMAT(trace->format_data)->stats_valid == 0) {
1751                if (FORMAT(trace->format_data)->per_thread) {
1752                        int i;
1753                        FORMAT(trace->format_data)->stats.tp_drops = 0;
1754                        FORMAT(trace->format_data)->stats.tp_packets = 0;
1755                        for (i = 0; i < trace->perpkt_thread_count; ++i) {
1756                                socklen_t len = sizeof(stats);
1757                                getsockopt(FORMAT(trace->format_data)->per_thread[i].fd,
1758                                           SOL_PACKET,
1759                                           PACKET_STATISTICS,
1760                                           &stats,
1761                                           &len);
1762                                FORMAT(trace->format_data)->stats.tp_drops += stats.tp_drops;
1763                                FORMAT(trace->format_data)->stats.tp_packets += stats.tp_packets;
1764                        }
1765                        FORMAT(trace->format_data)->stats_valid |= 1;
1766                } else {
1767                        socklen_t len = sizeof(FORMAT(trace->format_data)->stats);
1768                        getsockopt(FORMAT(trace->format_data)->fd,
1769                                   SOL_PACKET,
1770                                   PACKET_STATISTICS,
1771                                   &FORMAT(trace->format_data)->stats,
1772                                   &len);
1773                        FORMAT(trace->format_data)->stats_valid |= 1;
1774                }
1775        }
1776
1777        return FORMAT(trace->format_data)->stats.tp_packets;
1778#else
1779        return UINT64_MAX;
1780#endif
1781}
1782
1783/* Number of packets that got past filtering and were then dropped because
1784 * of lack of space
1785 */
1786static uint64_t linuxnative_get_dropped_packets(libtrace_t *trace) {
1787        struct tpacket_stats stats;
1788        if (trace->format_data == NULL)
1789                return UINT64_MAX;
1790        if (FORMAT(trace->format_data)->fd == -1) {
1791                /* This is probably a 'dead' trace so obviously we can't query
1792                 * the socket for drop counts, can we? */
1793                return UINT64_MAX;
1794        }
1795
1796#ifdef HAVE_NETPACKET_PACKET_H 
1797        if ((FORMAT(trace->format_data)->stats_valid & 2)
1798                || (FORMAT(trace->format_data)->stats_valid==0)) {
1799                if (FORMAT(trace->format_data)->per_thread) {
1800                        int i;
1801                        FORMAT(trace->format_data)->stats.tp_drops = 0;
1802                        FORMAT(trace->format_data)->stats.tp_packets = 0;
1803                        for (i = 0; i < trace->perpkt_thread_count; ++i) {
1804                                socklen_t len = sizeof(stats);
1805                                getsockopt(FORMAT(trace->format_data)->per_thread[i].fd,
1806                                           SOL_PACKET,
1807                                           PACKET_STATISTICS,
1808                                           &stats,
1809                                           &len);
1810                                FORMAT(trace->format_data)->stats.tp_drops += stats.tp_drops;
1811                                FORMAT(trace->format_data)->stats.tp_packets += stats.tp_packets;
1812                        }
1813                        FORMAT(trace->format_data)->stats_valid |= 2;
1814                } else {
1815                        socklen_t len = sizeof(FORMAT(trace->format_data)->stats);
1816                        getsockopt(FORMAT(trace->format_data)->fd,
1817                                   SOL_PACKET,
1818                                   PACKET_STATISTICS,
1819                                   &FORMAT(trace->format_data)->stats,
1820                                   &len);
1821                        FORMAT(trace->format_data)->stats_valid |= 2;
1822                }
1823        }
1824
1825        return FORMAT(trace->format_data)->stats.tp_drops;
1826#else
1827        return UINT64_MAX;
1828#endif
1829}
1830
1831#ifdef HAVE_NETPACKET_PACKET_H
1832static void linuxnative_help(void) {
1833        printf("linuxnative format module: $Revision: 1793 $\n");
1834        printf("Supported input URIs:\n");
1835        printf("\tint:eth0\n");
1836        printf("\n");
1837        printf("Supported output URIs:\n");
1838        printf("\tint:eth0\n");
1839        printf("\n");
1840        return;
1841}
1842
1843static void linuxring_help(void) {
1844        printf("linuxring format module: $Revision: 1793 $\n");
1845        printf("Supported input URIs:\n");
1846        printf("\tring:eth0\n");
1847        printf("\n");
1848        printf("Supported output URIs:\n");
1849        printf("\tring:eth0\n");
1850        printf("\n");
1851        return;
1852}
1853
1854static struct libtrace_format_t linuxnative = {
1855        "int",
1856        "$Id$",
1857        TRACE_FORMAT_LINUX_NATIVE,
1858        linuxnative_probe_filename,     /* probe filename */
1859        NULL,                           /* probe magic */
1860        linuxnative_init_input,         /* init_input */
1861        linuxnative_config_input,       /* config_input */
1862        linuxnative_start_input,        /* start_input */
1863        linuxnative_pause_input,        /* pause_input */
1864        linuxnative_init_output,        /* init_output */
1865        NULL,                           /* config_output */
1866        linuxnative_start_output,       /* start_ouput */
1867        linuxnative_fin_input,          /* fin_input */
1868        linuxnative_fin_output,         /* fin_output */
1869        linuxnative_read_packet,        /* read_packet */
1870        linuxnative_prepare_packet,     /* prepare_packet */
1871        NULL,                           /* fin_packet */
1872        linuxnative_write_packet,       /* write_packet */
1873        linuxnative_get_link_type,      /* get_link_type */
1874        linuxnative_get_direction,      /* get_direction */
1875        linuxnative_set_direction,      /* set_direction */
1876        NULL,                           /* get_erf_timestamp */
1877        linuxnative_get_timeval,        /* get_timeval */
1878        linuxnative_get_timespec,       /* get_timespec */
1879        NULL,                           /* get_seconds */
1880        NULL,                           /* seek_erf */
1881        NULL,                           /* seek_timeval */
1882        NULL,                           /* seek_seconds */
1883        linuxnative_get_capture_length, /* get_capture_length */
1884        linuxnative_get_wire_length,    /* get_wire_length */
1885        linuxnative_get_framing_length, /* get_framing_length */
1886        linuxnative_set_capture_length, /* set_capture_length */
1887        NULL,                           /* get_received_packets */
1888        linuxnative_get_filtered_packets,/* get_filtered_packets */
1889        linuxnative_get_dropped_packets,/* get_dropped_packets */
1890        linuxnative_get_captured_packets,/* get_captured_packets */
1891        linuxnative_get_fd,             /* get_fd */
1892        trace_event_device,             /* trace_event */
1893        linuxnative_help,               /* help */
1894        NULL,                                   /* next pointer */
1895        {true, -1},              /* Live, no thread limit */
1896        linuxnative_pstart_input,                       /* pstart_input */
1897        linuxnative_pread_packet,                       /* pread_packet */
1898        linuxnative_ppause_input,                       /* ppause */
1899        linuxnative_fin_input,                          /* p_fin */
1900        linuxnative_pconfig_input,                      /* pconfig input */
1901        linux_pregister_thread,
1902        NULL
1903};
1904
1905static struct libtrace_format_t linuxring = {
1906        "ring",
1907        "$Id$",
1908        TRACE_FORMAT_LINUX_RING,
1909        linuxnative_probe_filename,     /* probe filename */
1910        NULL,                           /* probe magic */
1911        linuxring_init_input,           /* init_input */
1912        linuxnative_config_input,       /* config_input */
1913        linuxring_start_input,  /* start_input */
1914        linuxring_pause_input,  /* pause_input */
1915        linuxring_init_output,  /* init_output */
1916        NULL,                           /* config_output */
1917        linuxring_start_output, /* start_ouput */
1918        linuxnative_fin_input,          /* fin_input */
1919        linuxring_fin_output,           /* fin_output */
1920        linuxring_read_packet,  /* read_packet */
1921        linuxring_prepare_packet,       /* prepare_packet */
1922        linuxring_fin_packet,                           /* fin_packet */
1923        linuxring_write_packet, /* write_packet */
1924        linuxring_get_link_type,        /* get_link_type */
1925        linuxring_get_direction,        /* get_direction */
1926        linuxring_set_direction,        /* set_direction */
1927        NULL,                           /* get_erf_timestamp */
1928        linuxring_get_timeval,  /* get_timeval */
1929        linuxring_get_timespec, /* get_timespec */
1930        NULL,                           /* get_seconds */
1931        NULL,                           /* seek_erf */
1932        NULL,                           /* seek_timeval */
1933        NULL,                           /* seek_seconds */
1934        linuxring_get_capture_length,   /* get_capture_length */
1935        linuxring_get_wire_length,      /* get_wire_length */
1936        linuxring_get_framing_length,   /* get_framing_length */
1937        linuxring_set_capture_length,   /* set_capture_length */
1938        NULL,                           /* get_received_packets */
1939        linuxnative_get_filtered_packets,/* get_filtered_packets */
1940        linuxnative_get_dropped_packets,/* get_dropped_packets */
1941        linuxnative_get_captured_packets,/* get_captured_packets */
1942        linuxnative_get_fd,             /* get_fd */
1943        linuxring_event,                /* trace_event */
1944        linuxring_help,         /* help */
1945        NULL,                           /* next pointer */
1946        {true, -1},              /* Live, no thread limit */
1947        linuxnative_pstart_input,                       /* pstart_input */
1948        linuxring_pread_packet,                 /* pread_packet */
1949        linuxnative_ppause_input,                       /* ppause */
1950        linuxnative_fin_input,                          /* p_fin */
1951        linuxnative_pconfig_input,
1952        linux_pregister_thread,
1953        NULL
1954};
1955#else
1956static void linuxnative_help(void) {
1957        printf("linuxnative format module: $Revision: 1793 $\n");
1958        printf("Not supported on this host\n");
1959}
1960static void linuxring_help(void) {
1961        printf("linuxring format module: $Revision: 1793 $\n");
1962        printf("Not supported on this host\n");
1963}
1964
1965static struct libtrace_format_t linuxnative = {
1966        "int",
1967        "$Id$",
1968        TRACE_FORMAT_LINUX_NATIVE,
1969        NULL,                           /* probe filename */
1970        NULL,                           /* probe magic */
1971        NULL,                           /* init_input */
1972        NULL,                           /* config_input */
1973        NULL,                           /* start_input */
1974        NULL,                           /* pause_input */
1975        NULL,                           /* init_output */
1976        NULL,                           /* config_output */
1977        NULL,                           /* start_ouput */
1978        NULL,                           /* fin_input */
1979        NULL,                           /* fin_output */
1980        NULL,                           /* read_packet */
1981        linuxnative_prepare_packet,     /* prepare_packet */
1982        NULL,                           /* fin_packet */
1983        NULL,                           /* write_packet */
1984        linuxnative_get_link_type,      /* get_link_type */
1985        linuxnative_get_direction,      /* get_direction */
1986        linuxnative_set_direction,      /* set_direction */
1987        NULL,                           /* get_erf_timestamp */
1988        linuxnative_get_timeval,        /* get_timeval */
1989        linuxnative_get_timespec,       /* get_timespec */
1990        NULL,                           /* get_seconds */
1991        NULL,                           /* seek_erf */
1992        NULL,                           /* seek_timeval */
1993        NULL,                           /* seek_seconds */
1994        linuxnative_get_capture_length, /* get_capture_length */
1995        linuxnative_get_wire_length,    /* get_wire_length */
1996        linuxnative_get_framing_length, /* get_framing_length */
1997        linuxnative_set_capture_length, /* set_capture_length */
1998        NULL,                           /* get_received_packets */
1999        linuxnative_get_filtered_packets,/* get_filtered_packets */
2000        linuxnative_get_dropped_packets,/* get_dropped_packets */
2001        linuxnative_get_captured_packets,/* get_captured_packets */
2002        linuxnative_get_fd,             /* get_fd */
2003        trace_event_device,             /* trace_event */
2004        linuxnative_help,               /* help */
2005        NULL,                   /* next pointer */
2006        NON_PARALLEL(true)
2007};
2008
2009static struct libtrace_format_t linuxring = {
2010        "ring",
2011        "$Id$",
2012        TRACE_FORMAT_LINUX_RING,
2013        NULL,                           /* probe filename */
2014        NULL,                           /* probe magic */
2015        NULL,                           /* init_input */
2016        NULL,                           /* config_input */
2017        NULL,                           /* start_input */
2018        NULL,                           /* pause_input */
2019        NULL,                           /* init_output */
2020        NULL,                           /* config_output */
2021        NULL,                           /* start_ouput */
2022        NULL,                           /* fin_input */
2023        NULL,                           /* fin_output */
2024        NULL,                           /* read_packet */
2025        linuxring_prepare_packet,       /* prepare_packet */
2026        NULL,                           /* fin_packet */
2027        NULL,                           /* write_packet */
2028        linuxring_get_link_type,        /* get_link_type */
2029        linuxring_get_direction,        /* get_direction */
2030        linuxring_set_direction,        /* set_direction */
2031        NULL,                           /* get_erf_timestamp */
2032        linuxring_get_timeval,          /* get_timeval */
2033        linuxring_get_timespec,         /* get_timespec */
2034        NULL,                           /* get_seconds */
2035        NULL,                           /* seek_erf */
2036        NULL,                           /* seek_timeval */
2037        NULL,                           /* seek_seconds */
2038        linuxring_get_capture_length,   /* get_capture_length */
2039        linuxring_get_wire_length,      /* get_wire_length */
2040        linuxring_get_framing_length,   /* get_framing_length */
2041        linuxring_set_capture_length,   /* set_capture_length */
2042        NULL,                           /* get_received_packets */
2043        linuxnative_get_filtered_packets,/* get_filtered_packets */
2044        linuxnative_get_dropped_packets,/* get_dropped_packets */
2045        linuxnative_get_captured_packets,/* get_captured_packets */
2046        linuxnative_get_fd,             /* get_fd */
2047        NULL,                           /* trace_event */
2048        linuxring_help,                 /* help */
2049        NULL,                   /* next pointer */
2050        NON_PARALLEL(true)
2051};
2052
2053#endif /* HAVE_NETPACKET_PACKET_H */
2054
2055
2056void linuxnative_constructor(void) {
2057        /* TODO: once we're happy with ring:, it would be a good idea to
2058         * swap the order of these calls so that ring: is preferred over
2059         * int: if the user just gives an interface name as an input without
2060         * explicitly choosing a format.
2061         */
2062        register_format(&linuxnative);
2063        register_format(&linuxring);
2064}
Note: See TracBrowser for help on using the repository browser.