1/*
2 * Copyright 2006-2012 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _NETINET6_IN6_H_
6#define _NETINET6_IN6_H_
7
8
9#include <sys/types.h>
10#include <stdint.h>
11
12
13struct in6_addr {
14	union {
15		uint8_t		u6_addr8[16];
16		uint16_t	u6_addr16[8];
17		uint32_t	u6_addr32[4];
18	} in6_u;
19	#define s6_addr		in6_u.u6_addr8
20	#define s6_addr16	in6_u.u6_addr16
21	#define s6_addr32	in6_u.u6_addr32
22} _PACKED;
23
24
25
26/* IP Version 6 socket address. */
27struct sockaddr_in6 {
28	uint8_t		sin6_len;
29	uint8_t		sin6_family;
30	uint16_t	sin6_port;
31	uint32_t	sin6_flowinfo;
32	struct in6_addr	sin6_addr;
33	uint32_t	sin6_scope_id;
34};
35
36
37#define IN6ADDR_ANY_INIT {{{ \
38	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
39	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
40#define IN6ADDR_LOOPBACK_INIT {{{ \
41	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
42	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
43#define IN6ADDR_NODELOCAL_ALLNODES_INIT {{{ \
44	0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
45	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
46#define IN6ADDR_LINKLOCAL_ALLNODES_INIT {{{ \
47	0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
48	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
49#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT {{{ \
50	0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
51	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
52
53extern const struct in6_addr in6addr_any;
54extern const struct in6_addr in6addr_loopback;
55
56
57struct ipv6_mreq {
58	struct in6_addr ipv6mr_multiaddr;
59	unsigned	ipv6mr_interface;
60};
61
62
63struct in6_pktinfo {
64	struct in6_addr ipi6_addr;      /* src/dst IPv6 address */
65	unsigned int    ipi6_ifindex;   /* send/recv interface index */
66};
67
68
69/* Non-standard helper defines (same as in FreeBSD, though) */
70#define __IPV6_ADDR_SCOPE_NODELOCAL			0x01
71#define __IPV6_ADDR_SCOPE_INTFACELOCAL		0x01
72#define __IPV6_ADDR_SCOPE_LINKLOCAL			0x02
73#define __IPV6_ADDR_SCOPE_SITELOCAL			0x05
74#define __IPV6_ADDR_SCOPE_ORGLOCAL			0x08
75#define __IPV6_ADDR_SCOPE_GLOBAL			0x0e
76
77#define __IPV6_ADDR_MC_SCOPE(a)				((a)->s6_addr[1] & 0x0f)
78
79
80#define IN6_IS_ADDR_UNSPECIFIED(a) \
81	(!memcmp((a)->s6_addr, in6addr_any.s6_addr, sizeof(struct in6_addr)))
82
83#define IN6_IS_ADDR_LOOPBACK(a) \
84	(!memcmp((a)->s6_addr, in6addr_loopback.s6_addr, sizeof(struct in6_addr)))
85
86#define IN6_IS_ADDR_MULTICAST(a) \
87	((a)->s6_addr[0] == 0xff)
88
89#define IN6_IS_ADDR_LINKLOCAL(a) \
90	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
91
92#define IN6_IS_ADDR_SITELOCAL(a) \
93	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
94
95#define IN6_IS_ADDR_V4MAPPED(a) \
96	((a)->s6_addr[0] == 0x00 && (a)->s6_addr[1] == 0x00 \
97	&& (a)->s6_addr[2] == 0x00 && (a)->s6_addr[3] == 0x00 \
98	&& (a)->s6_addr[4] == 0x00 && (a)->s6_addr[5] == 0x00 \
99	&& (a)->s6_addr[6] == 0x00 && (a)->s6_addr[7] == 0x00 \
100	&& (a)->s6_addr[8] == 0x00 && (a)->s6_addr[9] == 0x00 \
101	&& (a)->s6_addr[10] == 0xff && (a)->s6_addr[11] == 0xff)
102
103#define IN6_IS_ADDR_V4COMPAT(a) \
104	((a)->s6_addr[0] == 0x00 && (a)->s6_addr[1] == 0x00 \
105	&& (a)->s6_addr[2] == 0x00 && (a)->s6_addr[3] == 0x00 \
106	&& (a)->s6_addr[4] == 0x00 && (a)->s6_addr[5] == 0x00 \
107	&& (a)->s6_addr[6] == 0x00 && (a)->s6_addr[7] == 0x00 \
108	&& (a)->s6_addr[8] == 0x00 && (a)->s6_addr[9] == 0x00 \
109	&& (a)->s6_addr[10] == 0x00 && (a)->s6_addr[11] == 0x01)
110
111#define IN6_IS_ADDR_MC_NODELOCAL(a) \
112	(IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) \
113		== __IPV6_ADDR_SCOPE_NODELOCAL)
114
115#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
116	(IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) \
117		== __IPV6_ADDR_SCOPE_LINKLOCAL)
118
119#define IN6_IS_ADDR_MC_SITELOCAL(a) \
120	(IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) \
121		== __IPV6_ADDR_SCOPE_SITELOCAL)
122
123#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
124	(IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) \
125		== __IPV6_ADDR_SCOPE_ORGLOCAL)
126
127#define IN6_IS_ADDR_MC_GLOBAL(a) \
128	(IN6_IS_ADDR_MULTICAST(a) && __IPV6_ADDR_MC_SCOPE(a) \
129		== __IPV6_ADDR_SCOPE_GLOBAL)
130
131/* From RFC 2292 (Advanced Sockets API for IPv6) */
132#define IN6_ARE_ADDR_EQUAL(a, b) \
133	(!memcmp((a)->s6_addr, (b)->s6_addr, sizeof(struct in6_addr)))
134
135/* maximal length of the string representation of an IPv6 address */
136#define INET6_ADDRSTRLEN				46
137
138
139#endif	/* _NETINET6_IN6_H_ */
140