- Timestamp:
- 09/15/15 11:13:07 (5 years ago)
- Branches:
- 4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
- Children:
- aafdc55
- Parents:
- 6264e8e
- Location:
- tools/traceanon
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
tools/traceanon/Makefile.am
r29bbef0 rebb54a5 1 bin_PROGRAMS = traceanon traceanon_parallel1 bin_PROGRAMS = traceanon 2 2 3 3 man_MANS = traceanon.1 … … 5 5 6 6 include ../Makefile.tools 7 traceanon_SOURCES = traceanon.c rijndael.h rijndael.c panon.h panon.c ipenc.c ipenc.h8 traceanon_ parallel_SOURCES = traceanon_parallel.c rijndael.h rijndael.c panon.h panon.c ipenc.c ipenc.h7 #traceanon_SOURCES = traceanon.c rijndael.h rijndael.c panon.h panon.c ipenc.c ipenc.h 8 traceanon_SOURCES = traceanon.cc Anon.cc Anon.h 9 9 10 # rijndael.c does lots of nasty casting that is going to be a nightmare to fix 11 # and debug - I'm going to disable this warning in the interim, as it's really 12 # messy and hopefully isn't actually an issue. 13 traceanon_CFLAGS = $(AM_CFLAGS) 14 traceanon_parallel_CFLAGS = $(AM_CFLAGS) 10 traceanon_CPPFLAGS = $(AM_CPPFLAGS) -
tools/traceanon/traceanon.cc
r8b7f254 rebb54a5 1 #define _GNU_SOURCE 1 #include "config.h" 2 #include "Anon.h" 2 3 #include "libtrace_parallel.h" 3 4 #include <stdio.h> … … 18 19 char *key = NULL; 19 20 21 int level = -1; 22 trace_option_compresstype_t compress_type = TRACE_OPTION_COMPRESSTYPE_NONE; 20 23 21 24 struct libtrace_t *trace = NULL; … … 23 26 static void cleanup_signal(int signal) 24 27 { 25 static int s = 0;26 28 (void)signal; 27 //trace_interrupt();28 29 // trace_pstop isn't really signal safe because its got lots of locks in it 29 trace_pstop(trace); 30 /*if (s == 0) { 31 if (trace_ppause(trace) == -1) 32 trace_perror(trace, "Pause failed"); 33 } 34 else { 35 if (trace_pstart(trace, NULL, NULL, NULL) == -1) 36 trace_perror(trace, "Start failed"); 37 }*/ 38 s = !s; 30 trace_pstop(trace); 39 31 } 40 32 … … 49 41 "-c --cryptopan=key Encrypt the addresses with the cryptopan\n" 50 42 " prefix preserving\n" 51 "- f--keyfile=file A file containing the cryptopan key\n"43 "-F --keyfile=file A file containing the cryptopan key\n" 52 44 "-p --prefix=C.I.D.R/bits Substitute the prefix of the address\n" 53 "- H --libtrace-help Print libtrace runtime documentation\n"45 "-h --help Print this usage information\n" 54 46 "-z --compress-level Compress the output trace at the specified level\n" 55 47 "-Z --compress-type Compress the output trace using the specified" 56 48 " compression algorithm\n" 49 "-t --threads=max Use this number of threads for packet processing\n" 57 50 ,argv0); 58 51 exit(1); … … 60 53 61 54 /* Incrementally update a checksum */ 62 static void update_in_cksum(uint16_t *csum, uint16_t old, uint16_t new )63 { 64 uint32_t sum = (~htons(*csum) & 0xFFFF) 65 + (~htons(old) & 0xFFFF) 66 + htons(new );55 static void update_in_cksum(uint16_t *csum, uint16_t old, uint16_t newval) 56 { 57 uint32_t sum = (~htons(*csum) & 0xFFFF) 58 + (~htons(old) & 0xFFFF) 59 + htons(newval); 67 60 sum = (sum & 0xFFFF) + (sum >> 16); 68 61 *csum = htons(~(sum + (sum >> 16))); 69 62 } 70 63 71 static void update_in_cksum32(uint16_t *csum, uint32_t old, uint32_t new) 72 { 73 update_in_cksum(csum,(uint16_t)(old>>16),(uint16_t)(new>>16)); 74 update_in_cksum(csum,(uint16_t)(old&0xFFFF),(uint16_t)(new&0xFFFF)); 64 UNUSED static void update_in_cksum32(uint16_t *csum, uint32_t old, 65 uint32_t newval) 66 { 67 update_in_cksum(csum,(uint16_t)(old>>16),(uint16_t)(newval>>16)); 68 update_in_cksum(csum,(uint16_t)(old&0xFFFF),(uint16_t)(newval&0xFFFF)); 75 69 } 76 70 … … 85 79 * source instead of the source and destination! 86 80 */ 87 static void encrypt_ips(struct libtrace_ip *ip,bool enc_source,bool enc_dest) 88 { 89 struct libtrace_tcp *tcp; 90 struct libtrace_udp *udp; 91 struct libtrace_icmp *icmp; 92 93 tcp=trace_get_tcp_from_ip(ip,NULL); 94 udp=trace_get_udp_from_ip(ip,NULL); 95 icmp=trace_get_icmp_from_ip(ip,NULL); 81 static void encrypt_ips(Anonymiser *anon, struct libtrace_ip *ip, 82 bool enc_source,bool enc_dest) 83 { 84 libtrace_icmp_t *icmp=trace_get_icmp_from_ip(ip,NULL); 96 85 97 86 if (enc_source) { 98 uint32_t old_ip=ip->ip_src.s_addr; 99 uint32_t new_ip=htonl(enc_ip( 100 htonl(ip->ip_src.s_addr) 101 )); 102 update_in_cksum32(&ip->ip_sum,old_ip,new_ip); 103 if (tcp) update_in_cksum32(&tcp->check,old_ip,new_ip); 104 if (udp) update_in_cksum32(&udp->check,old_ip,new_ip); 87 uint32_t new_ip=htonl(anon->anonIPv4(ntohl(ip->ip_src.s_addr))); 105 88 ip->ip_src.s_addr = new_ip; 106 89 } 107 90 108 91 if (enc_dest) { 109 uint32_t old_ip=ip->ip_dst.s_addr; 110 uint32_t new_ip=htonl(enc_ip( 111 htonl(ip->ip_dst.s_addr) 112 )); 113 update_in_cksum32(&ip->ip_sum,old_ip,new_ip); 114 if (tcp) update_in_cksum32(&tcp->check,old_ip,new_ip); 115 if (udp) update_in_cksum32(&udp->check,old_ip,new_ip); 92 uint32_t new_ip=htonl(anon->anonIPv4(ntohl(ip->ip_dst.s_addr))); 116 93 ip->ip_dst.s_addr = new_ip; 117 94 } … … 126 103 || icmp->type == 11) { 127 104 char *ptr = (char *)icmp; 128 encrypt_ips( 105 encrypt_ips(anon, 129 106 (struct libtrace_ip*)(ptr+ 130 107 sizeof(struct libtrace_icmp)), … … 138 115 } 139 116 140 141 UNUSED static uint64_t bad_hash(UNUSED libtrace_packet_t * pkt) 142 { 143 return 0; 144 } 145 146 147 UNUSED static uint64_t rand_hash(UNUSED libtrace_packet_t * pkt) 148 { 149 return rand(); 150 } 151 152 153 static void* per_packet(libtrace_t *trace, libtrace_thread_t *t, 154 int mesg, libtrace_generic_t data, 155 libtrace_thread_t *sender UNUSED) 156 { 117 static void encrypt_ipv6(Anonymiser *anon, libtrace_ip6_t *ip6, 118 bool enc_source, bool enc_dest) { 119 120 uint8_t previp[16]; 121 122 if (enc_source) { 123 memcpy(previp, &(ip6->ip_src.s6_addr), 16); 124 anon->anonIPv6(previp, (uint8_t *)&(ip6->ip_src.s6_addr)); 125 } 126 127 if (enc_dest) { 128 memcpy(previp, &(ip6->ip_dst.s6_addr), 16); 129 anon->anonIPv6(previp, (uint8_t *)&(ip6->ip_dst.s6_addr)); 130 } 131 132 } 133 134 135 static libtrace_packet_t *per_packet(libtrace_t *trace, libtrace_thread_t *t, 136 void *global, void *tls, libtrace_packet_t *packet) { 137 157 138 struct libtrace_ip *ipptr; 139 libtrace_ip6_t *ip6; 158 140 libtrace_udp_t *udp = NULL; 159 141 libtrace_tcp_t *tcp = NULL; 160 libtrace_stat_t *stats = NULL; 161 switch (mesg) { 162 case MESSAGE_PACKET: 163 ipptr = trace_get_ip(data.pkt); 164 165 if (ipptr && (enc_source || enc_dest)) { 166 encrypt_ips(ipptr,enc_source,enc_dest); 167 ipptr->ip_sum = 0; 168 } 169 170 /* Replace checksums so that IP encryption cannot be 171 * reversed */ 172 173 /* XXX replace with nice use of trace_get_transport() */ 174 175 udp = trace_get_udp(data.pkt); 176 if (udp && (enc_source || enc_dest)) { 177 udp->check = 0; 178 } 179 180 tcp = trace_get_tcp(data.pkt); 181 if (tcp && (enc_source || enc_dest)) { 182 tcp->check = 0; 183 } 184 185 /* TODO: Encrypt IP's in ARP packets */ 186 187 // Send our result keyed with the time 188 // Arg don't copy packets 189 //libtrace_packet_t * packet_copy = trace_copy_packet(packet); 190 //libtrace_packet_t * packet_copy = trace_result_packet(trace, pkt); 191 //trace_publish_result(trace, trace_packet_get_order(pkt), pkt); 192 193 trace_publish_result(trace, t, trace_packet_get_order(data.pkt), data, RESULT_PACKET); 194 break; 195 case MESSAGE_STARTING: 196 enc_init(enc_type,key); 197 break; 198 case MESSAGE_TICK_INTERVAL: 199 trace_publish_result(trace, t, data.uint64, (libtrace_generic_t){0}, RESULT_TICK_INTERVAL); 200 break; 201 case MESSAGE_TICK_COUNT: 202 trace_publish_result(trace, t, data.uint64, (libtrace_generic_t){0}, RESULT_TICK_COUNT); 203 break; 204 case MESSAGE_STOPPING: 205 stats = trace_create_statistics(); 206 trace_get_thread_statistics(trace, t, stats); 207 trace_print_statistics(stats, stderr, NULL); 208 free(stats); 209 stats = trace_get_statistics(trace, NULL); 210 trace_print_statistics(stats, stderr, NULL); 211 //fprintf(stderr, "tracestats_parallel:\t Stopping thread - publishing results\n"); 212 break; 213 } 214 return NULL; 215 } 216 217 struct libtrace_out_t *writer = 0; 218 219 static void write_out(libtrace_t *trace UNUSED, int mesg, 220 libtrace_generic_t data, 221 libtrace_thread_t *sender UNUSED) { 222 static uint64_t packet_count = 0; // TESTING PURPOSES, this is not going to work with a live format 223 224 switch (mesg) { 225 case MESSAGE_RESULT: 226 if (data.res->type == RESULT_PACKET) { 227 libtrace_packet_t *packet = (libtrace_packet_t*) data.res->value.pkt; 228 assert(data.res->key >= packet_count); 229 packet_count = data.res->key; 230 if (trace_write_packet(writer,packet)==-1) { 231 trace_perror_output(writer,"writer"); 232 trace_interrupt(); 233 } 234 trace_free_packet(trace, packet); 235 236 } else { 237 assert(data.res->type == RESULT_TICK_COUNT || data.res->type == RESULT_TICK_INTERVAL); 238 // Ignore it 239 } 240 } 241 } 242 142 libtrace_icmp6_t *icmp6 = NULL; 143 Anonymiser *anon = (Anonymiser *)tls; 144 libtrace_generic_t result; 145 146 ipptr = trace_get_ip(packet); 147 ip6 = trace_get_ip6(packet); 148 149 if (ipptr && (enc_source || enc_dest)) { 150 encrypt_ips(anon, ipptr,enc_source,enc_dest); 151 ipptr->ip_sum = 0; 152 } else if (ip6 && (enc_source || enc_dest)) { 153 encrypt_ipv6(anon, ip6, enc_source, enc_dest); 154 } 155 156 157 /* Replace checksums so that IP encryption cannot be 158 * reversed -- TODO allow checksums to be updated and remain valid 159 * for the new addresses */ 160 161 /* XXX replace with nice use of trace_get_transport() */ 162 163 udp = trace_get_udp(packet); 164 if (udp && (enc_source || enc_dest)) { 165 udp->check = 0; 166 } 167 168 tcp = trace_get_tcp(packet); 169 if (tcp && (enc_source || enc_dest)) { 170 tcp->check = 0; 171 } 172 173 icmp6 = trace_get_icmp6(packet); 174 if (icmp6 && (enc_source || enc_dest)) { 175 icmp6->checksum = 0; 176 } 177 178 /* TODO: Encrypt IP's in ARP packets */ 179 result.pkt = packet; 180 trace_publish_result(trace, t, trace_packet_get_order(packet), result, RESULT_PACKET); 181 182 return NULL; 183 } 184 185 static void *start_anon(libtrace_t *trace, libtrace_thread_t *t, void *global) 186 { 187 if (enc_type == ENC_PREFIX_SUBSTITUTION) { 188 PrefixSub *sub = new PrefixSub(key, NULL); 189 return sub; 190 } 191 192 if (enc_type == ENC_CRYPTOPAN) { 193 #ifdef HAVE_LIBCRYPTO 194 CryptoAnon *anon = new CryptoAnon((uint8_t *)key, 195 (uint8_t)strlen(key), 20); 196 return anon; 197 #else 198 /* TODO nicer way of exiting? */ 199 fprintf(stderr, "Error: requested CryptoPan anonymisation but " 200 "libtrace was built without libcrypto support!\n"); 201 exit(1); 202 #endif 203 } 204 205 return NULL; 206 } 207 208 static void end_anon(libtrace_t *trace, libtrace_thread_t *t, void *global, 209 void *tls) { 210 Anonymiser *anon = (Anonymiser *)tls; 211 delete(anon); 212 213 } 214 215 static void *init_output(libtrace_t *trace, libtrace_thread_t *t, void *global) 216 { 217 libtrace_out_t *writer = NULL; 218 char *outputname = (char *)global; 219 220 writer = trace_create_output(outputname); 221 222 if (trace_is_err_output(writer)) { 223 trace_perror_output(writer,"trace_create_output"); 224 trace_destroy_output(writer); 225 return NULL; 226 } 227 228 /* Hopefully this will deal nicely with people who want to crank the 229 * compression level up to 11 :) */ 230 if (level > 9) { 231 fprintf(stderr, "WARNING: Compression level > 9 specified, setting to 9 instead\n"); 232 level = 9; 233 } 234 235 if (level >= 0 && trace_config_output(writer, 236 TRACE_OPTION_OUTPUT_COMPRESS, &level) == -1) { 237 trace_perror_output(writer, "Configuring compression level"); 238 trace_destroy_output(writer); 239 return NULL; 240 } 241 242 if (trace_config_output(writer, TRACE_OPTION_OUTPUT_COMPRESSTYPE, 243 &compress_type) == -1) { 244 trace_perror_output(writer, "Configuring compression type"); 245 trace_destroy_output(writer); 246 return NULL; 247 } 248 249 if (trace_start_output(writer)==-1) { 250 trace_perror_output(writer,"trace_start_output"); 251 trace_destroy_output(writer); 252 return NULL; 253 } 254 255 return writer; 256 257 } 258 259 static void write_packet(libtrace_t *trace, libtrace_thread_t *sender, 260 void *global, void *tls, libtrace_result_t *result) { 261 libtrace_packet_t *packet = (libtrace_packet_t*) result->value.pkt; 262 libtrace_out_t *writer = (libtrace_out_t *)tls; 263 264 if (writer != NULL && trace_write_packet(writer,packet)==-1) { 265 trace_perror_output(writer,"writer"); 266 trace_interrupt(); 267 } 268 trace_free_packet(trace, packet); 269 } 270 271 static void end_output(libtrace_t *trace, libtrace_thread_t *t, void *global, 272 void *tls) { 273 libtrace_out_t *writer = (libtrace_out_t *)tls; 274 275 trace_destroy_output(writer); 276 } 243 277 244 278 int main(int argc, char *argv[]) … … 247 281 struct sigaction sigact; 248 282 char *output = 0; 249 int level = -1;250 283 char *compress_type_str=NULL; 251 trace_option_compresstype_t compress_type = TRACE_OPTION_COMPRESSTYPE_NONE; 252 char *config = NULL; 253 char *config_file = NULL; 284 int maxthreads = 4; 285 libtrace_callback_set_t *pktcbs = NULL; 286 libtrace_callback_set_t *repcbs = NULL; 287 int exitcode = 0; 254 288 255 289 if (argc<2) … … 262 296 { "encrypt-dest", 0, 0, 'd' }, 263 297 { "cryptopan", 1, 0, 'c' }, 264 { "cryptopan-file", 1, 0, ' f' },298 { "cryptopan-file", 1, 0, 'F' }, 265 299 { "prefix", 1, 0, 'p' }, 300 { "threads", 1, 0, 't' }, 266 301 { "compress-level", 1, 0, 'z' }, 267 302 { "compress-type", 1, 0, 'Z' }, 268 { "libtrace-help", 0, 0, 'H' }, 269 { "config", 1, 0, 'u' }, 270 { "config-file", 1, 0, 'U' }, 303 { "help", 0, 0, 'h' }, 271 304 { NULL, 0, 0, 0 }, 272 305 }; 273 306 274 int c=getopt_long(argc, argv, "Z:z:sc:f:dp: Hu:U:",307 int c=getopt_long(argc, argv, "Z:z:sc:f:dp:ht:", 275 308 long_options, &option_index); 276 309 … … 291 324 enc_type = ENC_CRYPTOPAN; 292 325 break; 293 case ' f':326 case 'F': { 294 327 if(key != NULL) { 295 328 fprintf(stderr,"You can only have one encryption type and one key\n"); … … 310 343 enc_type = ENC_CRYPTOPAN; 311 344 break; 345 } 312 346 case 'p': 313 347 if (key!=NULL) { … … 318 352 enc_type = ENC_PREFIX_SUBSTITUTION; 319 353 break; 320 case 'H': 321 trace_help(); 322 exit(1); 323 break; 324 case 'u': 325 config = optarg; 326 break; 327 case 'U': 328 config_file = optarg; 329 break; 354 case 'h': 355 usage(argv[0]); 356 case 't': 357 maxthreads=atoi(optarg); 358 if (maxthreads <= 0) 359 maxthreads = 1; 360 break; 330 361 default: 331 362 fprintf(stderr,"unknown option: %c\n",c); … … 368 399 if (trace_is_err(trace)) { 369 400 trace_perror(trace,"trace_create"); 370 trace_destroy(trace);371 return 1;401 exitcode = 1; 402 goto exitanon; 372 403 } 373 404 … … 377 408 */ 378 409 output = strdup("erf:-"); 379 writer = trace_create_output(output);380 410 } else { 381 writer = trace_create_output(argv[optind +1]); 382 } 383 if (trace_is_err_output(writer)) { 384 trace_perror_output(writer,"trace_create_output"); 385 trace_destroy_output(writer); 386 trace_destroy(trace); 387 return 1; 388 } 389 390 /* Hopefully this will deal nicely with people who want to crank the 391 * compression level up to 11 :) */ 392 if (level > 9) { 393 fprintf(stderr, "WARNING: Compression level > 9 specified, setting to 9 instead\n"); 394 level = 9; 395 } 396 397 if (level >= 0 && trace_config_output(writer, 398 TRACE_OPTION_OUTPUT_COMPRESS, &level) == -1) { 399 trace_perror_output(writer, "Configuring compression level"); 400 trace_destroy_output(writer); 401 trace_destroy(trace); 402 return 1; 403 } 404 405 if (trace_config_output(writer, TRACE_OPTION_OUTPUT_COMPRESSTYPE, 406 &compress_type) == -1) { 407 trace_perror_output(writer, "Configuring compression type"); 408 trace_destroy_output(writer); 409 trace_destroy(trace); 410 return 1; 411 } 412 413 if (trace_start_output(writer)==-1) { 414 trace_perror_output(writer,"trace_start_output"); 415 trace_destroy_output(writer); 416 trace_destroy(trace); 417 return 1; 418 } 419 411 output = argv[optind +1]; 412 } 420 413 // OK parallel changes start here 421 414 … … 424 417 * special case to have. 425 418 */ 426 427 /* Apply config */428 if (config) {429 trace_set_configuration(trace, config);430 }431 432 if (config_file) {433 FILE * f = fopen(optarg, "r");434 if (f != NULL) {435 trace_set_configuration_file(trace, f);436 fclose(f);437 } else {438 perror("Failed to open configuration file\n");439 usage(argv[0]);440 }441 }442 443 419 trace_set_combiner(trace, &combiner_ordered, (libtrace_generic_t){0}); 444 420 445 //trace_set_hasher(trace, HASHER_CUSTOM, rand_hash, NULL); 446 447 if (trace_pstart(trace, NULL, &per_packet, &write_out)==-1) { 421 pktcbs = trace_create_callback_set(); 422 trace_set_packet_cb(pktcbs, per_packet); 423 trace_set_stopping_cb(pktcbs, end_anon); 424 trace_set_starting_cb(pktcbs, start_anon); 425 426 repcbs = trace_create_callback_set(); 427 trace_set_result_cb(repcbs, write_packet); 428 trace_set_stopping_cb(repcbs, end_output); 429 trace_set_starting_cb(repcbs, init_output); 430 431 trace_set_perpkt_threads(trace, maxthreads); 432 433 if (trace_pstart(trace, output, pktcbs, repcbs)==-1) { 448 434 trace_perror(trace,"trace_start"); 449 trace_destroy_output(writer); 450 trace_destroy(trace); 451 return 1; 435 exitcode = 1; 436 goto exitanon; 452 437 } 453 438 … … 461 446 // Wait for the trace to finish 462 447 trace_join(trace); 463 464 //trace_destroy_packet(packet); 465 //print_contention_stats(trace); 466 trace_destroy(trace); 467 trace_destroy_output(writer); 468 return 0; 469 } 448 449 exitanon: 450 if (pktcbs) 451 trace_destroy_callback_set(pktcbs); 452 if (repcbs) 453 trace_destroy_callback_set(repcbs); 454 if (trace) 455 trace_destroy(trace); 456 return exitcode; 457 }
Note: See TracChangeset
for help on using the changeset viewer.