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