# include <unistd.h>
#endif
-#ifndef __USE_BSD
-# define __USE_BSD
-#endif
-
#if HAVE_FCNTL_H
# include <fcntl.h>
#endif
#include "oping.h"
-#if DEBUG
+#if WITH_DEBUG
# define dprintf(...) printf ("%s[%4i]: %-20s: ", __FILE__, __LINE__, __FUNCTION__); printf (__VA_ARGS__)
#else
# define dprintf(...) /**/
#define PING_ERRMSG_LEN 256
-#define PING_DATA "Florian Forster <octo@verplant.org> http://verplant.org/"
-
struct pinghost
{
char *hostname;
int sequence;
struct timeval *timer;
double latency;
+ char *data;
void *context;
double timeout;
int ttl;
int addrfamily;
+ char *data;
char errmsg[PING_ERRMSG_LEN];
icmp4->icmp_id = htons (ph->ident);
icmp4->icmp_seq = htons (ph->sequence);
- strcpy (data, PING_DATA);
+ buflen = 4096 - sizeof (struct icmp);
+ strncpy (data, ph->data, buflen);
datalen = strlen (data);
buflen = datalen + sizeof (struct icmp);
icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
icmp6->icmp6_code = 0;
/* The checksum will be calculated by the TCP/IP stack. */
+ /* FIXME */
icmp6->icmp6_cksum = 0;
icmp6->icmp6_id = htons (ph->ident);
icmp6->icmp6_seq = htons (ph->sequence);
- strcpy (data, PING_DATA);
+ buflen = 4096 - sizeof (struct icmp6_hdr);
+ strncpy (data, ph->data, buflen);
datalen = strlen (data);
buflen = datalen + sizeof (struct icmp6_hdr);
if (ph->hostname != NULL)
free (ph->hostname);
+ if (ph->data != NULL)
+ free (ph->data);
+
free (ph);
}
obj->timeout = PING_DEF_TIMEOUT;
obj->ttl = PING_DEF_TTL;
obj->addrfamily = PING_DEF_AF;
+ obj->data = strdup (PING_DEF_DATA);
return (obj);
}
current = next;
}
+ if (obj->data != NULL)
+ free (obj->data);
+
free (obj);
return;
}
break;
+ case PING_OPT_DATA:
+ if (obj->data != NULL)
+ {
+ free (obj->data);
+ obj->data = NULL;
+ }
+ obj->data = strdup ((const char *) value);
+ break;
+
default:
ret = -2;
} /* switch (option) */
return (-1);
}
+ /* obj->data is not garuanteed to be != NULL */
+ if ((ph->data = strdup (obj->data == NULL ? PING_DEF_DATA : obj->data)) == NULL)
+ {
+ dprintf ("Out of memory!\n");
+ ping_set_error (obj, "strdup", strerror (errno));
+ ping_free (ph);
+ return (-1);
+ }
+
if ((ai_return = getaddrinfo (host, NULL, &ai_hints, &ai_list)) != 0)
{
dprintf ("getaddrinfo failed\n");
return (-1);
}
- ph->next = obj->head;
- obj->head = ph;
+ /*
+ * Adding in the front is much easier, but then the iterator will
+ * return the host that was added last as first host. That's just not
+ * nice. -octo
+ */
+ if (obj->head == NULL)
+ {
+ obj->head = ph;
+ }
+ else
+ {
+ pinghost_t *hptr;
+
+ hptr = obj->head;
+ while (hptr->next != NULL)
+ hptr = hptr->next;
+
+ assert ((hptr != NULL) && (hptr->next == NULL));
+ hptr->next = ph;
+ }
ping_set_ttl (ph, obj->ttl);
ret = 0;
break;
- /* FIXME Return the sequence as an unsigned int */
case PING_INFO_SEQUENCE:
ret = ENOMEM;
- *buffer_len = sizeof (uint16_t);
- if (orig_buffer_len < sizeof (uint16_t))
+ *buffer_len = sizeof (unsigned int);
+ if (orig_buffer_len < sizeof (unsigned int))
break;
- *((uint16_t *) buffer) = (uint16_t) iter->sequence;
+ *((unsigned int *) buffer) = (unsigned int) iter->sequence;
ret = 0;
break;
*((uint16_t *) buffer) = (uint16_t) iter->ident;
ret = 0;
break;
+
+ case PING_INFO_DATA:
+ ret = ENOMEM;
+ *buffer_len = strlen (iter->data);
+ if (orig_buffer_len < *buffer_len)
+ break;
+ strncpy ((char *) buffer, iter->data, orig_buffer_len);
+ ret = 0;
+ break;
}
return (ret);