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