5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson/*
bd911976d51f102751848568ccf56592fd5f6d77Tinderbox User * Copyright (C) 1999-2002, 2004, 2005, 2007, 2010-2012, 2014-2017 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson */
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id$ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson#include <config.h>
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson#include <stdio.h>
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson#include <isc/buffer.h>
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence#include <isc/msgs.h>
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews#include <isc/net.h>
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson#include <isc/netaddr.h>
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson#include <isc/print.h>
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson#include <isc/sockaddr.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafssonisc_boolean_t
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafssonisc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) {
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson REQUIRE(a != NULL && b != NULL);
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson if (a->family != b->family)
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson return (ISC_FALSE);
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews if (a->zone != b->zone)
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews return (ISC_FALSE);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson switch (a->family) {
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson case AF_INET:
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson if (a->type.in.s_addr != b->type.in.s_addr)
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson return (ISC_FALSE);
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson break;
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson case AF_INET6:
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews if (memcmp(&a->type.in6, &b->type.in6,
ec3f1d35170225c74d11c27bb184e250d150b209Tatuya JINMEI 神明達哉 sizeof(a->type.in6)) != 0 ||
ec3f1d35170225c74d11c27bb184e250d150b209Tatuya JINMEI 神明達哉 a->zone != b->zone)
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson return (ISC_FALSE);
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#ifdef ISC_PLATFORM_HAVESYSUNH
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews case AF_UNIX:
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews if (strcmp(a->type.un, b->type.un) != 0)
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews return (ISC_FALSE);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#endif
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson default:
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson return (ISC_FALSE);
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson }
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson return (ISC_TRUE);
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson}
b356893425f18a2399771faa875e91318f204fb5Andreas Gustafsson
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafssonisc_boolean_t
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafssonisc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson unsigned int prefixlen)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson{
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews const unsigned char *pa = NULL, *pb = NULL;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int ipabytes = 0; /* Length of whole IP address in bytes */
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int nbytes; /* Number of significant whole bytes */
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int nbits; /* Number of significant leftover bits */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson REQUIRE(a != NULL && b != NULL);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (a->family != b->family)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_FALSE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
c53a5699c8242636fd913a4d07b4447efebe3bbfMark Andrews if (a->zone != b->zone && b->zone != 0)
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews return (ISC_FALSE);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson switch (a->family) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson case AF_INET:
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence pa = (const unsigned char *) &a->type.in;
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence pb = (const unsigned char *) &b->type.in;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson ipabytes = 4;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson break;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson case AF_INET6:
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence pa = (const unsigned char *) &a->type.in6;
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence pb = (const unsigned char *) &b->type.in6;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson ipabytes = 16;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson break;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson default:
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_FALSE);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence /*
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence * Don't crash if we get a pattern like 10.0.0.1/9999999.
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence */
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (prefixlen > ipabytes * 8)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson prefixlen = ipabytes * 8;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson nbytes = prefixlen / 8;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson nbits = prefixlen % 8;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (nbytes > 0) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (memcmp(pa, pb, nbytes) != 0)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_FALSE);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (nbits > 0) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson unsigned int bytea, byteb, mask;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson INSIST(nbytes < ipabytes);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson INSIST(nbits < 8);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson bytea = pa[nbytes];
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson byteb = pb[nbytes];
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson mask = (0xFF << (8-nbits)) & 0xFF;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if ((bytea & mask) != (byteb & mask))
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_FALSE);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_TRUE);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson}
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafssonisc_result_t
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafssonisc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) {
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson char abuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews char zbuf[sizeof("%4294967295")];
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson unsigned int alen;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews int zlen;
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson const char *r;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews const void *type;
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson REQUIRE(netaddr != NULL);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews switch (netaddr->family) {
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews case AF_INET:
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews type = &netaddr->type.in;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews break;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews case AF_INET6:
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews type = &netaddr->type.in6;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#ifdef ISC_PLATFORM_HAVESYSUNH
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews case AF_UNIX:
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews alen = strlen(netaddr->type.un);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews if (alen > isc_buffer_availablelength(target))
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews return (ISC_R_NOSPACE);
66a12302e12be6813c3e16e6c05e4a7871e78e6eMark Andrews isc_buffer_putmem(target,
66a12302e12be6813c3e16e6c05e4a7871e78e6eMark Andrews (const unsigned char *)(netaddr->type.un),
66a12302e12be6813c3e16e6c05e4a7871e78e6eMark Andrews alen);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews return (ISC_R_SUCCESS);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#endif
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews default:
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews return (ISC_R_FAILURE);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews }
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf));
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson if (r == NULL)
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson return (ISC_R_FAILURE);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson alen = strlen(abuf);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson INSIST(alen < sizeof(abuf));
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews zlen = 0;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews if (netaddr->family == AF_INET6 && netaddr->zone != 0) {
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews if (zlen < 0)
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews return (ISC_R_FAILURE);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews INSIST((unsigned int)zlen < sizeof(zbuf));
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews }
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews if (alen + zlen > isc_buffer_availablelength(target))
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson return (ISC_R_NOSPACE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson isc_buffer_putmem(target, (unsigned char *)abuf, alen);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews isc_buffer_putmem(target, (unsigned char *)zbuf, zlen);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson return (ISC_R_SUCCESS);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson}
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafssonvoid
28e509b145c3d241d1d2d9102fea38afad95bbd4Andreas Gustafssonisc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) {
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson isc_result_t result;
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson isc_buffer_t buf;
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson isc_buffer_init(&buf, array, size);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson result = isc_netaddr_totext(na, &buf);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
4c577cbd1efc14156751e5b2ced7a866871a2f1aMark Andrews if (size == 0)
4c577cbd1efc14156751e5b2ced7a866871a2f1aMark Andrews return;
4c577cbd1efc14156751e5b2ced7a866871a2f1aMark Andrews
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson /*
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson * Null terminate.
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson */
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson if (result == ISC_R_SUCCESS) {
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson if (isc_buffer_availablelength(&buf) >= 1)
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson isc_buffer_putuint8(&buf, 0);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson else
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson result = ISC_R_NOSPACE;
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson if (result != ISC_R_SUCCESS) {
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson snprintf(array, size,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence ISC_MSG_UNKNOWNADDR,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "<unknown address, family %u>"),
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson na->family);
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson array[size - 1] = '\0';
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson }
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson}
8eaa51a6991ea6bc6c9db0b907beacde8dd1fed2Andreas Gustafsson
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsisc_result_t
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsisc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) {
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews static const unsigned char zeros[16];
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int nbits, nbytes, ipbytes = 0;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews const unsigned char *p;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews switch (na->family) {
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews case AF_INET:
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews p = (const unsigned char *) &na->type.in;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews ipbytes = 4;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews if (prefixlen > 32)
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews return (ISC_R_RANGE);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews break;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews case AF_INET6:
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews p = (const unsigned char *) &na->type.in6;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews ipbytes = 16;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews if (prefixlen > 128)
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews return (ISC_R_RANGE);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews break;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews default:
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews return (ISC_R_NOTIMPLEMENTED);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews }
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews nbytes = prefixlen / 8;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews nbits = prefixlen % 8;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews if (nbits != 0) {
bfbd478cdbd57c1e03c49932cad15b7d6344d709Mark Andrews INSIST(nbytes < ipbytes);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews if ((p[nbytes] & (0xff>>nbits)) != 0U)
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews return (ISC_R_FAILURE);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews nbytes++;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews }
e31a37787bbde482e2e26f89d8ad4c2ada5cc3b8Mark Andrews if (nbytes < ipbytes && memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0)
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews return (ISC_R_FAILURE);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews return (ISC_R_SUCCESS);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews}
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafssonisc_result_t
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrenceisc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) {
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int nbits = 0, nbytes = 0, ipbytes = 0, i;
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence const unsigned char *p;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson switch (s->family) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson case AF_INET:
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence p = (const unsigned char *) &s->type.in;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson ipbytes = 4;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson break;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson case AF_INET6:
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence p = (const unsigned char *) &s->type.in6;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson ipbytes = 16;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson break;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson default:
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_R_NOTIMPLEMENTED);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson for (i = 0; i < ipbytes; i++) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (p[i] != 0xFF)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson break;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson nbytes = i;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (i < ipbytes) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson unsigned int c = p[nbytes];
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson while ((c & 0x80) != 0 && nbits < 8) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson c <<= 1; nbits++;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if ((c & 0xFF) != 0)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_R_MASKNONCONTIG);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson i++;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson for (; i < ipbytes; i++) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson if (p[i] != 0)
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_R_MASKNONCONTIG);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson *lenp = nbytes * 8 + nbits;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson return (ISC_R_SUCCESS);
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson}
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafssonvoid
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrenceisc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina) {
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson memset(netaddr, 0, sizeof(*netaddr));
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson netaddr->family = AF_INET;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson netaddr->type.in = *ina;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson}
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafssonvoid
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrenceisc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) {
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson memset(netaddr, 0, sizeof(*netaddr));
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson netaddr->family = AF_INET6;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson netaddr->type.in6 = *ina6;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson}
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrewsisc_result_t
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrewsisc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path) {
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#ifdef ISC_PLATFORM_HAVESYSUNH
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater if (strlen(path) > sizeof(netaddr->type.un) - 1)
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater return (ISC_R_NOSPACE);
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater memset(netaddr, 0, sizeof(*netaddr));
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater netaddr->family = AF_UNIX;
7cd594b8427fe742d44295790ba367e1de22a47dEvan Hunt strlcpy(netaddr->type.un, path, sizeof(netaddr->type.un));
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater netaddr->zone = 0;
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater return (ISC_R_SUCCESS);
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater#else
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews UNUSED(netaddr);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews UNUSED(path);
33cc94f04cb44dc247f605a954e45e5adc699977Automatic Updater return (ISC_R_NOTIMPLEMENTED);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#endif
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews}
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrewsvoid
e12b02b62c0176646aad3097b3576cd47665e347Mark Andrewsisc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone) {
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews /* we currently only support AF_INET6. */
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews REQUIRE(netaddr->family == AF_INET6);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews netaddr->zone = zone;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews}
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews
e12b02b62c0176646aad3097b3576cd47665e347Mark Andrewsisc_uint32_t
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrewsisc_netaddr_getzone(const isc_netaddr_t *netaddr) {
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews return (netaddr->zone);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews}
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafssonvoid
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graffisc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) {
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson int family = s->type.sa.sa_family;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson t->family = family;
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson switch (family) {
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews case AF_INET:
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson t->type.in = s->type.sin.sin_addr;
cbc0becf053009dd4a94a66c3283aad2fbd512a4Mark Andrews t->zone = 0;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews break;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews case AF_INET6:
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(&t->type.in6, &s->type.sin6.sin6_addr, 16);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews#ifdef ISC_PLATFORM_HAVESCOPEID
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews t->zone = s->type.sin6.sin6_scope_id;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews#else
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews t->zone = 0;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews#endif
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#ifdef ISC_PLATFORM_HAVESYSUNH
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews case AF_UNIX:
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(t->type.un, s->type.sunix.sun_path, sizeof(t->type.un));
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews t->zone = 0;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#endif
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews default:
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews INSIST(0);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews }
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson}
5d82424f5d3c77c092c111b935041fd3dc4b3e98Andreas Gustafsson
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafssonvoid
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafssonisc_netaddr_any(isc_netaddr_t *netaddr) {
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson memset(netaddr, 0, sizeof(*netaddr));
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson netaddr->family = AF_INET;
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson netaddr->type.in.s_addr = INADDR_ANY;
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson}
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafssonvoid
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafssonisc_netaddr_any6(isc_netaddr_t *netaddr) {
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson memset(netaddr, 0, sizeof(*netaddr));
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson netaddr->family = AF_INET6;
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson netaddr->type.in6 = in6addr_any;
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson}
7e361074bc8a2df7a0891a7040eea02ca3a5e286Andreas Gustafsson
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graffisc_boolean_t
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graffisc_netaddr_ismulticast(isc_netaddr_t *na) {
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff switch (na->family) {
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff case AF_INET:
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff return (ISC_TF(ISC_IPADDR_ISMULTICAST(na->type.in.s_addr)));
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff case AF_INET6:
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff return (ISC_TF(IN6_IS_ADDR_MULTICAST(&na->type.in6)));
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff default:
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff return (ISC_FALSE); /* XXXMLG ? */
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff }
d80da258e377f02f0dcd703b89a1044cc58e949fMichael Graff}
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrewsisc_boolean_t
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrewsisc_netaddr_isexperimental(isc_netaddr_t *na) {
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews switch (na->family) {
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews case AF_INET:
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews return (ISC_TF(ISC_IPADDR_ISEXPERIMENTAL(na->type.in.s_addr)));
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews default:
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews return (ISC_FALSE); /* XXXMLG ? */
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews }
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews}
22fa4e3206c2048cabaf75a3ae21132fd5542848Mark Andrews
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrewsisc_boolean_t
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrewsisc_netaddr_islinklocal(isc_netaddr_t *na) {
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews switch (na->family) {
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews case AF_INET:
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews return (ISC_FALSE);
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews case AF_INET6:
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6)));
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews default:
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews return (ISC_FALSE);
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews }
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews}
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrewsisc_boolean_t
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrewsisc_netaddr_issitelocal(isc_netaddr_t *na) {
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews switch (na->family) {
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews case AF_INET:
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews return (ISC_FALSE);
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews case AF_INET6:
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews return (ISC_TF(IN6_IS_ADDR_SITELOCAL(&na->type.in6)));
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews default:
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews return (ISC_FALSE);
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews }
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews}
79a6a33184abff1999ba13b10922ccb34a2758a5Mark Andrews
5be93f5dff21fa067f52065e3521b7d82f32c779Mark Andrews#define ISC_IPADDR_ISNETZERO(i) \
9a4743fca821820464a6ae5be7a6ce1ff0af0e7fTinderbox User (((isc_uint32_t)(i) & ISC__IPADDR(0xff000000)) \
9a4743fca821820464a6ae5be7a6ce1ff0af0e7fTinderbox User == ISC__IPADDR(0x00000000))
6588a2b404365cea59e71a3f639349272600f68dMark Andrews
6588a2b404365cea59e71a3f639349272600f68dMark Andrewsisc_boolean_t
6588a2b404365cea59e71a3f639349272600f68dMark Andrewsisc_netaddr_isnetzero(isc_netaddr_t *na) {
6588a2b404365cea59e71a3f639349272600f68dMark Andrews switch (na->family) {
6588a2b404365cea59e71a3f639349272600f68dMark Andrews case AF_INET:
5be93f5dff21fa067f52065e3521b7d82f32c779Mark Andrews return (ISC_TF(ISC_IPADDR_ISNETZERO(na->type.in.s_addr)));
6588a2b404365cea59e71a3f639349272600f68dMark Andrews case AF_INET6:
6588a2b404365cea59e71a3f639349272600f68dMark Andrews return (ISC_FALSE);
6588a2b404365cea59e71a3f639349272600f68dMark Andrews default:
6588a2b404365cea59e71a3f639349272600f68dMark Andrews return (ISC_FALSE);
6588a2b404365cea59e71a3f639349272600f68dMark Andrews }
6588a2b404365cea59e71a3f639349272600f68dMark Andrews}
6588a2b404365cea59e71a3f639349272600f68dMark Andrews
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellingtonvoid
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellingtonisc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) {
de6fe5ebe289d8e922b2fd8e8d642b6dd4f2a8efDavid Lawrence isc_netaddr_t *src;
de6fe5ebe289d8e922b2fd8e8d642b6dd4f2a8efDavid Lawrence
de6fe5ebe289d8e922b2fd8e8d642b6dd4f2a8efDavid Lawrence DE_CONST(s, src); /* Must come before IN6_IS_ADDR_V4MAPPED. */
de6fe5ebe289d8e922b2fd8e8d642b6dd4f2a8efDavid Lawrence
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington REQUIRE(s->family == AF_INET6);
900d7d9c9bc443110f9a2b93c94def44093d64b0David Lawrence REQUIRE(IN6_IS_ADDR_V4MAPPED(&src->type.in6));
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington
de6fe5ebe289d8e922b2fd8e8d642b6dd4f2a8efDavid Lawrence memset(t, 0, sizeof(*t));
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington t->family = AF_INET;
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(&t->type.in, (char *)&src->type.in6 + 12, 4);
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington return;
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington}
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt
f592d2f76cac7115038124c510d2ba3050334b4dEvan Huntisc_boolean_t
f592d2f76cac7115038124c510d2ba3050334b4dEvan Huntisc_netaddr_isloopback(const isc_netaddr_t *na) {
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt switch (na->family) {
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt case AF_INET:
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt return (ISC_TF((ntohl(na->type.in.s_addr) & 0xff000000U) ==
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt 0x7f000000U));
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt case AF_INET6:
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt return (IN6_IS_ADDR_LOOPBACK(&na->type.in6));
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt default:
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt return (ISC_FALSE);
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt }
f592d2f76cac7115038124c510d2ba3050334b4dEvan Hunt}