1/*
2 * Copyright (C) 2004, 2005, 2007-2009  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: net.h,v 1.30.82.2 2009/02/16 23:47:15 tbox Exp $ */
19
20#ifndef ISC_NET_H
21#define ISC_NET_H 1
22
23/*
24 * Also define LWRES_IPV6_H to keep it from being included if liblwres is
25 * being used, or redefinition errors will occur.
26 */
27#define LWRES_IPV6_H 1
28
29
30
31/*****
32 ***** Module Info
33 *****/
34
35/*
36 * Basic Networking Types
37 *
38 * This module is responsible for defining the following basic networking
39 * types:
40 *
41 *		struct in_addr
42 *		struct in6_addr
43 *		struct in6_pktinfo
44 *		struct sockaddr
45 *		struct sockaddr_in
46 *		struct sockaddr_in6
47 *		in_port_t
48 *
49 * It ensures that the AF_ and PF_ macros are defined.
50 *
51 * It declares ntoh[sl]() and hton[sl]().
52 *
53 * It declares inet_aton(), inet_ntop(), and inet_pton().
54 *
55 * It ensures that INADDR_ANY, IN6ADDR_ANY_INIT, in6addr_any, and
56 * in6addr_loopback are available.
57 *
58 * It ensures that IN_MULTICAST() is available to check for multicast
59 * addresses.
60 *
61 * MP:
62 *	No impact.
63 *
64 * Reliability:
65 *	No anticipated impact.
66 *
67 * Resources:
68 *	N/A.
69 *
70 * Security:
71 *	No anticipated impact.
72 *
73 * Standards:
74 *	BSD Socket API
75 *	RFC2553
76 */
77
78/***
79 *** Imports.
80 ***/
81#include <isc/platform.h>
82
83/*
84 * Because of some sort of problem in the MS header files, this cannot
85 * be simple "#include <winsock2.h>", because winsock2.h tries to include
86 * windows.h, which then generates an error out of mswsock.h.  _You_
87 * figure it out.
88 */
89#ifndef _WINSOCKAPI_
90#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */
91#endif
92
93#include <winsock2.h>
94
95#include <sys/types.h>
96
97#include <isc/lang.h>
98#include <isc/types.h>
99
100#include <ws2tcpip.h>
101#include <isc/ipv6.h>
102
103/*
104 * This is here because named client, interfacemgr.c, etc. use the name as
105 * a variable
106 */
107#undef interface
108
109#ifndef INADDR_LOOPBACK
110#define INADDR_LOOPBACK 0x7f000001UL
111#endif
112
113#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
114struct in6_pktinfo {
115	struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
116	unsigned int    ipi6_ifindex; /* send/recv interface index */
117};
118#endif
119
120#if _MSC_VER < 1300
121#define in6addr_any isc_net_in6addrany
122#define in6addr_loopback isc_net_in6addrloop
123#endif
124
125/*
126 * Ensure type in_port_t is defined.
127 */
128#ifdef ISC_PLATFORM_NEEDPORTT
129typedef isc_uint16_t in_port_t;
130#endif
131
132/*
133 * If this system does not have MSG_TRUNC (as returned from recvmsg())
134 * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
135 * faking code in socket.c.
136 */
137#ifndef MSG_TRUNC
138#define ISC_PLATFORM_RECVOVERFLOW
139#endif
140
141#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
142
143#define ISC_IPADDR_ISMULTICAST(i) \
144		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
145		 == ISC__IPADDR(0xe0000000))
146
147#define ISC_IPADDR_ISEXPERIMENTAL(i) \
148		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
149		 == ISC__IPADDR(0xf0000000))
150
151/*
152 * Fix the FD_SET and FD_CLR Macros to properly cast
153 */
154#undef FD_CLR
155#define FD_CLR(fd, set) do { \
156    u_int __i; \
157    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
158	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \
159	    while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
160		((fd_set FAR *)(set))->fd_array[__i] = \
161		    ((fd_set FAR *)(set))->fd_array[__i+1]; \
162		__i++; \
163	    } \
164	    ((fd_set FAR *)(set))->fd_count--; \
165	    break; \
166	} \
167    } \
168} while (0)
169
170#undef FD_SET
171#define FD_SET(fd, set) do { \
172    u_int __i; \
173    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
174	if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \
175	    break; \
176	} \
177    } \
178    if (__i == ((fd_set FAR *)(set))->fd_count) { \
179	if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
180	    ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \
181	    ((fd_set FAR *)(set))->fd_count++; \
182	} \
183    } \
184} while (0)
185
186/*
187 * Windows Sockets errors redefined as regular Berkeley error constants.
188 * These are usually commented out in Windows NT to avoid conflicts with errno.h.
189 * Use the WSA constants instead.
190 */
191
192#define EWOULDBLOCK             WSAEWOULDBLOCK
193#define EINPROGRESS             WSAEINPROGRESS
194#define EALREADY                WSAEALREADY
195#define ENOTSOCK                WSAENOTSOCK
196#define EDESTADDRREQ            WSAEDESTADDRREQ
197#define EMSGSIZE                WSAEMSGSIZE
198#define EPROTOTYPE              WSAEPROTOTYPE
199#define ENOPROTOOPT             WSAENOPROTOOPT
200#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
201#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
202#define EOPNOTSUPP              WSAEOPNOTSUPP
203#define EPFNOSUPPORT            WSAEPFNOSUPPORT
204#define EAFNOSUPPORT            WSAEAFNOSUPPORT
205#define EADDRINUSE              WSAEADDRINUSE
206#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
207#define ENETDOWN                WSAENETDOWN
208#define ENETUNREACH             WSAENETUNREACH
209#define ENETRESET               WSAENETRESET
210#define ECONNABORTED            WSAECONNABORTED
211#define ECONNRESET              WSAECONNRESET
212#define ENOBUFS                 WSAENOBUFS
213#define EISCONN                 WSAEISCONN
214#define ENOTCONN                WSAENOTCONN
215#define ESHUTDOWN               WSAESHUTDOWN
216#define ETOOMANYREFS            WSAETOOMANYREFS
217#define ETIMEDOUT               WSAETIMEDOUT
218#define ECONNREFUSED            WSAECONNREFUSED
219#define ELOOP                   WSAELOOP
220#define EHOSTDOWN               WSAEHOSTDOWN
221#define EHOSTUNREACH            WSAEHOSTUNREACH
222#define EPROCLIM                WSAEPROCLIM
223#define EUSERS                  WSAEUSERS
224#define EDQUOT                  WSAEDQUOT
225#define ESTALE                  WSAESTALE
226#define EREMOTE                 WSAEREMOTE
227
228
229/***
230 *** Functions.
231 ***/
232
233ISC_LANG_BEGINDECLS
234
235isc_result_t
236isc_net_probeipv4(void);
237/*
238 * Check if the system's kernel supports IPv4.
239 *
240 * Returns:
241 *
242 *	ISC_R_SUCCESS		IPv4 is supported.
243 *	ISC_R_NOTFOUND		IPv4 is not supported.
244 *	ISC_R_DISABLED		IPv4 is disabled.
245 *	ISC_R_UNEXPECTED
246 */
247
248isc_result_t
249isc_net_probeipv6(void);
250/*
251 * Check if the system's kernel supports IPv6.
252 *
253 * Returns:
254 *
255 *	ISC_R_SUCCESS		IPv6 is supported.
256 *	ISC_R_NOTFOUND		IPv6 is not supported.
257 *	ISC_R_DISABLED		IPv6 is disabled.
258 *	ISC_R_UNEXPECTED
259 */
260
261isc_result_t
262isc_net_probeunix(void);
263/*
264 * Check if UNIX domain sockets are supported.
265 *
266 * Returns:
267 *
268 *	ISC_R_SUCCESS
269 *	ISC_R_NOTFOUND
270 */
271
272isc_result_t
273isc_net_probe_ipv6only(void);
274/*
275 * Check if the system's kernel supports the IPV6_V6ONLY socket option.
276 *
277 * Returns:
278 *
279 *	ISC_R_SUCCESS		the option is supported for both TCP and UDP.
280 *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
281 *	ISC_R_UNEXPECTED
282 */
283
284isc_result_t
285isc_net_probe_ipv6pktinfo(void);
286/*
287 * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
288 * for UDP sockets.
289 *
290 * Returns:
291 *
292 *	ISC_R_SUCCESS		the option is supported.
293 *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
294 *	ISC_R_UNEXPECTED
295 */
296
297void
298isc_net_disableipv4(void);
299
300void
301isc_net_disableipv6(void);
302
303void
304isc_net_enableipv4(void);
305
306void
307isc_net_enableipv6(void);
308
309isc_result_t
310isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
311/*%<
312 * Returns system's default range of ephemeral UDP ports, if defined.
313 * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
314 * ISC_NET_PORTRANGEHIGH will be returned.
315 *
316 * Requires:
317 *
318 *\li	'low' and 'high' must be non NULL.
319 *
320 * Returns:
321 *
322 *\li	*low and *high will be the ports specifying the low and high ends of
323 *	the range.
324 */
325
326#ifdef ISC_PLATFORM_NEEDNTOP
327const char *
328isc_net_ntop(int af, const void *src, char *dst, size_t size);
329#define inet_ntop isc_net_ntop
330#endif
331
332#ifdef ISC_PLATFORM_NEEDPTON
333int
334isc_net_pton(int af, const char *src, void *dst);
335#define inet_pton isc_net_pton
336#endif
337
338int
339isc_net_aton(const char *cp, struct in_addr *addr);
340#define inet_aton isc_net_aton
341
342ISC_LANG_ENDDECLS
343
344#endif /* ISC_NET_H */
345