aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-09-28 18:39:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-09-28 18:44:48 +0200
commit1c32e49bdf74dfe47cae108d06702996ead052f0 (patch)
tree129680cd72ef41bb9a64a3ca0edd2634cf430d1c
parent61fcc8c78174f92fbdad0a7f86b5086619b05ed9 (diff)
downloadbusybox-w32-1c32e49bdf74dfe47cae108d06702996ead052f0.tar.gz
busybox-w32-1c32e49bdf74dfe47cae108d06702996ead052f0.tar.bz2
busybox-w32-1c32e49bdf74dfe47cae108d06702996ead052f0.zip
traceroute: cleanup and fixes for packet size calculations
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>
-rw-r--r--configs/TEST_nommu_defconfig1
-rw-r--r--configs/TEST_noprintf_defconfig1
-rw-r--r--configs/TEST_rh9_defconfig1
-rw-r--r--configs/android2_defconfig1
-rw-r--r--configs/android_502_defconfig1
-rw-r--r--configs/android_defconfig1
-rw-r--r--configs/android_ndk_defconfig1
-rw-r--r--configs/cygwin_defconfig1
-rw-r--r--configs/freebsd_defconfig1
-rw-r--r--networking/Config.src12
-rw-r--r--networking/traceroute.c124
11 files changed, 40 insertions, 105 deletions
diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig
index 5f822e598..20c2e1550 100644
--- a/configs/TEST_nommu_defconfig
+++ b/configs/TEST_nommu_defconfig
@@ -760,7 +760,6 @@ CONFIG_TFTP_DEBUG=y
760CONFIG_TRACEROUTE=y 760CONFIG_TRACEROUTE=y
761CONFIG_TRACEROUTE6=y 761CONFIG_TRACEROUTE6=y
762CONFIG_FEATURE_TRACEROUTE_VERBOSE=y 762CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
763CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
764CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y 763CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
765CONFIG_UDHCPD=y 764CONFIG_UDHCPD=y
766CONFIG_DHCPRELAY=y 765CONFIG_DHCPRELAY=y
diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig
index c56781e32..845032ea1 100644
--- a/configs/TEST_noprintf_defconfig
+++ b/configs/TEST_noprintf_defconfig
@@ -762,7 +762,6 @@ CONFIG_IFUPDOWN_IFSTATE_PATH=""
762# CONFIG_TRACEROUTE is not set 762# CONFIG_TRACEROUTE is not set
763# CONFIG_TRACEROUTE6 is not set 763# CONFIG_TRACEROUTE6 is not set
764# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 764# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
765# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
766# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 765# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
767# CONFIG_TUNCTL is not set 766# CONFIG_TUNCTL is not set
768# CONFIG_FEATURE_TUNCTL_UG is not set 767# CONFIG_FEATURE_TUNCTL_UG is not set
diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig
index 28daa6273..d8c5af4f7 100644
--- a/configs/TEST_rh9_defconfig
+++ b/configs/TEST_rh9_defconfig
@@ -778,7 +778,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
778CONFIG_TRACEROUTE=y 778CONFIG_TRACEROUTE=y
779CONFIG_TRACEROUTE6=y 779CONFIG_TRACEROUTE6=y
780CONFIG_FEATURE_TRACEROUTE_VERBOSE=y 780CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
781# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
782# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 781# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
783CONFIG_TUNCTL=y 782CONFIG_TUNCTL=y
784CONFIG_FEATURE_TUNCTL_UG=y 783CONFIG_FEATURE_TUNCTL_UG=y
diff --git a/configs/android2_defconfig b/configs/android2_defconfig
index fbc0da091..857f9f5df 100644
--- a/configs/android2_defconfig
+++ b/configs/android2_defconfig
@@ -814,7 +814,6 @@ CONFIG_TCPSVD=y
814# CONFIG_TRACEROUTE is not set 814# CONFIG_TRACEROUTE is not set
815# CONFIG_TRACEROUTE6 is not set 815# CONFIG_TRACEROUTE6 is not set
816# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 816# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
817# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
818# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 817# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
819CONFIG_TUNCTL=y 818CONFIG_TUNCTL=y
820CONFIG_FEATURE_TUNCTL_UG=y 819CONFIG_FEATURE_TUNCTL_UG=y
diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig
index 7ef1585fb..cd06affab 100644
--- a/configs/android_502_defconfig
+++ b/configs/android_502_defconfig
@@ -959,7 +959,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
959CONFIG_TRACEROUTE=y 959CONFIG_TRACEROUTE=y
960CONFIG_TRACEROUTE6=y 960CONFIG_TRACEROUTE6=y
961CONFIG_FEATURE_TRACEROUTE_VERBOSE=y 961CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
962# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
963# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 962# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
964CONFIG_TUNCTL=y 963CONFIG_TUNCTL=y
965CONFIG_FEATURE_TUNCTL_UG=y 964CONFIG_FEATURE_TUNCTL_UG=y
diff --git a/configs/android_defconfig b/configs/android_defconfig
index 4e0224207..f1ddc45d4 100644
--- a/configs/android_defconfig
+++ b/configs/android_defconfig
@@ -843,7 +843,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
843CONFIG_TRACEROUTE=y 843CONFIG_TRACEROUTE=y
844# CONFIG_TRACEROUTE6 is not set 844# CONFIG_TRACEROUTE6 is not set
845CONFIG_FEATURE_TRACEROUTE_VERBOSE=y 845CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
846# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
847# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 846# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
848CONFIG_TUNCTL=y 847CONFIG_TUNCTL=y
849CONFIG_FEATURE_TUNCTL_UG=y 848CONFIG_FEATURE_TUNCTL_UG=y
diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig
index d657d33e9..18651fd7c 100644
--- a/configs/android_ndk_defconfig
+++ b/configs/android_ndk_defconfig
@@ -869,7 +869,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
869CONFIG_TRACEROUTE=y 869CONFIG_TRACEROUTE=y
870# CONFIG_TRACEROUTE6 is not set 870# CONFIG_TRACEROUTE6 is not set
871CONFIG_FEATURE_TRACEROUTE_VERBOSE=y 871CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
872# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
873# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 872# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
874CONFIG_TUNCTL=y 873CONFIG_TUNCTL=y
875CONFIG_FEATURE_TUNCTL_UG=y 874CONFIG_FEATURE_TUNCTL_UG=y
diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig
index 38d580ad1..dd7c21edb 100644
--- a/configs/cygwin_defconfig
+++ b/configs/cygwin_defconfig
@@ -814,7 +814,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
814# CONFIG_TRACEROUTE is not set 814# CONFIG_TRACEROUTE is not set
815# CONFIG_TRACEROUTE6 is not set 815# CONFIG_TRACEROUTE6 is not set
816# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 816# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
817# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
818# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 817# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
819# CONFIG_TUNCTL is not set 818# CONFIG_TUNCTL is not set
820# CONFIG_FEATURE_TUNCTL_UG is not set 819# CONFIG_FEATURE_TUNCTL_UG is not set
diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig
index ae62f1389..265ab1307 100644
--- a/configs/freebsd_defconfig
+++ b/configs/freebsd_defconfig
@@ -795,7 +795,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y
795# CONFIG_TRACEROUTE is not set 795# CONFIG_TRACEROUTE is not set
796# CONFIG_TRACEROUTE6 is not set 796# CONFIG_TRACEROUTE6 is not set
797# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 797# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
798# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
799# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 798# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
800# CONFIG_TUNCTL is not set 799# CONFIG_TUNCTL is not set
801# CONFIG_FEATURE_TUNCTL_UG is not set 800# CONFIG_FEATURE_TUNCTL_UG is not set
diff --git a/networking/Config.src b/networking/Config.src
index 27c604a31..eb0536a7c 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -912,17 +912,9 @@ config FEATURE_TRACEROUTE_VERBOSE
912 Add some verbosity to traceroute. This includes among other things 912 Add some verbosity to traceroute. This includes among other things
913 hostnames and ICMP response types. 913 hostnames and ICMP response types.
914 914
915config FEATURE_TRACEROUTE_SOURCE_ROUTE
916 bool "Enable loose source route"
917 default n
918 depends on TRACEROUTE
919 help
920 Add option to specify a loose source route gateway
921 (8 maximum).
922
923config FEATURE_TRACEROUTE_USE_ICMP 915config FEATURE_TRACEROUTE_USE_ICMP
924 bool "Use ICMP instead of UDP" 916 bool "Enable -I option (use ICMP instead of UDP)"
925 default n 917 default y
926 depends on TRACEROUTE 918 depends on TRACEROUTE
927 help 919 help
928 Add option -I to use ICMP ECHO instead of UDP datagrams. 920 Add option -I to use ICMP ECHO instead of UDP datagrams.
diff --git a/networking/traceroute.c b/networking/traceroute.c
index e43a36dc7..b9a9ca4bb 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -212,8 +212,7 @@
212 212
213//usage:#define traceroute_trivial_usage 213//usage:#define traceroute_trivial_usage
214//usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" 214//usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n"
215//usage: " [-t TOS] [-w WAIT_SEC]" 215//usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n"
216//usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n"
217//usage: " [-z PAUSE_MSEC] HOST [BYTES]" 216//usage: " [-z PAUSE_MSEC] HOST [BYTES]"
218//usage:#define traceroute_full_usage "\n\n" 217//usage:#define traceroute_full_usage "\n\n"
219//usage: "Trace the route to HOST\n" 218//usage: "Trace the route to HOST\n"
@@ -294,7 +293,6 @@
294 293
295#define OPT_STRING \ 294#define OPT_STRING \
296 "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ 295 "FIlnrdvxt:i:m:p:q:s:w:z:f:" \
297 IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \
298 "4" IF_TRACEROUTE6("6") 296 "4" IF_TRACEROUTE6("6")
299enum { 297enum {
300 OPT_DONT_FRAGMNT = (1 << 0), /* F */ 298 OPT_DONT_FRAGMNT = (1 << 0), /* F */
@@ -314,9 +312,8 @@ enum {
314 OPT_WAITTIME = (1 << 14), /* w */ 312 OPT_WAITTIME = (1 << 14), /* w */
315 OPT_PAUSE_MS = (1 << 15), /* z */ 313 OPT_PAUSE_MS = (1 << 15), /* z */
316 OPT_FIRST_TTL = (1 << 16), /* f */ 314 OPT_FIRST_TTL = (1 << 16), /* f */
317 OPT_SOURCE_ROUTE = (1 << 17) * ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE, /* g */ 315 OPT_IPV4 = (1 << 17), /* 4 */
318 OPT_IPV4 = (1 << (17+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)), /* 4 */ 316 OPT_IPV6 = (1 << 18) * ENABLE_TRACEROUTE6, /* 6 */
319 OPT_IPV6 = (1 << (18+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)) * ENABLE_TRACEROUTE6, /* 6 */
320}; 317};
321#define verbose (option_mask32 & OPT_VERBOSE) 318#define verbose (option_mask32 & OPT_VERBOSE)
322 319
@@ -343,26 +340,18 @@ struct outdata6_t {
343#endif 340#endif
344 341
345struct globals { 342struct globals {
343 /* Pointer to entire malloced IP packet, "packlen" bytes long: */
346 struct ip *outip; 344 struct ip *outip;
345 /* Pointer to ICMP or UDP payload (not header): */
347 struct outdata_t *outdata; 346 struct outdata_t *outdata;
347
348 len_and_sockaddr *dest_lsa; 348 len_and_sockaddr *dest_lsa;
349 int packlen; /* total length of packet */ 349 int packlen; /* total length of packet */
350 int pmtu; /* Path MTU Discovery (RFC1191) */ 350 int pmtu; /* Path MTU Discovery (RFC1191) */
351 uint32_t ident; 351 uint32_t ident;
352 uint16_t port; // 32768 + 666; /* start udp dest port # for probe packets */ 352 uint16_t port; // 33434; /* start udp dest port # for probe packets */
353 int waittime; // 5; /* time to wait for response (in seconds) */ 353 int waittime; // 5; /* time to wait for response (in seconds) */
354#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
355 int optlen; /* length of ip options */
356#else
357#define optlen 0
358#endif
359 unsigned char recv_pkt[512]; /* last inbound (icmp) packet */ 354 unsigned char recv_pkt[512]; /* last inbound (icmp) packet */
360#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
361 /* Maximum number of gateways (include room for one noop) */
362#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(uint32_t)))
363 /* loose source route gateway list (including room for final destination) */
364 uint32_t gwlist[NGATEWAYS + 1];
365#endif
366}; 355};
367 356
368#define G (*ptr_to_globals) 357#define G (*ptr_to_globals)
@@ -374,14 +363,11 @@ struct globals {
374#define ident (G.ident ) 363#define ident (G.ident )
375#define port (G.port ) 364#define port (G.port )
376#define waittime (G.waittime ) 365#define waittime (G.waittime )
377#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
378# define optlen (G.optlen )
379#endif
380#define recv_pkt (G.recv_pkt ) 366#define recv_pkt (G.recv_pkt )
381#define gwlist (G.gwlist ) 367#define gwlist (G.gwlist )
382#define INIT_G() do { \ 368#define INIT_G() do { \
383 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 369 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
384 port = 32768 + 666; \ 370 port = 33434; \
385 waittime = 5; \ 371 waittime = 5; \
386} while (0) 372} while (0)
387 373
@@ -421,7 +407,7 @@ send_probe(int seq, int ttl)
421 /* Payload */ 407 /* Payload */
422#if ENABLE_TRACEROUTE6 408#if ENABLE_TRACEROUTE6
423 if (dest_lsa->u.sa.sa_family == AF_INET6) { 409 if (dest_lsa->u.sa.sa_family == AF_INET6) {
424 struct outdata6_t *pkt = (struct outdata6_t *) outip; 410 struct outdata6_t *pkt = (struct outdata6_t *) outdata;
425 pkt->ident6 = htonl(ident); 411 pkt->ident6 = htonl(ident);
426 pkt->seq6 = htonl(seq); 412 pkt->seq6 = htonl(seq);
427 /*gettimeofday(&pkt->tv, &tz);*/ 413 /*gettimeofday(&pkt->tv, &tz);*/
@@ -438,8 +424,10 @@ send_probe(int seq, int ttl)
438 424
439 /* Always calculate checksum for icmp packets */ 425 /* Always calculate checksum for icmp packets */
440 outicmp->icmp_cksum = 0; 426 outicmp->icmp_cksum = 0;
441 outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp, 427 outicmp->icmp_cksum = inet_cksum(
442 packlen - (sizeof(*outip) + optlen)); 428 (uint16_t *)outicmp,
429 ((char*)outip + packlen) - (char*)outicmp
430 );
443 if (outicmp->icmp_cksum == 0) 431 if (outicmp->icmp_cksum == 0)
444 outicmp->icmp_cksum = 0xffff; 432 outicmp->icmp_cksum = 0xffff;
445 } 433 }
@@ -471,13 +459,12 @@ send_probe(int seq, int ttl)
471 } 459 }
472#endif 460#endif
473 461
462 out = outdata;
474#if ENABLE_TRACEROUTE6 463#if ENABLE_TRACEROUTE6
475 if (dest_lsa->u.sa.sa_family == AF_INET6) { 464 if (dest_lsa->u.sa.sa_family == AF_INET6) {
476 res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); 465 res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl);
477 if (res != 0) 466 if (res != 0)
478 bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); 467 bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl);
479 out = outip;
480 len = packlen;
481 } else 468 } else
482#endif 469#endif
483 { 470 {
@@ -486,15 +473,14 @@ send_probe(int seq, int ttl)
486 if (res != 0) 473 if (res != 0)
487 bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); 474 bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl);
488#endif 475#endif
489 out = outicmp; 476 if (option_mask32 & OPT_USE_ICMP)
490 len = packlen - sizeof(*outip); 477 out = outicmp;
491 if (!(option_mask32 & OPT_USE_ICMP)) {
492 out = outdata;
493 len -= sizeof(*outudp);
494 set_nport(&dest_lsa->u.sa, htons(port + seq));
495 }
496 } 478 }
497 479
480 if (!(option_mask32 & OPT_USE_ICMP)) {
481 set_nport(&dest_lsa->u.sa, htons(port + seq));
482 }
483 len = ((char*)outip + packlen) - (char*)out;
498 res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); 484 res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len);
499 if (res != len) 485 if (res != len)
500 bb_error_msg("sent %d octets, ret=%d", len, res); 486 bb_error_msg("sent %d octets, ret=%d", len, res);
@@ -801,10 +787,6 @@ common_traceroute_main(int op, char **argv)
801 char *pausemsecs_str; 787 char *pausemsecs_str;
802 char *first_ttl_str; 788 char *first_ttl_str;
803 char *dest_str; 789 char *dest_str;
804#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
805 llist_t *source_route_list = NULL;
806 int lsrr = 0;
807#endif
808#if ENABLE_TRACEROUTE6 790#if ENABLE_TRACEROUTE6
809 sa_family_t af; 791 sa_family_t af;
810#else 792#else
@@ -823,9 +805,6 @@ common_traceroute_main(int op, char **argv)
823 op |= getopt32(argv, OPT_STRING 805 op |= getopt32(argv, OPT_STRING
824 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str 806 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
825 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str 807 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str
826#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
827 , &source_route_list
828#endif
829 ); 808 );
830 argv += optind; 809 argv += optind;
831 810
@@ -858,26 +837,14 @@ common_traceroute_main(int op, char **argv)
858 if (op & OPT_FIRST_TTL) 837 if (op & OPT_FIRST_TTL)
859 first_ttl = xatou_range(first_ttl_str, 1, max_ttl); 838 first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
860 839
861#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
862 if (source_route_list) {
863 while (source_route_list) {
864 len_and_sockaddr *lsa;
865
866 if (lsrr >= NGATEWAYS)
867 bb_error_msg_and_die("no more than %d gateways", NGATEWAYS);
868 lsa = xhost_and_af2sockaddr(llist_pop(&source_route_list), 0, AF_INET);
869 gwlist[lsrr] = lsa->u.sin.sin_addr.s_addr;
870 free(lsa);
871 ++lsrr;
872 }
873 optlen = (lsrr + 1) * sizeof(gwlist[0]);
874 }
875#endif
876
877 /* Process destination and optional packet size */ 840 /* Process destination and optional packet size */
878 minpacket = sizeof(*outip) + SIZEOF_ICMP_HDR + sizeof(*outdata) + optlen; 841 minpacket = sizeof(struct ip)
842 + SIZEOF_ICMP_HDR
843 + sizeof(struct outdata_t);
879 if (!(op & OPT_USE_ICMP)) 844 if (!(op & OPT_USE_ICMP))
880 minpacket += sizeof(*outudp) - SIZEOF_ICMP_HDR; 845 minpacket = sizeof(struct ip)
846 + sizeof(struct udphdr)
847 + sizeof(struct outdata_t);
881#if ENABLE_TRACEROUTE6 848#if ENABLE_TRACEROUTE6
882 af = AF_UNSPEC; 849 af = AF_UNSPEC;
883 if (op & OPT_IPV4) 850 if (op & OPT_IPV4)
@@ -887,7 +854,9 @@ common_traceroute_main(int op, char **argv)
887 dest_lsa = xhost_and_af2sockaddr(argv[0], port, af); 854 dest_lsa = xhost_and_af2sockaddr(argv[0], port, af);
888 af = dest_lsa->u.sa.sa_family; 855 af = dest_lsa->u.sa.sa_family;
889 if (af == AF_INET6) 856 if (af == AF_INET6)
890 minpacket = sizeof(struct outdata6_t); 857 minpacket = sizeof(struct ip6_hdr)
858 + sizeof(struct udphdr)
859 + sizeof(struct outdata6_t);
891#else 860#else
892 dest_lsa = xhost2sockaddr(argv[0], port); 861 dest_lsa = xhost2sockaddr(argv[0], port);
893#endif 862#endif
@@ -932,31 +901,6 @@ common_traceroute_main(int op, char **argv)
932 xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock); 901 xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock);
933 else 902 else
934 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock); 903 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock);
935#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS
936 if (lsrr > 0) {
937 unsigned char optlist[MAX_IPOPTLEN];
938 unsigned size;
939
940 /* final hop */
941 gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr;
942 ++lsrr;
943
944 /* force 4 byte alignment */
945 optlist[0] = IPOPT_NOP;
946 /* loose source route option */
947 optlist[1] = IPOPT_LSRR;
948 size = lsrr * sizeof(gwlist[0]);
949 optlist[2] = size + 3;
950 /* pointer to LSRR addresses */
951 optlist[3] = IPOPT_MINOFF;
952 memcpy(optlist + 4, gwlist, size);
953
954 if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
955 (char *)optlist, size + sizeof(gwlist[0])) < 0) {
956 bb_perror_msg_and_die("IP_OPTIONS");
957 }
958 }
959#endif
960 } 904 }
961 905
962#ifdef SO_SNDBUF 906#ifdef SO_SNDBUF
@@ -984,7 +928,7 @@ common_traceroute_main(int op, char **argv)
984 928
985 ident = getpid(); 929 ident = getpid();
986 930
987 if (af == AF_INET) { 931 if (!ENABLE_TRACEROUTE6 || af == AF_INET) {
988 if (op & OPT_USE_ICMP) { 932 if (op & OPT_USE_ICMP) {
989 ident |= 0x8000; 933 ident |= 0x8000;
990 outicmp->icmp_type = ICMP_ECHO; 934 outicmp->icmp_type = ICMP_ECHO;
@@ -994,6 +938,14 @@ common_traceroute_main(int op, char **argv)
994 outdata = (struct outdata_t *)(outudp + 1); 938 outdata = (struct outdata_t *)(outudp + 1);
995 } 939 }
996 } 940 }
941#if ENABLE_TRACEROUTE6
942 if (af == AF_INET6) {
943 outdata = (void*)((char*)outip
944 + sizeof(struct ip6_hdr)
945 + sizeof(struct udphdr)
946 );
947 }
948#endif
997 949
998 if (op & OPT_DEVICE) /* hmm, do we need error check? */ 950 if (op & OPT_DEVICE) /* hmm, do we need error check? */
999 setsockopt_bindtodevice(sndsock, device); 951 setsockopt_bindtodevice(sndsock, device);