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