X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fliboping.c;h=36a3a3ef623d00c68f68d6fe1bdc241c89d5890e;hb=30ee957b4843140d0d3bae39859d5624824b8feb;hp=579aba31daf41087195d9d523115ea1e662be3b9;hpb=29d946c79b6b5ea54fb5c493267ce15fbfe3d04a;p=liboping.git diff --git a/src/liboping.c b/src/liboping.c index 579aba3..36a3a3e 100644 --- a/src/liboping.c +++ b/src/liboping.c @@ -145,7 +145,7 @@ struct pingobj /* 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; @@ -259,7 +259,8 @@ static uint16_t ping_icmp4_checksum (char *buf, size_t len) 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; @@ -306,7 +307,8 @@ static pinghost_t *ping_receive_ipv4 (pinghost_t *ph, char *buffer, size_t buffe 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); } @@ -314,7 +316,9 @@ static pinghost_t *ping_receive_ipv4 (pinghost_t *ph, char *buffer, size_t buffe 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)); @@ -331,7 +335,8 @@ static pinghost_t *ping_receive_ipv4 (pinghost_t *ph, char *buffer, size_t buffe 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; @@ -339,11 +344,12 @@ static pinghost_t *ping_receive_ipv4 (pinghost_t *ph, char *buffer, size_t buffe 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); } @@ -364,7 +370,8 @@ static pinghost_t *ping_receive_ipv4 (pinghost_t *ph, char *buffer, size_t buffe # 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; @@ -395,7 +402,9 @@ static pinghost_t *ping_receive_ipv6 (pinghost_t *ph, char *buffer, size_t buffe 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)); @@ -412,7 +421,8 @@ static pinghost_t *ping_receive_ipv6 (pinghost_t *ph, char *buffer, size_t buffe 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; @@ -420,15 +430,21 @@ static pinghost_t *ping_receive_ipv6 (pinghost_t *ph, char *buffer, size_t buffe 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; @@ -463,7 +479,7 @@ static int ping_receive_one (int fd, pinghost_t *ph, struct timeval *now) 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 @@ -473,11 +489,10 @@ static int ping_receive_one (int fd, pinghost_t *ph, struct timeval *now) #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)) @@ -526,13 +541,13 @@ static int ping_receive_one (int fd, pinghost_t *ph, struct timeval *now) 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); } @@ -591,7 +606,10 @@ static int ping_receive_all (pingobj_t *obj) 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) { @@ -677,7 +695,7 @@ static int ping_receive_all (pingobj_t *obj) 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) */ @@ -1036,6 +1054,9 @@ int ping_setopt (pingobj_t *obj, int option, void *value) { int ret = 0; + if (value == NULL) + return (-1); + switch (option) { case PING_OPT_TIMEOUT: @@ -1351,6 +1372,7 @@ int ping_host_add (pingobj_t *obj, const char *host) 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; @@ -1358,6 +1380,7 @@ int ping_host_add (pingobj_t *obj, const char *host) setsockopt (ph->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &opt, sizeof (opt)); } +#endif break; }