summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d7b4868)
raw | patch | inline | side by side (parent: d7b4868)
author | octo <octo> | |
Sat, 29 Apr 2006 11:13:32 +0000 (11:13 +0000) | ||
committer | octo <octo> | |
Sat, 29 Apr 2006 11:13:32 +0000 (11:13 +0000) |
configure.ac | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/oping.c | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index 694188784cecd4f8e414c4e6c219092125bd6517..6f74c816f6bd2e6421481d11fe8b9d37127f9d1c 100644 (file)
--- a/configure.ac
+++ b/configure.ac
#
AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(math.h)
AC_CHECK_HEADERS(fcntl.h)
AC_CHECK_HEADERS(sys/types.h)
AC_CHECK_HEADERS(sys/stat.h)
diff --git a/src/Makefile.am b/src/Makefile.am
index 72f00cf8812a1f979faa75310c44fc2e9907186b..08e84455d86fb76ac70d3864864c7316379c99cf 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
oping_SOURCES = oping.c
oping_LDADD = liboping.la
+oping_LDFLAGS = -lm
+if BUILD_WITH_LIBRT
+oping_LDFLAGS += -lrt
+endif
diff --git a/src/oping.c b/src/oping.c
index e70988f34b1779ddfb77fd228e0298176b209d38..b18accf5c699e6768a1fc0c06669a06cc2d94bf3 100644 (file)
--- a/src/oping.c
+++ b/src/oping.c
# error "You don't have the standard C99 header files installed"
#endif /* STDC_HEADERS */
+#if HAVE_MATH_H
+# include <math.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
#if HAVE_NETDB_H
# include <netdb.h> /* NI_MAXHOST */
#endif
#include <liboping.h>
+static double opt_interval = 1.0;
+static int opt_addrfamily = PING_DEF_AF;
+static int opt_count = -1;
+
+void usage_exit (const char *name)
+{
+ fprintf (stderr, "Usage: %s [-46] [-c count] [-i interval] host [host [host ...]]\n",
+ name);
+ exit (1);
+}
+
+int read_options (int argc, char **argv)
+{
+ int optchar;
+
+ while (1)
+ {
+ optchar = getopt (argc, argv, "46c:i:");
+
+ if (optchar == -1)
+ break;
+
+ switch (optchar)
+ {
+ case '4':
+ case '6':
+ opt_addrfamily = (optchar == '4') ? AF_INET : AF_INET6;
+ break;
+
+ case 'c':
+ {
+ int new_count;
+ new_count = atoi (optarg);
+ if (new_count > 0)
+ opt_count = new_count;
+ }
+ break;
+
+ case 'i':
+ {
+ double new_interval;
+ new_interval = atof (optarg);
+ if (new_interval >= 0.2)
+ opt_interval = new_interval;
+ }
+ break;
+
+ default:
+ usage_exit (argv[0]);
+ }
+ }
+
+ return (optind);
+}
+
+void print_host (pingobj_iter_t *iter)
+{
+ 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");
+ return;
+ }
+
+ 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");
+ return;
+ }
+
+ 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);
+}
+
+void time_normalize (struct timespec *ts)
+{
+ while (ts->tv_nsec < 0)
+ {
+ if (ts->tv_sec == 0)
+ {
+ ts->tv_nsec = 0;
+ return;
+ }
+
+ ts->tv_sec -= 1;
+ ts->tv_nsec += 1000000000;
+ }
+
+ while (ts->tv_nsec >= 1000000000)
+ {
+ ts->tv_sec += 1;
+ ts->tv_nsec -= 1000000000;
+ }
+}
+
+void time_calc (struct timespec *ts_dest,
+ const struct timespec *ts_int,
+ const struct timeval *tv_begin,
+ const struct timeval *tv_end)
+{
+ ts_dest->tv_sec = tv_begin->tv_sec + ts_int->tv_sec;
+ ts_dest->tv_nsec = (tv_begin->tv_usec * 1000) + ts_int->tv_nsec;
+ time_normalize (ts_dest);
+
+ /* Assure that `(begin + interval) > end'.
+ * This may seem overly complicated, but `tv_sec' is of type `time_t'
+ * which may be `unsigned. *sigh* */
+ if ((tv_end->tv_sec > ts_dest->tv_sec)
+ || ((tv_end->tv_sec == ts_dest->tv_sec)
+ && ((tv_end->tv_usec * 1000) > ts_dest->tv_nsec)))
+ {
+ ts_dest->tv_sec = 0;
+ ts_dest->tv_nsec = 0;
+ return;
+ }
+
+ ts_dest->tv_sec = ts_dest->tv_sec - tv_end->tv_sec;
+ ts_dest->tv_nsec = ts_dest->tv_nsec - (tv_end->tv_usec * 1000);
+ time_normalize (ts_dest);
+}
+
int main (int argc, char **argv)
{
pingobj_t *ping;
pingobj_iter_t *iter;
+ struct timeval tv_begin;
+ struct timeval tv_end;
+ struct timespec ts_wait;
+ struct timespec ts_int;
+
+ int optind;
int i;
- if (argc < 2)
- {
- printf ("Usage: %s <host> [host [host [...]]]\n", argv[0]);
- return (1);
- }
+
+ optind = read_options (argc, argv);
+
+ if (optind >= argc)
+ usage_exit (argv[0]);
if ((ping = ping_construct ()) == NULL)
{
return (1);
}
- for (i = 1; i < argc; i++)
+ {
+ double temp_sec;
+ double temp_nsec;
+
+ temp_sec = modf (opt_interval, &temp_nsec);
+ ts_int.tv_sec = (time_t) temp_sec;
+ ts_int.tv_nsec = (long) (temp_nsec * 1000000000L);
+ }
+
+ if (opt_addrfamily != PING_DEF_AF)
+ ping_setopt (ping, PING_OPT_AF, (void *) &opt_addrfamily);
+
+ for (i = optind; i < argc; i++)
{
if (ping_host_add (ping, argv[i]) > 0)
{
while (1)
{
+ int status;
+
+ if (opt_count > 0)
+ opt_count--;
+
+ if (gettimeofday (&tv_begin, NULL) < 0)
+ {
+ perror ("gettimeofday");
+ return (1);
+ }
+
if (ping_send (ping) < 0)
{
fprintf (stderr, "ping_send failed\n");
iter != NULL;
iter = ping_iterator_next (iter))
{
- 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;
- }
+ print_host (iter);
+ }
+ fflush (stdout);
- 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;
- }
+ if (opt_count == 0)
+ break;
- buffer_len = sizeof (latency);
- ping_iterator_get_info (iter, PING_INFO_LATENCY,
- &latency, &buffer_len);
+ if (gettimeofday (&tv_end, NULL) < 0)
+ {
+ perror ("gettimeofday");
+ return (1);
+ }
- buffer_len = sizeof (sequence);
- ping_iterator_get_info (iter, PING_INFO_SEQUENCE,
- &sequence, &buffer_len);
+ time_calc (&ts_wait, &ts_int, &tv_begin, &tv_end);
- printf ("echo reply from %s (%s): icmp_seq=%u time=%.1f ms\n",
- host, addr, (unsigned int) sequence, latency);
+ while ((status = nanosleep (&ts_wait, &ts_wait)) != 0)
+ {
+ if (errno != EINTR)
+ {
+ perror ("nanosleep");
+ break;
+ }
}
+ } /* while (opt_count != 0) */
- sleep (1);
- }
+ ping_destroy (ping);
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
- */