diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-09 17:32:16 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-09 17:32:16 +0000 |
commit | 9ca26d38c513c918cf88db8fef057b7ae5c133f0 (patch) | |
tree | 59a8c81de0d3631aca6303adc506363e2807f270 /networking/ping.c | |
parent | d244c5eaf80677bc785ada68d4bb805cdf2d4505 (diff) | |
download | busybox-w32-9ca26d38c513c918cf88db8fef057b7ae5c133f0.tar.gz busybox-w32-9ca26d38c513c918cf88db8fef057b7ae5c133f0.tar.bz2 busybox-w32-9ca26d38c513c918cf88db8fef057b7ae5c133f0.zip |
ping: support -I addr in family neutral manner; reuse a bit of common code
Diffstat (limited to 'networking/ping.c')
-rw-r--r-- | networking/ping.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/networking/ping.c b/networking/ping.c index e76584341..9bf38130e 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -254,7 +254,7 @@ static union { | |||
254 | struct sockaddr_in6 sin6; | 254 | struct sockaddr_in6 sin6; |
255 | #endif | 255 | #endif |
256 | } pingaddr; | 256 | } pingaddr; |
257 | static struct sockaddr_in sourceaddr; | 257 | static len_and_sockaddr *source_lsa; |
258 | static int pingsock = -1; | 258 | static int pingsock = -1; |
259 | static unsigned datalen; /* intentionally uninitialized to work around gcc bug */ | 259 | static unsigned datalen; /* intentionally uninitialized to work around gcc bug */ |
260 | 260 | ||
@@ -561,9 +561,8 @@ static void ping4(len_and_sockaddr *lsa) | |||
561 | 561 | ||
562 | pingsock = create_icmp_socket(); | 562 | pingsock = create_icmp_socket(); |
563 | pingaddr.sin = lsa->sin; | 563 | pingaddr.sin = lsa->sin; |
564 | if (sourceaddr.sin_addr.s_addr) { | 564 | if (source_lsa) |
565 | xbind(pingsock, (struct sockaddr*)&sourceaddr, sizeof(sourceaddr)); | 565 | xbind(pingsock, &lsa->sa, lsa->len); |
566 | } | ||
567 | 566 | ||
568 | /* enable broadcast pings */ | 567 | /* enable broadcast pings */ |
569 | setsockopt_broadcast(pingsock); | 568 | setsockopt_broadcast(pingsock); |
@@ -572,13 +571,6 @@ static void ping4(len_and_sockaddr *lsa) | |||
572 | sockopt = 48 * 1024; /* explain why 48k? */ | 571 | sockopt = 48 * 1024; /* explain why 48k? */ |
573 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); | 572 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); |
574 | 573 | ||
575 | printf("PING %s (%s)", hostname, dotted); | ||
576 | if (sourceaddr.sin_addr.s_addr) { | ||
577 | printf(" from %s", | ||
578 | inet_ntoa(*(struct in_addr *) &sourceaddr.sin_addr.s_addr)); | ||
579 | } | ||
580 | printf(": %d data bytes\n", datalen); | ||
581 | |||
582 | signal(SIGINT, pingstats); | 574 | signal(SIGINT, pingstats); |
583 | 575 | ||
584 | /* start the ping's going ... */ | 576 | /* start the ping's going ... */ |
@@ -615,9 +607,9 @@ static void ping6(len_and_sockaddr *lsa) | |||
615 | 607 | ||
616 | pingsock = create_icmp6_socket(); | 608 | pingsock = create_icmp6_socket(); |
617 | pingaddr.sin6 = lsa->sin6; | 609 | pingaddr.sin6 = lsa->sin6; |
618 | //if (sourceaddr.sin_addr.s_addr) { | 610 | /* untested whether "-I addr" really works for IPv6: */ |
619 | // xbind(pingsock, (struct sockaddr*)&sourceaddr, sizeof(sourceaddr)); | 611 | if (source_lsa) |
620 | //} | 612 | xbind(pingsock, &lsa->sa, lsa->len); |
621 | 613 | ||
622 | #ifdef ICMP6_FILTER | 614 | #ifdef ICMP6_FILTER |
623 | { | 615 | { |
@@ -652,8 +644,6 @@ static void ping6(len_and_sockaddr *lsa) | |||
652 | if (if_index) | 644 | if (if_index) |
653 | pingaddr.sin6.sin6_scope_id = if_index; | 645 | pingaddr.sin6.sin6_scope_id = if_index; |
654 | 646 | ||
655 | printf("PING %s (%s): %d data bytes\n", hostname, dotted, datalen); | ||
656 | |||
657 | signal(SIGINT, pingstats); | 647 | signal(SIGINT, pingstats); |
658 | 648 | ||
659 | /* start the ping's going ... */ | 649 | /* start the ping's going ... */ |
@@ -695,25 +685,21 @@ static void ping6(len_and_sockaddr *lsa) | |||
695 | } | 685 | } |
696 | #endif | 686 | #endif |
697 | 687 | ||
698 | /* TODO: consolidate ether-wake.c, dnsd.c, ifupdown.c, nslookup.c | 688 | static void ping(len_and_sockaddr *lsa) |
699 | * versions of below thing. BTW we have far too many "%u.%u.%u.%u" too... | ||
700 | */ | ||
701 | static int parse_nipquad(const char *str, struct sockaddr_in* addr) | ||
702 | { | 689 | { |
703 | char dummy; | 690 | printf("PING %s (%s)", hostname, dotted); |
704 | unsigned i1, i2, i3, i4; | 691 | if (source_lsa) { |
705 | if (sscanf(str, "%u.%u.%u.%u%c", | 692 | printf(" from %s", |
706 | &i1, &i2, &i3, &i4, &dummy) == 4 | 693 | xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len)); |
707 | && ( (i1|i2|i3|i4) <= 0xff ) | ||
708 | ) { | ||
709 | uint8_t* ptr = (uint8_t*)&addr->sin_addr; | ||
710 | ptr[0] = i1; | ||
711 | ptr[1] = i2; | ||
712 | ptr[2] = i3; | ||
713 | ptr[3] = i4; | ||
714 | return 0; | ||
715 | } | 694 | } |
716 | return 1; /* error */ | 695 | printf(": %d data bytes\n", datalen); |
696 | |||
697 | #if ENABLE_PING6 | ||
698 | if (lsa->sa.sa_family == AF_INET6) | ||
699 | ping6(lsa); | ||
700 | else | ||
701 | #endif | ||
702 | ping4(lsa); | ||
717 | } | 703 | } |
718 | 704 | ||
719 | int ping_main(int argc, char **argv); | 705 | int ping_main(int argc, char **argv); |
@@ -732,9 +718,11 @@ int ping_main(int argc, char **argv) | |||
732 | if (option_mask32 & OPT_s) datalen = xatou16(opt_s); // -s | 718 | if (option_mask32 & OPT_s) datalen = xatou16(opt_s); // -s |
733 | if (option_mask32 & OPT_I) { // -I | 719 | if (option_mask32 & OPT_I) { // -I |
734 | if_index = if_nametoindex(opt_I); | 720 | if_index = if_nametoindex(opt_I); |
735 | if (!if_index) | 721 | if (!if_index) { |
736 | if (parse_nipquad(opt_I, &sourceaddr)) | 722 | /* TODO: I'm not sure it takes IPv6 unless in [XX:XX..] format */ |
737 | bb_show_usage(); | 723 | /* (ping doesn't support source IPv6 addresses yet anyway) */ |
724 | source_lsa = xdotted2sockaddr(opt_I, 0); | ||
725 | } | ||
738 | } | 726 | } |
739 | myid = (int16_t) getpid(); | 727 | myid = (int16_t) getpid(); |
740 | hostname = argv[optind]; | 728 | hostname = argv[optind]; |
@@ -747,13 +735,13 @@ int ping_main(int argc, char **argv) | |||
747 | #else | 735 | #else |
748 | lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET); | 736 | lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET); |
749 | #endif | 737 | #endif |
738 | |||
739 | if (source_lsa && source_lsa->sa.sa_family != lsa->sa.sa_family) | ||
740 | /* leaking it here... */ | ||
741 | source_lsa = NULL; | ||
742 | |||
750 | dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len); | 743 | dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len); |
751 | #if ENABLE_PING6 | 744 | ping(lsa); |
752 | if (lsa->sa.sa_family == AF_INET6) | ||
753 | ping6(lsa); | ||
754 | else | ||
755 | #endif | ||
756 | ping4(lsa); | ||
757 | pingstats(0); | 745 | pingstats(0); |
758 | return EXIT_SUCCESS; | 746 | return EXIT_SUCCESS; |
759 | } | 747 | } |