traceroute: cleanup and fixes for packet size calculations
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 28 Sep 2016 16:39:06 +0000 (18:39 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 28 Sep 2016 16:44:48 +0000 (18:44 +0200)
Remove FEATURE_TRACEROUTE_SOURCE_ROUTE: it's off by default, and
source routing is not used in real world.

Tested that "traceroute -n ::1 100" and "traceroute -n 127.0.0.1 100"
both send 100 byte IP packets (this matches what traceroute on Fedora
Rawhide is doing).

function                                             old     new   delta
common_traceroute_main                              3731    3738      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
configs/TEST_nommu_defconfig
configs/TEST_noprintf_defconfig
configs/TEST_rh9_defconfig
configs/android2_defconfig
configs/android_502_defconfig
configs/android_defconfig
configs/android_ndk_defconfig
configs/cygwin_defconfig
configs/freebsd_defconfig
networking/Config.src
networking/traceroute.c

index 5f822e59821d682752bea6be66566388a43125a7..20c2e1550a6c07945c2dd457b0be3ff7a37c53a7 100644 (file)
@@ -760,7 +760,6 @@ CONFIG_TFTP_DEBUG=y
 CONFIG_TRACEROUTE=y
 CONFIG_TRACEROUTE6=y
 CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
 CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
 CONFIG_UDHCPD=y
 CONFIG_DHCPRELAY=y
index c56781e32faf5dbe6dc88aff62a45483f4e954da..845032ea17ac17de610ee8a1d1c803a5d3896346 100644 (file)
@@ -762,7 +762,6 @@ CONFIG_IFUPDOWN_IFSTATE_PATH=""
 # CONFIG_TRACEROUTE is not set
 # CONFIG_TRACEROUTE6 is not set
 # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 # CONFIG_TUNCTL is not set
 # CONFIG_FEATURE_TUNCTL_UG is not set
index 28daa627325dd8468ec1411dfde98c6986f42540..d8c5af4f75e06b9c20693e94fb71b79976901a3a 100644 (file)
@@ -778,7 +778,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
 CONFIG_TRACEROUTE=y
 CONFIG_TRACEROUTE6=y
 CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 CONFIG_TUNCTL=y
 CONFIG_FEATURE_TUNCTL_UG=y
index fbc0da091cc0a9d2b6d819200e9f434984434049..857f9f5df26e5e8337c2e09f31b74f2a2a79a533 100644 (file)
@@ -814,7 +814,6 @@ CONFIG_TCPSVD=y
 # CONFIG_TRACEROUTE is not set
 # CONFIG_TRACEROUTE6 is not set
 # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 CONFIG_TUNCTL=y
 CONFIG_FEATURE_TUNCTL_UG=y
index 7ef1585fb75ab131bd5540e825f6dddb22c5e5c8..cd06affabce34828cbe5c91ecea82bf46a2277f8 100644 (file)
@@ -959,7 +959,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
 CONFIG_TRACEROUTE=y
 CONFIG_TRACEROUTE6=y
 CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 CONFIG_TUNCTL=y
 CONFIG_FEATURE_TUNCTL_UG=y
index 4e0224207eace522bd73bead0cc09f8506d301bf..f1ddc45d41243353c8e5bc11bdb1fd1aa141d260 100644 (file)
@@ -843,7 +843,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
 CONFIG_TRACEROUTE=y
 # CONFIG_TRACEROUTE6 is not set
 CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 CONFIG_TUNCTL=y
 CONFIG_FEATURE_TUNCTL_UG=y
index d657d33e94db00f93062857ca240b491e19b9cb4..18651fd7cb70f75286a1999ca7ec2cb1cb65bebf 100644 (file)
@@ -869,7 +869,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
 CONFIG_TRACEROUTE=y
 # CONFIG_TRACEROUTE6 is not set
 CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 CONFIG_TUNCTL=y
 CONFIG_FEATURE_TUNCTL_UG=y
index 38d580ad114e0d08515af68379f29cebef35af8d..dd7c21edb3ff841bd1e7de9796ed90b675ddc90f 100644 (file)
@@ -814,7 +814,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
 # CONFIG_TRACEROUTE is not set
 # CONFIG_TRACEROUTE6 is not set
 # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 # CONFIG_TUNCTL is not set
 # CONFIG_FEATURE_TUNCTL_UG is not set
index ae62f13898ca7c0cc97940a2702d2663c31a43a2..265ab13078df9d77ae8ac04dd49bb299141a0bf2 100644 (file)
@@ -795,7 +795,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
 # CONFIG_TRACEROUTE is not set
 # CONFIG_TRACEROUTE6 is not set
 # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
 # CONFIG_TUNCTL is not set
 # CONFIG_FEATURE_TUNCTL_UG is not set
index 27c604a31698483bbdc03592a0cf1ef33ab5b867..eb0536a7c9302bdae684411b83e4b0119261b517 100644 (file)
@@ -912,17 +912,9 @@ config FEATURE_TRACEROUTE_VERBOSE
          Add some verbosity to traceroute. This includes among other things
          hostnames and ICMP response types.
 
-config FEATURE_TRACEROUTE_SOURCE_ROUTE
-       bool "Enable loose source route"
-       default n
-       depends on TRACEROUTE
-       help
-         Add option to specify a loose source route gateway
-         (8 maximum).
-
 config FEATURE_TRACEROUTE_USE_ICMP
-       bool "Use ICMP instead of UDP"
-       default n
+       bool "Enable -I option (use ICMP instead of UDP)"
+       default y
        depends on TRACEROUTE
        help
          Add option -I to use ICMP ECHO instead of UDP datagrams.
index e43a36dc7b5464d04172f89d9e12db5bb59f0234..b9a9ca4bb47d16341b5bdcf054c0f2436bab5c2a 100644 (file)
 
 //usage:#define traceroute_trivial_usage
 //usage:       "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n"
-//usage:       "       [-t TOS] [-w WAIT_SEC]"
-//usage:       IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n"
+//usage:       "       [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n"
 //usage:       "       [-z PAUSE_MSEC] HOST [BYTES]"
 //usage:#define traceroute_full_usage "\n\n"
 //usage:       "Trace the route to HOST\n"
 
 #define OPT_STRING \
        "FIlnrdvxt:i:m:p:q:s:w:z:f:" \
-       IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \
        "4" IF_TRACEROUTE6("6")
 enum {
        OPT_DONT_FRAGMNT = (1 << 0),    /* F */
@@ -314,9 +312,8 @@ enum {
        OPT_WAITTIME     = (1 << 14),   /* w */
        OPT_PAUSE_MS     = (1 << 15),   /* z */
        OPT_FIRST_TTL    = (1 << 16),   /* f */
-       OPT_SOURCE_ROUTE = (1 << 17) * ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE, /* g */
-       OPT_IPV4         = (1 << (17+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)),   /* 4 */
-       OPT_IPV6         = (1 << (18+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)) * ENABLE_TRACEROUTE6, /* 6 */
+       OPT_IPV4         = (1 << 17),   /* 4 */
+       OPT_IPV6         = (1 << 18) * ENABLE_TRACEROUTE6, /* 6 */
 };
 #define verbose (option_mask32 & OPT_VERBOSE)
 
@@ -343,26 +340,18 @@ struct outdata6_t {
 #endif
 
 struct globals {
+       /* Pointer to entire malloced IP packet, "packlen" bytes long: */
        struct ip *outip;
+       /* Pointer to ICMP or UDP payload (not header): */
        struct outdata_t *outdata;
+
        len_and_sockaddr *dest_lsa;
        int packlen;                    /* total length of packet */
        int pmtu;                       /* Path MTU Discovery (RFC1191) */
        uint32_t ident;
-       uint16_t port; // 32768 + 666;  /* start udp dest port # for probe packets */
+       uint16_t port; // 33434;        /* start udp dest port # for probe packets */
        int waittime; // 5;             /* time to wait for response (in seconds) */
-#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
-       int optlen;                     /* length of ip options */
-#else
-#define optlen 0
-#endif
        unsigned char recv_pkt[512];    /* last inbound (icmp) packet */
-#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)
@@ -374,14 +363,11 @@ struct globals {
 #define ident     (G.ident    )
 #define port      (G.port     )
 #define waittime  (G.waittime )
-#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
-# define optlen   (G.optlen   )
-#endif
 #define recv_pkt  (G.recv_pkt )
 #define gwlist    (G.gwlist   )
 #define INIT_G() do { \
        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
-       port = 32768 + 666; \
+       port = 33434; \
        waittime = 5; \
 } while (0)
 
@@ -421,7 +407,7 @@ send_probe(int seq, int ttl)
        /* Payload */
 #if ENABLE_TRACEROUTE6
        if (dest_lsa->u.sa.sa_family == AF_INET6) {
-               struct outdata6_t *pkt = (struct outdata6_t *) outip;
+               struct outdata6_t *pkt = (struct outdata6_t *) outdata;
                pkt->ident6 = htonl(ident);
                pkt->seq6   = htonl(seq);
                /*gettimeofday(&pkt->tv, &tz);*/
@@ -438,8 +424,10 @@ send_probe(int seq, int ttl)
 
                        /* Always calculate checksum for icmp packets */
                        outicmp->icmp_cksum = 0;
-                       outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp,
-                                               packlen - (sizeof(*outip) + optlen));
+                       outicmp->icmp_cksum = inet_cksum(
+                                       (uint16_t *)outicmp,
+                                       ((char*)outip + packlen) - (char*)outicmp
+                       );
                        if (outicmp->icmp_cksum == 0)
                                outicmp->icmp_cksum = 0xffff;
                }
@@ -471,13 +459,12 @@ send_probe(int seq, int ttl)
        }
 #endif
 
+       out = outdata;
 #if ENABLE_TRACEROUTE6
        if (dest_lsa->u.sa.sa_family == AF_INET6) {
                res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl);
                if (res != 0)
                        bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl);
-               out = outip;
-               len = packlen;
        } else
 #endif
        {
@@ -486,15 +473,14 @@ send_probe(int seq, int ttl)
                if (res != 0)
                        bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl);
 #endif
-               out = outicmp;
-               len = packlen - sizeof(*outip);
-               if (!(option_mask32 & OPT_USE_ICMP)) {
-                       out = outdata;
-                       len -= sizeof(*outudp);
-                       set_nport(&dest_lsa->u.sa, htons(port + seq));
-               }
+               if (option_mask32 & OPT_USE_ICMP)
+                       out = outicmp;
        }
 
+       if (!(option_mask32 & OPT_USE_ICMP)) {
+               set_nport(&dest_lsa->u.sa, htons(port + seq));
+       }
+       len = ((char*)outip + packlen) - (char*)out;
        res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len);
        if (res != len)
                bb_error_msg("sent %d octets, ret=%d", len, res);
@@ -801,10 +787,6 @@ common_traceroute_main(int op, char **argv)
        char *pausemsecs_str;
        char *first_ttl_str;
        char *dest_str;
-#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
-       llist_t *source_route_list = NULL;
-       int lsrr = 0;
-#endif
 #if ENABLE_TRACEROUTE6
        sa_family_t af;
 #else
@@ -823,9 +805,6 @@ common_traceroute_main(int op, char **argv)
        op |= getopt32(argv, OPT_STRING
                , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
                , &source, &waittime_str, &pausemsecs_str, &first_ttl_str
-#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
-               , &source_route_list
-#endif
        );
        argv += optind;
 
@@ -858,26 +837,14 @@ common_traceroute_main(int op, char **argv)
        if (op & OPT_FIRST_TTL)
                first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
 
-#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
-       if (source_route_list) {
-               while (source_route_list) {
-                       len_and_sockaddr *lsa;
-
-                       if (lsrr >= NGATEWAYS)
-                               bb_error_msg_and_die("no more than %d gateways", NGATEWAYS);
-                       lsa = xhost_and_af2sockaddr(llist_pop(&source_route_list), 0, AF_INET);
-                       gwlist[lsrr] = lsa->u.sin.sin_addr.s_addr;
-                       free(lsa);
-                       ++lsrr;
-               }
-               optlen = (lsrr + 1) * sizeof(gwlist[0]);
-       }
-#endif
-
        /* Process destination and optional packet size */
-       minpacket = sizeof(*outip) + SIZEOF_ICMP_HDR + sizeof(*outdata) + optlen;
+       minpacket = sizeof(struct ip)
+                       + SIZEOF_ICMP_HDR
+                       + sizeof(struct outdata_t);
        if (!(op & OPT_USE_ICMP))
-               minpacket += sizeof(*outudp) - SIZEOF_ICMP_HDR;
+               minpacket = sizeof(struct ip)
+                       + sizeof(struct udphdr)
+                       + sizeof(struct outdata_t);
 #if ENABLE_TRACEROUTE6
        af = AF_UNSPEC;
        if (op & OPT_IPV4)
@@ -887,7 +854,9 @@ common_traceroute_main(int op, char **argv)
        dest_lsa = xhost_and_af2sockaddr(argv[0], port, af);
        af = dest_lsa->u.sa.sa_family;
        if (af == AF_INET6)
-               minpacket = sizeof(struct outdata6_t);
+               minpacket = sizeof(struct ip6_hdr)
+                       + sizeof(struct udphdr)
+                       + sizeof(struct outdata6_t);
 #else
        dest_lsa = xhost2sockaddr(argv[0], port);
 #endif
@@ -932,31 +901,6 @@ common_traceroute_main(int op, char **argv)
                        xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock);
                else
                        xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock);
-#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS
-               if (lsrr > 0) {
-                       unsigned char optlist[MAX_IPOPTLEN];
-                       unsigned size;
-
-                       /* final hop */
-                       gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr;
-                       ++lsrr;
-
-                       /* force 4 byte alignment */
-                       optlist[0] = IPOPT_NOP;
-                       /* loose source route option */
-                       optlist[1] = IPOPT_LSRR;
-                       size = lsrr * sizeof(gwlist[0]);
-                       optlist[2] = size + 3;
-                       /* pointer to LSRR addresses */
-                       optlist[3] = IPOPT_MINOFF;
-                       memcpy(optlist + 4, gwlist, size);
-
-                       if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
-                                       (char *)optlist, size + sizeof(gwlist[0])) < 0) {
-                               bb_perror_msg_and_die("IP_OPTIONS");
-                       }
-               }
-#endif
        }
 
 #ifdef SO_SNDBUF
@@ -984,7 +928,7 @@ common_traceroute_main(int op, char **argv)
 
        ident = getpid();
 
-       if (af == AF_INET) {
+       if (!ENABLE_TRACEROUTE6 || af == AF_INET) {
                if (op & OPT_USE_ICMP) {
                        ident |= 0x8000;
                        outicmp->icmp_type = ICMP_ECHO;
@@ -994,6 +938,14 @@ common_traceroute_main(int op, char **argv)
                        outdata = (struct outdata_t *)(outudp + 1);
                }
        }
+#if ENABLE_TRACEROUTE6
+       if (af == AF_INET6) {
+               outdata = (void*)((char*)outip
+                               + sizeof(struct ip6_hdr)
+                               + sizeof(struct udphdr)
+                               );
+       }
+#endif
 
        if (op & OPT_DEVICE) /* hmm, do we need error check? */
                setsockopt_bindtodevice(sndsock, device);