1/* $NetBSD$ */ 2 3/* 4 * Copyright (C) 2004, 2005, 2007-2009 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: net.h,v 1.48.84.2 2009/02/16 23:47:15 tbox Exp */ 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 in_port_t 43 * 44 * It ensures that the AF_ and PF_ macros are defined. 45 * 46 * It declares ntoh[sl]() and hton[sl](). 47 * 48 * It declares inet_aton(), inet_ntop(), and inet_pton(). 49 * 50 * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT, 51 * in6addr_any, and in6addr_loopback are available. 52 * 53 * It ensures that IN_MULTICAST() is available to check for multicast 54 * addresses. 55 * 56 * MP: 57 *\li No impact. 58 * 59 * Reliability: 60 *\li No anticipated impact. 61 * 62 * Resources: 63 *\li N/A. 64 * 65 * Security: 66 *\li No anticipated impact. 67 * 68 * Standards: 69 *\li BSD Socket API 70 *\li RFC2553 71 */ 72 73/*** 74 *** Imports. 75 ***/ 76#include <isc/platform.h> 77 78#include <sys/types.h> 79#include <sys/socket.h> /* Contractual promise. */ 80 81#include <net/if.h> 82 83#include <netinet/in.h> /* Contractual promise. */ 84#include <arpa/inet.h> /* Contractual promise. */ 85#ifdef ISC_PLATFORM_NEEDNETINETIN6H 86#include <netinet/in6.h> /* Required on UnixWare. */ 87#endif 88#ifdef ISC_PLATFORM_NEEDNETINET6IN6H 89#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */ 90#endif 91 92#ifndef ISC_PLATFORM_HAVEIPV6 93#include <isc/ipv6.h> /* Contractual promise. */ 94#endif 95 96#include <isc/lang.h> 97#include <isc/types.h> 98 99#ifdef ISC_PLATFORM_HAVEINADDR6 100#define in6_addr in_addr6 /*%< Required for pre RFC2133 implementations. */ 101#endif 102 103#ifdef ISC_PLATFORM_HAVEIPV6 104#ifndef IN6ADDR_ANY_INIT 105#ifdef s6_addr 106/*% 107 * Required for some pre RFC2133 implementations. 108 * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in 109 * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt. 110 * If 's6_addr' is defined then assume that there is a union and three 111 * levels otherwise assume two levels required. 112 */ 113#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } 114#else 115#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } 116#endif 117#endif 118 119#ifndef IN6ADDR_LOOPBACK_INIT 120#ifdef s6_addr 121/*% IPv6 address loopback init */ 122#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } 123#else 124#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } 125#endif 126#endif 127 128#ifndef IN6_IS_ADDR_V4MAPPED 129/*% Is IPv6 address V4 mapped? */ 130#define IN6_IS_ADDR_V4MAPPED(x) \ 131 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ 132 (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) 133#endif 134 135#ifndef IN6_IS_ADDR_V4COMPAT 136/*% Is IPv6 address V4 compatible? */ 137#define IN6_IS_ADDR_V4COMPAT(x) \ 138 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ 139 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ 140 (x)->s6_addr[14] != 0 || \ 141 ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1))) 142#endif 143 144#ifndef IN6_IS_ADDR_MULTICAST 145/*% Is IPv6 address multicast? */ 146#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) 147#endif 148 149#ifndef IN6_IS_ADDR_LINKLOCAL 150/*% Is IPv6 address linklocal? */ 151#define IN6_IS_ADDR_LINKLOCAL(a) \ 152 (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) 153#endif 154 155#ifndef IN6_IS_ADDR_SITELOCAL 156/*% is IPv6 address sitelocal? */ 157#define IN6_IS_ADDR_SITELOCAL(a) \ 158 (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) 159#endif 160 161 162#ifndef IN6_IS_ADDR_LOOPBACK 163/*% is IPv6 address loopback? */ 164#define IN6_IS_ADDR_LOOPBACK(x) \ 165 (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0) 166#endif 167#endif 168 169#ifndef AF_INET6 170/*% IPv6 */ 171#define AF_INET6 99 172#endif 173 174#ifndef PF_INET6 175/*% IPv6 */ 176#define PF_INET6 AF_INET6 177#endif 178 179#ifndef INADDR_LOOPBACK 180/*% inaddr loopback */ 181#define INADDR_LOOPBACK 0x7f000001UL 182#endif 183 184#ifndef ISC_PLATFORM_HAVEIN6PKTINFO 185/*% IPv6 packet info */ 186struct in6_pktinfo { 187 struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */ 188 unsigned int ipi6_ifindex; /*%< send/recv interface index */ 189}; 190#endif 191 192#if defined(ISC_PLATFORM_NEEDIN6ADDRANY) 193extern const struct in6_addr isc_net_in6addrany; 194/*% 195 * Cope with a missing in6addr_any and in6addr_loopback. 196 */ 197#define in6addr_any isc_net_in6addrany 198#endif 199 200#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) 201extern const struct in6_addr isc_net_in6addrloop; 202#define in6addr_loopback isc_net_in6addrloop 203#endif 204 205#ifdef ISC_PLATFORM_FIXIN6ISADDR 206#undef IN6_IS_ADDR_GEOGRAPHIC 207/*! 208 * \brief 209 * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions. 210 */ 211#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80) 212#undef IN6_IS_ADDR_IPX 213#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) 214#undef IN6_IS_ADDR_LINKLOCAL 215#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) 216#undef IN6_IS_ADDR_MULTICAST 217#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) 218#undef IN6_IS_ADDR_NSAP 219#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) 220#undef IN6_IS_ADDR_PROVIDER 221#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) 222#undef IN6_IS_ADDR_SITELOCAL 223#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) 224#endif /* ISC_PLATFORM_FIXIN6ISADDR */ 225 226#ifdef ISC_PLATFORM_NEEDPORTT 227/*% 228 * Ensure type in_port_t is defined. 229 */ 230typedef isc_uint16_t in_port_t; 231#endif 232 233#ifndef MSG_TRUNC 234/*% 235 * If this system does not have MSG_TRUNC (as returned from recvmsg()) 236 * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC 237 * faking code in socket.c. 238 */ 239#define ISC_PLATFORM_RECVOVERFLOW 240#endif 241 242/*% IP address. */ 243#define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x))) 244 245/*% Is IP address multicast? */ 246#define ISC_IPADDR_ISMULTICAST(i) \ 247 (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ 248 == ISC__IPADDR(0xe0000000)) 249 250#define ISC_IPADDR_ISEXPERIMENTAL(i) \ 251 (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ 252 == ISC__IPADDR(0xf0000000)) 253 254/*** 255 *** Functions. 256 ***/ 257 258ISC_LANG_BEGINDECLS 259 260isc_result_t 261isc_net_probeipv4(void); 262/*%< 263 * Check if the system's kernel supports IPv4. 264 * 265 * Returns: 266 * 267 *\li #ISC_R_SUCCESS IPv4 is supported. 268 *\li #ISC_R_NOTFOUND IPv4 is not supported. 269 *\li #ISC_R_DISABLED IPv4 is disabled. 270 *\li #ISC_R_UNEXPECTED 271 */ 272 273isc_result_t 274isc_net_probeipv6(void); 275/*%< 276 * Check if the system's kernel supports IPv6. 277 * 278 * Returns: 279 * 280 *\li #ISC_R_SUCCESS IPv6 is supported. 281 *\li #ISC_R_NOTFOUND IPv6 is not supported. 282 *\li #ISC_R_DISABLED IPv6 is disabled. 283 *\li #ISC_R_UNEXPECTED 284 */ 285 286isc_result_t 287isc_net_probe_ipv6only(void); 288/*%< 289 * Check if the system's kernel supports the IPV6_V6ONLY socket option. 290 * 291 * Returns: 292 * 293 *\li #ISC_R_SUCCESS the option is supported for both TCP and UDP. 294 *\li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. 295 *\li #ISC_R_UNEXPECTED 296 */ 297 298isc_result_t 299isc_net_probe_ipv6pktinfo(void); 300/* 301 * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option 302 * for UDP sockets. 303 * 304 * Returns: 305 * 306 * \li #ISC_R_SUCCESS the option is supported. 307 * \li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. 308 * \li #ISC_R_UNEXPECTED 309 */ 310 311void 312isc_net_disableipv4(void); 313 314void 315isc_net_disableipv6(void); 316 317void 318isc_net_enableipv4(void); 319 320void 321isc_net_enableipv6(void); 322 323isc_result_t 324isc_net_probeunix(void); 325/* 326 * Returns whether UNIX domain sockets are supported. 327 */ 328 329isc_result_t 330isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high); 331/*%< 332 * Returns system's default range of ephemeral UDP ports, if defined. 333 * If the range is not available or unknown, ISC_NET_PORTRANGELOW and 334 * ISC_NET_PORTRANGEHIGH will be returned. 335 * 336 * Requires: 337 * 338 *\li 'low' and 'high' must be non NULL. 339 * 340 * Returns: 341 * 342 *\li *low and *high will be the ports specifying the low and high ends of 343 * the range. 344 */ 345 346#ifdef ISC_PLATFORM_NEEDNTOP 347const char * 348isc_net_ntop(int af, const void *src, char *dst, size_t size); 349#define inet_ntop isc_net_ntop 350#endif 351 352#ifdef ISC_PLATFORM_NEEDPTON 353int 354isc_net_pton(int af, const char *src, void *dst); 355#undef inet_pton 356#define inet_pton isc_net_pton 357#endif 358 359int 360isc_net_aton(const char *cp, struct in_addr *addr); 361#undef inet_aton 362#define inet_aton isc_net_aton 363 364ISC_LANG_ENDDECLS 365 366#endif /* ISC_NET_H */ 367