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/*****
24290001Sglebius ***** Module Info
25290001Sglebius *****/
26290001Sglebius
27290001Sglebius/*! \file
28290001Sglebius * \brief
29290001Sglebius * Basic Networking Types
30290001Sglebius *
31290001Sglebius * This module is responsible for defining the following basic networking
32290001Sglebius * types:
33290001Sglebius *
34290001Sglebius *\li		struct in_addr
35290001Sglebius *\li		struct in6_addr
36290001Sglebius *\li		struct in6_pktinfo
37290001Sglebius *\li		struct sockaddr
38290001Sglebius *\li		struct sockaddr_in
39290001Sglebius *\li		struct sockaddr_in6
40290001Sglebius *\li		in_port_t
41290001Sglebius *
42290001Sglebius * It ensures that the AF_ and PF_ macros are defined.
43290001Sglebius *
44290001Sglebius * It declares ntoh[sl]() and hton[sl]().
45290001Sglebius *
46290001Sglebius * It declares inet_aton(), inet_ntop(), and inet_pton().
47290001Sglebius *
48290001Sglebius * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
49290001Sglebius * in6addr_any, and in6addr_loopback are available.
50290001Sglebius *
51290001Sglebius * It ensures that IN_MULTICAST() is available to check for multicast
52290001Sglebius * addresses.
53290001Sglebius *
54290001Sglebius * MP:
55290001Sglebius *\li	No impact.
56290001Sglebius *
57290001Sglebius * Reliability:
58290001Sglebius *\li	No anticipated impact.
59290001Sglebius *
60290001Sglebius * Resources:
61290001Sglebius *\li	N/A.
62290001Sglebius *
63290001Sglebius * Security:
64290001Sglebius *\li	No anticipated impact.
65290001Sglebius *
66290001Sglebius * Standards:
67290001Sglebius *\li	BSD Socket API
68290001Sglebius *\li	RFC2553
69290001Sglebius */
70290001Sglebius
71290001Sglebius/***
72290001Sglebius *** Imports.
73290001Sglebius ***/
74290001Sglebius#include <isc/platform.h>
75290001Sglebius
76290001Sglebius#include <sys/types.h>
77290001Sglebius#include <sys/socket.h>		/* Contractual promise. */
78290001Sglebius
79290001Sglebius#include <net/if.h>
80290001Sglebius
81290001Sglebius#include <netinet/in.h>		/* Contractual promise. */
82290001Sglebius#include <arpa/inet.h>		/* Contractual promise. */
83290001Sglebius#ifdef ISC_PLATFORM_NEEDNETINETIN6H
84290001Sglebius#include <netinet/in6.h>	/* Required on UnixWare. */
85290001Sglebius#endif
86290001Sglebius#ifdef ISC_PLATFORM_NEEDNETINET6IN6H
87290001Sglebius#include <netinet6/in6.h>	/* Required on BSD/OS for in6_pktinfo. */
88290001Sglebius#endif
89290001Sglebius
90290001Sglebius#ifndef ISC_PLATFORM_HAVEIPV6
91290001Sglebius#include <isc/ipv6.h>		/* Contractual promise. */
92290001Sglebius#endif
93290001Sglebius
94290001Sglebius#include <isc/lang.h>
95290001Sglebius#include <isc/types.h>
96290001Sglebius
97290001Sglebius#ifdef ISC_PLATFORM_HAVEINADDR6
98290001Sglebius#define in6_addr in_addr6	/*%< Required for pre RFC2133 implementations. */
99290001Sglebius#endif
100290001Sglebius
101290001Sglebius#ifdef ISC_PLATFORM_HAVEIPV6
102290001Sglebius#ifndef IN6ADDR_ANY_INIT
103290001Sglebius#ifdef s6_addr
104290001Sglebius/*%
105290001Sglebius * Required for some pre RFC2133 implementations.
106290001Sglebius * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
107290001Sglebius * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
108290001Sglebius * If 's6_addr' is defined then assume that there is a union and three
109290001Sglebius * levels otherwise assume two levels required.
110290001Sglebius */
111290001Sglebius#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
112290001Sglebius#else
113290001Sglebius#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
114290001Sglebius#endif
115290001Sglebius#endif
116290001Sglebius
117290001Sglebius#ifndef IN6ADDR_LOOPBACK_INIT
118290001Sglebius#ifdef s6_addr
119290001Sglebius/*% IPv6 address loopback init */
120290001Sglebius#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
121290001Sglebius#else
122290001Sglebius#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
123290001Sglebius#endif
124290001Sglebius#endif
125290001Sglebius
126290001Sglebius#ifndef IN6_IS_ADDR_V4MAPPED
127290001Sglebius/*% Is IPv6 address V4 mapped? */
128290001Sglebius#define IN6_IS_ADDR_V4MAPPED(x) \
129290001Sglebius	 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
130290001Sglebius	  (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
131290001Sglebius#endif
132290001Sglebius
133290001Sglebius#ifndef IN6_IS_ADDR_V4COMPAT
134290001Sglebius/*% Is IPv6 address V4 compatible? */
135290001Sglebius#define IN6_IS_ADDR_V4COMPAT(x) \
136290001Sglebius	 (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
137290001Sglebius	 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \
138290001Sglebius	  (x)->s6_addr[14] != 0 || \
139290001Sglebius	  ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
140290001Sglebius#endif
141290001Sglebius
142290001Sglebius#ifndef IN6_IS_ADDR_MULTICAST
143290001Sglebius/*% Is IPv6 address multicast? */
144290001Sglebius#define IN6_IS_ADDR_MULTICAST(a)        ((a)->s6_addr[0] == 0xff)
145290001Sglebius#endif
146290001Sglebius
147290001Sglebius#ifndef IN6_IS_ADDR_LINKLOCAL
148290001Sglebius/*% Is IPv6 address linklocal? */
149290001Sglebius#define IN6_IS_ADDR_LINKLOCAL(a) \
150290001Sglebius	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
151290001Sglebius#endif
152290001Sglebius
153290001Sglebius#ifndef IN6_IS_ADDR_SITELOCAL
154290001Sglebius/*% is IPv6 address sitelocal? */
155290001Sglebius#define IN6_IS_ADDR_SITELOCAL(a) \
156290001Sglebius	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
157290001Sglebius#endif
158290001Sglebius
159290001Sglebius
160290001Sglebius#ifndef IN6_IS_ADDR_LOOPBACK
161290001Sglebius/*% is IPv6 address loopback? */
162290001Sglebius#define IN6_IS_ADDR_LOOPBACK(x) \
163290001Sglebius	(memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
164290001Sglebius#endif
165290001Sglebius#endif
166290001Sglebius
167290001Sglebius#ifndef AF_INET6
168290001Sglebius/*% IPv6 */
169290001Sglebius#define AF_INET6 99
170290001Sglebius#endif
171290001Sglebius
172290001Sglebius#ifndef PF_INET6
173290001Sglebius/*% IPv6 */
174290001Sglebius#define PF_INET6 AF_INET6
175290001Sglebius#endif
176290001Sglebius
177290001Sglebius#ifndef INADDR_LOOPBACK
178290001Sglebius/*% inaddr loopback */
179290001Sglebius#define INADDR_LOOPBACK 0x7f000001UL
180290001Sglebius#endif
181290001Sglebius
182290001Sglebius#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
183290001Sglebius/*% IPv6 packet info */
184290001Sglebiusstruct in6_pktinfo {
185290001Sglebius	struct in6_addr ipi6_addr;    /*%< src/dst IPv6 address */
186290001Sglebius	unsigned int    ipi6_ifindex; /*%< send/recv interface index */
187290001Sglebius};
188290001Sglebius#endif
189290001Sglebius
190290001Sglebius#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
191290001Sglebiusextern const struct in6_addr isc_net_in6addrany;
192290001Sglebius/*%
193290001Sglebius * Cope with a missing in6addr_any and in6addr_loopback.
194290001Sglebius */
195290001Sglebius#define in6addr_any isc_net_in6addrany
196290001Sglebius#endif
197290001Sglebius
198290001Sglebius#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
199290001Sglebiusextern const struct in6_addr isc_net_in6addrloop;
200290001Sglebius#define in6addr_loopback isc_net_in6addrloop
201290001Sglebius#endif
202290001Sglebius
203290001Sglebius#ifdef ISC_PLATFORM_FIXIN6ISADDR
204290001Sglebius#undef  IN6_IS_ADDR_GEOGRAPHIC
205290001Sglebius/*!
206290001Sglebius * \brief
207290001Sglebius * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions.
208290001Sglebius */
209290001Sglebius#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80)
210290001Sglebius#undef  IN6_IS_ADDR_IPX
211290001Sglebius#define IN6_IS_ADDR_IPX(a)        (((a)->S6_un.S6_l[0] & 0xFE) == 0x04)
212290001Sglebius#undef  IN6_IS_ADDR_LINKLOCAL
213290001Sglebius#define IN6_IS_ADDR_LINKLOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE)
214290001Sglebius#undef  IN6_IS_ADDR_MULTICAST
215290001Sglebius#define IN6_IS_ADDR_MULTICAST(a)  (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF)
216290001Sglebius#undef  IN6_IS_ADDR_NSAP
217290001Sglebius#define IN6_IS_ADDR_NSAP(a)       (((a)->S6_un.S6_l[0] & 0xFE) == 0x02)
218290001Sglebius#undef  IN6_IS_ADDR_PROVIDER
219290001Sglebius#define IN6_IS_ADDR_PROVIDER(a)   (((a)->S6_un.S6_l[0] & 0xE0) == 0x40)
220290001Sglebius#undef  IN6_IS_ADDR_SITELOCAL
221290001Sglebius#define IN6_IS_ADDR_SITELOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE)
222290001Sglebius#endif /* ISC_PLATFORM_FIXIN6ISADDR */
223290001Sglebius
224290001Sglebius#ifdef ISC_PLATFORM_NEEDPORTT
225290001Sglebius/*%
226290001Sglebius * Ensure type in_port_t is defined.
227290001Sglebius */
228290001Sglebiustypedef isc_uint16_t in_port_t;
229290001Sglebius#endif
230290001Sglebius
231290001Sglebius#ifndef MSG_TRUNC
232290001Sglebius/*%
233290001Sglebius * If this system does not have MSG_TRUNC (as returned from recvmsg())
234290001Sglebius * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
235290001Sglebius * faking code in socket.c.
236290001Sglebius */
237290001Sglebius#define ISC_PLATFORM_RECVOVERFLOW
238290001Sglebius#endif
239290001Sglebius
240290001Sglebius/*% IP address. */
241290001Sglebius#define ISC__IPADDR(x)	((isc_uint32_t)htonl((isc_uint32_t)(x)))
242290001Sglebius
243290001Sglebius/*% Is IP address multicast? */
244290001Sglebius#define ISC_IPADDR_ISMULTICAST(i) \
245290001Sglebius		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
246290001Sglebius		 == ISC__IPADDR(0xe0000000))
247290001Sglebius
248290001Sglebius#define ISC_IPADDR_ISEXPERIMENTAL(i) \
249290001Sglebius		(((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
250290001Sglebius		 == ISC__IPADDR(0xf0000000))
251290001Sglebius
252290001Sglebius/***
253290001Sglebius *** Functions.
254290001Sglebius ***/
255290001Sglebius
256290001SglebiusISC_LANG_BEGINDECLS
257290001Sglebius
258290001Sglebiusisc_result_t
259290001Sglebiusisc_net_probeipv4(void);
260290001Sglebius/*%<
261290001Sglebius * Check if the system's kernel supports IPv4.
262290001Sglebius *
263290001Sglebius * Returns:
264290001Sglebius *
265290001Sglebius *\li	#ISC_R_SUCCESS		IPv4 is supported.
266290001Sglebius *\li	#ISC_R_NOTFOUND		IPv4 is not supported.
267290001Sglebius *\li	#ISC_R_DISABLED		IPv4 is disabled.
268290001Sglebius *\li	#ISC_R_UNEXPECTED
269290001Sglebius */
270290001Sglebius
271290001Sglebiusisc_result_t
272290001Sglebiusisc_net_probeipv6(void);
273290001Sglebius/*%<
274290001Sglebius * Check if the system's kernel supports IPv6.
275290001Sglebius *
276290001Sglebius * Returns:
277290001Sglebius *
278290001Sglebius *\li	#ISC_R_SUCCESS		IPv6 is supported.
279290001Sglebius *\li	#ISC_R_NOTFOUND		IPv6 is not supported.
280290001Sglebius *\li	#ISC_R_DISABLED		IPv6 is disabled.
281290001Sglebius *\li	#ISC_R_UNEXPECTED
282290001Sglebius */
283290001Sglebius
284290001Sglebiusisc_result_t
285290001Sglebiusisc_net_probe_ipv6only(void);
286290001Sglebius/*%<
287290001Sglebius * Check if the system's kernel supports the IPV6_V6ONLY socket option.
288290001Sglebius *
289290001Sglebius * Returns:
290290001Sglebius *
291290001Sglebius *\li	#ISC_R_SUCCESS		the option is supported for both TCP and UDP.
292290001Sglebius *\li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
293290001Sglebius *\li	#ISC_R_UNEXPECTED
294290001Sglebius */
295290001Sglebius
296290001Sglebiusisc_result_t
297290001Sglebiusisc_net_probe_ipv6pktinfo(void);
298290001Sglebius/*
299290001Sglebius * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
300290001Sglebius * for UDP sockets.
301290001Sglebius *
302290001Sglebius * Returns:
303290001Sglebius *
304290001Sglebius * \li	#ISC_R_SUCCESS		the option is supported.
305290001Sglebius * \li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
306290001Sglebius * \li	#ISC_R_UNEXPECTED
307290001Sglebius */
308290001Sglebius
309290001Sglebiusvoid
310290001Sglebiusisc_net_disableipv4(void);
311290001Sglebius
312290001Sglebiusvoid
313290001Sglebiusisc_net_disableipv6(void);
314290001Sglebius
315290001Sglebiusvoid
316290001Sglebiusisc_net_enableipv4(void);
317290001Sglebius
318290001Sglebiusvoid
319290001Sglebiusisc_net_enableipv6(void);
320290001Sglebius
321290001Sglebiusisc_result_t
322290001Sglebiusisc_net_probeunix(void);
323290001Sglebius/*
324290001Sglebius * Returns whether UNIX domain sockets are supported.
325290001Sglebius */
326290001Sglebius
327290001Sglebiusisc_result_t
328290001Sglebiusisc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
329290001Sglebius/*%<
330290001Sglebius * Returns system's default range of ephemeral UDP ports, if defined.
331290001Sglebius * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
332290001Sglebius * ISC_NET_PORTRANGEHIGH will be returned.
333290001Sglebius *
334290001Sglebius * Requires:
335290001Sglebius *
336290001Sglebius *\li	'low' and 'high' must be non NULL.
337290001Sglebius *
338290001Sglebius * Returns:
339290001Sglebius *
340290001Sglebius *\li	*low and *high will be the ports specifying the low and high ends of
341290001Sglebius *	the range.
342290001Sglebius */
343290001Sglebius
344290001Sglebius#ifdef ISC_PLATFORM_NEEDNTOP
345290001Sglebiusconst char *
346290001Sglebiusisc_net_ntop(int af, const void *src, char *dst, size_t size);
347290001Sglebius#define inet_ntop isc_net_ntop
348290001Sglebius#endif
349290001Sglebius
350290001Sglebius#ifdef ISC_PLATFORM_NEEDPTON
351290001Sglebiusint
352290001Sglebiusisc_net_pton(int af, const char *src, void *dst);
353290001Sglebius#undef inet_pton
354290001Sglebius#define inet_pton isc_net_pton
355290001Sglebius#endif
356290001Sglebius
357290001Sglebiusint
358290001Sglebiusisc_net_aton(const char *cp, struct in_addr *addr);
359290001Sglebius#undef inet_aton
360290001Sglebius#define inet_aton isc_net_aton
361290001Sglebius
362290001SglebiusISC_LANG_ENDDECLS
363290001Sglebius
364290001Sglebius#endif /* ISC_NET_H */
365