traceroute: preparatory trivial cleanups
function old new delta traceroute_main 3932 3713 -219
This commit is contained in:
parent
39b681343b
commit
fa65a3d78f
@ -440,7 +440,7 @@ void FAST_FUNC xlisten(int s, int backlog)
|
|||||||
|
|
||||||
/* Die with an error message if sendto failed.
|
/* Die with an error message if sendto failed.
|
||||||
* Return bytes sent otherwise */
|
* Return bytes sent otherwise */
|
||||||
ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
|
ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
|
||||||
socklen_t tolen)
|
socklen_t tolen)
|
||||||
{
|
{
|
||||||
ssize_t ret = sendto(s, buf, len, 0, to, tolen);
|
ssize_t ret = sendto(s, buf, len, 0, to, tolen);
|
||||||
|
@ -223,11 +223,10 @@
|
|||||||
#define IPVERSION 4
|
#define IPVERSION 4
|
||||||
|
|
||||||
#ifndef IPPROTO_ICMP
|
#ifndef IPPROTO_ICMP
|
||||||
/* Grrrr.... */
|
# define IPPROTO_ICMP 1
|
||||||
#define IPPROTO_ICMP 1
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef IPPROTO_IP
|
#ifndef IPPROTO_IP
|
||||||
#define IPPROTO_IP 0
|
# define IPPROTO_IP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -482,7 +481,6 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
|
|||||||
return nipaddr;
|
return nipaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setsin(struct sockaddr_in *addr_sin, uint32_t addr)
|
setsin(struct sockaddr_in *addr_sin, uint32_t addr)
|
||||||
{
|
{
|
||||||
@ -494,7 +492,6 @@ setsin(struct sockaddr_in *addr_sin, uint32_t addr)
|
|||||||
addr_sin->sin_addr.s_addr = addr;
|
addr_sin->sin_addr.s_addr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the source address for the given destination address
|
* Return the source address for the given destination address
|
||||||
*/
|
*/
|
||||||
@ -547,13 +544,6 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
|
|||||||
setsin(from, al->addr);
|
setsin(from, al->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
"Usage: %s [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]\n"
|
|
||||||
"\t[-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]\n"
|
|
||||||
"\t[-w waittime] [-z pausemsecs] host [packetlen]"
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wait_for_reply(int sock, struct sockaddr_in *fromp)
|
wait_for_reply(int sock, struct sockaddr_in *fromp)
|
||||||
{
|
{
|
||||||
@ -581,12 +571,12 @@ in_cksum(uint16_t *addr, int len)
|
|||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our algorithm is simple, using a 32 bit accumulator (sum),
|
* Our algorithm is simple, using a 32 bit accumulator (sum),
|
||||||
* we add sequential 16 bit words to it, and at the end, fold
|
* we add sequential 16 bit words to it, and at the end, fold
|
||||||
* back all the carry bits from the top 16 bits into the lower
|
* back all the carry bits from the top 16 bits into the lower
|
||||||
* 16 bits.
|
* 16 bits.
|
||||||
*/
|
*/
|
||||||
while (nleft > 1) {
|
while (nleft > 1) {
|
||||||
sum += *w++;
|
sum += *w++;
|
||||||
nleft -= 2;
|
nleft -= 2;
|
||||||
}
|
}
|
||||||
@ -595,16 +585,13 @@ in_cksum(uint16_t *addr, int len)
|
|||||||
if (nleft == 1)
|
if (nleft == 1)
|
||||||
sum += *(unsigned char *)w;
|
sum += *(unsigned char *)w;
|
||||||
|
|
||||||
/*
|
/* add back carry outs from top 16 bits to low 16 bits */
|
||||||
* add back carry outs from top 16 bits to low 16 bits
|
|
||||||
*/
|
|
||||||
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
|
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
|
||||||
sum += (sum >> 16); /* add carry */
|
sum += (sum >> 16); /* add carry */
|
||||||
answer = ~sum; /* truncate to 16 bits */
|
answer = ~sum; /* truncate to 16 bits */
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_probe(int seq, int ttl)
|
send_probe(int seq, int ttl)
|
||||||
{
|
{
|
||||||
@ -617,12 +604,10 @@ send_probe(int seq, int ttl)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* In most cases, the kernel will recalculate the ip checksum.
|
* In most cases, the kernel will recalculate the ip checksum.
|
||||||
* But we must do it anyway so that the udp checksum comes out
|
* But we must do it anyway so that the udp checksum comes out right.
|
||||||
* right.
|
|
||||||
*/
|
*/
|
||||||
if (doipcksum) {
|
if (doipcksum) {
|
||||||
outip->ip_sum =
|
outip->ip_sum = in_cksum((uint16_t *)outip, sizeof(*outip) + optlen);
|
||||||
in_cksum((uint16_t *)outip, sizeof(*outip) + optlen);
|
|
||||||
if (outip->ip_sum == 0)
|
if (outip->ip_sum == 0)
|
||||||
outip->ip_sum = 0xffff;
|
outip->ip_sum = 0xffff;
|
||||||
}
|
}
|
||||||
@ -645,7 +630,7 @@ send_probe(int seq, int ttl)
|
|||||||
/* Always calculate checksum for icmp packets */
|
/* Always calculate checksum for icmp packets */
|
||||||
outicmp->icmp_cksum = 0;
|
outicmp->icmp_cksum = 0;
|
||||||
outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp,
|
outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp,
|
||||||
packlen - (sizeof(*outip) + optlen));
|
packlen - (sizeof(*outip) + optlen));
|
||||||
if (outicmp->icmp_cksum == 0)
|
if (outicmp->icmp_cksum == 0)
|
||||||
outicmp->icmp_cksum = 0xffff;
|
outicmp->icmp_cksum = 0xffff;
|
||||||
} else
|
} else
|
||||||
@ -656,7 +641,7 @@ send_probe(int seq, int ttl)
|
|||||||
ui = (struct udpiphdr *)outip;
|
ui = (struct udpiphdr *)outip;
|
||||||
oui = (struct udpiphdr *)&tip;
|
oui = (struct udpiphdr *)&tip;
|
||||||
/* Easier to zero and put back things that are ok */
|
/* Easier to zero and put back things that are ok */
|
||||||
memset((char *)ui, 0, sizeof(ui->ui_i));
|
memset(ui, 0, sizeof(ui->ui_i));
|
||||||
ui->ui_src = oui->ui_src;
|
ui->ui_src = oui->ui_src;
|
||||||
ui->ui_dst = oui->ui_dst;
|
ui->ui_dst = oui->ui_dst;
|
||||||
ui->ui_pr = oui->ui_pr;
|
ui->ui_pr = oui->ui_pr;
|
||||||
@ -668,7 +653,8 @@ send_probe(int seq, int ttl)
|
|||||||
*outip = tip;
|
*outip = tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_VERBOSE
|
//BUG! verbose is (x & OPT_VERBOSE), not a counter!
|
||||||
|
#if 0 //ENABLE_FEATURE_TRACEROUTE_VERBOSE
|
||||||
/* XXX undocumented debugging hack */
|
/* XXX undocumented debugging hack */
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
const uint16_t *sp;
|
const uint16_t *sp;
|
||||||
@ -695,15 +681,15 @@ send_probe(int seq, int ttl)
|
|||||||
|
|
||||||
#if !defined(IP_HDRINCL) && defined(IP_TTL)
|
#if !defined(IP_HDRINCL) && defined(IP_TTL)
|
||||||
if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
|
if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
|
||||||
(char *)&ttl, sizeof(ttl)) < 0) {
|
(char *)&ttl, sizeof(ttl)) < 0) {
|
||||||
bb_perror_msg_and_die("setsockopt ttl %d", ttl);
|
bb_perror_msg_and_die("setsockopt ttl %d", ttl);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cc = xsendto(sndsock, (char *)outip,
|
cc = xsendto(sndsock, outip, packlen,
|
||||||
packlen, (struct sockaddr *)&whereto, sizeof(whereto));
|
(struct sockaddr *)&whereto, sizeof(whereto));
|
||||||
if (cc != packlen) {
|
if (cc != packlen) {
|
||||||
bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc);
|
bb_info_msg("sent %s %d octets, ret=%d", hostname, packlen, cc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,7 +708,7 @@ pr_type(unsigned char t)
|
|||||||
"Info Reply", "Mask Request", "Mask Reply"
|
"Info Reply", "Mask Request", "Mask Reply"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (t > 18)
|
if (t >= ARRAY_SIZE(ttab))
|
||||||
return "OUT-OF-RANGE";
|
return "OUT-OF-RANGE";
|
||||||
|
|
||||||
return ttab[t];
|
return ttab[t];
|
||||||
@ -734,12 +720,12 @@ pr_type(unsigned char t)
|
|||||||
packet_ok(buf, cc, seq)
|
packet_ok(buf, cc, seq)
|
||||||
#endif
|
#endif
|
||||||
static int
|
static int
|
||||||
packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
|
packet_ok(const unsigned char *buf, int cc, const struct sockaddr_in *from, int seq)
|
||||||
{
|
{
|
||||||
struct icmp *icp;
|
const struct icmp *icp;
|
||||||
unsigned char type, code;
|
unsigned char type, code;
|
||||||
int hlen;
|
int hlen;
|
||||||
struct ip *ip;
|
const struct ip *ip;
|
||||||
|
|
||||||
ip = (struct ip *) buf;
|
ip = (struct ip *) buf;
|
||||||
hlen = ip->ip_hl << 2;
|
hlen = ip->ip_hl << 2;
|
||||||
@ -756,15 +742,16 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
|
|||||||
type = icp->icmp_type;
|
type = icp->icmp_type;
|
||||||
code = icp->icmp_code;
|
code = icp->icmp_code;
|
||||||
/* Path MTU Discovery (RFC1191) */
|
/* Path MTU Discovery (RFC1191) */
|
||||||
if (code != ICMP_UNREACH_NEEDFRAG)
|
pmtu = 0;
|
||||||
pmtu = 0;
|
if (code == ICMP_UNREACH_NEEDFRAG)
|
||||||
else {
|
|
||||||
pmtu = ntohs(icp->icmp_nextmtu);
|
pmtu = ntohs(icp->icmp_nextmtu);
|
||||||
}
|
|
||||||
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
|
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS)
|
||||||
type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
|
|| type == ICMP_UNREACH
|
||||||
struct ip *hip;
|
|| type == ICMP_ECHOREPLY
|
||||||
struct udphdr *up;
|
) {
|
||||||
|
const struct ip *hip;
|
||||||
|
const struct udphdr *up;
|
||||||
|
|
||||||
hip = &icp->icmp_ip;
|
hip = &icp->icmp_ip;
|
||||||
hlen = hip->ip_hl << 2;
|
hlen = hip->ip_hl << 2;
|
||||||
@ -804,8 +791,9 @@ packet_ok(unsigned char *buf, int cc, 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),
|
cc, inet_ntoa(from->sin_addr),
|
||||||
inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
|
inet_ntoa(ip->ip_dst),
|
||||||
|
type, pr_type(type), icp->icmp_code);
|
||||||
for (i = 4; i < cc; i += sizeof(*lp))
|
for (i = 4; i < cc; i += sizeof(*lp))
|
||||||
printf("%2d: x%8.8x\n", i, *lp++);
|
printf("%2d: x%8.8x\n", i, *lp++);
|
||||||
}
|
}
|
||||||
@ -813,14 +801,13 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct an Internet address representation.
|
* Construct an Internet address representation.
|
||||||
* If the nflag has been supplied, give
|
* If the -n flag has been supplied, give
|
||||||
* numeric value, otherwise try for symbolic name.
|
* numeric value, otherwise try for symbolic name.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_inetname(struct sockaddr_in *from)
|
print_inetname(const struct sockaddr_in *from)
|
||||||
{
|
{
|
||||||
const char *ina;
|
const char *ina;
|
||||||
|
|
||||||
@ -837,9 +824,9 @@ print_inetname(struct sockaddr_in *from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print(unsigned char *buf, int cc, struct sockaddr_in *from)
|
print(const unsigned char *buf, int cc, const struct sockaddr_in *from)
|
||||||
{
|
{
|
||||||
struct ip *ip;
|
const struct ip *ip;
|
||||||
int hlen;
|
int hlen;
|
||||||
|
|
||||||
ip = (struct ip *) buf;
|
ip = (struct ip *) buf;
|
||||||
@ -853,7 +840,6 @@ print(unsigned char *buf, int cc, struct sockaddr_in *from)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct hostinfo *
|
static struct hostinfo *
|
||||||
gethostinfo(const char *host)
|
gethostinfo(const char *host)
|
||||||
{
|
{
|
||||||
@ -910,15 +896,19 @@ static void
|
|||||||
print_delta_ms(unsigned t1p, unsigned t2p)
|
print_delta_ms(unsigned t1p, unsigned t2p)
|
||||||
{
|
{
|
||||||
unsigned tt = t2p - t1p;
|
unsigned tt = t2p - t1p;
|
||||||
printf(" %u.%03u ms", tt/1000, tt%1000);
|
printf(" %u.%03u ms", tt / 1000, tt % 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
"Usage: %s [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]\n"
|
||||||
|
"\t[-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]\n"
|
||||||
|
"\t[-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, char **argv)
|
||||||
{
|
{
|
||||||
int code, n;
|
|
||||||
unsigned char *outp;
|
unsigned char *outp;
|
||||||
uint32_t *ap;
|
|
||||||
struct sockaddr_in *from;
|
struct sockaddr_in *from;
|
||||||
struct sockaddr_in *to;
|
struct sockaddr_in *to;
|
||||||
struct hostinfo *hi;
|
struct hostinfo *hi;
|
||||||
@ -931,7 +921,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
||||||
int lsrr = 0;
|
int lsrr = 0;
|
||||||
#endif
|
#endif
|
||||||
uint16_t off = 0;
|
|
||||||
struct IFADDRLIST *al;
|
struct IFADDRLIST *al;
|
||||||
char *device;
|
char *device;
|
||||||
int max_ttl = 30;
|
int max_ttl = 30;
|
||||||
@ -952,7 +941,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
from = (struct sockaddr_in *)&wherefrom;
|
from = (struct sockaddr_in *)&wherefrom;
|
||||||
to = (struct sockaddr_in *)&whereto;
|
to = (struct sockaddr_in *)&whereto;
|
||||||
|
|
||||||
//opterr = 0;
|
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
||||||
opt_complementary = "x-x:g::";
|
opt_complementary = "x-x:g::";
|
||||||
#else
|
#else
|
||||||
@ -970,8 +958,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (op & OPT_DONT_FRAGMNT)
|
|
||||||
off = IP_DF;
|
|
||||||
if (op & OPT_IP_CHKSUM) {
|
if (op & OPT_IP_CHKSUM) {
|
||||||
doipcksum = 0;
|
doipcksum = 0;
|
||||||
bb_error_msg("warning: ip checksums disabled");
|
bb_error_msg("warning: ip checksums disabled");
|
||||||
@ -989,15 +975,15 @@ int traceroute_main(int argc, char **argv)
|
|||||||
* set the ip source address of the outbound
|
* set the ip source address of the outbound
|
||||||
* probe (e.g., on a multi-homed host).
|
* probe (e.g., on a multi-homed host).
|
||||||
*/
|
*/
|
||||||
if (getuid())
|
if (getuid() != 0)
|
||||||
bb_error_msg_and_die("-s %s: permission denied", source);
|
bb_error_msg_and_die("you must be root to use -s");
|
||||||
}
|
}
|
||||||
if (op & OPT_WAITTIME)
|
if (op & OPT_WAITTIME)
|
||||||
waittime = xatou_range(waittime_str, 2, 24 * 60 * 60);
|
waittime = xatou_range(waittime_str, 2, 24 * 60 * 60);
|
||||||
if (op & OPT_PAUSE_MS)
|
if (op & OPT_PAUSE_MS)
|
||||||
pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
|
pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
|
||||||
if (op & OPT_FIRST_TTL)
|
if (op & OPT_FIRST_TTL)
|
||||||
first_ttl = xatou_range(first_ttl_str, 1, 255);
|
first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
|
||||||
|
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
|
||||||
if (source_route_list) {
|
if (source_route_list) {
|
||||||
@ -1011,12 +997,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (first_ttl > max_ttl) {
|
|
||||||
bb_error_msg_and_die(
|
|
||||||
"first ttl (%d) may not be greater than max ttl (%d)",
|
|
||||||
first_ttl, max_ttl);
|
|
||||||
}
|
|
||||||
|
|
||||||
minpacket = sizeof(*outip) + sizeof(*outdata) + optlen;
|
minpacket = sizeof(*outip) + sizeof(*outdata) + optlen;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP
|
#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP
|
||||||
@ -1028,14 +1008,14 @@ int traceroute_main(int argc, char **argv)
|
|||||||
packlen = minpacket; /* minimum sized packet */
|
packlen = minpacket; /* minimum sized packet */
|
||||||
|
|
||||||
/* Process destination and optional packet size */
|
/* Process destination and optional packet size */
|
||||||
switch (argc - optind) {
|
argv += optind;
|
||||||
|
argc -= optind;
|
||||||
|
switch (argc) {
|
||||||
case 2:
|
case 2:
|
||||||
packlen = xatoul_range(argv[optind + 1], minpacket, maxpacket);
|
packlen = xatoul_range(argv[1], minpacket, maxpacket);
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
hostname = argv[optind];
|
hostname = argv[0];
|
||||||
hi = gethostinfo(hostname);
|
hi = gethostinfo(hostname);
|
||||||
setsin(to, hi->addrs[0]);
|
setsin(to, hi->addrs[0]);
|
||||||
if (hi->n > 1)
|
if (hi->n > 1)
|
||||||
@ -1045,7 +1025,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
hi->name = NULL;
|
hi->name = NULL;
|
||||||
freehostinfo(hi);
|
freehostinfo(hi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
@ -1081,12 +1060,12 @@ int traceroute_main(int argc, char **argv)
|
|||||||
optlist[1] = IPOPT_LSRR;
|
optlist[1] = IPOPT_LSRR;
|
||||||
i = lsrr * sizeof(gwlist[0]);
|
i = lsrr * sizeof(gwlist[0]);
|
||||||
optlist[2] = i + 3;
|
optlist[2] = i + 3;
|
||||||
/* Pointer to LSRR addresses */
|
/* pointer to LSRR addresses */
|
||||||
optlist[3] = IPOPT_MINOFF;
|
optlist[3] = IPOPT_MINOFF;
|
||||||
memcpy(optlist + 4, gwlist, i);
|
memcpy(optlist + 4, gwlist, i);
|
||||||
|
|
||||||
if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
|
if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
|
||||||
(char *)optlist, i + sizeof(gwlist[0]))) < 0) {
|
(char *)optlist, i + sizeof(gwlist[0])) < 0) {
|
||||||
bb_perror_msg_and_die("IP_OPTIONS");
|
bb_perror_msg_and_die("IP_OPTIONS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1106,7 +1085,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef IP_TOS
|
#ifdef IP_TOS
|
||||||
if (tos_str && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
|
if ((op & OPT_TOS) && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
|
||||||
bb_perror_msg_and_die("setsockopt tos %d", tos);
|
bb_perror_msg_and_die("setsockopt tos %d", tos);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1127,10 +1106,11 @@ int traceroute_main(int argc, char **argv)
|
|||||||
outip = xzalloc(packlen);
|
outip = xzalloc(packlen);
|
||||||
|
|
||||||
outip->ip_v = IPVERSION;
|
outip->ip_v = IPVERSION;
|
||||||
if (tos_str)
|
if (op & OPT_TOS)
|
||||||
outip->ip_tos = tos;
|
outip->ip_tos = tos;
|
||||||
outip->ip_len = htons(packlen);
|
outip->ip_len = htons(packlen);
|
||||||
outip->ip_off = htons(off);
|
if (op & OPT_DONT_FRAGMNT)
|
||||||
|
outip->ip_off = htons(IP_DF);
|
||||||
outp = (unsigned char *)(outip + 1);
|
outp = (unsigned char *)(outip + 1);
|
||||||
outip->ip_dst = to->sin_addr;
|
outip->ip_dst = to->sin_addr;
|
||||||
|
|
||||||
@ -1153,12 +1133,11 @@ int traceroute_main(int argc, char **argv)
|
|||||||
outdata = (outdata_t *)(outudp + 1);
|
outdata = (outdata_t *)(outudp + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the interface address list */
|
|
||||||
n = ifaddrlist(&al);
|
|
||||||
|
|
||||||
/* Look for a specific device */
|
/* Look for a specific device */
|
||||||
if (op & OPT_DEVICE) {
|
if (op & OPT_DEVICE) {
|
||||||
for (i = n; i > 0; --i, ++al)
|
/* Get the interface address list */
|
||||||
|
int n = ifaddrlist(&al);
|
||||||
|
for (; n > 0; --n, ++al)
|
||||||
if (strcmp(device, al->device) == 0)
|
if (strcmp(device, al->device) == 0)
|
||||||
goto found_dev;
|
goto found_dev;
|
||||||
bb_error_msg_and_die("can't find interface %s", device);
|
bb_error_msg_and_die("can't find interface %s", device);
|
||||||
@ -1185,6 +1164,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
* there are more than one).
|
* there are more than one).
|
||||||
*/
|
*/
|
||||||
if (op & OPT_DEVICE) {
|
if (op & OPT_DEVICE) {
|
||||||
|
uint32_t *ap;
|
||||||
for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
|
for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
|
||||||
if (*ap == al->addr)
|
if (*ap == al->addr)
|
||||||
goto found_dev2;
|
goto found_dev2;
|
||||||
@ -1197,7 +1177,7 @@ int traceroute_main(int argc, char **argv)
|
|||||||
if (hi->n > 1)
|
if (hi->n > 1)
|
||||||
bb_error_msg(
|
bb_error_msg(
|
||||||
"warning: %s has multiple addresses; using %s",
|
"warning: %s has multiple addresses; using %s",
|
||||||
source, inet_ntoa(from->sin_addr));
|
source, inet_ntoa(from->sin_addr));
|
||||||
}
|
}
|
||||||
freehostinfo(hi);
|
freehostinfo(hi);
|
||||||
}
|
}
|
||||||
@ -1211,7 +1191,6 @@ int traceroute_main(int argc, char **argv)
|
|||||||
if (op & OPT_SOURCE)
|
if (op & OPT_SOURCE)
|
||||||
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);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
|
for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
|
||||||
uint32_t lastaddr = 0;
|
uint32_t lastaddr = 0;
|
||||||
@ -1229,17 +1208,21 @@ int traceroute_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (sentfirst && pausemsecs > 0)
|
if (sentfirst && pausemsecs > 0)
|
||||||
usleep(pausemsecs * 1000);
|
usleep(pausemsecs * 1000);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
t1 = monotonic_us();
|
t1 = monotonic_us();
|
||||||
send_probe(++seq, ttl);
|
send_probe(++seq, ttl);
|
||||||
++sentfirst;
|
++sentfirst;
|
||||||
|
|
||||||
while ((cc = wait_for_reply(rcvsock, from)) != 0) {
|
while ((cc = wait_for_reply(rcvsock, from)) != 0) {
|
||||||
t2 = monotonic_us();
|
t2 = monotonic_us();
|
||||||
i = packet_ok(packet, cc, from, seq);
|
i = packet_ok(packet, cc, 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(packet, cc, from);
|
print(packet, cc, from);
|
||||||
lastaddr = from->sin_addr.s_addr;
|
lastaddr = from->sin_addr.s_addr;
|
||||||
++gotlastaddr;
|
++gotlastaddr;
|
||||||
@ -1251,99 +1234,86 @@ int traceroute_main(int argc, char **argv)
|
|||||||
if (i == -2) {
|
if (i == -2) {
|
||||||
if (ip->ip_ttl <= 1)
|
if (ip->ip_ttl <= 1)
|
||||||
printf(" !");
|
printf(" !");
|
||||||
++got_there;
|
got_there = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* time exceeded in transit */
|
/* time exceeded in transit */
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
break;
|
break;
|
||||||
code = i - 1;
|
i--;
|
||||||
switch (code) {
|
switch (i) {
|
||||||
|
|
||||||
case ICMP_UNREACH_PORT:
|
case ICMP_UNREACH_PORT:
|
||||||
if (ip->ip_ttl <= 1)
|
if (ip->ip_ttl <= 1)
|
||||||
printf(" !");
|
printf(" !");
|
||||||
++got_there;
|
got_there = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH_NET:
|
case ICMP_UNREACH_NET:
|
||||||
++unreachable;
|
|
||||||
printf(" !N");
|
printf(" !N");
|
||||||
|
++unreachable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH_HOST:
|
case ICMP_UNREACH_HOST:
|
||||||
++unreachable;
|
|
||||||
printf(" !H");
|
printf(" !H");
|
||||||
|
++unreachable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH_PROTOCOL:
|
case ICMP_UNREACH_PROTOCOL:
|
||||||
++got_there;
|
|
||||||
printf(" !P");
|
printf(" !P");
|
||||||
|
got_there = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH_NEEDFRAG:
|
case ICMP_UNREACH_NEEDFRAG:
|
||||||
++unreachable;
|
|
||||||
printf(" !F-%d", pmtu);
|
printf(" !F-%d", pmtu);
|
||||||
break;
|
|
||||||
|
|
||||||
case ICMP_UNREACH_SRCFAIL:
|
|
||||||
++unreachable;
|
++unreachable;
|
||||||
printf(" !S");
|
|
||||||
break;
|
break;
|
||||||
|
case ICMP_UNREACH_SRCFAIL:
|
||||||
|
printf(" !S");
|
||||||
|
++unreachable;
|
||||||
|
break;
|
||||||
case ICMP_UNREACH_FILTER_PROHIB:
|
case ICMP_UNREACH_FILTER_PROHIB:
|
||||||
case ICMP_UNREACH_NET_PROHIB: /* misuse */
|
case ICMP_UNREACH_NET_PROHIB: /* misuse */
|
||||||
++unreachable;
|
|
||||||
printf(" !A");
|
printf(" !A");
|
||||||
|
++unreachable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH_HOST_PROHIB:
|
case ICMP_UNREACH_HOST_PROHIB:
|
||||||
++unreachable;
|
|
||||||
printf(" !C");
|
printf(" !C");
|
||||||
|
++unreachable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH_HOST_PRECEDENCE:
|
case ICMP_UNREACH_HOST_PRECEDENCE:
|
||||||
++unreachable;
|
|
||||||
printf(" !V");
|
printf(" !V");
|
||||||
break;
|
|
||||||
|
|
||||||
case ICMP_UNREACH_PRECEDENCE_CUTOFF:
|
|
||||||
++unreachable;
|
++unreachable;
|
||||||
printf(" !C");
|
|
||||||
break;
|
break;
|
||||||
|
case ICMP_UNREACH_PRECEDENCE_CUTOFF:
|
||||||
|
printf(" !C");
|
||||||
|
++unreachable;
|
||||||
|
break;
|
||||||
case ICMP_UNREACH_NET_UNKNOWN:
|
case ICMP_UNREACH_NET_UNKNOWN:
|
||||||
case ICMP_UNREACH_HOST_UNKNOWN:
|
case ICMP_UNREACH_HOST_UNKNOWN:
|
||||||
++unreachable;
|
|
||||||
printf(" !U");
|
printf(" !U");
|
||||||
break;
|
|
||||||
|
|
||||||
case ICMP_UNREACH_ISOLATED:
|
|
||||||
++unreachable;
|
++unreachable;
|
||||||
printf(" !I");
|
|
||||||
break;
|
break;
|
||||||
|
case ICMP_UNREACH_ISOLATED:
|
||||||
|
printf(" !I");
|
||||||
|
++unreachable;
|
||||||
|
break;
|
||||||
case ICMP_UNREACH_TOSNET:
|
case ICMP_UNREACH_TOSNET:
|
||||||
case ICMP_UNREACH_TOSHOST:
|
case ICMP_UNREACH_TOSHOST:
|
||||||
++unreachable;
|
|
||||||
printf(" !T");
|
printf(" !T");
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
++unreachable;
|
++unreachable;
|
||||||
printf(" !<%d>", code);
|
break;
|
||||||
|
default:
|
||||||
|
printf(" !<%d>", i);
|
||||||
|
++unreachable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cc == 0)
|
if (cc == 0)
|
||||||
printf(" *");
|
printf(" *");
|
||||||
(void)fflush(stdout);
|
|
||||||
}
|
}
|
||||||
bb_putchar('\n');
|
bb_putchar('\n');
|
||||||
if (got_there ||
|
if (got_there
|
||||||
(unreachable > 0 && unreachable >= nprobes - 1))
|
|| (unreachable > 0 && unreachable >= nprobes - 1)
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user