source: lib/format_linux.c @ 8af0d01

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

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

Conflicts:

lib/Makefile.am
lib/libtrace_int.h

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