19439Sprr/*	$NetBSD: sockaddr.h,v 1.7 2024/02/21 22:52:31 christos Exp $	*/
29439Sprr
39439Sprr/*
49439Sprr * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
59439Sprr *
69439Sprr * SPDX-License-Identifier: MPL-2.0
79439Sprr *
89439Sprr * This Source Code Form is subject to the terms of the Mozilla Public
99439Sprr * License, v. 2.0. If a copy of the MPL was not distributed with this
109439Sprr * file, you can obtain one at https://mozilla.org/MPL/2.0/.
119439Sprr *
129439Sprr * See the COPYRIGHT file distributed with this work for additional
139439Sprr * information regarding copyright ownership.
149439Sprr */
159439Sprr
169439Sprr#pragma once
179439Sprr
189439Sprr/*! \file isc/sockaddr.h */
199439Sprr
209439Sprr#include <stdbool.h>
219439Sprr
229439Sprr#include <isc/lang.h>
239439Sprr#include <isc/net.h>
249439Sprr#include <isc/types.h>
259439Sprr
269439Sprr#include <sys/un.h>
279439Sprr
289439Sprr/*
299439Sprr * Any updates to this structure should also be applied in
309439Sprr * contrib/modules/dlz/dlz_minmal.h.
319439Sprr */
329439Sprrstruct isc_sockaddr {
339439Sprr	union {
349439Sprr		struct sockaddr		sa;
359439Sprr		struct sockaddr_in	sin;
369439Sprr		struct sockaddr_in6	sin6;
379439Sprr		struct sockaddr_storage ss;
389439Sprr		struct sockaddr_un	sunix;
399439Sprr	} type;
409439Sprr	unsigned int length; /* XXXRTH beginning? */
419439Sprr	ISC_LINK(struct isc_sockaddr) link;
429439Sprr};
439439Sprr
449439Sprr#define ISC_SOCKADDR_CMPADDR            \
459439Sprr	0x0001 /*%< compare the address \
469439Sprr		*   sin_addr/sin6_addr */
479439Sprr#define ISC_SOCKADDR_CMPPORT         \
489439Sprr	0x0002 /*%< compare the port \
499439Sprr		*   sin_port/sin6_port */
509439Sprr#define ISC_SOCKADDR_CMPSCOPE         \
519439Sprr	0x0004 /*%< compare the scope \
529439Sprr		*   sin6_scope */
539439Sprr#define ISC_SOCKADDR_CMPSCOPEZERO         \
549439Sprr	0x0008 /*%< when comparing scopes \
559439Sprr		*   zero scopes always match */
569439Sprr
579439SprrISC_LANG_BEGINDECLS
589439Sprr
599439Sprrbool
609439Sprrisc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
619439Sprr		     unsigned int flags);
629439Sprr/*%<
639439Sprr * Compare the elements of the two address ('a' and 'b') as specified
649439Sprr * by 'flags' and report if they are equal or not.
659439Sprr *
669439Sprr * 'flags' is set from ISC_SOCKADDR_CMP*.
679439Sprr */
689439Sprr
69bool
70isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
71/*%<
72 * Return true iff the socket addresses 'a' and 'b' are equal.
73 */
74
75bool
76isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
77/*%<
78 * Return true iff the address parts of the socket addresses
79 * 'a' and 'b' are equal, ignoring the ports.
80 */
81
82bool
83isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
84			  unsigned int prefixlen);
85/*%<
86 * Return true iff the most significant 'prefixlen' bits of the
87 * socket addresses 'a' and 'b' are equal, ignoring the ports.
88 * If 'b''s scope is zero then 'a''s scope will be ignored.
89 */
90
91unsigned int
92isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, bool address_only);
93/*%<
94 * Return a hash value for the socket address 'sockaddr'.  If 'address_only'
95 * is true, the hash value will not depend on the port.
96 *
97 * IPv6 addresses containing mapped IPv4 addresses generate the same hash
98 * value as the equivalent IPv4 address.
99 */
100
101void
102isc_sockaddr_any(isc_sockaddr_t *sockaddr);
103/*%<
104 * Return the IPv4 wildcard address.
105 */
106
107void
108isc_sockaddr_any6(isc_sockaddr_t *sockaddr);
109/*%<
110 * Return the IPv6 wildcard address.
111 */
112
113void
114isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int family);
115/*%<
116 * Set '*sockaddr' to the wildcard address of protocol family
117 * 'family'.
118 *
119 * Requires:
120 * \li	'family' is AF_INET or AF_INET6.
121 */
122
123void
124isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
125		    in_port_t port);
126/*%<
127 * Construct an isc_sockaddr_t from an IPv4 address and port.
128 */
129
130void
131isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6,
132		     in_port_t port);
133/*%<
134 * Construct an isc_sockaddr_t from an IPv6 address and port.
135 */
136
137void
138isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
139		      in_port_t port);
140/*%<
141 * Construct an IPv6 isc_sockaddr_t representing a mapped IPv4 address.
142 */
143
144void
145isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
146			 in_port_t port);
147/*%<
148 * Construct an isc_sockaddr_t from an isc_netaddr_t and port.
149 */
150
151int
152isc_sockaddr_pf(const isc_sockaddr_t *sockaddr);
153/*%<
154 * Get the protocol family of 'sockaddr'.
155 *
156 * Requires:
157 *
158 *\li	'sockaddr' is a valid sockaddr with an address family of AF_INET
159 *	or AF_INET6.
160 *
161 * Returns:
162 *
163 *\li	The protocol family of 'sockaddr', e.g. PF_INET or PF_INET6.
164 */
165
166void
167isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port);
168/*%<
169 * Set the port of 'sockaddr' to 'port'.
170 */
171
172in_port_t
173isc_sockaddr_getport(const isc_sockaddr_t *sockaddr);
174/*%<
175 * Get the port stored in 'sockaddr'.
176 */
177
178isc_result_t
179isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target);
180/*%<
181 * Append a text representation of 'sockaddr' to the buffer 'target'.
182 * The text will include both the IP address (v4 or v6) and the port.
183 * The text is null terminated, but the terminating null is not
184 * part of the buffer's used region.
185 *
186 * Returns:
187 * \li	ISC_R_SUCCESS
188 * \li	ISC_R_NOSPACE	The text or the null termination did not fit.
189 */
190
191void
192isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size);
193/*%<
194 * Format a human-readable representation of the socket address '*sa'
195 * into the character array 'array', which is of size 'size'.
196 * The resulting string is guaranteed to be null-terminated.
197 */
198
199bool
200isc_sockaddr_ismulticast(const isc_sockaddr_t *sa);
201/*%<
202 * Returns #true if the address is a multicast address.
203 */
204
205bool
206isc_sockaddr_isexperimental(const isc_sockaddr_t *sa);
207/*
208 * Returns true if the address is a experimental (CLASS E) address.
209 */
210
211bool
212isc_sockaddr_islinklocal(const isc_sockaddr_t *sa);
213/*%<
214 * Returns true if the address is a link local address.
215 */
216
217bool
218isc_sockaddr_issitelocal(const isc_sockaddr_t *sa);
219/*%<
220 * Returns true if the address is a sitelocal address.
221 */
222
223bool
224isc_sockaddr_isnetzero(const isc_sockaddr_t *sa);
225/*%<
226 * Returns true if the address is in net zero.
227 */
228
229isc_result_t
230isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path);
231/*
232 *  Create a UNIX domain sockaddr that refers to path.
233 *
234 * Returns:
235 * \li	ISC_R_NOSPACE
236 * \li	ISC_R_NOTIMPLEMENTED
237 * \li	ISC_R_SUCCESS
238 */
239
240isc_result_t
241isc_sockaddr_fromsockaddr(isc_sockaddr_t *isa, const struct sockaddr *sa);
242
243#define ISC_SOCKADDR_FORMATSIZE                                            \
244	sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS#" \
245	       "YYYYY")
246/*%<
247 * Minimum size of array to pass to isc_sockaddr_format().
248 */
249
250ISC_LANG_ENDDECLS
251