11592Srgrimes/*
21592Srgrimes * Copyright (C) 2004, 2005, 2007, 2008, 2012  Internet Systems Consortium, Inc. ("ISC")
31592Srgrimes * Copyright (C) 1999-2003  Internet Software Consortium.
41592Srgrimes *
51592Srgrimes * Permission to use, copy, modify, and/or distribute this software for any
61592Srgrimes * purpose with or without fee is hereby granted, provided that the above
71592Srgrimes * copyright notice and this permission notice appear in all copies.
81592Srgrimes *
91592Srgrimes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
101592Srgrimes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
111592Srgrimes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
121592Srgrimes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
131592Srgrimes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
141592Srgrimes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
151592Srgrimes * PERFORMANCE OF THIS SOFTWARE.
161592Srgrimes */
171592Srgrimes
181592Srgrimes/* $Id$ */
191592Srgrimes
201592Srgrimes#ifndef ISC_NET_H
211592Srgrimes#define ISC_NET_H 1
221592Srgrimes
231592Srgrimes#include <errno.h>
241592Srgrimes
251592Srgrimes/*
261592Srgrimes * Also define LWRES_IPV6_H to keep it from being included if liblwres is
271592Srgrimes * being used, or redefinition errors will occur.
281592Srgrimes */
291592Srgrimes#define LWRES_IPV6_H 1
301592Srgrimes
311592Srgrimes
321592Srgrimes
331592Srgrimes/*****
341592Srgrimes ***** Module Info
351592Srgrimes *****/
361592Srgrimes
371592Srgrimes/*
381592Srgrimes * Basic Networking Types
391592Srgrimes *
401592Srgrimes * This module is responsible for defining the following basic networking
4127074Ssteve * types:
4227077Ssteve *
431592Srgrimes *		struct in_addr
4427074Ssteve *		struct in6_addr
451592Srgrimes *		struct in6_pktinfo
461592Srgrimes *		struct sockaddr
471592Srgrimes *		struct sockaddr_in
481592Srgrimes *		struct sockaddr_in6
4927077Ssteve *		in_port_t
501592Srgrimes *
511592Srgrimes * It ensures that the AF_ and PF_ macros are defined.
521592Srgrimes *
5327077Ssteve * It declares ntoh[sl]() and hton[sl]().
541592Srgrimes *
551592Srgrimes * It declares inet_aton(), inet_ntop(), and inet_pton().
561592Srgrimes *
571592Srgrimes * It ensures that INADDR_ANY, IN6ADDR_ANY_INIT, in6addr_any, and
581592Srgrimes * in6addr_loopback are available.
591592Srgrimes *
601592Srgrimes * It ensures that IN_MULTICAST() is available to check for multicast
611592Srgrimes * addresses.
621592Srgrimes *
631592Srgrimes * MP:
641592Srgrimes *	No impact.
651592Srgrimes *
661592Srgrimes * Reliability:
671592Srgrimes *	No anticipated impact.
681592Srgrimes *
691592Srgrimes * Resources:
701592Srgrimes *	N/A.
711592Srgrimes *
721592Srgrimes * Security:
731592Srgrimes *	No anticipated impact.
741592Srgrimes *
751592Srgrimes * Standards:
761592Srgrimes *	BSD Socket API
771592Srgrimes *	RFC2553
781592Srgrimes */
791592Srgrimes
801592Srgrimes/***
811592Srgrimes *** Imports.
821592Srgrimes ***/
831592Srgrimes#include <isc/platform.h>
841592Srgrimes
851592Srgrimes/*
861592Srgrimes * Because of some sort of problem in the MS header files, this cannot
871592Srgrimes * be simple "#include <winsock2.h>", because winsock2.h tries to include
881592Srgrimes * windows.h, which then generates an error out of mswsock.h.  _You_
8927074Ssteve * figure it out.
901592Srgrimes */
911592Srgrimes#ifndef _WINSOCKAPI_
921592Srgrimes#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */
931592Srgrimes#endif
941592Srgrimes
951592Srgrimes#include <winsock2.h>
961592Srgrimes
971592Srgrimes#include <sys/types.h>
981592Srgrimes
991592Srgrimes#include <isc/lang.h>
1001592Srgrimes#include <isc/types.h>
1011592Srgrimes
1021592Srgrimes#include <ws2tcpip.h>
1031592Srgrimes#include <isc/ipv6.h>
1041592Srgrimes
1051592Srgrimes/*
1061592Srgrimes * This is here because named client, interfacemgr.c, etc. use the name as
1071592Srgrimes * a variable
1081592Srgrimes */
1091592Srgrimes#undef interface
1101592Srgrimes
1111592Srgrimes#ifndef INADDR_LOOPBACK
1121592Srgrimes#define INADDR_LOOPBACK 0x7f000001UL
1131592Srgrimes#endif
1141592Srgrimes
1151592Srgrimes#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
1161592Srgrimesstruct in6_pktinfo {
11727074Ssteve	struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
1181592Srgrimes	unsigned int    ipi6_ifindex; /* send/recv interface index */
1191592Srgrimes};
1201592Srgrimes#endif
12127074Ssteve
1221592Srgrimes#if _MSC_VER < 1300
1231592Srgrimes#define in6addr_any isc_net_in6addrany
1241592Srgrimes#define in6addr_loopback isc_net_in6addrloop
1251592Srgrimes#endif
1261592Srgrimes
1271592Srgrimes/*
1281592Srgrimes * Ensure type in_port_t is defined.
1291592Srgrimes */
1301592Srgrimes#ifdef ISC_PLATFORM_NEEDPORTT
13127074Sstevetypedef isc_uint16_t in_port_t;
1321592Srgrimes#endif
1331592Srgrimes
1341592Srgrimes/*
1351592Srgrimes * If this system does not have MSG_TRUNC (as returned from recvmsg())
1361592Srgrimes * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
1371592Srgrimes * faking code in socket.c.
1381592Srgrimes */
13927074Ssteve#ifndef MSG_TRUNC
14027074Ssteve#define ISC_PLATFORM_RECVOVERFLOW
1411592Srgrimes#endif
1421592Srgrimes
1431592Srgrimes#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
1441592Srgrimes
1451592Srgrimes#define ISC_IPADDR_ISMULTICAST(i) \
1461592Srgrimes		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
1471592Srgrimes		 == ISC__IPADDR(0xe0000000))
1481592Srgrimes
1491592Srgrimes#define ISC_IPADDR_ISEXPERIMENTAL(i) \
15027074Ssteve		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
15127074Ssteve		 == ISC__IPADDR(0xf0000000))
1521592Srgrimes
1531592Srgrimes/*
1541592Srgrimes * Fix the FD_SET and FD_CLR Macros to properly cast
1551592Srgrimes */
1561592Srgrimes#undef FD_CLR
1571592Srgrimes#define FD_CLR(fd, set) do { \
15827074Ssteve    u_int __i; \
1591592Srgrimes    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
16027074Ssteve	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \
1611592Srgrimes	    while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
1621592Srgrimes		((fd_set FAR *)(set))->fd_array[__i] = \
1631592Srgrimes		    ((fd_set FAR *)(set))->fd_array[__i+1]; \
1641592Srgrimes		__i++; \
1651592Srgrimes	    } \
16627074Ssteve	    ((fd_set FAR *)(set))->fd_count--; \
1671592Srgrimes	    break; \
1681592Srgrimes	} \
1691592Srgrimes    } \
1701592Srgrimes} while (0)
1711592Srgrimes
1721592Srgrimes#undef FD_SET
1731592Srgrimes#define FD_SET(fd, set) do { \
17427074Ssteve    u_int __i; \
1751592Srgrimes    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
1761592Srgrimes	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \
1771592Srgrimes	    break; \
1781592Srgrimes	} \
1791592Srgrimes    } \
1801592Srgrimes    if (__i == ((fd_set FAR *)(set))->fd_count) { \
1811592Srgrimes	if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
1821592Srgrimes	    ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \
1831592Srgrimes	    ((fd_set FAR *)(set))->fd_count++; \
1841592Srgrimes	} \
1851592Srgrimes    } \
1861592Srgrimes} while (0)
1871592Srgrimes
1881592Srgrimes/*
1891592Srgrimes * Windows Sockets errors redefined as regular Berkeley error constants.
1901592Srgrimes * These are usually commented out in Windows NT to avoid conflicts with errno.h.
1911592Srgrimes * Use the WSA constants instead.
1921592Srgrimes * Starting with VC9 (VC++ 2010) many of these are defined incompatibly
1931592Srgrimes * by errno.h -- #undef the conflicting values, which are not relevant to
1941592Srgrimes * Win32.
1951592Srgrimes */
1961592Srgrimes
1971592Srgrimes#undef EWOULDBLOCK
1981592Srgrimes#define EWOULDBLOCK             WSAEWOULDBLOCK
1991592Srgrimes#undef EINPROGRESS
2001592Srgrimes#define EINPROGRESS             WSAEINPROGRESS
2011592Srgrimes#undef EALREADY
2021592Srgrimes#define EALREADY                WSAEALREADY
2031592Srgrimes#undef ENOTSOCK
2041592Srgrimes#define ENOTSOCK                WSAENOTSOCK
2051592Srgrimes#undef EDESTADDRREQ
2061592Srgrimes#define EDESTADDRREQ            WSAEDESTADDRREQ
2071592Srgrimes#undef EMSGSIZE
2081592Srgrimes#define EMSGSIZE                WSAEMSGSIZE
20927074Ssteve#undef EPROTOTYPE
2101592Srgrimes#define EPROTOTYPE              WSAEPROTOTYPE
2111592Srgrimes#undef ENOPROTOOPT
2121592Srgrimes#define ENOPROTOOPT             WSAENOPROTOOPT
2131592Srgrimes#undef EPROTONOSUPPORT
21427074Ssteve#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
2151592Srgrimes#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
2161592Srgrimes#undef EOPNOTSUPP
2171592Srgrimes#define EOPNOTSUPP              WSAEOPNOTSUPP
2181592Srgrimes#define EPFNOSUPPORT            WSAEPFNOSUPPORT
2191592Srgrimes#undef EAFNOSUPPORT
2201592Srgrimes#define EAFNOSUPPORT            WSAEAFNOSUPPORT
22127074Ssteve#undef EADDRINUSE
2221592Srgrimes#define EADDRINUSE              WSAEADDRINUSE
22327074Ssteve#undef EADDRNOTAVAIL
22427074Ssteve#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
2251592Srgrimes#undef ENETDOWN
2261592Srgrimes#define ENETDOWN                WSAENETDOWN
22727074Ssteve#undef ENETUNREACH
2281592Srgrimes#define ENETUNREACH             WSAENETUNREACH
22927074Ssteve#undef ENETRESET
2301592Srgrimes#define ENETRESET               WSAENETRESET
2311592Srgrimes#undef ECONNABORTED
2321592Srgrimes#define ECONNABORTED            WSAECONNABORTED
2331592Srgrimes#undef ECONNRESET
2341592Srgrimes#define ECONNRESET              WSAECONNRESET
2351592Srgrimes#undef ENOBUFS
2361592Srgrimes#define ENOBUFS                 WSAENOBUFS
2371592Srgrimes#undef EISCONN
2381592Srgrimes#define EISCONN                 WSAEISCONN
2391592Srgrimes#undef ENOTCONN
2401592Srgrimes#define ENOTCONN                WSAENOTCONN
2411592Srgrimes#define ESHUTDOWN               WSAESHUTDOWN
2421592Srgrimes#define ETOOMANYREFS            WSAETOOMANYREFS
2431592Srgrimes#undef ETIMEDOUT
2441592Srgrimes#define ETIMEDOUT               WSAETIMEDOUT
2451592Srgrimes#undef ECONNREFUSED
2461592Srgrimes#define ECONNREFUSED            WSAECONNREFUSED
2471592Srgrimes#undef ELOOP
2481592Srgrimes#define ELOOP                   WSAELOOP
2491592Srgrimes#define EHOSTDOWN               WSAEHOSTDOWN
2501592Srgrimes#undef EHOSTUNREACH
2511592Srgrimes#define EHOSTUNREACH            WSAEHOSTUNREACH
2521592Srgrimes#define EPROCLIM                WSAEPROCLIM
2531592Srgrimes#define EUSERS                  WSAEUSERS
2541592Srgrimes#define EDQUOT                  WSAEDQUOT
25527074Ssteve#define ESTALE                  WSAESTALE
2561592Srgrimes#define EREMOTE                 WSAEREMOTE
2571592Srgrimes
2581592Srgrimes
2591592Srgrimes/***
2601592Srgrimes *** Functions.
2611592Srgrimes ***/
2621592Srgrimes
2631592SrgrimesISC_LANG_BEGINDECLS
2641592Srgrimes
2651592Srgrimesisc_result_t
2661592Srgrimesisc_net_probeipv4(void);
2671592Srgrimes/*
2681592Srgrimes * Check if the system's kernel supports IPv4.
2691592Srgrimes *
2701592Srgrimes * Returns:
2711592Srgrimes *
2721592Srgrimes *	ISC_R_SUCCESS		IPv4 is supported.
2731592Srgrimes *	ISC_R_NOTFOUND		IPv4 is not supported.
2741592Srgrimes *	ISC_R_DISABLED		IPv4 is disabled.
2751592Srgrimes *	ISC_R_UNEXPECTED
2761592Srgrimes */
27727074Ssteve
2781592Srgrimesisc_result_t
2791592Srgrimesisc_net_probeipv6(void);
2801592Srgrimes/*
2811592Srgrimes * Check if the system's kernel supports IPv6.
2821592Srgrimes *
2831592Srgrimes * Returns:
2841592Srgrimes *
2851592Srgrimes *	ISC_R_SUCCESS		IPv6 is supported.
2861592Srgrimes *	ISC_R_NOTFOUND		IPv6 is not supported.
2871592Srgrimes *	ISC_R_DISABLED		IPv6 is disabled.
2881592Srgrimes *	ISC_R_UNEXPECTED
2891592Srgrimes */
2901592Srgrimes
2911592Srgrimesisc_result_t
2921592Srgrimesisc_net_probeunix(void);
2931592Srgrimes/*
2941592Srgrimes * Check if UNIX domain sockets are supported.
2951592Srgrimes *
2961592Srgrimes * Returns:
2971592Srgrimes *
2981592Srgrimes *	ISC_R_SUCCESS
2991592Srgrimes *	ISC_R_NOTFOUND
3001592Srgrimes */
3011592Srgrimes
3021592Srgrimesisc_result_t
3031592Srgrimesisc_net_probe_ipv6only(void);
3041592Srgrimes/*
3051592Srgrimes * Check if the system's kernel supports the IPV6_V6ONLY socket option.
3061592Srgrimes *
3071592Srgrimes * Returns:
3081592Srgrimes *
3091592Srgrimes *	ISC_R_SUCCESS		the option is supported for both TCP and UDP.
3101592Srgrimes *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
3111592Srgrimes *	ISC_R_UNEXPECTED
3121592Srgrimes */
3131592Srgrimes
3141592Srgrimesisc_result_t
3151592Srgrimesisc_net_probe_ipv6pktinfo(void);
3161592Srgrimes/*
3171592Srgrimes * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
3181592Srgrimes * for UDP sockets.
3191592Srgrimes *
3201592Srgrimes * Returns:
3211592Srgrimes *
3221592Srgrimes *	ISC_R_SUCCESS		the option is supported.
3231592Srgrimes *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
3241592Srgrimes *	ISC_R_UNEXPECTED
3251592Srgrimes */
3261592Srgrimes
3271592Srgrimesvoid
3281592Srgrimesisc_net_disableipv4(void);
3291592Srgrimes
3301592Srgrimesvoid
3311592Srgrimesisc_net_disableipv6(void);
3321592Srgrimes
3331592Srgrimesvoid
3341592Srgrimesisc_net_enableipv4(void);
3351592Srgrimes
3361592Srgrimesvoid
3371592Srgrimesisc_net_enableipv6(void);
3381592Srgrimes
3391592Srgrimesisc_result_t
3401592Srgrimesisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
3411592Srgrimes/*%<
3421592Srgrimes * Returns system's default range of ephemeral UDP ports, if defined.
3431592Srgrimes * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
3441592Srgrimes * ISC_NET_PORTRANGEHIGH will be returned.
3451592Srgrimes *
3461592Srgrimes * Requires:
3471592Srgrimes *
3481592Srgrimes *\li	'low' and 'high' must be non NULL.
3491592Srgrimes *
3501592Srgrimes * Returns:
3511592Srgrimes *
3521592Srgrimes *\li	*low and *high will be the ports specifying the low and high ends of
3531592Srgrimes *	the range.
3541592Srgrimes */
3551592Srgrimes
3561592Srgrimes#ifdef ISC_PLATFORM_NEEDNTOP
3571592Srgrimesconst char *
3581592Srgrimesisc_net_ntop(int af, const void *src, char *dst, size_t size);
3591592Srgrimes#define inet_ntop isc_net_ntop
3601592Srgrimes#endif
3611592Srgrimes
3621592Srgrimes#ifdef ISC_PLATFORM_NEEDPTON
3631592Srgrimesint
3641592Srgrimesisc_net_pton(int af, const char *src, void *dst);
3651592Srgrimes#define inet_pton isc_net_pton
3661592Srgrimes#endif
3671592Srgrimes
3681592Srgrimesint
3691592Srgrimesisc_net_aton(const char *cp, struct in_addr *addr);
3701592Srgrimes#define inet_aton isc_net_aton
3711592Srgrimes
3721592SrgrimesISC_LANG_ENDDECLS
3731592Srgrimes
3741592Srgrimes#endif /* ISC_NET_H */
3751592Srgrimes