#if DEBUG
# define dprintf(...) printf ("%s[%4i]: %-20s: ", __FILE__, __LINE__, __FUNCTION__); printf (__VA_ARGS__)
#else
-# define dprintf(format, ...) /**/
+# define dprintf(...) /**/
#endif
#define PING_DATA "Florian Forster <octo@verplant.org> http://verplant.org/"
+/*
+ * private (static) functions
+ */
static int ping_timeval_sub (struct timeval *tv1, struct timeval *tv2,
struct timeval *res)
{
return (ptr);
}
-static void ping_receive_one (int fd, pinghost_t *ph)
+static int ping_receive_one (int fd, pinghost_t *ph)
{
char buffer[4096];
size_t buffer_len;
if (buffer_len == -1)
{
dprintf ("recvfrom: %s\n", strerror (errno));
- return;
+ return (-1);
}
dprintf ("Read %i bytes from fd = %i\n", buffer_len, fd);
if (sa.ss_family == AF_INET)
{
if ((host = ping_receive_ipv4 (ph, buffer, buffer_len)) == NULL)
- return;
+ return (-1);
}
else if (sa.ss_family == AF_INET6)
{
if ((host = ping_receive_ipv6 (ph, buffer, buffer_len)) == NULL)
- return;
+ return (-1);
}
if (gettimeofday (&now, NULL) == -1)
{
dprintf ("gettimeofday: %s\n", strerror (errno));
timerclear (host->timer);
- return;
+ return (-1);
}
dprintf ("sent: %12i.%06i\n",
if (ping_timeval_sub (&now, host->timer, &diff) < 0)
{
timerclear (host->timer);
- return;
+ return (-1);
}
dprintf ("diff: %12i.%06i\n",
host->latency += ((double) diff.tv_sec) * 1000.0;
timerclear (host->timer);
+
+ return (0);
}
static int ping_receive_all (pinghost_t *ph)
struct timeval timeout;
int status;
+ int ret;
+
+ ret = 0;
+
if (gettimeofday (&endtime, NULL) == -1)
return (-1);
endtime.tv_sec += 1;
for (ptr = ph; ptr != NULL; ptr = ptr->next)
{
if (FD_ISSET (ptr->fd, &readfds))
- ping_receive_one (ptr->fd, ph);
+ if (ping_receive_one (ptr->fd, ph) == 0)
+ ret++;
}
}
- /* FIXME - return correct status */
- return (0);
+ return (ret);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/*
* public methods
*/
-pingobj_t *ping_construct (int flags)
+pingobj_t *ping_construct (void)
{
pingobj_t *obj;
if ((obj = (pingobj_t *) malloc (sizeof (pingobj_t))) == NULL)
return (NULL);
- obj->flags = flags;
obj->head = NULL;
return (obj);
return;
}
+int ping_setopt (pingobj_t *obj, int option, void *value)
+{
+ int ret = 0;
+
+ switch (option)
+ {
+ case PING_OPT_TIMEOUT:
+ obj->timeout = *((double *) value);
+ if (obj->timeout < 0.0)
+ {
+ obj->timeout = PING_DEF_TIMEOUT;
+ ret = -1;
+ }
+ break;
+
+ case PING_OPT_TTL:
+ obj->ttl = *((int *) value);
+ if ((obj->ttl < 1) || (obj->ttl > 255))
+ {
+ obj->ttl = PING_DEF_TTL;
+ ret = -1;
+ }
+ break;
+
+ case PING_OPT_AF:
+ obj->addrfamily = *((int *) value);
+ if ((obj->addrfamily != AF_UNSPEC)
+ && (obj->addrfamily != AF_INET)
+ && (obj->addrfamily != AF_INET6))
+ {
+ obj->addrfamily = PING_DEF_AF;
+ ret = -1;
+ }
+ break;
+
+ default:
+ ret = -2;
+ } /* switch (option) */
+
+ return (ret);
+} /* int ping_setopt */
+
+
int ping_send (pingobj_t *obj)
{
+ int ret;
+
if (ping_send_all (obj->head) < 0)
return (-1);
- if (ping_receive_all (obj->head) < 0)
+ if ((ret = ping_receive_all (obj->head)) < 0)
return (-2);
- return (0);
+ return (ret);
}
static pinghost_t *ping_host_search (pinghost_t *ph, const char *host)
return (0);
memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_flags = AI_ADDRCONFIG;
- ai_hints.ai_family = PF_UNSPEC;
- ai_hints.ai_socktype = SOCK_RAW;
+ ai_hints.ai_flags = 0;
+#ifdef AI_ADDRCONFIG
+ ai_hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+ ai_hints.ai_family = PF_UNSPEC;
+ ai_hints.ai_socktype = SOCK_RAW;
if ((ph = ping_alloc ()) == NULL)
{
#ifndef OCTO_PING_H
#define OCTO_PING_H 1
-#ifndef AI_ADDRCONFIG
-#define AI_ADDRCONFIG 0
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-
-/* FIXME BEGIN */
#include <stdlib.h>
-#include <stdio.h>
#include <unistd.h>
-#include <assert.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/icmp6.h>
-
-#include <sys/time.h>
-#include <time.h>
-/* FIXME END */
-
/*
* Type definitions
*/
int sequence;
struct timeval *timer;
double latency;
+
struct pinghost *next;
} pinghost_t;
-typedef struct
+typedef pinghost_t pingobj_iter_t;
+
+typedef struct pingobj
{
- int flags;
+ double timeout;
+ int ttl;
+ int addrfamily;
+
pinghost_t *head;
} pingobj_t;
-typedef pinghost_t pingobj_iter_t;
+#define PING_OPT_TIMEOUT 0x01
+#define PING_OPT_TTL 0x02
+#define PING_OPT_AF 0x04
+
+#define PING_DEF_TIMEOUT 1.0
+#define PING_DEF_TTL 255
+#define PING_DEF_AF AF_UNSPEC
/*
* Method definitions
*/
-pingobj_t *ping_construct (int flags);
+pingobj_t *ping_construct (void);
void ping_destroy (pingobj_t *obj);
+int ping_setopt (pingobj_t *obj, int option, void *value);
+
int ping_send (pingobj_t *obj);
int ping_host_add (pingobj_t *obj, const char *host);