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