00001
00002
00003
00031 #include <libnet.h>
00032 #include <pcap.h>
00033 #include <errno.h>
00034 #include <sys/time.h>
00035 #include <stdio.h>
00036 #include <sys/types.h>
00037 #include <arpa/inet.h>
00038 #include <signal.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <netinet/in.h>
00042 #include <netdb.h>
00043 #include <ctype.h>
00044 #include <unistd.h>
00045 #include <assert.h>
00046
00047 #include "traceproto.h"
00048 #include "config.h"
00049 #include "tp_as.h"
00050 #include "tp_miscfunc.h"
00051 #include "tp_output.h"
00052 #include "tp_packet.h"
00053
00054 #ifdef HAVE_LIBDMALLOC
00055 #include <dmalloc.h>
00056 #endif
00057
00058 int main( int argc, char * argv[] )
00059 {
00060
00061
00062 int cmd_arg, i, l;
00063 u_int on = 1;
00064 char * opt_string;
00065 char * env_string;
00066
00067 #ifdef HAVE_LIBCAP
00068 dropexcesscapabilities();
00069 #endif
00070
00071
00072
00073
00074 if ( reg_name( argv[ 0 ] ) == 0 )
00075 {
00076 printf ( "setup error, unable to parse program name\n" );
00077 tixe ( tixe_cleanup, 1 );
00078 }
00079
00080
00081
00082
00083 behavior.continuous = NO;
00084 behavior.packets_per_hop = 3;
00085 behavior.src_port_incr = 1;
00086 behavior.dst_port_incr = 0;
00087 behavior.min_src_port = 10240;
00088 behavior.rndm_src_port = YES;
00089 behavior.min_dst_port = 80;
00090 behavior.max_ttl = 30;
00091 behavior.min_ttl = 1;
00092 behavior.wait_timeout = 5;
00093 behavior.wait_between_packets = 100;
00094 behavior.protocol = "tcp";
00095 behavior.tcp_resets = YES;
00096 behavior.account_level = TP_ACCOUNT_FULL;
00097 behavior.report = report_std;
00098 behavior.do_audit = NO;
00099 behavior.do_audit_exit = NO;
00100 behavior.do_skip = NO;
00101 behavior.as_discovery = NO;
00102 behavior.output_style = TP_STD_OUTPUT;
00103 behavior.payload_size = 12;
00104 behavior.libnet_resolve_choice = LIBNET_RESOLVE;
00105 behavior.hop_incr_unit = 1;
00106 behavior.timestamp = NO;
00107 behavior.timestamp_style = TP_TIMESTAMP_STD;
00108 behavior.filter_text = "( host %s and dst port %d and src port %d ) or ( icmp[12:2] == %d )";
00109 behavior.default_if = YES;
00110 memset ( behavior.interface, '\0', TP_IF_ARRAY );
00111 strncpy ( behavior.interface, "any", TP_IF_ARRAY - 1 );
00112
00113 packet.protocol_number = IPPROTO_TCP;
00114 packet.payload = 0;
00115 packet.frag_bit = 0;
00116 packet.tcp_flags = TH_SYN;
00117 packet.ip_packet_len = LIBNET_IPV4_H;
00118
00119 state.tcp_h = LIBNET_PTAG_INITIALIZER;
00120 state.udp_h = LIBNET_PTAG_INITIALIZER;
00121 state.icmp_h = LIBNET_PTAG_INITIALIZER;
00122 state.ip_h = LIBNET_PTAG_INITIALIZER;
00123 state.incr_error = NO;
00124 state.target_response = NO;
00125 state.continuous_count = ( int ) NULL;
00126
00127
00128
00129
00130
00131
00132
00133 if ( strncmp ( state.prog, "traceroute", 11 ) == 0 )
00134 {
00135 behavior.output_style = TP_CLASSIC_OUTPUT;
00136 behavior.protocol = "udp";
00137 behavior.min_dst_port = 32768 + 666;
00138 behavior.account_level = TP_ACCOUNT_NONE;
00139 behavior.src_port_incr = 0;
00140 behavior.dst_port_incr = 1;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 env_string = NULL;
00157 if ( ( env_string = getenv ( "TP_TIMESTAMP_STYLE" ) ) != NULL )
00158 {
00159 if ( strncmp ( env_string, "std", 3 ) == 0 )
00160 behavior.timestamp_style = TP_TIMESTAMP_STD;
00161 else if ( strncmp ( env_string, "us", 2 ) == 0 )
00162 behavior.timestamp_style = TP_TIMESTAMP_US;
00163 else if ( strncmp ( env_string, "desc", 4 ) == 0 )
00164 behavior.timestamp_style = TP_TIMESTAMP_DESCEND;
00165 else if ( strncmp ( env_string, "epoch", 5 ) == 0 )
00166 behavior.timestamp_style = TP_TIMESTAMP_EPOCH;
00167 else
00168 behavior.timestamp_style = TP_TIMESTAMP_STD;
00169 }
00170
00171 env_string = NULL;
00172 if ( ( env_string = getenv ( "TP_DEFAULT_IF" ) ) != NULL )
00173 {
00174 strncpy ( behavior.interface, env_string, TP_IF_ARRAY - 1 );
00175 behavior.default_if = NO;
00176 }
00177
00178 env_string = NULL;
00179 if ( ( env_string = getenv ( "TP_OUTPUT_STYLE" ) ) != NULL )
00180 {
00181 if (
00182 strncmp ( env_string, "stand", 5 ) == 0 ||
00183 strncmp ( env_string, "std", 3 ) == 0 ||
00184 strncmp ( env_string, "s", 1 ) == 0 )
00185 {
00186 behavior.output_style = TP_STD_OUTPUT;
00187 behavior.report = report_std;
00188 } else if (
00189 strncmp ( env_string, "graph", 5 ) == 0 ||
00190 strncmp ( env_string, "g", 1 ) == 0 )
00191 {
00192 behavior.output_style = TP_GRAPHIC_OUTPUT;
00193 behavior.report = report_graphic;
00194 } else if (
00195 strncmp ( env_string, "class", 5 ) == 0 ||
00196 strncmp ( env_string, "c", 1 ) == 0 )
00197 {
00198 behavior.output_style = TP_CLASSIC_OUTPUT;
00199 behavior.report = report_classic;
00200 } else if (
00201 strncmp ( env_string, "no", 2 ) == 0 ||
00202 strncmp ( env_string, "n", 1 ) == 0 )
00203 {
00204 behavior.output_style = TP_NO_OUTPUT;
00205 behavior.report = report_none;
00206 } else if (
00207 strncmp ( env_string, "min", 3 ) == 0 ||
00208 strncmp ( env_string, "m", 1 ) == 0 )
00209 {
00210 behavior.output_style = TP_MIN_OUTPUT;
00211 behavior.report = report_minimum;
00212 } else if (
00213 strncmp ( env_string, "script", 6 ) == 0 ||
00214 strncmp ( env_string, "p", 1 ) == 0 )
00215 {
00216 behavior.output_style = TP_SCRIPT_OUTPUT;
00217 behavior.report = report_scriptable;
00218 } else if (
00219 strncmp ( env_string, "curs", 4 ) == 0 ||
00220 strncmp ( env_string, "ncurs", 5 ) == 0 ||
00221 strncmp ( env_string, "C", 1 ) == 0 )
00222 {
00223 behavior.output_style = TP_CURSES_OUTPUT;
00224 behavior.report = report_curses;
00225 tixe_cleanup.curses_end = YES;
00226 } else {
00227 behavior.output_style = TP_STD_OUTPUT;
00228 behavior.report = report_std;
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237 while ( ( cmd_arg = getopt ( argc, argv,
00238 "cCvnhRfATp:i:I:D:r:t:k:o:a:s:S:H:d:M:m:w:W:F:p:P:z:"
00239 ) ) != EOF )
00240 {
00241 switch ( cmd_arg )
00242 {
00243 case 'c':
00244 behavior.continuous = YES;
00245 behavior.continuous_accounting = NO;
00246 break;
00247 case 'C':
00248 behavior.continuous = YES;
00249 behavior.continuous_accounting = YES;
00250 break;
00251 case 'I':
00252 state.continuous_count = atoi ( optarg );
00253 behavior.continuous = YES;
00254 break;
00255 case 'H':
00256 behavior.packets_per_hop = atoi ( optarg );
00257 break;
00258 case 'i':
00259
00260
00261
00262
00263 opt_string = optarg;
00264 for ( i = strlen ( opt_string ); i >= 0; i-- )
00265 {
00266 switch ( opt_string [ i ] )
00267 {
00268 case 's':
00269 behavior.src_port_incr = -1;
00270 break;
00271 case 'S':
00272 behavior.src_port_incr = 1;
00273 break;
00274 case 'd':
00275 behavior.dst_port_incr = -1;
00276 break;
00277 case 'D':
00278 behavior.dst_port_incr = 1;
00279 break;
00280 case 'n':
00281 behavior.src_port_incr = 0;
00282 break;
00283 case 'N':
00284 behavior.dst_port_incr = 0;
00285 break;
00286 case '\0':
00287 break;
00288 default:
00289 state.incr_error = YES;
00290 break;
00291 }
00292 }
00293 break;
00294 case 'd':
00295 behavior.min_dst_port = atoi( optarg );
00296 break;
00297 case 'D':
00298 behavior.max_dst_port = atoi( optarg );
00299 break;
00300 case 'm':
00301 behavior.min_ttl = atoi ( optarg );
00302 break;
00303 case 'M':
00304 behavior.max_ttl = atoi( optarg );
00305 break;
00306 case 'n':
00307 behavior.libnet_resolve_choice = LIBNET_DONT_RESOLVE;
00308 break;
00309 case 'w':
00310
00311 behavior.wait_timeout = atoi ( optarg );
00312 break;
00313 case 'W':
00314
00315
00316 behavior.wait_between_packets = atoi ( optarg );
00317 break;
00318 case 's':
00319 behavior.min_src_port = atoi ( optarg );
00320 behavior.rndm_src_port = NO;
00321 break;
00322 case 'S':
00323 behavior.max_src_port = atoi ( optarg );
00324 behavior.rndm_src_port = NO;
00325 break;
00326 case 'p':
00327 behavior.protocol = optarg;
00328 break;
00329 case 'a':
00330 behavior.account_level = atoi ( optarg );
00331 break;
00332 case 'k':
00333
00334 behavior.skip_str = optarg;
00335 behavior.do_skip = YES;
00336 break;
00337 case 'h':
00338 usage ( );
00339 tixe ( tixe_cleanup, 0 );
00340 break;
00341 case 'v':
00342 version ( );
00343 tixe ( tixe_cleanup, 1 );
00344 break;
00345 case 'o':
00346
00347 opt_string = optarg;
00348 if ( opt_string [ 0 ] == 's' )
00349 {
00350 behavior.output_style = TP_STD_OUTPUT;
00351 behavior.report = report_std;
00352 break;
00353 } else if ( opt_string [ 0 ] == 'g' ) {
00354 behavior.output_style = TP_GRAPHIC_OUTPUT;
00355 behavior.report = report_graphic;
00356 break;
00357 } else if ( opt_string [ 0 ] == 'c' ) {
00358 behavior.output_style = TP_CLASSIC_OUTPUT;
00359 behavior.report = report_classic;
00360 break;
00361 } else if ( opt_string [ 0 ] == 'C' ) {
00362 behavior.output_style = TP_CURSES_OUTPUT;
00363 behavior.report = report_curses;
00364 break;
00365 } else if ( opt_string [ 0 ] == 'n' ) {
00366 behavior.output_style = TP_NO_OUTPUT;
00367 behavior.report = report_none;
00368 break;
00369 } else if ( opt_string [ 0 ] == 'm' ) {
00370 behavior.output_style = TP_MIN_OUTPUT;
00371 behavior.report = report_minimum;
00372 break;
00373 } else if ( opt_string [ 0 ] == 'p' ) {
00374 behavior.output_style = TP_SCRIPT_OUTPUT;
00375 behavior.report = report_scriptable;
00376 break;
00377 } else {
00378 printf ( "invalid output style: %c\n", * opt_string );
00379 usage ( );
00380 tixe ( tixe_cleanup, 1 );
00381 }
00382 break;
00383 case 't':
00384
00385 opt_string = optarg;
00386 packet.tcp_flags = parse_flags ( opt_string );
00387 break;
00388 case 'P':
00389 behavior.payload_size = atoi ( optarg );
00390 break;
00391 case 'f':
00392 packet.frag_bit = TP_DONT_FRAG;
00393 break;
00394 case 'F':
00395 strncpy ( behavior.interface, optarg, TP_IF_ARRAY - 1 );
00396 behavior.default_if = NO;
00397 break;
00398 case 'A':
00399 behavior.as_discovery = YES;
00400 break;
00401 case 'T':
00402 behavior.timestamp = YES;
00403 make_timestamp ( behavior.timestamp_str );
00404 break;
00405 case 'R':
00406
00407
00408 behavior.hop_incr_unit = -1;
00409 break;
00410 case 'z':
00411
00412 parse_debug ( optarg );
00413 break;
00414 default:
00415 usage( );
00416 tixe ( tixe_cleanup, 1 );
00417 break;
00418 }
00419 }
00420 behavior.target = argv[optind];
00421
00422
00423
00424
00425 if ( ! behavior.max_src_port )
00426 behavior.max_src_port = behavior.min_src_port
00427 + ((( behavior.max_ttl - behavior.min_ttl )
00428 + behavior.packets_per_hop )
00429 * behavior.packets_per_hop );
00430
00431 if ( ! behavior.max_dst_port )
00432 behavior.max_dst_port = behavior.min_dst_port
00433 + ((( behavior.max_ttl - behavior.min_ttl )
00434 + behavior.packets_per_hop )
00435 * behavior.packets_per_hop );
00436
00437 if ( behavior.rndm_src_port == YES )
00438 {
00439
00440 srand ( ( unsigned int ) getpid() );
00441 behavior.rndm_src_port = abs ( rand() % 256 );
00442 behavior.min_src_port += behavior.rndm_src_port;
00443 behavior.max_src_port += behavior.rndm_src_port;
00444 }
00445
00446 if ( behavior.src_port_incr == -1 )
00447 packet.src_port = behavior.max_src_port - behavior.src_port_incr;
00448 else
00449 packet.src_port = behavior.min_src_port - behavior.src_port_incr;
00450
00451 if ( behavior.dst_port_incr == -1 )
00452 packet.dst_port = behavior.max_dst_port - behavior.dst_port_incr;
00453 else
00454 packet.dst_port = behavior.min_dst_port - behavior.dst_port_incr;
00455
00456
00457
00458
00459
00460
00461 if ( geteuid() != 0 )
00462 {
00463 printf ( "error: root privileges required\n" );
00464 tixe ( tixe_cleanup, 1 );
00465 }
00466
00467
00468 if ( behavior.target == NULL )
00469 {
00470 printf ( "error: invalid target\n" );
00471 usage( );
00472 tixe ( tixe_cleanup, 1 );
00473 }
00474
00475 if ( state.incr_error != NO )
00476 {
00477 printf ( "invalid incriment option specified with -i\n" );
00478 usage ( );
00479 tixe ( tixe_cleanup, 1 );
00480 }
00481
00482
00483 if ( behavior.packets_per_hop <= 0 || behavior.packets_per_hop > 10 )
00484 {
00485 printf("packets per hop must be between 1 and 10\n");
00486 behavior.packets_per_hop = 3;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 if ( state.continuous_count > 2048 )
00498 {
00499 printf ( "warning: unusually large iteration number set with -I\n" );
00500 }
00501
00502
00503 if ( strncmp( behavior.protocol, "udp", 3 ) == 0 )
00504 {
00505 behavior.protocol = "udp";
00506 packet.protocol_number = IPPROTO_UDP;
00507 packet.ip_packet_len += LIBNET_UDP_H;
00508 }
00509 else if ( strncmp( behavior.protocol, "tcp", 3 ) == 0 )
00510 {
00511 behavior.protocol = "tcp";
00512 packet.protocol_number = IPPROTO_TCP;
00513 packet.ip_packet_len += LIBNET_TCP_H;
00514 }
00515 else if ( strncmp( behavior.protocol, "icm", 3 ) == 0 )
00516 {
00517 behavior.protocol = "icmp";
00518 packet.protocol_number = IPPROTO_ICMP;
00519 behavior.filter_text = "( icmp[12:2] == %d ) or ( host %s and icmp[0] == 0 )";
00520 packet.ip_packet_len += LIBNET_ICMPV4_ECHO_H;
00521 }
00522 else
00523 {
00524 printf("error: invalid protocol specified with -p\n");
00525 usage( );
00526 tixe ( tixe_cleanup, 1 );
00527 }
00528
00529 if ( packet.dst_port <= 0 || packet.dst_port > 65535 )
00530 {
00531 printf("error: illegal destination port specified with -d\n");
00532 usage( );
00533 tixe ( tixe_cleanup, 1 );
00534 }
00535
00536 if ( packet.src_port <= 0 || packet.dst_port > 65535 )
00537 {
00538 printf("error: illegal source port specified with -s\n");
00539 usage( );
00540 tixe ( tixe_cleanup, 1 );
00541 }
00542
00543 if ( behavior.max_ttl <= 0 )
00544 {
00545 printf("error: illegal maximum time to live value specified with -m\n");
00546 usage( );
00547 tixe ( tixe_cleanup, 1 );
00548 } else if ( behavior.max_ttl > 256 ) {
00549 printf("warning: using an unusually high max ttl value\n");
00550 }
00551
00552 if ( behavior.min_ttl <= 0 )
00553 {
00554 printf("error: illegal minimum time to live value specified with -n\n");
00555 behavior.min_ttl = 1;
00556 } else if ( behavior.min_ttl > behavior.max_ttl ) {
00557 printf("error: minimum ttl (-n) must be less than maximum ttl (-m)\n");
00558 usage( );
00559 tixe ( tixe_cleanup, 1 );
00560 }
00561
00562 if ( behavior.max_src_port < behavior.min_src_port )
00563 {
00564 printf ( "error: maximum src port ( specified with -S )\n" );
00565 printf ( "\tmust be greater than the minimum src port\n" );
00566 printf ( "\t( specified with -s or default 10240 )\n" );
00567 usage( );
00568 tixe ( tixe_cleanup, 1 );
00569 }
00570
00571 if ( behavior.wait_timeout <= 0 )
00572 {
00573 printf("error: illegal timeout specified with -w\n");
00574 usage( );
00575 tixe ( tixe_cleanup, 1 );
00576 } else if ( behavior.wait_timeout > 300 ) {
00577 printf("warning: using and unusually high wait timeout specified with -w\n");
00578 }
00579
00580 if ( behavior.wait_between_packets < 0 )
00581 {
00582 printf("error: illegal timeout specified with -z\n");
00583 usage( );
00584 tixe ( tixe_cleanup, 1 );
00585 } else if ( behavior.wait_between_packets > 10000 ) {
00586 printf("warning: using an unusually high wait time between packets\n");
00587 }
00588
00589 if ( packet.src_port == 0 )
00590 {
00591 printf("warning: using source port 0\n");
00592 }
00593
00594 if ( behavior.account_level > TP_ACCOUNT_FULL )
00595 {
00596 behavior.account_level = TP_ACCOUNT_FULL;
00597 }
00598 else if ( behavior.account_level < TP_ACCOUNT_NONE )
00599 {
00600 behavior.account_level = TP_ACCOUNT_NONE;
00601 }
00602
00603
00604 if ( strlen ( behavior.filter_text )
00605 + strlen ( behavior.target )
00606 + 12 > FILTERSIZE )
00607 {
00608 printf ( "error: bpf filter size limit exceeded. "
00609 "Specify a shorter target name (perhaps the ip address).\n" );
00610 tixe ( tixe_cleanup, 1 );
00611 }
00612
00613
00614
00615
00616
00617 if ( behavior.output_style == TP_CURSES_OUTPUT )
00618 behavior.continuous_accounting = NO;
00619
00620
00621
00622
00623
00624
00625
00626 if ( behavior.payload_size != 0 )
00627 {
00628 if ( behavior.payload_size > 8192 )
00629 {
00630 printf ( "illegal payload size\n" );
00631 usage ( );
00632 tixe ( tixe_cleanup, 1 );
00633 }
00634 packet.payload = ( u_char * ) malloc ( behavior.payload_size );
00635 assert(packet.payload != NULL);
00636 if ( packet.payload == NULL )
00637 {
00638 printf ( "error allocating payload memory for payload\n" );
00639 tixe ( tixe_cleanup, 1 );
00640 }
00641 tixe_cleanup.payload_free = YES;
00642 memset ( packet.payload, '\0', behavior.payload_size );
00643
00644 packet.ip_packet_len += behavior.payload_size;
00645 }
00646
00647
00648
00649
00650 tp_align_freelist.next = ( struct tp_align_ref * ) malloc ( sizeof ( struct tp_align_ref ) );
00651 if ( tp_align_freelist.next == NULL )
00652 {
00653 printf ( "error allocating memory for the free list\n" );
00654 tixe ( tixe_cleanup, 1 );
00655 }
00656 tixe_cleanup.free_list_free = YES;
00657
00658
00659
00660
00661
00662 #ifdef HAVE_GETADDRINFO
00663
00664
00665 behavior.hint.ai_flags = 0;
00666 behavior.hint.ai_family = PF_UNSPEC;
00667 behavior.hint.ai_socktype = SOCK_STREAM;
00668 behavior.hint.ai_protocol = IPPROTO_IP;
00669 behavior.hint.ai_addrlen = 0;
00670 behavior.hint.ai_addr = NULL;
00671 behavior.hint.ai_canonname = NULL;
00672 behavior.hint.ai_next = NULL;
00673 behavior.target_addrinfo_list_start = NULL;
00674
00675 if ( (i = getaddrinfo( behavior.target, NULL, &behavior.hint, &behavior.target_addrinfo_list_start )) != 0 ) {
00676 printf ( "error resolving target address %s: %s\n", behavior.target, gai_strerror(i));
00677 tixe ( tixe_cleanup, 1 );
00678 }
00679
00680 tixe_cleanup.addrinfo_cleanup = YES;
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 behavior.target_addrinfo = behavior.target_addrinfo_list_start;
00691 while ( (behavior.target_addrinfo->ai_addr->sa_family != AF_INET) &&
00692 (behavior.target_addrinfo->ai_next != NULL) ) {
00693 behavior.target_addrinfo = behavior.target_addrinfo->ai_next;
00694 }
00695
00696 # ifdef DEBUG
00697 fprintf ( stderr, "resolving %s: success\n", behavior.target );
00698 # endif
00699
00700 if ( behavior.target_addrinfo->ai_addr->sa_family == AF_INET ) {
00701 # ifdef DEBUG
00702 fprintf ( stderr, "Address family: AF_INET\n" );
00703 # endif
00704 l = sizeof(struct sockaddr_in);
00705 } else if ( behavior.target_addrinfo->ai_addr->sa_family == AF_INET6 ) {
00706 # ifdef DEBUG
00707 fprintf ( stderr, "Address family: AF_INET6\n" );
00708 # endif
00709 l = sizeof(struct sockaddr_in6);
00710 } else {
00711 fprintf ( stderr, "Address family %d not supported\n", behavior.target_addrinfo->ai_addr->sa_family );
00712 l = 0;
00713 tixe ( tixe_cleanup, 1 );
00714 }
00715 behavior.target_reverse = malloc( NI_MAXHOST );
00716 assert(behavior.target_reverse != NULL);
00717 if ( (i = getnameinfo( behavior.target_addrinfo->ai_addr, l, behavior.target_reverse, NI_MAXHOST-1, NULL, 0, NI_NUMERICHOST )) != 0 ) {
00718 fprintf ( stderr, "getnameinfo(...) failed: %s\n", gai_strerror(i) );
00719 }
00720
00721
00722 if ( behavior.target_addrinfo->ai_addr->sa_family != AF_INET ) {
00723 fprintf ( stderr, "Sorry, target address %s did not resolve to an IPv4 address (address family is %d)\n", behavior.target, behavior.target_addrinfo->ai_addr->sa_family );
00724 tixe ( tixe_cleanup, 1 );
00725 }
00726 #else
00727
00728 behavior.packed_target_reverse = gethostbyname ( behavior.target );
00729 if ( behavior.packed_target_reverse == NULL )
00730 {
00731 printf ( "error resolving target address %s\n", behavior.target );
00732 tixe ( tixe_cleanup, 1 );
00733 }
00734
00735 behavior.target_reverse = inet_ntoa (
00736 *(struct in_addr *)( behavior.packed_target_reverse->h_addr_list[0]));
00737 #endif
00738
00739
00740
00741
00742
00743 if ( behavior.do_skip == YES && parse_skips ( behavior.skip_str ) != 0 )
00744 {
00745 fprintf ( stderr, "error with option k arguments\n" );
00746 usage ( );
00747 tixe ( tixe_cleanup, 1 );
00748 }
00749
00750
00751
00752
00753 state.account_hops = behavior.max_ttl + 1;
00754 state.hop_record = ( struct hop_record * ) calloc (
00755 state.account_hops,
00756 sizeof ( struct hop_record ) );
00757 if ( state.hop_record == NULL )
00758 {
00759 perror ( "memory allocation error" );
00760 tixe ( tixe_cleanup, 1 );
00761 }
00762 tixe_cleanup.hop_record_free = YES;
00763
00764
00765
00766
00767
00768
00769 #ifdef OS_FREEBSD
00770
00771
00772
00773
00774
00775
00776
00777 behavior.default_if = NO;
00778 #endif
00779
00780 if ( debug.interface == YES )
00781 {
00782 printf ( "debug: using default interface = %s\n",
00783 behavior.default_if ? "YES" : "NO" );
00784 printf ( "debug: interface flag is %s\n",
00785 behavior.default_if == NO ? behavior.interface : "NULL" );
00786
00787 }
00788
00789 state.packet = libnet_init (
00790 LIBNET_RAW4,
00791
00792 behavior.default_if == NO ? behavior.interface : NULL,
00793 ( char * ) state.error_buff );
00794 if (!state.packet)
00795 {
00796 printf("Error: %s\n", * state.error_buff);
00797 tixe ( tixe_cleanup, 1 );
00798 }
00799 tixe_cleanup.libnet_cleanup = YES;
00800
00801 packet.packed_target = libnet_name2addr4(
00802 state.packet, behavior.target, LIBNET_RESOLVE );
00803 if ( packet.packed_target == -1 )
00804 {
00805 printf("error resolving destination (%s): %s\n",
00806 behavior.target, libnet_geterror( state.packet ) );
00807 usage( );
00808 tixe ( tixe_cleanup, 1 );
00809 }
00810
00811 packet.packed_src = libnet_get_ipaddr4( state.packet );
00812 if ( packet.packed_src == -1 )
00813 {
00814 printf("error resolving source: %s\n",
00815 libnet_geterror( state.packet ) );
00816 tixe ( tixe_cleanup, 1 );
00817 }
00818
00819 libnet_seed_prand( state.packet );
00820
00821
00822
00823
00824
00825
00826 state.psocket = pcap_open_live (
00827 behavior.default_if == NO ? behavior.interface : NULL,
00828 SNAPLEN,
00829 NO_PROMISC,
00830 ( behavior.wait_timeout * 1000 ),
00831 state.pc_error );
00832 if ( state.psocket == NULL )
00833 {
00834 printf("pcap error: %s\n", state.pc_error);
00835 tixe ( tixe_cleanup, 1 );
00836 }
00837 tixe_cleanup.pcap_cleanup = YES;
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 #ifdef USE_PCAP_FILENO
00853 state.fake_psocket = ( struct fake_pcap * )
00854 malloc ( sizeof ( struct fake_pcap ) );
00855 if ( state.fake_psocket == NULL )
00856 {
00857 printf ( "error allocating pcap_fileno memory\n" );
00858 tixe ( tixe_cleanup, 1 );
00859 }
00860 tixe_cleanup.fake_psocket_free = YES;
00861
00862 state.fake_psocket->fd = pcap_fileno ( state.psocket );
00863 #else
00864 state.fake_psocket = ( struct fake_pcap * ) state.psocket;
00865 #endif
00866
00867 #ifdef OS_FREEBSD
00868
00869
00870
00871
00872
00873
00874 if ( ioctl ( state.fake_psocket->fd, BIOCIMMEDIATE, & on ) > 0 )
00875 {
00876 printf ( "error setting BSD BPF fd to immediate\n" );
00877 tixe ( tixe_cleanup, 1 );
00878 }
00879 #endif
00880
00881
00882
00883
00884 if ( do_filter() != 0 )
00885 {
00886 tixe ( tixe_cleanup, 1 );
00887 }
00888
00889
00890
00891
00892 if ( setuid ( getuid ( ) ) != 0 )
00893 {
00894 printf ( "error dropping privileges\n" );
00895 tixe ( tixe_cleanup, 1 );
00896 }
00897 if ( setgid ( getgid ( ) ) != 0 )
00898 {
00899 printf ( "error dropping privileges\n" );
00900 tixe ( tixe_cleanup, 1 );
00901 }
00902
00903
00904
00905
00906 if ( behavior.as_discovery == YES && setup_as ( ) != 0 )
00907 {
00908 printf ( "error doing AS discovery: %s\n", as_string );
00909 behavior.as_discovery = NO;
00910 }
00911
00912
00913
00914
00915 signal ( SIGINT, ctrl_c );
00916 signal ( SIGTSTP, ctrl_z );
00917
00918
00919
00920
00921 if ( behavior.hop_incr_unit == 1 )
00922 state.current_hop = behavior.min_ttl;
00923 else
00924 state.current_hop = behavior.max_ttl;
00925
00926
00927
00928
00929
00930
00931 behavior.report( TP_OUT_HEADER, NULL, 0 );
00932
00933
00934
00935
00936
00937 for ( state.packets_this_hop = 0;
00938
00939 ( state.current_hop >= behavior.min_ttl
00940 &&
00941 state.current_hop <= behavior.max_ttl )
00942 ||
00943 state.packets_this_hop < behavior.packets_per_hop;
00944
00945 ++( state.packets_this_hop ) )
00946 {
00947
00948
00949
00950 if ( state.packets_this_hop >= behavior.packets_per_hop )
00951 {
00952 state.current_hop += behavior.hop_incr_unit;
00953 state.packets_this_hop = 0;
00954 }
00955
00956
00957
00958
00959 if ( behavior.do_skip == YES && behavior.skips[ state.current_hop ] == YES )
00960 {
00961 state.current_hop += behavior.hop_incr_unit;
00962 state.packets_this_hop = -1;
00963 continue;
00964 }
00965
00966 state.packet_match = TP_PACKET_NO;
00967 state.low_ttl = NO;
00968
00969
00970
00971
00972 packet.src_port += behavior.src_port_incr;
00973 packet.dst_port += behavior.dst_port_incr;
00974
00975 build_packet();
00976
00977
00978
00979
00980
00981 packet.ip_id = libnet_get_prand(LIBNET_PRu16);
00982 if ( debug.packet_length == YES )
00983 printf ( "debug: packet.ip_id=%d", packet.ip_id );
00984
00985 state.ip_h = libnet_build_ipv4(
00986 packet.ip_packet_len,
00987 0,
00988 packet.ip_id,
00989 packet.frag_bit,
00990 state.current_hop,
00991 packet.protocol_number,
00992 0,
00993 packet.packed_src,
00994 packet.packed_target,
00995 NULL,
00996 0,
00997 state.packet,
00998 state.ip_h );
00999
01000 if ( debug.packet_length == YES )
01001 printf ( "\nHEADER_LENGTH IP:%d payload:%d, total:%d\n",
01002 LIBNET_IPV4_H, behavior.payload_size, packet.ip_packet_len );
01003
01004 if ( debug.send_buf == YES )
01005 {
01006 printf ( "debug: send buffer:\n" );
01007 debug_packet ( libnet_getpbuf ( state.packet, state.ip_h ),
01008 libnet_getpbuf_size ( state.packet, state.ip_h ) );
01009 debug_packet ( libnet_getpbuf ( state.packet, state.tcp_h ),
01010 libnet_getpbuf_size ( state.packet, state.tcp_h ) );
01011 debug_packet ( packet.payload, behavior.payload_size );
01012 }
01013
01014
01015
01016 if ( do_filter() != 0 )
01017 {
01018 tixe ( tixe_cleanup, 1 );
01019 }
01020
01021
01022
01023
01024
01025 if ( state.packets_this_hop == 0 )
01026 behavior.report( TP_OUT_HOP_NUMBER, ( struct in_addr * ) NULL, 0 );
01027
01028 gettimeofday ( & state.start_time, NULL );
01029
01030 if ( debug.loop == YES ) { printf ( "debug: time checked, writing packet\n" ); }
01031
01032 if ( libnet_write( state.packet ) == -1 )
01033 {
01034 printf("error at send: %s\n",
01035 libnet_geterror( state.packet ) );
01036 tixe ( tixe_cleanup, 1 );
01037 }
01038
01039 if ( debug.loop == YES ) { printf ( "debug: packet written, waiting\n" ); }
01040
01041
01042
01043
01044
01045
01046 while ( state.packet_match == TP_PACKET_NO )
01047 {
01048 state.packet_wait.tv_sec = behavior.wait_timeout;
01049 state.packet_wait.tv_usec = 0;
01050 FD_ZERO( & ( state.wheel ) );
01051 FD_SET( state.fake_psocket->fd, & ( state.wheel ) );
01052
01053 if ( debug.loop == YES ) { printf ( "debug: select\n" ); }
01054
01055 if ( select( ( state.fake_psocket->fd ) + 1,
01056 & ( state.wheel ),
01057 NULL,
01058 NULL,
01059 & state.packet_wait ) > 0 )
01060 {
01061
01062
01063
01064
01065 gettimeofday ( & ( state.end_time ), NULL );
01066
01067 if ( debug.loop == YES )
01068 printf ( "debug: select returned, capturing\n" );
01069
01070 strcpy ( state.pc_error, "unknown" );
01071
01072
01073
01074
01075
01076 state.capture_buf = pcap_next(
01077 state.psocket,
01078 & ( state.psock_hdr ) );
01079
01080
01081
01082
01083
01084
01085
01086
01087 if ( state.capture_buf == NULL )
01088 {
01089 state.capture_buf = pcap_next(
01090 state.psocket,
01091 & ( state.psock_hdr ) );
01092
01093 if ( state.capture_buf == NULL )
01094 {
01095 printf ( "error receiving packet: %s\n",
01096 state.pc_error );
01097 tixe ( tixe_cleanup, 1 );
01098 }
01099 }
01100
01101 if ( debug.loop == YES )
01102 printf ( "debug: captured, parsing\n" );
01103
01104 state.trip_time = diff_time (
01105 & ( state.start_time ),
01106 & ( state.end_time ) );
01107
01108 if ( parse_packet( state.capture_buf ) > 0 )
01109 {
01110 freelist_cleaner ( );
01111 }
01112
01113 if ( debug.loop == YES )
01114 printf ( "debug: parsed, resets\n" );
01115
01116 if ( packet.protocol_number == IPPROTO_TCP
01117 && behavior.tcp_resets == YES
01118 && state.packet_match == TP_PACKET_DONE )
01119 {
01120 if ( send_tcp_reset ( ) != 0 )
01121 printf("error at send: %s\n",
01122 libnet_geterror( state.packet ) );
01123 }
01124
01125
01126 memset ( (char *) state.capture_buf, '\0', sizeof ( state.capture_buf ) );
01127 state.trip_time = ( double ) 0.0;
01128 } else {
01129
01130
01131
01132 account_packet ( ( double ) 0 );
01133 behavior.report( TP_OUT_HOP_INFO, ( struct in_addr * ) NULL, TP_TYPE_NR );
01134 state.packet_match = TP_PACKET_TIMEOUT;
01135
01136 if ( debug.loop == YES )
01137 printf ( "debug: no answer (%d)\n", FD_ISSET ( state.fake_psocket->fd, & ( state.wheel ) ) );
01138 }
01139
01140
01141
01142
01143 if ( behavior.do_audit == YES || behavior.do_audit_exit == YES )
01144 {
01145 if ( behavior.do_audit_exit == YES )
01146 behavior.report( TP_OUT_FOOTER, NULL, 0 );
01147 else
01148 hop_audit();
01149 }
01150 }
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 if ( ( ( state.target_response == YES
01164 ||
01165 state.current_hop == behavior.max_ttl )
01166 &&
01167 state.packets_this_hop >= behavior.packets_per_hop - 1
01168 &&
01169 behavior.hop_incr_unit == 1 )
01170 ||
01171 ( behavior.hop_incr_unit == -1
01172 &&
01173 state.current_hop == behavior.min_ttl
01174 &&
01175 state.packets_this_hop >= behavior.packets_per_hop - 1 ) )
01176 {
01177
01178
01179
01180
01181
01182 state.current_hop = behavior.max_ttl + 1;
01183
01184
01185
01186
01187
01188 if ( state.continuous_count != (int) NULL )
01189 {
01190 state.continuous_count--;
01191 if ( state.continuous_count == 0 )
01192 behavior.continuous = NO;
01193 }
01194 if ( behavior.continuous == YES )
01195 {
01196 state.packet_match = TP_PACKET_NO;
01197 state.target_response = NO;
01198
01199 if ( behavior.hop_incr_unit == 1 )
01200 state.current_hop = behavior.min_ttl;
01201 else
01202 state.current_hop = behavior.max_ttl;
01203
01204
01205
01206
01207
01208 state.packets_this_hop = -1;
01209
01210 if ( behavior.continuous_accounting == YES )
01211 hop_audit();
01212 }
01213 }
01214
01215
01216
01217
01218
01219 if ( behavior.wait_between_packets != 0 )
01220 usleep ( behavior.wait_between_packets * 1000 );
01221
01222
01223
01224
01225 if ( packet.src_port >= behavior.max_src_port && behavior.src_port_incr == 1 )
01226 packet.src_port = behavior.min_src_port - 1;
01227 else if ( packet.src_port <= behavior.min_src_port && behavior.src_port_incr == -1 )
01228 packet.src_port = behavior.max_src_port + 1;
01229
01230 if ( packet.dst_port >= behavior.max_dst_port && behavior.dst_port_incr == 1)
01231 packet.dst_port = behavior.min_dst_port - 1;
01232 else if ( packet.dst_port <= behavior.min_dst_port && behavior.dst_port_incr == -1)
01233 packet.dst_port = behavior.max_dst_port + 1;
01234
01235 if ( debug.loop == YES ) { printf ( "debug, looping back to the beginning\n" ); }
01236
01237 }
01238
01239
01240
01241
01242
01243
01244
01245 behavior.report ( TP_OUT_FOOTER, NULL, 0 );
01246
01247
01248 tixe ( tixe_cleanup, 0 );
01249
01250 exit ( 0 );
01251 }
01252