diff options
-rw-r--r-- | networking/traceroute.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c index 588570fcb..e6afdd8b9 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -394,8 +394,12 @@ struct globals { int packlen; /* total length of packet */ int pmtu; /* Path MTU Discovery (RFC1191) */ uint32_t ident; - uint16_t port; // 33434; /* start udp dest port # for probe packets */ - int waittime; // 5; /* time to wait for response (in seconds) */ + uint16_t port; /* start udp dest port # for probe packets */ + int waittime; /* time to wait for response (in seconds) */ + int first_ttl; + int nprobes; + unsigned pausemsecs; + int max_ttl; unsigned char recv_pkt[512]; /* last inbound (icmp) packet */ }; @@ -412,8 +416,6 @@ struct globals { #define gwlist (G.gwlist ) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ - port = 33434; \ - waittime = 5; \ } while (0) #define outudp ((struct udphdr *)(outip + 1)) @@ -862,22 +864,16 @@ print_delta_ms(unsigned t1p, unsigned t2p) printf(" %u.%03u ms", tt / 1000, tt % 1000); } -/* - * Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl] - * [-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos] - * [-w waittime] [-z pausemsecs] host [packetlen]" +/* Keeping init code in a separate (not inlined!) function + * for stack use reduction and better register allocation in main loop. */ -static int -common_traceroute_main(int op, char **argv) +static NOINLINE void +traceroute_init(int op, char **argv) { int minpacket; #ifdef IP_TOS int tos = 0; #endif - int max_ttl = 30; - int nprobes = 3; - int first_ttl = 1; - unsigned pausemsecs = 0; char *source; char *device; char *tos_str; @@ -893,14 +889,16 @@ common_traceroute_main(int op, char **argv) #else enum { af = AF_INET }; #endif - int ttl; - int seq; - struct sockaddr *lastaddr; /* Ensure the socket fds won't be 0, 1 or 2 */ bb_sanitize_stdio(); INIT_G(); + port = 33434; + waittime = 5; + G.first_ttl = 1; + G.nprobes = 3; + G.max_ttl = 30; op |= getopt32(argv, "^" OPT_STRING @@ -919,17 +917,17 @@ common_traceroute_main(int op, char **argv) tos = xatou_range(tos_str, 0, 255); #endif if (op & OPT_MAX_TTL) - max_ttl = xatou_range(max_ttl_str, 1, 255); + G.max_ttl = xatou_range(max_ttl_str, 1, 255); if (op & OPT_PORT) port = xatou16(port_str); if (op & OPT_NPROBES) - nprobes = xatou_range(nprobes_str, 1, INT_MAX); + G.nprobes = xatou_range(nprobes_str, 1, INT_MAX); if (op & OPT_WAITTIME) waittime = xatou_range(waittime_str, 1, 24 * 60 * 60); if (op & OPT_PAUSE_MS) - pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000); + G.pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000); if (op & OPT_FIRST_TTL) - first_ttl = xatou_range(first_ttl_str, 1, max_ttl); + G.first_ttl = xatou_range(first_ttl_str, 1, G.max_ttl); /* Process destination and optional packet size */ minpacket = sizeof(struct ip) @@ -961,6 +959,9 @@ common_traceroute_main(int op, char **argv) #else dest_lsa = xhost2sockaddr(argv[0], port); #endif + G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len); + G.to = xzalloc(dest_lsa->len); + packlen = minpacket; if (argv[1]) packlen = xatoul_range(argv[1], minpacket, 32 * 1024); @@ -1102,20 +1103,28 @@ common_traceroute_main(int op, char **argv) if (op & OPT_SOURCE) printf(" from %s", source); - printf(", %d hops max, %d byte packets\n", max_ttl, packlen); + printf(", %d hops max, %d byte packets\n", G.max_ttl, packlen); +} + +static int +common_traceroute_main(int op, char **argv) +{ + int ttl; + int seq; + struct sockaddr *lastaddr; + + traceroute_init(op, argv); lastaddr = xzalloc(dest_lsa->len); - G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len); - G.to = xzalloc(dest_lsa->len); seq = 0; - for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { + for (ttl = G.first_ttl; ttl <= G.max_ttl; ++ttl) { int probe; int unreachable = 0; /* counter */ int gotlastaddr = 0; /* flags */ int got_there = 0; printf("%2d", ttl); - for (probe = 0; probe < nprobes; ++probe) { + for (probe = 0; probe < G.nprobes; ++probe) { int read_len; unsigned t1; unsigned t2; @@ -1123,14 +1132,15 @@ common_traceroute_main(int op, char **argv) fflush_all(); if (probe != 0) - msleep(pausemsecs); + msleep(G.pausemsecs); send_probe(++seq, ttl); t2 = t1 = monotonic_us(); left_ms = waittime * 1000; - /* NB: wait_for_reply() fills "G.from_lsa" and "G.to" - * with "where it came from" and "to which local address it arrived". + /* NB: wait_for_reply() fills "G.from_lsa" and "G.to" with + * "where it came from" and "what local address it arrived to" + * addresses. */ while ((read_len = wait_for_reply(&t2, &left_ms)) != 0) { int icmp_code; @@ -1255,7 +1265,7 @@ common_traceroute_main(int op, char **argv) bb_putchar('\n'); if (got_there - || (unreachable > 0 && unreachable >= nprobes - 1) + || (unreachable > 0 && unreachable >= G.nprobes - 1) ) { break; } |