diff --git a/src/icmp-ping.c b/src/icmp-ping.c index 8c2fc1bb..fba906db 100644 --- a/src/icmp-ping.c +++ b/src/icmp-ping.c @@ -279,14 +279,15 @@ int icmp_ping4(main_server_st * s, struct sockaddr_in *addr1, } int icmp_ping6(main_server_st * s, - struct sockaddr_in6 *addr1) + struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2) { struct icmp6_hdr *pkt; - char buf1[64]; + char buf1[64], buf2[64]; int pingsock, c; int sockopt; char packet1[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; - uint16_t id1; + char packet2[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; + uint16_t id1, id2; unsigned gotreply = 0, unreachable = 0; time_t now; @@ -294,6 +295,7 @@ int icmp_ping6(main_server_st * s, return 0; gnutls_rnd(GNUTLS_RND_NONCE, &id1, sizeof(id1)); + gnutls_rnd(GNUTLS_RND_NONCE, &id2, sizeof(id2)); pingsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); @@ -302,6 +304,11 @@ int icmp_ping6(main_server_st * s, pkt->icmp6_type = ICMP6_ECHO_REQUEST; pkt->icmp6_id = id1; + pkt = (struct icmp6_hdr *) packet2; + memset(pkt, 0, sizeof(packet2)); + pkt->icmp6_type = ICMP6_ECHO_REQUEST; + pkt->icmp6_id = id2; + #if defined(SOL_RAW) && defined(IPV6_CHECKSUM) sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, @@ -313,6 +320,13 @@ int icmp_ping6(main_server_st * s, (struct sockaddr *) addr1, sizeof(*addr1)) == -1) && retry(errno)); + while ((c = + sendto(pingsock, packet2, + DEFDATALEN + + sizeof(struct icmp6_hdr), 0, + (struct sockaddr *) addr2, sizeof(*addr2)) == -1) + && retry(errno)); + /* listen for replies */ now = time(0); while (time(0) - now < PING_TIMEOUT @@ -328,10 +342,13 @@ int icmp_ping6(main_server_st * s, } else if (c >= 8 && fromlen == sizeof(struct sockaddr_in6)) { /* icmp6_hdr */ if (memcmp (SA_IN6_P(&from), SA_IN6_P(addr1), - SA_IN_SIZE(sizeof(*addr1))) == 0) { + SA_IN_SIZE(sizeof(*addr1))) == 0 || + memcmp(SA_IN6_P(&from), + SA_IN6_P(addr2), + SA_IN_SIZE(sizeof(*addr2))) == 0) { pkt = (struct icmp6_hdr *) packet1; - if (pkt->icmp6_id == id1) { + if (pkt->icmp6_id == id1 || pkt->icmp6_id == id2) { if (pkt->icmp6_type == ICMP6_ECHO_REPLY) gotreply++; else if (pkt->icmp6_type == ICMP_DEST_UNREACH) @@ -345,17 +362,25 @@ int icmp_ping6(main_server_st * s, if (gotreply > 0) { mslog(s, NULL, LOG_INFO, - "pinged %s and is in use", + "pinged %s and %s and are in use", human_addr((void *) addr1, sizeof(struct sockaddr_in6), buf1, - sizeof(buf1))); + sizeof(buf1)), human_addr((void *) addr2, + sizeof(struct + sockaddr_in6), + buf2, + sizeof(buf2))); return gotreply; } else { mslog(s, NULL, LOG_INFO, - "pinged %s and is not in use", + "pinged %s and %s and are not in use", human_addr((void *) addr1, sizeof(struct sockaddr_in6), buf1, - sizeof(buf1))); + sizeof(buf1)), human_addr((void *) addr2, + sizeof(struct + sockaddr_in6), + buf2, + sizeof(buf2))); return 0; } } diff --git a/src/icmp-ping.h b/src/icmp-ping.h index d401ba7a..406b81a2 100644 --- a/src/icmp-ping.h +++ b/src/icmp-ping.h @@ -26,6 +26,6 @@ /* returns the number of positive replies received or * 0 if no host with this IP exists. */ int icmp_ping4(main_server_st* s, struct sockaddr_in* addr1, struct sockaddr_in* addr2); -int icmp_ping6(main_server_st* s, struct sockaddr_in6* addr1); +int icmp_ping6(main_server_st* s, struct sockaddr_in6* addr1, struct sockaddr_in6* addr2); #endif