/* Even though Posix requires "strerror_r" to return an "int",
* some systems (e.g. the GNU libc) return a "char *" _and_
* ignore the second argument ... -tokkee */
-char *sstrerror (int errnum, char *buf, size_t buflen)
+static char *sstrerror (int errnum, char *buf, size_t buflen)
{
buf[0] = 0;
return (ret);
}
-static pinghost_t *ping_receive_ipv4 (pinghost_t *ph, char *buffer, size_t buffer_len)
+static pinghost_t *ping_receive_ipv4 (pingobj_t *obj, char *buffer,
+ size_t buffer_len)
{
struct ip *ip_hdr;
struct icmp *icmp_hdr;
if (recv_checksum != calc_checksum)
{
- dprintf ("Checksum missmatch: Got 0x%04x, calculated 0x%04x\n",
+ dprintf ("Checksum missmatch: Got 0x%04"PRIx16", "
+ "calculated 0x%04"PRIx16"\n",
recv_checksum, calc_checksum);
return (NULL);
}
ident = ntohs (icmp_hdr->icmp_id);
seq = ntohs (icmp_hdr->icmp_seq);
- for (ptr = ph; ptr != NULL; ptr = ptr->next)
+ /* We have to iterate over all hosts, since ICMPv4 packets may
+ * be received on any raw v4 socket. */
+ for (ptr = obj->head; ptr != NULL; ptr = ptr->next)
{
dprintf ("hostname = %s, ident = 0x%04x, seq = %i\n",
ptr->hostname, ptr->ident, ((ptr->sequence - 1) & 0xFFFF));
if (((ptr->sequence - 1) & 0xFFFF) != seq)
continue;
- dprintf ("Match found: hostname = %s, ident = 0x%04x, seq = %i\n",
+ dprintf ("Match found: hostname = %s, ident = 0x%04"PRIx16", "
+ "seq = %"PRIu16"\n",
ptr->hostname, ident, seq);
break;
if (ptr == NULL)
{
- dprintf ("No match found for ident = 0x%04x, seq = %i\n",
+ dprintf ("No match found for ident = 0x%04"PRIx16", seq = %"PRIu16"\n",
ident, seq);
}
-
- ptr->recv_ttl = ip_hdr->ip_ttl;
+
+ if (ptr != NULL)
+ ptr->recv_ttl = ip_hdr->ip_ttl;
return (ptr);
}
# endif
#endif
-static pinghost_t *ping_receive_ipv6 (pinghost_t *ph, char *buffer, size_t buffer_len)
+static pinghost_t *ping_receive_ipv6 (pingobj_t *obj, char *buffer,
+ size_t buffer_len)
{
struct icmp6_hdr *icmp_hdr;
ident = ntohs (icmp_hdr->icmp6_id);
seq = ntohs (icmp_hdr->icmp6_seq);
- for (ptr = ph; ptr != NULL; ptr = ptr->next)
+ /* We have to iterate over all hosts, since ICMPv6 packets may
+ * be received on any raw v6 socket. */
+ for (ptr = obj->head; ptr != NULL; ptr = ptr->next)
{
dprintf ("hostname = %s, ident = 0x%04x, seq = %i\n",
ptr->hostname, ptr->ident, ((ptr->sequence - 1) & 0xFFFF));
if (((ptr->sequence - 1) & 0xFFFF) != seq)
continue;
- dprintf ("Match found: hostname = %s, ident = 0x%04x, seq = %i\n",
+ dprintf ("Match found: hostname = %s, ident = 0x%04"PRIx16", "
+ "seq = %"PRIu16"\n",
ptr->hostname, ident, seq);
break;
if (ptr == NULL)
{
- dprintf ("No match found for ident = 0x%04x, seq = %i\n",
+ dprintf ("No match found for ident = 0x%04"PRIx16", "
+ "seq = %"PRIu16"\n",
ident, seq);
}
return (ptr);
}
-static int ping_receive_one (int fd, pinghost_t *ph, struct timeval *now)
+static int ping_receive_one (pingobj_t *obj, const pinghost_t *ph,
+ struct timeval *now)
{
+ /* Note: 'ph' is not necessarily the host object for which we receive a
+ * reply. The right object will be returned by ping_receive_ipv*(). For
+ * now, we can only rely on ph->fd and ph->addrfamily. */
+
struct timeval diff;
pinghost_t *host = NULL;
int recv_ttl;
msghdr.msg_flags |= MSG_XPG4_2;
#endif
- payload_buffer_len = recvmsg (fd, &msghdr, /* flags = */ 0);
+ payload_buffer_len = recvmsg (ph->fd, &msghdr, /* flags = */ 0);
if (payload_buffer_len < 0)
{
#if WITH_DEBUG
#endif
return (-1);
}
- dprintf ("Read %zi bytes from fd = %i\n", payload_buffer_len, fd);
+ dprintf ("Read %zi bytes from fd = %i\n", payload_buffer_len, ph->fd);
/* Iterate over all auxiliary data in msghdr */
recv_ttl = -1;
- ph->recv_ttl = -1;
for (cmsg = CMSG_FIRSTHDR (&msghdr); /* {{{ */
cmsg != NULL;
cmsg = CMSG_NXTHDR (&msghdr, cmsg))
if (ph->addrfamily == AF_INET)
{
- host = ping_receive_ipv4 (ph, payload_buffer, payload_buffer_len);
+ host = ping_receive_ipv4 (obj, payload_buffer, payload_buffer_len);
if (host == NULL)
return (-1);
}
else if (ph->addrfamily == AF_INET6)
{
- host = ping_receive_ipv6 (ph, payload_buffer, payload_buffer_len);
+ host = ping_receive_ipv6 (obj, payload_buffer, payload_buffer_len);
if (host == NULL)
return (-1);
}
ret = 0;
for (ptr = ph; ptr != NULL; ptr = ptr->next)
- ptr->latency = -1.0;
+ {
+ ptr->latency = -1.0;
+ ptr->recv_ttl = -1;
+ }
if (gettimeofday (&nowtime, NULL) == -1)
{
for (ptr = ph; ptr != NULL; ptr = ptr->next)
{
if (FD_ISSET (ptr->fd, &readfds))
- if (ping_receive_one (ptr->fd, ph, &nowtime) == 0)
+ if (ping_receive_one (obj, ptr, &nowtime) == 0)
ret++;
}
} /* while (1) */
*/
const char *ping_get_error (pingobj_t *obj)
{
+ if (obj == NULL)
+ return (NULL);
return (obj->errmsg);
}
pinghost_t *current;
pinghost_t *next;
+ if (obj == NULL)
+ return;
+
current = obj->head;
next = NULL;
{
int ret = 0;
+ if ((obj == NULL) || (value == NULL))
+ return (-1);
+
switch (option)
{
case PING_OPT_TIMEOUT:
{
int ret;
+ if (obj == NULL)
+ return (-1);
+
if (ping_send_all (obj) < 0)
return (-1);
struct addrinfo *ai_list, *ai_ptr;
int ai_return;
+ if ((obj == NULL) || (host == NULL))
+ return (-1);
+
dprintf ("host = %s\n", host);
if (ping_host_search (obj->head, host) != NULL)
setsockopt (ph->fd, IPPROTO_IP, IP_RECVTTL,
&opt, sizeof (opt));
}
+#if defined(IPPROTO_IPV6) && defined(IPV6_RECVHOPLIMIT)
else if (ph->addrfamily == AF_INET6)
{
int opt = 1;
setsockopt (ph->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
&opt, sizeof (opt));
}
+#endif
break;
}
{
pinghost_t *pre, *cur;
+ if ((obj == NULL) || (host == NULL))
+ return (-1);
+
pre = NULL;
cur = obj->head;
pingobj_iter_t *ping_iterator_get (pingobj_t *obj)
{
+ if (obj == NULL)
+ return (NULL);
return ((pingobj_iter_t *) obj->head);
}
pingobj_iter_t *ping_iterator_next (pingobj_iter_t *iter)
{
+ if (iter == NULL)
+ return (NULL);
return ((pingobj_iter_t *) iter->next);
}
size_t orig_buffer_len = *buffer_len;
+ if ((iter == NULL) || (buffer == NULL) || (buffer_len == NULL))
+ return (-1);
+
switch (info)
{
case PING_INFO_USERNAME:
void *ping_iterator_get_context (pingobj_iter_t *iter)
{
+ if (iter == NULL)
+ return (NULL);
return (iter->context);
}
void ping_iterator_set_context (pingobj_iter_t *iter, void *context)
{
+ if (iter == NULL)
+ return;
iter->context = context;
}