1 /* $NetBSD: net.h,v 1.6 2015/07/08 17:29:00 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007, 2008, 2012-2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id */ 21 22 #ifndef ISC_NET_H 23 #define ISC_NET_H 1 24 25 /***** 26 ***** Module Info 27 *****/ 28 29 /*! \file 30 * \brief 31 * Basic Networking Types 32 * 33 * This module is responsible for defining the following basic networking 34 * types: 35 * 36 *\li struct in_addr 37 *\li struct in6_addr 38 *\li struct in6_pktinfo 39 *\li struct sockaddr 40 *\li struct sockaddr_in 41 *\li struct sockaddr_in6 42 *\li struct sockaddr_storage 43 *\li in_port_t 44 * 45 * It ensures that the AF_ and PF_ macros are defined. 46 * 47 * It declares ntoh[sl]() and hton[sl](). 48 * 49 * It declares inet_aton(), inet_ntop(), and inet_pton(). 50 * 51 * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT, 52 * in6addr_any, and in6addr_loopback are available. 53 * 54 * It ensures that IN_MULTICAST() is available to check for multicast 55 * addresses. 56 * 57 * MP: 58 *\li No impact. 59 * 60 * Reliability: 61 *\li No anticipated impact. 62 * 63 * Resources: 64 *\li N/A. 65 * 66 * Security: 67 *\li No anticipated impact. 68 * 69 * Standards: 70 *\li BSD Socket API 71 *\li RFC2553 72 */ 73 74 /*** 75 *** Imports. 76 ***/ 77 #include <isc/platform.h> 78 79 #include <sys/types.h> 80 #include <sys/socket.h> /* Contractual promise. */ 81 82 #include <net/if.h> 83 84 #include <netinet/in.h> /* Contractual promise. */ 85 #include <arpa/inet.h> /* Contractual promise. */ 86 #ifdef ISC_PLATFORM_NEEDNETINETIN6H 87 #include <netinet/in6.h> /* Required on UnixWare. */ 88 #endif 89 #ifdef ISC_PLATFORM_NEEDNETINET6IN6H 90 #include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */ 91 #endif 92 93 #ifndef ISC_PLATFORM_HAVEIPV6 94 #include <isc/ipv6.h> /* Contractual promise. */ 95 #endif 96 97 #include <isc/lang.h> 98 #include <isc/types.h> 99 100 #ifdef ISC_PLATFORM_HAVEINADDR6 101 #define in6_addr in_addr6 /*%< Required for pre RFC2133 implementations. */ 102 #endif 103 104 #ifdef ISC_PLATFORM_HAVEIPV6 105 #ifndef IN6ADDR_ANY_INIT 106 #ifdef s6_addr 107 /*% 108 * Required for some pre RFC2133 implementations. 109 * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in 110 * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt. 111 * If 's6_addr' is defined then assume that there is a union and three 112 * levels otherwise assume two levels required. 113 */ 114 #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } 115 #else 116 #define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } 117 #endif 118 #endif 119 120 #ifndef IN6ADDR_LOOPBACK_INIT 121 #ifdef s6_addr 122 /*% IPv6 address loopback init */ 123 #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } 124 #else 125 #define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } 126 #endif 127 #endif 128 129 #ifndef IN6_IS_ADDR_V4MAPPED 130 /*% Is IPv6 address V4 mapped? */ 131 #define IN6_IS_ADDR_V4MAPPED(x) \ 132 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ 133 (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) 134 #endif 135 136 #ifndef IN6_IS_ADDR_V4COMPAT 137 /*% Is IPv6 address V4 compatible? */ 138 #define IN6_IS_ADDR_V4COMPAT(x) \ 139 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ 140 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ 141 (x)->s6_addr[14] != 0 || \ 142 ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1))) 143 #endif 144 145 #ifndef IN6_IS_ADDR_MULTICAST 146 /*% Is IPv6 address multicast? */ 147 #define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) 148 #endif 149 150 #ifndef IN6_IS_ADDR_LINKLOCAL 151 /*% Is IPv6 address linklocal? */ 152 #define IN6_IS_ADDR_LINKLOCAL(a) \ 153 (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) 154 #endif 155 156 #ifndef IN6_IS_ADDR_SITELOCAL 157 /*% is IPv6 address sitelocal? */ 158 #define IN6_IS_ADDR_SITELOCAL(a) \ 159 (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) 160 #endif 161 162 163 #ifndef IN6_IS_ADDR_LOOPBACK 164 /*% is IPv6 address loopback? */ 165 #define IN6_IS_ADDR_LOOPBACK(x) \ 166 (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0) 167 #endif 168 #endif 169 170 #ifndef AF_INET6 171 /*% IPv6 */ 172 #define AF_INET6 99 173 #endif 174 175 #ifndef PF_INET6 176 /*% IPv6 */ 177 #define PF_INET6 AF_INET6 178 #endif 179 180 #ifndef INADDR_LOOPBACK 181 /*% inaddr loopback */ 182 #define INADDR_LOOPBACK 0x7f000001UL 183 #endif 184 185 #ifndef ISC_PLATFORM_HAVEIN6PKTINFO 186 /*% IPv6 packet info */ 187 struct in6_pktinfo { 188 struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */ 189 unsigned int ipi6_ifindex; /*%< send/recv interface index */ 190 }; 191 #endif 192 193 194 #ifndef ISC_PLATFORM_HAVESOCKADDRSTORAGE 195 #define _SS_MAXSIZE 128 196 #define _SS_ALIGNSIZE (sizeof (isc_uint64_t)) 197 #ifdef ISC_PLATFORM_HAVESALEN 198 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - (2 * sizeof(isc_uint8_t))) 199 #define _SS_PAD2SIZE (_SS_MAXSIZE - (_SS_ALIGNSIZE + _SS_PAD1SIZE \ 200 + 2 * sizeof(isc_uint8_t))) 201 #else 202 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(isc_uint16_t)) 203 #define _SS_PAD2SIZE (_SS_MAXSIZE - (_SS_ALIGNSIZE + _SS_PAD1SIZE \ 204 + sizeof(isc_uint16_t))) 205 #endif 206 207 struct sockaddr_storage { 208 #ifdef ISC_PLATFORM_HAVESALEN 209 isc_uint8_t ss_len; 210 isc_uint8_t ss_family; 211 #else 212 isc_uint16_t ss_family; 213 #endif 214 char __ss_pad1[_SS_PAD1SIZE]; 215 isc_uint64_t __ss_align; /* field to force desired structure */ 216 char __ss_pad2[_SS_PAD2SIZE]; 217 }; 218 #endif 219 220 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY) 221 extern const struct in6_addr isc_net_in6addrany; 222 /*% 223 * Cope with a missing in6addr_any and in6addr_loopback. 224 */ 225 #define in6addr_any isc_net_in6addrany 226 #endif 227 228 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) 229 extern const struct in6_addr isc_net_in6addrloop; 230 #define in6addr_loopback isc_net_in6addrloop 231 #endif 232 233 #ifdef ISC_PLATFORM_FIXIN6ISADDR 234 #undef IN6_IS_ADDR_GEOGRAPHIC 235 /*! 236 * \brief 237 * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions. 238 */ 239 #define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80) 240 #undef IN6_IS_ADDR_IPX 241 #define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) 242 #undef IN6_IS_ADDR_LINKLOCAL 243 #define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) 244 #undef IN6_IS_ADDR_MULTICAST 245 #define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) 246 #undef IN6_IS_ADDR_NSAP 247 #define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) 248 #undef IN6_IS_ADDR_PROVIDER 249 #define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) 250 #undef IN6_IS_ADDR_SITELOCAL 251 #define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) 252 #endif /* ISC_PLATFORM_FIXIN6ISADDR */ 253 254 #ifdef ISC_PLATFORM_NEEDPORTT 255 /*% 256 * Ensure type in_port_t is defined. 257 */ 258 typedef isc_uint16_t in_port_t; 259 #endif 260 261 #ifndef MSG_TRUNC 262 /*% 263 * If this system does not have MSG_TRUNC (as returned from recvmsg()) 264 * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC 265 * faking code in socket.c. 266 */ 267 #define ISC_PLATFORM_RECVOVERFLOW 268 #endif 269 270 /*% IP address. */ 271 #define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x))) 272 273 /*% Is IP address multicast? */ 274 #define ISC_IPADDR_ISMULTICAST(i) \ 275 (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ 276 == ISC__IPADDR(0xe0000000)) 277 278 #define ISC_IPADDR_ISEXPERIMENTAL(i) \ 279 (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ 280 == ISC__IPADDR(0xf0000000)) 281 282 /*** 283 *** Functions. 284 ***/ 285 286 ISC_LANG_BEGINDECLS 287 288 isc_result_t 289 isc_net_probeipv4(void); 290 /*%< 291 * Check if the system's kernel supports IPv4. 292 * 293 * Returns: 294 * 295 *\li #ISC_R_SUCCESS IPv4 is supported. 296 *\li #ISC_R_NOTFOUND IPv4 is not supported. 297 *\li #ISC_R_DISABLED IPv4 is disabled. 298 *\li #ISC_R_UNEXPECTED 299 */ 300 301 isc_result_t 302 isc_net_probeipv6(void); 303 /*%< 304 * Check if the system's kernel supports IPv6. 305 * 306 * Returns: 307 * 308 *\li #ISC_R_SUCCESS IPv6 is supported. 309 *\li #ISC_R_NOTFOUND IPv6 is not supported. 310 *\li #ISC_R_DISABLED IPv6 is disabled. 311 *\li #ISC_R_UNEXPECTED 312 */ 313 314 isc_result_t 315 isc_net_probe_ipv6only(void); 316 /*%< 317 * Check if the system's kernel supports the IPV6_V6ONLY socket option. 318 * 319 * Returns: 320 * 321 *\li #ISC_R_SUCCESS the option is supported for both TCP and UDP. 322 *\li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. 323 *\li #ISC_R_UNEXPECTED 324 */ 325 326 isc_result_t 327 isc_net_probe_ipv6pktinfo(void); 328 /* 329 * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option 330 * for UDP sockets. 331 * 332 * Returns: 333 * 334 * \li #ISC_R_SUCCESS the option is supported. 335 * \li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. 336 * \li #ISC_R_UNEXPECTED 337 */ 338 339 void 340 isc_net_disableipv4(void); 341 342 void 343 isc_net_disableipv6(void); 344 345 void 346 isc_net_enableipv4(void); 347 348 void 349 isc_net_enableipv6(void); 350 351 isc_result_t 352 isc_net_probeunix(void); 353 /* 354 * Returns whether UNIX domain sockets are supported. 355 */ 356 357 #define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ 358 #define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ 359 #define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ 360 #define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ 361 #define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ 362 #define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ 363 #define ISC_NET_DSCPALL 0x3f /* All valid flags */ 364 365 unsigned int 366 isc_net_probedscp(void); 367 /*%< 368 * Probe the level of DSCP support. 369 */ 370 371 372 isc_result_t 373 isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high); 374 /*%< 375 * Returns system's default range of ephemeral UDP ports, if defined. 376 * If the range is not available or unknown, ISC_NET_PORTRANGELOW and 377 * ISC_NET_PORTRANGEHIGH will be returned. 378 * 379 * Requires: 380 * 381 *\li 'low' and 'high' must be non NULL. 382 * 383 * Returns: 384 * 385 *\li *low and *high will be the ports specifying the low and high ends of 386 * the range. 387 */ 388 389 #ifdef ISC_PLATFORM_NEEDNTOP 390 const char * 391 isc_net_ntop(int af, const void *src, char *dst, size_t size); 392 #define inet_ntop isc_net_ntop 393 #endif 394 395 #ifdef ISC_PLATFORM_NEEDPTON 396 int 397 isc_net_pton(int af, const char *src, void *dst); 398 #undef inet_pton 399 #define inet_pton isc_net_pton 400 #endif 401 402 int 403 isc_net_aton(const char *cp, struct in_addr *addr); 404 #undef inet_aton 405 #define inet_aton isc_net_aton 406 407 ISC_LANG_ENDDECLS 408 409 #endif /* ISC_NET_H */ 410