diff options
-rw-r--r-- | networking/traceroute.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c index 2f4d6bb43..1204c5e3a 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -392,7 +392,9 @@ struct globals { | |||
392 | struct outdata_t *outdata; | 392 | struct outdata_t *outdata; |
393 | len_and_sockaddr *dest_lsa; | 393 | len_and_sockaddr *dest_lsa; |
394 | len_and_sockaddr *from_lsa; /* response came from this address */ | 394 | len_and_sockaddr *from_lsa; /* response came from this address */ |
395 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
395 | struct sockaddr *to; /* response came to this (local) address */ | 396 | struct sockaddr *to; /* response came to this (local) address */ |
397 | #endif | ||
396 | uint32_t ident; | 398 | uint32_t ident; |
397 | uint16_t port; /* start udp dest port # for probe packets */ | 399 | uint16_t port; /* start udp dest port # for probe packets */ |
398 | #if ENABLE_TRACEROUTE6 | 400 | #if ENABLE_TRACEROUTE6 |
@@ -463,10 +465,17 @@ wait_for_reply(unsigned *timestamp_us, int *left_ms) | |||
463 | if (*left_ms >= 0 && safe_poll(pfd, 1, *left_ms) > 0) { | 465 | if (*left_ms >= 0 && safe_poll(pfd, 1, *left_ms) > 0) { |
464 | unsigned t; | 466 | unsigned t; |
465 | 467 | ||
468 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
466 | read_len = recv_from_to(rcvsock, | 469 | read_len = recv_from_to(rcvsock, |
467 | recv_pkt, sizeof(recv_pkt), | 470 | recv_pkt, sizeof(recv_pkt), |
468 | /*flags:*/ MSG_DONTWAIT, | 471 | /*flags:*/ MSG_DONTWAIT, |
469 | &G.from_lsa->u.sa, G.to, G.from_lsa->len); | 472 | &G.from_lsa->u.sa, G.to, G.from_lsa->len); |
473 | #else | ||
474 | read_len = recvfrom(rcvsock, | ||
475 | recv_pkt, sizeof(recv_pkt), | ||
476 | /*flags:*/ MSG_DONTWAIT, | ||
477 | &G.from_lsa->u.sa, &G.from_lsa->len); | ||
478 | #endif | ||
470 | if (read_len < 0) | 479 | if (read_len < 0) |
471 | bb_perror_msg_and_die("recv"); | 480 | bb_perror_msg_and_die("recv"); |
472 | t = monotonic_us(); | 481 | t = monotonic_us(); |
@@ -724,6 +733,12 @@ packet6_ok(int read_len, int seq) | |||
724 | * return only ICMP packet (IOW: they strip IPv6 header). | 733 | * return only ICMP packet (IOW: they strip IPv6 header). |
725 | * This differs from (AF_INET, SOCK_RAW, IPPROTO_ICMP) sockets!? | 734 | * This differs from (AF_INET, SOCK_RAW, IPPROTO_ICMP) sockets!? |
726 | */ | 735 | */ |
736 | if (read_len < ICMP_MINLEN) { | ||
737 | if (verbose) | ||
738 | printf("packet too short (%d bytes) from %s\n", read_len, | ||
739 | auto_string(xmalloc_sockaddr2dotted_noport(&G.from_lsa->u.sa))); | ||
740 | return 0; | ||
741 | } | ||
727 | icp = (struct icmp6_hdr *) recv_pkt; | 742 | icp = (struct icmp6_hdr *) recv_pkt; |
728 | 743 | ||
729 | type = icp->icmp6_type; | 744 | type = icp->icmp6_type; |
@@ -789,7 +804,12 @@ packet_ok(int read_len, int seq) | |||
789 | #endif | 804 | #endif |
790 | 805 | ||
791 | static void | 806 | static void |
807 | #if !ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
808 | print(void) | ||
809 | # define print(len) print() | ||
810 | #else | ||
792 | print(int read_len) | 811 | print(int read_len) |
812 | #endif | ||
793 | { | 813 | { |
794 | char *ina = auto_string(xmalloc_sockaddr2dotted_noport(&G.from_lsa->u.sa)); | 814 | char *ina = auto_string(xmalloc_sockaddr2dotted_noport(&G.from_lsa->u.sa)); |
795 | 815 | ||
@@ -806,8 +826,9 @@ print(int read_len) | |||
806 | printf(" %s (%s)", (n ? n : ina), ina); | 826 | printf(" %s (%s)", (n ? n : ina), ina); |
807 | } | 827 | } |
808 | 828 | ||
829 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
809 | if (verbose) { | 830 | if (verbose) { |
810 | #if ENABLE_TRACEROUTE6 | 831 | # if ENABLE_TRACEROUTE6 |
811 | /* NB: reads from (AF_INET, SOCK_RAW, IPPROTO_ICMP) socket | 832 | /* NB: reads from (AF_INET, SOCK_RAW, IPPROTO_ICMP) socket |
812 | * return the entire IP packet (IOW: they do not strip IP header). | 833 | * return the entire IP packet (IOW: they do not strip IP header). |
813 | * Reads from (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) do strip IPv6 | 834 | * Reads from (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) do strip IPv6 |
@@ -816,7 +837,7 @@ print(int read_len) | |||
816 | if (G_ipv6) { | 837 | if (G_ipv6) { |
817 | /* read_len -= sizeof(struct ip6_hdr); - WRONG! */ | 838 | /* read_len -= sizeof(struct ip6_hdr); - WRONG! */ |
818 | } else | 839 | } else |
819 | #endif | 840 | # endif |
820 | { | 841 | { |
821 | struct ip *ip4packet = (struct ip*)recv_pkt; | 842 | struct ip *ip4packet = (struct ip*)recv_pkt; |
822 | read_len -= ip4packet->ip_hl << 2; | 843 | read_len -= ip4packet->ip_hl << 2; |
@@ -825,6 +846,7 @@ print(int read_len) | |||
825 | auto_string(xmalloc_sockaddr2dotted_noport(G.to)) | 846 | auto_string(xmalloc_sockaddr2dotted_noport(G.to)) |
826 | ); | 847 | ); |
827 | } | 848 | } |
849 | #endif | ||
828 | } | 850 | } |
829 | 851 | ||
830 | static void | 852 | static void |
@@ -925,20 +947,26 @@ traceroute_init(int op, char **argv) | |||
925 | dest_lsa = xhost_and_af2sockaddr(argv[0], port, AF_INET); | 947 | dest_lsa = xhost_and_af2sockaddr(argv[0], port, AF_INET); |
926 | #endif | 948 | #endif |
927 | G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len); | 949 | G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len); |
950 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
928 | G.to = xzalloc(dest_lsa->len); | 951 | G.to = xzalloc(dest_lsa->len); |
952 | #endif | ||
929 | if (argv[1]) | 953 | if (argv[1]) |
930 | packlen = xatoul_range(argv[1], packlen, 32 * 1024); | 954 | packlen = xatoul_range(argv[1], packlen, 32 * 1024); |
931 | 955 | ||
932 | if (af == AF_INET) { | 956 | if (af == AF_INET) { |
933 | xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), rcvsock); | 957 | xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), rcvsock); |
958 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
934 | /* want recvmsg to report target local address (for -v) */ | 959 | /* want recvmsg to report target local address (for -v) */ |
935 | setsockopt_1(rcvsock, IPPROTO_IP, IP_PKTINFO); | 960 | setsockopt_1(rcvsock, IPPROTO_IP, IP_PKTINFO); |
961 | #endif | ||
936 | } | 962 | } |
937 | #if ENABLE_TRACEROUTE6 | 963 | #if ENABLE_TRACEROUTE6 |
938 | else { | 964 | else { |
939 | xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); | 965 | xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); |
966 | # if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
940 | /* want recvmsg to report target local address (for -v) */ | 967 | /* want recvmsg to report target local address (for -v) */ |
941 | setsockopt_1(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO); | 968 | setsockopt_1(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO); |
969 | # endif | ||
942 | } | 970 | } |
943 | #endif | 971 | #endif |
944 | #if TRACEROUTE_SO_DEBUG | 972 | #if TRACEROUTE_SO_DEBUG |
@@ -1231,7 +1259,9 @@ common_traceroute_main(int op, char **argv) | |||
1231 | } | 1259 | } |
1232 | 1260 | ||
1233 | if (ENABLE_FEATURE_CLEAN_UP) { | 1261 | if (ENABLE_FEATURE_CLEAN_UP) { |
1262 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | ||
1234 | free(G.to); | 1263 | free(G.to); |
1264 | #endif | ||
1235 | free(lastaddr); | 1265 | free(lastaddr); |
1236 | free(G.from_lsa); | 1266 | free(G.from_lsa); |
1237 | } | 1267 | } |