X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Ftraceroute.c;h=33023e74fd09909a3bab115c3360dad28bdc2b13;hb=2f7b923f5c46de0840d7a683b75b6e8561461135;hp=e7e1311491d02f385143645a242c772db94c9b50;hpb=9275814a9e6a3af390c932238c0b1130de8d0edd;p=oweals%2Fbusybox.git diff --git a/networking/traceroute.c b/networking/traceroute.c index e7e131149..33023e74f 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -196,15 +196,17 @@ * Tue Dec 20 03:50:13 PST 1988 */ -#undef CONFIG_FEATURE_TRACEROUTE_VERBOSE +#define TRACEROUTE_SO_DEBUG 0 + +/* TODO: undefs were uncommented - ??! we have config system for that! */ +/* probably ok to remove altogether */ +//#undef CONFIG_FEATURE_TRACEROUTE_VERBOSE //#define CONFIG_FEATURE_TRACEROUTE_VERBOSE -#undef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG /* not in documentation man */ -#undef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE +//#undef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE //#define CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE -#undef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +//#undef CONFIG_FEATURE_TRACEROUTE_USE_ICMP //#define CONFIG_FEATURE_TRACEROUTE_USE_ICMP -#include "inet_common.h" #include #include @@ -214,6 +216,7 @@ #include #include "busybox.h" +#include "inet_common.h" /* @@ -244,7 +247,7 @@ struct ipovly { /* * UDP kernel structures and variables. */ -struct udpiphdr { +struct udpiphdr { struct ipovly ui_i; /* overlaid ip structure */ struct udphdr ui_u; /* udp header */ }; @@ -265,7 +268,7 @@ struct udpiphdr { struct hostinfo { char *name; int n; - u_int32_t *addrs; + uint32_t *addrs; }; /* Data section of the probe packet */ @@ -276,36 +279,22 @@ struct outdata { }; struct IFADDRLIST { - u_int32_t addr; + uint32_t addr; char device[sizeof(struct ifreq)]; }; -static const char route[] = "/proc/net/route"; - -/* last inbound (icmp) packet */ -static unsigned char packet[512] ATTRIBUTE_ALIGNED(32); - static struct ip *outip; /* last output (udp) packet */ static struct udphdr *outudp; /* last output (udp) packet */ static struct outdata *outdata; /* last output (udp) packet */ -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP static struct icmp *outicmp; /* last output (icmp) packet */ #endif -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE -/* Maximum number of gateways (include room for one noop) */ -#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t))) -/* loose source route gateway list (including room for final destination) */ -static u_int32_t gwlist[NGATEWAYS + 1]; -#endif - static int s; /* receive (icmp) socket file descriptor */ static int sndsock; /* send (udp/icmp) socket file descriptor */ -static struct sockaddr_storage whereto; /* Who to try to reach */ -static struct sockaddr_storage wherefrom; /* Who we are */ static int packlen; /* total length of packet */ static int minpacket; /* min ip packet size */ static int maxpacket = 32 * 1024; /* max ip packet size */ @@ -313,25 +302,68 @@ static int pmtu; /* Path MTU Discovery (RFC1191) */ static char *hostname; -static u_short ident; -static u_short port = 32768 + 666; /* start udp dest port # for probe packets */ +static uint16_t ident; +static uint16_t port = 32768 + 666; /* start udp dest port # for probe packets */ static int waittime = 5; /* time to wait for response (in seconds) */ -static int nflag; /* print addresses numerically */ static int doipcksum = 1; /* calculate ip checksums by default */ -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE static int optlen; /* length of ip options */ #else #define optlen 0 #endif -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP -static int useicmp; /* use icmp echo instead of udp packets */ + +/* Keep in sync with getopt32 call! */ +#define OPT_DONT_FRAGMNT (1<<0) /* F */ +#define OPT_USE_ICMP (1<<1) /* I */ +#define OPT_TTL_FLAG (1<<2) /* l */ +#define OPT_ADDR_NUM (1<<3) /* n */ +#define OPT_BYPASS_ROUTE (1<<4) /* r */ +#define OPT_DEBUG (1<<5) /* d */ +#define OPT_VERBOSE (1<<6) /* v */ +#define OPT_IP_CHKSUM (1<<7) /* x */ +#define OPT_TOS (1<<8) /* t */ +#define OPT_DEVICE (1<<9) /* i */ +#define OPT_MAX_TTL (1<<10) /* m */ +#define OPT_PORT (1<<11) /* p */ +#define OPT_NPROBES (1<<12) /* q */ +#define OPT_SOURCE (1<<13) /* s */ +#define OPT_WAITTIME (1<<14) /* w */ +#define OPT_PAUSE_MS (1<<15) /* z */ +#define OPT_FIRST_TTL (1<<16) /* f */ + +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP +/* use icmp echo instead of udp packets */ +#define useicmp (option_mask32 & OPT_USE_ICMP) +#endif +#if ENABLE_FEATURE_TRACEROUTE_VERBOSE +#define verbose (option_mask32 & OPT_VERBOSE) #endif -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE -static int verbose; +#define nflag (option_mask32 & OPT_ADDR_NUM) + + +struct globals { + /* last inbound (icmp) packet */ + unsigned char packet[512]; + struct sockaddr_storage whereto; /* Who to try to reach */ + struct sockaddr_storage wherefrom; /* Who we are */ +#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) + +#define packet (G.packet ) +#define whereto (G.whereto ) +#define wherefrom (G.wherefrom) +#define gwlist (G.gwlist ) + /* * Return the interface list @@ -416,8 +448,8 @@ ifaddrlist(struct IFADDRLIST **ipaddrp) ++al; ++nipaddr; } - if(nipaddr == 0) - bb_error_msg_and_die ("Can't find any network interfaces"); + if (nipaddr == 0) + bb_error_msg_and_die ("can't find any network interfaces"); (void)close(fd); *ipaddrp = st_ifaddrlist; @@ -426,7 +458,7 @@ ifaddrlist(struct IFADDRLIST **ipaddrp) static void -setsin(struct sockaddr_in *addr_sin, u_int32_t addr) +setsin(struct sockaddr_in *addr_sin, uint32_t addr) { memset(addr_sin, 0, sizeof(*addr_sin)); #ifdef HAVE_SOCKADDR_SA_LEN @@ -445,12 +477,12 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) { int i, n; FILE *f; - u_int32_t mask; - u_int32_t dest, tmask; + uint32_t mask; + uint32_t dest, tmask; struct IFADDRLIST *al; char buf[256], tdevice[256], device[256]; - f = xfopen(route, "r"); + f = xfopen("/proc/net/route", "r"); /* Find the appropriate interface */ n = 0; @@ -472,7 +504,7 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) fclose(f); if (device[0] == '\0') - bb_error_msg_and_die ("Can't find interface"); + bb_error_msg_and_die ("can't find interface"); /* Get the interface address list */ n = ifaddrlist(&al); @@ -482,7 +514,7 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) if (strcmp(device, al->device) == 0) break; if (i <= 0) - bb_error_msg_and_die("Can't find interface %s", device); + bb_error_msg_and_die("can't find interface %s", device); setsin(from, al->addr); } @@ -494,34 +526,6 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) */ -/* String to value with optional min and max. Handles decimal and hex. */ -static int -str2val(const char *str, const char *what, int mi, int ma) -{ - const char *cp; - int val; - char *ep; - - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { - cp = str + 2; - val = (int)strtol(cp, &ep, 16); - } else - val = (int)strtol(str, &ep, 10); - if (*ep != '\0') { - bb_error_msg_and_die("\"%s\" bad value for %s", str, what); - } - if (val < mi && mi >= 0) { - if (mi == 0) - bb_error_msg_and_die("%s must be >= %d", what, mi); - else - bb_error_msg_and_die("%s must be > %d", what, mi - 1); - } - if (val > ma && ma >= 0) - bb_error_msg_and_die("%s must be <= %d", what, ma); - return val; -} - - /* * Subtract 2 timeval structs: out = out - in. * Out is assumed to be >= in. @@ -564,12 +568,12 @@ wait_for_reply(int sock, struct sockaddr_in *fromp, const struct timeval *tp) /* * Checksum routine for Internet Protocol family headers (C Version) */ -static u_short -in_cksum(u_short *addr, int len) +static uint16_t +in_cksum(uint16_t *addr, int len) { int nleft = len; - u_short *w = addr; - u_short answer; + uint16_t *w = addr; + uint16_t answer; int sum = 0; /* @@ -614,7 +618,7 @@ send_probe(int seq, int ttl, struct timeval *tp) */ if (doipcksum) { outip->ip_sum = - in_cksum((u_short *)outip, sizeof(*outip) + optlen); + in_cksum((uint16_t *)outip, sizeof(*outip) + optlen); if (outip->ip_sum == 0) outip->ip_sum = 0xffff; } @@ -624,18 +628,18 @@ send_probe(int seq, int ttl, struct timeval *tp) outdata->ttl = ttl; memcpy(&outdata->tv, tp, sizeof(outdata->tv)); -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP if (useicmp) outicmp->icmp_seq = htons(seq); else #endif outudp->dest = htons(port + seq); -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP if (useicmp) { /* Always calculate checksum for icmp packets */ outicmp->icmp_cksum = 0; - outicmp->icmp_cksum = in_cksum((u_short *)outicmp, + outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp, packlen - (sizeof(*outip) + optlen)); if (outicmp->icmp_cksum == 0) outicmp->icmp_cksum = 0xffff; @@ -653,20 +657,20 @@ send_probe(int seq, int ttl, struct timeval *tp) ui->ui_pr = oui->ui_pr; ui->ui_len = outudp->len; outudp->check = 0; - outudp->check = in_cksum((u_short *)ui, packlen); + outudp->check = in_cksum((uint16_t *)ui, packlen); if (outudp->check == 0) outudp->check = 0xffff; *outip = tip; } -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE +#if ENABLE_FEATURE_TRACEROUTE_VERBOSE /* XXX undocumented debugging hack */ if (verbose > 1) { - const u_short *sp; + const uint16_t *sp; int nshorts, i; - sp = (u_short *)outip; - nshorts = (u_int)packlen / sizeof(u_short); + sp = (uint16_t *)outip; + nshorts = (unsigned)packlen / sizeof(uint16_t); i = 0; printf("[ %d bytes", packlen); while (--nshorts >= 0) { @@ -697,7 +701,7 @@ send_probe(int seq, int ttl, struct timeval *tp) if (cc < 0) bb_perror_msg_and_die("sendto"); printf("%s: wrote %s %d chars, ret=%d\n", - bb_applet_name, hostname, packlen, cc); + applet_name, hostname, packlen, cc); (void)fflush(stdout); } } @@ -712,7 +716,7 @@ deltaT(struct timeval *t1p, struct timeval *t2p) return dt; } -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE +#if ENABLE_FEATURE_TRACEROUTE_VERBOSE /* * Convert an ICMP "type" field to a printable string. */ @@ -745,7 +749,7 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq) ip = (struct ip *) buf; hlen = ip->ip_hl << 2; if (cc < hlen + ICMP_MINLEN) { -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE +#if ENABLE_FEATURE_TRACEROUTE_VERBOSE if (verbose) printf("packet too short (%d bytes) from %s\n", cc, inet_ntoa(from->sin_addr)); @@ -769,7 +773,7 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq) hip = &icp->icmp_ip; hlen = hip->ip_hl << 2; -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP if (useicmp) { struct icmp *hicmp; @@ -798,10 +802,10 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq) return (type == ICMP_TIMXCEED ? -1 : code + 1); } } -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE +#if ENABLE_FEATURE_TRACEROUTE_VERBOSE if (verbose) { int i; - u_int32_t *lp = (u_int32_t *)&icp->icmp_ip; + uint32_t *lp = (uint32_t *)&icp->icmp_ip; printf("\n%d bytes from %s to " "%s: icmp type %d (%s) code %d\n", @@ -828,7 +832,8 @@ inetname(struct sockaddr_in *from) char name[257]; if (!nflag && from->sin_addr.s_addr != INADDR_ANY) { - if(INET_rresolve(name, sizeof(name), from, 0x4000, 0xffffffff) >= 0) + if (INET_rresolve(name, sizeof(name), from, 0x4000, + 0xffffffff) >= 0) n = name; } ina = inet_ntoa(from->sin_addr); @@ -849,7 +854,7 @@ print(unsigned char *buf, int cc, struct sockaddr_in *from) cc -= hlen; inetname(from); -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE +#if ENABLE_FEATURE_TRACEROUTE_VERBOSE if (verbose) printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst)); #endif @@ -863,11 +868,11 @@ gethostinfo(const char *host) struct hostent *hp; struct hostinfo *hi; char **p; - u_int32_t addr, *ap; + uint32_t addr, *ap; hi = xzalloc(sizeof(*hi)); addr = inet_addr(host); - if ((int32_t)addr != -1) { + if (addr != 0xffffffff) { hi->name = xstrdup(host); hi->n = 1; hi->addrs = xzalloc(sizeof(hi->addrs[0])); @@ -897,9 +902,9 @@ freehostinfo(struct hostinfo *hi) free((char *)hi); } -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE static void -getaddr(u_int32_t *ap, const char *host) +getaddr(uint32_t *ap, const char *host) { struct hostinfo *hi; @@ -910,110 +915,98 @@ getaddr(u_int32_t *ap, const char *host) #endif -int -traceroute_main(int argc, char *argv[]) +int traceroute_main(int argc, char **argv); +int traceroute_main(int argc, char **argv) { int code, n; unsigned char *outp; - u_int32_t *ap; - struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom; - struct sockaddr_in *to = (struct sockaddr_in *)&whereto; + uint32_t *ap; + struct sockaddr_in *from; + struct sockaddr_in *to; struct hostinfo *hi; - int on = 1; int ttl, probe, i; int seq = 0; int tos = 0; - char *tos_str = NULL; - char *source = NULL; - unsigned long op; - -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE + char *tos_str; + char *source; + unsigned op; +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE int lsrr = 0; #endif - u_short off = 0; + uint16_t off = 0; struct IFADDRLIST *al; - char *device = NULL; + char *device; int max_ttl = 30; - char *max_ttl_str = NULL; - char *port_str = NULL; + char *max_ttl_str; + char *port_str; int nprobes = 3; - char *nprobes_str = NULL; - char *waittime_str = NULL; - u_int pausemsecs = 0; - char *pausemsecs_str = NULL; + char *nprobes_str; + char *waittime_str; + unsigned pausemsecs = 0; + char *pausemsecs_str; int first_ttl = 1; - char *first_ttl_str = NULL; -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE + char *first_ttl_str; +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE llist_t *sourse_route_list = NULL; #endif - opterr = 0; -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE - bb_opt_complementally = "x-x:g::"; + PTR_TO_GLOBALS = xzalloc(sizeof(G)); + from = (struct sockaddr_in *)&wherefrom; + to = (struct sockaddr_in *)&whereto; + + //opterr = 0; +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE + opt_complementary = "x-x:g::"; #else - bb_opt_complementally = "x-x"; + opt_complementary = "x-x"; #endif - op = bb_getopt_ulflags(argc, argv, "FIlnrdvxt:i:m:p:q:s:w:z:f:" -#define USAGE_OP_DONT_FRAGMNT (1<<0) /* F */ -#define USAGE_OP_USE_ICMP (1<<1) /* I */ -#define USAGE_OP_TTL_FLAG (1<<2) /* l */ -#define USAGE_OP_ADDR_NUM (1<<3) /* n */ -#define USAGE_OP_BYPASS_ROUTE (1<<4) /* r */ -#define USAGE_OP_DEBUG (1<<5) /* d */ -#define USAGE_OP_VERBOSE (1<<6) /* v */ -#define USAGE_OP_IP_CHKSUM (1<<7) /* x */ - -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE + op = getopt32(argc, 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, - &source, &waittime_str, &pausemsecs_str, &first_ttl_str -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE - , &sourse_route_list + , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str + , &source, &waittime_str, &pausemsecs_str, &first_ttl_str +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE + , &sourse_route_list #endif ); - if(op & USAGE_OP_DONT_FRAGMNT) + if (op & OPT_DONT_FRAGMNT) off = IP_DF; -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP - useicmp = op & USAGE_OP_USE_ICMP; -#endif - nflag = op & USAGE_OP_ADDR_NUM; -#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE - verbose = op & USAGE_OP_VERBOSE; -#endif - if(op & USAGE_OP_IP_CHKSUM) { + if (op & OPT_IP_CHKSUM) { doipcksum = 0; - bb_error_msg("Warning: ip checksums disabled"); + bb_error_msg("warning: ip checksums disabled"); } - if (tos_str) - tos = str2val(tos_str, "tos", 0, 255); - if(max_ttl_str) - max_ttl = str2val(max_ttl_str, "max ttl", 1, 255); - if(port_str) - port = (u_short)str2val(port_str, "port", 1, (1 << 16) - 1); - if(nprobes_str) - nprobes = str2val(nprobes_str, "nprobes", 1, -1); - if(source) { + if (op & OPT_TOS) + tos = xatou_range(tos_str, 0, 255); + if (op & OPT_MAX_TTL) + max_ttl = xatou_range(max_ttl_str, 1, 255); + if (op & OPT_PORT) + port = xatou16(port_str); + if (op & OPT_NPROBES) + nprobes = xatou_range(nprobes_str, 1, INT_MAX); + if (op & OPT_SOURCE) { /* * set the ip source address of the outbound * probe (e.g., on a multi-homed host). */ - if (getuid()) bb_error_msg_and_die("-s %s: permission denied", source); + if (getuid()) + bb_error_msg_and_die("-s %s: permission denied", source); } - if(waittime_str) - waittime = str2val(waittime_str, "wait time", 2, 24 * 60 * 60); - if(pausemsecs_str) - pausemsecs = str2val(pausemsecs_str, "pause msecs", 0, 60 * 60 * 1000); - if(first_ttl_str) - first_ttl = str2val(first_ttl_str, "first ttl", 1, 255); - -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE - if(sourse_route_list) { + if (op & OPT_WAITTIME) + waittime = xatou_range(waittime_str, 2, 24 * 60 * 60); + if (op & OPT_PAUSE_MS) + pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000); + if (op & OPT_FIRST_TTL) + first_ttl = xatou_range(first_ttl_str, 1, 255); + +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE + if (sourse_route_list) { llist_t *l_sr; - for(l_sr = sourse_route_list; l_sr; ) { + l_sr = sourse_route_list; + while (l_sr) { if (lsrr >= NGATEWAYS) bb_error_msg_and_die("no more than %d gateways", NGATEWAYS); getaddr(gwlist + lsrr, l_sr->data); @@ -1034,7 +1027,7 @@ traceroute_main(int argc, char *argv[]) minpacket = sizeof(*outip) + sizeof(*outdata) + optlen; -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP if (useicmp) minpacket += 8; /* XXX magic number */ else @@ -1046,8 +1039,7 @@ traceroute_main(int argc, char *argv[]) switch (argc - optind) { case 2: - packlen = str2val(argv[optind + 1], - "packet length", minpacket, maxpacket); + packlen = xatoul_range(argv[optind + 1], minpacket, maxpacket); /* Fall through */ case 1: @@ -1055,8 +1047,7 @@ traceroute_main(int argc, char *argv[]) hi = gethostinfo(hostname); setsin(to, hi->addrs[0]); if (hi->n > 1) - bb_error_msg( - "Warning: %s has multiple addresses; using %s", + bb_error_msg("warning: %s has multiple addresses; using %s", hostname, inet_ntoa(to->sin_addr)); hostname = hi->name; hi->name = NULL; @@ -1067,25 +1058,23 @@ traceroute_main(int argc, char *argv[]) bb_show_usage(); } - /* Insure the socket fds won't be 0, 1 or 2 */ - do n = xopen(bb_dev_null, O_RDONLY); while (n < 2); - if (n > 2) - close(n); + /* Ensure the socket fds won't be 0, 1 or 2 */ + bb_sanitize_stdio(); s = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP); -#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG - if (op & USAGE_OP_DEBUG) - (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, - sizeof(on)); +#if TRACEROUTE_SO_DEBUG + if (op & OPT_DEBUG) + setsockopt(s, SOL_SOCKET, SO_DEBUG, + &const_int_1, sizeof(const_int_1)); #endif - if (op & USAGE_OP_BYPASS_ROUTE) - (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on, - sizeof(on)); + if (op & OPT_BYPASS_ROUTE) + setsockopt(s, SOL_SOCKET, SO_DONTROUTE, + &const_int_1, sizeof(const_int_1)); sndsock = xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW); -#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE +#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE #if defined(IP_OPTIONS) if (lsrr > 0) { unsigned char optlist[MAX_IPOPTLEN]; @@ -1113,38 +1102,37 @@ traceroute_main(int argc, char *argv[]) #endif /* CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE */ #ifdef SO_SNDBUF - if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen, - sizeof(packlen)) < 0) { + if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) { bb_perror_msg_and_die("SO_SNDBUF"); } #endif #ifdef IP_HDRINCL - if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, - sizeof(on)) < 0 && errno != ENOPROTOOPT) { + if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, &const_int_1, sizeof(const_int_1)) < 0 + && errno != ENOPROTOOPT + ) { bb_perror_msg_and_die("IP_HDRINCL"); } #else #ifdef IP_TOS - if (tos_str && setsockopt(sndsock, IPPROTO_IP, IP_TOS, - (char *)&tos, sizeof(tos)) < 0) { + if (tos_str && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { bb_perror_msg_and_die("setsockopt tos %d", tos); } #endif #endif -#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG - if (op & USAGE_OP_DEBUG) - (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, - sizeof(on)); +#if TRACEROUTE_SO_DEBUG + if (op & OPT_DEBUG) + setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, + &const_int_1, sizeof(const_int_1)); #endif - if (op & USAGE_OP_BYPASS_ROUTE) - (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, - sizeof(on)); + if (op & OPT_BYPASS_ROUTE) + setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, + &const_int_1, sizeof(const_int_1)); /* Revert to non-privileged user after opening sockets */ xsetgid(getgid()); xsetuid(getuid()); - outip = (struct ip *)xzalloc(packlen); + outip = xzalloc(packlen); outip->ip_v = IPVERSION; if (tos_str) @@ -1156,24 +1144,20 @@ traceroute_main(int argc, char *argv[]) outip->ip_hl = (outp - (unsigned char *)outip) >> 2; ident = (getpid() & 0xffff) | 0x8000; -#ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP +#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP if (useicmp) { outip->ip_p = IPPROTO_ICMP; - outicmp = (struct icmp *)outp; outicmp->icmp_type = ICMP_ECHO; outicmp->icmp_id = htons(ident); - outdata = (struct outdata *)(outp + 8); /* XXX magic number */ } else #endif - { + { outip->ip_p = IPPROTO_UDP; - outudp = (struct udphdr *)outp; outudp->source = htons(ident); - outudp->len = - htons((u_short)(packlen - (sizeof(*outip) + optlen))); + outudp->len = htons((uint16_t)(packlen - (sizeof(*outip) + optlen))); outdata = (struct outdata *)(outudp + 1); } @@ -1181,22 +1165,21 @@ traceroute_main(int argc, char *argv[]) n = ifaddrlist(&al); /* Look for a specific device */ - if (device != NULL) { + if (op & OPT_DEVICE) { for (i = n; i > 0; --i, ++al) if (strcmp(device, al->device) == 0) - break; - if (i <= 0) { - bb_error_msg_and_die("Can't find interface %s", device); - } + goto found_dev; + bb_error_msg_and_die("can't find interface %s", device); } + found_dev: /* Determine our source address */ - if (source == NULL) { + if (!(op & OPT_SOURCE)) { /* * If a device was specified, use the interface address. * Otherwise, try to determine our source address. */ - if (device != NULL) + if (op & OPT_DEVICE) setsin(from, al->addr); findsaddr(to, from); } else { @@ -1209,21 +1192,19 @@ traceroute_main(int argc, char *argv[]) * Otherwise, use the first address (and warn if * there are more than one). */ - if (device != NULL) { + if (op & OPT_DEVICE) { for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap) if (*ap == al->addr) - break; - if (i <= 0) { - bb_error_msg_and_die( - "%s is not on interface %s", - source, device); - } + goto found_dev2; + bb_error_msg_and_die("%s is not on interface %s", + source, device); + found_dev2: setsin(from, *ap); } else { setsin(from, hi->addrs[0]); if (hi->n > 1) bb_error_msg( - "Warning: %s has multiple addresses; using %s", + "warning: %s has multiple addresses; using %s", source, inet_ntoa(from->sin_addr)); } freehostinfo(hi); @@ -1234,14 +1215,14 @@ traceroute_main(int argc, char *argv[]) xbind(sndsock, (struct sockaddr *)from, sizeof(*from)); #endif - fprintf(stderr, "traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr)); - if (source) - fprintf(stderr, " from %s", source); - fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen); - (void)fflush(stderr); + printf("traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr)); + if (op & OPT_SOURCE) + printf(" from %s", source); + printf(", %d hops max, %d byte packets\n", max_ttl, packlen); + fflush(stdout); for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { - u_int32_t lastaddr = 0; + uint32_t lastaddr = 0; int gotlastaddr = 0; int got_there = 0; int unreachable = 0; @@ -1273,7 +1254,7 @@ traceroute_main(int argc, char *argv[]) } printf(" %.3f ms", deltaT(&t1, &t2)); ip = (struct ip *)packet; - if (op & USAGE_OP_TTL_FLAG) + if (op & OPT_TTL_FLAG) printf(" (%d)", ip->ip_ttl); if (i == -2) { if (ip->ip_ttl <= 1)