wget: -O FILE is allowed to overwrite existing file (compat)
[oweals/busybox.git] / networking / ping.c
index c4a498cd8e925b154864978d94f5dfad488ac29e..5d61cd768058ddaf30300c60e7b4e0a9c9f9ea3c 100644 (file)
@@ -179,7 +179,8 @@ int ping_main(int argc, char **argv)
        len_and_sockaddr *lsa;
 #if ENABLE_PING6
        sa_family_t af = AF_UNSPEC;
-       while (++argv[0][0] == '-') {
+
+       while ((++argv)[0] && argv[0][0] == '-') {
                if (argv[0][1] == '4') {
                        af = AF_INET;
                        continue;
@@ -530,8 +531,12 @@ static void ping4(len_and_sockaddr *lsa)
 
        pingsock = create_icmp_socket();
        pingaddr.sin = lsa->sin;
-       if (source_lsa)
-               xbind(pingsock, &lsa->sa, lsa->len);
+       if (source_lsa) {
+               if (setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_IF,
+                               &source_lsa->sa, source_lsa->len))
+                       bb_error_msg_and_die("can't set multicast source interface");
+               xbind(pingsock, &source_lsa->sa, source_lsa->len);
+       }
 
        /* enable broadcast pings */
        setsockopt_broadcast(pingsock);
@@ -578,7 +583,7 @@ static void ping6(len_and_sockaddr *lsa)
        pingaddr.sin6 = lsa->sin6;
        /* untested whether "-I addr" really works for IPv6: */
        if (source_lsa)
-               xbind(pingsock, &lsa->sa, lsa->len);
+               xbind(pingsock, &source_lsa->sa, source_lsa->len);
 
 #ifdef ICMP6_FILTER
        {
@@ -659,7 +664,7 @@ static void ping(len_and_sockaddr *lsa)
        printf("PING %s (%s)", hostname, dotted);
        if (source_lsa) {
                printf(" from %s",
-                       xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len));
+                       xmalloc_sockaddr2dotted_noport(&source_lsa->sa));
        }
        printf(": %d data bytes\n", datalen);
 
@@ -684,14 +689,13 @@ int ping_main(int argc, char **argv)
 
        /* exactly one argument needed, -v and -q don't mix */
        opt_complementary = "=1:q--v:v--q";
-       getopt32(argc, argv, OPT_STRING, &opt_c, &opt_s, &opt_I);
+       getopt32(argv, OPT_STRING, &opt_c, &opt_s, &opt_I);
        if (option_mask32 & OPT_c) pingcount = xatoul(opt_c); // -c
        if (option_mask32 & OPT_s) datalen = xatou16(opt_s); // -s
        if (option_mask32 & OPT_I) { // -I
                if_index = if_nametoindex(opt_I);
                if (!if_index) {
                        /* TODO: I'm not sure it takes IPv6 unless in [XX:XX..] format */
-                       /* (ping doesn't support source IPv6 addresses yet anyway) */
                        source_lsa = xdotted2sockaddr(opt_I, 0);
                }
        }
@@ -711,7 +715,7 @@ int ping_main(int argc, char **argv)
                /* leaking it here... */
                source_lsa = NULL;
 
-       dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len);
+       dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa);
        ping(lsa);
        pingstats(0);
        return EXIT_SUCCESS;