diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 0aa47e2eb7..de712edb21 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -37,6 +37,9 @@ typedef struct isc_sockaddr { isc_boolean_t isc_sockaddr_equal(isc_sockaddr_t *a, isc_sockaddr_t *b); +isc_boolean_t +isc_sockaddr_eqaddr(isc_sockaddr_t *a, isc_sockaddr_t *b); + unsigned int isc_sockaddr_hash(isc_sockaddr_t *sockaddr, isc_boolean_t address_only); diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index 8a177d09c5..2f6ff55c8b 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -65,6 +65,43 @@ isc_sockaddr_equal(isc_sockaddr_t *a, isc_sockaddr_t *b) return (ISC_TRUE); } + +/* + * compare just the addresses (ignore ports) + */ +isc_boolean_t +isc_sockaddr_eqaddr(isc_sockaddr_t *a, isc_sockaddr_t *b) +{ + REQUIRE(a != NULL && b != NULL); + + if (a->length != b->length) + return (ISC_FALSE); + + /* + * We don't just memcmp because the sin_zero field isn't always + * zero. + */ + + if (a->type.sa.sa_family != b->type.sa.sa_family) + return (ISC_FALSE); + switch (a->type.sa.sa_family) { + case AF_INET: + if (memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr, + sizeof a->type.sin.sin_addr) != 0) + return (ISC_FALSE); + break; + case AF_INET6: + if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr, + sizeof a->type.sin6.sin6_addr) != 0) + return (ISC_FALSE); + break; + default: + if (memcmp(&a->type, &b->type, a->length) != 0) + return (ISC_FALSE); + } + return (ISC_TRUE); +} + char * isc_sockaddr_totext(isc_sockaddr_t *sockaddr, isc_mem_t *mctx) { char abuf[sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255"];