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 <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2020-12-13 14:58:11 +01:00
parent 8055173128
commit b4b1828076

View File

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