source: lib/trace.c @ 5b4d121

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

Adds a configuration parser to make it easy to change the parallel configuration.
Adds more configuration options (Tidies some verbose debugging output).
Implements tick packets for the hasher thread case.
Some other minor bug fixes

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