1118e757roberto/*
2047f369cy * Copyright (C) 2004, 2005, 2007, 2008, 2012  Internet Systems Consortium, Inc. ("ISC")
37a6072eroberto * Copyright (C) 1999-2003  Internet Software Consortium.
4118e757roberto *
5d54cfbdroberto * Permission to use, copy, modify, and/or distribute this software for any
6118e757roberto * purpose with or without fee is hereby granted, provided that the above
7118e757roberto * copyright notice and this permission notice appear in all copies.
8118e757roberto *
97a6072eroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
107a6072eroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
117a6072eroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
127a6072eroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
137a6072eroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
147a6072eroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
157a6072eroberto * PERFORMANCE OF THIS SOFTWARE.
16118e757roberto */
17118e757roberto
18047f369cy/* $Id$ */
19118e757roberto
20118e757roberto#ifndef ISC_NET_H
21118e757roberto#define ISC_NET_H 1
22118e757roberto
23118e757roberto/*****
24118e757roberto ***** Module Info
25118e757roberto *****/
26118e757roberto
27d54cfbdroberto/*! \file
28d54cfbdroberto * \brief
29118e757roberto * Basic Networking Types
30118e757roberto *
31118e757roberto * This module is responsible for defining the following basic networking
32118e757roberto * types:
33118e757roberto *
34d54cfbdroberto *\li		struct in_addr
35d54cfbdroberto *\li		struct in6_addr
36d54cfbdroberto *\li		struct in6_pktinfo
37d54cfbdroberto *\li		struct sockaddr
38d54cfbdroberto *\li		struct sockaddr_in
39d54cfbdroberto *\li		struct sockaddr_in6
40d54cfbdroberto *\li		in_port_t
41118e757roberto *
42118e757roberto * It ensures that the AF_ and PF_ macros are defined.
43118e757roberto *
44118e757roberto * It declares ntoh[sl]() and hton[sl]().
45118e757roberto *
46118e757roberto * It declares inet_aton(), inet_ntop(), and inet_pton().
47118e757roberto *
48d54cfbdroberto * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
49118e757roberto * in6addr_any, and in6addr_loopback are available.
50118e757roberto *
51118e757roberto * It ensures that IN_MULTICAST() is available to check for multicast
52118e757roberto * addresses.
53118e757roberto *
54118e757roberto * MP:
55d54cfbdroberto *\li	No impact.
56118e757roberto *
57118e757roberto * Reliability:
58d54cfbdroberto *\li	No anticipated impact.
59118e757roberto *
60118e757roberto * Resources:
61d54cfbdroberto *\li	N/A.
62118e757roberto *
63118e757roberto * Security:
64d54cfbdroberto *\li	No anticipated impact.
65118e757roberto *
66118e757roberto * Standards:
67d54cfbdroberto *\li	BSD Socket API
68d54cfbdroberto *\li	RFC2553
69118e757roberto */
70118e757roberto
71118e757roberto/***
72118e757roberto *** Imports.
73118e757roberto ***/
74118e757roberto#include <isc/platform.h>
75118e757roberto
76118e757roberto#include <sys/types.h>
77118e757roberto#include <sys/socket.h>		/* Contractual promise. */
78118e757roberto
797a6072eroberto#include <net/if.h>
807a6072eroberto
81118e757roberto#include <netinet/in.h>		/* Contractual promise. */
82118e757roberto#include <arpa/inet.h>		/* Contractual promise. */
83118e757roberto#ifdef ISC_PLATFORM_NEEDNETINETIN6H
84118e757roberto#include <netinet/in6.h>	/* Required on UnixWare. */
85118e757roberto#endif
86118e757roberto#ifdef ISC_PLATFORM_NEEDNETINET6IN6H
87118e757roberto#include <netinet6/in6.h>	/* Required on BSD/OS for in6_pktinfo. */
88118e757roberto#endif
89118e757roberto
90118e757roberto#ifndef ISC_PLATFORM_HAVEIPV6
91118e757roberto#include <isc/ipv6.h>		/* Contractual promise. */
92118e757roberto#endif
93118e757roberto
94118e757roberto#include <isc/lang.h>
95118e757roberto#include <isc/types.h>
96118e757roberto
97118e757roberto#ifdef ISC_PLATFORM_HAVEINADDR6
98d54cfbdroberto#define in6_addr in_addr6	/*%< Required for pre RFC2133 implementations. */
99118e757roberto#endif
100118e757roberto
101118e757roberto#ifdef ISC_PLATFORM_HAVEIPV6
102d54cfbdroberto#ifndef IN6ADDR_ANY_INIT
103d54cfbdroberto#ifdef s6_addr
104d54cfbdroberto/*%
105118e757roberto * Required for some pre RFC2133 implementations.
106118e757roberto * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
107d54cfbdroberto * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
108118e757roberto * If 's6_addr' is defined then assume that there is a union and three
109118e757roberto * levels otherwise assume two levels required.
110118e757roberto */
111118e757roberto#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
112118e757roberto#else
113118e757roberto#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
114118e757roberto#endif
115118e757roberto#endif
116118e757roberto
117118e757roberto#ifndef IN6ADDR_LOOPBACK_INIT
118118e757roberto#ifdef s6_addr
119d54cfbdroberto/*% IPv6 address loopback init */
120118e757roberto#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
121118e757roberto#else
122118e757roberto#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
123118e757roberto#endif
124118e757roberto#endif
125118e757roberto
126118e757roberto#ifndef IN6_IS_ADDR_V4MAPPED
127d54cfbdroberto/*% Is IPv6 address V4 mapped? */
128118e757roberto#define IN6_IS_ADDR_V4MAPPED(x) \
129118e757roberto	 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
130118e757roberto	  (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
131118e757roberto#endif
132118e757roberto
133118e757roberto#ifndef IN6_IS_ADDR_V4COMPAT
134d54cfbdroberto/*% Is IPv6 address V4 compatible? */
135118e757roberto#define IN6_IS_ADDR_V4COMPAT(x) \
136118e757roberto	 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
137118e757roberto	 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \
138118e757roberto	  (x)->s6_addr[14] != 0 || \
139118e757roberto	  ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
140118e757roberto#endif
141118e757roberto
142118e757roberto#ifndef IN6_IS_ADDR_MULTICAST
143d54cfbdroberto/*% Is IPv6 address multicast? */
144118e757roberto#define IN6_IS_ADDR_MULTICAST(a)        ((a)->s6_addr[0] == 0xff)
145118e757roberto#endif
146118e757roberto
147118e757roberto#ifndef IN6_IS_ADDR_LINKLOCAL
148d54cfbdroberto/*% Is IPv6 address linklocal? */
149118e757roberto#define IN6_IS_ADDR_LINKLOCAL(a) \
150118e757roberto	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
151118e757roberto#endif
152118e757roberto
153118e757roberto#ifndef IN6_IS_ADDR_SITELOCAL
154d54cfbdroberto/*% is IPv6 address sitelocal? */
155118e757roberto#define IN6_IS_ADDR_SITELOCAL(a) \
156118e757roberto	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
157118e757roberto#endif
158118e757roberto
159118e757roberto
160118e757roberto#ifndef IN6_IS_ADDR_LOOPBACK
161d54cfbdroberto/*% is IPv6 address loopback? */
162118e757roberto#define IN6_IS_ADDR_LOOPBACK(x) \
163118e757roberto	(memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
164118e757roberto#endif
165118e757roberto#endif
166118e757roberto
167118e757roberto#ifndef AF_INET6
168d54cfbdroberto/*% IPv6 */
169118e757roberto#define AF_INET6 99
170118e757roberto#endif
171118e757roberto
172118e757roberto#ifndef PF_INET6
173d54cfbdroberto/*% IPv6 */
174118e757roberto#define PF_INET6 AF_INET6
175118e757roberto#endif
176118e757roberto
177118e757roberto#ifndef INADDR_LOOPBACK
178d54cfbdroberto/*% inaddr loopback */
179118e757roberto#define INADDR_LOOPBACK 0x7f000001UL
180118e757roberto#endif
181118e757roberto
182118e757roberto#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
183d54cfbdroberto/*% IPv6 packet info */
184118e757robertostruct in6_pktinfo {
185d54cfbdroberto	struct in6_addr ipi6_addr;    /*%< src/dst IPv6 address */
186d54cfbdroberto	unsigned int    ipi6_ifindex; /*%< send/recv interface index */
187118e757roberto};
188118e757roberto#endif
189118e757roberto
190d54cfbdroberto#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
191d54cfbdrobertoextern const struct in6_addr isc_net_in6addrany;
192d54cfbdroberto/*%
193118e757roberto * Cope with a missing in6addr_any and in6addr_loopback.
194118e757roberto */
195118e757roberto#define in6addr_any isc_net_in6addrany
196118e757roberto#endif
197118e757roberto
198118e757roberto#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
199118e757robertoextern const struct in6_addr isc_net_in6addrloop;
200118e757roberto#define in6addr_loopback isc_net_in6addrloop
201118e757roberto#endif
202118e757roberto
203118e757roberto#ifdef ISC_PLATFORM_FIXIN6ISADDR
204118e757roberto#undef  IN6_IS_ADDR_GEOGRAPHIC
205d54cfbdroberto/*!
206d54cfbdroberto * \brief
207d54cfbdroberto * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions.
208d54cfbdroberto */
209118e757roberto#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80)
210118e757roberto#undef  IN6_IS_ADDR_IPX
211118e757roberto#define IN6_IS_ADDR_IPX(a)        (((a)->S6_un.S6_l[0] & 0xFE) == 0x04)
212118e757roberto#undef  IN6_IS_ADDR_LINKLOCAL
213118e757roberto#define IN6_IS_ADDR_LINKLOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE)
214118e757roberto#undef  IN6_IS_ADDR_MULTICAST
215118e757roberto#define IN6_IS_ADDR_MULTICAST(a)  (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF)
216118e757roberto#undef  IN6_IS_ADDR_NSAP
217118e757roberto#define IN6_IS_ADDR_NSAP(a)       (((a)->S6_un.S6_l[0] & 0xFE) == 0x02)
218118e757roberto#undef  IN6_IS_ADDR_PROVIDER
219118e757roberto#define IN6_IS_ADDR_PROVIDER(a)   (((a)->S6_un.S6_l[0] & 0xE0) == 0x40)
220118e757roberto#undef  IN6_IS_ADDR_SITELOCAL
221118e757roberto#define IN6_IS_ADDR_SITELOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE)
222118e757roberto#endif /* ISC_PLATFORM_FIXIN6ISADDR */
223118e757roberto
224d54cfbdroberto#ifdef ISC_PLATFORM_NEEDPORTT
225d54cfbdroberto/*%
226118e757roberto * Ensure type in_port_t is defined.
227118e757roberto */
228118e757robertotypedef isc_uint16_t in_port_t;
229118e757roberto#endif
230118e757roberto
231d54cfbdroberto#ifndef MSG_TRUNC
232d54cfbdroberto/*%
233118e757roberto * If this system does not have MSG_TRUNC (as returned from recvmsg())
234118e757roberto * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
235118e757roberto * faking code in socket.c.
236118e757roberto */
237118e757roberto#define ISC_PLATFORM_RECVOVERFLOW
238118e757roberto#endif
239118e757roberto
240d54cfbdroberto/*% IP address. */
241118e757roberto#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
242118e757roberto
243d54cfbdroberto/*% Is IP address multicast? */
244118e757roberto#define ISC_IPADDR_ISMULTICAST(i) \
245118e757roberto		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
246118e757roberto		 == ISC__IPADDR(0xe0000000))
247118e757roberto
2487a6072eroberto#define ISC_IPADDR_ISEXPERIMENTAL(i) \
2497a6072eroberto		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
2507a6072eroberto		 == ISC__IPADDR(0xf0000000))
2517a6072eroberto
252118e757roberto/***
253118e757roberto *** Functions.
254118e757roberto ***/
255118e757roberto
256118e757robertoISC_LANG_BEGINDECLS
257118e757roberto
258118e757robertoisc_result_t
259118e757robertoisc_net_probeipv4(void);
260d54cfbdroberto/*%<
261118e757roberto * Check if the system's kernel supports IPv4.
262118e757roberto *
263118e757roberto * Returns:
264118e757roberto *
265d54cfbdroberto *\li	#ISC_R_SUCCESS		IPv4 is supported.
266d54cfbdroberto *\li	#ISC_R_NOTFOUND		IPv4 is not supported.
267d54cfbdroberto *\li	#ISC_R_DISABLED		IPv4 is disabled.
268d54cfbdroberto *\li	#ISC_R_UNEXPECTED
269118e757roberto */
270118e757roberto
271118e757robertoisc_result_t
272118e757robertoisc_net_probeipv6(void);
273d54cfbdroberto/*%<
274118e757roberto * Check if the system's kernel supports IPv6.
275118e757roberto *
276118e757roberto * Returns:
277118e757roberto *
278d54cfbdroberto *\li	#ISC_R_SUCCESS		IPv6 is supported.
279d54cfbdroberto *\li	#ISC_R_NOTFOUND		IPv6 is not supported.
280d54cfbdroberto *\li	#ISC_R_DISABLED		IPv6 is disabled.
281d54cfbdroberto *\li	#ISC_R_UNEXPECTED
282118e757roberto */
283118e757roberto
2847a6072erobertoisc_result_t
2857a6072erobertoisc_net_probe_ipv6only(void);
286d54cfbdroberto/*%<
2877a6072eroberto * Check if the system's kernel supports the IPV6_V6ONLY socket option.
2887a6072eroberto *
2897a6072eroberto * Returns:
2907a6072eroberto *
291d54cfbdroberto *\li	#ISC_R_SUCCESS		the option is supported for both TCP and UDP.
292d54cfbdroberto *\li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
293d54cfbdroberto *\li	#ISC_R_UNEXPECTED
2947a6072eroberto */
2957a6072eroberto
2967a6072erobertoisc_result_t
2977a6072erobertoisc_net_probe_ipv6pktinfo(void);
2987a6072eroberto/*
2997a6072eroberto * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
3007a6072eroberto * for UDP sockets.
3017a6072eroberto *
3027a6072eroberto * Returns:
3037a6072eroberto *
304d54cfbdroberto * \li	#ISC_R_SUCCESS		the option is supported.
305d54cfbdroberto * \li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
306d54cfbdroberto * \li	#ISC_R_UNEXPECTED
3077a6072eroberto */
3087a6072eroberto
3097a6072erobertovoid
3107a6072erobertoisc_net_disableipv4(void);
3117a6072eroberto
3127a6072erobertovoid
3137a6072erobertoisc_net_disableipv6(void);
3147a6072eroberto
3157a6072erobertovoid
3167a6072erobertoisc_net_enableipv4(void);
3177a6072eroberto
3187a6072erobertovoid
3197a6072erobertoisc_net_enableipv6(void);
3207a6072eroberto
321d54cfbdrobertoisc_result_t
322d54cfbdrobertoisc_net_probeunix(void);
323d54cfbdroberto/*
324d54cfbdroberto * Returns whether UNIX domain sockets are supported.
325d54cfbdroberto */
326d54cfbdroberto
327d54cfbdrobertoisc_result_t
328d54cfbdrobertoisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
329d54cfbdroberto/*%<
330d54cfbdroberto * Returns system's default range of ephemeral UDP ports, if defined.
331d54cfbdroberto * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
332d54cfbdroberto * ISC_NET_PORTRANGEHIGH will be returned.
333d54cfbdroberto *
334d54cfbdroberto * Requires:
335d54cfbdroberto *
336d54cfbdroberto *\li	'low' and 'high' must be non NULL.
337d54cfbdroberto *
338d54cfbdroberto * Returns:
339d54cfbdroberto *
340d54cfbdroberto *\li	*low and *high will be the ports specifying the low and high ends of
341d54cfbdroberto *	the range.
342d54cfbdroberto */
343d54cfbdroberto
3447a6072eroberto#ifdef ISC_PLATFORM_NEEDNTOP
345118e757robertoconst char *
346118e757robertoisc_net_ntop(int af, const void *src, char *dst, size_t size);
347118e757roberto#define inet_ntop isc_net_ntop
348118e757roberto#endif
349118e757roberto
3507a6072eroberto#ifdef ISC_PLATFORM_NEEDPTON
351118e757robertoint
352118e757robertoisc_net_pton(int af, const char *src, void *dst);
353118e757roberto#undef inet_pton
354118e757roberto#define inet_pton isc_net_pton
355118e757roberto#endif
356118e757roberto
357118e757robertoint
358118e757robertoisc_net_aton(const char *cp, struct in_addr *addr);
359d54cfbdroberto#undef inet_aton
360118e757roberto#define inet_aton isc_net_aton
361118e757roberto
362118e757robertoISC_LANG_ENDDECLS
363118e757roberto
364118e757roberto#endif /* ISC_NET_H */
365