diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-12 21:44:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-12 21:44:32 +0100 |
commit | 724c7df683b8f3d0c487ce3d3cdcc1f6e762c181 (patch) | |
tree | 2d63c3ebaec9c46d87d75f2501be7cbf93087359 | |
parent | e76f03b267aed3c7c9a247ef4b27e1bb1c56e024 (diff) | |
download | busybox-w32-724c7df683b8f3d0c487ce3d3cdcc1f6e762c181.tar.gz busybox-w32-724c7df683b8f3d0c487ce3d3cdcc1f6e762c181.tar.bz2 busybox-w32-724c7df683b8f3d0c487ce3d3cdcc1f6e762c181.zip |
traceroute: untangle main loop
function old new delta
common_traceroute_main 1785 1730 -55
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/traceroute.c | 218 |
1 files changed, 106 insertions, 112 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c index 0fb01ff5b..1e96a73cf 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -463,6 +463,8 @@ wait_for_reply(unsigned *timestamp_us, int *left_ms) | |||
463 | recv_pkt, sizeof(recv_pkt), | 463 | recv_pkt, sizeof(recv_pkt), |
464 | /*flags:*/ MSG_DONTWAIT, | 464 | /*flags:*/ MSG_DONTWAIT, |
465 | &G.from_lsa->u.sa, G.to, G.from_lsa->len); | 465 | &G.from_lsa->u.sa, G.to, G.from_lsa->len); |
466 | if (read_len < 0) | ||
467 | bb_perror_msg_and_die("recv"); | ||
466 | t = monotonic_us(); | 468 | t = monotonic_us(); |
467 | *left_ms -= (t - *timestamp_us) / 1000; | 469 | *left_ms -= (t - *timestamp_us) / 1000; |
468 | *timestamp_us = t; | 470 | *timestamp_us = t; |
@@ -1076,147 +1078,139 @@ common_traceroute_main(int op, char **argv) | |||
1076 | for (ttl = G.first_ttl; ttl <= G.max_ttl; ++ttl) { | 1078 | for (ttl = G.first_ttl; ttl <= G.max_ttl; ++ttl) { |
1077 | int probe; | 1079 | int probe; |
1078 | int unreachable = 0; /* counter */ | 1080 | int unreachable = 0; /* counter */ |
1079 | int gotlastaddr = 0; /* flags */ | ||
1080 | int got_there = 0; | 1081 | int got_there = 0; |
1081 | 1082 | ||
1082 | printf("%2d", ttl); | 1083 | printf("%2d", ttl); |
1083 | for (probe = 0; probe < G.nprobes; ++probe) { | 1084 | for (probe = 0; probe < G.nprobes; ++probe) { |
1084 | int read_len; | ||
1085 | unsigned t1; | 1085 | unsigned t1; |
1086 | unsigned t2; | 1086 | unsigned t2; |
1087 | int left_ms; | 1087 | int left_ms; |
1088 | int read_len; | ||
1089 | int icmp_code; | ||
1088 | 1090 | ||
1089 | fflush_all(); | 1091 | fflush_all(); |
1090 | if (probe != 0) | 1092 | if (probe != 0) |
1091 | msleep(G.pausemsecs); | 1093 | msleep(G.pausemsecs); |
1092 | 1094 | ||
1093 | send_probe(++seq, ttl); | 1095 | send_probe(++seq, ttl); |
1094 | t2 = t1 = monotonic_us(); | ||
1095 | 1096 | ||
1097 | t2 = t1 = monotonic_us(); | ||
1096 | left_ms = waittime * 1000; | 1098 | left_ms = waittime * 1000; |
1097 | /* NB: wait_for_reply() fills "G.from_lsa" and "G.to" with | 1099 | for (;;) { |
1098 | * "where it came from" and "what local address it arrived to" | 1100 | /* NB: wait_for_reply() fills "G.from_lsa" and "G.to" with |
1099 | * addresses. | 1101 | * "where it came from" and "what local address it arrived to" |
1100 | */ | 1102 | * addresses. Sets t2 = monotonic_us(), updates left_ms. |
1101 | while ((read_len = wait_for_reply(&t2, &left_ms)) != 0) { | 1103 | */ |
1102 | int icmp_code; | 1104 | read_len = wait_for_reply(&t2, &left_ms); |
1103 | 1105 | ||
1104 | /* Recv'ed a packet, or read error */ | 1106 | if (read_len == 0) { /* there was no packet at all? */ |
1105 | /* t2 = monotonic_us() - set by wait_for_reply */ | 1107 | printf(" *"); |
1106 | 1108 | goto next_probe; | |
1107 | if (read_len < 0) | ||
1108 | continue; | ||
1109 | icmp_code = packet_ok(read_len, seq); | ||
1110 | /* Skip short packet */ | ||
1111 | if (icmp_code == 0) | ||
1112 | continue; | ||
1113 | |||
1114 | if (!gotlastaddr | ||
1115 | || (memcmp(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len) != 0) | ||
1116 | ) { | ||
1117 | print(read_len); | ||
1118 | memcpy(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len); | ||
1119 | gotlastaddr = 1; | ||
1120 | } | 1109 | } |
1110 | icmp_code = packet_ok(read_len, seq); | ||
1111 | if (icmp_code != 0) | ||
1112 | break; /* got a good response */ | ||
1113 | /* unrecognized type/code or too short, back to recv */ | ||
1114 | } | ||
1121 | 1115 | ||
1122 | print_delta_ms(t1, t2); | 1116 | if (probe == 0 |
1123 | 1117 | || (memcmp(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len) != 0) | |
1124 | if (G.from_lsa->u.sa.sa_family == AF_INET) { | 1118 | ) { |
1125 | if (op & OPT_TTL_FLAG) { | 1119 | print(read_len); |
1126 | struct ip *ip = (struct ip *)recv_pkt; | 1120 | memcpy(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len); |
1127 | printf(" (%d)", ip->ip_ttl); | 1121 | } |
1128 | } | 1122 | print_delta_ms(t1, t2); |
1123 | if (G.from_lsa->u.sa.sa_family == AF_INET) { | ||
1124 | if (op & OPT_TTL_FLAG) { | ||
1125 | struct ip *ip = (struct ip *)recv_pkt; | ||
1126 | printf(" (%d)", ip->ip_ttl); | ||
1129 | } | 1127 | } |
1128 | } | ||
1130 | 1129 | ||
1131 | /* Got a "time exceeded in transit" icmp message? */ | 1130 | /* Got a "time exceeded in transit" icmp message? */ |
1132 | if (icmp_code == -1) | 1131 | if (icmp_code == -1) |
1133 | break; | 1132 | continue; |
1134 | 1133 | ||
1135 | icmp_code--; | 1134 | icmp_code--; |
1136 | switch (icmp_code) { | 1135 | switch (icmp_code) { |
1137 | #if ENABLE_TRACEROUTE6 | 1136 | #if ENABLE_TRACEROUTE6 |
1138 | case ICMP6_DST_UNREACH_NOPORT << 8: | 1137 | case ICMP6_DST_UNREACH_NOPORT << 8: |
1139 | got_there = 1; | 1138 | got_there = 1; |
1140 | break; | 1139 | break; |
1141 | #endif | 1140 | #endif |
1142 | case ICMP_UNREACH_PORT: { | 1141 | case ICMP_UNREACH_PORT: { |
1143 | struct ip *ip = (struct ip *)recv_pkt; | 1142 | struct ip *ip = (struct ip *)recv_pkt; |
1144 | if (ip->ip_ttl <= 1) | 1143 | if (ip->ip_ttl <= 1) |
1145 | printf(" !"); | 1144 | printf(" !"); |
1146 | got_there = 1; | 1145 | got_there = 1; |
1147 | break; | 1146 | break; |
1148 | } | 1147 | } |
1149 | case ICMP_UNREACH_NET: | 1148 | case ICMP_UNREACH_NET: |
1150 | #if ENABLE_TRACEROUTE6 && (ICMP6_DST_UNREACH_NOROUTE != ICMP_UNREACH_NET) | 1149 | #if ENABLE_TRACEROUTE6 && (ICMP6_DST_UNREACH_NOROUTE != ICMP_UNREACH_NET) |
1151 | case ICMP6_DST_UNREACH_NOROUTE << 8: | 1150 | case ICMP6_DST_UNREACH_NOROUTE << 8: |
1152 | #endif | 1151 | #endif |
1153 | printf(" !N"); | 1152 | printf(" !N"); |
1154 | ++unreachable; | 1153 | ++unreachable; |
1155 | break; | 1154 | break; |
1156 | case ICMP_UNREACH_HOST: | 1155 | case ICMP_UNREACH_HOST: |
1157 | #if ENABLE_TRACEROUTE6 | 1156 | #if ENABLE_TRACEROUTE6 |
1158 | case ICMP6_DST_UNREACH_ADDR << 8: | 1157 | case ICMP6_DST_UNREACH_ADDR << 8: |
1159 | #endif | 1158 | #endif |
1160 | printf(" !H"); | 1159 | printf(" !H"); |
1161 | ++unreachable; | 1160 | ++unreachable; |
1162 | break; | 1161 | break; |
1163 | case ICMP_UNREACH_PROTOCOL: | 1162 | case ICMP_UNREACH_PROTOCOL: |
1164 | printf(" !P"); | 1163 | printf(" !P"); |
1165 | got_there = 1; | 1164 | got_there = 1; |
1166 | break; | 1165 | break; |
1167 | case ICMP_UNREACH_NEEDFRAG: | 1166 | case ICMP_UNREACH_NEEDFRAG: |
1168 | printf(" !F-%d", pmtu); | 1167 | printf(" !F-%d", pmtu); |
1169 | ++unreachable; | 1168 | ++unreachable; |
1170 | break; | 1169 | break; |
1171 | case ICMP_UNREACH_SRCFAIL: | 1170 | case ICMP_UNREACH_SRCFAIL: |
1172 | #if ENABLE_TRACEROUTE6 | 1171 | #if ENABLE_TRACEROUTE6 |
1173 | case ICMP6_DST_UNREACH_ADMIN << 8: | 1172 | case ICMP6_DST_UNREACH_ADMIN << 8: |
1174 | #endif | 1173 | #endif |
1175 | printf(" !S"); | 1174 | printf(" !S"); |
1176 | ++unreachable; | 1175 | ++unreachable; |
1177 | break; | ||
1178 | case ICMP_UNREACH_FILTER_PROHIB: | ||
1179 | case ICMP_UNREACH_NET_PROHIB: /* misuse */ | ||
1180 | printf(" !A"); | ||
1181 | ++unreachable; | ||
1182 | break; | ||
1183 | case ICMP_UNREACH_HOST_PROHIB: | ||
1184 | printf(" !C"); | ||
1185 | ++unreachable; | ||
1186 | break; | ||
1187 | case ICMP_UNREACH_HOST_PRECEDENCE: | ||
1188 | printf(" !V"); | ||
1189 | ++unreachable; | ||
1190 | break; | ||
1191 | case ICMP_UNREACH_PRECEDENCE_CUTOFF: | ||
1192 | printf(" !C"); | ||
1193 | ++unreachable; | ||
1194 | break; | ||
1195 | case ICMP_UNREACH_NET_UNKNOWN: | ||
1196 | case ICMP_UNREACH_HOST_UNKNOWN: | ||
1197 | printf(" !U"); | ||
1198 | ++unreachable; | ||
1199 | break; | ||
1200 | case ICMP_UNREACH_ISOLATED: | ||
1201 | printf(" !I"); | ||
1202 | ++unreachable; | ||
1203 | break; | ||
1204 | case ICMP_UNREACH_TOSNET: | ||
1205 | case ICMP_UNREACH_TOSHOST: | ||
1206 | printf(" !T"); | ||
1207 | ++unreachable; | ||
1208 | break; | ||
1209 | default: | ||
1210 | printf(" !<%d>", icmp_code); | ||
1211 | ++unreachable; | ||
1212 | break; | ||
1213 | } | ||
1214 | break; | 1176 | break; |
1215 | } /* while (wait and read a packet) */ | 1177 | case ICMP_UNREACH_FILTER_PROHIB: |
1216 | 1178 | case ICMP_UNREACH_NET_PROHIB: /* misuse */ | |
1217 | /* there was no packet at all? */ | 1179 | printf(" !A"); |
1218 | if (read_len == 0) | 1180 | ++unreachable; |
1219 | printf(" *"); | 1181 | break; |
1182 | case ICMP_UNREACH_HOST_PROHIB: | ||
1183 | printf(" !C"); | ||
1184 | ++unreachable; | ||
1185 | break; | ||
1186 | case ICMP_UNREACH_HOST_PRECEDENCE: | ||
1187 | printf(" !V"); | ||
1188 | ++unreachable; | ||
1189 | break; | ||
1190 | case ICMP_UNREACH_PRECEDENCE_CUTOFF: | ||
1191 | printf(" !C"); | ||
1192 | ++unreachable; | ||
1193 | break; | ||
1194 | case ICMP_UNREACH_NET_UNKNOWN: | ||
1195 | case ICMP_UNREACH_HOST_UNKNOWN: | ||
1196 | printf(" !U"); | ||
1197 | ++unreachable; | ||
1198 | break; | ||
1199 | case ICMP_UNREACH_ISOLATED: | ||
1200 | printf(" !I"); | ||
1201 | ++unreachable; | ||
1202 | break; | ||
1203 | case ICMP_UNREACH_TOSNET: | ||
1204 | case ICMP_UNREACH_TOSHOST: | ||
1205 | printf(" !T"); | ||
1206 | ++unreachable; | ||
1207 | break; | ||
1208 | default: | ||
1209 | printf(" !<%d>", icmp_code); | ||
1210 | ++unreachable; | ||
1211 | break; | ||
1212 | } | ||
1213 | next_probe: ; | ||
1220 | } /* for (nprobes) */ | 1214 | } /* for (nprobes) */ |
1221 | 1215 | ||
1222 | bb_putchar('\n'); | 1216 | bb_putchar('\n'); |