source: lib/trace.c @ e732393

cachetimestampsdevelopetsiliverc-4.0.4ringdecrementfixringperformance
Last change on this file since e732393 was e732393, checked in by Shane Alcock <salcock@…>, 3 years ago

Improve error explanation when in-libtrace filtering fails.

The typical failure case is because the packet linktype does not
correspond to a pcap DLT, which BPF needs to apply filters
properly.

Since the packets being filtered may not actually be pcap, an
error message that complains about pcap is rather confusing.
Better to be more detailed about what went wrong.

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