online
  *   ˆl–Ãa¾”ji?u@?pÜŠbÑ¿ÁƒpN·_†I|¥�+ÁÀ ƒ    /*
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
 */

#ifndef ISC_SOCKADDR_H
#define ISC_SOCKADDR_H 1

/*! \file isc/sockaddr.h */

#include <stdbool.h>

#include <isc/lang.h>
#include <isc/net.h>
#include <isc/types.h>
#ifdef ISC_PLATFORM_HAVESYSUNH
#include <sys/un.h>
#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */

struct isc_sockaddr {
	union {
		struct sockaddr		sa;
		struct sockaddr_in	sin;
		struct sockaddr_in6	sin6;
		struct sockaddr_storage ss;
#ifdef ISC_PLATFORM_HAVESYSUNH
		struct sockaddr_un sunix;
#endif /* ifdef ISC_PLATFORM_HAVESYSUNH */
	} type;
	unsigned int length; /* XXXRTH beginning? */
	ISC_LINK(struct isc_sockaddr) link;
};

#define ISC_SOCKADDR_CMPADDR            \
	0x0001 /*%< compare the address \
		*   sin_addr/sin6_addr */
#define ISC_SOCKADDR_CMPPORT         \
	0x0002 /*%< compare the port \
		*   sin_port/sin6_port */
#define ISC_SOCKADDR_CMPSCOPE         \
	0x0004 /*%< compare the scope \
		*   sin6_scope */
#define ISC_SOCKADDR_CMPSCOPEZERO         \
	0x0008 /*%< when comparing scopes \
		*   zero scopes always match */

ISC_LANG_BEGINDECLS

bool
isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
		     unsigned int flags);
/*%<
 * Compare the elements of the two address ('a' and 'b') as specified
 * by 'flags' and report if they are equal or not.
 *
 * 'flags' is set from ISC_SOCKADDR_CMP*.
 */

bool
isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
/*%<
 * Return true iff the socket addresses 'a' and 'b' are equal.
 */

bool
isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
/*%<
 * Return true iff the address parts of the socket addresses
 * 'a' and 'b' are equal, ignoring the ports.
 */

bool
isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
			  unsigned int prefixlen);
/*%<
 * Return true iff the most significant 'prefixlen' bits of the
 * socket addresses 'a' and 'b' are equal, ignoring the ports.
 * If 'b''s scope is zero then 'a''s scope will be ignored.
 */

unsigned int
isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, bool address_only);
/*%<
 * Return a hash value for the socket address 'sockaddr'.  If 'address_only'
 * is true, the hash value will not depend on the port.
 *
 * IPv6 addresses containing mapped IPv4 addresses generate the same hash
 * value as the equivalent IPv4 address.
 */

void
isc_sockaddr_any(isc_sockaddr_t *sockaddr);
/*%<
 * Return the IPv4 wildcard address.
 */

void
isc_sockaddr_any6(isc_sockaddr_t *sockaddr);
/*%<
 * Return the IPv6 wildcard address.
 */

void
isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int family);
/*%<
 * Set '*sockaddr' to the wildcard address of protocol family
 * 'family'.
 *
 * Requires:
 * \li	'family' is AF_INET or AF_INET6.
 */

void
isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
		    in_port_t port);
/*%<
 * Construct an isc_sockaddr_t from an IPv4 address and port.
 */

void
isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6,
		     in_port_t port);
/*%<
 * Construct an isc_sockaddr_t from an IPv6 address and port.
 */

void
isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
		      in_port_t port);
/*%<
 * Construct an IPv6 isc_sockaddr_t representing a mapped IPv4 address.
 */

void
isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
			 in_port_t port);
/*%<
 * Construct an isc_sockaddr_t from an isc_netaddr_t and port.
 */

int
isc_sockaddr_pf(const isc_sockaddr_t *sockaddr);
/*%<
 * Get the protocol family of 'sockaddr'.
 *
 * Requires:
 *
 *\li	'sockaddr' is a valid sockaddr with an address family of AF_INET
 *	or AF_INET6.
 *
 * Returns:
 *
