From: Sebastian Harl Date: Fri, 17 Jul 2009 12:05:17 +0000 (+0200) Subject: Added support for PING_OPT_DEVICE. X-Git-Tag: liboping-1.3.0~9 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=6f3b7d94ab32cd6fc94398ebd326055ad36d88f2;p=liboping.git Added support for PING_OPT_DEVICE. This option may be used to 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.g. eth0). Please note that this might not be supported by all operating systems. In that case, ping_setopt() sets the error to "operation not supported". --- diff --git a/src/liboping.c b/src/liboping.c index b21188b..acbc715 100644 --- a/src/liboping.c +++ b/src/liboping.c @@ -134,6 +134,8 @@ struct pingobj struct sockaddr *srcaddr; socklen_t srcaddrlen; + char *device; + char errmsg[PING_ERRMSG_LEN]; pinghost_t *head; @@ -1045,6 +1047,9 @@ void ping_destroy (pingobj_t *obj) if (obj->srcaddr != NULL) free (obj->srcaddr); + if (obj->device != NULL) + free (obj->device); + free (obj); return; @@ -1167,6 +1172,28 @@ int ping_setopt (pingobj_t *obj, int option, void *value) } /* 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) */ @@ -1334,6 +1361,25 @@ int ping_host_add (pingobj_t *obj, const char *host) } } +#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); diff --git a/src/mans/ping_setopt.pod b/src/mans/ping_setopt.pod index 2452701..ad85979 100644 --- a/src/mans/ping_setopt.pod +++ b/src/mans/ping_setopt.pod @@ -53,10 +53,19 @@ L command. =item B 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) and will set the object's address family according to the source address assigned. +=item B + +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.Eg. C). Please note that this might not be supported by all +operating systems. In that case, B sets the error to C. + =back The I argument is a pointer to the new value. It must not be NULL. It is diff --git a/src/oping.h b/src/oping.h index 0debadf..2ffdf1f 100644 --- a/src/oping.h +++ b/src/oping.h @@ -59,6 +59,7 @@ typedef struct pingobj pingobj_t; #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