ifupdown: stop emitting annoying/misleading error messages.
[oweals/busybox.git] / networking / traceroute.c
index c2084fc1e3e1543fe24fbca1b4e8b87442df8332..84ce8ae69920589531ff683bf11a4dc644a8d786 100644 (file)
 #undef CONFIG_FEATURE_TRACEROUTE_USE_ICMP
 //#define CONFIG_FEATURE_TRACEROUTE_USE_ICMP
 
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <endian.h>
-#include <getopt.h>
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/select.h>
 #include "inet_common.h"
 
 #include <net/if.h>
-#include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netinet/in.h>
 #include <netinet/udp.h>
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
  * Definitions for internet protocol version 4.
  * Per RFC 791, September 1981.
  */
-#define IPVERSION       4
+#define IPVERSION 4
+
+#ifndef IPPROTO_ICMP
+/* Grrrr.... */
+#define IPPROTO_ICMP 1
+#endif
+#ifndef IPPROTO_IP
+#define IPPROTO_IP 0
+#endif
 
 /*
  * Overlay for ip header used by other protocols (tcp, udp).
@@ -357,7 +350,7 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
        struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr;
        struct IFADDRLIST *st_ifaddrlist;
 
-       fd = bb_xsocket(AF_INET, SOCK_DGRAM, 0);
+       fd = xsocket(AF_INET, SOCK_DGRAM, 0);
 
        ifc.ifc_len = sizeof(ibuf);
        ifc.ifc_buf = (caddr_t)ibuf;
@@ -375,7 +368,7 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
        ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
 
        nipaddr = 1 + (ifc.ifc_len / sizeof(struct ifreq));
-       st_ifaddrlist = xcalloc(nipaddr, sizeof(struct IFADDRLIST));
+       st_ifaddrlist = xzalloc(nipaddr * sizeof(struct IFADDRLIST));
        al = st_ifaddrlist;
        nipaddr = 0;
 
@@ -423,7 +416,7 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
                ++al;
                ++nipaddr;
        }
-       if(nipaddr == 0)
+       if (nipaddr == 0)
            bb_error_msg_and_die ("Can't find any network interfaces");
        (void)close(fd);
 
@@ -457,7 +450,7 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
        struct IFADDRLIST *al;
        char buf[256], tdevice[256], device[256];
 
-       f = bb_xfopen(route, "r");
+       f = xfopen(route, "r");
 
        /* Find the appropriate interface */
        n = 0;
@@ -501,34 +494,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 \n", str, what);
-       }
-       if (val < mi && mi >= 0) {
-               if (mi == 0)
-                       bb_error_msg_and_die("%s must be >= %d\n", what, mi);
-               else
-                       bb_error_msg_and_die("%s must be > %d\n", what, mi - 1);
-       }
-       if (val > ma && ma >= 0)
-               bb_error_msg_and_die("%s must be <= %d\n", what, ma);
-       return val;
-}
-
-
 /*
  * Subtract 2 timeval structs:  out = out - in.
  * Out is assumed to be >= in.
@@ -648,7 +613,7 @@ send_probe(int seq, int ttl, struct timeval *tp)
                        outicmp->icmp_cksum = 0xffff;
        } else
 #endif
-              if (doipcksum) {
+       if (doipcksum) {
                /* Checksum (we must save and restore ip header) */
                tip = *outip;
                ui = (struct udpiphdr *)outip;
@@ -704,7 +669,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);
        }
 }
@@ -795,7 +760,7 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
                                return (type == ICMP_TIMXCEED ? -1 : code + 1);
                } else
 #endif
-                     {
+               {
                        up = (struct udphdr *)((unsigned char *)hip + hlen);
                        /* XXX 8 is a magic number */
                        if (hlen + 12 <= cc &&
@@ -835,7 +800,7 @@ 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);
@@ -872,12 +837,12 @@ gethostinfo(const char *host)
        char **p;
        u_int32_t addr, *ap;
 
-       hi = xcalloc(1, sizeof(*hi));
+       hi = xzalloc(sizeof(*hi));
        addr = inet_addr(host);
        if ((int32_t)addr != -1) {
-               hi->name = bb_xstrdup(host);
+               hi->name = xstrdup(host);
                hi->n = 1;
-               hi->addrs = xcalloc(1, sizeof(hi->addrs[0]));
+               hi->addrs = xzalloc(sizeof(hi->addrs[0]));
                hi->addrs[0] = addr;
                return hi;
        }
@@ -885,11 +850,11 @@ gethostinfo(const char *host)
        hp = xgethostbyname(host);
        if (hp->h_addrtype != AF_INET || hp->h_length != 4)
                bb_perror_msg_and_die("bad host %s", host);
-       hi->name = bb_xstrdup(hp->h_name);
+       hi->name = xstrdup(hp->h_name);
        for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
                continue;
        hi->n = n;
-       hi->addrs = xcalloc(n, sizeof(hi->addrs[0]));
+       hi->addrs = xzalloc(n * sizeof(hi->addrs[0]));
        for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
                memcpy(ap, *p, sizeof(*ap));
        return hi;
@@ -921,14 +886,12 @@ int
 traceroute_main(int argc, char *argv[])
 {
        int code, n;
-       char *cp;
        unsigned char *outp;
        u_int32_t *ap;
        struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
        struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
        struct hostinfo *hi;
        int on = 1;
-       struct protoent *pe;
        int ttl, probe, i;
        int seq = 0;
        int tos = 0;
@@ -958,12 +921,12 @@ traceroute_main(int argc, char *argv[])
 
        opterr = 0;
 #ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE
-       bb_opt_complementally = "x-x:g::";
+       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:"
+       op = getopt32(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  */
@@ -983,7 +946,7 @@ traceroute_main(int argc, char *argv[])
 #endif
        );
 
-       if(op & USAGE_OP_DONT_FRAGMNT)
+       if (op & USAGE_OP_DONT_FRAGMNT)
                off = IP_DF;
 #ifdef CONFIG_FEATURE_TRACEROUTE_USE_ICMP
        useicmp = op & USAGE_OP_USE_ICMP;
@@ -992,39 +955,39 @@ traceroute_main(int argc, char *argv[])
 #ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
        verbose = op &  USAGE_OP_VERBOSE;
 #endif
-       if(op & USAGE_OP_IP_CHKSUM) {
+       if (op & USAGE_OP_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(optarg, "nprobes", 1, -1);
-       if(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);
+               tos = xatoul_range(tos_str, 0, 255);
+       if (max_ttl_str)
+               max_ttl = xatoul_range(max_ttl_str, 1, 255);
+       if (port_str)
+               port = xatou16(port_str);
+       if (nprobes_str)
+               nprobes = xatoul_range(nprobes_str, 1, INT_MAX);
+       if (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(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);
+       if (waittime_str)
+               waittime = xatoul_range(waittime_str, 2, 24 * 60 * 60);
+       if (pausemsecs_str)
+               pausemsecs = xatoul_range(pausemsecs_str, 0, 60 * 60 * 1000);
+       if (first_ttl_str)
+               first_ttl = xatoul_range(first_ttl_str, 1, 255);
 
 #ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE
-       if(sourse_route_list) {
+       if (sourse_route_list) {
                llist_t *l_sr;
 
                for(l_sr = sourse_route_list; l_sr; ) {
                        if (lsrr >= NGATEWAYS)
-                               bb_error_msg_and_die("No more than %d gateways", NGATEWAYS);
+                               bb_error_msg_and_die("no more than %d gateways", NGATEWAYS);
                        getaddr(gwlist + lsrr, l_sr->data);
                        ++lsrr;
                        l_sr = l_sr->link;
@@ -1055,8 +1018,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:
@@ -1064,8 +1026,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;
@@ -1076,16 +1037,12 @@ traceroute_main(int argc, char *argv[])
                bb_show_usage();
        }
 
-       cp = "icmp";
-       if ((pe = getprotobyname(cp)) == NULL)
-               bb_perror_msg_and_die("unknown protocol %s", cp);
-
        /* Insure the socket fds won't be 0, 1 or 2 */
-       do n = bb_xopen(bb_dev_null, O_RDONLY); while (n < 2);
+       do n = xopen(bb_dev_null, O_RDONLY); while (n < 2);
        if (n > 2)
                close(n);
 
-       s = bb_xsocket(AF_INET, SOCK_RAW, pe->p_proto);
+       s = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 
 #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
        if (op & USAGE_OP_DEBUG)
@@ -1096,17 +1053,13 @@ traceroute_main(int argc, char *argv[])
                (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
                    sizeof(on));
 
-       sndsock = bb_xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+       sndsock = xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 
 #ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE
 #if defined(IP_OPTIONS)
        if (lsrr > 0) {
                unsigned char optlist[MAX_IPOPTLEN];
 
-               cp = "ip";
-               if ((pe = getprotobyname(cp)) == NULL)
-                       bb_perror_msg_and_die("unknown protocol");
-
                /* final hop */
                gwlist[lsrr] = to->sin_addr.s_addr;
                ++lsrr;
@@ -1121,10 +1074,10 @@ traceroute_main(int argc, char *argv[])
                optlist[3] = IPOPT_MINOFF;
                memcpy(optlist + 4, gwlist, i);
 
-               if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
+               if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
                    (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
                        bb_perror_msg_and_die("IP_OPTIONS");
-                   }
+               }
        }
 #endif /* IP_OPTIONS */
 #endif /* CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE */
@@ -1161,7 +1114,7 @@ traceroute_main(int argc, char *argv[])
        xsetgid(getgid());
        xsetuid(getuid());
 
-       outip = (struct ip *)xcalloc(1, (unsigned)packlen);
+       outip = (struct ip *)xzalloc(packlen);
 
        outip->ip_v = IPVERSION;
        if (tos_str)
@@ -1248,7 +1201,7 @@ traceroute_main(int argc, char *argv[])
 
        outip->ip_src = from->sin_addr;
 #ifndef IP_HDRINCL
-       bb_xbind(sndsock, (struct sockaddr *)from, sizeof(*from));
+       xbind(sndsock, (struct sockaddr *)from, sizeof(*from));
 #endif
 
        fprintf(stderr, "traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr));