1290001Sglebius/*
2290001Sglebius * Copyright (C) 2004, 2005, 2007, 2008, 2012  Internet Systems Consortium, Inc. ("ISC")
3290001Sglebius * Copyright (C) 1999-2003  Internet Software Consortium.
4290001Sglebius *
5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any
6290001Sglebius * purpose with or without fee is hereby granted, provided that the above
7290001Sglebius * copyright notice and this permission notice appear in all copies.
8290001Sglebius *
9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11290001Sglebius * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15290001Sglebius * PERFORMANCE OF THIS SOFTWARE.
16290001Sglebius */
17290001Sglebius
18290001Sglebius/* $Id$ */
19290001Sglebius
20290001Sglebius#ifndef ISC_NET_H
21290001Sglebius#define ISC_NET_H 1
22290001Sglebius
23290001Sglebius#include <errno.h>
24290001Sglebius
25290001Sglebius/*
26290001Sglebius * Also define LWRES_IPV6_H to keep it from being included if liblwres is
27290001Sglebius * being used, or redefinition errors will occur.
28290001Sglebius */
29290001Sglebius#define LWRES_IPV6_H 1
30290001Sglebius
31290001Sglebius
32290001Sglebius
33290001Sglebius/*****
34290001Sglebius ***** Module Info
35290001Sglebius *****/
36290001Sglebius
37290001Sglebius/*
38290001Sglebius * Basic Networking Types
39290001Sglebius *
40290001Sglebius * This module is responsible for defining the following basic networking
41290001Sglebius * types:
42290001Sglebius *
43290001Sglebius *		struct in_addr
44290001Sglebius *		struct in6_addr
45290001Sglebius *		struct in6_pktinfo
46290001Sglebius *		struct sockaddr
47290001Sglebius *		struct sockaddr_in
48290001Sglebius *		struct sockaddr_in6
49290001Sglebius *		in_port_t
50290001Sglebius *
51290001Sglebius * It ensures that the AF_ and PF_ macros are defined.
52290001Sglebius *
53290001Sglebius * It declares ntoh[sl]() and hton[sl]().
54290001Sglebius *
55290001Sglebius * It declares inet_aton(), inet_ntop(), and inet_pton().
56290001Sglebius *
57290001Sglebius * It ensures that INADDR_ANY, IN6ADDR_ANY_INIT, in6addr_any, and
58290001Sglebius * in6addr_loopback are available.
59290001Sglebius *
60290001Sglebius * It ensures that IN_MULTICAST() is available to check for multicast
61290001Sglebius * addresses.
62290001Sglebius *
63290001Sglebius * MP:
64290001Sglebius *	No impact.
65290001Sglebius *
66290001Sglebius * Reliability:
67290001Sglebius *	No anticipated impact.
68290001Sglebius *
69290001Sglebius * Resources:
70290001Sglebius *	N/A.
71290001Sglebius *
72290001Sglebius * Security:
73290001Sglebius *	No anticipated impact.
74290001Sglebius *
75290001Sglebius * Standards:
76290001Sglebius *	BSD Socket API
77290001Sglebius *	RFC2553
78290001Sglebius */
79290001Sglebius
80290001Sglebius/***
81290001Sglebius *** Imports.
82290001Sglebius ***/
83290001Sglebius#include <isc/platform.h>
84290001Sglebius
85290001Sglebius/*
86290001Sglebius * Because of some sort of problem in the MS header files, this cannot
87290001Sglebius * be simple "#include <winsock2.h>", because winsock2.h tries to include
88290001Sglebius * windows.h, which then generates an error out of mswsock.h.  _You_
89290001Sglebius * figure it out.
90290001Sglebius */
91290001Sglebius#ifndef _WINSOCKAPI_
92290001Sglebius#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */
93290001Sglebius#endif
94290001Sglebius
95290001Sglebius#include <winsock2.h>
96290001Sglebius
97290001Sglebius#include <sys/types.h>
98290001Sglebius
99290001Sglebius#include <isc/lang.h>
100290001Sglebius#include <isc/types.h>
101290001Sglebius
102290001Sglebius#include <ws2tcpip.h>
103290001Sglebius#include <isc/ipv6.h>
104290001Sglebius
105290001Sglebius/*
106290001Sglebius * This is here because named client, interfacemgr.c, etc. use the name as
107290001Sglebius * a variable
108290001Sglebius */
109290001Sglebius#undef interface
110290001Sglebius
111290001Sglebius#ifndef INADDR_LOOPBACK
112290001Sglebius#define INADDR_LOOPBACK 0x7f000001UL
113290001Sglebius#endif
114290001Sglebius
115290001Sglebius#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
116290001Sglebiusstruct in6_pktinfo {
117290001Sglebius	struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
118290001Sglebius	unsigned int    ipi6_ifindex; /* send/recv interface index */
119290001Sglebius};
120290001Sglebius#endif
121290001Sglebius
122290001Sglebius#if _MSC_VER < 1300
123290001Sglebius#define in6addr_any isc_net_in6addrany
124290001Sglebius#define in6addr_loopback isc_net_in6addrloop
125290001Sglebius#endif
126290001Sglebius
127290001Sglebius/*
128290001Sglebius * Ensure type in_port_t is defined.
129290001Sglebius */
130290001Sglebius#ifdef ISC_PLATFORM_NEEDPORTT
131290001Sglebiustypedef isc_uint16_t in_port_t;
132290001Sglebius#endif
133290001Sglebius
134290001Sglebius/*
135290001Sglebius * If this system does not have MSG_TRUNC (as returned from recvmsg())
136290001Sglebius * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
137290001Sglebius * faking code in socket.c.
138290001Sglebius */
139290001Sglebius#ifndef MSG_TRUNC
140290001Sglebius#define ISC_PLATFORM_RECVOVERFLOW
141290001Sglebius#endif
142290001Sglebius
143290001Sglebius#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
144290001Sglebius
145290001Sglebius#define ISC_IPADDR_ISMULTICAST(i) \
146290001Sglebius		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
147290001Sglebius		 == ISC__IPADDR(0xe0000000))
148290001Sglebius
149290001Sglebius#define ISC_IPADDR_ISEXPERIMENTAL(i) \
150290001Sglebius		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
151290001Sglebius		 == ISC__IPADDR(0xf0000000))
152290001Sglebius
153290001Sglebius/*
154290001Sglebius * Fix the FD_SET and FD_CLR Macros to properly cast
155290001Sglebius */
156290001Sglebius#undef FD_CLR
157290001Sglebius#define FD_CLR(fd, set) do { \
158290001Sglebius    u_int __i; \
159290001Sglebius    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
160290001Sglebius	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \
161290001Sglebius	    while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
162290001Sglebius		((fd_set FAR *)(set))->fd_array[__i] = \
163290001Sglebius		    ((fd_set FAR *)(set))->fd_array[__i+1]; \
164290001Sglebius		__i++; \
165290001Sglebius	    } \
166290001Sglebius	    ((fd_set FAR *)(set))->fd_count--; \
167290001Sglebius	    break; \
168290001Sglebius	} \
169290001Sglebius    } \
170290001Sglebius} while (0)
171290001Sglebius
172290001Sglebius#undef FD_SET
173290001Sglebius#define FD_SET(fd, set) do { \
174290001Sglebius    u_int __i; \
175290001Sglebius    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
176290001Sglebius	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \
177290001Sglebius	    break; \
178290001Sglebius	} \
179290001Sglebius    } \
180290001Sglebius    if (__i == ((fd_set FAR *)(set))->fd_count) { \
181290001Sglebius	if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
182290001Sglebius	    ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \
183290001Sglebius	    ((fd_set FAR *)(set))->fd_count++; \
184290001Sglebius	} \
185290001Sglebius    } \
186290001Sglebius} while (0)
187290001Sglebius
188290001Sglebius/*
189290001Sglebius * Windows Sockets errors redefined as regular Berkeley error constants.
190290001Sglebius * These are usually commented out in Windows NT to avoid conflicts with errno.h.
191290001Sglebius * Use the WSA constants instead.
192290001Sglebius * Starting with VC9 (VC++ 2010) many of these are defined incompatibly
193290001Sglebius * by errno.h -- #undef the conflicting values, which are not relevant to
194290001Sglebius * Win32.
195290001Sglebius */
196290001Sglebius
197290001Sglebius#undef EWOULDBLOCK
198290001Sglebius#define EWOULDBLOCK             WSAEWOULDBLOCK
199290001Sglebius#undef EINPROGRESS
200290001Sglebius#define EINPROGRESS             WSAEINPROGRESS
201290001Sglebius#undef EALREADY
202290001Sglebius#define EALREADY                WSAEALREADY
203290001Sglebius#undef ENOTSOCK
204290001Sglebius#define ENOTSOCK                WSAENOTSOCK
205290001Sglebius#undef EDESTADDRREQ
206290001Sglebius#define EDESTADDRREQ            WSAEDESTADDRREQ
207290001Sglebius#undef EMSGSIZE
208290001Sglebius#define EMSGSIZE                WSAEMSGSIZE
209290001Sglebius#undef EPROTOTYPE
210290001Sglebius#define EPROTOTYPE              WSAEPROTOTYPE
211290001Sglebius#undef ENOPROTOOPT
212290001Sglebius#define ENOPROTOOPT             WSAENOPROTOOPT
213290001Sglebius#undef EPROTONOSUPPORT
214290001Sglebius#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
215290001Sglebius#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
216290001Sglebius#undef EOPNOTSUPP
217290001Sglebius#define EOPNOTSUPP              WSAEOPNOTSUPP
218290001Sglebius#define EPFNOSUPPORT            WSAEPFNOSUPPORT
219290001Sglebius#undef EAFNOSUPPORT
220290001Sglebius#define EAFNOSUPPORT            WSAEAFNOSUPPORT
221290001Sglebius#undef EADDRINUSE
222290001Sglebius#define EADDRINUSE              WSAEADDRINUSE
223290001Sglebius#undef EADDRNOTAVAIL
224290001Sglebius#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
225290001Sglebius#undef ENETDOWN
226290001Sglebius#define ENETDOWN                WSAENETDOWN
227290001Sglebius#undef ENETUNREACH
228290001Sglebius#define ENETUNREACH             WSAENETUNREACH
229290001Sglebius#undef ENETRESET
230290001Sglebius#define ENETRESET               WSAENETRESET
231290001Sglebius#undef ECONNABORTED
232290001Sglebius#define ECONNABORTED            WSAECONNABORTED
233290001Sglebius#undef ECONNRESET
234290001Sglebius#define ECONNRESET              WSAECONNRESET
235290001Sglebius#undef ENOBUFS
236290001Sglebius#define ENOBUFS                 WSAENOBUFS
237290001Sglebius#undef EISCONN
238290001Sglebius#define EISCONN                 WSAEISCONN
239290001Sglebius#undef ENOTCONN
240290001Sglebius#define ENOTCONN                WSAENOTCONN
241290001Sglebius#define ESHUTDOWN               WSAESHUTDOWN
242290001Sglebius#define ETOOMANYREFS            WSAETOOMANYREFS
243290001Sglebius#undef ETIMEDOUT
244290001Sglebius#define ETIMEDOUT               WSAETIMEDOUT
245290001Sglebius#undef ECONNREFUSED
246290001Sglebius#define ECONNREFUSED            WSAECONNREFUSED
247290001Sglebius#undef ELOOP
248290001Sglebius#define ELOOP                   WSAELOOP
249290001Sglebius#define EHOSTDOWN               WSAEHOSTDOWN
250290001Sglebius#undef EHOSTUNREACH
251290001Sglebius#define EHOSTUNREACH            WSAEHOSTUNREACH
252290001Sglebius#define EPROCLIM                WSAEPROCLIM
253290001Sglebius#define EUSERS                  WSAEUSERS
254290001Sglebius#define EDQUOT                  WSAEDQUOT
255290001Sglebius#define ESTALE                  WSAESTALE
256290001Sglebius#define EREMOTE                 WSAEREMOTE
257290001Sglebius
258290001Sglebius
259290001Sglebius/***
260290001Sglebius *** Functions.
261290001Sglebius ***/
262290001Sglebius
263290001SglebiusISC_LANG_BEGINDECLS
264290001Sglebius
265290001Sglebiusisc_result_t
266290001Sglebiusisc_net_probeipv4(void);
267290001Sglebius/*
268290001Sglebius * Check if the system's kernel supports IPv4.
269290001Sglebius *
270290001Sglebius * Returns:
271290001Sglebius *
272290001Sglebius *	ISC_R_SUCCESS		IPv4 is supported.
273290001Sglebius *	ISC_R_NOTFOUND		IPv4 is not supported.
274290001Sglebius *	ISC_R_DISABLED		IPv4 is disabled.
275290001Sglebius *	ISC_R_UNEXPECTED
276290001Sglebius */
277290001Sglebius
278290001Sglebiusisc_result_t
279290001Sglebiusisc_net_probeipv6(void);
280290001Sglebius/*
281290001Sglebius * Check if the system's kernel supports IPv6.
282290001Sglebius *
283290001Sglebius * Returns:
284290001Sglebius *
285290001Sglebius *	ISC_R_SUCCESS		IPv6 is supported.
286290001Sglebius *	ISC_R_NOTFOUND		IPv6 is not supported.
287290001Sglebius *	ISC_R_DISABLED		IPv6 is disabled.
288290001Sglebius *	ISC_R_UNEXPECTED
289290001Sglebius */
290290001Sglebius
291290001Sglebiusisc_result_t
292290001Sglebiusisc_net_probeunix(void);
293290001Sglebius/*
294290001Sglebius * Check if UNIX domain sockets are supported.
295290001Sglebius *
296290001Sglebius * Returns:
297290001Sglebius *
298290001Sglebius *	ISC_R_SUCCESS
299290001Sglebius *	ISC_R_NOTFOUND
300290001Sglebius */
301290001Sglebius
302290001Sglebiusisc_result_t
303290001Sglebiusisc_net_probe_ipv6only(void);
304290001Sglebius/*
305290001Sglebius * Check if the system's kernel supports the IPV6_V6ONLY socket option.
306290001Sglebius *
307290001Sglebius * Returns:
308290001Sglebius *
309290001Sglebius *	ISC_R_SUCCESS		the option is supported for both TCP and UDP.
310290001Sglebius *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
311290001Sglebius *	ISC_R_UNEXPECTED
312290001Sglebius */
313290001Sglebius
314290001Sglebiusisc_result_t
315290001Sglebiusisc_net_probe_ipv6pktinfo(void);
316290001Sglebius/*
317290001Sglebius * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
318290001Sglebius * for UDP sockets.
319290001Sglebius *
320290001Sglebius * Returns:
321290001Sglebius *
322290001Sglebius *	ISC_R_SUCCESS		the option is supported.
323290001Sglebius *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
324290001Sglebius *	ISC_R_UNEXPECTED
325290001Sglebius */
326290001Sglebius
327290001Sglebiusvoid
328290001Sglebiusisc_net_disableipv4(void);
329290001Sglebius
330290001Sglebiusvoid
331290001Sglebiusisc_net_disableipv6(void);
332290001Sglebius
333290001Sglebiusvoid
334290001Sglebiusisc_net_enableipv4(void);
335290001Sglebius
336290001Sglebiusvoid
337290001Sglebiusisc_net_enableipv6(void);
338290001Sglebius
339290001Sglebiusisc_result_t
340290001Sglebiusisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
341290001Sglebius/*%<
342290001Sglebius * Returns system's default range of ephemeral UDP ports, if defined.
343290001Sglebius * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
344290001Sglebius * ISC_NET_PORTRANGEHIGH will be returned.
345290001Sglebius *
346290001Sglebius * Requires:
347290001Sglebius *
348290001Sglebius *\li	'low' and 'high' must be non NULL.
349290001Sglebius *
350290001Sglebius * Returns:
351290001Sglebius *
352290001Sglebius *\li	*low and *high will be the ports specifying the low and high ends of
353290001Sglebius *	the range.
354290001Sglebius */
355290001Sglebius
356290001Sglebius#ifdef ISC_PLATFORM_NEEDNTOP
357290001Sglebiusconst char *
358290001Sglebiusisc_net_ntop(int af, const void *src, char *dst, size_t size);
359290001Sglebius#define inet_ntop isc_net_ntop
360290001Sglebius#endif
361290001Sglebius
362290001Sglebius#ifdef ISC_PLATFORM_NEEDPTON
363290001Sglebiusint
364290001Sglebiusisc_net_pton(int af, const char *src, void *dst);
365290001Sglebius#define inet_pton isc_net_pton
366290001Sglebius#endif
367290001Sglebius
368290001Sglebiusint
369290001Sglebiusisc_net_aton(const char *cp, struct in_addr *addr);
370290001Sglebius#define inet_aton isc_net_aton
371290001Sglebius
372290001SglebiusISC_LANG_ENDDECLS
373290001Sglebius
374290001Sglebius#endif /* ISC_NET_H */
375