source: lib/trace.c @ 2498008

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

Refactor the combining step to allow user defined functions here.

Remove the old trace_get_results, now instead simply provide a reporter function which gets called as soon as results are ready.
The combiner function used determines the order of these results and when they are released etc.
The combiner function can be selected from those built-in or a custom version can be defined results are provided when ready.
Quickly hacked the parallel tests to work with this update, these are still a bit messy.

Also some fixes some compile warnings.

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