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#include <errno.h>
24258945Sroberto
25258945Sroberto/*
26258945Sroberto * Also define LWRES_IPV6_H to keep it from being included if liblwres is
27258945Sroberto * being used, or redefinition errors will occur.
28258945Sroberto */
29258945Sroberto#define LWRES_IPV6_H 1
30258945Sroberto
31258945Sroberto
32258945Sroberto
33258945Sroberto/*****
34258945Sroberto ***** Module Info
35258945Sroberto *****/
36258945Sroberto
37258945Sroberto/*
38258945Sroberto * Basic Networking Types
39258945Sroberto *
40258945Sroberto * This module is responsible for defining the following basic networking
41258945Sroberto * types:
42258945Sroberto *
43258945Sroberto *		struct in_addr
44258945Sroberto *		struct in6_addr
45258945Sroberto *		struct in6_pktinfo
46258945Sroberto *		struct sockaddr
47258945Sroberto *		struct sockaddr_in
48258945Sroberto *		struct sockaddr_in6
49258945Sroberto *		in_port_t
50258945Sroberto *
51258945Sroberto * It ensures that the AF_ and PF_ macros are defined.
52258945Sroberto *
53258945Sroberto * It declares ntoh[sl]() and hton[sl]().
54258945Sroberto *
55258945Sroberto * It declares inet_aton(), inet_ntop(), and inet_pton().
56258945Sroberto *
57258945Sroberto * It ensures that INADDR_ANY, IN6ADDR_ANY_INIT, in6addr_any, and
58258945Sroberto * in6addr_loopback are available.
59258945Sroberto *
60258945Sroberto * It ensures that IN_MULTICAST() is available to check for multicast
61258945Sroberto * addresses.
62258945Sroberto *
63258945Sroberto * MP:
64258945Sroberto *	No impact.
65258945Sroberto *
66258945Sroberto * Reliability:
67258945Sroberto *	No anticipated impact.
68258945Sroberto *
69258945Sroberto * Resources:
70258945Sroberto *	N/A.
71258945Sroberto *
72258945Sroberto * Security:
73258945Sroberto *	No anticipated impact.
74258945Sroberto *
75258945Sroberto * Standards:
76258945Sroberto *	BSD Socket API
77258945Sroberto *	RFC2553
78258945Sroberto */
79258945Sroberto
80258945Sroberto/***
81258945Sroberto *** Imports.
82258945Sroberto ***/
83258945Sroberto#include <isc/platform.h>
84258945Sroberto
85258945Sroberto/*
86258945Sroberto * Because of some sort of problem in the MS header files, this cannot
87258945Sroberto * be simple "#include <winsock2.h>", because winsock2.h tries to include
88258945Sroberto * windows.h, which then generates an error out of mswsock.h.  _You_
89258945Sroberto * figure it out.
90258945Sroberto */
91258945Sroberto#ifndef _WINSOCKAPI_
92258945Sroberto#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */
93258945Sroberto#endif
94258945Sroberto
95258945Sroberto#include <winsock2.h>
96258945Sroberto
97258945Sroberto#include <sys/types.h>
98258945Sroberto
99258945Sroberto#include <isc/lang.h>
100258945Sroberto#include <isc/types.h>
101258945Sroberto
102258945Sroberto#include <ws2tcpip.h>
103258945Sroberto#include <isc/ipv6.h>
104258945Sroberto
105258945Sroberto/*
106258945Sroberto * This is here because named client, interfacemgr.c, etc. use the name as
107258945Sroberto * a variable
108258945Sroberto */
109258945Sroberto#undef interface
110258945Sroberto
111258945Sroberto#ifndef INADDR_LOOPBACK
112258945Sroberto#define INADDR_LOOPBACK 0x7f000001UL
113258945Sroberto#endif
114258945Sroberto
115258945Sroberto#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
116258945Srobertostruct in6_pktinfo {
117258945Sroberto	struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
118258945Sroberto	unsigned int    ipi6_ifindex; /* send/recv interface index */
119258945Sroberto};
120258945Sroberto#endif
121258945Sroberto
122258945Sroberto#if _MSC_VER < 1300
123258945Sroberto#define in6addr_any isc_net_in6addrany
124258945Sroberto#define in6addr_loopback isc_net_in6addrloop
125258945Sroberto#endif
126258945Sroberto
127258945Sroberto/*
128258945Sroberto * Ensure type in_port_t is defined.
129258945Sroberto */
130258945Sroberto#ifdef ISC_PLATFORM_NEEDPORTT
131258945Srobertotypedef isc_uint16_t in_port_t;
132258945Sroberto#endif
133258945Sroberto
134258945Sroberto/*
135258945Sroberto * If this system does not have MSG_TRUNC (as returned from recvmsg())
136258945Sroberto * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
137258945Sroberto * faking code in socket.c.
138258945Sroberto */
139258945Sroberto#ifndef MSG_TRUNC
140258945Sroberto#define ISC_PLATFORM_RECVOVERFLOW
141258945Sroberto#endif
142258945Sroberto
143258945Sroberto#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
144258945Sroberto
145258945Sroberto#define ISC_IPADDR_ISMULTICAST(i) \
146258945Sroberto		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
147258945Sroberto		 == ISC__IPADDR(0xe0000000))
148258945Sroberto
149258945Sroberto#define ISC_IPADDR_ISEXPERIMENTAL(i) \
150258945Sroberto		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
151258945Sroberto		 == ISC__IPADDR(0xf0000000))
152258945Sroberto
153258945Sroberto/*
154258945Sroberto * Fix the FD_SET and FD_CLR Macros to properly cast
155258945Sroberto */
156258945Sroberto#undef FD_CLR
157258945Sroberto#define FD_CLR(fd, set) do { \
158258945Sroberto    u_int __i; \
159258945Sroberto    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
160258945Sroberto	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \
161258945Sroberto	    while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
162258945Sroberto		((fd_set FAR *)(set))->fd_array[__i] = \
163258945Sroberto		    ((fd_set FAR *)(set))->fd_array[__i+1]; \
164258945Sroberto		__i++; \
165258945Sroberto	    } \
166258945Sroberto	    ((fd_set FAR *)(set))->fd_count--; \
167258945Sroberto	    break; \
168258945Sroberto	} \
169258945Sroberto    } \
170258945Sroberto} while (0)
171258945Sroberto
172258945Sroberto#undef FD_SET
173258945Sroberto#define FD_SET(fd, set) do { \
174258945Sroberto    u_int __i; \
175258945Sroberto    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
176258945Sroberto	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \
177258945Sroberto	    break; \
178258945Sroberto	} \
179258945Sroberto    } \
180258945Sroberto    if (__i == ((fd_set FAR *)(set))->fd_count) { \
181258945Sroberto	if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
182258945Sroberto	    ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \
183258945Sroberto	    ((fd_set FAR *)(set))->fd_count++; \
184258945Sroberto	} \
185258945Sroberto    } \
186258945Sroberto} while (0)
187258945Sroberto
188258945Sroberto/*
189258945Sroberto * Windows Sockets errors redefined as regular Berkeley error constants.
190258945Sroberto * These are usually commented out in Windows NT to avoid conflicts with errno.h.
191258945Sroberto * Use the WSA constants instead.
192258945Sroberto * Starting with VC9 (VC++ 2010) many of these are defined incompatibly
193258945Sroberto * by errno.h -- #undef the conflicting values, which are not relevant to
194258945Sroberto * Win32.
195258945Sroberto */
196258945Sroberto
197258945Sroberto#undef EWOULDBLOCK
198258945Sroberto#define EWOULDBLOCK             WSAEWOULDBLOCK
199258945Sroberto#undef EINPROGRESS
200258945Sroberto#define EINPROGRESS             WSAEINPROGRESS
201258945Sroberto#undef EALREADY
202258945Sroberto#define EALREADY                WSAEALREADY
203258945Sroberto#undef ENOTSOCK
204258945Sroberto#define ENOTSOCK                WSAENOTSOCK
205258945Sroberto#undef EDESTADDRREQ
206258945Sroberto#define EDESTADDRREQ            WSAEDESTADDRREQ
207258945Sroberto#undef EMSGSIZE
208258945Sroberto#define EMSGSIZE                WSAEMSGSIZE
209258945Sroberto#undef EPROTOTYPE
210258945Sroberto#define EPROTOTYPE              WSAEPROTOTYPE
211258945Sroberto#undef ENOPROTOOPT
212258945Sroberto#define ENOPROTOOPT             WSAENOPROTOOPT
213258945Sroberto#undef EPROTONOSUPPORT
214258945Sroberto#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
215258945Sroberto#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
216258945Sroberto#undef EOPNOTSUPP
217258945Sroberto#define EOPNOTSUPP              WSAEOPNOTSUPP
218258945Sroberto#define EPFNOSUPPORT            WSAEPFNOSUPPORT
219258945Sroberto#undef EAFNOSUPPORT
220258945Sroberto#define EAFNOSUPPORT            WSAEAFNOSUPPORT
221258945Sroberto#undef EADDRINUSE
222258945Sroberto#define EADDRINUSE              WSAEADDRINUSE
223258945Sroberto#undef EADDRNOTAVAIL
224258945Sroberto#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
225258945Sroberto#undef ENETDOWN
226258945Sroberto#define ENETDOWN                WSAENETDOWN
227258945Sroberto#undef ENETUNREACH
228258945Sroberto#define ENETUNREACH             WSAENETUNREACH
229258945Sroberto#undef ENETRESET
230258945Sroberto#define ENETRESET               WSAENETRESET
231258945Sroberto#undef ECONNABORTED
232258945Sroberto#define ECONNABORTED            WSAECONNABORTED
233258945Sroberto#undef ECONNRESET
234258945Sroberto#define ECONNRESET              WSAECONNRESET
235258945Sroberto#undef ENOBUFS
236258945Sroberto#define ENOBUFS                 WSAENOBUFS
237258945Sroberto#undef EISCONN
238258945Sroberto#define EISCONN                 WSAEISCONN
239258945Sroberto#undef ENOTCONN
240258945Sroberto#define ENOTCONN                WSAENOTCONN
241258945Sroberto#define ESHUTDOWN               WSAESHUTDOWN
242258945Sroberto#define ETOOMANYREFS            WSAETOOMANYREFS
243258945Sroberto#undef ETIMEDOUT
244258945Sroberto#define ETIMEDOUT               WSAETIMEDOUT
245258945Sroberto#undef ECONNREFUSED
246258945Sroberto#define ECONNREFUSED            WSAECONNREFUSED
247258945Sroberto#undef ELOOP
248258945Sroberto#define ELOOP                   WSAELOOP
249258945Sroberto#define EHOSTDOWN               WSAEHOSTDOWN
250258945Sroberto#undef EHOSTUNREACH
251258945Sroberto#define EHOSTUNREACH            WSAEHOSTUNREACH
252258945Sroberto#define EPROCLIM                WSAEPROCLIM
253258945Sroberto#define EUSERS                  WSAEUSERS
254258945Sroberto#define EDQUOT                  WSAEDQUOT
255258945Sroberto#define ESTALE                  WSAESTALE
256258945Sroberto#define EREMOTE                 WSAEREMOTE
257258945Sroberto
258258945Sroberto
259258945Sroberto/***
260258945Sroberto *** Functions.
261258945Sroberto ***/
262258945Sroberto
263258945SrobertoISC_LANG_BEGINDECLS
264258945Sroberto
265258945Srobertoisc_result_t
266258945Srobertoisc_net_probeipv4(void);
267258945Sroberto/*
268258945Sroberto * Check if the system's kernel supports IPv4.
269258945Sroberto *
270258945Sroberto * Returns:
271258945Sroberto *
272258945Sroberto *	ISC_R_SUCCESS		IPv4 is supported.
273258945Sroberto *	ISC_R_NOTFOUND		IPv4 is not supported.
274258945Sroberto *	ISC_R_DISABLED		IPv4 is disabled.
275258945Sroberto *	ISC_R_UNEXPECTED
276258945Sroberto */
277258945Sroberto
278258945Srobertoisc_result_t
279258945Srobertoisc_net_probeipv6(void);
280258945Sroberto/*
281258945Sroberto * Check if the system's kernel supports IPv6.
282258945Sroberto *
283258945Sroberto * Returns:
284258945Sroberto *
285258945Sroberto *	ISC_R_SUCCESS		IPv6 is supported.
286258945Sroberto *	ISC_R_NOTFOUND		IPv6 is not supported.
287258945Sroberto *	ISC_R_DISABLED		IPv6 is disabled.
288258945Sroberto *	ISC_R_UNEXPECTED
289258945Sroberto */
290258945Sroberto
291258945Srobertoisc_result_t
292258945Srobertoisc_net_probeunix(void);
293258945Sroberto/*
294258945Sroberto * Check if UNIX domain sockets are supported.
295258945Sroberto *
296258945Sroberto * Returns:
297258945Sroberto *
298258945Sroberto *	ISC_R_SUCCESS
299258945Sroberto *	ISC_R_NOTFOUND
300258945Sroberto */
301258945Sroberto
302258945Srobertoisc_result_t
303258945Srobertoisc_net_probe_ipv6only(void);
304258945Sroberto/*
305258945Sroberto * Check if the system's kernel supports the IPV6_V6ONLY socket option.
306258945Sroberto *
307258945Sroberto * Returns:
308258945Sroberto *
309258945Sroberto *	ISC_R_SUCCESS		the option is supported for both TCP and UDP.
310258945Sroberto *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
311258945Sroberto *	ISC_R_UNEXPECTED
312258945Sroberto */
313258945Sroberto
314258945Srobertoisc_result_t
315258945Srobertoisc_net_probe_ipv6pktinfo(void);
316258945Sroberto/*
317258945Sroberto * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
318258945Sroberto * for UDP sockets.
319258945Sroberto *
320258945Sroberto * Returns:
321258945Sroberto *
322258945Sroberto *	ISC_R_SUCCESS		the option is supported.
323258945Sroberto *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
324258945Sroberto *	ISC_R_UNEXPECTED
325258945Sroberto */
326258945Sroberto
327258945Srobertovoid
328258945Srobertoisc_net_disableipv4(void);
329258945Sroberto
330258945Srobertovoid
331258945Srobertoisc_net_disableipv6(void);
332258945Sroberto
333258945Srobertovoid
334258945Srobertoisc_net_enableipv4(void);
335258945Sroberto
336258945Srobertovoid
337258945Srobertoisc_net_enableipv6(void);
338258945Sroberto
339258945Srobertoisc_result_t
340258945Srobertoisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
341258945Sroberto/*%<
342258945Sroberto * Returns system's default range of ephemeral UDP ports, if defined.
343258945Sroberto * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
344258945Sroberto * ISC_NET_PORTRANGEHIGH will be returned.
345258945Sroberto *
346258945Sroberto * Requires:
347258945Sroberto *
348258945Sroberto *\li	'low' and 'high' must be non NULL.
349258945Sroberto *
350258945Sroberto * Returns:
351258945Sroberto *
352258945Sroberto *\li	*low and *high will be the ports specifying the low and high ends of
353258945Sroberto *	the range.
354258945Sroberto */
355258945Sroberto
356258945Sroberto#ifdef ISC_PLATFORM_NEEDNTOP
357258945Srobertoconst char *
358258945Srobertoisc_net_ntop(int af, const void *src, char *dst, size_t size);
359258945Sroberto#define inet_ntop isc_net_ntop
360258945Sroberto#endif
361258945Sroberto
362258945Sroberto#ifdef ISC_PLATFORM_NEEDPTON
363258945Srobertoint
364258945Srobertoisc_net_pton(int af, const char *src, void *dst);
365258945Sroberto#define inet_pton isc_net_pton
366258945Sroberto#endif
367258945Sroberto
368258945Srobertoint
369258945Srobertoisc_net_aton(const char *cp, struct in_addr *addr);
370258945Sroberto#define inet_aton isc_net_aton
371258945Sroberto
372258945SrobertoISC_LANG_ENDDECLS
373258945Sroberto
374258945Sroberto#endif /* ISC_NET_H */
375