From: Florian Forster Date: Mon, 12 Jun 2006 20:30:13 +0000 (+0200) Subject: Added the ability to set the source address in the library. X-Git-Tag: liboping-0.3.0~9 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=b827d58ef4e6ab7a53287942a9603287d42e5325;p=liboping.git Added the ability to set the source address in the library. Use `ping_setopt' and `PING_OPT_SOURCE' to set it. This _might_ fail under *BSD and/or Mac OS X, I have to test that.. --- diff --git a/src/liboping.c b/src/liboping.c index 6131107..d74659f 100644 --- a/src/liboping.c +++ b/src/liboping.c @@ -115,14 +115,17 @@ struct pinghost struct pingobj { - double timeout; - int ttl; - int addrfamily; - char *data; + double timeout; + int ttl; + int addrfamily; + char *data; + + struct sockaddr_storage *srcaddr; + socklen_t srcaddrlen; - char errmsg[PING_ERRMSG_LEN]; + char errmsg[PING_ERRMSG_LEN]; - pinghost_t *head; + pinghost_t *head; }; /* @@ -824,6 +827,9 @@ void ping_destroy (pingobj_t *obj) if (obj->data != NULL) free (obj->data); + if (obj->srcaddr != NULL) + free (obj->srcaddr); + free (obj); return; @@ -862,6 +868,11 @@ int ping_setopt (pingobj_t *obj, int option, void *value) obj->addrfamily = PING_DEF_AF; ret = -1; } + if (obj->srcaddr != NULL) + { + free (obj->srcaddr); + obj->srcaddr = NULL; + } break; case PING_OPT_DATA: @@ -873,6 +884,57 @@ int ping_setopt (pingobj_t *obj, int option, void *value) obj->data = strdup ((const char *) value); break; + case PING_OPT_SOURCE: + { + char *hostname = (char *) value; + struct addrinfo ai_hints; + struct addrinfo *ai_list; + int status; + + memset ((void *) &ai_hints, '\0', sizeof (ai_hints)); + ai_hints.ai_family = obj->addrfamily; +#if defined(AI_ADDRCONFIG) + ai_hints.ai_flags = AI_ADDRCONFIG; +#endif + status = getaddrinfo (hostname, NULL, &ai_hints, &ai_list); + if (status != 0) + { + ping_set_error (obj, "getaddrinfo", + status == EAI_SYSTEM + ? strerror (errno) + : gai_strerror (status)); + ret = -1; + break; + } +#if WITH_DEBUG + if (ai_list->ai_next != NULL) + { + dprintf ("hostname = `%s' is ambiguous.\n", hostname); + } +#endif + if (obj->srcaddr == NULL) + { + obj->srcaddrlen = 0; + obj->srcaddr = (struct sockaddr_storage *) malloc (sizeof (struct sockaddr_storage)); + if (obj->srcaddr == NULL) + { + ping_set_error (obj, "malloc", + strerror (errno)); + ret = -1; + freeaddrinfo (ai_list); + break; + } + } + memset ((void *) obj->srcaddr, '\0', sizeof (struct sockaddr_storage)); + assert (ai_list->ai_addrlen <= sizeof (struct sockaddr_storage)); + memcpy ((void *) obj->srcaddr, (const void *) ai_list->ai_addr, + ai_list->ai_addrlen); + obj->srcaddrlen = ai_list->ai_addrlen; + + freeaddrinfo (ai_list); + } /* case PING_OPT_SOURCE */ + break; + default: ret = -2; } /* switch (option) */ diff --git a/src/oping.h b/src/oping.h index 54d0310..4cdb3cf 100644 --- a/src/oping.h +++ b/src/oping.h @@ -49,6 +49,7 @@ typedef struct pingobj pingobj_t; #define PING_OPT_TTL 0x02 #define PING_OPT_AF 0x04 #define PING_OPT_DATA 0x08 +#define PING_OPT_SOURCE 0x10 #define PING_DEF_TIMEOUT 1.0 #define PING_DEF_TTL 255