source: lib/format_linux.c @ fac8c46

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

Tidies up the pausing so that it now works as expected and a trace can easily be paused and restarted.
Ensures that packets will not be lost if pause is called on a file, any queued packets will be read (a message is sent allowing the user to drop these packets if they are unwanted).
Differentiates packets from other results in the queues to the reducer/reporter and makes a copy of the packets in result queues when pausing

  • this is needed to ensure that bad memory isn't referenced if a zero-copy trace is paused by closing sockets/associated data like in the case of ring:.

Fixed up the re-starting of traces which hadn't been finished to account for different configurations.
Adds a 'state' to libtrace to handle the state of parallel traces, rather than hacking around the existing 'started' boolean. Also provides two levels of checks for consistency if the trace is using existing that are checking started.

Various other bug fixes and tidy ups.

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