mirror of
https://github.com/sheumann/hush.git
synced 2024-12-22 14:30:31 +00:00
traceroute: cleanup preparing it for traceroute6. -17 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
11f3a8b7ed
commit
0d56568654
@ -211,6 +211,13 @@
|
|||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip_icmp.h>
|
#include <netinet/ip_icmp.h>
|
||||||
|
#if ENABLE_FEATURE_IPV6
|
||||||
|
# include <netinet/ip6.h>
|
||||||
|
# include <netinet/icmp6.h>
|
||||||
|
# ifndef SOL_IPV6
|
||||||
|
# define SOL_IPV6 IPPROTO_IPV6
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include "inet_common.h"
|
#include "inet_common.h"
|
||||||
@ -222,7 +229,9 @@
|
|||||||
# define IPPROTO_IP 0
|
# define IPPROTO_IP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Keep in sync with getopt32 call! */
|
|
||||||
|
#define OPT_STRING "FIlnrdvxt:i:m:p:q:s:w:z:f:" \
|
||||||
|
IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:")
|
||||||
enum {
|
enum {
|
||||||
OPT_DONT_FRAGMNT = (1 << 0), /* F */
|
OPT_DONT_FRAGMNT = (1 << 0), /* F */
|
||||||
OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */
|
OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */
|
||||||
@ -309,15 +318,15 @@ static int
|
|||||||
wait_for_reply(struct sockaddr_in *fromp)
|
wait_for_reply(struct sockaddr_in *fromp)
|
||||||
{
|
{
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
int cc = 0;
|
int read_len = 0;
|
||||||
socklen_t fromlen = sizeof(*fromp);
|
socklen_t fromlen = sizeof(*fromp);
|
||||||
|
|
||||||
pfd[0].fd = rcvsock;
|
pfd[0].fd = rcvsock;
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
if (safe_poll(pfd, 1, waittime * 1000) > 0)
|
if (safe_poll(pfd, 1, waittime * 1000) > 0)
|
||||||
cc = recvfrom(rcvsock, recv_pkt, sizeof(recv_pkt), 0,
|
read_len = recvfrom(rcvsock, recv_pkt, sizeof(recv_pkt), 0,
|
||||||
(struct sockaddr *)fromp, &fromlen);
|
(struct sockaddr *)fromp, &fromlen);
|
||||||
return cc;
|
return read_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -417,8 +426,7 @@ send_probe(int seq, int ttl)
|
|||||||
len -= sizeof(*outudp);
|
len -= sizeof(*outudp);
|
||||||
set_nport(dest_lsa, htons(port + seq));
|
set_nport(dest_lsa, htons(port + seq));
|
||||||
}
|
}
|
||||||
res = xsendto(sndsock, out, len,
|
res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len);
|
||||||
(struct sockaddr *)&dest_lsa->u.sa, dest_lsa->len);
|
|
||||||
if (res != len) {
|
if (res != len) {
|
||||||
bb_info_msg("sent %d octets, ret=%d", len, res);
|
bb_info_msg("sent %d octets, ret=%d", len, res);
|
||||||
}
|
}
|
||||||
@ -447,11 +455,11 @@ pr_type(unsigned char t)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !ENABLE_FEATURE_TRACEROUTE_VERBOSE
|
#if !ENABLE_FEATURE_TRACEROUTE_VERBOSE
|
||||||
#define packet_ok(cc, from, seq) \
|
#define packet_ok(read_len, from, seq) \
|
||||||
packet_ok(cc, seq)
|
packet_ok(read_len, seq)
|
||||||
#endif
|
#endif
|
||||||
static int
|
static int
|
||||||
packet_ok(int cc, const struct sockaddr_in *from, int seq)
|
packet_ok(int read_len, const struct sockaddr_in *from, int seq)
|
||||||
{
|
{
|
||||||
const struct icmp *icp;
|
const struct icmp *icp;
|
||||||
unsigned char type, code;
|
unsigned char type, code;
|
||||||
@ -460,15 +468,15 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq)
|
|||||||
|
|
||||||
ip = (struct ip *) recv_pkt;
|
ip = (struct ip *) recv_pkt;
|
||||||
hlen = ip->ip_hl << 2;
|
hlen = ip->ip_hl << 2;
|
||||||
if (cc < hlen + ICMP_MINLEN) {
|
if (read_len < hlen + ICMP_MINLEN) {
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_VERBOSE
|
#if ENABLE_FEATURE_TRACEROUTE_VERBOSE
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("packet too short (%d bytes) from %s\n", cc,
|
printf("packet too short (%d bytes) from %s\n", read_len,
|
||||||
inet_ntoa(from->sin_addr));
|
inet_ntoa(from->sin_addr));
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cc -= hlen;
|
read_len -= hlen;
|
||||||
icp = (struct icmp *)(recv_pkt + hlen);
|
icp = (struct icmp *)(recv_pkt + hlen);
|
||||||
type = icp->icmp_type;
|
type = icp->icmp_type;
|
||||||
code = icp->icmp_code;
|
code = icp->icmp_code;
|
||||||
@ -498,7 +506,7 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hicmp = (struct icmp *)((unsigned char *)hip + hlen);
|
hicmp = (struct icmp *)((unsigned char *)hip + hlen);
|
||||||
if (hlen + SIZEOF_ICMP_HDR <= cc
|
if (hlen + SIZEOF_ICMP_HDR <= read_len
|
||||||
&& hip->ip_p == IPPROTO_ICMP
|
&& hip->ip_p == IPPROTO_ICMP
|
||||||
&& hicmp->icmp_id == htons(ident)
|
&& hicmp->icmp_id == htons(ident)
|
||||||
&& hicmp->icmp_seq == htons(seq)
|
&& hicmp->icmp_seq == htons(seq)
|
||||||
@ -507,7 +515,7 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
up = (struct udphdr *)((char *)hip + hlen);
|
up = (struct udphdr *)((char *)hip + hlen);
|
||||||
if (hlen + 12 <= cc
|
if (hlen + 12 <= read_len
|
||||||
&& hip->ip_p == IPPROTO_UDP
|
&& hip->ip_p == IPPROTO_UDP
|
||||||
// Off: since we do not form the entire IP packet,
|
// Off: since we do not form the entire IP packet,
|
||||||
// but defer it to kernel, we can't set source port,
|
// but defer it to kernel, we can't set source port,
|
||||||
@ -526,10 +534,10 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq)
|
|||||||
|
|
||||||
printf("\n%d bytes from %s to "
|
printf("\n%d bytes from %s to "
|
||||||
"%s: icmp type %d (%s) code %d\n",
|
"%s: icmp type %d (%s) code %d\n",
|
||||||
cc, inet_ntoa(from->sin_addr),
|
read_len, inet_ntoa(from->sin_addr),
|
||||||
inet_ntoa(ip->ip_dst),
|
inet_ntoa(ip->ip_dst),
|
||||||
type, pr_type(type), icp->icmp_code);
|
type, pr_type(type), icp->icmp_code);
|
||||||
for (i = 4; i < cc; i += sizeof(*lp))
|
for (i = 4; i < read_len; i += sizeof(*lp))
|
||||||
printf("%2d: x%8.8x\n", i, *lp++);
|
printf("%2d: x%8.8x\n", i, *lp++);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -542,34 +550,39 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq)
|
|||||||
* numeric value, otherwise try for symbolic name.
|
* numeric value, otherwise try for symbolic name.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_inetname(const struct sockaddr_in *from)
|
print_inetname(const struct sockaddr *from)
|
||||||
{
|
{
|
||||||
const char *ina;
|
char *ina = xmalloc_sockaddr2dotted_noport(from);
|
||||||
|
|
||||||
ina = inet_ntoa(from->sin_addr);
|
if (option_mask32 & OPT_ADDR_NUM) {
|
||||||
if (option_mask32 & OPT_ADDR_NUM)
|
|
||||||
printf(" %s", ina);
|
printf(" %s", ina);
|
||||||
else {
|
} else {
|
||||||
char *n = NULL;
|
char *n = NULL;
|
||||||
if (from->sin_addr.s_addr != INADDR_ANY)
|
|
||||||
|
if (from->sa_family != AF_INET
|
||||||
|
|| ((struct sockaddr_in*)from)->sin_addr.s_addr != INADDR_ANY
|
||||||
|
) {
|
||||||
|
/* Try to reverse resolve if it is not 0.0.0.0 */
|
||||||
n = xmalloc_sockaddr2host_noport((struct sockaddr*)from);
|
n = xmalloc_sockaddr2host_noport((struct sockaddr*)from);
|
||||||
|
}
|
||||||
printf(" %s (%s)", (n ? n : ina), ina);
|
printf(" %s (%s)", (n ? n : ina), ina);
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
|
free(ina);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print(int cc, const struct sockaddr_in *from)
|
print(int read_len, const struct sockaddr_in *from)
|
||||||
{
|
{
|
||||||
print_inetname(from);
|
print_inetname((const struct sockaddr*)from);
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
const struct ip *ip;
|
const struct ip *ip;
|
||||||
int hlen;
|
int hlen;
|
||||||
|
|
||||||
ip = (struct ip *) recv_pkt;
|
ip = (struct ip *) recv_pkt;
|
||||||
hlen = ip->ip_hl << 2;
|
hlen = ip->ip_hl << 2;
|
||||||
cc -= hlen;
|
read_len -= hlen;
|
||||||
printf(" %d bytes to %s", cc, inet_ntoa(ip->ip_dst));
|
printf(" %d bytes to %s", read_len, inet_ntoa(ip->ip_dst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,17 +594,16 @@ print_delta_ms(unsigned t1p, unsigned t2p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]
|
* Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]
|
||||||
[-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]
|
* [-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]
|
||||||
[-w waittime] [-z pausemsecs] host [packetlen]"
|
* [-w waittime] [-z pausemsecs] host [packetlen]"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int traceroute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int traceroute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int traceroute_main(int argc, char **argv)
|
int traceroute_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
int minpacket;
|
int minpacket;
|
||||||
int ttl, i;
|
|
||||||
int seq = 0;
|
|
||||||
int tos = 0;
|
int tos = 0;
|
||||||
int max_ttl = 30;
|
int max_ttl = 30;
|
||||||
int nprobes = 3;
|
int nprobes = 3;
|
||||||
@ -611,19 +623,14 @@ int traceroute_main(int argc, char **argv)
|
|||||||
llist_t *source_route_list = NULL;
|
llist_t *source_route_list = NULL;
|
||||||
int lsrr = 0;
|
int lsrr = 0;
|
||||||
#endif
|
#endif
|
||||||
|
int ttl;
|
||||||
|
int seq;
|
||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
/* minimum 1 arg */
|
||||||
opt_complementary = "x-x:g::";
|
opt_complementary = "-1:x-x" IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(":g::");
|
||||||
#else
|
op = getopt32(argv, OPT_STRING
|
||||||
opt_complementary = "x-x";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
op = getopt32(argv, "FIlnrdvxt:i:m:p:q:s:w:z:f:"
|
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
|
||||||
"g:"
|
|
||||||
#endif
|
|
||||||
, &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
|
, &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
|
||||||
, &source, &waittime_str, &pausemsecs_str, &first_ttl_str
|
, &source, &waittime_str, &pausemsecs_str, &first_ttl_str
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
||||||
@ -681,17 +688,9 @@ int traceroute_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Process destination and optional packet size */
|
/* Process destination and optional packet size */
|
||||||
argv += optind;
|
argv += optind;
|
||||||
argc -= optind;
|
if (argv[1])
|
||||||
switch (argc) {
|
|
||||||
case 2:
|
|
||||||
packlen = xatoul_range(argv[1], minpacket, 32 * 1024);
|
packlen = xatoul_range(argv[1], minpacket, 32 * 1024);
|
||||||
/* Fall through */
|
dest_lsa = xhost2sockaddr(argv[0], port);
|
||||||
case 1:
|
|
||||||
dest_lsa = xhost2sockaddr(argv[0], port);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bb_show_usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the socket fds won't be 0, 1 or 2 */
|
/* Ensure the socket fds won't be 0, 1 or 2 */
|
||||||
bb_sanitize_stdio();
|
bb_sanitize_stdio();
|
||||||
@ -710,8 +709,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock);
|
xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock);
|
||||||
else
|
else
|
||||||
xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock);
|
xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock);
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS
|
||||||
#if defined(IP_OPTIONS)
|
|
||||||
if (lsrr > 0) {
|
if (lsrr > 0) {
|
||||||
unsigned char optlist[MAX_IPOPTLEN];
|
unsigned char optlist[MAX_IPOPTLEN];
|
||||||
|
|
||||||
@ -734,8 +732,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
bb_perror_msg_and_die("IP_OPTIONS");
|
bb_perror_msg_and_die("IP_OPTIONS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* IP_OPTIONS */
|
#endif
|
||||||
#endif /* CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE */
|
|
||||||
#ifdef SO_SNDBUF
|
#ifdef SO_SNDBUF
|
||||||
if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) {
|
if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) {
|
||||||
bb_perror_msg_and_die("SO_SNDBUF");
|
bb_perror_msg_and_die("SO_SNDBUF");
|
||||||
@ -796,6 +793,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
printf(" from %s", source);
|
printf(" from %s", source);
|
||||||
printf(", %d hops max, %d byte packets\n", max_ttl, packlen);
|
printf(", %d hops max, %d byte packets\n", max_ttl, packlen);
|
||||||
|
|
||||||
|
seq = 0;
|
||||||
for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
|
for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
|
||||||
//TODO: make it protocol agnostic (get rid of sockaddr_in)
|
//TODO: make it protocol agnostic (get rid of sockaddr_in)
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
@ -808,7 +806,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
|
|
||||||
printf("%2d", ttl);
|
printf("%2d", ttl);
|
||||||
for (probe = 0; probe < nprobes; ++probe) {
|
for (probe = 0; probe < nprobes; ++probe) {
|
||||||
int cc;
|
int read_len;
|
||||||
unsigned t1;
|
unsigned t1;
|
||||||
unsigned t2;
|
unsigned t2;
|
||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
@ -819,18 +817,18 @@ int traceroute_main(int argc, char **argv)
|
|||||||
|
|
||||||
t1 = monotonic_us();
|
t1 = monotonic_us();
|
||||||
send_probe(++seq, ttl);
|
send_probe(++seq, ttl);
|
||||||
first = 0;
|
|
||||||
|
|
||||||
while ((cc = wait_for_reply(&from)) != 0) {
|
first = 0;
|
||||||
|
while ((read_len = wait_for_reply(&from)) != 0) {
|
||||||
t2 = monotonic_us();
|
t2 = monotonic_us();
|
||||||
i = packet_ok(cc, &from, seq);
|
i = packet_ok(read_len, &from, seq);
|
||||||
/* Skip short packet */
|
/* Skip short packet */
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
continue;
|
continue;
|
||||||
if (!gotlastaddr
|
if (!gotlastaddr
|
||||||
|| from.sin_addr.s_addr != lastaddr
|
|| from.sin_addr.s_addr != lastaddr
|
||||||
) {
|
) {
|
||||||
print(cc, &from);
|
print(read_len, &from);
|
||||||
lastaddr = from.sin_addr.s_addr;
|
lastaddr = from.sin_addr.s_addr;
|
||||||
gotlastaddr = 1;
|
gotlastaddr = 1;
|
||||||
}
|
}
|
||||||
@ -912,7 +910,8 @@ int traceroute_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cc == 0)
|
/* there was no packet at all? */
|
||||||
|
if (read_len == 0)
|
||||||
printf(" *");
|
printf(" *");
|
||||||
}
|
}
|
||||||
bb_putchar('\n');
|
bb_putchar('\n');
|
||||||
@ -922,5 +921,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user