source: lib/trace.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@…>, 7 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: 57.8 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
5 * New Zealand.
6 *
7 * Authors: Daniel Lawson
8 *          Perry Lorier
9 *          Shane Alcock
10 *         
11 * All rights reserved.
12 *
13 * This code has been developed by the University of Waikato WAND
14 * research group. For further information please see http://www.wand.net.nz/
15 *
16 * libtrace is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * libtrace is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with libtrace; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 *
30 * $Id$
31 *
32 */
33
34
35#define _GNU_SOURCE
36#include "common.h"
37#include "config.h"
38#include <assert.h>
39#include <errno.h>
40#include <fcntl.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <sys/stat.h>
45#include <sys/types.h>
46#ifndef WIN32
47#include <sys/socket.h>
48#endif
49#include <stdarg.h>
50#include <sys/param.h>
51
52#ifdef HAVE_LIMITS_H
53#  include <limits.h>
54#endif
55
56#ifdef HAVE_SYS_LIMITS_H
57#  include <sys/limits.h>
58#endif
59
60#ifdef HAVE_NET_IF_ARP_H
61#  include <net/if_arp.h>
62#endif
63
64#ifdef HAVE_NET_IF_H
65#  include <net/if.h>
66#endif
67
68#ifdef HAVE_NETINET_IN_H
69#  include <netinet/in.h>
70#endif
71
72#ifdef HAVE_NET_ETHERNET_H
73#  include <net/ethernet.h>
74#endif
75
76#ifdef HAVE_NETINET_IF_ETHER_H
77#  include <netinet/if_ether.h>
78#endif
79
80#include <time.h>
81#ifdef WIN32
82#include <sys/timeb.h>
83#endif
84
85#include "libtrace.h"
86#include "libtrace_int.h"
87
88#ifdef HAVE_PCAP_BPF_H
89#  include <pcap-bpf.h>
90#else
91#  ifdef HAVE_NET_BPF_H
92#    include <net/bpf.h>
93#  endif
94#endif
95
96
97#include "libtrace_int.h"
98#include "format_helper.h"
99#include "rt_protocol.h"
100
101#include <pthread.h>
102#include <signal.h>
103
104#define MAXOPTS 1024
105
106/* This file contains much of the implementation of the libtrace API itself. */
107
108static struct libtrace_format_t *formats_list = NULL;
109
110int libtrace_halt = 0;
111
112/* Set once pstart is called used for backwards compatibility reasons */
113int libtrace_parallel = 0;
114
115/* strncpy is not assured to copy the final \0, so we
116 * will use our own one that does
117 */
118static void xstrncpy(char *dest, const char *src, size_t n)
119{
120        strncpy(dest,src,n);
121        dest[n]='\0';
122}
123 
124static char *xstrndup(const char *src,size_t n)
125{       
126        char *ret=(char*)malloc(n+1);
127        if (ret==NULL) {
128                fprintf(stderr,"Out of memory");
129                exit(EXIT_FAILURE);
130        }
131        xstrncpy(ret,src,n);
132        return ret;
133}
134
135
136/* call all the constructors if they haven't yet all been called */
137static void trace_init(void)
138{
139        if (!formats_list) {
140                duck_constructor();
141                erf_constructor();
142                tsh_constructor();
143                legacy_constructor();
144                atmhdr_constructor();
145                linuxnative_constructor();
146#ifdef HAVE_LIBPCAP
147                pcap_constructor();
148#endif
149                bpf_constructor();
150                pcapfile_constructor();
151                rt_constructor();
152#ifdef HAVE_DAG
153                dag_constructor();
154#endif
155#ifdef HAVE_DPDK
156        dpdk_constructor();
157#endif
158        }
159}
160
161/* Prints help information for libtrace
162 *
163 * Function prints out some basic help information regarding libtrace,
164 * and then prints out the help() function registered with each input module
165 */
166DLLEXPORT void trace_help(void) {
167        struct libtrace_format_t *tmp;
168        trace_init();
169        printf("libtrace %s\n\n",PACKAGE_VERSION);
170        printf("Following this are a list of the format modules supported in this build of libtrace\n\n");
171        for(tmp=formats_list;tmp;tmp=tmp->next) {
172                if (tmp->help)
173                        tmp->help();
174        }
175}
176
177#define URI_PROTO_LINE 16U
178
179/* Try to guess which format module is appropriate for a given trace file or
180 * device */
181static void guess_format(libtrace_t *libtrace, const char *filename)
182{
183        struct libtrace_format_t *tmp;
184       
185        /* Try and guess based on filename */
186        for(tmp = formats_list; tmp; tmp=tmp->next) {
187                if (tmp->probe_filename && tmp->probe_filename(filename)) {
188                        libtrace->format = tmp;
189                        libtrace->uridata = strdup(filename);
190                        return;
191                }
192        }
193
194        libtrace->io = wandio_create(filename);
195        if (!libtrace->io)
196                return;
197
198        /* Try and guess based on file magic */
199        for(tmp = formats_list; tmp; tmp=tmp->next) {
200                if (tmp->probe_magic && tmp->probe_magic(libtrace->io)) {
201                        libtrace->format = tmp;
202                        libtrace->uridata = strdup(filename);
203                        return;
204                }
205        }
206       
207        /* Oh well */
208        return;
209}
210
211/* Creates an input trace from a URI
212 *
213 * @params char * containing a valid libtrace URI
214 * @returns opaque pointer to a libtrace_t
215 *
216 * Some valid URI's are:
217 *  erf:/path/to/erf/file
218 *  erf:/path/to/erf/file.gz
219 *  erf:-                       (stdin)
220 *  dag:/dev/dagcard
221 *  pcapint:pcapinterface               (eg: pcapint:eth0)
222 *  pcapfile:/path/to/pcap/file
223 *  pcapfile:-
224 *  int:interface                       (eg: int:eth0) only on Linux
225 *  rt:hostname
226 *  rt:hostname:port
227 *
228 * If an error occured when attempting to open a trace, NULL is returned
229 * and an error is output to stdout.
230 */
231DLLEXPORT libtrace_t *trace_create(const char *uri) {
232        libtrace_t *libtrace = 
233                        (libtrace_t *)malloc(sizeof(libtrace_t));
234        char *scan = 0;
235        const char *uridata = 0;                 
236
237        trace_init();
238
239        assert(uri && "Passing NULL to trace_create makes me a very sad program");
240
241        if (!libtrace) {
242                /* Out of memory */
243                return NULL;
244        }
245       
246        libtrace->err.err_num = TRACE_ERR_NOERROR;
247        libtrace->format=NULL;
248       
249        libtrace->event.tdelta = 0.0;
250        libtrace->event.packet = NULL;
251        libtrace->event.psize = 0;
252        libtrace->event.trace_last_ts = 0.0;
253        libtrace->event.waiting = false;
254        libtrace->filter = NULL;
255        libtrace->snaplen = 0;
256        libtrace->started=false;
257        libtrace->uridata = NULL;
258        libtrace->io = NULL;
259        libtrace->filtered_packets = 0;
260        libtrace->accepted_packets = 0;
261       
262        /* Parallel inits */
263        // libtrace->libtrace_lock
264        // libtrace->perpkt_cond;
265        libtrace->state = STATE_NEW;
266        libtrace->perpkts_pausing = 0;
267        libtrace->perpkt_queue_full = false;
268        libtrace->perpkts_finishing = -1;
269        libtrace->reducer_flags = 0;
270        libtrace->joined = false;
271        libtrace->global_blob = NULL;
272        libtrace->per_pkt = NULL;
273        libtrace->reducer = NULL;
274        libtrace->hasher = NULL;
275        libtrace->packet_freelist_size = 0;
276        libtrace->perpkt_buffer_size = 0;
277        libtrace->expected_key = 0;
278        libtrace_zero_ringbuffer(&libtrace->packet_freelist);
279        libtrace_zero_thread(&libtrace->hasher_thread);
280        libtrace_zero_thread(&libtrace->reducer_thread);
281        libtrace_zero_slidingwindow(&libtrace->sliding_window);
282        libtrace->reducer_thread.type = THREAD_EMPTY;
283        libtrace->perpkt_thread_count = 0;
284        libtrace->perpkt_threads = NULL;
285        libtrace->tracetime = 0;
286
287        /* Parse the URI to determine what sort of trace we are dealing with */
288        if ((uridata = trace_parse_uri(uri, &scan)) == 0) {
289                /* Could not parse the URI nicely */
290                guess_format(libtrace,uri);
291                if (!libtrace->format) {
292                        trace_set_err(libtrace,TRACE_ERR_BAD_FORMAT,"Unable to guess format (%s)",uri);
293                        return libtrace;
294                }
295        }
296        else {
297                struct libtrace_format_t *tmp;
298
299                /* Find a format that matches the first part of the URI */
300                for (tmp=formats_list;tmp;tmp=tmp->next) {
301                        if (strlen(scan) == strlen(tmp->name) &&
302                                        strncasecmp(scan, tmp->name, strlen(scan)) == 0
303                                        ) {
304                                libtrace->format=tmp;
305                                break;
306                        }
307                }
308
309                if (libtrace->format == 0) {
310                        trace_set_err(libtrace, TRACE_ERR_BAD_FORMAT,
311                                        "Unknown format (%s)",scan);
312                        return libtrace;
313                }
314
315                libtrace->uridata = strdup(uridata);
316        }
317        /* libtrace->format now contains the type of uri
318         * libtrace->uridata contains the appropriate data for this
319         */
320       
321        /* Call the init_input function for the matching capture format */ 
322        if (libtrace->format->init_input) {
323                int err=libtrace->format->init_input(libtrace);
324                assert (err==-1 || err==0);
325                if (err==-1) {
326                        /* init_input should call trace_set_err to set
327                         * the error message
328                         */
329                        return libtrace;
330                }
331        } else {
332                trace_set_err(libtrace,TRACE_ERR_UNSUPPORTED,
333                                "Format does not support input (%s)",scan);
334                return libtrace;
335        }
336       
337        if (scan)
338                free(scan);
339        libtrace->err.err_num=TRACE_ERR_NOERROR;
340        libtrace->err.problem[0]='\0';
341        return libtrace;
342}
343
344/* Creates a "dummy" trace file that has only the format type set.
345 *
346 * @returns opaque pointer to a (sparsely initialised) libtrace_t
347 *
348 * IMPORTANT: Do not attempt to call trace_read_packet or other such functions
349 * with the dummy trace. Its intended purpose is to act as a packet->trace for
350 * libtrace_packet_t's that are not associated with a libtrace_t structure.
351 */
352DLLEXPORT libtrace_t * trace_create_dead (const char *uri) {
353        libtrace_t *libtrace = (libtrace_t *) malloc(sizeof(libtrace_t));
354        char *scan = (char *)calloc(sizeof(char),URI_PROTO_LINE);
355        char *uridata;
356        struct libtrace_format_t *tmp;
357
358        trace_init();
359       
360        libtrace->err.err_num = TRACE_ERR_NOERROR;
361
362        if((uridata = strchr(uri,':')) == NULL) {
363                xstrncpy(scan, uri, strlen(uri));
364        } else {
365                xstrncpy(scan,uri, (size_t)(uridata - uri));
366        }
367       
368        libtrace->err.err_num = TRACE_ERR_NOERROR;
369        libtrace->format=NULL;
370       
371        libtrace->event.tdelta = 0.0;
372        libtrace->event.packet = NULL;
373        libtrace->event.psize = 0;
374        libtrace->event.trace_last_ts = 0.0;
375        libtrace->filter = NULL;
376        libtrace->snaplen = 0;
377        libtrace->started=false;
378        libtrace->uridata = NULL;
379        libtrace->io = NULL;
380        libtrace->filtered_packets = 0;
381       
382        /* Parallel inits */
383        // libtrace->libtrace_lock
384        // libtrace->perpkt_cond;
385        libtrace->state = STATE_NEW; // TODO MAYBE DEAD
386        libtrace->perpkts_pausing = 0;
387        libtrace->perpkt_queue_full = false;
388        libtrace->perpkts_finishing = -1;
389        libtrace->reducer_flags = 0;
390        libtrace->joined = false;
391        libtrace->global_blob = NULL;
392        libtrace->per_pkt = NULL;
393        libtrace->reducer = NULL;
394        libtrace->hasher = NULL;
395        libtrace->expected_key = 0;
396        libtrace->packet_freelist_size = 0;
397        libtrace->perpkt_buffer_size = 0;
398        libtrace_zero_ringbuffer(&libtrace->packet_freelist);
399        libtrace_zero_thread(&libtrace->hasher_thread);
400        libtrace_zero_thread(&libtrace->reducer_thread);
401        libtrace_zero_slidingwindow(&libtrace->sliding_window);
402        libtrace->reducer_thread.type = THREAD_EMPTY;
403        libtrace->perpkt_thread_count = 0;
404        libtrace->perpkt_threads = NULL;
405        libtrace->tracetime = 0;
406       
407        for(tmp=formats_list;tmp;tmp=tmp->next) {
408                if (strlen(scan) == strlen(tmp->name) &&
409                                !strncasecmp(scan,
410                                        tmp->name,
411                                        strlen(scan))) {
412                                libtrace->format=tmp;
413                                break;
414                                }
415        }
416        if (libtrace->format == 0) {
417                trace_set_err(libtrace,TRACE_ERR_BAD_FORMAT,
418                                "Unknown format (%s)",scan);
419        }
420
421        libtrace->format_data = NULL;
422        free(scan);
423        return libtrace;
424
425}
426
427/* Creates an output trace from a URI.
428 *
429 * @param uri   the uri string describing the output format and destination
430 * @returns opaque pointer to a libtrace_output_t
431 *
432 *  If an error occured when attempting to open the output trace, NULL is
433 *  returned and trace_errno is set.
434 */
435       
436DLLEXPORT libtrace_out_t *trace_create_output(const char *uri) {
437        libtrace_out_t *libtrace = 
438                        (libtrace_out_t*)malloc(sizeof(libtrace_out_t));
439       
440        char *scan = 0;
441        const char *uridata = 0;
442        struct libtrace_format_t *tmp;
443
444        trace_init();
445
446        libtrace->err.err_num = TRACE_ERR_NOERROR;
447        strcpy(libtrace->err.problem,"Error message set\n");
448        libtrace->format = NULL;
449        libtrace->uridata = NULL;
450       
451        /* Parse the URI to determine what capture format we want to write */
452
453        if ((uridata = trace_parse_uri(uri, &scan)) == 0) {
454                trace_set_err_out(libtrace,TRACE_ERR_BAD_FORMAT,
455                                "Bad uri format (%s)",uri);
456                return libtrace;
457        }
458       
459        /* Attempt to find the format in the list of supported formats */
460        for(tmp=formats_list;tmp;tmp=tmp->next) {
461                if (strlen(scan) == strlen(tmp->name) &&
462                                !strncasecmp(scan,
463                                        tmp->name,
464                                        strlen(scan))) {
465                                libtrace->format=tmp;
466                                break;
467                                }
468        }
469        free(scan);
470
471        if (libtrace->format == NULL) {
472                trace_set_err_out(libtrace,TRACE_ERR_BAD_FORMAT,
473                                "Unknown output format (%s)",scan);
474                return libtrace;
475        }
476        libtrace->uridata = strdup(uridata);
477
478        /* libtrace->format now contains the type of uri
479         * libtrace->uridata contains the appropriate data for this
480         */
481
482        if (libtrace->format->init_output) {
483                /* 0 on success, -1 on failure */
484                switch(libtrace->format->init_output(libtrace)) {
485                        case -1: /* failure */
486                                return libtrace;
487                        case 0: /* success */
488                                break;
489                        default:
490                                assert(!"Internal error: init_output() should return -1 for failure, or 0 for success");
491                }
492        } else {
493                trace_set_err_out(libtrace,TRACE_ERR_UNSUPPORTED,
494                                "Format does not support writing (%s)",scan);
495                return libtrace;
496        }
497
498
499        libtrace->started=false;
500        return libtrace;
501}
502
503/* Start an input trace
504 * @param libtrace      the input trace to start
505 * @returns 0 on success
506 *
507 * This does the work associated with actually starting up
508 * the trace.  it may fail.
509 */
510DLLEXPORT int trace_start(libtrace_t *libtrace)
511{
512        assert(libtrace);
513        if (trace_is_err(libtrace))
514                return -1;
515        if (libtrace->format->start_input) {
516                int ret=libtrace->format->start_input(libtrace);
517                if (ret < 0) {
518                        return ret;
519                }
520        }
521
522        libtrace->started=true;
523        return 0;
524}
525
526/* Start an output trace */
527DLLEXPORT int trace_start_output(libtrace_out_t *libtrace) 
528{
529        assert(libtrace);
530        if (libtrace->format->start_output) {
531                int ret=libtrace->format->start_output(libtrace);
532                if (ret < 0) {
533                        return ret;
534                }
535        }
536
537        libtrace->started=true;
538        return 0;
539}
540
541DLLEXPORT int trace_pause(libtrace_t *libtrace)
542{
543        assert(libtrace);
544        if (!libtrace->started) {
545                trace_set_err(libtrace,TRACE_ERR_BAD_STATE, "You must call trace_start() before calling trace_pause()");
546                return -1;
547        }
548        if (libtrace->format->pause_input)
549                libtrace->format->pause_input(libtrace);
550        libtrace->started=false;
551        return 0;
552}
553
554DLLEXPORT int trace_config(libtrace_t *libtrace,
555                trace_option_t option,
556                void *value)
557{
558        int ret;
559
560        if (trace_is_err(libtrace)) {
561                return -1;
562        }
563       
564        /* If the capture format supports configuration, try using their
565         * native configuration first */
566        if (libtrace->format->config_input) {
567                ret=libtrace->format->config_input(libtrace,option,value);
568                if (ret==0)
569                        return 0;
570        }
571
572        /* If we get here, either the native configuration failed or the
573         * format did not support configuration. However, libtrace can
574         * deal with some options itself, so give that a go */
575        switch(option) {
576                case TRACE_OPTION_SNAPLEN:
577                        /* Clear the error if there was one */
578                        if (trace_is_err(libtrace)) {
579                                trace_get_err(libtrace);
580                        }
581                        if (*(int*)value<0 
582                                || *(int*)value>LIBTRACE_PACKET_BUFSIZE) {
583                                trace_set_err(libtrace,TRACE_ERR_BAD_STATE,
584                                        "Invalid snap length");
585                        }
586                        libtrace->snaplen=*(int*)value;
587                        return 0;
588                case TRACE_OPTION_FILTER:
589                        /* Clear the error if there was one */
590                        if (trace_is_err(libtrace)) {
591                                trace_get_err(libtrace);
592                        }
593                        libtrace->filter=(libtrace_filter_t *)value;
594                        return 0;
595                case TRACE_OPTION_PROMISC:
596                        if (!trace_is_err(libtrace)) {
597                                trace_set_err(libtrace,TRACE_ERR_OPTION_UNAVAIL,
598                                                "Promisc mode is not supported by this format module");
599                        }
600                        return -1;
601                case TRACE_OPTION_META_FREQ:
602                        if (!trace_is_err(libtrace)) {
603                                trace_set_err(libtrace, 
604                                                TRACE_ERR_OPTION_UNAVAIL,
605                                                "This format does not support meta-data gathering");
606                        }
607                        return -1;
608                case TRACE_OPTION_EVENT_REALTIME:
609                        if (!trace_is_err(libtrace)) {
610                                trace_set_err(libtrace, 
611                                                TRACE_ERR_OPTION_UNAVAIL,
612                                                "This format does not support realtime events");
613                        }
614                        return -1;
615                       
616        }
617        if (!trace_is_err(libtrace)) {
618                trace_set_err(libtrace,TRACE_ERR_UNKNOWN_OPTION,
619                        "Unknown option %i", option);
620        }
621        return -1;
622}
623
624DLLEXPORT int trace_config_output(libtrace_out_t *libtrace, 
625                trace_option_output_t option,
626                void *value) {
627       
628        /* Unlike the input options, libtrace does not natively support any of
629         * the output options - the format module must be able to deal with
630         * them. */
631        if (libtrace->format->config_output) {
632                return libtrace->format->config_output(libtrace, option, value);
633        }
634        return -1;
635}
636
637/* Close an input trace file, freeing up any resources it may have been using
638 *
639 */
640DLLEXPORT void trace_destroy(libtrace_t *libtrace) {
641    int i;
642        assert(libtrace);
643        if (libtrace->format) {
644                if (libtrace->started && libtrace->format->pause_input)
645                        libtrace->format->pause_input(libtrace);
646                if (libtrace->format->fin_input)
647                        libtrace->format->fin_input(libtrace);
648        }
649        /* Need to free things! */
650        if (libtrace->uridata)
651                free(libtrace->uridata);
652       
653        /* Empty any packet memory */
654
655        libtrace_packet_t * packet;
656        while (libtrace_ringbuffer_try_read(&libtrace->packet_freelist,(void **) &packet))
657                trace_destroy_packet(packet);
658       
659        libtrace_ringbuffer_destroy(&libtrace->packet_freelist);
660       
661        for (i = 0; i < libtrace->perpkt_thread_count; ++i) {
662                assert (libtrace_vector_get_size(&libtrace->perpkt_threads[i].vector) == 0);
663                libtrace_vector_destroy(&libtrace->perpkt_threads[i].vector);
664        }
665        free(libtrace->perpkt_threads);
666        libtrace->perpkt_threads = NULL;
667        libtrace->perpkt_thread_count = 0;
668       
669        if (libtrace->event.packet) {
670                /* Don't use trace_destroy_packet here - there is almost
671                 * certainly going to be another libtrace_packet_t that is
672                 * pointing to the buffer for this packet, so we don't want
673                 * to free it. Rather, it will get freed when the user calls
674                 * trace_destroy_packet on the libtrace_packet_t that they
675                 * own.
676                 *
677                 * All we need to do then is free our packet structure itself.
678                 */
679                 free(libtrace->event.packet);
680        }
681        free(libtrace);
682}
683
684
685DLLEXPORT void trace_destroy_dead(libtrace_t *libtrace) {
686        assert(libtrace);
687
688        /* Don't call pause_input or fin_input, because we should never have
689         * used this trace to do any reading anyway. Do make sure we free
690         * any format_data that has been created, though. */
691        if (libtrace->format_data)
692                free(libtrace->format_data);
693        free(libtrace);
694}
695/* Close an output trace file, freeing up any resources it may have been using
696 *
697 * @param libtrace      the output trace file to be destroyed
698 */
699DLLEXPORT void trace_destroy_output(libtrace_out_t *libtrace) 
700{
701        assert(libtrace);
702        if (libtrace->format && libtrace->format->fin_output)
703                libtrace->format->fin_output(libtrace);
704        if (libtrace->uridata)
705                free(libtrace->uridata);
706        free(libtrace);
707}
708
709DLLEXPORT libtrace_packet_t *trace_create_packet(void) 
710{
711        libtrace_packet_t *packet = 
712                (libtrace_packet_t*)calloc((size_t)1,sizeof(libtrace_packet_t));
713
714        packet->buf_control=TRACE_CTRL_PACKET;
715        trace_clear_cache(packet);
716        return packet;
717}
718
719DLLEXPORT libtrace_packet_t *trace_copy_packet(const libtrace_packet_t *packet) {
720        libtrace_packet_t *dest = 
721                (libtrace_packet_t *)malloc(sizeof(libtrace_packet_t));
722        if (!dest) {
723                printf("Out of memory constructing packet\n");
724                abort();
725        }
726        dest->trace=packet->trace;
727        dest->buffer=malloc(65536);
728        if (!dest->buffer) {
729                printf("Out of memory allocating buffer memory\n");
730                abort();
731        }
732        dest->header=dest->buffer;
733        dest->payload=(void*)
734                ((char*)dest->buffer+trace_get_framing_length(packet));
735        dest->type=packet->type;
736        dest->buf_control=TRACE_CTRL_PACKET;
737        dest->order = packet->order;
738        /* Reset the cache - better to recalculate than try to convert
739         * the values over to the new packet */
740        trace_clear_cache(dest);       
741        /* Ooooh nasty memcpys! This is why we want to avoid copying packets
742         * as much as possible */
743        memcpy(dest->header,packet->header,trace_get_framing_length(packet));
744        memcpy(dest->payload,packet->payload,trace_get_capture_length(packet));
745
746        return dest;
747}
748
749/** Destroy a packet object
750 */
751DLLEXPORT void trace_destroy_packet(libtrace_packet_t *packet) {
752        /* Free any resources possibly associated with the packet */
753        if (libtrace_parallel && packet->trace && packet->trace->format->fin_packet) {
754                packet->trace->format->fin_packet(packet);
755        }
756       
757        if (packet->buf_control == TRACE_CTRL_PACKET && packet->buffer) {
758                free(packet->buffer);
759        }
760        packet->buf_control=(buf_control_t)'\0'; 
761                                /* A "bad" value to force an assert
762                                 * if this packet is ever reused
763                                 */
764        free(packet);
765}       
766
767/**
768 * Removes any possible data stored againt the trace and releases any data.
769 * This will not destroy a reusable good malloc'd buffer (TRACE_CTRL_PACKET)
770 * use trace_destroy_packet() for those diabolical purposes.
771 */
772void trace_fin_packet(libtrace_packet_t *packet);
773void trace_fin_packet(libtrace_packet_t *packet) {
774        if (packet)
775        {
776                if (packet->trace && packet->trace->format->fin_packet) {
777                        packet->trace->format->fin_packet(packet);
778                        //gettimeofday(&tv, NULL);
779                        //printf ("%d.%06d DESTROYED #%"PRIu64"\n", tv.tv_sec, tv.tv_usec, trace_packet_get(packet));
780                }
781
782                // No matter what we remove the header and link pointers
783                packet->trace = NULL;
784                packet->header = NULL;
785                packet->payload = NULL;
786
787                if (packet->buf_control != TRACE_CTRL_PACKET)
788                {
789                        packet->buffer = NULL;
790                }
791
792                packet->trace = NULL;
793                packet->hash = 0;
794                packet->order = 0;
795                trace_clear_cache(packet);
796        }
797}
798
799/* Read one packet from the trace into buffer. Note that this function will
800 * block until a packet is read (or EOF is reached).
801 *
802 * @param libtrace      the libtrace opaque pointer
803 * @param packet        the packet opaque pointer
804 * @returns 0 on EOF, negative value on error
805 *
806 */
807DLLEXPORT int trace_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
808
809        assert(libtrace && "You called trace_read_packet() with a NULL libtrace parameter!\n");
810        if (trace_is_err(libtrace))
811                return -1;
812        if (!libtrace->started) {
813                trace_set_err(libtrace,TRACE_ERR_BAD_STATE,"You must call libtrace_start() before trace_read_packet()\n");
814                return -1;
815        }
816        if (!(packet->buf_control==TRACE_CTRL_PACKET || packet->buf_control==TRACE_CTRL_EXTERNAL)) {
817                trace_set_err(libtrace,TRACE_ERR_BAD_STATE,"Packet passed to trace_read_packet() is invalid\n");
818                return -1;
819        }
820        assert(packet);
821
822        if (libtrace->format->read_packet) {
823                do {
824                        size_t ret;
825                        /* Finalise the packet, freeing any resources the format module
826                         * may have allocated it and zeroing all data associated with it.
827                         */
828                        trace_fin_packet(packet);
829                        /* Store the trace we are reading from into the packet opaque
830                         * structure */
831                        packet->trace = libtrace;
832                        ret=libtrace->format->read_packet(libtrace,packet);
833                        if (ret==(size_t)-1 || ret==0) {
834                                return ret;
835                        }
836                        if (libtrace->filter) {
837                                /* If the filter doesn't match, read another
838                                 * packet
839                                 */
840                                if (!trace_apply_filter(libtrace->filter,packet)){
841                                        ++libtrace->filtered_packets;
842                                        continue;
843                                }
844                        }
845                        if (libtrace->snaplen>0) {
846                                /* Snap the packet */
847                                trace_set_capture_length(packet,
848                                                libtrace->snaplen);
849                        }
850                        trace_packet_set_order(packet, libtrace->accepted_packets);
851                        ++libtrace->accepted_packets;
852                        return ret;
853                } while(1);
854        }
855        trace_set_err(libtrace,TRACE_ERR_UNSUPPORTED,"This format does not support reading packets\n");
856        return ~0U;
857}
858
859/* Converts the provided buffer into a libtrace packet of the given type.
860 *
861 * Unlike trace_construct_packet, the buffer is expected to begin with the
862 * appropriate capture format header for the format type that the packet is
863 * being converted to. This also allows for a packet to be converted into
864 * just about capture format that is supported by libtrace, provided the
865 * format header is present in the buffer.
866 *
867 * This function is primarily used to convert packets received via the RT
868 * protocol back into their original capture format. The RT header encapsulates
869 * the original capture format header, so after removing it the packet must
870 * have it's header and payload pointers updated and the packet format and type
871 * changed, amongst other things.
872 *
873 * Intended only for internal use at this point - this function is not
874 * available through the external libtrace API.
875 */
876int trace_prepare_packet(libtrace_t *trace, libtrace_packet_t *packet,
877                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
878
879        assert(packet);
880        assert(trace);
881       
882        /* XXX Proper error handling?? */
883        if (buffer == NULL)
884                return -1;
885
886        if (!(packet->buf_control==TRACE_CTRL_PACKET || packet->buf_control==TRACE_CTRL_EXTERNAL)) {
887                trace_set_err(trace,TRACE_ERR_BAD_STATE,"Packet passed to trace_read_packet() is invalid\n");
888                return -1;
889        }
890       
891        packet->trace = trace;
892       
893        /* Clear packet cache */
894        trace_clear_cache(packet);
895
896        if (trace->format->prepare_packet) {
897                return trace->format->prepare_packet(trace, packet,
898                                buffer, rt_type, flags);
899        }
900        trace_set_err(trace, TRACE_ERR_UNSUPPORTED, 
901                        "This format does not support preparing packets\n");
902        return -1;
903
904}
905
906/* Writes a packet to the specified output trace
907 *
908 * @param libtrace      describes the output format, destination, etc.
909 * @param packet        the packet to be written out
910 * @returns the number of bytes written, -1 if write failed
911 */
912DLLEXPORT int trace_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) {
913        assert(libtrace);
914        assert(packet); 
915        /* Verify the packet is valid */
916        if (!libtrace->started) {
917                trace_set_err_out(libtrace,TRACE_ERR_BAD_STATE,
918                        "Trace is not started before trace_write_packet");
919                return -1;
920        }
921
922        if (libtrace->format->write_packet) {
923                return libtrace->format->write_packet(libtrace, packet);
924        }
925        trace_set_err_out(libtrace,TRACE_ERR_UNSUPPORTED,
926                "This format does not support writing packets");
927        return -1;
928}
929
930/* Get a pointer to the first byte of the packet payload */
931DLLEXPORT void *trace_get_packet_buffer(const libtrace_packet_t *packet,
932                libtrace_linktype_t *linktype, uint32_t *remaining) {
933        int cap_len;
934        int wire_len;
935
936        assert(packet != NULL);
937        if (linktype) *linktype = trace_get_link_type(packet);
938        if (remaining) {
939                /* I think we should choose the minimum of the capture and
940                 * wire lengths to be the "remaining" value. If the packet has
941                 * been padded to increase the capture length, we don't want
942                 * to allow subsequent protocol decoders to consider the
943                 * padding as part of the packet.
944                 *
945                 * For example, in Auck 4 there is a trace where the IP header
946                 * length is incorrect (24 bytes) followed by a 20 byte TCP
947                 * header. Total IP length is 40 bytes. As a result, the
948                 * legacyatm padding gets treated as the "missing" bytes of
949                 * the TCP header, which isn't the greatest. We're probably
950                 * better off returning an incomplete TCP header in that case.
951                 */
952               
953                cap_len = trace_get_capture_length(packet);
954                wire_len = trace_get_wire_length(packet);
955
956                assert(cap_len >= 0);
957
958                /* There is the odd corrupt packet, e.g. in IPLS II, that have
959                 * massively negative wire lens. We could assert fail here on
960                 * them, but we could at least try the capture length instead.
961                 *
962                 * You may still run into problems if you try to write that
963                 * packet, but at least reading should work OK.
964                 */
965                if (wire_len < 0)
966                        *remaining = cap_len;
967                else if (wire_len < cap_len)
968                        *remaining = wire_len;
969                else
970                        *remaining = cap_len;
971                /* *remaining = trace_get_capture_length(packet); */
972        }
973        return (void *) packet->payload;
974}
975
976
977/* Get a pointer to the first byte of the packet payload
978 *
979 * DEPRECATED - use trace_get_packet_buffer() instead */
980DLLEXPORT void *trace_get_link(const libtrace_packet_t *packet) {
981        return (void *)packet->payload;
982}
983
984/* Get the current time in DAG time format
985 * @param packet        a pointer to a libtrace_packet structure
986 * @returns a 64 bit timestamp in DAG ERF format (upper 32 bits are the seconds
987 * past 1970-01-01, the lower 32bits are partial seconds)
988 */ 
989DLLEXPORT uint64_t trace_get_erf_timestamp(const libtrace_packet_t *packet) {
990        if (packet->trace->format->get_erf_timestamp) {
991                /* timestamp -> timestamp */
992                return packet->trace->format->get_erf_timestamp(packet);
993        } else if (packet->trace->format->get_timespec) {
994                /* timespec -> timestamp */
995                struct timespec ts;
996                ts = packet->trace->format->get_timespec(packet);
997                return ((((uint64_t)ts.tv_sec) << 32) +
998                                (((uint64_t)ts.tv_nsec << 32)/1000000000));
999        } else if (packet->trace->format->get_timeval) {
1000                /* timeval -> timestamp */
1001                struct timeval tv;
1002                tv = packet->trace->format->get_timeval(packet);
1003                return ((((uint64_t)tv.tv_sec) << 32) +
1004                                (((uint64_t)tv.tv_usec << 32)/1000000));
1005        } else if (packet->trace->format->get_seconds) {
1006                /* seconds -> timestamp */
1007                double seconds = packet->trace->format->get_seconds(packet);
1008                return (((uint64_t)seconds)<<32)
1009                          + (uint64_t)((seconds-(uint64_t)seconds)*UINT_MAX);
1010        }
1011        else {
1012                return (uint64_t)0;
1013        }
1014                     
1015}
1016
1017/* Get the current time in struct timeval
1018 * @param packet        a pointer to a libtrace_packet structure
1019 *
1020 * @returns time that this packet was seen in a struct timeval
1021 * @author Daniel Lawson
1022 * @author Perry Lorier
1023 */ 
1024DLLEXPORT struct timeval trace_get_timeval(const libtrace_packet_t *packet) {
1025        struct timeval tv;
1026        uint64_t ts = 0;
1027        if (packet->trace->format->get_timeval) {
1028                /* timeval -> timeval */
1029                tv = packet->trace->format->get_timeval(packet);
1030        } else if (packet->trace->format->get_erf_timestamp) {
1031                /* timestamp -> timeval */
1032                ts = packet->trace->format->get_erf_timestamp(packet);
1033                tv.tv_sec = ts >> 32;
1034                tv.tv_usec = ((ts&0xFFFFFFFF)*1000000)>>32;
1035                if (tv.tv_usec >= 1000000) {
1036                        tv.tv_usec -= 1000000;
1037                        tv.tv_sec += 1;
1038                }
1039        } else if (packet->trace->format->get_timespec) {
1040                struct timespec ts = packet->trace->format->get_timespec(packet);
1041                tv.tv_sec = ts.tv_sec;
1042                tv.tv_usec = ts.tv_nsec/1000;
1043        } else if (packet->trace->format->get_seconds) {
1044                /* seconds -> timeval */
1045                double seconds = packet->trace->format->get_seconds(packet);
1046                tv.tv_sec = (uint32_t)seconds;
1047                tv.tv_usec = (uint32_t)(((seconds - tv.tv_sec) * 1000000)/UINT_MAX);
1048        }
1049        else {
1050                tv.tv_sec=-1;
1051                tv.tv_usec=-1;
1052        }
1053
1054    return tv;
1055}
1056
1057DLLEXPORT struct timespec trace_get_timespec(const libtrace_packet_t *packet) {
1058        struct timespec ts;
1059
1060        if (packet->trace->format->get_timespec) {
1061                return packet->trace->format->get_timespec(packet);
1062        } else if (packet->trace->format->get_erf_timestamp) {
1063                /* timestamp -> timeval */
1064                uint64_t erfts = packet->trace->format->get_erf_timestamp(packet);
1065                ts.tv_sec = erfts >> 32;
1066                ts.tv_nsec = ((erfts&0xFFFFFFFF)*1000000000)>>32;
1067                if (ts.tv_nsec >= 1000000000) {
1068                        ts.tv_nsec -= 1000000000;
1069                        ts.tv_sec += 1;
1070                }
1071                return ts;
1072        } else if (packet->trace->format->get_timeval) {
1073                /* timeval -> timespec */
1074                struct timeval tv = packet->trace->format->get_timeval(packet);
1075                ts.tv_sec = tv.tv_sec;
1076                ts.tv_nsec = tv.tv_usec*1000;
1077                return ts;
1078        } else if (packet->trace->format->get_seconds) {
1079                /* seconds -> timespec */
1080                double seconds = packet->trace->format->get_seconds(packet);
1081                ts.tv_sec = (uint32_t)seconds;
1082                ts.tv_nsec = (long)(((seconds - ts.tv_sec) * 1000000000)/UINT_MAX);
1083                return ts;
1084        }
1085        else {
1086                ts.tv_sec=-1;
1087                ts.tv_nsec=-1;
1088                return ts;
1089        }
1090}
1091
1092
1093/* Get the current time in floating point seconds
1094 * @param packet        a pointer to a libtrace_packet structure
1095 * @returns time that this packet was seen in 64bit floating point seconds
1096 */ 
1097DLLEXPORT double trace_get_seconds(const libtrace_packet_t *packet) {
1098        double seconds = 0.0;
1099
1100        if (packet->trace->format->get_seconds) {
1101                /* seconds->seconds */
1102                seconds = packet->trace->format->get_seconds(packet);
1103        } else if (packet->trace->format->get_erf_timestamp) {
1104                /* timestamp -> seconds */
1105                uint64_t ts = 0;
1106                ts = packet->trace->format->get_erf_timestamp(packet);
1107                seconds =  (ts>>32) + ((ts & UINT_MAX)*1.0 / UINT_MAX);
1108        } else if (packet->trace->format->get_timespec) {
1109                /* timespec -> seconds */
1110                struct timespec ts;
1111                ts = packet->trace->format->get_timespec(packet);
1112                seconds = ts.tv_sec + ((ts.tv_nsec * 1.0) / 1000000000);
1113        } else if (packet->trace->format->get_timeval) {
1114                /* timeval -> seconds */
1115                struct timeval tv;
1116                tv = packet->trace->format->get_timeval(packet);
1117                seconds = tv.tv_sec + ((tv.tv_usec * 1.0) / 1000000);
1118        }
1119
1120        return seconds;
1121}
1122
1123DLLEXPORT size_t trace_get_capture_length(const libtrace_packet_t *packet) 
1124{
1125        /* Cache the capture length */
1126        if (packet->capture_length == -1) {
1127                if (!packet->trace->format->get_capture_length)
1128                        return ~0U;
1129                /* Cast away constness because this is "just" a cache */
1130                ((libtrace_packet_t*)packet)->capture_length = 
1131                        packet->trace->format->get_capture_length(packet);
1132        }
1133
1134        assert(packet->capture_length < LIBTRACE_PACKET_BUFSIZE);
1135
1136        return packet->capture_length;
1137}
1138       
1139/* Get the size of the packet as it was seen on the wire.
1140 * @param packet        a pointer to a libtrace_packet structure
1141 *
1142 * @returns the size of the packet as it was on the wire.
1143 * @note Due to the trace being a header capture, or anonymisation this may
1144 * not be the same as the Capture Len.
1145 */ 
1146DLLEXPORT size_t trace_get_wire_length(const libtrace_packet_t *packet){
1147       
1148        if (packet->wire_length == -1) {
1149                if (!packet->trace->format->get_wire_length) 
1150                        return ~0U;
1151                ((libtrace_packet_t *)packet)->wire_length = 
1152                        packet->trace->format->get_wire_length(packet);
1153        }
1154
1155        assert(packet->wire_length < LIBTRACE_PACKET_BUFSIZE);
1156        return packet->wire_length;
1157
1158}
1159
1160/* Get the length of the capture framing headers.
1161 * @param packet        the packet opaque pointer
1162 * @returns the size of the packet as it was on the wire.
1163 * @note this length corresponds to the difference between the size of a
1164 * captured packet in memory, and the captured length of the packet
1165 */ 
1166DLLEXPORT SIMPLE_FUNCTION
1167size_t trace_get_framing_length(const libtrace_packet_t *packet) {
1168        if (packet->trace->format->get_framing_length) {
1169                return packet->trace->format->get_framing_length(packet);
1170        }
1171        return ~0U;
1172}
1173
1174
1175/* Get the type of the link layer
1176 * @param packet        a pointer to a libtrace_packet structure
1177 * @returns libtrace_linktype_t
1178 */
1179DLLEXPORT libtrace_linktype_t trace_get_link_type(const libtrace_packet_t *packet ) {
1180
1181        if (packet->link_type == 0) {
1182                if (!packet->trace->format->get_link_type)
1183                        return TRACE_TYPE_UNKNOWN;
1184                ((libtrace_packet_t *)packet)->link_type =
1185                        packet->trace->format->get_link_type(packet);
1186        }
1187
1188        return packet->link_type;
1189}
1190
1191/* process a libtrace event
1192 * @param trace the libtrace opaque pointer
1193 * @param packet the libtrace_packet opaque pointer
1194 * @returns
1195 *  TRACE_EVENT_IOWAIT  Waiting on I/O on fd
1196 *  TRACE_EVENT_SLEEP   Next event in seconds
1197 *  TRACE_EVENT_PACKET  Packet arrived in buffer with size size
1198 *  TRACE_EVENT_TERMINATE Trace terminated (perhaps with an error condition)
1199 * FIXME currently keeps a copy of the packet inside the trace pointer,
1200 * which in turn is stored inside the new packet object...
1201 */
1202DLLEXPORT libtrace_eventobj_t trace_event(libtrace_t *trace, 
1203                libtrace_packet_t *packet) {
1204        libtrace_eventobj_t event = {TRACE_EVENT_IOWAIT,0,0.0,0};
1205
1206        if (!trace) {
1207                fprintf(stderr,"You called trace_event() with a NULL trace object!\n");
1208        }
1209        assert(trace);
1210        assert(packet);
1211
1212        /* Clear the packet cache */
1213        trace_clear_cache(packet);
1214       
1215        /* Store the trace we are reading from into the packet opaque
1216         * structure */
1217        packet->trace = trace;
1218
1219        if (packet->trace->format->trace_event) {
1220                event=packet->trace->format->trace_event(trace,packet);
1221                if (event.type == TRACE_EVENT_PACKET) {
1222                        ++trace->accepted_packets;
1223                }
1224        }
1225        return event;
1226
1227}
1228
1229/** Setup a BPF filter based on pre-compiled byte-code.
1230 * @param bf_insns      A pointer to the start of the byte-code
1231 * @param bf_len        The number of BPF instructions
1232 * @returns             an opaque pointer to a libtrace_filter_t object
1233 * @note                The supplied byte-code is not checked for correctness.
1234 * @author              Scott Raynel
1235 */
1236DLLEXPORT libtrace_filter_t *
1237trace_create_filter_from_bytecode(void *bf_insns, unsigned int bf_len)
1238{
1239#ifndef HAVE_BPF_FILTER
1240        fprintf(stderr, "This version of libtrace does not have BPF support\n");
1241        return NULL;
1242#else
1243        struct libtrace_filter_t *filter = (struct libtrace_filter_t *)
1244                malloc(sizeof(struct libtrace_filter_t));
1245        filter->filter.bf_insns = (struct bpf_insn *)
1246                malloc(sizeof(struct bpf_insn) * bf_len);
1247       
1248        memcpy(filter->filter.bf_insns, bf_insns,
1249                        bf_len * sizeof(struct bpf_insn));
1250       
1251        filter->filter.bf_len = bf_len;
1252        filter->filterstring = NULL;
1253        filter->jitfilter = NULL;
1254        /* "flag" indicates that the filter member is valid */
1255        filter->flag = 1; 
1256       
1257        return filter;
1258#endif
1259}
1260
1261/* Create a BPF filter
1262 * @param filterstring a char * containing the bpf filter string
1263 * @returns opaque pointer pointer to a libtrace_filter_t object
1264 */
1265DLLEXPORT libtrace_filter_t *trace_create_filter(const char *filterstring) {
1266#ifdef HAVE_BPF_FILTER
1267        libtrace_filter_t *filter = (libtrace_filter_t*)
1268                                malloc(sizeof(libtrace_filter_t));
1269        filter->filterstring = strdup(filterstring);
1270        filter->jitfilter = NULL;
1271        filter->flag = 0;
1272        return filter;
1273#else
1274        fprintf(stderr,"This version of libtrace does not have bpf filter support\n");
1275        return NULL;
1276#endif
1277}
1278
1279DLLEXPORT void trace_destroy_filter(libtrace_filter_t *filter)
1280{
1281#ifdef HAVE_BPF_FILTER
1282        free(filter->filterstring);
1283        if (filter->flag)
1284                pcap_freecode(&filter->filter);
1285#ifdef HAVE_LLVM
1286        if (filter->jitfilter) 
1287                destroy_program(filter->jitfilter);
1288#endif
1289        free(filter);
1290#else
1291
1292#endif
1293}
1294
1295/* Compile a bpf filter, now we know the link type for the trace that we're
1296 * applying it to.
1297 *
1298 * @internal
1299 *
1300 * @returns -1 on error, 0 on success
1301 */
1302static int trace_bpf_compile(libtrace_filter_t *filter,
1303                const libtrace_packet_t *packet,
1304                void *linkptr, 
1305                libtrace_linktype_t linktype    ) {
1306#ifdef HAVE_BPF_FILTER
1307        /* It just so happens that the underlying libs used by pthread arn't
1308         * thread safe, namely lex/flex thingys, so single threaded compile
1309         * multi threaded running should be safe.
1310         */
1311        static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1312        assert(filter);
1313
1314        /* If this isn't a real packet, then fail */
1315        if (!linkptr) {
1316                trace_set_err(packet->trace,
1317                                TRACE_ERR_BAD_FILTER,"Packet has no payload");
1318                return -1;
1319        }
1320       
1321        if (filter->filterstring && ! filter->flag) {
1322                pcap_t *pcap = NULL;
1323                if (linktype==(libtrace_linktype_t)-1) {
1324                        trace_set_err(packet->trace,
1325                                        TRACE_ERR_BAD_FILTER,
1326                                        "Packet has an unknown linktype");
1327                        return -1;
1328                }
1329                if (libtrace_to_pcap_dlt(linktype) == TRACE_DLT_ERROR) {
1330                        trace_set_err(packet->trace,TRACE_ERR_BAD_FILTER,
1331                                        "Unknown pcap equivalent linktype");
1332                        return -1;
1333                }
1334                assert (pthread_mutex_lock(&mutex) == 0);
1335                /* Make sure not one bet us to this */
1336                if (filter->flag) {
1337                        printf("Someone bet us to compile the filter\n");
1338                        assert (pthread_mutex_unlock(&mutex) == 0);
1339                        return 1;
1340                }
1341                pcap=(pcap_t *)pcap_open_dead(
1342                                (int)libtrace_to_pcap_dlt(linktype),
1343                                1500U);
1344                /* build filter */
1345                assert(pcap);
1346                if (pcap_compile( pcap, &filter->filter, filter->filterstring, 
1347                                        1, 0)) {
1348                        trace_set_err(packet->trace,TRACE_ERR_BAD_FILTER,
1349                                        "Unable to compile the filter \"%s\": %s", 
1350                                        filter->filterstring,
1351                                        pcap_geterr(pcap));
1352                        pcap_close(pcap);
1353                        assert (pthread_mutex_unlock(&mutex) == 0);
1354                        return -1;
1355                }
1356                pcap_close(pcap);
1357                filter->flag=1;
1358                assert (pthread_mutex_unlock(&mutex) == 0);
1359        }
1360        return 0;
1361#else
1362        assert(!"Internal bug: This should never be called when BPF not enabled");
1363        trace_set_err(packet->trace,TRACE_ERR_OPTION_UNAVAIL,
1364                                "Feature unavailable");
1365        return -1;
1366#endif
1367}
1368
1369DLLEXPORT int trace_apply_filter(libtrace_filter_t *filter,
1370                        const libtrace_packet_t *packet) {
1371#ifdef HAVE_BPF_FILTER
1372        void *linkptr = 0;
1373        uint32_t clen = 0;
1374        bool free_packet_needed = false;
1375        int ret;
1376        libtrace_linktype_t linktype;
1377        libtrace_packet_t *packet_copy = (libtrace_packet_t*)packet;
1378#ifdef HAVE_LLVM
1379        static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1380#endif
1381
1382        assert(filter);
1383        assert(packet);
1384
1385        /* Match all non-data packets as we probably want them to pass
1386         * through to the caller */
1387        linktype = trace_get_link_type(packet);
1388
1389        if (linktype == TRACE_TYPE_NONDATA)
1390                return 1;       
1391
1392        if (libtrace_to_pcap_dlt(linktype)==TRACE_DLT_ERROR) {
1393               
1394                /* If we cannot get a suitable DLT for the packet, it may
1395                 * be because the packet is encapsulated in a link type that
1396                 * does not correspond to a DLT. Therefore, we should try
1397                 * popping off headers until we either can find a suitable
1398                 * link type or we can't do any more sensible decapsulation. */
1399               
1400                /* Copy the packet, as we don't want to trash the one we
1401                 * were passed in */
1402                packet_copy=trace_copy_packet(packet);
1403                free_packet_needed=true;
1404
1405                while (libtrace_to_pcap_dlt(linktype) == TRACE_DLT_ERROR) {
1406                        if (!demote_packet(packet_copy)) {
1407                                trace_set_err(packet->trace, 
1408                                                TRACE_ERR_NO_CONVERSION,
1409                                                "pcap does not support this format");
1410                                if (free_packet_needed) {
1411                                        trace_destroy_packet(packet_copy);
1412                                }
1413                                return -1;
1414                        }
1415                        linktype = trace_get_link_type(packet_copy);
1416                }
1417
1418        }
1419       
1420        linkptr = trace_get_packet_buffer(packet_copy,NULL,&clen);
1421        if (!linkptr) {
1422                if (free_packet_needed) {
1423                        trace_destroy_packet(packet_copy);
1424                }
1425                return 0;
1426        }
1427
1428        /* We need to compile the filter now, because before we didn't know
1429         * what the link type was
1430         */
1431        // Note internal mutex locking used here
1432        if (trace_bpf_compile(filter,packet_copy,linkptr,linktype)==-1) {
1433                if (free_packet_needed) {
1434                        trace_destroy_packet(packet_copy);
1435                }
1436                return -1;
1437        }
1438
1439        /* If we're jitting, we may need to JIT the BPF code now too */
1440#if HAVE_LLVM
1441        if (!filter->jitfilter) {
1442                assert(pthread_mutex_lock(&mutex) == 0);
1443                /* Again double check here like the bpf filter */
1444                if(filter->jitfilter) 
1445                        printf("Someone bet us to compile the JIT thingy\n");
1446                else
1447                /* Looking at compile_program source this appears to be thread safe
1448                 * however if this gets called twice we will leak this memory :(
1449                 * as such lock here anyways */
1450                        filter->jitfilter = compile_program(filter->filter.bf_insns, filter->filter.bf_len);
1451                assert(pthread_mutex_unlock(&mutex) == 0);
1452        }
1453#endif
1454
1455        assert(filter->flag);
1456        /* Now execute the filter */
1457#if HAVE_LLVM
1458        ret=filter->jitfilter->bpf_run((unsigned char *)linkptr, clen);
1459#else
1460        ret=bpf_filter(filter->filter.bf_insns,(u_char*)linkptr,(unsigned int)clen,(unsigned int)clen);
1461#endif
1462
1463        /* If we copied the packet earlier, make sure that we free it */
1464        if (free_packet_needed) {
1465                trace_destroy_packet(packet_copy);
1466        }
1467        return ret;
1468#else
1469        fprintf(stderr,"This version of libtrace does not have bpf filter support\n");
1470        return 0;
1471#endif
1472}
1473
1474/* Set the direction flag, if it has one
1475 * @param packet the packet opaque pointer
1476 * @param direction the new direction (0,1,2,3)
1477 * @returns a signed value containing the direction flag, or -1 if this is not supported
1478 */
1479DLLEXPORT libtrace_direction_t trace_set_direction(libtrace_packet_t *packet, 
1480                libtrace_direction_t direction) 
1481{
1482        assert(packet);
1483        if (packet->trace->format->set_direction) {
1484                return packet->trace->format->set_direction(packet,direction);
1485        }
1486        return (libtrace_direction_t)~0U;
1487}
1488
1489/* Get the direction flag, if it has one
1490 * @param packet a pointer to a libtrace_packet structure
1491 * @returns a signed value containing the direction flag, or -1 if this is not supported
1492 * The direction is defined as 0 for packets originating locally (ie, outbound)
1493 * and 1 for packets originating remotely (ie, inbound).
1494 * Other values are possible, which might be overloaded to mean special things
1495 * for a special trace.
1496 */
1497DLLEXPORT libtrace_direction_t trace_get_direction(const libtrace_packet_t *packet) 
1498{
1499        assert(packet);
1500        if (packet->trace->format->get_direction) {
1501                return packet->trace->format->get_direction(packet);
1502        }
1503        return (libtrace_direction_t)~0U;
1504}
1505
1506#define ROOT_SERVER(x) ((x) < 512)
1507#define ROOT_CLIENT(x) ((512 <= (x)) && ((x) < 1024))
1508#define NONROOT_SERVER(x) ((x) >= 5000)
1509#define NONROOT_CLIENT(x) ((1024 <= (x)) && ((x) < 5000))
1510#define DYNAMIC(x) ((49152 < (x)) && ((x) < 65535))
1511#define SERVER(x) ROOT_SERVER(x) || NONROOT_SERVER(x)
1512#define CLIENT(x) ROOT_CLIENT(x) || NONROOT_CLIENT(x)
1513
1514/* Attempt to deduce the 'server' port
1515 * @param protocol the IP protocol (eg, 6 or 17 for TCP or UDP)
1516 * @param source the TCP or UDP source port
1517 * @param dest the TCP or UDP destination port
1518 * @returns a hint as to which port is the server port
1519 */
1520DLLEXPORT int8_t trace_get_server_port(UNUSED uint8_t protocol, 
1521                uint16_t source, uint16_t dest) 
1522{
1523        /*
1524         * * If the ports are equal, return DEST
1525         * * Check for well-known ports in the given protocol
1526         * * Root server ports: 0 - 511
1527         * * Root client ports: 512 - 1023
1528         * * non-root client ports: 1024 - 4999
1529         * * non-root server ports: 5000+
1530         * * Check for static ranges: 1024 - 49151
1531         * * Check for dynamic ranges: 49152 - 65535
1532         * * flip a coin.
1533         */
1534       
1535        /* equal */
1536        if (source == dest)
1537                return USE_DEST;
1538
1539        /* root server port, 0 - 511 */
1540        if (ROOT_SERVER(source) && ROOT_SERVER(dest)) {
1541                if (source < dest)
1542                        return USE_SOURCE;
1543                return USE_DEST;
1544        }
1545
1546        if (ROOT_SERVER(source) && !ROOT_SERVER(dest))
1547                return USE_SOURCE;
1548        if (!ROOT_SERVER(source) && ROOT_SERVER(dest))
1549                return USE_DEST;
1550
1551        /* non-root server */
1552        if (NONROOT_SERVER(source) && NONROOT_SERVER(dest)) {
1553                if (source < dest)
1554                        return USE_SOURCE;
1555                return USE_DEST;
1556        }
1557        if (NONROOT_SERVER(source) && !NONROOT_SERVER(dest))
1558                return USE_SOURCE;
1559        if (!NONROOT_SERVER(source) && NONROOT_SERVER(dest))
1560                return USE_DEST;
1561
1562        /* root client */
1563        if (ROOT_CLIENT(source) && ROOT_CLIENT(dest)) {
1564                if (source < dest)
1565                        return USE_SOURCE;
1566                return USE_DEST;
1567        }
1568        if (ROOT_CLIENT(source) && !ROOT_CLIENT(dest)) {
1569                /* prefer root-client over nonroot-client */
1570                if (NONROOT_CLIENT(dest))
1571                        return USE_SOURCE;
1572                return USE_DEST;
1573        }
1574        if (!ROOT_CLIENT(source) && ROOT_CLIENT(dest)) {
1575                /* prefer root-client over nonroot-client */
1576                if (NONROOT_CLIENT(source))
1577                        return USE_DEST;
1578                return USE_SOURCE;
1579        }
1580       
1581        /* nonroot client */
1582        if (NONROOT_CLIENT(source) && NONROOT_CLIENT(dest)) {
1583                if (source < dest) 
1584                        return USE_SOURCE;
1585                return USE_DEST;
1586        }
1587        if (NONROOT_CLIENT(source) && !NONROOT_CLIENT(dest))
1588                return USE_DEST;
1589        if (!NONROOT_CLIENT(source) && NONROOT_CLIENT(dest))
1590                return USE_SOURCE;
1591
1592        /* dynamic range */
1593        if (DYNAMIC(source) && DYNAMIC(dest)) {
1594                if (source < dest)
1595                        return USE_SOURCE;
1596                return USE_DEST;
1597        }
1598        if (DYNAMIC(source) && !DYNAMIC(dest))
1599                return USE_DEST;
1600        if (!DYNAMIC(source) && DYNAMIC(dest))
1601                return USE_SOURCE;
1602        /*
1603        if (SERVER(source) && CLIENT(dest))
1604                return USE_SOURCE;
1605       
1606        if (SERVER(dest) && CLIENT(source))
1607                return USE_DEST;
1608        if (ROOT_SERVER(source) && !ROOT_SERVER(dest))
1609                return USE_SOURCE;
1610        if (ROOT_SERVER(dest) && !ROOT_SERVER(source))
1611                return USE_DEST;
1612        */
1613        /* failing that test... */
1614        if (source < dest) {
1615                return USE_SOURCE;
1616        } 
1617        return USE_DEST;
1618       
1619}
1620
1621/* Truncate the packet at the suggested length
1622 * @param packet        the packet opaque pointer
1623 * @param size          the new length of the packet
1624 * @returns the new size of the packet
1625 * @note size and the return size refer to the network-level payload of the
1626 * packet, and do not include any capture headers. For example, to truncate a
1627 * packet after the IP header, set size to sizeof(ethernet_header) +
1628 * sizeof(ip_header)
1629 * @note If the original network-level payload is smaller than size, then the
1630 * original size is returned and the packet is left unchanged.
1631 */
1632DLLEXPORT size_t trace_set_capture_length(libtrace_packet_t *packet, size_t size) {
1633        assert(packet);
1634
1635        if (packet->trace->format->set_capture_length) {
1636                packet->capture_length = packet->trace->format->set_capture_length(packet,size);
1637                return packet->capture_length;
1638        }
1639
1640        return ~0U;
1641}
1642
1643/* Splits a URI into two components - the format component which is seen before
1644 * the ':', and the uridata which follows the ':'.
1645 *
1646 * Returns a pointer to the URI data, but updates the format parameter to
1647 * point to a copy of the format component.
1648 */
1649
1650DLLEXPORT const char * trace_parse_uri(const char *uri, char **format) {
1651        const char *uridata = 0;
1652       
1653        if((uridata = strchr(uri,':')) == NULL) {
1654                /* Badly formed URI - needs a : */
1655                return 0;
1656        }
1657
1658        if ((unsigned)(uridata - uri) > URI_PROTO_LINE) {
1659                /* Badly formed URI - uri type is too long */
1660                return 0;
1661        }
1662
1663        /* NOTE: this is allocated memory - it should be freed by the caller
1664         * once they are done with it */
1665        *format=xstrndup(uri, (size_t)(uridata - uri));
1666
1667        /* Push uridata past the delimiter */
1668        uridata++;
1669       
1670        return uridata;
1671}
1672
1673enum base_format_t trace_get_format(libtrace_packet_t *packet) 
1674{
1675        assert(packet);
1676
1677        return packet->trace->format->type;
1678}
1679       
1680DLLEXPORT libtrace_err_t trace_get_err(libtrace_t *trace)
1681{
1682        libtrace_err_t err = trace->err;
1683        trace->err.err_num = 0; /* "OK" */
1684        trace->err.problem[0]='\0';
1685        return err;
1686}
1687
1688DLLEXPORT bool trace_is_err(libtrace_t *trace)
1689{
1690        return trace->err.err_num != 0;
1691}
1692
1693/* Prints the input error status to standard error and clears the error state */
1694DLLEXPORT void trace_perror(libtrace_t *trace,const char *msg,...)
1695{
1696        char buf[256];
1697        va_list va;
1698        va_start(va,msg);
1699        vsnprintf(buf,sizeof(buf),msg,va);
1700        va_end(va);
1701        if(trace->err.err_num) {
1702                if (trace->uridata) {
1703                        fprintf(stderr,"%s(%s): %s\n",
1704                                        buf,trace->uridata,trace->err.problem);
1705                } else {
1706                        fprintf(stderr,"%s: %s\n", buf, trace->err.problem);
1707                }
1708        } else {
1709                if (trace->uridata) {
1710                        fprintf(stderr,"%s(%s): No error\n",buf,trace->uridata);
1711                } else {
1712                        fprintf(stderr,"%s: No error\n", buf);
1713                }
1714        }
1715        trace->err.err_num = 0; /* "OK" */
1716        trace->err.problem[0]='\0';
1717}
1718
1719DLLEXPORT libtrace_err_t trace_get_err_output(libtrace_out_t *trace)
1720{
1721        libtrace_err_t err = trace->err;
1722        trace->err.err_num = TRACE_ERR_NOERROR; /* "OK" */
1723        trace->err.problem[0]='\0';
1724        return err;
1725}
1726
1727DLLEXPORT bool trace_is_err_output(libtrace_out_t *trace)
1728{
1729        return trace->err.err_num != 0;
1730}
1731
1732/* Prints the output error status to standard error and clears the error state
1733 */
1734DLLEXPORT void trace_perror_output(libtrace_out_t *trace,const char *msg,...)
1735{
1736        char buf[256];
1737        va_list va;
1738        va_start(va,msg);
1739        vsnprintf(buf,sizeof(buf),msg,va);
1740        va_end(va);
1741        if(trace->err.err_num) {
1742                fprintf(stderr,"%s(%s): %s\n",
1743                                buf,
1744                                trace->uridata?trace->uridata:"no uri",
1745                                trace->err.problem);
1746        } else {
1747                fprintf(stderr,"%s(%s): No error\n",buf,trace->uridata);
1748        }
1749        trace->err.err_num = TRACE_ERR_NOERROR; /* "OK" */
1750        trace->err.problem[0]='\0';
1751}
1752
1753DLLEXPORT int trace_seek_erf_timestamp(libtrace_t *trace, uint64_t ts)
1754{
1755        if (trace->format->seek_erf) {
1756                return trace->format->seek_erf(trace,ts);
1757        }
1758        else {
1759                if (trace->format->seek_timeval) {
1760                        struct timeval tv;
1761#if __BYTE_ORDER == __BIG_ENDIAN
1762                        tv.tv_sec = ts & 0xFFFFFFFF;
1763                        tv.tv_usec = ((ts >> 32) * 1000000) & 0xFFFFFFFF;
1764#elif __BYTE_ORDER == __LITTLE_ENDIAN
1765                        tv.tv_sec = ts >> 32;
1766                        tv.tv_usec = ((ts&0xFFFFFFFF)*1000000)>>32;
1767#else
1768#error "What on earth are you running this on?"
1769#endif
1770                        if (tv.tv_usec >= 1000000) {
1771                                tv.tv_usec -= 1000000;
1772                                tv.tv_sec += 1;
1773                        }
1774                        return trace->format->seek_timeval(trace,tv);
1775                }
1776                if (trace->format->seek_seconds) {
1777                        double seconds = 
1778                                (ts>>32) + ((ts & UINT_MAX)*1.0 / UINT_MAX);
1779                        return trace->format->seek_seconds(trace,seconds);
1780                }
1781                trace_set_err(trace,
1782                                TRACE_ERR_OPTION_UNAVAIL,
1783                                "Feature unimplemented");
1784                return -1;
1785        }
1786}
1787
1788DLLEXPORT int trace_seek_seconds(libtrace_t *trace, double seconds)
1789{
1790        if (trace->format->seek_seconds) {
1791                return trace->format->seek_seconds(trace,seconds);
1792        }
1793        else {
1794                if (trace->format->seek_timeval) {
1795                        struct timeval tv;
1796                        tv.tv_sec = (uint32_t)seconds;
1797                        tv.tv_usec = (uint32_t)(((seconds - tv.tv_sec) * 1000000)/UINT_MAX);
1798                        return trace->format->seek_timeval(trace,tv);
1799                }
1800                if (trace->format->seek_erf) {
1801                        uint64_t timestamp = 
1802                                ((uint64_t)((uint32_t)seconds) << 32) + \
1803                            (uint64_t)(( seconds - (uint32_t)seconds   ) * UINT_MAX);
1804                        return trace->format->seek_erf(trace,timestamp);
1805                }
1806                trace_set_err(trace,
1807                                TRACE_ERR_OPTION_UNAVAIL,
1808                                "Feature unimplemented");
1809                return -1;
1810        }
1811}
1812
1813DLLEXPORT int trace_seek_timeval(libtrace_t *trace, struct timeval tv)
1814{
1815        if (trace->format->seek_timeval) {
1816                return trace->format->seek_timeval(trace,tv);
1817        }
1818        else {
1819                if (trace->format->seek_erf) {
1820                        uint64_t timestamp = ((((uint64_t)tv.tv_sec) << 32) + \
1821                                (((uint64_t)tv.tv_usec * UINT_MAX)/1000000));
1822                        return trace->format->seek_erf(trace,timestamp);
1823                }
1824                if (trace->format->seek_seconds) {
1825                        double seconds = tv.tv_sec + ((tv.tv_usec * 1.0)/1000000);
1826                        return trace->format->seek_seconds(trace,seconds);
1827                }
1828                trace_set_err(trace,
1829                                TRACE_ERR_OPTION_UNAVAIL,
1830                                "Feature unimplemented");
1831                return -1;
1832        }
1833}
1834
1835/* Converts a binary ethernet MAC address into a printable string */
1836DLLEXPORT char *trace_ether_ntoa(const uint8_t *addr, char *buf)
1837{
1838        static char staticbuf[18]={0,};
1839        if (!buf)
1840                buf=staticbuf;
1841        snprintf(buf,(size_t)18,"%02x:%02x:%02x:%02x:%02x:%02x",
1842                        addr[0],addr[1],addr[2],
1843                        addr[3],addr[4],addr[5]);
1844        return buf;
1845}
1846
1847/* Converts a printable ethernet MAC address into a binary format */
1848DLLEXPORT uint8_t *trace_ether_aton(const char *buf, uint8_t *addr)
1849{
1850        uint8_t *buf2 = addr;
1851        unsigned int tmp[6];
1852        static uint8_t staticaddr[6];
1853        if (!buf2)
1854                buf2=staticaddr;
1855        sscanf(buf,"%x:%x:%x:%x:%x:%x",
1856                        &tmp[0],&tmp[1],&tmp[2],
1857                        &tmp[3],&tmp[4],&tmp[5]);
1858        buf2[0]=tmp[0]; buf2[1]=tmp[1]; buf2[2]=tmp[2];
1859        buf2[3]=tmp[3]; buf2[4]=tmp[4]; buf2[5]=tmp[5];
1860        return buf2;
1861}
1862
1863
1864/* Creates a libtrace packet from scratch using the contents of the provided
1865 * buffer as the packet payload.
1866 *
1867 * Unlike trace_prepare_packet(), the buffer should not contain any capture
1868 * format headers; instead this function will add the PCAP header to the
1869 * packet record. This also means only PCAP packets can be constructed using
1870 * this function.
1871 *
1872 */
1873DLLEXPORT
1874void trace_construct_packet(libtrace_packet_t *packet,
1875                libtrace_linktype_t linktype,
1876                const void *data,
1877                uint16_t len)
1878{
1879        size_t size;
1880        static libtrace_t *deadtrace=NULL;
1881        libtrace_pcapfile_pkt_hdr_t hdr;
1882#ifdef WIN32
1883        struct _timeb tstruct;
1884#else
1885        struct timeval tv;
1886#endif
1887
1888        /* We need a trace to attach the constructed packet to (and it needs
1889         * to be PCAP) */
1890        if (NULL == deadtrace) 
1891                deadtrace=trace_create_dead("pcapfile");
1892
1893        /* Fill in the new PCAP header */
1894#ifdef WIN32
1895        _ftime(&tstruct);
1896        hdr.ts_sec=tstruct.time;
1897        hdr.ts_usec=tstruct.millitm * 1000;
1898#else
1899        gettimeofday(&tv,NULL);
1900        hdr.ts_sec=tv.tv_sec;
1901        hdr.ts_usec=tv.tv_usec;
1902#endif
1903
1904        hdr.caplen=len;
1905        hdr.wirelen=len;
1906
1907        /* Now fill in the libtrace packet itself */
1908        packet->trace=deadtrace;
1909        size=len+sizeof(hdr);
1910        if (packet->buf_control==TRACE_CTRL_PACKET) {
1911                packet->buffer=realloc(packet->buffer,size);
1912        }
1913        else {
1914                packet->buffer=malloc(size);
1915        }
1916        packet->buf_control=TRACE_CTRL_PACKET;
1917        packet->header=packet->buffer;
1918        packet->payload=(void*)((char*)packet->buffer+sizeof(hdr));
1919       
1920        /* Ugh, memcpy - sadly necessary */
1921        memcpy(packet->header,&hdr,sizeof(hdr));
1922        memcpy(packet->payload,data,(size_t)len);
1923        packet->type=pcap_linktype_to_rt(libtrace_to_pcap_linktype(linktype));
1924
1925        trace_clear_cache(packet);
1926}
1927
1928
1929uint64_t trace_get_received_packets(libtrace_t *trace)
1930{
1931        assert(trace);
1932        if (trace->format->get_received_packets) {
1933                return trace->format->get_received_packets(trace);
1934        }
1935        return (uint64_t)-1;
1936}
1937
1938uint64_t trace_get_filtered_packets(libtrace_t *trace)
1939{
1940        assert(trace);
1941        if (trace->format->get_filtered_packets) {
1942                return trace->format->get_filtered_packets(trace)+
1943                        trace->filtered_packets;
1944        }
1945        if (trace->format->get_received_packets
1946                && trace->format->get_dropped_packets) {
1947                return 
1948                        ((trace_get_received_packets(trace)
1949                        -trace_get_accepted_packets(trace))
1950                        -trace_get_dropped_packets(trace))
1951                        +trace->filtered_packets;
1952        }
1953        return trace->filtered_packets;
1954}
1955
1956uint64_t trace_get_dropped_packets(libtrace_t *trace)
1957{
1958        assert(trace);
1959        if (trace->format->get_dropped_packets) {
1960                return trace->format->get_dropped_packets(trace);
1961        }
1962        return (uint64_t)-1;
1963}
1964
1965uint64_t trace_get_accepted_packets(libtrace_t *trace)
1966{
1967        assert(trace);
1968        return trace->accepted_packets;
1969}
1970
1971void trace_clear_cache(libtrace_packet_t *packet) {
1972
1973        packet->l2_header = NULL;
1974        packet->l3_header = NULL;
1975        packet->l4_header = NULL;
1976        packet->link_type = 0;
1977        packet->l3_ethertype = 0;
1978        packet->transport_proto = 0;
1979        packet->capture_length = -1;
1980        packet->wire_length = -1;
1981        packet->payload_length = -1;
1982        packet->l2_remaining = 0;
1983        packet->l3_remaining = 0;
1984        packet->l4_remaining = 0;
1985
1986}
1987
1988void trace_interrupt(void) {
1989        libtrace_halt = 1;
1990}
1991
1992void register_format(struct libtrace_format_t *f) {
1993        assert(f->next==NULL); /* Can't register a format twice */
1994        f->next=formats_list;
1995        formats_list=f;
1996
1997        /* Now, verify that the format has at least the minimum functionality.
1998         *
1999         * This #if can be changed to a 1 to output warnings about inconsistent
2000         * functions being provided by format modules.  This generally is very
2001         * noisy, as almost all modules don't implement one or more functions
2002         * for various reasons.  This is very useful when checking a new
2003         * format module is sane.
2004         */ 
2005#if 0
2006        if (f->init_input) {
2007#define REQUIRE(x) \
2008                if (!f->x) \
2009                        fprintf(stderr,"%s: Input format should provide " #x "\n",f->name)
2010                REQUIRE(read_packet);
2011                REQUIRE(start_input);
2012                REQUIRE(fin_input);
2013                REQUIRE(get_link_type);
2014                REQUIRE(get_capture_length);
2015                REQUIRE(get_wire_length);
2016                REQUIRE(get_framing_length);
2017                REQUIRE(trace_event);
2018                if (!f->get_erf_timestamp
2019                        && !f->get_seconds
2020                        && !f->get_timeval) {
2021                        fprintf(stderr,"%s: A trace format capable of input, should provide at least one of\n"
2022"get_erf_timestamp, get_seconds or trace_timeval\n",f->name);
2023                }
2024                if (f->trace_event!=trace_event_trace) {
2025                        /* Theres nothing that a trace file could optimise with
2026                         * config_input
2027                         */
2028                        REQUIRE(pause_input);
2029                        REQUIRE(config_input);
2030                        REQUIRE(get_fd);
2031                }
2032                else {
2033                        if (f->get_fd) {
2034                                fprintf(stderr,"%s: Unnecessary get_fd\n",
2035                                                f->name);
2036                        }
2037                }
2038#undef REQUIRE
2039        }
2040        else {
2041#define REQUIRE(x) \
2042                if (f->x) \
2043                        fprintf(stderr,"%s: Non Input format shouldn't need " #x "\n",f->name)
2044                REQUIRE(read_packet);
2045                REQUIRE(start_input);
2046                REQUIRE(pause_input);
2047                REQUIRE(fin_input);
2048                REQUIRE(get_link_type);
2049                REQUIRE(get_capture_length);
2050                REQUIRE(get_wire_length);
2051                REQUIRE(get_framing_length);
2052                REQUIRE(trace_event);
2053                REQUIRE(get_seconds);
2054                REQUIRE(get_timeval);
2055                REQUIRE(get_erf_timestamp);
2056#undef REQUIRE
2057        }
2058        if (f->init_output) {
2059#define REQUIRE(x) \
2060                if (!f->x) \
2061                        fprintf(stderr,"%s: Output format should provide " #x "\n",f->name)
2062                REQUIRE(write_packet);
2063                REQUIRE(start_output);
2064                REQUIRE(config_output);
2065                REQUIRE(fin_output);
2066#undef REQUIRE
2067        }
2068        else {
2069#define REQUIRE(x) \
2070                if (f->x) \
2071                        fprintf(stderr,"%s: Non Output format shouldn't need " #x "\n",f->name)
2072                REQUIRE(write_packet);
2073                REQUIRE(start_output);
2074                REQUIRE(config_output);
2075                REQUIRE(fin_output);
2076#undef REQUIRE
2077        }
2078#endif
2079}
2080
Note: See TracBrowser for help on using the repository browser.