xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isc/unix/include/isc/net.h (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
1 /*	$NetBSD: net.h,v 1.1 2024/02/18 20:57:57 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #ifndef ISC_NET_H
17 #define ISC_NET_H 1
18 
19 /*****
20 ***** Module Info
21 *****/
22 
23 /*! \file
24  * \brief
25  * Basic Networking Types
26  *
27  * This module is responsible for defining the following basic networking
28  * types:
29  *
30  *\li		struct in_addr
31  *\li		struct in6_addr
32  *\li		struct in6_pktinfo
33  *\li		struct sockaddr
34  *\li		struct sockaddr_in
35  *\li		struct sockaddr_in6
36  *\li		struct sockaddr_storage
37  *\li		in_port_t
38  *
39  * It ensures that the AF_ and PF_ macros are defined.
40  *
41  * It declares ntoh[sl]() and hton[sl]().
42  *
43  * It declares inet_ntop(), and inet_pton().
44  *
45  * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
46  * IN6ADDR_V4MAPPED_INIT, in6addr_any, and in6addr_loopback are available.
47  *
48  * It ensures that IN_MULTICAST() is available to check for multicast
49  * addresses.
50  *
51  * MP:
52  *\li	No impact.
53  *
54  * Reliability:
55  *\li	No anticipated impact.
56  *
57  * Resources:
58  *\li	N/A.
59  *
60  * Security:
61  *\li	No anticipated impact.
62  *
63  * Standards:
64  *\li	BSD Socket API
65  *\li	RFC2553
66  */
67 
68 /***
69  *** Imports.
70  ***/
71 #include <inttypes.h>
72 
73 #include <isc/lang.h>
74 #include <isc/platform.h>
75 #include <isc/types.h>
76 
77 #include <arpa/inet.h> /* Contractual promise. */
78 #include <net/if.h>
79 #include <netinet/in.h> /* Contractual promise. */
80 #include <sys/socket.h> /* Contractual promise. */
81 #include <sys/types.h>
82 
83 #ifndef IN6ADDR_LOOPBACK_INIT
84 #ifdef s6_addr
85 /*% IPv6 address loopback init */
86 #define IN6ADDR_LOOPBACK_INIT                                                  \
87 	{                                                                      \
88 		{                                                              \
89 			{                                                      \
90 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
91 			}                                                      \
92 		}                                                              \
93 	}
94 #else /* ifdef s6_addr */
95 #define IN6ADDR_LOOPBACK_INIT                                          \
96 	{                                                              \
97 		{                                                      \
98 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
99 		}                                                      \
100 	}
101 #endif /* ifdef s6_addr */
102 #endif /* ifndef IN6ADDR_LOOPBACK_INIT */
103 
104 #ifndef IN6ADDR_V4MAPPED_INIT
105 #ifdef s6_addr
106 /*% IPv6 v4mapped prefix init */
107 #define IN6ADDR_V4MAPPED_INIT                                                \
108 	{                                                                    \
109 		{                                                            \
110 			{                                                    \
111 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, \
112 					0, 0, 0                              \
113 			}                                                    \
114 		}                                                            \
115 	}
116 #else /* ifdef s6_addr */
117 #define IN6ADDR_V4MAPPED_INIT                                                \
118 	{                                                                    \
119 		{                                                            \
120 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0 \
121 		}                                                            \
122 	}
123 #endif /* ifdef s6_addr */
124 #endif /* ifndef IN6ADDR_V4MAPPED_INIT */
125 
126 #ifndef IN6_IS_ADDR_V4MAPPED
127 /*% Is IPv6 address V4 mapped? */
128 #define IN6_IS_ADDR_V4MAPPED(x)                                \
129 	(memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
130 	 (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
131 #endif /* ifndef IN6_IS_ADDR_V4MAPPED */
132 
133 #ifndef IN6_IS_ADDR_V4COMPAT
134 /*% Is IPv6 address V4 compatible? */
135 #define IN6_IS_ADDR_V4COMPAT(x)                                \
136 	(memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
137 	 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 ||    \
138 	  (x)->s6_addr[14] != 0 ||                             \
139 	  ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
140 #endif /* ifndef IN6_IS_ADDR_V4COMPAT */
141 
142 #ifndef IN6_IS_ADDR_MULTICAST
143 /*% Is IPv6 address multicast? */
144 #define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)
145 #endif /* ifndef IN6_IS_ADDR_MULTICAST */
146 
147 #ifndef IN6_IS_ADDR_LINKLOCAL
148 /*% Is IPv6 address linklocal? */
149 #define IN6_IS_ADDR_LINKLOCAL(a) \
150 	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
151 #endif /* ifndef IN6_IS_ADDR_LINKLOCAL */
152 
153 #ifndef IN6_IS_ADDR_SITELOCAL
154 /*% is IPv6 address sitelocal? */
155 #define IN6_IS_ADDR_SITELOCAL(a) \
156 	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
157 #endif /* ifndef IN6_IS_ADDR_SITELOCAL */
158 
159 #ifndef IN6_IS_ADDR_LOOPBACK
160 /*% is IPv6 address loopback? */
161 #define IN6_IS_ADDR_LOOPBACK(x) \
162 	(memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
163 #endif /* ifndef IN6_IS_ADDR_LOOPBACK */
164 
165 #ifndef AF_INET6
166 /*% IPv6 */
167 #define AF_INET6 99
168 #endif /* ifndef AF_INET6 */
169 
170 #ifndef PF_INET6
171 /*% IPv6 */
172 #define PF_INET6 AF_INET6
173 #endif /* ifndef PF_INET6 */
174 
175 #ifndef INADDR_ANY
176 /*% inaddr any */
177 #define INADDR_ANY 0x00000000UL
178 #endif /* ifndef INADDR_ANY */
179 
180 #ifndef INADDR_LOOPBACK
181 /*% inaddr loopback */
182 #define INADDR_LOOPBACK 0x7f000001UL
183 #endif /* ifndef INADDR_LOOPBACK */
184 
185 #ifndef MSG_TRUNC
186 /*%
187  * If this system does not have MSG_TRUNC (as returned from recvmsg())
188  * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
189  * faking code in socket.c.
190  */
191 #define ISC_PLATFORM_RECVOVERFLOW
192 #endif /* ifndef MSG_TRUNC */
193 
194 /*% IP address. */
195 #define ISC__IPADDR(x) ((uint32_t)htonl((uint32_t)(x)))
196 
197 /*% Is IP address multicast? */
198 #define ISC_IPADDR_ISMULTICAST(i) \
199 	(((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xe0000000))
200 
201 #define ISC_IPADDR_ISEXPERIMENTAL(i) \
202 	(((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xf0000000))
203 
204 /***
205  *** Functions.
206  ***/
207 
208 ISC_LANG_BEGINDECLS
209 
210 isc_result_t
211 isc_net_probeipv4(void);
212 /*%<
213  * Check if the system's kernel supports IPv4.
214  *
215  * Returns:
216  *
217  *\li	#ISC_R_SUCCESS		IPv4 is supported.
218  *\li	#ISC_R_NOTFOUND		IPv4 is not supported.
219  *\li	#ISC_R_DISABLED		IPv4 is disabled.
220  *\li	#ISC_R_UNEXPECTED
221  */
222 
223 isc_result_t
224 isc_net_probeipv6(void);
225 /*%<
226  * Check if the system's kernel supports IPv6.
227  *
228  * Returns:
229  *
230  *\li	#ISC_R_SUCCESS		IPv6 is supported.
231  *\li	#ISC_R_NOTFOUND		IPv6 is not supported.
232  *\li	#ISC_R_DISABLED		IPv6 is disabled.
233  *\li	#ISC_R_UNEXPECTED
234  */
235 
236 isc_result_t
237 isc_net_probe_ipv6only(void);
238 /*%<
239  * Check if the system's kernel supports the IPV6_V6ONLY socket option.
240  *
241  * Returns:
242  *
243  *\li	#ISC_R_SUCCESS		the option is supported for both TCP and UDP.
244  *\li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
245  *\li	#ISC_R_UNEXPECTED
246  */
247 
248 isc_result_t
249 isc_net_probe_ipv6pktinfo(void);
250 /*
251  * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
252  * for UDP sockets.
253  *
254  * Returns:
255  *
256  * \li	#ISC_R_SUCCESS		the option is supported.
257  * \li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
258  * \li	#ISC_R_UNEXPECTED
259  */
260 
261 void
262 isc_net_disableipv4(void);
263 
264 void
265 isc_net_disableipv6(void);
266 
267 void
268 isc_net_enableipv4(void);
269 
270 void
271 isc_net_enableipv6(void);
272 
273 isc_result_t
274 isc_net_probeunix(void);
275 /*
276  * Returns whether UNIX domain sockets are supported.
277  */
278 
279 #define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */
280 #define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */
281 #define ISC_NET_DSCPSETV4  0x04 /* Can set DSCP on socket IPv4 */
282 #define ISC_NET_DSCPSETV6  0x08 /* Can set DSCP on socket IPv6 */
283 #define ISC_NET_DSCPPKTV4  0x10 /* Can set DSCP on per packet IPv4 */
284 #define ISC_NET_DSCPPKTV6  0x20 /* Can set DSCP on per packet IPv6 */
285 #define ISC_NET_DSCPALL	   0x3f /* All valid flags */
286 
287 unsigned int
288 isc_net_probedscp(void);
289 /*%<
290  * Probe the level of DSCP support.
291  */
292 
293 isc_result_t
294 isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
295 /*%<
296  * Returns system's default range of ephemeral UDP ports, if defined.
297  * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
298  * ISC_NET_PORTRANGEHIGH will be returned.
299  *
300  * Requires:
301  *
302  *\li	'low' and 'high' must be non NULL.
303  *
304  * Returns:
305  *
306  *\li	*low and *high will be the ports specifying the low and high ends of
307  *	the range.
308  */
309 
310 ISC_LANG_ENDDECLS
311 
312 #endif /* ISC_NET_H */
313