Changeset e26c1fc
- Timestamp:
- 05/06/16 11:37:53 (6 years ago)
- Branches:
- 4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, master, ndag_format, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
- Children:
- 2b0eae9
- Parents:
- 89aa13f (diff), ee0805a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Files:
-
- 1 added
- 6 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
INSTALL
rc24de65 r38c00dd 39 39 40 40 41 Q. What operating systems do you support? 42 43 A. Linux, FreeBSD, Mac OS X and OpenBSD. Windows is not supported. 44 41 45 ---------------------------------- 42 46 Using libtrace: … … 44 48 The best source of information on how to use libtrace and the tools that come 45 49 with it is the libtrace wiki located at 46 http://www. wand.net.nz/trac/libtrace/wiki50 http://www.github.com/wanduow/libtrace/wiki 47 51 48 52 -
README
r3e5518a rb6cbdaf 13 13 This directory contains source code for libtrace, a userspace library for 14 14 processing of network traffic capture from live interfaces or from offline 15 traces. 15 traces. 16 16 17 17 libtrace was primarily designed for use with the real-time interface to the 18 18 Waikato DAG Capture Point software running at The University of Waikato, 19 19 and has been since extended to a range of other trace and interface formats. 20 21 Libtrace should build and run on Linux, Mac OS X, FreeBSD and OpenBSD systems. 20 22 21 23 Further information about libtrace see -
examples/tutorial/sourcedemo.c
r8835f5a ree0805a 28 28 static inline void print_ip(struct sockaddr *ip) { 29 29 30 char str[ 20];30 char str[40]; 31 31 32 32 /* Check the sockaddr family so we can cast it to the appropriate … … 37 37 /* Use inet_ntop to convert the address into a string using 38 38 * dotted decimal notation */ 39 printf("%s ", inet_ntop(AF_INET, &(v4->sin_addr), str, 20));39 printf("%s ", inet_ntop(AF_INET, &(v4->sin_addr), str, sizeof(str))); 40 40 } 41 41 … … 45 45 /* Use inet_ntop to convert the address into a string using 46 46 * IPv6 address notation */ 47 printf("%s ", inet_ntop(AF_INET6, &(v6->sin6_addr), str, 20));47 printf("%s ", inet_ntop(AF_INET6, &(v6->sin6_addr), str, sizeof(str))); 48 48 } 49 49 -
lib/format_dpdk.c
rb585975 rbb0a1f4 135 135 #else 136 136 # define DPDK_USE_LOG_LEVEL 0 137 #endif 138 139 /* 1.8.0-rc2 140 * rx/tx_conf thresholds can be set to NULL in rte_eth_rx/tx_queue_setup 141 * this uses the default values, which are better tuned per device 142 * See issue #26 143 */ 144 #if RTE_VERSION >= RTE_VERSION_NUM(1, 8, 0, 2) 145 # define DPDK_USE_NULL_QUEUE_CONFIG 1 146 #else 147 # define DPDK_USE_NULL_QUEUE_CONFIG 0 137 148 #endif 138 149 … … 898 909 */ 899 910 ret = rte_eth_tx_queue_setup(format_data->port, format_data->queue_id, 900 format_data->nb_tx_buf, rte_socket_id(), &tx_conf); 911 format_data->nb_tx_buf, rte_socket_id(), 912 DPDK_USE_NULL_QUEUE_CONFIG ? NULL : &tx_conf); 901 913 if (ret < 0) { 902 914 snprintf(err, errlen, "Intel DPDK - Cannot configure TX queue on port" … … 908 920 ret = rte_eth_rx_queue_setup(format_data->port, format_data->queue_id, 909 921 format_data->nb_rx_buf, rte_socket_id(), 910 &rx_conf, format_data->pktmbuf_pool); 922 DPDK_USE_NULL_QUEUE_CONFIG ? NULL : &rx_conf, 923 format_data->pktmbuf_pool); 911 924 if (ret < 0) { 912 925 snprintf(err, errlen, "Intel DPDK - Cannot configure RX queue on port" -
lib/libtrace.h.in
r0277ab8 r38c00dd 1425 1425 /** Create a new packet object 1426 1426 * 1427 * @return A pointer to an initialised libtrace_packet_t object 1427 * @return A pointer to an initialised libtrace_packet_t object, or NULL if 1428 * libtrace is unable to allocate space for a new packet. 1428 1429 */ 1429 1430 DLLEXPORT libtrace_packet_t *trace_create_packet(void); -
lib/trace.c
r584d907 r38c00dd 2 2 * This file is part of libtrace 3 3 * 4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton, 4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton, 5 5 * New Zealand. 6 6 * 7 * Authors: Daniel Lawson 7 * Authors: Daniel Lawson 8 8 * Perry Lorier 9 * Shane Alcock 10 * 9 * Shane Alcock 10 * 11 11 * All rights reserved. 12 12 * 13 * This code has been developed by the University of Waikato WAND 13 * This code has been developed by the University of Waikato WAND 14 14 * research group. For further information please see http://www.wand.net.nz/ 15 15 * … … 115 115 dest[n]='\0'; 116 116 } 117 117 118 118 static char *xstrndup(const char *src,size_t n) 119 { 119 { 120 120 char *ret=(char*)malloc(n+1); 121 121 if (ret==NULL) { … … 153 153 } 154 154 155 /* Prints help information for libtrace 155 /* Prints help information for libtrace 156 156 * 157 157 * Function prints out some basic help information regarding libtrace, … … 176 176 { 177 177 struct libtrace_format_t *tmp; 178 178 179 179 /* Try and guess based on filename */ 180 180 for(tmp = formats_list; tmp; tmp=tmp->next) { … … 198 198 } 199 199 } 200 200 201 201 /* No formats matched -- make sure we clean up the IO object we 202 202 * used to probe the file magic */ … … 213 213 * erf:/path/to/erf/file 214 214 * erf:/path/to/erf/file.gz 215 * erf:- 215 * erf:- (stdin) 216 216 * dag:/dev/dagcard 217 * pcapint:pcapinterface 217 * pcapint:pcapinterface (eg: pcapint:eth0) 218 218 * pcapfile:/path/to/pcap/file 219 219 * pcapfile:- … … 226 226 */ 227 227 DLLEXPORT libtrace_t *trace_create(const char *uri) { 228 libtrace_t *libtrace = 228 libtrace_t *libtrace = 229 229 (libtrace_t *)malloc(sizeof(libtrace_t)); 230 230 char *scan = 0; 231 const char *uridata = 0; 231 const char *uridata = 0; 232 232 233 233 trace_init(); … … 239 239 return NULL; 240 240 } 241 241 242 242 libtrace->err.err_num = TRACE_ERR_NOERROR; 243 243 libtrace->format=NULL; 244 244 245 245 libtrace->event.tdelta = 0.0; 246 246 libtrace->event.packet = NULL; … … 289 289 * libtrace->uridata contains the appropriate data for this 290 290 */ 291 292 /* Call the init_input function for the matching capture format */ 291 292 /* Call the init_input function for the matching capture format */ 293 293 if (libtrace->format->init_input) { 294 294 int err=libtrace->format->init_input(libtrace); 295 295 assert (err==-1 || err==0); 296 296 if (err==-1) { 297 /* init_input should call trace_set_err to set 298 * theerror message297 /* init_input should call trace_set_err to set the 298 * error message 299 299 */ 300 300 return libtrace; … … 305 305 return libtrace; 306 306 } 307 307 308 308 if (scan) 309 309 free(scan); … … 328 328 329 329 trace_init(); 330 330 331 331 libtrace->err.err_num = TRACE_ERR_NOERROR; 332 332 … … 336 336 xstrncpy(scan,uri, (size_t)(uridata - uri)); 337 337 } 338 338 339 339 libtrace->err.err_num = TRACE_ERR_NOERROR; 340 340 libtrace->format=NULL; 341 341 342 342 libtrace->event.tdelta = 0.0; 343 343 libtrace->event.packet = NULL; … … 350 350 libtrace->io = NULL; 351 351 libtrace->filtered_packets = 0; 352 352 353 353 for(tmp=formats_list;tmp;tmp=tmp->next) { 354 354 if (strlen(scan) == strlen(tmp->name) && … … 371 371 } 372 372 373 /* Creates an output trace from a URI. 373 /* Creates an output trace from a URI. 374 374 * 375 375 * @param uri the uri string describing the output format and destination 376 * @returns opaque pointer to a libtrace_output_t 376 * @returns opaque pointer to a libtrace_output_t 377 377 * 378 378 * If an error occured when attempting to open the output trace, NULL is 379 * returned and trace_errno is set. 380 */ 381 379 * returned and trace_errno is set. 380 */ 381 382 382 DLLEXPORT libtrace_out_t *trace_create_output(const char *uri) { 383 libtrace_out_t *libtrace = 383 libtrace_out_t *libtrace = 384 384 (libtrace_out_t*)malloc(sizeof(libtrace_out_t)); 385 385 386 386 char *scan = 0; 387 387 const char *uridata = 0; … … 394 394 libtrace->format = NULL; 395 395 libtrace->uridata = NULL; 396 396 397 397 /* Parse the URI to determine what capture format we want to write */ 398 398 … … 402 402 return libtrace; 403 403 } 404 404 405 405 /* Attempt to find the format in the list of supported formats */ 406 406 for(tmp=formats_list;tmp;tmp=tmp->next) { … … 471 471 472 472 /* Start an output trace */ 473 DLLEXPORT int trace_start_output(libtrace_out_t *libtrace) 473 DLLEXPORT int trace_start_output(libtrace_out_t *libtrace) 474 474 { 475 475 assert(libtrace); … … 507 507 return -1; 508 508 } 509 509 510 510 /* If the capture format supports configuration, try using their 511 511 * native configuration first */ … … 517 517 518 518 /* If we get here, either the native configuration failed or the 519 * format did not support configuration. However, libtrace can 519 * format did not support configuration. However, libtrace can 520 520 * deal with some options itself, so give that a go */ 521 521 switch(option) { … … 525 525 trace_get_err(libtrace); 526 526 } 527 if (*(int*)value<0 527 if (*(int*)value<0 528 528 || *(int*)value>LIBTRACE_PACKET_BUFSIZE) { 529 529 trace_set_err(libtrace,TRACE_ERR_BAD_STATE, … … 547 547 case TRACE_OPTION_META_FREQ: 548 548 if (!trace_is_err(libtrace)) { 549 trace_set_err(libtrace, 549 trace_set_err(libtrace, 550 550 TRACE_ERR_OPTION_UNAVAIL, 551 551 "This format does not support meta-data gathering"); … … 554 554 case TRACE_OPTION_EVENT_REALTIME: 555 555 if (!trace_is_err(libtrace)) { 556 trace_set_err(libtrace, 556 trace_set_err(libtrace, 557 557 TRACE_ERR_OPTION_UNAVAIL, 558 558 "This format does not support realtime events"); 559 559 } 560 560 return -1; 561 561 562 562 } 563 563 if (!trace_is_err(libtrace)) { … … 568 568 } 569 569 570 DLLEXPORT int trace_config_output(libtrace_out_t *libtrace, 570 DLLEXPORT int trace_config_output(libtrace_out_t *libtrace, 571 571 trace_option_output_t option, 572 572 void *value) { 573 573 574 574 /* Unlike the input options, libtrace does not natively support any of 575 575 * the output options - the format module must be able to deal with … … 625 625 * @param libtrace the output trace file to be destroyed 626 626 */ 627 DLLEXPORT void trace_destroy_output(libtrace_out_t *libtrace) 627 DLLEXPORT void trace_destroy_output(libtrace_out_t *libtrace) 628 628 { 629 629 assert(libtrace); … … 635 635 } 636 636 637 DLLEXPORT libtrace_packet_t *trace_create_packet(void) 638 { 639 libtrace_packet_t *packet = 637 DLLEXPORT libtrace_packet_t *trace_create_packet(void) 638 { 639 libtrace_packet_t *packet = 640 640 (libtrace_packet_t*)calloc((size_t)1,sizeof(libtrace_packet_t)); 641 642 if (packet == NULL) 643 return NULL; 641 644 642 645 packet->buf_control=TRACE_CTRL_PACKET; … … 646 649 647 650 DLLEXPORT libtrace_packet_t *trace_copy_packet(const libtrace_packet_t *packet) { 648 libtrace_packet_t *dest = 651 libtrace_packet_t *dest = 649 652 (libtrace_packet_t *)malloc(sizeof(libtrace_packet_t)); 650 653 if (!dest) { … … 665 668 /* Reset the cache - better to recalculate than try to convert 666 669 * the values over to the new packet */ 667 trace_clear_cache(dest); 670 trace_clear_cache(dest); 668 671 /* Ooooh nasty memcpys! This is why we want to avoid copying packets 669 672 * as much as possible */ … … 680 683 free(packet->buffer); 681 684 } 682 packet->buf_control=(buf_control_t)'\0'; 685 packet->buf_control=(buf_control_t)'\0'; 683 686 /* A "bad" value to force an assert 684 687 * if this packet is ever reused 685 688 */ 686 689 free(packet); 687 } 690 } 688 691 689 692 /* Read one packet from the trace into buffer. Note that this function will 690 693 * block until a packet is read (or EOF is reached). 691 694 * 692 * @param libtrace 693 * @param packet 695 * @param libtrace the libtrace opaque pointer 696 * @param packet the packet opaque pointer 694 697 * @returns 0 on EOF, negative value on error 695 698 * … … 704 707 return -1; 705 708 } 706 if (!(packet->buf_control==TRACE_CTRL_PACKET || packet->buf_control==TRACE_CTRL_EXTERNAL)) { 709 if (!(packet->buf_control==TRACE_CTRL_PACKET 710 || packet->buf_control==TRACE_CTRL_EXTERNAL)) { 707 711 trace_set_err(libtrace,TRACE_ERR_BAD_STATE,"Packet passed to trace_read_packet() is invalid\n"); 708 712 return -1; 709 713 } 710 714 assert(packet); 711 712 /* Store the trace we are reading from into the packet opaque 715 716 /* Store the trace we are reading from into the packet opaque 713 717 * structure */ 714 718 packet->trace = libtrace; … … 741 745 return ~0U; 742 746 } 743 747 744 748 if (filtret == 0) { 745 749 ++libtrace->filtered_packets; … … 765 769 * appropriate capture format header for the format type that the packet is 766 770 * being converted to. This also allows for a packet to be converted into 767 * just about capture format that is supported by libtrace, provided the 771 * just about capture format that is supported by libtrace, provided the 768 772 * format header is present in the buffer. 769 773 * 770 774 * This function is primarily used to convert packets received via the RT 771 775 * protocol back into their original capture format. The RT header encapsulates 772 * the original capture format header, so after removing it the packet must 776 * the original capture format header, so after removing it the packet must 773 777 * have it's header and payload pointers updated and the packet format and type 774 778 * changed, amongst other things. 775 779 * 776 * Intended only for internal use at this point - this function is not 780 * Intended only for internal use at this point - this function is not 777 781 * available through the external libtrace API. 778 782 */ … … 782 786 assert(packet); 783 787 assert(trace); 784 788 785 789 /* XXX Proper error handling?? */ 786 790 if (buffer == NULL) … … 791 795 return -1; 792 796 } 793 797 794 798 packet->trace = trace; 795 799 796 800 /* Clear packet cache */ 797 801 trace_clear_cache(packet); … … 801 805 buffer, rt_type, flags); 802 806 } 803 trace_set_err(trace, TRACE_ERR_UNSUPPORTED, 807 trace_set_err(trace, TRACE_ERR_UNSUPPORTED, 804 808 "This format does not support preparing packets\n"); 805 809 return -1; … … 815 819 DLLEXPORT int trace_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 816 820 assert(libtrace); 817 assert(packet); 821 assert(packet); 818 822 /* Verify the packet is valid */ 819 823 if (!libtrace->started) { … … 843 847 * wire lengths to be the "remaining" value. If the packet has 844 848 * been padded to increase the capture length, we don't want 845 * to allow subsequent protocol decoders to consider the 849 * to allow subsequent protocol decoders to consider the 846 850 * padding as part of the packet. 847 851 * … … 853 857 * better off returning an incomplete TCP header in that case. 854 858 */ 855 859 856 860 cap_len = trace_get_capture_length(packet); 857 861 wire_len = trace_get_wire_length(packet); … … 862 866 * massively negative wire lens. We could assert fail here on 863 867 * them, but we could at least try the capture length instead. 864 * 868 * 865 869 * You may still run into problems if you try to write that 866 870 * packet, but at least reading should work OK. … … 878 882 879 883 880 /* Get a pointer to the first byte of the packet payload 884 /* Get a pointer to the first byte of the packet payload 881 885 * 882 886 * DEPRECATED - use trace_get_packet_buffer() instead */ … … 885 889 } 886 890 887 /* Get the current time in DAG time format 888 * @param packet 891 /* Get the current time in DAG time format 892 * @param packet a pointer to a libtrace_packet structure 889 893 * @returns a 64 bit timestamp in DAG ERF format (upper 32 bits are the seconds 890 894 * past 1970-01-01, the lower 32bits are partial seconds) 891 */ 895 */ 892 896 DLLEXPORT uint64_t trace_get_erf_timestamp(const libtrace_packet_t *packet) { 893 897 if (packet->trace->format->get_erf_timestamp) { … … 915 919 return (uint64_t)0; 916 920 } 917 918 921 } 919 922 … … 924 927 * @author Daniel Lawson 925 928 * @author Perry Lorier 926 */ 929 */ 927 930 DLLEXPORT struct timeval trace_get_timeval(const libtrace_packet_t *packet) { 928 931 struct timeval tv; … … 936 939 tv.tv_sec = ts >> 32; 937 940 tv.tv_usec = ((ts&0xFFFFFFFF)*1000000)>>32; 938 939 940 941 941 if (tv.tv_usec >= 1000000) { 942 tv.tv_usec -= 1000000; 943 tv.tv_sec += 1; 944 } 942 945 } else if (packet->trace->format->get_timespec) { 943 946 struct timespec ts = packet->trace->format->get_timespec(packet); … … 968 971 ts.tv_sec = erfts >> 32; 969 972 ts.tv_nsec = ((erfts&0xFFFFFFFF)*1000000000)>>32; 970 971 972 973 973 if (ts.tv_nsec >= 1000000000) { 974 ts.tv_nsec -= 1000000000; 975 ts.tv_sec += 1; 976 } 974 977 return ts; 975 978 } else if (packet->trace->format->get_timeval) { … … 995 998 996 999 /* Get the current time in floating point seconds 997 * @param packet 1000 * @param packet a pointer to a libtrace_packet structure 998 1001 * @returns time that this packet was seen in 64bit floating point seconds 999 */ 1002 */ 1000 1003 DLLEXPORT double trace_get_seconds(const libtrace_packet_t *packet) { 1001 1004 double seconds = 0.0; … … 1024 1027 } 1025 1028 1026 DLLEXPORT size_t trace_get_capture_length(const libtrace_packet_t *packet) 1029 DLLEXPORT size_t trace_get_capture_length(const libtrace_packet_t *packet) 1027 1030 { 1028 1031 /* Cache the capture length */ … … 1031 1034 return ~0U; 1032 1035 /* Cast away constness because this is "just" a cache */ 1033 ((libtrace_packet_t*)packet)->capture_length = 1036 ((libtrace_packet_t*)packet)->capture_length = 1034 1037 packet->trace->format->get_capture_length(packet); 1035 1038 } … … 1039 1042 return packet->capture_length; 1040 1043 } 1041 1044 1042 1045 /* Get the size of the packet as it was seen on the wire. 1043 1046 * @param packet a pointer to a libtrace_packet structure … … 1046 1049 * @note Due to the trace being a header capture, or anonymisation this may 1047 1050 * not be the same as the Capture Len. 1048 */ 1051 */ 1049 1052 DLLEXPORT size_t trace_get_wire_length(const libtrace_packet_t *packet){ 1050 1053 1051 1054 if (packet->wire_length == -1) { 1052 if (!packet->trace->format->get_wire_length) 1055 if (!packet->trace->format->get_wire_length) 1053 1056 return ~0U; 1054 ((libtrace_packet_t *)packet)->wire_length = 1057 ((libtrace_packet_t *)packet)->wire_length = 1055 1058 packet->trace->format->get_wire_length(packet); 1056 1059 } … … 1062 1065 1063 1066 /* Get the length of the capture framing headers. 1064 * @param packet 1067 * @param packet the packet opaque pointer 1065 1068 * @returns the size of the packet as it was on the wire. 1066 * @note this length corresponds to the difference between the size of a 1069 * @note this length corresponds to the difference between the size of a 1067 1070 * captured packet in memory, and the captured length of the packet 1068 */ 1071 */ 1069 1072 DLLEXPORT SIMPLE_FUNCTION 1070 1073 size_t trace_get_framing_length(const libtrace_packet_t *packet) { … … 1077 1080 1078 1081 /* Get the type of the link layer 1079 * @param packet 1082 * @param packet a pointer to a libtrace_packet structure 1080 1083 * @returns libtrace_linktype_t 1081 1084 */ … … 1103 1106 * which in turn is stored inside the new packet object... 1104 1107 */ 1105 DLLEXPORT libtrace_eventobj_t trace_event(libtrace_t *trace, 1108 DLLEXPORT libtrace_eventobj_t trace_event(libtrace_t *trace, 1106 1109 libtrace_packet_t *packet) { 1107 1110 libtrace_eventobj_t event = {TRACE_EVENT_IOWAIT,0,0.0,0}; … … 1115 1118 /* Clear the packet cache */ 1116 1119 trace_clear_cache(packet); 1117 1120 1118 1121 /* Store the trace we are reading from into the packet opaque 1119 1122 * structure */ … … 1122 1125 if (packet->trace->format->trace_event) { 1123 1126 /* Note: incrementing accepted, filtered etc. packet 1124 * counters is handled by the format-specific 1127 * counters is handled by the format-specific 1125 1128 * function so don't increment them here. 1126 1129 */ … … 1149 1152 filter->filter.bf_insns = (struct bpf_insn *) 1150 1153 malloc(sizeof(struct bpf_insn) * bf_len); 1151 1154 1152 1155 memcpy(filter->filter.bf_insns, bf_insns, 1153 1156 bf_len * sizeof(struct bpf_insn)); 1154 1157 1155 1158 filter->filter.bf_len = bf_len; 1156 1159 filter->filterstring = NULL; 1157 1160 filter->jitfilter = NULL; 1158 1161 /* "flag" indicates that the filter member is valid */ 1159 filter->flag = 1; 1160 1162 filter->flag = 1; 1163 1161 1164 return filter; 1162 1165 #endif … … 1188 1191 pcap_freecode(&filter->filter); 1189 1192 #ifdef HAVE_LLVM 1190 if (filter->jitfilter) 1193 if (filter->jitfilter) 1191 1194 destroy_program(filter->jitfilter); 1192 1195 #endif … … 1206 1209 static int trace_bpf_compile(libtrace_filter_t *filter, 1207 1210 const libtrace_packet_t *packet, 1208 void *linkptr, 1211 void *linkptr, 1209 1212 libtrace_linktype_t linktype ) { 1210 1213 #ifdef HAVE_BPF_FILTER … … 1217 1220 return -1; 1218 1221 } 1219 1222 1220 1223 if (filter->filterstring && ! filter->flag) { 1221 1224 pcap_t *pcap = NULL; … … 1236 1239 /* build filter */ 1237 1240 assert(pcap); 1238 if (pcap_compile( pcap, &filter->filter, filter->filterstring, 1241 if (pcap_compile( pcap, &filter->filter, filter->filterstring, 1239 1242 1, 0)) { 1240 1243 trace_set_err(packet->trace,TRACE_ERR_BAD_FILTER, 1241 "Unable to compile the filter \"%s\": %s", 1244 "Unable to compile the filter \"%s\": %s", 1242 1245 filter->filterstring, 1243 1246 pcap_geterr(pcap)); … … 1275 1278 1276 1279 if (linktype == TRACE_TYPE_NONDATA) 1277 return 1; 1280 return 1; 1278 1281 1279 1282 if (libtrace_to_pcap_dlt(linktype)==TRACE_DLT_ERROR) { 1280 1283 1281 1284 /* If we cannot get a suitable DLT for the packet, it may 1282 1285 * be because the packet is encapsulated in a link type that … … 1284 1287 * popping off headers until we either can find a suitable 1285 1288 * link type or we can't do any more sensible decapsulation. */ 1286 1289 1287 1290 /* Copy the packet, as we don't want to trash the one we 1288 1291 * were passed in */ … … 1292 1295 while (libtrace_to_pcap_dlt(linktype) == TRACE_DLT_ERROR) { 1293 1296 if (!demote_packet(packet_copy)) { 1294 trace_set_err(packet->trace, 1297 trace_set_err(packet->trace, 1295 1298 TRACE_ERR_NO_CONVERSION, 1296 1299 "pcap does not support this format"); … … 1304 1307 1305 1308 } 1306 1309 1307 1310 linkptr = trace_get_packet_buffer(packet_copy,NULL,&clen); 1308 1311 if (!linkptr) { … … 1313 1316 } 1314 1317 1315 /* We need to compile the filter now, because before we didn't know 1318 /* We need to compile the filter now, because before we didn't know 1316 1319 * what the link type was 1317 1320 */ … … 1354 1357 * @returns a signed value containing the direction flag, or -1 if this is not supported 1355 1358 */ 1356 DLLEXPORT libtrace_direction_t trace_set_direction(libtrace_packet_t *packet, 1357 libtrace_direction_t direction) 1359 DLLEXPORT libtrace_direction_t trace_set_direction(libtrace_packet_t *packet, 1360 libtrace_direction_t direction) 1358 1361 { 1359 1362 assert(packet); … … 1372 1375 * for a special trace. 1373 1376 */ 1374 DLLEXPORT libtrace_direction_t trace_get_direction(const libtrace_packet_t *packet) 1377 DLLEXPORT libtrace_direction_t trace_get_direction(const libtrace_packet_t *packet) 1375 1378 { 1376 1379 assert(packet); … … 1387 1390 #define DYNAMIC(x) ((49152 < (x)) && ((x) < 65535)) 1388 1391 #define SERVER(x) ROOT_SERVER(x) || NONROOT_SERVER(x) 1389 #define CLIENT(x) ROOT_CLIENT(x) || NONROOT_CLIENT(x) 1392 #define CLIENT(x) ROOT_CLIENT(x) || NONROOT_CLIENT(x) 1390 1393 1391 1394 /* Attempt to deduce the 'server' port … … 1395 1398 * @returns a hint as to which port is the server port 1396 1399 */ 1397 DLLEXPORT int8_t trace_get_server_port(UNUSED uint8_t protocol, 1398 uint16_t source, uint16_t dest) 1400 DLLEXPORT int8_t trace_get_server_port(UNUSED uint8_t protocol, 1401 uint16_t source, uint16_t dest) 1399 1402 { 1400 1403 /* … … 1409 1412 * * flip a coin. 1410 1413 */ 1411 1414 1412 1415 /* equal */ 1413 1416 if (source == dest) … … 1455 1458 return USE_SOURCE; 1456 1459 } 1457 1460 1458 1461 /* nonroot client */ 1459 1462 if (NONROOT_CLIENT(source) && NONROOT_CLIENT(dest)) { 1460 if (source < dest) 1463 if (source < dest) 1461 1464 return USE_SOURCE; 1462 1465 return USE_DEST; … … 1478 1481 return USE_SOURCE; 1479 1482 /* 1480 if (SERVER(source) && CLIENT(dest)) 1483 if (SERVER(source) && CLIENT(dest)) 1481 1484 return USE_SOURCE; 1482 1483 if (SERVER(dest) && CLIENT(source)) 1485 1486 if (SERVER(dest) && CLIENT(source)) 1484 1487 return USE_DEST; 1485 if (ROOT_SERVER(source) && !ROOT_SERVER(dest)) 1488 if (ROOT_SERVER(source) && !ROOT_SERVER(dest)) 1486 1489 return USE_SOURCE; 1487 if (ROOT_SERVER(dest) && !ROOT_SERVER(source)) 1490 if (ROOT_SERVER(dest) && !ROOT_SERVER(source)) 1488 1491 return USE_DEST; 1489 1492 */ … … 1491 1494 if (source < dest) { 1492 1495 return USE_SOURCE; 1493 } 1496 } 1494 1497 return USE_DEST; 1495 1498 1496 1499 } 1497 1500 … … 1522 1525 * 1523 1526 * Returns a pointer to the URI data, but updates the format parameter to 1524 * point to a copy of the format component. 1527 * point to a copy of the format component. 1525 1528 */ 1526 1529 1527 1530 DLLEXPORT const char * trace_parse_uri(const char *uri, char **format) { 1528 1531 const char *uridata = 0; 1529 1532 1530 1533 if((uridata = strchr(uri,':')) == NULL) { 1531 1534 /* Badly formed URI - needs a : */ … … 1544 1547 /* Push uridata past the delimiter */ 1545 1548 uridata++; 1546 1549 1547 1550 return uridata; 1548 1551 } 1549 1552 1550 enum base_format_t trace_get_format(libtrace_packet_t *packet) 1553 enum base_format_t trace_get_format(libtrace_packet_t *packet) 1551 1554 { 1552 1555 assert(packet); … … 1554 1557 return packet->trace->format->type; 1555 1558 } 1556 1559 1557 1560 DLLEXPORT libtrace_err_t trace_get_err(libtrace_t *trace) 1558 1561 { … … 1652 1655 } 1653 1656 if (trace->format->seek_seconds) { 1654 double seconds = 1657 double seconds = 1655 1658 (ts>>32) + ((ts & UINT_MAX)*1.0 / UINT_MAX); 1656 1659 return trace->format->seek_seconds(trace,seconds); … … 1676 1679 } 1677 1680 if (trace->format->seek_erf) { 1678 uint64_t timestamp = 1681 uint64_t timestamp = 1679 1682 ((uint64_t)((uint32_t)seconds) << 32) + \ 1680 1683 (uint64_t)(( seconds - (uint32_t)seconds ) * UINT_MAX); … … 1739 1742 1740 1743 1741 /* Creates a libtrace packet from scratch using the contents of the provided 1744 /* Creates a libtrace packet from scratch using the contents of the provided 1742 1745 * buffer as the packet payload. 1743 1746 * 1744 1747 * Unlike trace_prepare_packet(), the buffer should not contain any capture 1745 * format headers; instead this function will add the PCAP header to the 1748 * format headers; instead this function will add the PCAP header to the 1746 1749 * packet record. This also means only PCAP packets can be constructed using 1747 1750 * this function. … … 1765 1768 /* We need a trace to attach the constructed packet to (and it needs 1766 1769 * to be PCAP) */ 1767 if (NULL == deadtrace) 1770 if (NULL == deadtrace) 1768 1771 deadtrace=trace_create_dead("pcapfile"); 1769 1772 … … 1783 1786 1784 1787 /* Now fill in the libtrace packet itself */ 1788 assert(deadtrace); 1785 1789 packet->trace=deadtrace; 1786 1790 size=len+sizeof(hdr); 1791 if (size < LIBTRACE_PACKET_BUFSIZE) 1792 size = LIBTRACE_PACKET_BUFSIZE; 1787 1793 if (packet->buf_control==TRACE_CTRL_PACKET) { 1788 packet->buffer=realloc(packet->buffer,size);1794 packet->buffer = realloc(packet->buffer, size); 1789 1795 } 1790 1796 else { 1791 packet->buffer =malloc(size);1797 packet->buffer = malloc(size); 1792 1798 } 1793 1799 packet->buf_control=TRACE_CTRL_PACKET; 1794 1800 packet->header=packet->buffer; 1795 1801 packet->payload=(void*)((char*)packet->buffer+sizeof(hdr)); 1796 1797 /* Ugh, memcpy - sadly necessary */ 1798 memcpy(packet->header,&hdr,sizeof(hdr)); 1799 memcpy(packet->payload,data,(size_t)len); 1802 1803 /* Ugh, memmove - sadly necessary, also beware that we might be 1804 * moving data around within this packet, so ordering is important. 1805 */ 1806 memmove(packet->payload, data, (size_t)len); 1807 memmove(packet->header, &hdr, sizeof(hdr)); 1800 1808 packet->type=pcap_linktype_to_rt(libtrace_to_pcap_linktype(linktype)); 1801 1809 … … 1865 1873 1866 1874 /* Now, verify that the format has at least the minimum functionality. 1867 * 1875 * 1868 1876 * This #if can be changed to a 1 to output warnings about inconsistent 1869 1877 * functions being provided by format modules. This generally is very 1870 1878 * noisy, as almost all modules don't implement one or more functions 1871 * for various reasons. This is very useful when checking a new 1879 * for various reasons. This is very useful when checking a new 1872 1880 * format module is sane. 1873 */ 1881 */ 1874 1882 #if 0 1875 1883 if (f->init_input) { … … 1885 1893 REQUIRE(get_framing_length); 1886 1894 REQUIRE(trace_event); 1887 if (!f->get_erf_timestamp 1895 if (!f->get_erf_timestamp 1888 1896 && !f->get_seconds 1889 1897 && !f->get_timeval) { -
tools/tracesplit/tracesplit.1
r17f954f r7affaae 5 5 .B tracesplit 6 6 [ \fB-f \fRbpf | \fB--filter=\fRbpf] 7 [ \fB-j \fRnumhdrs | \fB--jump=\fRnumhdrs] 7 8 [ \fB-c \fRcount | \fB--count=\fRcount] 8 9 [ \fB-b \fRbytes | \fB--bytes=\fRbytes] … … 20 21 \fB\-f\fR bpf filter 21 22 output only packets that match tcpdump style bpf filter 23 24 .TP 25 \fB\-j\fR numhdrs 26 Strip headers before the numhdrs layer 3 header. For example, \-j1 will strip 27 off all the layer 2 headers, \-j2 will strip off all the l2 headers, the first 28 l3 header, any transport headers, and return a trace that starts at the next 29 l3 header. 22 30 23 31 .TP -
tools/tracesplit/tracesplit.c
r17f954f ra1935fa 25 25 uint64_t filescreated = 0; 26 26 uint16_t snaplen = 0; 27 int jump=0; 27 28 int verbose=0; 28 29 int compress_level=-1; … … 56 57 "-e --endtime=time End at time\n" 57 58 "-m --maxfiles=n Create a maximum of n trace files\n" 59 "-j --jump=n Jump to the nth IP header\n" 58 60 "-H --libtrace-help Print libtrace runtime documentation\n" 59 61 "-S --snaplen Snap packets at the specified length\n" … … 75 77 76 78 79 static libtrace_packet_t *perform_jump(libtrace_packet_t *packet, int jump) 80 { 81 uint16_t ethertype; 82 uint32_t remaining; 83 uint8_t ipproto; 84 void *offset = trace_get_layer3(packet, ðertype, &remaining); 85 while(jump > 0 && offset) { 86 --jump; 87 switch (ethertype) { 88 case TRACE_ETHERTYPE_IP: 89 if (jump <= 0) { 90 void *newpacket = trace_create_packet(); 91 trace_construct_packet(newpacket, 92 TRACE_TYPE_NONE, 93 offset, 94 remaining); 95 return newpacket; 96 } 97 offset = trace_get_payload_from_ip(offset, 98 &ipproto, 99 &remaining); 100 if (!offset) 101 return NULL; 102 break; 103 case TRACE_ETHERTYPE_IPV6: 104 if (jump <= 0) { 105 void *newpacket = trace_create_packet(); 106 trace_construct_packet(newpacket, 107 TRACE_TYPE_NONE, 108 offset, 109 remaining); 110 return newpacket; 111 } 112 offset = trace_get_payload_from_ip6(offset, 113 &ipproto, 114 &remaining); 115 if (!offset) 116 return NULL; 117 break; 118 /* TODO: vlan, etc */ 119 default: 120 return NULL; 121 } 122 if (!offset) 123 return false; 124 switch (ipproto) { 125 case TRACE_IPPROTO_IPV6: 126 ethertype = TRACE_ETHERTYPE_IPV6; 127 continue; 128 case TRACE_IPPROTO_IPIP: 129 ethertype = TRACE_ETHERTYPE_IP; 130 continue; 131 case TRACE_IPPROTO_GRE: 132 if (remaining < sizeof(libtrace_gre_t)) { 133 return NULL; 134 } 135 ethertype = ((libtrace_gre_t *)offset)->ethertype; 136 offset = trace_get_payload_from_gre(offset, &remaining); 137 continue; 138 case TRACE_IPPROTO_UDP: 139 offset = trace_get_vxlan_from_udp(offset, &remaining); 140 if (!offset) 141 return NULL; 142 offset = trace_get_payload_from_vxlan(offset, &remaining); 143 if (!offset) 144 return NULL; 145 offset = trace_get_payload_from_layer2(offset, 146 TRACE_TYPE_ETH, 147 ðertype, 148 &remaining); 149 if (!offset) 150 return NULL; 151 continue; 152 } 153 return NULL; 154 } 155 return NULL; 156 } 157 158 77 159 /* Return values: 78 160 * 1 = continue reading packets … … 80 162 * -1 = stop reading packets, we've got an error 81 163 */ 82 static int per_packet(libtrace_packet_t * packet) {83 84 if (trace_get_link_type( packet) == ~0U) {164 static int per_packet(libtrace_packet_t **packet) { 165 166 if (trace_get_link_type(*packet) == -1) { 85 167 fprintf(stderr, "Halted due to being unable to determine linktype - input trace may be corrupt.\n"); 86 168 return -1; … … 88 170 89 171 if (snaplen>0) { 90 trace_set_capture_length( packet,snaplen);91 } 92 93 if (trace_get_seconds( packet)<starttime) {172 trace_set_capture_length(*packet,snaplen); 173 } 174 175 if (trace_get_seconds(*packet)<starttime) { 94 176 return 1; 95 177 } 96 178 97 if (trace_get_seconds( packet)>endtime) {179 if (trace_get_seconds(*packet)>endtime) { 98 180 return 0; 99 181 } 100 182 101 183 if (firsttime==0) { 102 time_t now = trace_get_seconds( packet);184 time_t now = trace_get_seconds(*packet); 103 185 if (starttime != 0) { 104 186 firsttime=now-((now - starttime)%interval); … … 109 191 } 110 192 111 if (output && trace_get_seconds( packet)>firsttime+interval) {193 if (output && trace_get_seconds(*packet)>firsttime+interval) { 112 194 trace_destroy_output(output); 113 195 output=NULL; … … 121 203 122 204 pktcount++; 123 totbytes+=trace_get_capture_length( packet);205 totbytes+=trace_get_capture_length(*packet); 124 206 if (output && totbytes-totbyteslast>=bytes) { 125 207 trace_destroy_output(output); … … 198 280 } 199 281 200 /* Some traces we have are padded (usually with 0x00), so 282 /* Some traces we have are padded (usually with 0x00), so 201 283 * lets sort that out now and truncate them properly 202 284 */ 203 285 204 if (trace_get_capture_length(packet) 205 > trace_get_wire_length(packet)) { 206 trace_set_capture_length(packet,trace_get_wire_length(packet)); 207 } 208 209 if (trace_write_packet(output,packet)==-1) { 286 if (trace_get_capture_length(*packet) 287 > trace_get_wire_length(*packet)) { 288 trace_set_capture_length(*packet, 289 trace_get_wire_length(*packet)); 290 } 291 292 /* Support "jump"ping to the nth IP header. */ 293 if (jump) { 294 /* Skip headers */ 295 void *newpacket = perform_jump(*packet, jump); 296 if (newpacket) { 297 trace_destroy_packet(*packet); 298 *packet = newpacket; 299 } 300 else /* Skip packet */ 301 return 1; 302 } 303 304 if (trace_write_packet(output, *packet)==-1) { 210 305 trace_perror_output(output,"write_packet"); 211 306 return -1; … … 223 318 struct libtrace_packet_t *packet = trace_create_packet(); 224 319 struct sigaction sigact; 225 int i; 226 320 int i; 321 227 322 if (argc<2) { 228 323 usage(argv[0]); … … 240 335 { "endtime", 1, 0, 'e' }, 241 336 { "interval", 1, 0, 'i' }, 337 { "jump", 1, 0, 'j' }, 242 338 { "libtrace-help", 0, 0, 'H' }, 243 339 { "maxfiles", 1, 0, 'm' }, … … 249 345 }; 250 346 251 int c=getopt_long(argc, argv, " f:c:b:s:e:i:m:S:Hvz:Z:",347 int c=getopt_long(argc, argv, "j:f:c:b:s:e:i:m:S:Hvz:Z:", 252 348 long_options, &option_index); 253 349 … … 268 364 case 'i': interval=atoi(optarg); 269 365 break; 366 case 'j': jump=atoi(optarg); 367 break; 270 368 case 'm': maxfiles=atoi(optarg); 271 369 break; … … 283 381 if (compress_level<0 || compress_level>9) { 284 382 usage(argv[0]); 285 383 exit(1); 286 384 } 287 385 break; 288 386 case 'Z': 289 387 compress_type_str=optarg; 290 break; 388 break; 291 389 default: 292 390 fprintf(stderr,"Unknown option: %c\n",c); … … 321 419 compress_type = TRACE_OPTION_COMPRESSTYPE_NONE; 322 420 } else { 323 fprintf(stderr, "Unknown compression type: %s\n", 421 fprintf(stderr, "Unknown compression type: %s\n", 324 422 compress_type_str); 325 423 return 1; … … 348 446 349 447 350 input = trace_create(argv[i]); 351 448 input = trace_create(argv[i]); 449 352 450 if (trace_is_err(input)) { 353 451 trace_perror(input,"%s",argv[i]); … … 356 454 357 455 if (filter && trace_config(input, TRACE_OPTION_FILTER, filter) == 1) { 358 trace_perror(input, "Configuring filter for %s", 456 trace_perror(input, "Configuring filter for %s", 359 457 argv[i]); 360 458 return 1; … … 367 465 368 466 while (trace_read_packet(input,packet)>0) { 369 if (per_packet( packet) < 1)467 if (per_packet(&packet) < 1) 370 468 done = 1; 371 469 if (done)
Note: See TracChangeset
for help on using the changeset viewer.