aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-01-24 20:11:36 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-01-24 20:11:36 +0000
commitfa65a3d78f32a305239494b8dc0f8ef14f83465d (patch)
treec9a569eb94741eda1324055150032bb40a2ae449
parent39b681343bee81fb7c31fd06e4dc5343bcef1292 (diff)
downloadbusybox-w32-fa65a3d78f32a305239494b8dc0f8ef14f83465d.tar.gz
busybox-w32-fa65a3d78f32a305239494b8dc0f8ef14f83465d.tar.bz2
busybox-w32-fa65a3d78f32a305239494b8dc0f8ef14f83465d.zip
traceroute: preparatory trivial cleanups
function old new delta traceroute_main 3932 3713 -219
-rw-r--r--libbb/xfuncs_printf.c2
-rw-r--r--networking/traceroute.c218
2 files changed, 95 insertions, 125 deletions
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 46ae7ac60..cd0f84dea 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -440,7 +440,7 @@ void FAST_FUNC xlisten(int s, int backlog)
440 440
441/* Die with an error message if sendto failed. 441/* Die with an error message if sendto failed.
442 * Return bytes sent otherwise */ 442 * Return bytes sent otherwise */
443ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, 443ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
444 socklen_t tolen) 444 socklen_t tolen)
445{ 445{
446 ssize_t ret = sendto(s, buf, len, 0, to, tolen); 446 ssize_t ret = sendto(s, buf, len, 0, to, tolen);
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 5d1baacf5..958299aaa 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -223,11 +223,10 @@
223#define IPVERSION 4 223#define IPVERSION 4
224 224
225#ifndef IPPROTO_ICMP 225#ifndef IPPROTO_ICMP
226/* Grrrr.... */ 226# define IPPROTO_ICMP 1
227#define IPPROTO_ICMP 1
228#endif 227#endif
229#ifndef IPPROTO_IP 228#ifndef IPPROTO_IP
230#define IPPROTO_IP 0 229# define IPPROTO_IP 0
231#endif 230#endif
232 231
233/* 232/*
@@ -482,7 +481,6 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
482 return nipaddr; 481 return nipaddr;
483} 482}
484 483
485
486static void 484static void
487setsin(struct sockaddr_in *addr_sin, uint32_t addr) 485setsin(struct sockaddr_in *addr_sin, uint32_t addr)
488{ 486{
@@ -494,7 +492,6 @@ setsin(struct sockaddr_in *addr_sin, uint32_t addr)
494 addr_sin->sin_addr.s_addr = addr; 492 addr_sin->sin_addr.s_addr = addr;
495} 493}
496 494
497
498/* 495/*
499 * Return the source address for the given destination address 496 * Return the source address for the given destination address
500 */ 497 */
@@ -547,13 +544,6 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
547 setsin(from, al->addr); 544 setsin(from, al->addr);
548} 545}
549 546
550/*
551"Usage: %s [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]\n"
552"\t[-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]\n"
553"\t[-w waittime] [-z pausemsecs] host [packetlen]"
554
555*/
556
557static int 547static int
558wait_for_reply(int sock, struct sockaddr_in *fromp) 548wait_for_reply(int sock, struct sockaddr_in *fromp)
559{ 549{
@@ -581,12 +571,12 @@ in_cksum(uint16_t *addr, int len)
581 int sum = 0; 571 int sum = 0;
582 572
583 /* 573 /*
584 * Our algorithm is simple, using a 32 bit accumulator (sum), 574 * Our algorithm is simple, using a 32 bit accumulator (sum),
585 * we add sequential 16 bit words to it, and at the end, fold 575 * we add sequential 16 bit words to it, and at the end, fold
586 * back all the carry bits from the top 16 bits into the lower 576 * back all the carry bits from the top 16 bits into the lower
587 * 16 bits. 577 * 16 bits.
588 */ 578 */
589 while (nleft > 1) { 579 while (nleft > 1) {
590 sum += *w++; 580 sum += *w++;
591 nleft -= 2; 581 nleft -= 2;
592 } 582 }
@@ -595,16 +585,13 @@ in_cksum(uint16_t *addr, int len)
595 if (nleft == 1) 585 if (nleft == 1)
596 sum += *(unsigned char *)w; 586 sum += *(unsigned char *)w;
597 587
598 /* 588 /* add back carry outs from top 16 bits to low 16 bits */
599 * add back carry outs from top 16 bits to low 16 bits
600 */
601 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 589 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
602 sum += (sum >> 16); /* add carry */ 590 sum += (sum >> 16); /* add carry */
603 answer = ~sum; /* truncate to 16 bits */ 591 answer = ~sum; /* truncate to 16 bits */
604 return answer; 592 return answer;
605} 593}
606 594
607
608static void 595static void
609send_probe(int seq, int ttl) 596send_probe(int seq, int ttl)
610{ 597{
@@ -617,12 +604,10 @@ send_probe(int seq, int ttl)
617 604
618 /* 605 /*
619 * In most cases, the kernel will recalculate the ip checksum. 606 * In most cases, the kernel will recalculate the ip checksum.
620 * But we must do it anyway so that the udp checksum comes out 607 * But we must do it anyway so that the udp checksum comes out right.
621 * right.
622 */ 608 */
623 if (doipcksum) { 609 if (doipcksum) {
624 outip->ip_sum = 610 outip->ip_sum = in_cksum((uint16_t *)outip, sizeof(*outip) + optlen);
625 in_cksum((uint16_t *)outip, sizeof(*outip) + optlen);
626 if (outip->ip_sum == 0) 611 if (outip->ip_sum == 0)
627 outip->ip_sum = 0xffff; 612 outip->ip_sum = 0xffff;
628 } 613 }
@@ -645,7 +630,7 @@ send_probe(int seq, int ttl)
645 /* Always calculate checksum for icmp packets */ 630 /* Always calculate checksum for icmp packets */
646 outicmp->icmp_cksum = 0; 631 outicmp->icmp_cksum = 0;
647 outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp, 632 outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp,
648 packlen - (sizeof(*outip) + optlen)); 633 packlen - (sizeof(*outip) + optlen));
649 if (outicmp->icmp_cksum == 0) 634 if (outicmp->icmp_cksum == 0)
650 outicmp->icmp_cksum = 0xffff; 635 outicmp->icmp_cksum = 0xffff;
651 } else 636 } else
@@ -656,7 +641,7 @@ send_probe(int seq, int ttl)
656 ui = (struct udpiphdr *)outip; 641 ui = (struct udpiphdr *)outip;
657 oui = (struct udpiphdr *)&tip; 642 oui = (struct udpiphdr *)&tip;
658 /* Easier to zero and put back things that are ok */ 643 /* Easier to zero and put back things that are ok */
659 memset((char *)ui, 0, sizeof(ui->ui_i)); 644 memset(ui, 0, sizeof(ui->ui_i));
660 ui->ui_src = oui->ui_src; 645 ui->ui_src = oui->ui_src;
661 ui->ui_dst = oui->ui_dst; 646 ui->ui_dst = oui->ui_dst;
662 ui->ui_pr = oui->ui_pr; 647 ui->ui_pr = oui->ui_pr;
@@ -668,7 +653,8 @@ send_probe(int seq, int ttl)
668 *outip = tip; 653 *outip = tip;
669 } 654 }
670 655
671#if ENABLE_FEATURE_TRACEROUTE_VERBOSE 656//BUG! verbose is (x & OPT_VERBOSE), not a counter!
657#if 0 //ENABLE_FEATURE_TRACEROUTE_VERBOSE
672 /* XXX undocumented debugging hack */ 658 /* XXX undocumented debugging hack */
673 if (verbose > 1) { 659 if (verbose > 1) {
674 const uint16_t *sp; 660 const uint16_t *sp;
@@ -695,15 +681,15 @@ send_probe(int seq, int ttl)
695 681
696#if !defined(IP_HDRINCL) && defined(IP_TTL) 682#if !defined(IP_HDRINCL) && defined(IP_TTL)
697 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL, 683 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
698 (char *)&ttl, sizeof(ttl)) < 0) { 684 (char *)&ttl, sizeof(ttl)) < 0) {
699 bb_perror_msg_and_die("setsockopt ttl %d", ttl); 685 bb_perror_msg_and_die("setsockopt ttl %d", ttl);
700 } 686 }
701#endif 687#endif
702 688
703 cc = xsendto(sndsock, (char *)outip, 689 cc = xsendto(sndsock, outip, packlen,
704 packlen, (struct sockaddr *)&whereto, sizeof(whereto)); 690 (struct sockaddr *)&whereto, sizeof(whereto));
705 if (cc != packlen) { 691 if (cc != packlen) {
706 bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc); 692 bb_info_msg("sent %s %d octets, ret=%d", hostname, packlen, cc);
707 } 693 }
708} 694}
709 695
@@ -722,7 +708,7 @@ pr_type(unsigned char t)
722 "Info Reply", "Mask Request", "Mask Reply" 708 "Info Reply", "Mask Request", "Mask Reply"
723 }; 709 };
724 710
725 if (t > 18) 711 if (t >= ARRAY_SIZE(ttab))
726 return "OUT-OF-RANGE"; 712 return "OUT-OF-RANGE";
727 713
728 return ttab[t]; 714 return ttab[t];
@@ -734,12 +720,12 @@ pr_type(unsigned char t)
734 packet_ok(buf, cc, seq) 720 packet_ok(buf, cc, seq)
735#endif 721#endif
736static int 722static int
737packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq) 723packet_ok(const unsigned char *buf, int cc, const struct sockaddr_in *from, int seq)
738{ 724{
739 struct icmp *icp; 725 const struct icmp *icp;
740 unsigned char type, code; 726 unsigned char type, code;
741 int hlen; 727 int hlen;
742 struct ip *ip; 728 const struct ip *ip;
743 729
744 ip = (struct ip *) buf; 730 ip = (struct ip *) buf;
745 hlen = ip->ip_hl << 2; 731 hlen = ip->ip_hl << 2;
@@ -756,15 +742,16 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
756 type = icp->icmp_type; 742 type = icp->icmp_type;
757 code = icp->icmp_code; 743 code = icp->icmp_code;
758 /* Path MTU Discovery (RFC1191) */ 744 /* Path MTU Discovery (RFC1191) */
759 if (code != ICMP_UNREACH_NEEDFRAG) 745 pmtu = 0;
760 pmtu = 0; 746 if (code == ICMP_UNREACH_NEEDFRAG)
761 else {
762 pmtu = ntohs(icp->icmp_nextmtu); 747 pmtu = ntohs(icp->icmp_nextmtu);
763 } 748
764 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) || 749 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS)
765 type == ICMP_UNREACH || type == ICMP_ECHOREPLY) { 750 || type == ICMP_UNREACH
766 struct ip *hip; 751 || type == ICMP_ECHOREPLY
767 struct udphdr *up; 752 ) {
753 const struct ip *hip;
754 const struct udphdr *up;
768 755
769 hip = &icp->icmp_ip; 756 hip = &icp->icmp_ip;
770 hlen = hip->ip_hl << 2; 757 hlen = hip->ip_hl << 2;
@@ -804,8 +791,9 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
804 791
805 printf("\n%d bytes from %s to " 792 printf("\n%d bytes from %s to "
806 "%s: icmp type %d (%s) code %d\n", 793 "%s: icmp type %d (%s) code %d\n",
807 cc, inet_ntoa(from->sin_addr), 794 cc, inet_ntoa(from->sin_addr),
808 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code); 795 inet_ntoa(ip->ip_dst),
796 type, pr_type(type), icp->icmp_code);
809 for (i = 4; i < cc; i += sizeof(*lp)) 797 for (i = 4; i < cc; i += sizeof(*lp))
810 printf("%2d: x%8.8x\n", i, *lp++); 798 printf("%2d: x%8.8x\n", i, *lp++);
811 } 799 }
@@ -813,14 +801,13 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
813 return 0; 801 return 0;
814} 802}
815 803
816
817/* 804/*
818 * Construct an Internet address representation. 805 * Construct an Internet address representation.
819 * If the nflag has been supplied, give 806 * If the -n flag has been supplied, give
820 * numeric value, otherwise try for symbolic name. 807 * numeric value, otherwise try for symbolic name.
821 */ 808 */
822static void 809static void
823print_inetname(struct sockaddr_in *from) 810print_inetname(const struct sockaddr_in *from)
824{ 811{
825 const char *ina; 812 const char *ina;
826 813
@@ -837,9 +824,9 @@ print_inetname(struct sockaddr_in *from)
837} 824}
838 825
839static void 826static void
840print(unsigned char *buf, int cc, struct sockaddr_in *from) 827print(const unsigned char *buf, int cc, const struct sockaddr_in *from)
841{ 828{
842 struct ip *ip; 829 const struct ip *ip;
843 int hlen; 830 int hlen;
844 831
845 ip = (struct ip *) buf; 832 ip = (struct ip *) buf;
@@ -853,7 +840,6 @@ print(unsigned char *buf, int cc, struct sockaddr_in *from)
853#endif 840#endif
854} 841}
855 842
856
857static struct hostinfo * 843static struct hostinfo *
858gethostinfo(const char *host) 844gethostinfo(const char *host)
859{ 845{
@@ -910,15 +896,19 @@ static void
910print_delta_ms(unsigned t1p, unsigned t2p) 896print_delta_ms(unsigned t1p, unsigned t2p)
911{ 897{
912 unsigned tt = t2p - t1p; 898 unsigned tt = t2p - t1p;
913 printf(" %u.%03u ms", tt/1000, tt%1000); 899 printf(" %u.%03u ms", tt / 1000, tt % 1000);
914} 900}
915 901
902/*
903"Usage: %s [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]\n"
904"\t[-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]\n"
905"\t[-w waittime] [-z pausemsecs] host [packetlen]"
906*/
907
916int traceroute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 908int traceroute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
917int traceroute_main(int argc, char **argv) 909int traceroute_main(int argc, char **argv)
918{ 910{
919 int code, n;
920 unsigned char *outp; 911 unsigned char *outp;
921 uint32_t *ap;
922 struct sockaddr_in *from; 912 struct sockaddr_in *from;
923 struct sockaddr_in *to; 913 struct sockaddr_in *to;
924 struct hostinfo *hi; 914 struct hostinfo *hi;
@@ -931,7 +921,6 @@ int traceroute_main(int argc, char **argv)
931#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 921#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
932 int lsrr = 0; 922 int lsrr = 0;
933#endif 923#endif
934 uint16_t off = 0;
935 struct IFADDRLIST *al; 924 struct IFADDRLIST *al;
936 char *device; 925 char *device;
937 int max_ttl = 30; 926 int max_ttl = 30;
@@ -952,7 +941,6 @@ int traceroute_main(int argc, char **argv)
952 from = (struct sockaddr_in *)&wherefrom; 941 from = (struct sockaddr_in *)&wherefrom;
953 to = (struct sockaddr_in *)&whereto; 942 to = (struct sockaddr_in *)&whereto;
954 943
955 //opterr = 0;
956#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 944#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
957 opt_complementary = "x-x:g::"; 945 opt_complementary = "x-x:g::";
958#else 946#else
@@ -970,8 +958,6 @@ int traceroute_main(int argc, char **argv)
970#endif 958#endif
971 ); 959 );
972 960
973 if (op & OPT_DONT_FRAGMNT)
974 off = IP_DF;
975 if (op & OPT_IP_CHKSUM) { 961 if (op & OPT_IP_CHKSUM) {
976 doipcksum = 0; 962 doipcksum = 0;
977 bb_error_msg("warning: ip checksums disabled"); 963 bb_error_msg("warning: ip checksums disabled");
@@ -989,15 +975,15 @@ int traceroute_main(int argc, char **argv)
989 * set the ip source address of the outbound 975 * set the ip source address of the outbound
990 * probe (e.g., on a multi-homed host). 976 * probe (e.g., on a multi-homed host).
991 */ 977 */
992 if (getuid()) 978 if (getuid() != 0)
993 bb_error_msg_and_die("-s %s: permission denied", source); 979 bb_error_msg_and_die("you must be root to use -s");
994 } 980 }
995 if (op & OPT_WAITTIME) 981 if (op & OPT_WAITTIME)
996 waittime = xatou_range(waittime_str, 2, 24 * 60 * 60); 982 waittime = xatou_range(waittime_str, 2, 24 * 60 * 60);
997 if (op & OPT_PAUSE_MS) 983 if (op & OPT_PAUSE_MS)
998 pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000); 984 pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
999 if (op & OPT_FIRST_TTL) 985 if (op & OPT_FIRST_TTL)
1000 first_ttl = xatou_range(first_ttl_str, 1, 255); 986 first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
1001 987
1002#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 988#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
1003 if (source_route_list) { 989 if (source_route_list) {
@@ -1011,12 +997,6 @@ int traceroute_main(int argc, char **argv)
1011 } 997 }
1012#endif 998#endif
1013 999
1014 if (first_ttl > max_ttl) {
1015 bb_error_msg_and_die(
1016 "first ttl (%d) may not be greater than max ttl (%d)",
1017 first_ttl, max_ttl);
1018 }
1019
1020 minpacket = sizeof(*outip) + sizeof(*outdata) + optlen; 1000 minpacket = sizeof(*outip) + sizeof(*outdata) + optlen;
1021 1001
1022#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP 1002#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP
@@ -1028,14 +1008,14 @@ int traceroute_main(int argc, char **argv)
1028 packlen = minpacket; /* minimum sized packet */ 1008 packlen = minpacket; /* minimum sized packet */
1029 1009
1030 /* Process destination and optional packet size */ 1010 /* Process destination and optional packet size */
1031 switch (argc - optind) { 1011 argv += optind;
1032 1012 argc -= optind;
1013 switch (argc) {
1033 case 2: 1014 case 2:
1034 packlen = xatoul_range(argv[optind + 1], minpacket, maxpacket); 1015 packlen = xatoul_range(argv[1], minpacket, maxpacket);
1035 /* Fall through */ 1016 /* Fall through */
1036
1037 case 1: 1017 case 1:
1038 hostname = argv[optind]; 1018 hostname = argv[0];
1039 hi = gethostinfo(hostname); 1019 hi = gethostinfo(hostname);
1040 setsin(to, hi->addrs[0]); 1020 setsin(to, hi->addrs[0]);
1041 if (hi->n > 1) 1021 if (hi->n > 1)
@@ -1045,7 +1025,6 @@ int traceroute_main(int argc, char **argv)
1045 hi->name = NULL; 1025 hi->name = NULL;
1046 freehostinfo(hi); 1026 freehostinfo(hi);
1047 break; 1027 break;
1048
1049 default: 1028 default:
1050 bb_show_usage(); 1029 bb_show_usage();
1051 } 1030 }
@@ -1081,12 +1060,12 @@ int traceroute_main(int argc, char **argv)
1081 optlist[1] = IPOPT_LSRR; 1060 optlist[1] = IPOPT_LSRR;
1082 i = lsrr * sizeof(gwlist[0]); 1061 i = lsrr * sizeof(gwlist[0]);
1083 optlist[2] = i + 3; 1062 optlist[2] = i + 3;
1084 /* Pointer to LSRR addresses */ 1063 /* pointer to LSRR addresses */
1085 optlist[3] = IPOPT_MINOFF; 1064 optlist[3] = IPOPT_MINOFF;
1086 memcpy(optlist + 4, gwlist, i); 1065 memcpy(optlist + 4, gwlist, i);
1087 1066
1088 if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, 1067 if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS,
1089 (char *)optlist, i + sizeof(gwlist[0]))) < 0) { 1068 (char *)optlist, i + sizeof(gwlist[0])) < 0) {
1090 bb_perror_msg_and_die("IP_OPTIONS"); 1069 bb_perror_msg_and_die("IP_OPTIONS");
1091 } 1070 }
1092 } 1071 }
@@ -1106,7 +1085,7 @@ int traceroute_main(int argc, char **argv)
1106 } 1085 }
1107#else 1086#else
1108#ifdef IP_TOS 1087#ifdef IP_TOS
1109 if (tos_str && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { 1088 if ((op & OPT_TOS) && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
1110 bb_perror_msg_and_die("setsockopt tos %d", tos); 1089 bb_perror_msg_and_die("setsockopt tos %d", tos);
1111 } 1090 }
1112#endif 1091#endif
@@ -1127,10 +1106,11 @@ int traceroute_main(int argc, char **argv)
1127 outip = xzalloc(packlen); 1106 outip = xzalloc(packlen);
1128 1107
1129 outip->ip_v = IPVERSION; 1108 outip->ip_v = IPVERSION;
1130 if (tos_str) 1109 if (op & OPT_TOS)
1131 outip->ip_tos = tos; 1110 outip->ip_tos = tos;
1132 outip->ip_len = htons(packlen); 1111 outip->ip_len = htons(packlen);
1133 outip->ip_off = htons(off); 1112 if (op & OPT_DONT_FRAGMNT)
1113 outip->ip_off = htons(IP_DF);
1134 outp = (unsigned char *)(outip + 1); 1114 outp = (unsigned char *)(outip + 1);
1135 outip->ip_dst = to->sin_addr; 1115 outip->ip_dst = to->sin_addr;
1136 1116
@@ -1153,12 +1133,11 @@ int traceroute_main(int argc, char **argv)
1153 outdata = (outdata_t *)(outudp + 1); 1133 outdata = (outdata_t *)(outudp + 1);
1154 } 1134 }
1155 1135
1156 /* Get the interface address list */
1157 n = ifaddrlist(&al);
1158
1159 /* Look for a specific device */ 1136 /* Look for a specific device */
1160 if (op & OPT_DEVICE) { 1137 if (op & OPT_DEVICE) {
1161 for (i = n; i > 0; --i, ++al) 1138 /* Get the interface address list */
1139 int n = ifaddrlist(&al);
1140 for (; n > 0; --n, ++al)
1162 if (strcmp(device, al->device) == 0) 1141 if (strcmp(device, al->device) == 0)
1163 goto found_dev; 1142 goto found_dev;
1164 bb_error_msg_and_die("can't find interface %s", device); 1143 bb_error_msg_and_die("can't find interface %s", device);
@@ -1185,6 +1164,7 @@ int traceroute_main(int argc, char **argv)
1185 * there are more than one). 1164 * there are more than one).
1186 */ 1165 */
1187 if (op & OPT_DEVICE) { 1166 if (op & OPT_DEVICE) {
1167 uint32_t *ap;
1188 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap) 1168 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
1189 if (*ap == al->addr) 1169 if (*ap == al->addr)
1190 goto found_dev2; 1170 goto found_dev2;
@@ -1197,7 +1177,7 @@ int traceroute_main(int argc, char **argv)
1197 if (hi->n > 1) 1177 if (hi->n > 1)
1198 bb_error_msg( 1178 bb_error_msg(
1199 "warning: %s has multiple addresses; using %s", 1179 "warning: %s has multiple addresses; using %s",
1200 source, inet_ntoa(from->sin_addr)); 1180 source, inet_ntoa(from->sin_addr));
1201 } 1181 }
1202 freehostinfo(hi); 1182 freehostinfo(hi);
1203 } 1183 }
@@ -1211,7 +1191,6 @@ int traceroute_main(int argc, char **argv)
1211 if (op & OPT_SOURCE) 1191 if (op & OPT_SOURCE)
1212 printf(" from %s", source); 1192 printf(" from %s", source);
1213 printf(", %d hops max, %d byte packets\n", max_ttl, packlen); 1193 printf(", %d hops max, %d byte packets\n", max_ttl, packlen);
1214 fflush(stdout);
1215 1194
1216 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { 1195 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
1217 uint32_t lastaddr = 0; 1196 uint32_t lastaddr = 0;
@@ -1229,17 +1208,21 @@ int traceroute_main(int argc, char **argv)
1229 1208
1230 if (sentfirst && pausemsecs > 0) 1209 if (sentfirst && pausemsecs > 0)
1231 usleep(pausemsecs * 1000); 1210 usleep(pausemsecs * 1000);
1211 fflush(stdout);
1212
1232 t1 = monotonic_us(); 1213 t1 = monotonic_us();
1233 send_probe(++seq, ttl); 1214 send_probe(++seq, ttl);
1234 ++sentfirst; 1215 ++sentfirst;
1216
1235 while ((cc = wait_for_reply(rcvsock, from)) != 0) { 1217 while ((cc = wait_for_reply(rcvsock, from)) != 0) {
1236 t2 = monotonic_us(); 1218 t2 = monotonic_us();
1237 i = packet_ok(packet, cc, from, seq); 1219 i = packet_ok(packet, cc, from, seq);
1238 /* Skip short packet */ 1220 /* Skip short packet */
1239 if (i == 0) 1221 if (i == 0)
1240 continue; 1222 continue;
1241 if (!gotlastaddr || 1223 if (!gotlastaddr
1242 from->sin_addr.s_addr != lastaddr) { 1224 || from->sin_addr.s_addr != lastaddr
1225 ) {
1243 print(packet, cc, from); 1226 print(packet, cc, from);
1244 lastaddr = from->sin_addr.s_addr; 1227 lastaddr = from->sin_addr.s_addr;
1245 ++gotlastaddr; 1228 ++gotlastaddr;
@@ -1251,99 +1234,86 @@ int traceroute_main(int argc, char **argv)
1251 if (i == -2) { 1234 if (i == -2) {
1252 if (ip->ip_ttl <= 1) 1235 if (ip->ip_ttl <= 1)
1253 printf(" !"); 1236 printf(" !");
1254 ++got_there; 1237 got_there = 1;
1255 break; 1238 break;
1256 } 1239 }
1257 /* time exceeded in transit */ 1240 /* time exceeded in transit */
1258 if (i == -1) 1241 if (i == -1)
1259 break; 1242 break;
1260 code = i - 1; 1243 i--;
1261 switch (code) { 1244 switch (i) {
1262
1263 case ICMP_UNREACH_PORT: 1245 case ICMP_UNREACH_PORT:
1264 if (ip->ip_ttl <= 1) 1246 if (ip->ip_ttl <= 1)
1265 printf(" !"); 1247 printf(" !");
1266 ++got_there; 1248 got_there = 1;
1267 break; 1249 break;
1268
1269 case ICMP_UNREACH_NET: 1250 case ICMP_UNREACH_NET:
1270 ++unreachable;
1271 printf(" !N"); 1251 printf(" !N");
1252 ++unreachable;
1272 break; 1253 break;
1273
1274 case ICMP_UNREACH_HOST: 1254 case ICMP_UNREACH_HOST:
1275 ++unreachable;
1276 printf(" !H"); 1255 printf(" !H");
1256 ++unreachable;
1277 break; 1257 break;
1278
1279 case ICMP_UNREACH_PROTOCOL: 1258 case ICMP_UNREACH_PROTOCOL:
1280 ++got_there;
1281 printf(" !P"); 1259 printf(" !P");
1260 got_there = 1;
1282 break; 1261 break;
1283
1284 case ICMP_UNREACH_NEEDFRAG: 1262 case ICMP_UNREACH_NEEDFRAG:
1285 ++unreachable;
1286 printf(" !F-%d", pmtu); 1263 printf(" !F-%d", pmtu);
1264 ++unreachable;
1287 break; 1265 break;
1288
1289 case ICMP_UNREACH_SRCFAIL: 1266 case ICMP_UNREACH_SRCFAIL:
1290 ++unreachable;
1291 printf(" !S"); 1267 printf(" !S");
1268 ++unreachable;
1292 break; 1269 break;
1293
1294 case ICMP_UNREACH_FILTER_PROHIB: 1270 case ICMP_UNREACH_FILTER_PROHIB:
1295 case ICMP_UNREACH_NET_PROHIB: /* misuse */ 1271 case ICMP_UNREACH_NET_PROHIB: /* misuse */
1296 ++unreachable;
1297 printf(" !A"); 1272 printf(" !A");
1273 ++unreachable;
1298 break; 1274 break;
1299
1300 case ICMP_UNREACH_HOST_PROHIB: 1275 case ICMP_UNREACH_HOST_PROHIB:
1301 ++unreachable;
1302 printf(" !C"); 1276 printf(" !C");
1277 ++unreachable;
1303 break; 1278 break;
1304
1305 case ICMP_UNREACH_HOST_PRECEDENCE: 1279 case ICMP_UNREACH_HOST_PRECEDENCE:
1306 ++unreachable;
1307 printf(" !V"); 1280 printf(" !V");
1281 ++unreachable;
1308 break; 1282 break;
1309
1310 case ICMP_UNREACH_PRECEDENCE_CUTOFF: 1283 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1311 ++unreachable;
1312 printf(" !C"); 1284 printf(" !C");
1285 ++unreachable;
1313 break; 1286 break;
1314
1315 case ICMP_UNREACH_NET_UNKNOWN: 1287 case ICMP_UNREACH_NET_UNKNOWN:
1316 case ICMP_UNREACH_HOST_UNKNOWN: 1288 case ICMP_UNREACH_HOST_UNKNOWN:
1317 ++unreachable;
1318 printf(" !U"); 1289 printf(" !U");
1290 ++unreachable;
1319 break; 1291 break;
1320
1321 case ICMP_UNREACH_ISOLATED: 1292 case ICMP_UNREACH_ISOLATED:
1322 ++unreachable;
1323 printf(" !I"); 1293 printf(" !I");
1294 ++unreachable;
1324 break; 1295 break;
1325
1326 case ICMP_UNREACH_TOSNET: 1296 case ICMP_UNREACH_TOSNET:
1327 case ICMP_UNREACH_TOSHOST: 1297 case ICMP_UNREACH_TOSHOST:
1328 ++unreachable;
1329 printf(" !T"); 1298 printf(" !T");
1299 ++unreachable;
1330 break; 1300 break;
1331
1332 default: 1301 default:
1302 printf(" !<%d>", i);
1333 ++unreachable; 1303 ++unreachable;
1334 printf(" !<%d>", code);
1335 break; 1304 break;
1336 } 1305 }
1337 break; 1306 break;
1338 } 1307 }
1339 if (cc == 0) 1308 if (cc == 0)
1340 printf(" *"); 1309 printf(" *");
1341 (void)fflush(stdout);
1342 } 1310 }
1343 bb_putchar('\n'); 1311 bb_putchar('\n');
1344 if (got_there || 1312 if (got_there
1345 (unreachable > 0 && unreachable >= nprobes - 1)) 1313 || (unreachable > 0 && unreachable >= nprobes - 1)
1314 ) {
1346 break; 1315 break;
1316 }
1347 } 1317 }
1348 return 0; 1318 return 0;
1349} 1319}