[git commit] traceroute: make "ipv4 or ipv6?" cheaper to find out

Denys Vlasenko vda.linux at googlemail.com
Sun Dec 13 13:58:11 UTC 2020


commit: https://git.busybox.net/busybox/commit/?id=b4b182807687a872c49a89b840754a553c00f8a1
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
traceroute_init                                     1131    1135      +4
hexdump                                              274     270      -4
common_traceroute_main                              1730    1715     -15
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 4/-19)             Total: -15 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/traceroute.c | 36 +++++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/networking/traceroute.c b/networking/traceroute.c
index 8e13238bf..4d0ebc3b7 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -324,7 +324,6 @@
 #ifndef IPPROTO_IP
 # define IPPROTO_IP 0
 #endif
-
 /* Some operating systems, like GNU/Hurd, don't define SOL_RAW, but do have
  * IPPROTO_RAW. Since the IPPROTO definitions are also valid to use for
  * setsockopt (and take the same value as their corresponding SOL definitions,
@@ -391,19 +390,24 @@ struct globals {
 	struct ip *outip;
 	/* Pointer to ICMP or UDP payload (not header): */
 	struct outdata_t *outdata;
-
 	len_and_sockaddr *dest_lsa;
 	len_and_sockaddr *from_lsa;	/* response came from this address */
 	struct sockaddr *to; 		/* response came to this (local) address */
-	int packlen;                    /* total length of packet */
-	int pmtu;                       /* Path MTU Discovery (RFC1191) */
 	uint32_t ident;
 	uint16_t port;                  /* start udp dest port # for probe packets */
+#if ENABLE_TRACEROUTE6
+	smallint ipv6;
+# define G_ipv6 G.ipv6
+#else
+# define G_ipv6 0
+#endif
+	int packlen;                    /* total length of packet */
+	int pmtu;                       /* Path MTU Discovery (RFC1191) */
 	int waittime;                   /* time to wait for response (in seconds) */
 	int first_ttl;
 	int nprobes;
-	unsigned pausemsecs;
 	int max_ttl;
+	unsigned pausemsecs;
 	unsigned char recv_pkt[512];    /* last inbound (icmp) packet */
 };
 
@@ -482,7 +486,7 @@ send_probe(int seq, int ttl)
 
 	/* Payload */
 #if ENABLE_TRACEROUTE6
-	if (dest_lsa->u.sa.sa_family == AF_INET6) {
+	if (G_ipv6) {
 		struct outdata6_t *pkt = (void *) outdata;
 		pkt->ident6 = ident;
 		pkt->seq6   = htonl(seq);
@@ -541,7 +545,7 @@ send_probe(int seq, int ttl)
 #endif
 
 #if ENABLE_TRACEROUTE6
-	if (dest_lsa->u.sa.sa_family == AF_INET6) {
+	if (G_ipv6) {
 		res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl);
 		if (res != 0)
 			bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl);
@@ -585,7 +589,7 @@ pr_type(unsigned char t)
 [16]	= "Neighbor Advert", "Redirect",
 	};
 
-	if (dest_lsa->u.sa.sa_family == AF_INET6) {
+	if (G_ipv6) {
 		if (t < 5)
 			return ttab6[t];
 		if (t < 128 || t > ND_REDIRECT)
@@ -772,7 +776,7 @@ packet6_ok(int read_len, int seq)
 static int
 packet_ok(int read_len, int seq)
 {
-	if (G.from_lsa->u.sa.sa_family == AF_INET)
+	if (!G_ipv6)
 		return packet4_ok(read_len, seq);
 	return packet6_ok(read_len, seq);
 }
@@ -792,10 +796,10 @@ print(int read_len)
 		printf("  %s", ina);
 	} else {
 		char *n = NULL;
-		if (G.from_lsa->u.sa.sa_family != AF_INET
+		if (G_ipv6
 		 || G.from_lsa->u.sin.sin_addr.s_addr != INADDR_ANY
 		) {
-			/* Try to reverse resolve if it is not 0.0.0.0 */
+			/* Reverse resolve if IPV6 or not 0.0.0.0 */
 			n = auto_string(xmalloc_sockaddr2host_noport(&G.from_lsa->u.sa));
 		}
 		printf("  %s (%s)", (n ? n : ina), ina);
@@ -808,7 +812,7 @@ print(int read_len)
 		 * Reads from (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) do strip IPv6
 		 * header and return only ICMP6 packet. Weird.
 		 */
-		if (G.from_lsa->u.sa.sa_family == AF_INET6) {
+		if (G_ipv6) {
 			/* read_len -= sizeof(struct ip6_hdr); - WRONG! */
 		} else
 #endif
@@ -904,7 +908,9 @@ traceroute_init(int op, char **argv)
 		af = AF_INET6;
 	dest_lsa = xhost_and_af2sockaddr(argv[0], port, af);
 	af = dest_lsa->u.sa.sa_family;
+//TODO: make sure af == AF_INET[6]? (FEATURE_UNIX_LOCAL=y allows "local:/PATH" to be translated to AF_UNIX)
 	if (af == AF_INET6) {
+		G_ipv6 = 1;
 		packlen = sizeof(struct ip6_hdr)
 				+ sizeof(struct udphdr)
 				+ sizeof(struct outdata6_t);
@@ -914,9 +920,9 @@ traceroute_init(int op, char **argv)
 				+ sizeof(struct outdata6_t);
 	}
 #else
-	dest_lsa = xhost2sockaddr(argv[0], port);
+	/* accept only IPv4 addresses */
+	dest_lsa = xhost_and_af2sockaddr(argv[0], port, AF_INET);
 #endif
-//TODO: make sure af == AF_INET[6]? (FEATURE_UNIX_LOCAL=y allows "local:/PATH" to be translated to AF_UNIX)
 	G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
 	G.to = xzalloc(dest_lsa->len);
 	if (argv[1])
@@ -1117,7 +1123,7 @@ common_traceroute_main(int op, char **argv)
 				memcpy(lastaddr, &G.from_lsa->u.sa, G.from_lsa->len);
 			}
 			print_delta_ms(t1, t2);
-			if (G.from_lsa->u.sa.sa_family == AF_INET) {
+			if (!G_ipv6) {
 				if (op & OPT_TTL_FLAG) {
 					struct ip *ip = (struct ip *)recv_pkt;
 					printf(" (%d)", ip->ip_ttl);


More information about the busybox-cvs mailing list