source: lib/trace.c @ 903f64d

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 903f64d was 903f64d, checked in by Shane Alcock <salcock@…>, 5 years ago

Fix segfault when destroying a packet from an EOF'd trace.

The problem is caused by not setting packet->trace to be NULL when
read_packet is going to return EOF. As a result, the trace_destroy()
code thinks that there are no packets pointing to the trace about
to be destroyed. Since there are no packets that need to be unlinked
from the trace (i.e. have their ->trace pointers set to NULL), the
unlinking step is skipped.

In actuality, we still have the packet that we tried
to read into when we got an EOF still pointing at the trace -- as soon
as we try to destroy that packet, it tries to access the trace structure
that we just freed with trace_destroy(), causing the segfault.

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