From d7b4868eaebaa8cda3f0cb907a4da4556ef5bd9e Mon Sep 17 00:00:00 2001 From: octo Date: Sat, 29 Apr 2006 09:24:21 +0000 Subject: [PATCH] Implemented `ping_iterator_get_info' which obsoletes `ping_iterator_get_{hostname,latency}' and adds additional functionality. --- src/liboping.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++---- src/liboping.h | 10 ++++-- src/oping.c | 68 +++++++++++++++++++++++++++++++++-------- 3 files changed, 140 insertions(+), 21 deletions(-) diff --git a/src/liboping.c b/src/liboping.c index fb6df676..e1604e71 100644 --- a/src/liboping.c +++ b/src/liboping.c @@ -1056,12 +1056,83 @@ pingobj_iter_t *ping_iterator_next (pingobj_iter_t *iter) return ((pingobj_iter_t *) iter->next); } -const char *ping_iterator_get_host (pingobj_iter_t *iter) +int ping_iterator_get_info (pingobj_iter_t *iter, int info, + void *buffer, size_t *buffer_len) { - return (iter->hostname); -} + int ret = EINVAL; -double ping_iterator_get_latency (pingobj_iter_t *iter) -{ - return (iter->latency); + size_t orig_buffer_len = *buffer_len; + + switch (info) + { + case PING_INFO_HOSTNAME: + ret = ENOMEM; + *buffer_len = strlen (iter->hostname); + if (orig_buffer_len <= *buffer_len) + break; + /* Since (orig_buffer_len > *buffer_len) `strncpy' + * will copy `*buffer_len' and pad the rest of + * `buffer' with null-bytes */ + strncpy (buffer, iter->hostname, orig_buffer_len); + ret = 0; + break; + + case PING_INFO_ADDRESS: + ret = getnameinfo ((struct sockaddr *) iter->addr, + iter->addrlen, + (char *) buffer, + *buffer_len, + NULL, 0, + NI_NUMERICHOST); + if (ret != 0) + { + if ((ret == EAI_OVERFLOW) + || (ret == EAI_MEMORY)) + ret = ENOMEM; + else if (ret == EAI_SYSTEM) + /* XXX: Not thread-safe! */ + ret = errno; + else + ret = EINVAL; + } + break; + + case PING_INFO_FAMILY: + ret = ENOMEM; + *buffer_len = sizeof (int); + if (orig_buffer_len < sizeof (int)) + break; + *((int *) buffer) = iter->addrfamily; + ret = 0; + break; + + case PING_INFO_LATENCY: + ret = ENOMEM; + *buffer_len = sizeof (double); + if (orig_buffer_len < sizeof (double)) + break; + *((double *) buffer) = iter->latency; + ret = 0; + break; + + case PING_INFO_SEQUENCE: + ret = ENOMEM; + *buffer_len = sizeof (uint16_t); + if (orig_buffer_len < sizeof (uint16_t)) + break; + *((uint16_t *) buffer) = (uint16_t) iter->sequence; + ret = 0; + break; + + case PING_INFO_IDENT: + ret = ENOMEM; + *buffer_len = sizeof (uint16_t); + if (orig_buffer_len < sizeof (uint16_t)) + break; + *((uint16_t *) buffer) = (uint16_t) iter->ident; + ret = 0; + break; + } + + return (ret); } diff --git a/src/liboping.h b/src/liboping.h index 9fd7597f..97f116dd 100644 --- a/src/liboping.h +++ b/src/liboping.h @@ -69,8 +69,14 @@ int ping_host_remove (pingobj_t *obj, const char *host); pingobj_iter_t *ping_iterator_get (pingobj_t *obj); pingobj_iter_t *ping_iterator_next (pingobj_iter_t *iter); -const char *ping_iterator_get_host (pingobj_iter_t *iter); -double ping_iterator_get_latency (pingobj_iter_t *iter); +#define PING_INFO_HOSTNAME 1 +#define PING_INFO_ADDRESS 2 +#define PING_INFO_FAMILY 3 +#define PING_INFO_LATENCY 4 +#define PING_INFO_SEQUENCE 5 +#define PING_INFO_IDENT 6 +int ping_iterator_get_info (pingobj_iter_t *iter, int info, + void *buffer, size_t *buffer_len); const char *ping_get_error (pingobj_t *obj); diff --git a/src/oping.c b/src/oping.c index 65d74c7c..e70988f3 100644 --- a/src/oping.c +++ b/src/oping.c @@ -31,6 +31,10 @@ # error "You don't have the standard C99 header files installed" #endif /* STDC_HEADERS */ +#if HAVE_NETDB_H +# include /* NI_MAXHOST */ +#endif + #include int main (int argc, char **argv) @@ -49,17 +53,15 @@ int main (int argc, char **argv) if ((ping = ping_construct ()) == NULL) { fprintf (stderr, "ping_construct failed\n"); - return (-1); + return (1); } for (i = 1; i < argc; i++) { - printf ("Adding host `%s'..\n", argv[i]); - if (ping_host_add (ping, argv[i]) > 0) { - fprintf (stderr, "ping_host_add (verplant.org) failed\n"); - return (-1); + fprintf (stderr, "ping_host_add (%s) failed\n", argv[i]); + return (1); } } @@ -68,22 +70,62 @@ int main (int argc, char **argv) if (ping_send (ping) < 0) { fprintf (stderr, "ping_send failed\n"); - return (-1); + return (1); } - for (iter = ping_iterator_get (ping); iter != NULL; iter = ping_iterator_next (iter)) + for (iter = ping_iterator_get (ping); + iter != NULL; + iter = ping_iterator_next (iter)) { - const char *host; - double latency; + char host[NI_MAXHOST]; + char addr[NI_MAXHOST]; + double latency; + uint16_t sequence; + size_t buffer_len; + + buffer_len = sizeof (host); + if (ping_iterator_get_info (iter, PING_INFO_HOSTNAME, + host, &buffer_len) != 0) + { + fprintf (stderr, "ping_iterator_get_info failed.\n"); + continue; + } - host = ping_iterator_get_host (iter); - latency = ping_iterator_get_latency (iter); + buffer_len = sizeof (addr); + if (ping_iterator_get_info (iter, PING_INFO_ADDRESS, + addr, &buffer_len) != 0) + { + fprintf (stderr, "ping_iterator_get_info failed.\n"); + continue; + } - printf ("host = %s, latency = %f\n", host, latency); + buffer_len = sizeof (latency); + ping_iterator_get_info (iter, PING_INFO_LATENCY, + &latency, &buffer_len); + + buffer_len = sizeof (sequence); + ping_iterator_get_info (iter, PING_INFO_SEQUENCE, + &sequence, &buffer_len); + + printf ("echo reply from %s (%s): icmp_seq=%u time=%.1f ms\n", + host, addr, (unsigned int) sequence, latency); } - sleep (5); + sleep (1); } return (0); } + +/* + * octo@leeloo:~ $ ping verplant.org + * PING verplant.org (213.95.21.52) 56(84) bytes of data. + * 64 bytes from verplant.org (213.95.21.52): icmp_seq=1 ttl=57 time=141 ms + * 64 bytes from verplant.org (213.95.21.52): icmp_seq=2 ttl=57 time=47.0 ms + * 64 bytes from verplant.org (213.95.21.52): icmp_seq=3 ttl=57 time=112 ms + * 64 bytes from verplant.org (213.95.21.52): icmp_seq=4 ttl=57 time=46.7 ms + * + * --- verplant.org ping statistics --- + * 4 packets transmitted, 4 received, 0% packet loss, time 3002ms + * rtt min/avg/max/mdev = 46.782/86.870/141.373/41.257 ms + */ -- 2.30.2