source: lib/trace.c @ 3296252

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

Fixes pausing the trace in the edge case that some threads have already ended.
Tidy up the state system, for both threads and the the overall state.
General tidies to the code.

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