aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-12-12 17:45:49 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-12-12 18:09:45 +0100
commit70726640b33e50d0802f297c5a3f18494a488c8d (patch)
tree1bc63c57a6121e5ca9410ea8e75b6b4e08205dcd
parentd0dea17900267ec9644aa72721d2f0473338651c (diff)
downloadbusybox-w32-70726640b33e50d0802f297c5a3f18494a488c8d.tar.gz
busybox-w32-70726640b33e50d0802f297c5a3f18494a488c8d.tar.bz2
busybox-w32-70726640b33e50d0802f297c5a3f18494a488c8d.zip
traceroute: code shrink
Do not pass "from" and "to" addresses as parameters, keep them in globals function old new delta common_traceroute_main 3426 3391 -35 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/traceroute.c84
1 files changed, 35 insertions, 49 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 764d66ef8..588570fcb 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -389,6 +389,8 @@ struct globals {
389 struct outdata_t *outdata; 389 struct outdata_t *outdata;
390 390
391 len_and_sockaddr *dest_lsa; 391 len_and_sockaddr *dest_lsa;
392 len_and_sockaddr *from_lsa; /* response came from this address */
393 struct sockaddr *to; /* response came to this (local) address */
392 int packlen; /* total length of packet */ 394 int packlen; /* total length of packet */
393 int pmtu; /* Path MTU Discovery (RFC1191) */ 395 int pmtu; /* Path MTU Discovery (RFC1191) */
394 uint32_t ident; 396 uint32_t ident;
@@ -442,7 +444,7 @@ struct globals {
442 */ 444 */
443 445
444static int 446static int
445wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timestamp_us, int *left_ms) 447wait_for_reply(unsigned *timestamp_us, int *left_ms)
446{ 448{
447 struct pollfd pfd[1]; 449 struct pollfd pfd[1];
448 int read_len = 0; 450 int read_len = 0;
@@ -455,7 +457,7 @@ wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timest
455 read_len = recv_from_to(rcvsock, 457 read_len = recv_from_to(rcvsock,
456 recv_pkt, sizeof(recv_pkt), 458 recv_pkt, sizeof(recv_pkt),
457 /*flags:*/ MSG_DONTWAIT, 459 /*flags:*/ MSG_DONTWAIT,
458 &from_lsa->u.sa, to, from_lsa->len); 460 &G.from_lsa->u.sa, G.to, G.from_lsa->len);
459 t = monotonic_us(); 461 t = monotonic_us();
460 *left_ms -= (t - *timestamp_us) / 1000; 462 *left_ms -= (t - *timestamp_us) / 1000;
461 *timestamp_us = t; 463 *timestamp_us = t;
@@ -598,7 +600,7 @@ pr_type(unsigned char t)
598 packet4_ok(read_len, seq) 600 packet4_ok(read_len, seq)
599#endif 601#endif
600static int 602static int
601packet4_ok(int read_len, const struct sockaddr_in *from, int seq) 603packet4_ok(int read_len, int seq)
602{ 604{
603 const struct icmp *icp; 605 const struct icmp *icp;
604 unsigned char type, code; 606 unsigned char type, code;
@@ -616,7 +618,7 @@ packet4_ok(int read_len, const struct sockaddr_in *from, int seq)
616#if ENABLE_FEATURE_TRACEROUTE_VERBOSE 618#if ENABLE_FEATURE_TRACEROUTE_VERBOSE
617 if (verbose) 619 if (verbose)
618 printf("packet too short (%d bytes) from %s\n", read_len, 620 printf("packet too short (%d bytes) from %s\n", read_len,
619 inet_ntoa(from->sin_addr)); 621 inet_ntoa(G.from_lsa->u.sin.sin_addr));
620#endif 622#endif
621 return 0; 623 return 0;
622 } 624 }
@@ -680,7 +682,7 @@ packet4_ok(int read_len, const struct sockaddr_in *from, int seq)
680 uint32_t *lp = (uint32_t *)&icp->icmp_ip; 682 uint32_t *lp = (uint32_t *)&icp->icmp_ip;
681 683
682 printf("\n%d bytes from %s", 684 printf("\n%d bytes from %s",
683 read_len, inet_ntoa(from->sin_addr)); 685 read_len, inet_ntoa(G.from_lsa->u.sin.sin_addr));
684 /* Two separate printf() because inet_ntoa() returns static string */ 686 /* Two separate printf() because inet_ntoa() returns static string */
685 printf(" to %s: icmp type %d (%s) code %d\n", 687 printf(" to %s: icmp type %d (%s) code %d\n",
686 inet_ntoa(ip->ip_dst), 688 inet_ntoa(ip->ip_dst),
@@ -694,14 +696,8 @@ packet4_ok(int read_len, const struct sockaddr_in *from, int seq)
694 696
695#if ENABLE_TRACEROUTE6 697#if ENABLE_TRACEROUTE6
696 698
697# if !ENABLE_FEATURE_TRACEROUTE_VERBOSE
698#define packet6_ok(read_len, from_lsa, to, seq) \
699 packet6_ok(read_len, from_lsa, seq)
700# endif
701static int 699static int
702packet6_ok(int read_len, const struct sockaddr_in6 *from, 700packet6_ok(int read_len, int seq)
703 struct sockaddr *to,
704 int seq)
705{ 701{
706 const struct icmp6_hdr *icp; 702 const struct icmp6_hdr *icp;
707 unsigned char type, code; 703 unsigned char type, code;
@@ -757,21 +753,18 @@ packet6_ok(int read_len, const struct sockaddr_in6 *from,
757 753
758# if ENABLE_FEATURE_TRACEROUTE_VERBOSE 754# if ENABLE_FEATURE_TRACEROUTE_VERBOSE
759 if (verbose) { 755 if (verbose) {
760# ifndef MAXHOSTNAMELEN
761# define MAXHOSTNAMELEN 80
762# endif
763 unsigned char *p; 756 unsigned char *p;
764 char pa[MAXHOSTNAMELEN]; 757 char pa[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") + 4];
765 int i; 758 int i;
766 759
767 p = (unsigned char *) (icp + 1); 760 p = (unsigned char *) (icp + 1);
768 761
769 printf("\n%d bytes from %s", 762 printf("\n%d bytes from %s",
770 read_len, 763 read_len,
771 inet_ntop(AF_INET6, &from->sin6_addr, pa, sizeof(pa))); 764 inet_ntop(AF_INET6, &G.from_lsa->u.sin6.sin6_addr, pa, sizeof(pa)));
772 /* Two printf() instead of one - reuse string constants */ 765 /* Two printf() instead of one - reuse string constants */
773 printf(" to %s: icmp type %d (%s) code %d\n", 766 printf(" to %s: icmp type %d (%s) code %d\n",
774 inet_ntop(AF_INET6, &((struct sockaddr_in6*)to)->sin6_addr, pa, sizeof(pa)), 767 inet_ntop(AF_INET6, &((struct sockaddr_in6*)G.to)->sin6_addr, pa, sizeof(pa)),
775 type, pr_type(type), icp->icmp6_code); 768 type, pr_type(type), icp->icmp6_code);
776 769
777 read_len -= sizeof(struct icmp6_hdr); 770 read_len -= sizeof(struct icmp6_hdr);
@@ -790,29 +783,21 @@ packet6_ok(int read_len, const struct sockaddr_in6 *from,
790 783
791 return 0; 784 return 0;
792} 785}
793# if !ENABLE_FEATURE_TRACEROUTE_VERBOSE 786
794#define packet_ok(read_len, from_lsa, to, seq) \
795 packet_ok(read_len, from_lsa, seq)
796# endif
797static int 787static int
798packet_ok(int read_len, len_and_sockaddr *from_lsa, 788packet_ok(int read_len, int seq)
799 struct sockaddr *to,
800 int seq)
801{ 789{
802 if (from_lsa->u.sa.sa_family == AF_INET) 790 if (G.from_lsa->u.sa.sa_family == AF_INET)
803 return packet4_ok(read_len, &from_lsa->u.sin, seq); 791 return packet4_ok(read_len, seq);
804 return packet6_ok(read_len, &from_lsa->u.sin6, to, seq); 792 return packet6_ok(read_len, seq);
805} 793}
806 794
807#else /* !ENABLE_TRACEROUTE6 */ 795#else /* !ENABLE_TRACEROUTE6 */
808 796
809static ALWAYS_INLINE int 797static ALWAYS_INLINE int
810packet_ok(int read_len, 798packet_ok(int read_len, int seq)
811 len_and_sockaddr *from_lsa IF_NOT_FEATURE_TRACEROUTE_VERBOSE(UNUSED_PARAM),
812 struct sockaddr *to UNUSED_PARAM,
813 int seq)
814{ 799{
815 return packet4_ok(read_len, &from_lsa->u.sin, seq); 800 return packet4_ok(read_len, seq);
816} 801}
817 802
818#endif 803#endif
@@ -845,19 +830,19 @@ print_inetname(const struct sockaddr *from)
845} 830}
846 831
847static void 832static void
848print(int read_len, const struct sockaddr *from, const struct sockaddr *to) 833print(int read_len)
849{ 834{
850 print_inetname(from); 835 print_inetname(&G.from_lsa->u.sa);
851 836
852 if (verbose) { 837 if (verbose) {
853 char *ina = xmalloc_sockaddr2dotted_noport(to); 838 char *ina = xmalloc_sockaddr2dotted_noport(G.to);
854#if ENABLE_TRACEROUTE6 839#if ENABLE_TRACEROUTE6
855 /* NB: reads from (AF_INET, SOCK_RAW, IPPROTO_ICMP) socket 840 /* NB: reads from (AF_INET, SOCK_RAW, IPPROTO_ICMP) socket
856 * return the entire IP packet (IOW: they do not strip IP header). 841 * return the entire IP packet (IOW: they do not strip IP header).
857 * Reads from (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) do strip IPv6 842 * Reads from (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) do strip IPv6
858 * header and return only ICMP6 packet. Weird. 843 * header and return only ICMP6 packet. Weird.
859 */ 844 */
860 if (to->sa_family == AF_INET6) { 845 if (G.to->sa_family == AF_INET6) {
861 /* read_len -= sizeof(struct ip6_hdr); - WRONG! */ 846 /* read_len -= sizeof(struct ip6_hdr); - WRONG! */
862 } else 847 } else
863#endif 848#endif
@@ -910,9 +895,7 @@ common_traceroute_main(int op, char **argv)
910#endif 895#endif
911 int ttl; 896 int ttl;
912 int seq; 897 int seq;
913 len_and_sockaddr *from_lsa;
914 struct sockaddr *lastaddr; 898 struct sockaddr *lastaddr;
915 struct sockaddr *to;
916 899
917 /* Ensure the socket fds won't be 0, 1 or 2 */ 900 /* Ensure the socket fds won't be 0, 1 or 2 */
918 bb_sanitize_stdio(); 901 bb_sanitize_stdio();
@@ -1121,9 +1104,9 @@ common_traceroute_main(int op, char **argv)
1121 printf(" from %s", source); 1104 printf(" from %s", source);
1122 printf(", %d hops max, %d byte packets\n", max_ttl, packlen); 1105 printf(", %d hops max, %d byte packets\n", max_ttl, packlen);
1123 1106
1124 from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
1125 lastaddr = xzalloc(dest_lsa->len); 1107 lastaddr = xzalloc(dest_lsa->len);
1126 to = xzalloc(dest_lsa->len); 1108 G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
1109 G.to = xzalloc(dest_lsa->len);
1127 seq = 0; 1110 seq = 0;
1128 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { 1111 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
1129 int probe; 1112 int probe;
@@ -1146,7 +1129,10 @@ common_traceroute_main(int op, char **argv)
1146 t2 = t1 = monotonic_us(); 1129 t2 = t1 = monotonic_us();
1147 1130
1148 left_ms = waittime * 1000; 1131 left_ms = waittime * 1000;
1149 while ((read_len = wait_for_reply(from_lsa, to, &t2, &left_ms)) != 0) { 1132 /* NB: wait_for_reply() fills "G.from_lsa" and "G.to"
1133 * with "where it came from" and "to which local address it arrived".
1134 */
1135 while ((read_len = wait_for_reply(&t2, &left_ms)) != 0) {
1150 int icmp_code; 1136 int icmp_code;
1151 1137
1152 /* Recv'ed a packet, or read error */ 1138 /* Recv'ed a packet, or read error */
@@ -1154,22 +1140,22 @@ common_traceroute_main(int op, char **argv)
1154 1140
1155 if (read_len < 0) 1141 if (read_len < 0)
1156 continue; 1142 continue;
1157 icmp_code = packet_ok(read_len, from_lsa, to, seq); 1143 icmp_code = packet_ok(read_len, seq);
1158 /* Skip short packet */ 1144 /* Skip short packet */
1159 if (icmp_code == 0) 1145 if (icmp_code == 0)
1160 continue; 1146 continue;
1161 1147
1162 if (!gotlastaddr 1148 if (!gotlastaddr
1163 || (memcmp(lastaddr, &from_lsa->u.sa, from_lsa->len) != 0) 1149 || (memcmp(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len) != 0)
1164 ) { 1150 ) {
1165 print(read_len, &from_lsa->u.sa, to); 1151 print(read_len);
1166 memcpy(lastaddr, &from_lsa->u.sa, from_lsa->len); 1152 memcpy(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len);
1167 gotlastaddr = 1; 1153 gotlastaddr = 1;
1168 } 1154 }
1169 1155
1170 print_delta_ms(t1, t2); 1156 print_delta_ms(t1, t2);
1171 1157
1172 if (from_lsa->u.sa.sa_family == AF_INET) { 1158 if (G.from_lsa->u.sa.sa_family == AF_INET) {
1173 if (op & OPT_TTL_FLAG) { 1159 if (op & OPT_TTL_FLAG) {
1174 struct ip *ip = (struct ip *)recv_pkt; 1160 struct ip *ip = (struct ip *)recv_pkt;
1175 printf(" (%d)", ip->ip_ttl); 1161 printf(" (%d)", ip->ip_ttl);
@@ -1276,9 +1262,9 @@ common_traceroute_main(int op, char **argv)
1276 } 1262 }
1277 1263
1278 if (ENABLE_FEATURE_CLEAN_UP) { 1264 if (ENABLE_FEATURE_CLEAN_UP) {
1279 free(to); 1265 free(G.to);
1280 free(lastaddr); 1266 free(lastaddr);
1281 free(from_lsa); 1267 free(G.from_lsa);
1282 } 1268 }
1283 1269
1284 return 0; 1270 return 0;