traceroute: cleanup and fixes for packet size calculations

Remove FEATURE_TRACEROUTE_SOURCE_ROUTE: it's off by default, and
source routing is not used in real world.

Tested that "traceroute -n ::1 100" and "traceroute -n 127.0.0.1 100"
both send 100 byte IP packets (this matches what traceroute on Fedora
Rawhide is doing).

function                                             old     new   delta
common_traceroute_main                              3731    3738      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2016-09-28 18:39:06 +02:00
parent 61fcc8c781
commit 1c32e49bdf
11 changed files with 40 additions and 105 deletions

View File

@ -760,7 +760,6 @@ CONFIG_TFTP_DEBUG=y
CONFIG_TRACEROUTE=y
CONFIG_TRACEROUTE6=y
CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
CONFIG_UDHCPD=y
CONFIG_DHCPRELAY=y

View File

@ -762,7 +762,6 @@ CONFIG_IFUPDOWN_IFSTATE_PATH=""
# CONFIG_TRACEROUTE is not set
# CONFIG_TRACEROUTE6 is not set
# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
# CONFIG_TUNCTL is not set
# CONFIG_FEATURE_TUNCTL_UG is not set

View File

@ -778,7 +778,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
CONFIG_TRACEROUTE=y
CONFIG_TRACEROUTE6=y
CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
CONFIG_TUNCTL=y
CONFIG_FEATURE_TUNCTL_UG=y

View File

@ -814,7 +814,6 @@ CONFIG_TCPSVD=y
# CONFIG_TRACEROUTE is not set
# CONFIG_TRACEROUTE6 is not set
# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
CONFIG_TUNCTL=y
CONFIG_FEATURE_TUNCTL_UG=y

View File

@ -959,7 +959,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
CONFIG_TRACEROUTE=y
CONFIG_TRACEROUTE6=y
CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
CONFIG_TUNCTL=y
CONFIG_FEATURE_TUNCTL_UG=y

View File

@ -843,7 +843,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
CONFIG_TRACEROUTE=y
# CONFIG_TRACEROUTE6 is not set
CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
CONFIG_TUNCTL=y
CONFIG_FEATURE_TUNCTL_UG=y

View File

@ -869,7 +869,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
CONFIG_TRACEROUTE=y
# CONFIG_TRACEROUTE6 is not set
CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
CONFIG_TUNCTL=y
CONFIG_FEATURE_TUNCTL_UG=y

View File

@ -814,7 +814,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
# CONFIG_TRACEROUTE is not set
# CONFIG_TRACEROUTE6 is not set
# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
# CONFIG_TUNCTL is not set
# CONFIG_FEATURE_TUNCTL_UG is not set

View File

@ -795,7 +795,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
# CONFIG_TRACEROUTE is not set
# CONFIG_TRACEROUTE6 is not set
# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
# CONFIG_TUNCTL is not set
# CONFIG_FEATURE_TUNCTL_UG is not set

View File

@ -912,17 +912,9 @@ config FEATURE_TRACEROUTE_VERBOSE
Add some verbosity to traceroute. This includes among other things
hostnames and ICMP response types.
config FEATURE_TRACEROUTE_SOURCE_ROUTE
bool "Enable loose source route"
default n
depends on TRACEROUTE
help
Add option to specify a loose source route gateway
(8 maximum).
config FEATURE_TRACEROUTE_USE_ICMP
bool "Use ICMP instead of UDP"
default n
bool "Enable -I option (use ICMP instead of UDP)"
default y
depends on TRACEROUTE
help
Add option -I to use ICMP ECHO instead of UDP datagrams.

View File

@ -212,8 +212,7 @@
//usage:#define traceroute_trivial_usage
//usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n"
//usage: " [-t TOS] [-w WAIT_SEC]"
//usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n"
//usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n"
//usage: " [-z PAUSE_MSEC] HOST [BYTES]"
//usage:#define traceroute_full_usage "\n\n"
//usage: "Trace the route to HOST\n"
@ -294,7 +293,6 @@
#define OPT_STRING \
"FIlnrdvxt:i:m:p:q:s:w:z:f:" \
IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \
"4" IF_TRACEROUTE6("6")
enum {
OPT_DONT_FRAGMNT = (1 << 0), /* F */
@ -314,9 +312,8 @@ enum {
OPT_WAITTIME = (1 << 14), /* w */
OPT_PAUSE_MS = (1 << 15), /* z */
OPT_FIRST_TTL = (1 << 16), /* f */
OPT_SOURCE_ROUTE = (1 << 17) * ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE, /* g */
OPT_IPV4 = (1 << (17+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)), /* 4 */
OPT_IPV6 = (1 << (18+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)) * ENABLE_TRACEROUTE6, /* 6 */
OPT_IPV4 = (1 << 17), /* 4 */
OPT_IPV6 = (1 << 18) * ENABLE_TRACEROUTE6, /* 6 */
};
#define verbose (option_mask32 & OPT_VERBOSE)
@ -343,26 +340,18 @@ struct outdata6_t {
#endif
struct globals {
/* Pointer to entire malloced IP packet, "packlen" bytes long: */
struct ip *outip;
/* Pointer to ICMP or UDP payload (not header): */
struct outdata_t *outdata;
len_and_sockaddr *dest_lsa;
int packlen; /* total length of packet */
int pmtu; /* Path MTU Discovery (RFC1191) */
uint32_t ident;
uint16_t port; // 32768 + 666; /* start udp dest port # for probe packets */
uint16_t port; // 33434; /* start udp dest port # for probe packets */
int waittime; // 5; /* time to wait for response (in seconds) */
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
int optlen; /* length of ip options */
#else
#define optlen 0
#endif
unsigned char recv_pkt[512]; /* last inbound (icmp) packet */
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
/* Maximum number of gateways (include room for one noop) */
#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(uint32_t)))
/* loose source route gateway list (including room for final destination) */
uint32_t gwlist[NGATEWAYS + 1];
#endif
};
#define G (*ptr_to_globals)
@ -374,14 +363,11 @@ struct globals {
#define ident (G.ident )
#define port (G.port )
#define waittime (G.waittime )
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
# define optlen (G.optlen )
#endif
#define recv_pkt (G.recv_pkt )
#define gwlist (G.gwlist )
#define INIT_G() do { \
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
port = 32768 + 666; \
port = 33434; \
waittime = 5; \
} while (0)
@ -421,7 +407,7 @@ send_probe(int seq, int ttl)
/* Payload */
#if ENABLE_TRACEROUTE6
if (dest_lsa->u.sa.sa_family == AF_INET6) {
struct outdata6_t *pkt = (struct outdata6_t *) outip;
struct outdata6_t *pkt = (struct outdata6_t *) outdata;
pkt->ident6 = htonl(ident);
pkt->seq6 = htonl(seq);
/*gettimeofday(&pkt->tv, &tz);*/
@ -438,8 +424,10 @@ send_probe(int seq, int ttl)
/* Always calculate checksum for icmp packets */
outicmp->icmp_cksum = 0;
outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp,
packlen - (sizeof(*outip) + optlen));
outicmp->icmp_cksum = inet_cksum(
(uint16_t *)outicmp,
((char*)outip + packlen) - (char*)outicmp
);
if (outicmp->icmp_cksum == 0)
outicmp->icmp_cksum = 0xffff;
}
@ -471,13 +459,12 @@ send_probe(int seq, int ttl)
}
#endif
out = outdata;
#if ENABLE_TRACEROUTE6
if (dest_lsa->u.sa.sa_family == AF_INET6) {
res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl);
if (res != 0)
bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl);
out = outip;
len = packlen;
} else
#endif
{
@ -486,15 +473,14 @@ send_probe(int seq, int ttl)
if (res != 0)
bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl);
#endif
if (option_mask32 & OPT_USE_ICMP)
out = outicmp;
len = packlen - sizeof(*outip);
if (!(option_mask32 & OPT_USE_ICMP)) {
out = outdata;
len -= sizeof(*outudp);
set_nport(&dest_lsa->u.sa, htons(port + seq));
}
}
if (!(option_mask32 & OPT_USE_ICMP)) {
set_nport(&dest_lsa->u.sa, htons(port + seq));
}
len = ((char*)outip + packlen) - (char*)out;
res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len);
if (res != len)
bb_error_msg("sent %d octets, ret=%d", len, res);
@ -801,10 +787,6 @@ common_traceroute_main(int op, char **argv)
char *pausemsecs_str;
char *first_ttl_str;
char *dest_str;
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
llist_t *source_route_list = NULL;
int lsrr = 0;
#endif
#if ENABLE_TRACEROUTE6
sa_family_t af;
#else
@ -823,9 +805,6 @@ common_traceroute_main(int op, char **argv)
op |= getopt32(argv, OPT_STRING
, &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
, &source, &waittime_str, &pausemsecs_str, &first_ttl_str
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
, &source_route_list
#endif
);
argv += optind;
@ -858,26 +837,14 @@ common_traceroute_main(int op, char **argv)
if (op & OPT_FIRST_TTL)
first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
if (source_route_list) {
while (source_route_list) {
len_and_sockaddr *lsa;
if (lsrr >= NGATEWAYS)
bb_error_msg_and_die("no more than %d gateways", NGATEWAYS);
lsa = xhost_and_af2sockaddr(llist_pop(&source_route_list), 0, AF_INET);
gwlist[lsrr] = lsa->u.sin.sin_addr.s_addr;
free(lsa);
++lsrr;
}
optlen = (lsrr + 1) * sizeof(gwlist[0]);
}
#endif
/* Process destination and optional packet size */
minpacket = sizeof(*outip) + SIZEOF_ICMP_HDR + sizeof(*outdata) + optlen;
minpacket = sizeof(struct ip)
+ SIZEOF_ICMP_HDR
+ sizeof(struct outdata_t);
if (!(op & OPT_USE_ICMP))
minpacket += sizeof(*outudp) - SIZEOF_ICMP_HDR;
minpacket = sizeof(struct ip)
+ sizeof(struct udphdr)
+ sizeof(struct outdata_t);
#if ENABLE_TRACEROUTE6
af = AF_UNSPEC;
if (op & OPT_IPV4)
@ -887,7 +854,9 @@ common_traceroute_main(int op, char **argv)
dest_lsa = xhost_and_af2sockaddr(argv[0], port, af);
af = dest_lsa->u.sa.sa_family;
if (af == AF_INET6)
minpacket = sizeof(struct outdata6_t);
minpacket = sizeof(struct ip6_hdr)
+ sizeof(struct udphdr)
+ sizeof(struct outdata6_t);
#else
dest_lsa = xhost2sockaddr(argv[0], port);
#endif
@ -932,31 +901,6 @@ common_traceroute_main(int op, char **argv)
xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock);
else
xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock);
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS
if (lsrr > 0) {
unsigned char optlist[MAX_IPOPTLEN];
unsigned size;
/* final hop */
gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr;
++lsrr;
/* force 4 byte alignment */
optlist[0] = IPOPT_NOP;
/* loose source route option */
optlist[1] = IPOPT_LSRR;
size = lsrr * sizeof(gwlist[0]);
optlist[2] = size + 3;
/* pointer to LSRR addresses */
optlist[3] = IPOPT_MINOFF;
memcpy(optlist + 4, gwlist, size);
if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
(char *)optlist, size + sizeof(gwlist[0])) < 0) {
bb_perror_msg_and_die("IP_OPTIONS");
}
}
#endif
}
#ifdef SO_SNDBUF
@ -984,7 +928,7 @@ common_traceroute_main(int op, char **argv)
ident = getpid();
if (af == AF_INET) {
if (!ENABLE_TRACEROUTE6 || af == AF_INET) {
if (op & OPT_USE_ICMP) {
ident |= 0x8000;
outicmp->icmp_type = ICMP_ECHO;
@ -994,6 +938,14 @@ common_traceroute_main(int op, char **argv)
outdata = (struct outdata_t *)(outudp + 1);
}
}
#if ENABLE_TRACEROUTE6
if (af == AF_INET6) {
outdata = (void*)((char*)outip
+ sizeof(struct ip6_hdr)
+ sizeof(struct udphdr)
);
}
#endif
if (op & OPT_DEVICE) /* hmm, do we need error check? */
setsockopt_bindtodevice(sndsock, device);