aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--networking/traceroute.c70
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 {
394 int packlen; /* total length of packet */ 394 int packlen; /* total length of packet */
395 int pmtu; /* Path MTU Discovery (RFC1191) */ 395 int pmtu; /* Path MTU Discovery (RFC1191) */
396 uint32_t ident; 396 uint32_t ident;
397 uint16_t port; // 33434; /* start udp dest port # for probe packets */ 397 uint16_t port; /* start udp dest port # for probe packets */
398 int waittime; // 5; /* time to wait for response (in seconds) */ 398 int waittime; /* time to wait for response (in seconds) */
399 int first_ttl;
400 int nprobes;
401 unsigned pausemsecs;
402 int max_ttl;
399 unsigned char recv_pkt[512]; /* last inbound (icmp) packet */ 403 unsigned char recv_pkt[512]; /* last inbound (icmp) packet */
400}; 404};
401 405
@@ -412,8 +416,6 @@ struct globals {
412#define gwlist (G.gwlist ) 416#define gwlist (G.gwlist )
413#define INIT_G() do { \ 417#define INIT_G() do { \
414 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 418 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
415 port = 33434; \
416 waittime = 5; \
417} while (0) 419} while (0)
418 420
419#define outudp ((struct udphdr *)(outip + 1)) 421#define outudp ((struct udphdr *)(outip + 1))
@@ -862,22 +864,16 @@ print_delta_ms(unsigned t1p, unsigned t2p)
862 printf(" %u.%03u ms", tt / 1000, tt % 1000); 864 printf(" %u.%03u ms", tt / 1000, tt % 1000);
863} 865}
864 866
865/* 867/* Keeping init code in a separate (not inlined!) function
866 * Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl] 868 * for stack use reduction and better register allocation in main loop.
867 * [-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]
868 * [-w waittime] [-z pausemsecs] host [packetlen]"
869 */ 869 */
870static int 870static NOINLINE void
871common_traceroute_main(int op, char **argv) 871traceroute_init(int op, char **argv)
872{ 872{
873 int minpacket; 873 int minpacket;
874#ifdef IP_TOS 874#ifdef IP_TOS
875 int tos = 0; 875 int tos = 0;
876#endif 876#endif
877 int max_ttl = 30;
878 int nprobes = 3;
879 int first_ttl = 1;
880 unsigned pausemsecs = 0;
881 char *source; 877 char *source;
882 char *device; 878 char *device;
883 char *tos_str; 879 char *tos_str;
@@ -893,14 +889,16 @@ common_traceroute_main(int op, char **argv)
893#else 889#else
894 enum { af = AF_INET }; 890 enum { af = AF_INET };
895#endif 891#endif
896 int ttl;
897 int seq;
898 struct sockaddr *lastaddr;
899 892
900 /* Ensure the socket fds won't be 0, 1 or 2 */ 893 /* Ensure the socket fds won't be 0, 1 or 2 */
901 bb_sanitize_stdio(); 894 bb_sanitize_stdio();
902 895
903 INIT_G(); 896 INIT_G();
897 port = 33434;
898 waittime = 5;
899 G.first_ttl = 1;
900 G.nprobes = 3;
901 G.max_ttl = 30;
904 902
905 op |= getopt32(argv, "^" 903 op |= getopt32(argv, "^"
906 OPT_STRING 904 OPT_STRING
@@ -919,17 +917,17 @@ common_traceroute_main(int op, char **argv)
919 tos = xatou_range(tos_str, 0, 255); 917 tos = xatou_range(tos_str, 0, 255);
920#endif 918#endif
921 if (op & OPT_MAX_TTL) 919 if (op & OPT_MAX_TTL)
922 max_ttl = xatou_range(max_ttl_str, 1, 255); 920 G.max_ttl = xatou_range(max_ttl_str, 1, 255);
923 if (op & OPT_PORT) 921 if (op & OPT_PORT)
924 port = xatou16(port_str); 922 port = xatou16(port_str);
925 if (op & OPT_NPROBES) 923 if (op & OPT_NPROBES)
926 nprobes = xatou_range(nprobes_str, 1, INT_MAX); 924 G.nprobes = xatou_range(nprobes_str, 1, INT_MAX);
927 if (op & OPT_WAITTIME) 925 if (op & OPT_WAITTIME)
928 waittime = xatou_range(waittime_str, 1, 24 * 60 * 60); 926 waittime = xatou_range(waittime_str, 1, 24 * 60 * 60);
929 if (op & OPT_PAUSE_MS) 927 if (op & OPT_PAUSE_MS)
930 pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000); 928 G.pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
931 if (op & OPT_FIRST_TTL) 929 if (op & OPT_FIRST_TTL)
932 first_ttl = xatou_range(first_ttl_str, 1, max_ttl); 930 G.first_ttl = xatou_range(first_ttl_str, 1, G.max_ttl);
933 931
934 /* Process destination and optional packet size */ 932 /* Process destination and optional packet size */
935 minpacket = sizeof(struct ip) 933 minpacket = sizeof(struct ip)
@@ -961,6 +959,9 @@ common_traceroute_main(int op, char **argv)
961#else 959#else
962 dest_lsa = xhost2sockaddr(argv[0], port); 960 dest_lsa = xhost2sockaddr(argv[0], port);
963#endif 961#endif
962 G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
963 G.to = xzalloc(dest_lsa->len);
964
964 packlen = minpacket; 965 packlen = minpacket;
965 if (argv[1]) 966 if (argv[1])
966 packlen = xatoul_range(argv[1], minpacket, 32 * 1024); 967 packlen = xatoul_range(argv[1], minpacket, 32 * 1024);
@@ -1102,20 +1103,28 @@ common_traceroute_main(int op, char **argv)
1102 1103
1103 if (op & OPT_SOURCE) 1104 if (op & OPT_SOURCE)
1104 printf(" from %s", source); 1105 printf(" from %s", source);
1105 printf(", %d hops max, %d byte packets\n", max_ttl, packlen); 1106 printf(", %d hops max, %d byte packets\n", G.max_ttl, packlen);
1107}
1108
1109static int
1110common_traceroute_main(int op, char **argv)
1111{
1112 int ttl;
1113 int seq;
1114 struct sockaddr *lastaddr;
1115
1116 traceroute_init(op, argv);
1106 1117
1107 lastaddr = xzalloc(dest_lsa->len); 1118 lastaddr = xzalloc(dest_lsa->len);
1108 G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
1109 G.to = xzalloc(dest_lsa->len);
1110 seq = 0; 1119 seq = 0;
1111 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { 1120 for (ttl = G.first_ttl; ttl <= G.max_ttl; ++ttl) {
1112 int probe; 1121 int probe;
1113 int unreachable = 0; /* counter */ 1122 int unreachable = 0; /* counter */
1114 int gotlastaddr = 0; /* flags */ 1123 int gotlastaddr = 0; /* flags */
1115 int got_there = 0; 1124 int got_there = 0;
1116 1125
1117 printf("%2d", ttl); 1126 printf("%2d", ttl);
1118 for (probe = 0; probe < nprobes; ++probe) { 1127 for (probe = 0; probe < G.nprobes; ++probe) {
1119 int read_len; 1128 int read_len;
1120 unsigned t1; 1129 unsigned t1;
1121 unsigned t2; 1130 unsigned t2;
@@ -1123,14 +1132,15 @@ common_traceroute_main(int op, char **argv)
1123 1132
1124 fflush_all(); 1133 fflush_all();
1125 if (probe != 0) 1134 if (probe != 0)
1126 msleep(pausemsecs); 1135 msleep(G.pausemsecs);
1127 1136
1128 send_probe(++seq, ttl); 1137 send_probe(++seq, ttl);
1129 t2 = t1 = monotonic_us(); 1138 t2 = t1 = monotonic_us();
1130 1139
1131 left_ms = waittime * 1000; 1140 left_ms = waittime * 1000;
1132 /* NB: wait_for_reply() fills "G.from_lsa" and "G.to" 1141 /* NB: wait_for_reply() fills "G.from_lsa" and "G.to" with
1133 * with "where it came from" and "to which local address it arrived". 1142 * "where it came from" and "what local address it arrived to"
1143 * addresses.
1134 */ 1144 */
1135 while ((read_len = wait_for_reply(&t2, &left_ms)) != 0) { 1145 while ((read_len = wait_for_reply(&t2, &left_ms)) != 0) {
1136 int icmp_code; 1146 int icmp_code;
@@ -1255,7 +1265,7 @@ common_traceroute_main(int op, char **argv)
1255 1265
1256 bb_putchar('\n'); 1266 bb_putchar('\n');
1257 if (got_there 1267 if (got_there
1258 || (unreachable > 0 && unreachable >= nprobes - 1) 1268 || (unreachable > 0 && unreachable >= G.nprobes - 1)
1259 ) { 1269 ) {
1260 break; 1270 break;
1261 } 1271 }