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;
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);
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
{
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);
/* 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);
}
}
/* 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;