1258945Sroberto/* 2280849Scy * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * Copyright (C) 1999-2003 Internet Software Consortium. 4258945Sroberto * 5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 6258945Sroberto * purpose with or without fee is hereby granted, provided that the above 7258945Sroberto * copyright notice and this permission notice appear in all copies. 8258945Sroberto * 9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 16258945Sroberto */ 17258945Sroberto 18280849Scy/* $Id$ */ 19258945Sroberto 20258945Sroberto#ifndef ISC_NET_H 21258945Sroberto#define ISC_NET_H 1 22258945Sroberto 23258945Sroberto/***** 24258945Sroberto ***** Module Info 25258945Sroberto *****/ 26258945Sroberto 27258945Sroberto/*! \file 28258945Sroberto * \brief 29258945Sroberto * Basic Networking Types 30258945Sroberto * 31258945Sroberto * This module is responsible for defining the following basic networking 32258945Sroberto * types: 33258945Sroberto * 34258945Sroberto *\li struct in_addr 35258945Sroberto *\li struct in6_addr 36258945Sroberto *\li struct in6_pktinfo 37258945Sroberto *\li struct sockaddr 38258945Sroberto *\li struct sockaddr_in 39258945Sroberto *\li struct sockaddr_in6 40258945Sroberto *\li in_port_t 41258945Sroberto * 42258945Sroberto * It ensures that the AF_ and PF_ macros are defined. 43258945Sroberto * 44258945Sroberto * It declares ntoh[sl]() and hton[sl](). 45258945Sroberto * 46258945Sroberto * It declares inet_aton(), inet_ntop(), and inet_pton(). 47258945Sroberto * 48258945Sroberto * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT, 49258945Sroberto * in6addr_any, and in6addr_loopback are available. 50258945Sroberto * 51258945Sroberto * It ensures that IN_MULTICAST() is available to check for multicast 52258945Sroberto * addresses. 53258945Sroberto * 54258945Sroberto * MP: 55258945Sroberto *\li No impact. 56258945Sroberto * 57258945Sroberto * Reliability: 58258945Sroberto *\li No anticipated impact. 59258945Sroberto * 60258945Sroberto * Resources: 61258945Sroberto *\li N/A. 62258945Sroberto * 63258945Sroberto * Security: 64258945Sroberto *\li No anticipated impact. 65258945Sroberto * 66258945Sroberto * Standards: 67258945Sroberto *\li BSD Socket API 68258945Sroberto *\li RFC2553 69258945Sroberto */ 70258945Sroberto 71258945Sroberto/*** 72258945Sroberto *** Imports. 73258945Sroberto ***/ 74258945Sroberto#include <isc/platform.h> 75258945Sroberto 76258945Sroberto#include <sys/types.h> 77258945Sroberto#include <sys/socket.h> /* Contractual promise. */ 78258945Sroberto 79258945Sroberto#include <net/if.h> 80258945Sroberto 81258945Sroberto#include <netinet/in.h> /* Contractual promise. */ 82258945Sroberto#include <arpa/inet.h> /* Contractual promise. */ 83258945Sroberto#ifdef ISC_PLATFORM_NEEDNETINETIN6H 84258945Sroberto#include <netinet/in6.h> /* Required on UnixWare. */ 85258945Sroberto#endif 86258945Sroberto#ifdef ISC_PLATFORM_NEEDNETINET6IN6H 87258945Sroberto#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */ 88258945Sroberto#endif 89258945Sroberto 90258945Sroberto#ifndef ISC_PLATFORM_HAVEIPV6 91258945Sroberto#include <isc/ipv6.h> /* Contractual promise. */ 92258945Sroberto#endif 93258945Sroberto 94258945Sroberto#include <isc/lang.h> 95258945Sroberto#include <isc/types.h> 96258945Sroberto 97258945Sroberto#ifdef ISC_PLATFORM_HAVEINADDR6 98258945Sroberto#define in6_addr in_addr6 /*%< Required for pre RFC2133 implementations. */ 99258945Sroberto#endif 100258945Sroberto 101258945Sroberto#ifdef ISC_PLATFORM_HAVEIPV6 102258945Sroberto#ifndef IN6ADDR_ANY_INIT 103258945Sroberto#ifdef s6_addr 104258945Sroberto/*% 105258945Sroberto * Required for some pre RFC2133 implementations. 106258945Sroberto * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in 107258945Sroberto * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt. 108258945Sroberto * If 's6_addr' is defined then assume that there is a union and three 109258945Sroberto * levels otherwise assume two levels required. 110258945Sroberto */ 111258945Sroberto#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } 112258945Sroberto#else 113258945Sroberto#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } 114258945Sroberto#endif 115258945Sroberto#endif 116258945Sroberto 117258945Sroberto#ifndef IN6ADDR_LOOPBACK_INIT 118258945Sroberto#ifdef s6_addr 119258945Sroberto/*% IPv6 address loopback init */ 120258945Sroberto#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } 121258945Sroberto#else 122258945Sroberto#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } 123258945Sroberto#endif 124258945Sroberto#endif 125258945Sroberto 126258945Sroberto#ifndef IN6_IS_ADDR_V4MAPPED 127258945Sroberto/*% Is IPv6 address V4 mapped? */ 128258945Sroberto#define IN6_IS_ADDR_V4MAPPED(x) \ 129258945Sroberto (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ 130258945Sroberto (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) 131258945Sroberto#endif 132258945Sroberto 133258945Sroberto#ifndef IN6_IS_ADDR_V4COMPAT 134258945Sroberto/*% Is IPv6 address V4 compatible? */ 135258945Sroberto#define IN6_IS_ADDR_V4COMPAT(x) \ 136258945Sroberto (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ 137258945Sroberto ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ 138258945Sroberto (x)->s6_addr[14] != 0 || \ 139258945Sroberto ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1))) 140258945Sroberto#endif 141258945Sroberto 142258945Sroberto#ifndef IN6_IS_ADDR_MULTICAST 143258945Sroberto/*% Is IPv6 address multicast? */ 144258945Sroberto#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) 145258945Sroberto#endif 146258945Sroberto 147258945Sroberto#ifndef IN6_IS_ADDR_LINKLOCAL 148258945Sroberto/*% Is IPv6 address linklocal? */ 149258945Sroberto#define IN6_IS_ADDR_LINKLOCAL(a) \ 150258945Sroberto (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) 151258945Sroberto#endif 152258945Sroberto 153258945Sroberto#ifndef IN6_IS_ADDR_SITELOCAL 154258945Sroberto/*% is IPv6 address sitelocal? */ 155258945Sroberto#define IN6_IS_ADDR_SITELOCAL(a) \ 156258945Sroberto (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) 157258945Sroberto#endif 158258945Sroberto 159258945Sroberto 160258945Sroberto#ifndef IN6_IS_ADDR_LOOPBACK 161258945Sroberto/*% is IPv6 address loopback? */ 162258945Sroberto#define IN6_IS_ADDR_LOOPBACK(x) \ 163258945Sroberto (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0) 164258945Sroberto#endif 165258945Sroberto#endif 166258945Sroberto 167258945Sroberto#ifndef AF_INET6 168258945Sroberto/*% IPv6 */ 169258945Sroberto#define AF_INET6 99 170258945Sroberto#endif 171258945Sroberto 172258945Sroberto#ifndef PF_INET6 173258945Sroberto/*% IPv6 */ 174258945Sroberto#define PF_INET6 AF_INET6 175258945Sroberto#endif 176258945Sroberto 177258945Sroberto#ifndef INADDR_LOOPBACK 178258945Sroberto/*% inaddr loopback */ 179258945Sroberto#define INADDR_LOOPBACK 0x7f000001UL 180258945Sroberto#endif 181258945Sroberto 182258945Sroberto#ifndef ISC_PLATFORM_HAVEIN6PKTINFO 183258945Sroberto/*% IPv6 packet info */ 184258945Srobertostruct in6_pktinfo { 185258945Sroberto struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */ 186258945Sroberto unsigned int ipi6_ifindex; /*%< send/recv interface index */ 187258945Sroberto}; 188258945Sroberto#endif 189258945Sroberto 190258945Sroberto#if defined(ISC_PLATFORM_NEEDIN6ADDRANY) 191258945Srobertoextern const struct in6_addr isc_net_in6addrany; 192258945Sroberto/*% 193258945Sroberto * Cope with a missing in6addr_any and in6addr_loopback. 194258945Sroberto */ 195258945Sroberto#define in6addr_any isc_net_in6addrany 196258945Sroberto#endif 197258945Sroberto 198258945Sroberto#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) 199258945Srobertoextern const struct in6_addr isc_net_in6addrloop; 200258945Sroberto#define in6addr_loopback isc_net_in6addrloop 201258945Sroberto#endif 202258945Sroberto 203258945Sroberto#ifdef ISC_PLATFORM_FIXIN6ISADDR 204258945Sroberto#undef IN6_IS_ADDR_GEOGRAPHIC 205258945Sroberto/*! 206258945Sroberto * \brief 207258945Sroberto * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions. 208258945Sroberto */ 209258945Sroberto#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80) 210258945Sroberto#undef IN6_IS_ADDR_IPX 211258945Sroberto#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) 212258945Sroberto#undef IN6_IS_ADDR_LINKLOCAL 213258945Sroberto#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) 214258945Sroberto#undef IN6_IS_ADDR_MULTICAST 215258945Sroberto#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) 216258945Sroberto#undef IN6_IS_ADDR_NSAP 217258945Sroberto#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) 218258945Sroberto#undef IN6_IS_ADDR_PROVIDER 219258945Sroberto#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) 220258945Sroberto#undef IN6_IS_ADDR_SITELOCAL 221258945Sroberto#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) 222258945Sroberto#endif /* ISC_PLATFORM_FIXIN6ISADDR */ 223258945Sroberto 224258945Sroberto#ifdef ISC_PLATFORM_NEEDPORTT 225258945Sroberto/*% 226258945Sroberto * Ensure type in_port_t is defined. 227258945Sroberto */ 228258945Srobertotypedef isc_uint16_t in_port_t; 229258945Sroberto#endif 230258945Sroberto 231258945Sroberto#ifndef MSG_TRUNC 232258945Sroberto/*% 233258945Sroberto * If this system does not have MSG_TRUNC (as returned from recvmsg()) 234258945Sroberto * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC 235258945Sroberto * faking code in socket.c. 236258945Sroberto */ 237258945Sroberto#define ISC_PLATFORM_RECVOVERFLOW 238258945Sroberto#endif 239258945Sroberto 240258945Sroberto/*% IP address. */ 241258945Sroberto#define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x))) 242258945Sroberto 243258945Sroberto/*% Is IP address multicast? */ 244258945Sroberto#define ISC_IPADDR_ISMULTICAST(i) \ 245258945Sroberto (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ 246258945Sroberto == ISC__IPADDR(0xe0000000)) 247258945Sroberto 248258945Sroberto#define ISC_IPADDR_ISEXPERIMENTAL(i) \ 249258945Sroberto (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ 250258945Sroberto == ISC__IPADDR(0xf0000000)) 251258945Sroberto 252258945Sroberto/*** 253258945Sroberto *** Functions. 254258945Sroberto ***/ 255258945Sroberto 256258945SrobertoISC_LANG_BEGINDECLS 257258945Sroberto 258258945Srobertoisc_result_t 259258945Srobertoisc_net_probeipv4(void); 260258945Sroberto/*%< 261258945Sroberto * Check if the system's kernel supports IPv4. 262258945Sroberto * 263258945Sroberto * Returns: 264258945Sroberto * 265258945Sroberto *\li #ISC_R_SUCCESS IPv4 is supported. 266258945Sroberto *\li #ISC_R_NOTFOUND IPv4 is not supported. 267258945Sroberto *\li #ISC_R_DISABLED IPv4 is disabled. 268258945Sroberto *\li #ISC_R_UNEXPECTED 269258945Sroberto */ 270258945Sroberto 271258945Srobertoisc_result_t 272258945Srobertoisc_net_probeipv6(void); 273258945Sroberto/*%< 274258945Sroberto * Check if the system's kernel supports IPv6. 275258945Sroberto * 276258945Sroberto * Returns: 277258945Sroberto * 278258945Sroberto *\li #ISC_R_SUCCESS IPv6 is supported. 279258945Sroberto *\li #ISC_R_NOTFOUND IPv6 is not supported. 280258945Sroberto *\li #ISC_R_DISABLED IPv6 is disabled. 281258945Sroberto *\li #ISC_R_UNEXPECTED 282258945Sroberto */ 283258945Sroberto 284258945Srobertoisc_result_t 285258945Srobertoisc_net_probe_ipv6only(void); 286258945Sroberto/*%< 287258945Sroberto * Check if the system's kernel supports the IPV6_V6ONLY socket option. 288258945Sroberto * 289258945Sroberto * Returns: 290258945Sroberto * 291258945Sroberto *\li #ISC_R_SUCCESS the option is supported for both TCP and UDP. 292258945Sroberto *\li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. 293258945Sroberto *\li #ISC_R_UNEXPECTED 294258945Sroberto */ 295258945Sroberto 296258945Srobertoisc_result_t 297258945Srobertoisc_net_probe_ipv6pktinfo(void); 298258945Sroberto/* 299258945Sroberto * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option 300258945Sroberto * for UDP sockets. 301258945Sroberto * 302258945Sroberto * Returns: 303258945Sroberto * 304258945Sroberto * \li #ISC_R_SUCCESS the option is supported. 305258945Sroberto * \li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. 306258945Sroberto * \li #ISC_R_UNEXPECTED 307258945Sroberto */ 308258945Sroberto 309258945Srobertovoid 310258945Srobertoisc_net_disableipv4(void); 311258945Sroberto 312258945Srobertovoid 313258945Srobertoisc_net_disableipv6(void); 314258945Sroberto 315258945Srobertovoid 316258945Srobertoisc_net_enableipv4(void); 317258945Sroberto 318258945Srobertovoid 319258945Srobertoisc_net_enableipv6(void); 320258945Sroberto 321258945Srobertoisc_result_t 322258945Srobertoisc_net_probeunix(void); 323258945Sroberto/* 324258945Sroberto * Returns whether UNIX domain sockets are supported. 325258945Sroberto */ 326258945Sroberto 327258945Srobertoisc_result_t 328258945Srobertoisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high); 329258945Sroberto/*%< 330258945Sroberto * Returns system's default range of ephemeral UDP ports, if defined. 331258945Sroberto * If the range is not available or unknown, ISC_NET_PORTRANGELOW and 332258945Sroberto * ISC_NET_PORTRANGEHIGH will be returned. 333258945Sroberto * 334258945Sroberto * Requires: 335258945Sroberto * 336258945Sroberto *\li 'low' and 'high' must be non NULL. 337258945Sroberto * 338258945Sroberto * Returns: 339258945Sroberto * 340258945Sroberto *\li *low and *high will be the ports specifying the low and high ends of 341258945Sroberto * the range. 342258945Sroberto */ 343258945Sroberto 344258945Sroberto#ifdef ISC_PLATFORM_NEEDNTOP 345258945Srobertoconst char * 346258945Srobertoisc_net_ntop(int af, const void *src, char *dst, size_t size); 347258945Sroberto#define inet_ntop isc_net_ntop 348258945Sroberto#endif 349258945Sroberto 350258945Sroberto#ifdef ISC_PLATFORM_NEEDPTON 351258945Srobertoint 352258945Srobertoisc_net_pton(int af, const char *src, void *dst); 353258945Sroberto#undef inet_pton 354258945Sroberto#define inet_pton isc_net_pton 355258945Sroberto#endif 356258945Sroberto 357258945Srobertoint 358258945Srobertoisc_net_aton(const char *cp, struct in_addr *addr); 359258945Sroberto#undef inet_aton 360258945Sroberto#define inet_aton isc_net_aton 361258945Sroberto 362258945SrobertoISC_LANG_ENDDECLS 363258945Sroberto 364258945Sroberto#endif /* ISC_NET_H */ 365