diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-23 06:15:38 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-23 06:15:38 +0100 |
commit | 0d56568654973a522bd005616b86d4dc8c833c81 (patch) | |
tree | 5ad6705c2868d1ed51a2411599d145a35536ecab | |
parent | 11f3a8b7ed366b23e4740fc847662a971cf65de3 (diff) | |
download | busybox-w32-0d56568654973a522bd005616b86d4dc8c833c81.tar.gz busybox-w32-0d56568654973a522bd005616b86d4dc8c833c81.tar.bz2 busybox-w32-0d56568654973a522bd005616b86d4dc8c833c81.zip |
traceroute: cleanup preparing it for traceroute6. -17 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/traceroute.c | 126 |
1 files changed, 63 insertions, 63 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c index fa45db98a..d36ddee14 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -211,6 +211,13 @@ | |||
211 | #include <netinet/udp.h> | 211 | #include <netinet/udp.h> |
212 | #include <netinet/ip.h> | 212 | #include <netinet/ip.h> |
213 | #include <netinet/ip_icmp.h> | 213 | #include <netinet/ip_icmp.h> |
214 | #if ENABLE_FEATURE_IPV6 | ||
215 | # include <netinet/ip6.h> | ||
216 | # include <netinet/icmp6.h> | ||
217 | # ifndef SOL_IPV6 | ||
218 | # define SOL_IPV6 IPPROTO_IPV6 | ||
219 | # endif | ||
220 | #endif | ||
214 | 221 | ||
215 | #include "libbb.h" | 222 | #include "libbb.h" |
216 | #include "inet_common.h" | 223 | #include "inet_common.h" |
@@ -222,7 +229,9 @@ | |||
222 | # define IPPROTO_IP 0 | 229 | # define IPPROTO_IP 0 |
223 | #endif | 230 | #endif |
224 | 231 | ||
225 | /* Keep in sync with getopt32 call! */ | 232 | |
233 | #define OPT_STRING "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ | ||
234 | IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") | ||
226 | enum { | 235 | enum { |
227 | OPT_DONT_FRAGMNT = (1 << 0), /* F */ | 236 | OPT_DONT_FRAGMNT = (1 << 0), /* F */ |
228 | OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */ | 237 | OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */ |
@@ -309,15 +318,15 @@ static int | |||
309 | wait_for_reply(struct sockaddr_in *fromp) | 318 | wait_for_reply(struct sockaddr_in *fromp) |
310 | { | 319 | { |
311 | struct pollfd pfd[1]; | 320 | struct pollfd pfd[1]; |
312 | int cc = 0; | 321 | int read_len = 0; |
313 | socklen_t fromlen = sizeof(*fromp); | 322 | socklen_t fromlen = sizeof(*fromp); |
314 | 323 | ||
315 | pfd[0].fd = rcvsock; | 324 | pfd[0].fd = rcvsock; |
316 | pfd[0].events = POLLIN; | 325 | pfd[0].events = POLLIN; |
317 | if (safe_poll(pfd, 1, waittime * 1000) > 0) | 326 | if (safe_poll(pfd, 1, waittime * 1000) > 0) |
318 | cc = recvfrom(rcvsock, recv_pkt, sizeof(recv_pkt), 0, | 327 | read_len = recvfrom(rcvsock, recv_pkt, sizeof(recv_pkt), 0, |
319 | (struct sockaddr *)fromp, &fromlen); | 328 | (struct sockaddr *)fromp, &fromlen); |
320 | return cc; | 329 | return read_len; |
321 | } | 330 | } |
322 | 331 | ||
323 | /* | 332 | /* |
@@ -417,8 +426,7 @@ send_probe(int seq, int ttl) | |||
417 | len -= sizeof(*outudp); | 426 | len -= sizeof(*outudp); |
418 | set_nport(dest_lsa, htons(port + seq)); | 427 | set_nport(dest_lsa, htons(port + seq)); |
419 | } | 428 | } |
420 | res = xsendto(sndsock, out, len, | 429 | res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); |
421 | (struct sockaddr *)&dest_lsa->u.sa, dest_lsa->len); | ||
422 | if (res != len) { | 430 | if (res != len) { |
423 | bb_info_msg("sent %d octets, ret=%d", len, res); | 431 | bb_info_msg("sent %d octets, ret=%d", len, res); |
424 | } | 432 | } |
@@ -447,11 +455,11 @@ pr_type(unsigned char t) | |||
447 | #endif | 455 | #endif |
448 | 456 | ||
449 | #if !ENABLE_FEATURE_TRACEROUTE_VERBOSE | 457 | #if !ENABLE_FEATURE_TRACEROUTE_VERBOSE |
450 | #define packet_ok(cc, from, seq) \ | 458 | #define packet_ok(read_len, from, seq) \ |
451 | packet_ok(cc, seq) | 459 | packet_ok(read_len, seq) |
452 | #endif | 460 | #endif |
453 | static int | 461 | static int |
454 | packet_ok(int cc, const struct sockaddr_in *from, int seq) | 462 | packet_ok(int read_len, const struct sockaddr_in *from, int seq) |
455 | { | 463 | { |
456 | const struct icmp *icp; | 464 | const struct icmp *icp; |
457 | unsigned char type, code; | 465 | unsigned char type, code; |
@@ -460,15 +468,15 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq) | |||
460 | 468 | ||
461 | ip = (struct ip *) recv_pkt; | 469 | ip = (struct ip *) recv_pkt; |
462 | hlen = ip->ip_hl << 2; | 470 | hlen = ip->ip_hl << 2; |
463 | if (cc < hlen + ICMP_MINLEN) { | 471 | if (read_len < hlen + ICMP_MINLEN) { |
464 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | 472 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE |
465 | if (verbose) | 473 | if (verbose) |
466 | printf("packet too short (%d bytes) from %s\n", cc, | 474 | printf("packet too short (%d bytes) from %s\n", read_len, |
467 | inet_ntoa(from->sin_addr)); | 475 | inet_ntoa(from->sin_addr)); |
468 | #endif | 476 | #endif |
469 | return 0; | 477 | return 0; |
470 | } | 478 | } |
471 | cc -= hlen; | 479 | read_len -= hlen; |
472 | icp = (struct icmp *)(recv_pkt + hlen); | 480 | icp = (struct icmp *)(recv_pkt + hlen); |
473 | type = icp->icmp_type; | 481 | type = icp->icmp_type; |
474 | code = icp->icmp_code; | 482 | code = icp->icmp_code; |
@@ -498,7 +506,7 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq) | |||
498 | } | 506 | } |
499 | 507 | ||
500 | hicmp = (struct icmp *)((unsigned char *)hip + hlen); | 508 | hicmp = (struct icmp *)((unsigned char *)hip + hlen); |
501 | if (hlen + SIZEOF_ICMP_HDR <= cc | 509 | if (hlen + SIZEOF_ICMP_HDR <= read_len |
502 | && hip->ip_p == IPPROTO_ICMP | 510 | && hip->ip_p == IPPROTO_ICMP |
503 | && hicmp->icmp_id == htons(ident) | 511 | && hicmp->icmp_id == htons(ident) |
504 | && hicmp->icmp_seq == htons(seq) | 512 | && hicmp->icmp_seq == htons(seq) |
@@ -507,7 +515,7 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq) | |||
507 | } | 515 | } |
508 | } else { | 516 | } else { |
509 | up = (struct udphdr *)((char *)hip + hlen); | 517 | up = (struct udphdr *)((char *)hip + hlen); |
510 | if (hlen + 12 <= cc | 518 | if (hlen + 12 <= read_len |
511 | && hip->ip_p == IPPROTO_UDP | 519 | && hip->ip_p == IPPROTO_UDP |
512 | // Off: since we do not form the entire IP packet, | 520 | // Off: since we do not form the entire IP packet, |
513 | // but defer it to kernel, we can't set source port, | 521 | // but defer it to kernel, we can't set source port, |
@@ -526,10 +534,10 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq) | |||
526 | 534 | ||
527 | printf("\n%d bytes from %s to " | 535 | printf("\n%d bytes from %s to " |
528 | "%s: icmp type %d (%s) code %d\n", | 536 | "%s: icmp type %d (%s) code %d\n", |
529 | cc, inet_ntoa(from->sin_addr), | 537 | read_len, inet_ntoa(from->sin_addr), |
530 | inet_ntoa(ip->ip_dst), | 538 | inet_ntoa(ip->ip_dst), |
531 | type, pr_type(type), icp->icmp_code); | 539 | type, pr_type(type), icp->icmp_code); |
532 | for (i = 4; i < cc; i += sizeof(*lp)) | 540 | for (i = 4; i < read_len; i += sizeof(*lp)) |
533 | printf("%2d: x%8.8x\n", i, *lp++); | 541 | printf("%2d: x%8.8x\n", i, *lp++); |
534 | } | 542 | } |
535 | #endif | 543 | #endif |
@@ -542,34 +550,39 @@ packet_ok(int cc, const struct sockaddr_in *from, int seq) | |||
542 | * numeric value, otherwise try for symbolic name. | 550 | * numeric value, otherwise try for symbolic name. |
543 | */ | 551 | */ |
544 | static void | 552 | static void |
545 | print_inetname(const struct sockaddr_in *from) | 553 | print_inetname(const struct sockaddr *from) |
546 | { | 554 | { |
547 | const char *ina; | 555 | char *ina = xmalloc_sockaddr2dotted_noport(from); |
548 | 556 | ||
549 | ina = inet_ntoa(from->sin_addr); | 557 | if (option_mask32 & OPT_ADDR_NUM) { |
550 | if (option_mask32 & OPT_ADDR_NUM) | ||
551 | printf(" %s", ina); | 558 | printf(" %s", ina); |
552 | else { | 559 | } else { |
553 | char *n = NULL; | 560 | char *n = NULL; |
554 | if (from->sin_addr.s_addr != INADDR_ANY) | 561 | |
562 | if (from->sa_family != AF_INET | ||
563 | || ((struct sockaddr_in*)from)->sin_addr.s_addr != INADDR_ANY | ||
564 | ) { | ||
565 | /* Try to reverse resolve if it is not 0.0.0.0 */ | ||
555 | n = xmalloc_sockaddr2host_noport((struct sockaddr*)from); | 566 | n = xmalloc_sockaddr2host_noport((struct sockaddr*)from); |
567 | } | ||
556 | printf(" %s (%s)", (n ? n : ina), ina); | 568 | printf(" %s (%s)", (n ? n : ina), ina); |
557 | free(n); | 569 | free(n); |
558 | } | 570 | } |
571 | free(ina); | ||
559 | } | 572 | } |
560 | 573 | ||
561 | static void | 574 | static void |
562 | print(int cc, const struct sockaddr_in *from) | 575 | print(int read_len, const struct sockaddr_in *from) |
563 | { | 576 | { |
564 | print_inetname(from); | 577 | print_inetname((const struct sockaddr*)from); |
565 | if (verbose) { | 578 | if (verbose) { |
566 | const struct ip *ip; | 579 | const struct ip *ip; |
567 | int hlen; | 580 | int hlen; |
568 | 581 | ||
569 | ip = (struct ip *) recv_pkt; | 582 | ip = (struct ip *) recv_pkt; |
570 | hlen = ip->ip_hl << 2; | 583 | hlen = ip->ip_hl << 2; |
571 | cc -= hlen; | 584 | read_len -= hlen; |
572 | printf(" %d bytes to %s", cc, inet_ntoa(ip->ip_dst)); | 585 | printf(" %d bytes to %s", read_len, inet_ntoa(ip->ip_dst)); |
573 | } | 586 | } |
574 | } | 587 | } |
575 | 588 | ||
@@ -581,17 +594,16 @@ print_delta_ms(unsigned t1p, unsigned t2p) | |||
581 | } | 594 | } |
582 | 595 | ||
583 | /* | 596 | /* |
584 | Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl] | 597 | * Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl] |
585 | [-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos] | 598 | * [-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos] |
586 | [-w waittime] [-z pausemsecs] host [packetlen]" | 599 | * [-w waittime] [-z pausemsecs] host [packetlen]" |
587 | */ | 600 | */ |
588 | 601 | ||
589 | int traceroute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 602 | int traceroute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
590 | int traceroute_main(int argc, char **argv) | 603 | int traceroute_main(int argc UNUSED_PARAM, char **argv) |
591 | { | 604 | { |
605 | int i; | ||
592 | int minpacket; | 606 | int minpacket; |
593 | int ttl, i; | ||
594 | int seq = 0; | ||
595 | int tos = 0; | 607 | int tos = 0; |
596 | int max_ttl = 30; | 608 | int max_ttl = 30; |
597 | int nprobes = 3; | 609 | int nprobes = 3; |
@@ -611,19 +623,14 @@ int traceroute_main(int argc, char **argv) | |||
611 | llist_t *source_route_list = NULL; | 623 | llist_t *source_route_list = NULL; |
612 | int lsrr = 0; | 624 | int lsrr = 0; |
613 | #endif | 625 | #endif |
626 | int ttl; | ||
627 | int seq; | ||
614 | 628 | ||
615 | INIT_G(); | 629 | INIT_G(); |
616 | 630 | ||
617 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | 631 | /* minimum 1 arg */ |
618 | opt_complementary = "x-x:g::"; | 632 | opt_complementary = "-1:x-x" IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(":g::"); |
619 | #else | 633 | op = getopt32(argv, OPT_STRING |
620 | opt_complementary = "x-x"; | ||
621 | #endif | ||
622 | |||
623 | op = getopt32(argv, "FIlnrdvxt:i:m:p:q:s:w:z:f:" | ||
624 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
625 | "g:" | ||
626 | #endif | ||
627 | , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str | 634 | , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str |
628 | , &source, &waittime_str, &pausemsecs_str, &first_ttl_str | 635 | , &source, &waittime_str, &pausemsecs_str, &first_ttl_str |
629 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | 636 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE |
@@ -681,17 +688,9 @@ int traceroute_main(int argc, char **argv) | |||
681 | 688 | ||
682 | /* Process destination and optional packet size */ | 689 | /* Process destination and optional packet size */ |
683 | argv += optind; | 690 | argv += optind; |
684 | argc -= optind; | 691 | if (argv[1]) |
685 | switch (argc) { | ||
686 | case 2: | ||
687 | packlen = xatoul_range(argv[1], minpacket, 32 * 1024); | 692 | packlen = xatoul_range(argv[1], minpacket, 32 * 1024); |
688 | /* Fall through */ | 693 | dest_lsa = xhost2sockaddr(argv[0], port); |
689 | case 1: | ||
690 | dest_lsa = xhost2sockaddr(argv[0], port); | ||
691 | break; | ||
692 | default: | ||
693 | bb_show_usage(); | ||
694 | } | ||
695 | 694 | ||
696 | /* Ensure the socket fds won't be 0, 1 or 2 */ | 695 | /* Ensure the socket fds won't be 0, 1 or 2 */ |
697 | bb_sanitize_stdio(); | 696 | bb_sanitize_stdio(); |
@@ -710,8 +709,7 @@ int traceroute_main(int argc, char **argv) | |||
710 | xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock); | 709 | xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock); |
711 | else | 710 | else |
712 | xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock); | 711 | xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock); |
713 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | 712 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS |
714 | #if defined(IP_OPTIONS) | ||
715 | if (lsrr > 0) { | 713 | if (lsrr > 0) { |
716 | unsigned char optlist[MAX_IPOPTLEN]; | 714 | unsigned char optlist[MAX_IPOPTLEN]; |
717 | 715 | ||
@@ -734,8 +732,7 @@ int traceroute_main(int argc, char **argv) | |||
734 | bb_perror_msg_and_die("IP_OPTIONS"); | 732 | bb_perror_msg_and_die("IP_OPTIONS"); |
735 | } | 733 | } |
736 | } | 734 | } |
737 | #endif /* IP_OPTIONS */ | 735 | #endif |
738 | #endif /* CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE */ | ||
739 | #ifdef SO_SNDBUF | 736 | #ifdef SO_SNDBUF |
740 | if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) { | 737 | if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) { |
741 | bb_perror_msg_and_die("SO_SNDBUF"); | 738 | bb_perror_msg_and_die("SO_SNDBUF"); |
@@ -796,6 +793,7 @@ int traceroute_main(int argc, char **argv) | |||
796 | printf(" from %s", source); | 793 | printf(" from %s", source); |
797 | printf(", %d hops max, %d byte packets\n", max_ttl, packlen); | 794 | printf(", %d hops max, %d byte packets\n", max_ttl, packlen); |
798 | 795 | ||
796 | seq = 0; | ||
799 | for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { | 797 | for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { |
800 | //TODO: make it protocol agnostic (get rid of sockaddr_in) | 798 | //TODO: make it protocol agnostic (get rid of sockaddr_in) |
801 | struct sockaddr_in from; | 799 | struct sockaddr_in from; |
@@ -808,7 +806,7 @@ int traceroute_main(int argc, char **argv) | |||
808 | 806 | ||
809 | printf("%2d", ttl); | 807 | printf("%2d", ttl); |
810 | for (probe = 0; probe < nprobes; ++probe) { | 808 | for (probe = 0; probe < nprobes; ++probe) { |
811 | int cc; | 809 | int read_len; |
812 | unsigned t1; | 810 | unsigned t1; |
813 | unsigned t2; | 811 | unsigned t2; |
814 | struct ip *ip; | 812 | struct ip *ip; |
@@ -819,18 +817,18 @@ int traceroute_main(int argc, char **argv) | |||
819 | 817 | ||
820 | t1 = monotonic_us(); | 818 | t1 = monotonic_us(); |
821 | send_probe(++seq, ttl); | 819 | send_probe(++seq, ttl); |
822 | first = 0; | ||
823 | 820 | ||
824 | while ((cc = wait_for_reply(&from)) != 0) { | 821 | first = 0; |
822 | while ((read_len = wait_for_reply(&from)) != 0) { | ||
825 | t2 = monotonic_us(); | 823 | t2 = monotonic_us(); |
826 | i = packet_ok(cc, &from, seq); | 824 | i = packet_ok(read_len, &from, seq); |
827 | /* Skip short packet */ | 825 | /* Skip short packet */ |
828 | if (i == 0) | 826 | if (i == 0) |
829 | continue; | 827 | continue; |
830 | if (!gotlastaddr | 828 | if (!gotlastaddr |
831 | || from.sin_addr.s_addr != lastaddr | 829 | || from.sin_addr.s_addr != lastaddr |
832 | ) { | 830 | ) { |
833 | print(cc, &from); | 831 | print(read_len, &from); |
834 | lastaddr = from.sin_addr.s_addr; | 832 | lastaddr = from.sin_addr.s_addr; |
835 | gotlastaddr = 1; | 833 | gotlastaddr = 1; |
836 | } | 834 | } |
@@ -912,7 +910,8 @@ int traceroute_main(int argc, char **argv) | |||
912 | } | 910 | } |
913 | break; | 911 | break; |
914 | } | 912 | } |
915 | if (cc == 0) | 913 | /* there was no packet at all? */ |
914 | if (read_len == 0) | ||
916 | printf(" *"); | 915 | printf(" *"); |
917 | } | 916 | } |
918 | bb_putchar('\n'); | 917 | bb_putchar('\n'); |
@@ -922,5 +921,6 @@ int traceroute_main(int argc, char **argv) | |||
922 | break; | 921 | break; |
923 | } | 922 | } |
924 | } | 923 | } |
924 | |||
925 | return 0; | 925 | return 0; |
926 | } | 926 | } |