1132451Sroberto/*
2182007Sroberto * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3182007Sroberto * Copyright (C) 1999-2003  Internet Software Consortium.
4132451Sroberto *
5132451Sroberto * Permission to use, copy, modify, and distribute this software for any
6132451Sroberto * purpose with or without fee is hereby granted, provided that the above
7132451Sroberto * copyright notice and this permission notice appear in all copies.
8132451Sroberto *
9182007Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10182007Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11182007Sroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12182007Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13182007Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14182007Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15182007Sroberto * PERFORMANCE OF THIS SOFTWARE.
16132451Sroberto */
17132451Sroberto
18182007Sroberto/* $Id: net.h,v 1.31.2.2.10.8 2004/04/29 01:31:23 marka Exp $ */
19132451Sroberto
20132451Sroberto#ifndef ISC_NET_H
21132451Sroberto#define ISC_NET_H 1
22132451Sroberto
23132451Sroberto/*****
24132451Sroberto ***** Module Info
25132451Sroberto *****/
26132451Sroberto
27132451Sroberto/*
28132451Sroberto * Basic Networking Types
29132451Sroberto *
30132451Sroberto * This module is responsible for defining the following basic networking
31132451Sroberto * types:
32132451Sroberto *
33132451Sroberto *		struct in_addr
34132451Sroberto *		struct in6_addr
35132451Sroberto *		struct in6_pktinfo
36132451Sroberto *		struct sockaddr
37132451Sroberto *		struct sockaddr_in
38132451Sroberto *		struct sockaddr_in6
39132451Sroberto *		in_port_t
40132451Sroberto *
41132451Sroberto * It ensures that the AF_ and PF_ macros are defined.
42132451Sroberto *
43132451Sroberto * It declares ntoh[sl]() and hton[sl]().
44132451Sroberto *
45132451Sroberto * It declares inet_aton(), inet_ntop(), and inet_pton().
46132451Sroberto *
47132451Sroberto * It ensures that INADDR_LOOPBACK, INADDR_ANY, IN6ADDR_ANY_INIT,
48132451Sroberto * in6addr_any, and in6addr_loopback are available.
49132451Sroberto *
50132451Sroberto * It ensures that IN_MULTICAST() is available to check for multicast
51132451Sroberto * addresses.
52132451Sroberto *
53132451Sroberto * MP:
54132451Sroberto *	No impact.
55132451Sroberto *
56132451Sroberto * Reliability:
57132451Sroberto *	No anticipated impact.
58132451Sroberto *
59132451Sroberto * Resources:
60132451Sroberto *	N/A.
61132451Sroberto *
62132451Sroberto * Security:
63132451Sroberto *	No anticipated impact.
64132451Sroberto *
65132451Sroberto * Standards:
66132451Sroberto *	BSD Socket API
67132451Sroberto *	RFC 2553
68132451Sroberto */
69132451Sroberto
70132451Sroberto/***
71132451Sroberto *** Imports.
72132451Sroberto ***/
73132451Sroberto#include <isc/platform.h>
74132451Sroberto
75132451Sroberto#include <sys/types.h>
76132451Sroberto#include <sys/socket.h>		/* Contractual promise. */
77132451Sroberto
78182007Sroberto#include <net/if.h>
79182007Sroberto
80132451Sroberto#include <netinet/in.h>		/* Contractual promise. */
81132451Sroberto#include <arpa/inet.h>		/* Contractual promise. */
82132451Sroberto#ifdef ISC_PLATFORM_NEEDNETINETIN6H
83132451Sroberto#include <netinet/in6.h>	/* Required on UnixWare. */
84132451Sroberto#endif
85132451Sroberto#ifdef ISC_PLATFORM_NEEDNETINET6IN6H
86132451Sroberto#include <netinet6/in6.h>	/* Required on BSD/OS for in6_pktinfo. */
87132451Sroberto#endif
88132451Sroberto
89132451Sroberto#ifndef ISC_PLATFORM_HAVEIPV6
90132451Sroberto#include <isc/ipv6.h>		/* Contractual promise. */
91132451Sroberto#endif
92132451Sroberto
93132451Sroberto#include <isc/lang.h>
94132451Sroberto#include <isc/types.h>
95132451Sroberto
96132451Sroberto#ifdef ISC_PLATFORM_HAVEINADDR6
97132451Sroberto#define in6_addr in_addr6	/* Required for pre RFC2133 implementations. */
98132451Sroberto#endif
99132451Sroberto
100132451Sroberto#ifdef ISC_PLATFORM_HAVEIPV6
101132451Sroberto/*
102132451Sroberto * Required for some pre RFC2133 implementations.
103132451Sroberto * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
104132451Sroberto * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
105132451Sroberto * If 's6_addr' is defined then assume that there is a union and three
106132451Sroberto * levels otherwise assume two levels required.
107132451Sroberto */
108132451Sroberto#ifndef IN6ADDR_ANY_INIT
109132451Sroberto#ifdef s6_addr
110132451Sroberto#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
111132451Sroberto#else
112132451Sroberto#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
113132451Sroberto#endif
114132451Sroberto#endif
115132451Sroberto
116132451Sroberto#ifndef IN6ADDR_LOOPBACK_INIT
117132451Sroberto#ifdef s6_addr
118132451Sroberto#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
119132451Sroberto#else
120132451Sroberto#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
121132451Sroberto#endif
122132451Sroberto#endif
123132451Sroberto
124132451Sroberto#ifndef IN6_IS_ADDR_V4MAPPED
125132451Sroberto#define IN6_IS_ADDR_V4MAPPED(x) \
126132451Sroberto	 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
127132451Sroberto	  (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
128132451Sroberto#endif
129132451Sroberto
130132451Sroberto#ifndef IN6_IS_ADDR_V4COMPAT
131132451Sroberto#define IN6_IS_ADDR_V4COMPAT(x) \
132132451Sroberto	 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
133132451Sroberto	 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \
134132451Sroberto	  (x)->s6_addr[14] != 0 || \
135132451Sroberto	  ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
136132451Sroberto#endif
137132451Sroberto
138132451Sroberto#ifndef IN6_IS_ADDR_MULTICAST
139132451Sroberto#define IN6_IS_ADDR_MULTICAST(a)        ((a)->s6_addr[0] == 0xff)
140132451Sroberto#endif
141132451Sroberto
142132451Sroberto#ifndef IN6_IS_ADDR_LINKLOCAL
143132451Sroberto#define IN6_IS_ADDR_LINKLOCAL(a) \
144132451Sroberto	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
145132451Sroberto#endif
146132451Sroberto
147132451Sroberto#ifndef IN6_IS_ADDR_SITELOCAL
148132451Sroberto#define IN6_IS_ADDR_SITELOCAL(a) \
149132451Sroberto	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
150132451Sroberto#endif
151132451Sroberto
152132451Sroberto
153132451Sroberto#ifndef IN6_IS_ADDR_LOOPBACK
154132451Sroberto#define IN6_IS_ADDR_LOOPBACK(x) \
155132451Sroberto	(memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
156132451Sroberto#endif
157132451Sroberto#endif
158132451Sroberto
159132451Sroberto#ifndef AF_INET6
160132451Sroberto#define AF_INET6 99
161132451Sroberto#endif
162132451Sroberto
163132451Sroberto#ifndef PF_INET6
164132451Sroberto#define PF_INET6 AF_INET6
165132451Sroberto#endif
166132451Sroberto
167132451Sroberto#ifndef INADDR_LOOPBACK
168132451Sroberto#define INADDR_LOOPBACK 0x7f000001UL
169132451Sroberto#endif
170132451Sroberto
171132451Sroberto#if 0
172132451Sroberto#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
173132451Srobertostruct in6_pktinfo {
174132451Sroberto	struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
175132451Sroberto	unsigned int    ipi6_ifindex; /* send/recv interface index */
176132451Sroberto};
177132451Sroberto#endif
178132451Sroberto#endif
179132451Sroberto
180132451Sroberto/*
181132451Sroberto * Cope with a missing in6addr_any and in6addr_loopback.
182132451Sroberto */
183132451Sroberto#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY)
184132451Srobertoextern const struct in6_addr isc_net_in6addrany;
185132451Sroberto#define in6addr_any isc_net_in6addrany
186132451Sroberto#endif
187132451Sroberto
188132451Sroberto#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
189132451Srobertoextern const struct in6_addr isc_net_in6addrloop;
190132451Sroberto#define in6addr_loopback isc_net_in6addrloop
191132451Sroberto#endif
192132451Sroberto
193132451Sroberto/*
194132451Sroberto * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions.
195132451Sroberto */
196132451Sroberto#ifdef ISC_PLATFORM_FIXIN6ISADDR
197132451Sroberto#undef  IN6_IS_ADDR_GEOGRAPHIC
198132451Sroberto#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80)
199132451Sroberto#undef  IN6_IS_ADDR_IPX
200132451Sroberto#define IN6_IS_ADDR_IPX(a)        (((a)->S6_un.S6_l[0] & 0xFE) == 0x04)
201132451Sroberto#undef  IN6_IS_ADDR_LINKLOCAL
202132451Sroberto#define IN6_IS_ADDR_LINKLOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE)
203132451Sroberto#undef  IN6_IS_ADDR_MULTICAST
204132451Sroberto#define IN6_IS_ADDR_MULTICAST(a)  (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF)
205132451Sroberto#undef  IN6_IS_ADDR_NSAP
206132451Sroberto#define IN6_IS_ADDR_NSAP(a)       (((a)->S6_un.S6_l[0] & 0xFE) == 0x02)
207132451Sroberto#undef  IN6_IS_ADDR_PROVIDER
208132451Sroberto#define IN6_IS_ADDR_PROVIDER(a)   (((a)->S6_un.S6_l[0] & 0xE0) == 0x40)
209132451Sroberto#undef  IN6_IS_ADDR_SITELOCAL
210132451Sroberto#define IN6_IS_ADDR_SITELOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE)
211132451Sroberto#endif /* ISC_PLATFORM_FIXIN6ISADDR */
212132451Sroberto
213132451Sroberto/*
214132451Sroberto * Ensure type in_port_t is defined.
215132451Sroberto */
216132451Sroberto#ifdef ISC_PLATFORM_NEEDPORTT
217132451Srobertotypedef isc_uint16_t in_port_t;
218132451Sroberto#endif
219132451Sroberto
220132451Sroberto/*
221132451Sroberto * If this system does not have MSG_TRUNC (as returned from recvmsg())
222132451Sroberto * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
223132451Sroberto * faking code in socket.c.
224132451Sroberto */
225132451Sroberto#ifndef MSG_TRUNC
226132451Sroberto#define ISC_PLATFORM_RECVOVERFLOW
227132451Sroberto#endif
228132451Sroberto
229132451Sroberto#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
230132451Sroberto
231132451Sroberto#define ISC_IPADDR_ISMULTICAST(i) \
232132451Sroberto		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
233132451Sroberto		 == ISC__IPADDR(0xe0000000))
234132451Sroberto
235182007Sroberto#define ISC_IPADDR_ISEXPERIMENTAL(i) \
236182007Sroberto		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
237182007Sroberto		 == ISC__IPADDR(0xf0000000))
238182007Sroberto
239132451Sroberto/***
240132451Sroberto *** Functions.
241132451Sroberto ***/
242132451Sroberto
243132451SrobertoISC_LANG_BEGINDECLS
244132451Sroberto
245132451Srobertoisc_result_t
246132451Srobertoisc_net_probeipv4(void);
247132451Sroberto/*
248132451Sroberto * Check if the system's kernel supports IPv4.
249132451Sroberto *
250132451Sroberto * Returns:
251132451Sroberto *
252132451Sroberto *	ISC_R_SUCCESS		IPv4 is supported.
253132451Sroberto *	ISC_R_NOTFOUND		IPv4 is not supported.
254182007Sroberto *	ISC_R_DISABLED		IPv4 is disabled.
255132451Sroberto *	ISC_R_UNEXPECTED
256132451Sroberto */
257132451Sroberto
258132451Srobertoisc_result_t
259132451Srobertoisc_net_probeipv6(void);
260132451Sroberto/*
261132451Sroberto * Check if the system's kernel supports IPv6.
262132451Sroberto *
263132451Sroberto * Returns:
264132451Sroberto *
265132451Sroberto *	ISC_R_SUCCESS		IPv6 is supported.
266132451Sroberto *	ISC_R_NOTFOUND		IPv6 is not supported.
267182007Sroberto *	ISC_R_DISABLED		IPv6 is disabled.
268132451Sroberto *	ISC_R_UNEXPECTED
269132451Sroberto */
270132451Sroberto
271182007Srobertoisc_result_t
272182007Srobertoisc_net_probe_ipv6only(void);
273182007Sroberto/*
274182007Sroberto * Check if the system's kernel supports the IPV6_V6ONLY socket option.
275182007Sroberto *
276182007Sroberto * Returns:
277182007Sroberto *
278182007Sroberto *	ISC_R_SUCCESS		the option is supported for both TCP and UDP.
279182007Sroberto *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
280182007Sroberto *	ISC_R_UNEXPECTED
281182007Sroberto */
282182007Sroberto
283182007Srobertoisc_result_t
284182007Srobertoisc_net_probe_ipv6pktinfo(void);
285182007Sroberto/*
286182007Sroberto * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
287182007Sroberto * for UDP sockets.
288182007Sroberto *
289182007Sroberto * Returns:
290182007Sroberto *
291182007Sroberto *	ISC_R_SUCCESS		the option is supported.
292182007Sroberto *	ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
293182007Sroberto *	ISC_R_UNEXPECTED
294182007Sroberto */
295182007Sroberto
296182007Srobertovoid
297182007Srobertoisc_net_disableipv4(void);
298182007Sroberto
299182007Srobertovoid
300182007Srobertoisc_net_disableipv6(void);
301182007Sroberto
302182007Srobertovoid
303182007Srobertoisc_net_enableipv4(void);
304182007Sroberto
305182007Srobertovoid
306182007Srobertoisc_net_enableipv6(void);
307182007Sroberto
308182007Sroberto#ifdef ISC_PLATFORM_NEEDNTOP
309132451Srobertoconst char *
310132451Srobertoisc_net_ntop(int af, const void *src, char *dst, size_t size);
311132451Sroberto#define inet_ntop isc_net_ntop
312132451Sroberto#endif
313132451Sroberto
314182007Sroberto#ifdef ISC_PLATFORM_NEEDPTON
315132451Srobertoint
316132451Srobertoisc_net_pton(int af, const char *src, void *dst);
317132451Sroberto#undef inet_pton
318132451Sroberto#define inet_pton isc_net_pton
319132451Sroberto#endif
320132451Sroberto
321182007Sroberto#ifdef ISC_PLATFORM_NEEDATON
322132451Srobertoint
323132451Srobertoisc_net_aton(const char *cp, struct in_addr *addr);
324132451Sroberto#define inet_aton isc_net_aton
325132451Sroberto#endif
326132451Sroberto
327132451SrobertoISC_LANG_ENDDECLS
328132451Sroberto
329132451Sroberto#endif /* ISC_NET_H */
330