| @@ -212,8 +212,7 @@ |
| |
| //usage:#define traceroute_trivial_usage |
| //usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" |
| - | //usage: " [-t TOS] [-w WAIT_SEC]" |
| - | //usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n" |
| + | //usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n" |
| //usage: " [-z PAUSE_MSEC] HOST [BYTES]" |
| //usage:#define traceroute_full_usage "\n\n" |
| //usage: "Trace the route to HOST\n" |
| @@ -294,7 +293,6 @@ |
| |
| #define OPT_STRING \ |
| "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ |
| - | IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \ |
| "4" IF_TRACEROUTE6("6") |
| enum { |
| OPT_DONT_FRAGMNT = (1 << 0), /* F */ |
| @@ -314,9 +312,8 @@ enum { |
| OPT_WAITTIME = (1 << 14), /* w */ |
| OPT_PAUSE_MS = (1 << 15), /* z */ |
| OPT_FIRST_TTL = (1 << 16), /* f */ |
| - | OPT_SOURCE_ROUTE = (1 << 17) * ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE, /* g */ |
| - | OPT_IPV4 = (1 << (17+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)), /* 4 */ |
| - | OPT_IPV6 = (1 << (18+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)) * ENABLE_TRACEROUTE6, /* 6 */ |
| + | OPT_IPV4 = (1 << 17), /* 4 */ |
| + | OPT_IPV6 = (1 << 18) * ENABLE_TRACEROUTE6, /* 6 */ |
| }; |
| #define verbose (option_mask32 & OPT_VERBOSE) |
| |
| @@ -343,26 +340,18 @@ struct outdata6_t { |
| #endif |
| |
| struct globals { |
| + | /* Pointer to entire malloced IP packet, "packlen" bytes long: */ |
| struct ip *outip; |
| + | /* Pointer to ICMP or UDP payload (not header): */ |
| struct outdata_t *outdata; |
| + | |
| len_and_sockaddr *dest_lsa; |
| int packlen; /* total length of packet */ |
| int pmtu; /* Path MTU Discovery (RFC1191) */ |
| uint32_t ident; |
| - | uint16_t port; // 32768 + 666; /* start udp dest port # for probe packets */ |
| + | uint16_t port; // 33434; /* start udp dest port # for probe packets */ |
| int waittime; // 5; /* time to wait for response (in seconds) */ |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
| - | int optlen; /* length of ip options */ |
| - | #else |
| - | #define optlen 0 |
| - | #endif |
| unsigned char recv_pkt[512]; /* last inbound (icmp) packet */ |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
| - | /* Maximum number of gateways (include room for one noop) */ |
| - | #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(uint32_t))) |
| - | /* loose source route gateway list (including room for final destination) */ |
| - | uint32_t gwlist[NGATEWAYS + 1]; |
| - | #endif |
| }; |
| |
| #define G (*ptr_to_globals) |
| @@ -374,14 +363,11 @@ struct globals { |
| #define ident (G.ident ) |
| #define port (G.port ) |
| #define waittime (G.waittime ) |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
| - | # define optlen (G.optlen ) |
| - | #endif |
| #define recv_pkt (G.recv_pkt ) |
| #define gwlist (G.gwlist ) |
| #define INIT_G() do { \ |
| SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
| - | port = 32768 + 666; \ |
| + | port = 33434; \ |
| waittime = 5; \ |
| } while (0) |
| |
| @@ -421,7 +407,7 @@ send_probe(int seq, int ttl) |
| /* Payload */ |
| #if ENABLE_TRACEROUTE6 |
| if (dest_lsa->u.sa.sa_family == AF_INET6) { |
| - | struct outdata6_t *pkt = (struct outdata6_t *) outip; |
| + | struct outdata6_t *pkt = (struct outdata6_t *) outdata; |
| pkt->ident6 = htonl(ident); |
| pkt->seq6 = htonl(seq); |
| /*gettimeofday(&pkt->tv, &tz);*/ |
| @@ -438,8 +424,10 @@ send_probe(int seq, int ttl) |
| |
| /* Always calculate checksum for icmp packets */ |
| outicmp->icmp_cksum = 0; |
| - | outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp, |
| - | packlen - (sizeof(*outip) + optlen)); |
| + | outicmp->icmp_cksum = inet_cksum( |
| + | (uint16_t *)outicmp, |
| + | ((char*)outip + packlen) - (char*)outicmp |
| + | ); |
| if (outicmp->icmp_cksum == 0) |
| outicmp->icmp_cksum = 0xffff; |
| } |
| @@ -471,13 +459,12 @@ send_probe(int seq, int ttl) |
| } |
| #endif |
| |
| + | out = outdata; |
| #if ENABLE_TRACEROUTE6 |
| if (dest_lsa->u.sa.sa_family == AF_INET6) { |
| res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); |
| if (res != 0) |
| bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); |
| - | out = outip; |
| - | len = packlen; |
| } else |
| #endif |
| { |
| @@ -486,15 +473,14 @@ send_probe(int seq, int ttl) |
| if (res != 0) |
| bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); |
| #endif |
| - | out = outicmp; |
| - | len = packlen - sizeof(*outip); |
| - | if (!(option_mask32 & OPT_USE_ICMP)) { |
| - | out = outdata; |
| - | len -= sizeof(*outudp); |
| - | set_nport(&dest_lsa->u.sa, htons(port + seq)); |
| - | } |
| + | if (option_mask32 & OPT_USE_ICMP) |
| + | out = outicmp; |
| } |
| |
| + | if (!(option_mask32 & OPT_USE_ICMP)) { |
| + | set_nport(&dest_lsa->u.sa, htons(port + seq)); |
| + | } |
| + | len = ((char*)outip + packlen) - (char*)out; |
| res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); |
| if (res != len) |
| bb_error_msg("sent %d octets, ret=%d", len, res); |
| @@ -801,10 +787,6 @@ common_traceroute_main(int op, char **argv) |
| char *pausemsecs_str; |
| char *first_ttl_str; |
| char *dest_str; |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
| - | llist_t *source_route_list = NULL; |
| - | int lsrr = 0; |
| - | #endif |
| #if ENABLE_TRACEROUTE6 |
| sa_family_t af; |
| #else |
| @@ -823,9 +805,6 @@ common_traceroute_main(int op, char **argv) |
| op |= getopt32(argv, OPT_STRING |
| , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str |
| , &source, &waittime_str, &pausemsecs_str, &first_ttl_str |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
| - | , &source_route_list |
| - | #endif |
| ); |
| argv += optind; |
| |
| @@ -858,26 +837,14 @@ common_traceroute_main(int op, char **argv) |
| if (op & OPT_FIRST_TTL) |
| first_ttl = xatou_range(first_ttl_str, 1, max_ttl); |
| |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
| - | if (source_route_list) { |
| - | while (source_route_list) { |
| - | len_and_sockaddr *lsa; |
| - | |
| - | if (lsrr >= NGATEWAYS) |
| - | bb_error_msg_and_die("no more than %d gateways", NGATEWAYS); |
| - | lsa = xhost_and_af2sockaddr(llist_pop(&source_route_list), 0, AF_INET); |
| - | gwlist[lsrr] = lsa->u.sin.sin_addr.s_addr; |
| - | free(lsa); |
| - | ++lsrr; |
| - | } |
| - | optlen = (lsrr + 1) * sizeof(gwlist[0]); |
| - | } |
| - | #endif |
| - | |
| /* Process destination and optional packet size */ |
| - | minpacket = sizeof(*outip) + SIZEOF_ICMP_HDR + sizeof(*outdata) + optlen; |
| + | minpacket = sizeof(struct ip) |
| + | + SIZEOF_ICMP_HDR |
| + | + sizeof(struct outdata_t); |
| if (!(op & OPT_USE_ICMP)) |
| - | minpacket += sizeof(*outudp) - SIZEOF_ICMP_HDR; |
| + | minpacket = sizeof(struct ip) |
| + | + sizeof(struct udphdr) |
| + | + sizeof(struct outdata_t); |
| #if ENABLE_TRACEROUTE6 |
| af = AF_UNSPEC; |
| if (op & OPT_IPV4) |
| @@ -887,7 +854,9 @@ common_traceroute_main(int op, char **argv) |
| dest_lsa = xhost_and_af2sockaddr(argv[0], port, af); |
| af = dest_lsa->u.sa.sa_family; |
| if (af == AF_INET6) |
| - | minpacket = sizeof(struct outdata6_t); |
| + | minpacket = sizeof(struct ip6_hdr) |
| + | + sizeof(struct udphdr) |
| + | + sizeof(struct outdata6_t); |
| #else |
| dest_lsa = xhost2sockaddr(argv[0], port); |
| #endif |
| @@ -932,31 +901,6 @@ common_traceroute_main(int op, char **argv) |
| xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock); |
| else |
| xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock); |
| - | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS |
| - | if (lsrr > 0) { |
| - | unsigned char optlist[MAX_IPOPTLEN]; |
| - | unsigned size; |
| - | |
| - | /* final hop */ |
| - | gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr; |
| - | ++lsrr; |
| - | |
| - | /* force 4 byte alignment */ |
| - | optlist[0] = IPOPT_NOP; |
| - | /* loose source route option */ |
| - | optlist[1] = IPOPT_LSRR; |
| - | size = lsrr * sizeof(gwlist[0]); |
| - | optlist[2] = size + 3; |
| - | /* pointer to LSRR addresses */ |
| - | optlist[3] = IPOPT_MINOFF; |
| - | memcpy(optlist + 4, gwlist, size); |
| - | |
| - | if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, |
| - | (char *)optlist, size + sizeof(gwlist[0])) < 0) { |
| - | bb_perror_msg_and_die("IP_OPTIONS"); |
| - | } |
| - | } |
| - | #endif |
| } |
| |
| #ifdef SO_SNDBUF |
| @@ -984,7 +928,7 @@ common_traceroute_main(int op, char **argv) |
| |
| ident = getpid(); |
| |
| - | if (af == AF_INET) { |
| + | if (!ENABLE_TRACEROUTE6 || af == AF_INET) { |
| if (op & OPT_USE_ICMP) { |
| ident |= 0x8000; |
| outicmp->icmp_type = ICMP_ECHO; |
| @@ -994,6 +938,14 @@ common_traceroute_main(int op, char **argv) |
| outdata = (struct outdata_t *)(outudp + 1); |
| } |
| } |
| + | #if ENABLE_TRACEROUTE6 |
| + | if (af == AF_INET6) { |
| + | outdata = (void*)((char*)outip |
| + | + sizeof(struct ip6_hdr) |
| + | + sizeof(struct udphdr) |
| + | ); |
| + | } |
| + | #endif |
| |
| if (op & OPT_DEVICE) /* hmm, do we need error check? */ |
| setsockopt_bindtodevice(sndsock, device); |