import ether-wake applet by haveaniceday Bug 252
[oweals/busybox.git] / networking / traceroute.c
index 106cf043b0ac2e7c314a5d394c1e8799fe8fee59..44ffdf07e34704ad3ee50abc69f29baa5f6b52fb 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by the University of
- *      California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -62,9 +58,9 @@
  *     Tue Dec 20 03:50:13 PST 1988
  */
 
-#undef BB_FEATURE_TRACEROUTE_VERBOSE
-//#define BB_FEATURE_TRACEROUTE_VERBOSE
-#undef BB_FEATURE_TRACEROUTE_SO_DEBUG   /* not in documentation man */
+#undef CONFIG_FEATURE_TRACEROUTE_VERBOSE
+//#define CONFIG_FEATURE_TRACEROUTE_VERBOSE
+#undef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG   /* not in documentation man */
 
 #include <stdio.h>
 #include <errno.h>
@@ -72,9 +68,9 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include "inet_common.h"
 #include <netdb.h>
 #include <endian.h>
-#include <arpa/inet.h>
 #include <netinet/udp.h>
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
@@ -120,7 +116,7 @@ static int max_ttl = 30;
 static u_short ident;
 static u_short port = 32768+666;       /* start udp dest port # for probe packets */
 
-#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
+#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
 static int verbose;
 #endif
 static int waittime = 5;               /* time to wait for response (in seconds) */
@@ -131,40 +127,34 @@ static int nflag;                      /* print addresses numerically */
  * If the nflag has been supplied, give
  * numeric value, otherwise try for symbolic name.
  */
-static inline char *
-inetname(struct in_addr in)
+static inline void
+inetname(struct sockaddr_in *from)
 {
        char *cp;
-       static char line[50];
-       struct hostent *hp;
        static char domain[MAXHOSTNAMELEN + 1];
+       char name[MAXHOSTNAMELEN + 1];
        static int first = 1;
+       const char *ina;
 
        if (first && !nflag) {
                first = 0;
-               if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
-                   (cp = index(domain, '.')))
-                       (void) strcpy(domain, cp + 1);
-               else
+               if (getdomainname(domain, MAXHOSTNAMELEN) != 0)
                        domain[0] = 0;
        }
        cp = 0;
-       if (!nflag && in.s_addr != INADDR_ANY) {
-               hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
-               if (hp) {
-                       if ((cp = index(hp->h_name, '.')) &&
+       if (!nflag && from->sin_addr.s_addr != INADDR_ANY) {
+               if(INET_rresolve(name, sizeof(name), from, 0x4000, 0xffffffff) >= 0) {
+                       if ((cp = strchr(name, '.')) &&
                            !strcmp(cp + 1, domain))
                                *cp = 0;
-                       cp = (char *)hp->h_name;
+                       cp = (char *)name;
                }
        }
-       if (cp)
-               (void) strcpy(line, cp);
-       else {
-               in.s_addr = ntohl(in.s_addr);
-               strcpy(line, inet_ntoa(in));
-       }
-       return (line);
+       ina = inet_ntoa(from->sin_addr);
+       if (nflag)
+               printf(" %s", ina);
+       else
+               printf(" %s (%s)", (cp ? cp : ina), ina);
 }
 
 static inline void
@@ -177,13 +167,8 @@ print(u_char *buf, int cc, struct sockaddr_in *from)
        hlen = ip->ip_hl << 2;
        cc -= hlen;
 
-       if (nflag)
-               printf(" %s", inet_ntoa(from->sin_addr));
-       else
-               printf(" %s (%s)", inetname(from->sin_addr),
-                      inet_ntoa(from->sin_addr));
-
-#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
+       inetname(from);
+#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
        if (verbose)
                printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
 #endif
@@ -233,13 +218,12 @@ wait_for_reply(int sock, struct sockaddr_in *from, int reset_timer)
        return(cc);
 }
 
-#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
+#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
 /*
  * Convert an ICMP "type" field to a printable string.
  */
 static inline const char *
-pr_type(t)
-       u_char t;
+pr_type(u_char t)
 {
        static const char * const ttab[] = {
        "Echo Reply",   "ICMP 1",       "ICMP 2",       "Dest Unreachable",
@@ -267,7 +251,7 @@ packet_ok(u_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 BB_FEATURE_TRACEROUTE_VERBOSE
+#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
                if (verbose)
                        printf("packet too short (%d bytes) from %s\n", cc,
                                inet_ntoa(from->sin_addr));
@@ -290,7 +274,7 @@ packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
                    up->dest == htons(port+seq))
                        return (type == ICMP_TIMXCEED? -1 : code+1);
        }
-#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
+#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
        if (verbose) {
                int i;
                u_long *lp = (u_long *)&icp->icmp_ip;
@@ -344,13 +328,11 @@ send_probe(int seq, int ttl)
 
 
 int
-#ifndef BB_TRACEROUTE
-main(argc, argv)
+#ifndef CONFIG_TRACEROUTE
+main(int argc, char *argv[])
 #else
-traceroute_main(argc, argv)
+traceroute_main(int argc, char *argv[])
 #endif
-       int argc;
-       char *argv[];
 {
        extern char *optarg;
        extern int optind;
@@ -368,14 +350,14 @@ traceroute_main(argc, argv)
        while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
                switch(ch) {
                case 'd':
-#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
+#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
                        options |= SO_DEBUG;
 #endif
                        break;
                case 'm':
                        max_ttl = atoi(optarg);
                        if (max_ttl <= 1)
-                               error_msg_and_die("max ttl must be >1.");
+                               bb_error_msg_and_die("max ttl must be >1.");
                        break;
                case 'n':
                        nflag++;
@@ -383,12 +365,12 @@ traceroute_main(argc, argv)
                case 'p':
                        port = atoi(optarg);
                        if (port < 1)
-                               error_msg_and_die("port must be >0.");
+                               bb_error_msg_and_die("port must be >0.");
                        break;
                case 'q':
                        nprobes = atoi(optarg);
                        if (nprobes < 1)
-                               error_msg_and_die("nprobes must be >0.");
+                               bb_error_msg_and_die("nprobes must be >0.");
                        break;
                case 'r':
                        options |= SO_DONTROUTE;
@@ -403,26 +385,26 @@ traceroute_main(argc, argv)
                case 't':
                        tos = atoi(optarg);
                        if (tos < 0 || tos > 255)
-                               error_msg_and_die("tos must be 0 to 255.");
+                               bb_error_msg_and_die("tos must be 0 to 255.");
                        break;
                case 'v':
-#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
+#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
                        verbose++;
 #endif
                        break;
                case 'w':
                        waittime = atoi(optarg);
                        if (waittime <= 1)
-                               error_msg_and_die("wait must be >1 sec.");
+                               bb_error_msg_and_die("wait must be >1 sec.");
                        break;
                default:
-                       show_usage();
+                       bb_show_usage();
                }
        argc -= optind;
        argv += optind;
 
        if (argc < 1)
-               show_usage();
+               bb_show_usage();
 
        setlinebuf (stdout);
 
@@ -434,7 +416,7 @@ traceroute_main(argc, argv)
        if (*++argv)
                datalen = atoi(*argv);
        if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
-               error_msg_and_die("packet size must be 0 <= s < %d.",
+               bb_error_msg_and_die("packet size must be 0 <= s < %d.",
                    MAXPACKET - sizeof(struct opacket));
        datalen += sizeof(struct opacket);
        outpacket = (struct opacket *)xmalloc((unsigned)datalen);
@@ -447,11 +429,11 @@ traceroute_main(argc, argv)
        ident = (getpid() & 0xffff) | 0x8000;
 
        if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
-               perror_msg_and_die(can_not_create_raw_socket);
+               bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
 
        s = create_icmp_socket();
 
-#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
+#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
        if (options & SO_DEBUG)
                (void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
                                  (char *)&on, sizeof(on));
@@ -462,14 +444,14 @@ traceroute_main(argc, argv)
 #ifdef SO_SNDBUF
        if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
                       sizeof(datalen)) < 0)
-               perror_msg_and_die("SO_SNDBUF");
-#endif SO_SNDBUF
+               bb_perror_msg_and_die("SO_SNDBUF");
+#endif
 #ifdef IP_HDRINCL
        if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
                       sizeof(on)) < 0)
-               perror_msg_and_die("IP_HDRINCL");
-#endif IP_HDRINCL
-#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
+               bb_perror_msg_and_die("IP_HDRINCL");
+#endif
+#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
        if (options & SO_DEBUG)
                (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
                                  (char *)&on, sizeof(on));
@@ -483,12 +465,12 @@ traceroute_main(argc, argv)
                from.sin_family = AF_INET;
                from.sin_addr.s_addr = inet_addr(source);
                if (from.sin_addr.s_addr == -1)
-                       error_msg_and_die("unknown host %s", source);
+                       bb_error_msg_and_die("unknown host %s", source);
                outpacket->ip.ip_src = from.sin_addr;
 #ifndef IP_HDRINCL
                if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
-                       perror_msg_and_die("bind");
-#endif IP_HDRINCL
+                       bb_perror_msg_and_die("bind");
+#endif
        }
 
        fprintf(stderr, "traceroute to %s (%s)", hostname,
@@ -559,7 +541,7 @@ traceroute_main(argc, argv)
                }
                putchar('\n');
                if (got_there || unreachable >= nprobes-1)
-                       exit(0);
+                       return 0;
        }
 
        return 0;