From b4b182807687a872c49a89b840754a553c00f8a1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 13 Dec 2020 14:58:11 +0100 Subject: traceroute: make "ipv4 or ipv6?" cheaper to find out 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 --- 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); -- cgit v1.2.3