struct sockaddr *srcaddr;
socklen_t srcaddrlen;
+ char *device;
+
char errmsg[PING_ERRMSG_LEN];
pinghost_t *head;
if (obj->srcaddr != NULL)
free (obj->srcaddr);
+ if (obj->device != NULL)
+ free (obj->device);
+
free (obj);
return;
} /* case PING_OPT_SOURCE */
break;
+ case PING_OPT_DEVICE:
+ {
+#ifdef SO_BINDTODEVICE
+ char *device = strdup ((char *) value);
+
+ if (device == NULL)
+ {
+ ping_set_errno (obj, errno);
+ ret = -1;
+ break;
+ }
+
+ if (obj->device != NULL)
+ free (obj->device);
+ obj->device = device;
+#else /* ! SO_BINDTODEVICE */
+ ping_set_errno (obj, ENOTSUP);
+ ret = -1;
+#endif /* ! SO_BINDTODEVICE */
+ } /* case PING_OPT_DEVICE */
+ break;
+
default:
ret = -2;
} /* switch (option) */
}
}
+#ifdef SO_BINDTODEVICE
+ if (obj->device != NULL)
+ {
+ if (setsockopt (ph->fd, SOL_SOCKET, SO_BINDTODEVICE,
+ obj->device, strlen (obj->device) + 1) != 0)
+ {
+#if WITH_DEBUG
+ char errbuf[PING_ERRMSG_LEN];
+ dprintf ("setsockopt: %s\n",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+#endif
+ ping_set_errno (obj, errno);
+ close (ph->fd);
+ ph->fd = -1;
+ continue;
+ }
+ }
+#endif /* SO_BINDTODEVICE */
+
assert (sizeof (struct sockaddr_storage) >= ai_ptr->ai_addrlen);
memset (ph->addr, '\0', sizeof (struct sockaddr_storage));
memcpy (ph->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
=item B<-I> I<address>
-Set the source address to use. You B<cannot> pass the interface name, as you
-can with GNU's L<ping(8)>.
+Set the source address to use. You may either specify an IP number or a
+hostname. You B<cannot> pass the interface name, as you can with GNU's
+L<ping(8)> - use the B<-D> option for that purpose.
+
+=item B<-D> I<interface name>
+
+Set the outgoing network device to use.
=item B<-f> I<filename>
=item B<PING_OPT_SOURCE>
Set the source address to use. The value passed must be a char-pointer to a
-null-terminated string. This option will ignore the address family setting (as
+null-terminated string specifying either a numerical network address or
+network hostname. This option will ignore the address family setting (as
set with B<PING_OPT_AF>) and will set the object's address family according to
the source address assigned.
+=item B<PING_OPT_DEVICE>
+
+Set the outgoing network device to be used. The value passed must be a
+char-pointer to a null-terminated string specifying an interface name
+(e.E<nbsp>g. C<eth0>). Please note that this might not be supported by all
+operating systems. In that case, B<ping_setopt> sets the error to C<operation
+not supported>.
+
=back
The I<val> argument is a pointer to the new value. It must not be NULL. It is
static double opt_interval = 1.0;
static int opt_addrfamily = PING_DEF_AF;
static char *opt_srcaddr = NULL;
+static char *opt_device = NULL;
static char *opt_filename = NULL;
static int opt_count = -1;
static int opt_send_ttl = 64;
" -i interval interval with which to send ICMP packets\n"
" -t ttl time to live for each ICMP packet\n"
" -I srcaddr source address\n"
+ " -D device outgoing interface name\n"
" -f filename filename to read hosts from\n"
"\noping "PACKAGE_VERSION", http://verplant.org/liboping/\n"
while (1)
{
- optchar = getopt (argc, argv, "46c:hi:I:t:f:");
+ optchar = getopt (argc, argv, "46c:hi:I:t:f:D:");
if (optchar == -1)
break;
}
break;
+ case 'D':
+ opt_device = optarg;
+ break;
+
case 't':
{
int new_send_ttl;
}
}
+ if (opt_device != NULL)
+ {
+ if (ping_setopt (ping, PING_OPT_DEVICE, (void *) opt_device) != 0)
+ {
+ fprintf (stderr, "Setting device failed: %s\n",
+ ping_get_error (ping));
+ }
+ }
+
if (opt_filename != NULL)
{
FILE *infile;
#define PING_OPT_AF 0x04
#define PING_OPT_DATA 0x08
#define PING_OPT_SOURCE 0x10
+#define PING_OPT_DEVICE 0x20
#define PING_DEF_TIMEOUT 1.0
#define PING_DEF_TTL 255