traceroute: preparatory trivial cleanups
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 24 Jan 2009 20:11:36 +0000 (20:11 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 24 Jan 2009 20:11:36 +0000 (20:11 -0000)
function                                             old     new   delta
traceroute_main                                     3932    3713    -219

libbb/xfuncs_printf.c
networking/traceroute.c

index 46ae7ac60568517d9f0d1405b9296b6c2242b593..cd0f84dea1b561084da859b8066118c5b95451d8 100644 (file)
@@ -440,7 +440,7 @@ void FAST_FUNC xlisten(int s, int backlog)
 
 /* Die with an error message if sendto failed.
  * 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)
 {
        ssize_t ret = sendto(s, buf, len, 0, to, tolen);
index 5d1baacf59f4291123e0f05e83dd43b12672b00d..958299aaa3943d2f4fbd6949435a4d73f6af80b9 100644 (file)
 #define IPVERSION 4
 
 #ifndef IPPROTO_ICMP
-/* Grrrr.... */
-#define IPPROTO_ICMP 1
+# define IPPROTO_ICMP 1
 #endif
 #ifndef IPPROTO_IP
-#define IPPROTO_IP 0
+# define IPPROTO_IP 0
 #endif
 
 /*
@@ -482,7 +481,6 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
        return nipaddr;
 }
 
-
 static void
 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;
 }
 
-
 /*
  * 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);
 }
 
-/*
-"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
 wait_for_reply(int sock, struct sockaddr_in *fromp)
 {
@@ -581,12 +571,12 @@ in_cksum(uint16_t *addr, int len)
        int sum = 0;
 
        /*
-        *  Our algorithm is simple, using a 32 bit accumulator (sum),
-        *  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
-        *  16 bits.
+        * Our algorithm is simple, using a 32 bit accumulator (sum),
+        * 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
+        * 16 bits.
         */
-       while (nleft > 1)  {
+       while (nleft > 1) {
                sum += *w++;
                nleft -= 2;
        }
@@ -595,16 +585,13 @@ in_cksum(uint16_t *addr, int len)
        if (nleft == 1)
                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);                     /* add carry */
        answer = ~sum;                          /* truncate to 16 bits */
        return answer;
 }
 
-
 static void
 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.
-        * But we must do it anyway so that the udp checksum comes out
-        * right.
+        * But we must do it anyway so that the udp checksum comes out right.
         */
        if (doipcksum) {
-               outip->ip_sum =
-                   in_cksum((uint16_t *)outip, sizeof(*outip) + optlen);
+               outip->ip_sum = in_cksum((uint16_t *)outip, sizeof(*outip) + optlen);
                if (outip->ip_sum == 0)
                        outip->ip_sum = 0xffff;
        }
@@ -645,7 +630,7 @@ send_probe(int seq, int ttl)
                /* Always calculate checksum for icmp packets */
                outicmp->icmp_cksum = 0;
                outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp,
-                   packlen - (sizeof(*outip) + optlen));
+                                       packlen - (sizeof(*outip) + optlen));
                if (outicmp->icmp_cksum == 0)
                        outicmp->icmp_cksum = 0xffff;
        } else
@@ -656,7 +641,7 @@ send_probe(int seq, int ttl)
                ui = (struct udpiphdr *)outip;
                oui = (struct udpiphdr *)&tip;
                /* 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_dst = oui->ui_dst;
                ui->ui_pr = oui->ui_pr;
@@ -668,7 +653,8 @@ send_probe(int seq, int ttl)
                *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 */
        if (verbose > 1) {
                const uint16_t *sp;
@@ -695,15 +681,15 @@ send_probe(int seq, int ttl)
 
 #if !defined(IP_HDRINCL) && defined(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);
        }
 #endif
 
-       cc = xsendto(sndsock, (char *)outip,
-           packlen, (struct sockaddr *)&whereto, sizeof(whereto));
-       if (cc != packlen)  {
-               bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc);
+       cc = xsendto(sndsock, outip, packlen,
+                       (struct sockaddr *)&whereto, sizeof(whereto));
+       if (cc != packlen) {
+               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"
        };
 
-       if (t > 18)
+       if (t >= ARRAY_SIZE(ttab))
                return "OUT-OF-RANGE";
 
        return ttab[t];
@@ -734,12 +720,12 @@ pr_type(unsigned char t)
        packet_ok(buf, cc, seq)
 #endif
 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;
        int hlen;
-       struct ip *ip;
+       const struct ip *ip;
 
        ip = (struct ip *) buf;
        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;
        code = icp->icmp_code;
        /* Path MTU Discovery (RFC1191) */
-       if (code != ICMP_UNREACH_NEEDFRAG)
-               pmtu = 0;
-       else {
+       pmtu = 0;
+       if (code == ICMP_UNREACH_NEEDFRAG)
                pmtu = ntohs(icp->icmp_nextmtu);
-       }
-       if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
-           type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
-               struct ip *hip;
-               struct udphdr *up;
+
+       if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS)
+        || type == ICMP_UNREACH
+        || type == ICMP_ECHOREPLY
+       ) {
+               const struct ip *hip;
+               const struct udphdr *up;
 
                hip = &icp->icmp_ip;
                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 "
                       "%s: icmp type %d (%s) code %d\n",
-                   cc, inet_ntoa(from->sin_addr),
-                   inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
+                       cc, inet_ntoa(from->sin_addr),
+                       inet_ntoa(ip->ip_dst),
+                       type, pr_type(type), icp->icmp_code);
                for (i = 4; i < cc; i += sizeof(*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;
 }
 
-
 /*
  * 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.
  */
 static void
-print_inetname(struct sockaddr_in *from)
+print_inetname(const struct sockaddr_in *from)
 {
        const char *ina;
 
@@ -837,9 +824,9 @@ print_inetname(struct sockaddr_in *from)
 }
 
 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;
 
        ip = (struct ip *) buf;
@@ -853,7 +840,6 @@ print(unsigned char *buf, int cc, struct sockaddr_in *from)
 #endif
 }
 
-
 static struct hostinfo *
 gethostinfo(const char *host)
 {
@@ -910,15 +896,19 @@ static void
 print_delta_ms(unsigned t1p, unsigned t2p)
 {
        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)
 {
-       int code, n;
        unsigned char *outp;
-       uint32_t *ap;
        struct sockaddr_in *from;
        struct sockaddr_in *to;
        struct hostinfo *hi;
@@ -931,7 +921,6 @@ int traceroute_main(int argc, char **argv)
 #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
        int lsrr = 0;
 #endif
-       uint16_t off = 0;
        struct IFADDRLIST *al;
        char *device;
        int max_ttl = 30;
@@ -952,7 +941,6 @@ int traceroute_main(int argc, char **argv)
        from = (struct sockaddr_in *)&wherefrom;
        to = (struct sockaddr_in *)&whereto;
 
-       //opterr = 0;
 #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
        opt_complementary = "x-x:g::";
 #else
@@ -970,8 +958,6 @@ int traceroute_main(int argc, char **argv)
 #endif
        );
 
-       if (op & OPT_DONT_FRAGMNT)
-               off = IP_DF;
        if (op & OPT_IP_CHKSUM) {
                doipcksum = 0;
                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
                 * probe (e.g., on a multi-homed host).
                 */
-               if (getuid())
-                       bb_error_msg_and_die("-s %s: permission denied", source);
+               if (getuid() != 0)
+                       bb_error_msg_and_die("you must be root to use -s");
        }
        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);
+               first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
 
 #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
        if (source_route_list) {
@@ -1011,12 +997,6 @@ int traceroute_main(int argc, char **argv)
        }
 #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;
 
 #if ENABLE_FEATURE_TRACEROUTE_USE_ICMP
@@ -1028,14 +1008,14 @@ int traceroute_main(int argc, char **argv)
        packlen = minpacket;                    /* minimum sized packet */
 
        /* Process destination and optional packet size */
-       switch (argc - optind) {
-
+       argv += optind;
+       argc -= optind;
+       switch (argc) {
        case 2:
-               packlen = xatoul_range(argv[optind + 1], minpacket, maxpacket);
+               packlen = xatoul_range(argv[1], minpacket, maxpacket);
                /* Fall through */
-
        case 1:
-               hostname = argv[optind];
+               hostname = argv[0];
                hi = gethostinfo(hostname);
                setsin(to, hi->addrs[0]);
                if (hi->n > 1)
@@ -1045,7 +1025,6 @@ int traceroute_main(int argc, char **argv)
                hi->name = NULL;
                freehostinfo(hi);
                break;
-
        default:
                bb_show_usage();
        }
@@ -1081,12 +1060,12 @@ int traceroute_main(int argc, char **argv)
                optlist[1] = IPOPT_LSRR;
                i = lsrr * sizeof(gwlist[0]);
                optlist[2] = i + 3;
-               /* Pointer to LSRR addresses */
+               /* pointer to LSRR addresses */
                optlist[3] = IPOPT_MINOFF;
                memcpy(optlist + 4, gwlist, i);
 
-               if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
-                   (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
+               if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
+                               (char *)optlist, i + sizeof(gwlist[0])) < 0) {
                        bb_perror_msg_and_die("IP_OPTIONS");
                }
        }
@@ -1106,7 +1085,7 @@ int traceroute_main(int argc, char **argv)
        }
 #else
 #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);
        }
 #endif
@@ -1127,10 +1106,11 @@ int traceroute_main(int argc, char **argv)
        outip = xzalloc(packlen);
 
        outip->ip_v = IPVERSION;
-       if (tos_str)
+       if (op & OPT_TOS)
                outip->ip_tos = tos;
        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);
        outip->ip_dst = to->sin_addr;
 
@@ -1153,12 +1133,11 @@ int traceroute_main(int argc, char **argv)
                outdata = (outdata_t *)(outudp + 1);
        }
 
-       /* Get the interface address list */
-       n = ifaddrlist(&al);
-
        /* Look for a specific 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)
                                goto found_dev;
                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).
                 */
                if (op & OPT_DEVICE) {
+                       uint32_t *ap;
                        for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
                                if (*ap == al->addr)
                                        goto found_dev2;
@@ -1197,7 +1177,7 @@ int traceroute_main(int argc, char **argv)
                        if (hi->n > 1)
                                bb_error_msg(
                        "warning: %s has multiple addresses; using %s",
-                                   source, inet_ntoa(from->sin_addr));
+                                       source, inet_ntoa(from->sin_addr));
                }
                freehostinfo(hi);
        }
@@ -1211,7 +1191,6 @@ int traceroute_main(int argc, char **argv)
        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) {
                uint32_t lastaddr = 0;
@@ -1229,17 +1208,21 @@ int traceroute_main(int argc, char **argv)
 
                        if (sentfirst && pausemsecs > 0)
                                usleep(pausemsecs * 1000);
+                       fflush(stdout);
+
                        t1 = monotonic_us();
                        send_probe(++seq, ttl);
                        ++sentfirst;
+
                        while ((cc = wait_for_reply(rcvsock, from)) != 0) {
                                t2 = monotonic_us();
                                i = packet_ok(packet, cc, from, seq);
                                /* Skip short packet */
                                if (i == 0)
                                        continue;
-                               if (!gotlastaddr ||
-                                   from->sin_addr.s_addr != lastaddr) {
+                               if (!gotlastaddr
+                                || from->sin_addr.s_addr != lastaddr
+                               ) {
                                        print(packet, cc, from);
                                        lastaddr = from->sin_addr.s_addr;
                                        ++gotlastaddr;
@@ -1251,99 +1234,86 @@ int traceroute_main(int argc, char **argv)
                                if (i == -2) {
                                        if (ip->ip_ttl <= 1)
                                                printf(" !");
-                                       ++got_there;
+                                       got_there = 1;
                                        break;
                                }
                                /* time exceeded in transit */
                                if (i == -1)
                                        break;
-                               code = i - 1;
-                               switch (code) {
-
+                               i--;
+                               switch (i) {
                                case ICMP_UNREACH_PORT:
                                        if (ip->ip_ttl <= 1)
                                                printf(" !");
-                                       ++got_there;
+                                       got_there = 1;
                                        break;
-
                                case ICMP_UNREACH_NET:
-                                       ++unreachable;
                                        printf(" !N");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_HOST:
-                                       ++unreachable;
                                        printf(" !H");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_PROTOCOL:
-                                       ++got_there;
                                        printf(" !P");
+                                       got_there = 1;
                                        break;
-
                                case ICMP_UNREACH_NEEDFRAG:
-                                       ++unreachable;
                                        printf(" !F-%d", pmtu);
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_SRCFAIL:
-                                       ++unreachable;
                                        printf(" !S");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_FILTER_PROHIB:
                                case ICMP_UNREACH_NET_PROHIB:   /* misuse */
-                                       ++unreachable;
                                        printf(" !A");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_HOST_PROHIB:
-                                       ++unreachable;
                                        printf(" !C");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_HOST_PRECEDENCE:
-                                       ++unreachable;
                                        printf(" !V");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_PRECEDENCE_CUTOFF:
-                                       ++unreachable;
                                        printf(" !C");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_NET_UNKNOWN:
                                case ICMP_UNREACH_HOST_UNKNOWN:
-                                       ++unreachable;
                                        printf(" !U");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_ISOLATED:
-                                       ++unreachable;
                                        printf(" !I");
+                                       ++unreachable;
                                        break;
-
                                case ICMP_UNREACH_TOSNET:
                                case ICMP_UNREACH_TOSHOST:
-                                       ++unreachable;
                                        printf(" !T");
+                                       ++unreachable;
                                        break;
-
                                default:
+                                       printf(" !<%d>", i);
                                        ++unreachable;
-                                       printf(" !<%d>", code);
                                        break;
                                }
                                break;
                        }
                        if (cc == 0)
-                               printf(" *");
-                       (void)fflush(stdout);
+                               printf("  *");
                }
                bb_putchar('\n');
-               if (got_there ||
-                   (unreachable > 0 && unreachable >= nprobes - 1))
+               if (got_there
+                || (unreachable > 0 && unreachable >= nprobes - 1)
+               ) {
                        break;
+               }
        }
        return 0;
 }