xref: /titanic_53/usr/src/uts/common/inet/ip6.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_INET_IP6_H
28*7c478bd9Sstevel@tonic-gate #define	_INET_IP6_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
33*7c478bd9Sstevel@tonic-gate extern "C" {
34*7c478bd9Sstevel@tonic-gate #endif
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
39*7c478bd9Sstevel@tonic-gate /* icmp6_t is used in the prototype of icmp_inbound_error_fanout_v6() */
40*7c478bd9Sstevel@tonic-gate #include <netinet/icmp6.h>
41*7c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate /* version number for IPv6 - hard to get this one wrong! */
44*7c478bd9Sstevel@tonic-gate #define	IPV6_VERSION		6
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #define	IPV6_HDR_LEN		40
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate #define	IPV6_ADDR_LEN		16
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate /*
51*7c478bd9Sstevel@tonic-gate  * IPv6 address scopes.  The values of these enums also match the scope
52*7c478bd9Sstevel@tonic-gate  * field of multicast addresses.
53*7c478bd9Sstevel@tonic-gate  */
54*7c478bd9Sstevel@tonic-gate typedef enum {
55*7c478bd9Sstevel@tonic-gate 	IP6_SCOPE_INTFLOCAL = 1,	/* Multicast addresses only */
56*7c478bd9Sstevel@tonic-gate 	IP6_SCOPE_LINKLOCAL,
57*7c478bd9Sstevel@tonic-gate 	IP6_SCOPE_SUBNETLOCAL,		/* Multicast addresses only */
58*7c478bd9Sstevel@tonic-gate 	IP6_SCOPE_ADMINLOCAL,		/* Multicast addresses only */
59*7c478bd9Sstevel@tonic-gate 	IP6_SCOPE_SITELOCAL,
60*7c478bd9Sstevel@tonic-gate 	IP6_SCOPE_GLOBAL
61*7c478bd9Sstevel@tonic-gate } in6addr_scope_t;
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate /*
66*7c478bd9Sstevel@tonic-gate  * Private header used between the transports and IP to carry the content
67*7c478bd9Sstevel@tonic-gate  * of the options IPV6_PKTINFO/IPV6_RECVPKTINFO (the interface index only)
68*7c478bd9Sstevel@tonic-gate  * and IPV6_NEXTHOP.
69*7c478bd9Sstevel@tonic-gate  * Also used to specify that raw sockets do not want the UDP/TCP transport
70*7c478bd9Sstevel@tonic-gate  * checksums calculated in IP (akin to IP_HDR_INCLUDED) and provide for
71*7c478bd9Sstevel@tonic-gate  * IPV6_CHECKSUM on the transmit side (using ip6i_checksum_off).
72*7c478bd9Sstevel@tonic-gate  *
73*7c478bd9Sstevel@tonic-gate  * When this header is used it must be the first header in the packet i.e.
74*7c478bd9Sstevel@tonic-gate  * before the real ip6 header. The use of a next header value of 255
75*7c478bd9Sstevel@tonic-gate  * (IPPROTO_RAW) in this header indicates its presence. Note that
76*7c478bd9Sstevel@tonic-gate  * ip6_nxt = IPPROTO_RAW indicates that "this" header is ip6_info - the
77*7c478bd9Sstevel@tonic-gate  * next header is always IPv6.
78*7c478bd9Sstevel@tonic-gate  *
79*7c478bd9Sstevel@tonic-gate  * Note that ip6i_nexthop is at the same offset as ip6_dst so that
80*7c478bd9Sstevel@tonic-gate  * this header can be kept in the packet while the it passes through
81*7c478bd9Sstevel@tonic-gate  * ip_newroute* and the ndp code. Those routines will use ip6_dst for
82*7c478bd9Sstevel@tonic-gate  * resolution.
83*7c478bd9Sstevel@tonic-gate  *
84*7c478bd9Sstevel@tonic-gate  * Implementation offset assumptions about ip6_info_t and ip6_t fields
85*7c478bd9Sstevel@tonic-gate  * and their alignments shown in figure below
86*7c478bd9Sstevel@tonic-gate  *
87*7c478bd9Sstevel@tonic-gate  * ip6_info (Private headers from transports to IP) header below
88*7c478bd9Sstevel@tonic-gate  * _______________________________________________________________ _ _ _ _ _
89*7c478bd9Sstevel@tonic-gate  * | .... | ip6i_nxt (255)| ......................|ip6i_nexthop| ...ip6_t.
90*7c478bd9Sstevel@tonic-gate  * --------------------------------------------------------------- - - - - -
91*7c478bd9Sstevel@tonic-gate  *        ^                                       ^
92*7c478bd9Sstevel@tonic-gate  * <---- >| same offset for {ip6i_nxt,ip6_nxt}    ^
93*7c478bd9Sstevel@tonic-gate  *        ^                                       ^
94*7c478bd9Sstevel@tonic-gate  * <------^-------------------------------------->| same offset for
95*7c478bd9Sstevel@tonic-gate  *        ^                                       ^ {ip6i_nxthop,ip6_dst}
96*7c478bd9Sstevel@tonic-gate  * _______________________________________________________________ _ _ _
97*7c478bd9Sstevel@tonic-gate  * | .... | ip6_nxt       | ......................|ip6_dst     | .other hdrs...
98*7c478bd9Sstevel@tonic-gate  * --------------------------------------------------------------- - - -
99*7c478bd9Sstevel@tonic-gate  * ip6_t (IPv6 protocol) header above
100*7c478bd9Sstevel@tonic-gate  */
101*7c478bd9Sstevel@tonic-gate struct ip6_info {
102*7c478bd9Sstevel@tonic-gate 	union {
103*7c478bd9Sstevel@tonic-gate 		struct ip6_info_ctl {
104*7c478bd9Sstevel@tonic-gate 			uint32_t	ip6i_un1_flow;
105*7c478bd9Sstevel@tonic-gate 			uint16_t	ip6i_un1_plen;   /* payload length */
106*7c478bd9Sstevel@tonic-gate 			uint8_t		ip6i_un1_nxt;    /* next header */
107*7c478bd9Sstevel@tonic-gate 			uint8_t		ip6i_un1_hlim;   /* hop limit */
108*7c478bd9Sstevel@tonic-gate 		} ip6i_un1;
109*7c478bd9Sstevel@tonic-gate 	} ip6i_ctlun;
110*7c478bd9Sstevel@tonic-gate 	int		ip6i_flags;	/* See below */
111*7c478bd9Sstevel@tonic-gate 	int		ip6i_ifindex;
112*7c478bd9Sstevel@tonic-gate 	int		ip6i_checksum_off;
113*7c478bd9Sstevel@tonic-gate 	int		ip6i_pad;
114*7c478bd9Sstevel@tonic-gate 	in6_addr_t	ip6i_nexthop;	/* Same offset as ip6_dst */
115*7c478bd9Sstevel@tonic-gate };
116*7c478bd9Sstevel@tonic-gate typedef struct ip6_info	ip6i_t;
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate #define	ip6i_flow	ip6i_ctlun.ip6i_un1.ip6i_un1_flow
119*7c478bd9Sstevel@tonic-gate #define	ip6i_vcf	ip6i_flow		/* Version, class, flow */
120*7c478bd9Sstevel@tonic-gate #define	ip6i_nxt	ip6i_ctlun.ip6i_un1.ip6i_un1_nxt
121*7c478bd9Sstevel@tonic-gate #define	ip6i_hops	ip6i_ctlun.ip6i_un1.ip6i_un1_hlim
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate /* ip6_info flags */
124*7c478bd9Sstevel@tonic-gate #define	IP6I_IFINDEX	0x1	/* ip6i_ifindex is set (to nonzero value) */
125*7c478bd9Sstevel@tonic-gate #define	IP6I_NEXTHOP	0x2	/* ip6i_nexthop is different than ip6_dst */
126*7c478bd9Sstevel@tonic-gate #define	IP6I_NO_ULP_CKSUM	0x4
127*7c478bd9Sstevel@tonic-gate 			/*
128*7c478bd9Sstevel@tonic-gate 			 * Do not generate TCP/UDP/SCTP transport checksum.
129*7c478bd9Sstevel@tonic-gate 			 * Used by raw sockets. Does not affect the
130*7c478bd9Sstevel@tonic-gate 			 * generation of transport checksums for ICMPv6
131*7c478bd9Sstevel@tonic-gate 			 * since such packets always arrive through
132*7c478bd9Sstevel@tonic-gate 			 * a raw socket.
133*7c478bd9Sstevel@tonic-gate 			 */
134*7c478bd9Sstevel@tonic-gate #define	IP6I_UNSPEC_SRC	0x8
135*7c478bd9Sstevel@tonic-gate 			/* Used to carry conn_unspec_src through ip_newroute* */
136*7c478bd9Sstevel@tonic-gate #define	IP6I_RAW_CHECKSUM	0x10
137*7c478bd9Sstevel@tonic-gate 			/* Compute checksum and stuff in ip6i_checksum_off */
138*7c478bd9Sstevel@tonic-gate #define	IP6I_VERIFY_SRC	0x20	/* Verify ip6_src. Used when IPV6_PKTINFO */
139*7c478bd9Sstevel@tonic-gate #define	IP6I_ATTACH_IF	0x40	/* Bind to no failover address or BOUND_PIF. */
140*7c478bd9Sstevel@tonic-gate #define	IP6I_DROP_IFDELAYED	0x80
141*7c478bd9Sstevel@tonic-gate 			/* Drop the packet if delayed in ndp resolver */
142*7c478bd9Sstevel@tonic-gate #define	IP6I_ND_DELAYED 0x100	/* Packet was delayed in ndp resolver */
143*7c478bd9Sstevel@tonic-gate #define	IP6I_DONTFRAG	0x200	/* Don't fragment this packet */
144*7c478bd9Sstevel@tonic-gate #define	IP6I_HOPLIMIT	0x400	/* hoplimit has been set by the sender */
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate /*
147*7c478bd9Sstevel@tonic-gate  * These constants refer to the IPV6_USE_MIN_MTU API.  The
148*7c478bd9Sstevel@tonic-gate  * actually values used in the API are these values shifted down
149*7c478bd9Sstevel@tonic-gate  * 10 bits minus 2 [-1, 1].  0 (-2 after conversion) is considered
150*7c478bd9Sstevel@tonic-gate  * the same as the default (-1).  IP6I_API_USE_MIN_MTU(f, x) returns
151*7c478bd9Sstevel@tonic-gate  * the flags field updated with min mtu.  IP6I_USE_MIN_MTU_API takes the
152*7c478bd9Sstevel@tonic-gate  * field and returns the API value (+ the -2 value).
153*7c478bd9Sstevel@tonic-gate  */
154*7c478bd9Sstevel@tonic-gate #define	IP6I_USE_MIN_MTU_UNICAST	0x400
155*7c478bd9Sstevel@tonic-gate #define	IP6I_USE_MIN_MTU_ALWAYS		0x800
156*7c478bd9Sstevel@tonic-gate #define	IP6I_USE_MIN_MTU_NEVER		0xC00
157*7c478bd9Sstevel@tonic-gate #define	IP6I_USE_MIN_MTU_API(x)		((((x) & 0xC00) >> 10) - 2)
158*7c478bd9Sstevel@tonic-gate #define	IP6I_API_USE_MIN_MTU(f, x)	(((f) & ~0xC00) &\
159*7c478bd9Sstevel@tonic-gate 					((((x) + 2) & 0x3) << 11))
160*7c478bd9Sstevel@tonic-gate #define	IPV6_USE_MIN_MTU_DEFAULT	-2
161*7c478bd9Sstevel@tonic-gate #define	IPV6_USE_MIN_MTU_UNICAST	-1
162*7c478bd9Sstevel@tonic-gate #define	IPV6_USE_MIN_MTU_ALWAYS		0
163*7c478bd9Sstevel@tonic-gate #define	IPV6_USE_MIN_MTU_NEVER		1
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate /* Extract the scope from a multicast address */
166*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
167*7c478bd9Sstevel@tonic-gate #define	IN6_ADDR_MC_SCOPE(addr) \
168*7c478bd9Sstevel@tonic-gate 	(((addr)->s6_addr32[0] & 0x000f0000) >> 16)
169*7c478bd9Sstevel@tonic-gate #else
170*7c478bd9Sstevel@tonic-gate #define	IN6_ADDR_MC_SCOPE(addr) \
171*7c478bd9Sstevel@tonic-gate 	(((addr)->s6_addr32[0] & 0x00000f00) >> 8)
172*7c478bd9Sstevel@tonic-gate #endif
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate /* Default IPv4 TTL for IPv6-in-IPv4 encapsulated packets */
175*7c478bd9Sstevel@tonic-gate #define	IPV6_DEFAULT_HOPS	60	/* XXX What should it be? */
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate /* Max IPv6 TTL */
178*7c478bd9Sstevel@tonic-gate #define	IPV6_MAX_HOPS	255
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate /* Minimum IPv6 MTU from rfc2460 */
181*7c478bd9Sstevel@tonic-gate #define	IPV6_MIN_MTU		1280
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate /* EUI-64 based token length */
184*7c478bd9Sstevel@tonic-gate #define	IPV6_TOKEN_LEN		64
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate /* Length of an advertised IPv6 prefix */
187*7c478bd9Sstevel@tonic-gate #define	IPV6_PREFIX_LEN		64
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate /* Default and maximum tunnel encapsulation limits.  See RFC 2473. */
190*7c478bd9Sstevel@tonic-gate #define	IPV6_DEFAULT_ENCAPLIMIT	4
191*7c478bd9Sstevel@tonic-gate #define	IPV6_MAX_ENCAPLIMIT	255
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate /*
194*7c478bd9Sstevel@tonic-gate  * Minimum and maximum extension header lengths for IPv6.  The 8-bit
195*7c478bd9Sstevel@tonic-gate  * length field of each extension header (see rfc2460) specifies the
196*7c478bd9Sstevel@tonic-gate  * number of 8 octet units of data in the header not including the
197*7c478bd9Sstevel@tonic-gate  * first 8 octets.  A value of 0 would indicate 8 bytes (0 * 8 + 8),
198*7c478bd9Sstevel@tonic-gate  * and 255 would indicate 2048 bytes (255 * 8 + 8).
199*7c478bd9Sstevel@tonic-gate  */
200*7c478bd9Sstevel@tonic-gate #define	MIN_EHDR_LEN		8
201*7c478bd9Sstevel@tonic-gate #define	MAX_EHDR_LEN		2048
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate /*
204*7c478bd9Sstevel@tonic-gate  * The high-order bit of the version field is used by the transports to
205*7c478bd9Sstevel@tonic-gate  * indicate a rechability confirmation to IP.
206*7c478bd9Sstevel@tonic-gate  */
207*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
208*7c478bd9Sstevel@tonic-gate #define	IPV6_DEFAULT_VERS_AND_FLOW	0x60000000
209*7c478bd9Sstevel@tonic-gate #define	IPV6_VERS_AND_FLOW_MASK		0xF0000000
210*7c478bd9Sstevel@tonic-gate #define	IP_FORWARD_PROG			0x80000000
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate #define	V6_MCAST			0xFF000000
213*7c478bd9Sstevel@tonic-gate #define	V6_LINKLOCAL			0xFE800000
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate #define	IPV6_FLOW_TCLASS(x)		(((x) & IPV6_FLOWINFO_TCLASS) >> 20)
216*7c478bd9Sstevel@tonic-gate #define	IPV6_TCLASS_FLOW(f, c)		(((f) & ~IPV6_FLOWINFO_TCLASS) |\
217*7c478bd9Sstevel@tonic-gate 					((c) << 20))
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate #else
220*7c478bd9Sstevel@tonic-gate #define	IPV6_DEFAULT_VERS_AND_FLOW	0x00000060
221*7c478bd9Sstevel@tonic-gate #define	IPV6_VERS_AND_FLOW_MASK		0x000000F0
222*7c478bd9Sstevel@tonic-gate #define	IP_FORWARD_PROG			0x00000080
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate #define	V6_MCAST			0x000000FF
225*7c478bd9Sstevel@tonic-gate #define	V6_LINKLOCAL			0x000080FE
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate #define	IPV6_FLOW_TCLASS(x)		((((x) & 0xf000U) >> 12) |\
228*7c478bd9Sstevel@tonic-gate 					(((x) & 0xf) << 4))
229*7c478bd9Sstevel@tonic-gate #define	IPV6_TCLASS_FLOW(f, c)		(((f) & ~IPV6_FLOWINFO_TCLASS) |\
230*7c478bd9Sstevel@tonic-gate 					((((c) & 0xf) << 12) |\
231*7c478bd9Sstevel@tonic-gate 					(((c) & 0xf0) >> 4)))
232*7c478bd9Sstevel@tonic-gate #endif
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate /*
235*7c478bd9Sstevel@tonic-gate  * UTILITY MACROS FOR ADDRESSES.
236*7c478bd9Sstevel@tonic-gate  */
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate /*
239*7c478bd9Sstevel@tonic-gate  * Convert an IPv4 address mask to an IPv6 mask.   Pad with 1-bits.
240*7c478bd9Sstevel@tonic-gate  */
241*7c478bd9Sstevel@tonic-gate #define	V4MASK_TO_V6(v4, v6)	((v6).s6_addr32[0] = 0xffffffffUL,	\
242*7c478bd9Sstevel@tonic-gate 				(v6).s6_addr32[1] = 0xffffffffUL,	\
243*7c478bd9Sstevel@tonic-gate 				(v6).s6_addr32[2] = 0xffffffffUL,	\
244*7c478bd9Sstevel@tonic-gate 				(v6).s6_addr32[3] = (v4))
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate /*
247*7c478bd9Sstevel@tonic-gate  * Convert aligned IPv4-mapped IPv6 address into an IPv4 address.
248*7c478bd9Sstevel@tonic-gate  * Note: We use "v6" here in definition of macro instead of "(v6)"
249*7c478bd9Sstevel@tonic-gate  * Not possible to use "(v6)" here since macro is used with struct
250*7c478bd9Sstevel@tonic-gate  * field names as arguments.
251*7c478bd9Sstevel@tonic-gate  */
252*7c478bd9Sstevel@tonic-gate #define	V4_PART_OF_V6(v6)	v6.s6_addr32[3]
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
255*7c478bd9Sstevel@tonic-gate #define	V6_OR_V4_INADDR_ANY(a)	((a).s6_addr32[3] == 0 &&		\
256*7c478bd9Sstevel@tonic-gate 				((a).s6_addr32[2] == 0xffffU ||	\
257*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[2] == 0) &&		\
258*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[1] == 0 &&		\
259*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[0] == 0)
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate #else
262*7c478bd9Sstevel@tonic-gate #define	V6_OR_V4_INADDR_ANY(a)	((a).s6_addr32[3] == 0 && 		\
263*7c478bd9Sstevel@tonic-gate 				((a).s6_addr32[2] == 0xffff0000U ||	\
264*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[2] == 0) &&		\
265*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[1] == 0 &&		\
266*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[0] == 0)
267*7c478bd9Sstevel@tonic-gate #endif /* _BIG_ENDIAN */
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate /* IPv4-mapped CLASSD addresses */
270*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
271*7c478bd9Sstevel@tonic-gate #define	IN6_IS_ADDR_V4MAPPED_CLASSD(addr) \
272*7c478bd9Sstevel@tonic-gate 	(((addr)->_S6_un._S6_u32[2] == 0x0000ffff) && \
273*7c478bd9Sstevel@tonic-gate 	(CLASSD((addr)->_S6_un._S6_u32[3])) && \
274*7c478bd9Sstevel@tonic-gate 	((addr)->_S6_un._S6_u32[1] == 0) && \
275*7c478bd9Sstevel@tonic-gate 	((addr)->_S6_un._S6_u32[0] == 0))
276*7c478bd9Sstevel@tonic-gate #else  /* _BIG_ENDIAN */
277*7c478bd9Sstevel@tonic-gate #define	IN6_IS_ADDR_V4MAPPED_CLASSD(addr) \
278*7c478bd9Sstevel@tonic-gate 	(((addr)->_S6_un._S6_u32[2] == 0xffff0000U) && \
279*7c478bd9Sstevel@tonic-gate 	(CLASSD((addr)->_S6_un._S6_u32[3])) && \
280*7c478bd9Sstevel@tonic-gate 	((addr)->_S6_un._S6_u32[1] == 0) && \
281*7c478bd9Sstevel@tonic-gate 	((addr)->_S6_un._S6_u32[0] == 0))
282*7c478bd9Sstevel@tonic-gate #endif /* _BIG_ENDIAN */
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate /* Clear an IPv6 addr */
285*7c478bd9Sstevel@tonic-gate #define	V6_SET_ZERO(a)		((a).s6_addr32[0] = 0,			\
286*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[1] = 0,			\
287*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[2] = 0,			\
288*7c478bd9Sstevel@tonic-gate 				(a).s6_addr32[3] = 0)
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate /* Mask comparison: is IPv6 addr a, and'ed with mask m, equal to addr b? */
291*7c478bd9Sstevel@tonic-gate #define	V6_MASK_EQ(a, m, b)						\
292*7c478bd9Sstevel@tonic-gate 	((((a).s6_addr32[0] & (m).s6_addr32[0]) == (b).s6_addr32[0]) &&	\
293*7c478bd9Sstevel@tonic-gate 	(((a).s6_addr32[1] & (m).s6_addr32[1]) == (b).s6_addr32[1]) &&	\
294*7c478bd9Sstevel@tonic-gate 	(((a).s6_addr32[2] & (m).s6_addr32[2]) == (b).s6_addr32[2]) &&	\
295*7c478bd9Sstevel@tonic-gate 	(((a).s6_addr32[3] & (m).s6_addr32[3]) == (b).s6_addr32[3]))
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate #define	V6_MASK_EQ_2(a, m, b)						\
298*7c478bd9Sstevel@tonic-gate 	((((a).s6_addr32[0] & (m).s6_addr32[0]) ==			\
299*7c478bd9Sstevel@tonic-gate 	    ((b).s6_addr32[0]  & (m).s6_addr32[0])) &&			\
300*7c478bd9Sstevel@tonic-gate 	(((a).s6_addr32[1] & (m).s6_addr32[1]) ==			\
301*7c478bd9Sstevel@tonic-gate 	    ((b).s6_addr32[1]  & (m).s6_addr32[1])) &&			\
302*7c478bd9Sstevel@tonic-gate 	(((a).s6_addr32[2] & (m).s6_addr32[2]) ==			\
303*7c478bd9Sstevel@tonic-gate 	    ((b).s6_addr32[2]  & (m).s6_addr32[2])) &&			\
304*7c478bd9Sstevel@tonic-gate 	(((a).s6_addr32[3] & (m).s6_addr32[3]) ==			\
305*7c478bd9Sstevel@tonic-gate 	    ((b).s6_addr32[3]  & (m).s6_addr32[3])))
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate /* Copy IPv6 address (s), logically and'ed with mask (m), into (d) */
308*7c478bd9Sstevel@tonic-gate #define	V6_MASK_COPY(s, m, d)						\
309*7c478bd9Sstevel@tonic-gate 	((d).s6_addr32[0] = (s).s6_addr32[0] & (m).s6_addr32[0],	\
310*7c478bd9Sstevel@tonic-gate 	(d).s6_addr32[1] = (s).s6_addr32[1] & (m).s6_addr32[1],		\
311*7c478bd9Sstevel@tonic-gate 	(d).s6_addr32[2] = (s).s6_addr32[2] & (m).s6_addr32[2],		\
312*7c478bd9Sstevel@tonic-gate 	(d).s6_addr32[3] = (s).s6_addr32[3] & (m).s6_addr32[3])
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate #define	ILL_FRAG_HASH_V6(v6addr, i)					\
315*7c478bd9Sstevel@tonic-gate 	((ntohl((v6addr).s6_addr32[3]) ^ (i ^ (i >> 8))) % 		\
316*7c478bd9Sstevel@tonic-gate 						ILL_FRAG_HASH_TBL_COUNT)
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate /*
319*7c478bd9Sstevel@tonic-gate  * GLOBAL EXTERNALS
320*7c478bd9Sstevel@tonic-gate  */
321*7c478bd9Sstevel@tonic-gate extern uint_t ipv6_ire_default_count;	/* Number of IPv6 IRE_DEFAULT entries */
322*7c478bd9Sstevel@tonic-gate extern uint_t ipv6_ire_default_index;	/* Walking IPv6 index used to mod in */
323*7c478bd9Sstevel@tonic-gate extern int ipv6_ire_cache_cnt;	/* Number of IPv6 IRE_CACHE entries */
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_all_ones;
326*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_all_zeros;
327*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_loopback;
328*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_all_hosts_mcast;
329*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_all_rtrs_mcast;
330*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_all_v2rtrs_mcast;
331*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_solicited_node_mcast;
332*7c478bd9Sstevel@tonic-gate extern const in6_addr_t	ipv6_unspecified_group;
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate /*
335*7c478bd9Sstevel@tonic-gate  * IPv6 mibs when the interface (ill) is not known.
336*7c478bd9Sstevel@tonic-gate  * When the ill is known the per-interface mib in the ill is used.
337*7c478bd9Sstevel@tonic-gate  */
338*7c478bd9Sstevel@tonic-gate extern mib2_ipv6IfStatsEntry_t	ip6_mib;
339*7c478bd9Sstevel@tonic-gate extern mib2_ipv6IfIcmpEntry_t	icmp6_mib;
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate /*
342*7c478bd9Sstevel@tonic-gate  * FUNCTION PROTOTYPES
343*7c478bd9Sstevel@tonic-gate  */
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate struct ipsec_out_s;
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate extern void	convert2ascii(char *buf, const in6_addr_t *addr);
348*7c478bd9Sstevel@tonic-gate extern char	*inet_ntop(int, const void *, char *, int);
349*7c478bd9Sstevel@tonic-gate extern int	inet_pton(int, char *, void *);
350*7c478bd9Sstevel@tonic-gate extern void	icmp_time_exceeded_v6(queue_t *, mblk_t *, uint8_t,
351*7c478bd9Sstevel@tonic-gate 		    boolean_t, boolean_t);
352*7c478bd9Sstevel@tonic-gate extern void	icmp_unreachable_v6(queue_t *, mblk_t *, uint8_t,
353*7c478bd9Sstevel@tonic-gate 		    boolean_t, boolean_t);
354*7c478bd9Sstevel@tonic-gate extern void	icmp_inbound_error_fanout_v6(queue_t *, mblk_t *, ip6_t *,
355*7c478bd9Sstevel@tonic-gate 		    icmp6_t *, ill_t *, boolean_t, zoneid_t);
356*7c478bd9Sstevel@tonic-gate extern boolean_t conn_wantpacket_v6(conn_t *, ill_t *, ip6_t *, int, zoneid_t);
357*7c478bd9Sstevel@tonic-gate extern mblk_t	*ip_add_info_v6(mblk_t *, ill_t *, const in6_addr_t *);
358*7c478bd9Sstevel@tonic-gate extern in6addr_scope_t	ip_addr_scope_v6(const in6_addr_t *);
359*7c478bd9Sstevel@tonic-gate extern mblk_t	*ip_bind_v6(queue_t *, mblk_t *, conn_t *, ip6_pkt_t *);
360*7c478bd9Sstevel@tonic-gate extern void	ip_build_hdrs_v6(uchar_t *, uint_t, ip6_pkt_t *, uint8_t);
361*7c478bd9Sstevel@tonic-gate extern void	ip_deliver_local_v6(queue_t *, mblk_t *, ill_t *, uint8_t,
362*7c478bd9Sstevel@tonic-gate 		    uint_t, uint_t);
363*7c478bd9Sstevel@tonic-gate extern int	ip_fanout_send_icmp_v6(queue_t *, mblk_t *, uint_t,
364*7c478bd9Sstevel@tonic-gate 		    uint_t, uint8_t, uint_t, boolean_t, zoneid_t);
365*7c478bd9Sstevel@tonic-gate extern int	ip_find_hdr_v6(mblk_t *, ip6_t *, ip6_pkt_t *, uint8_t *);
366*7c478bd9Sstevel@tonic-gate extern in6_addr_t ip_get_dst_v6(ip6_t *, boolean_t *);
367*7c478bd9Sstevel@tonic-gate extern ip6_rthdr_t	*ip_find_rthdr_v6(ip6_t *, uint8_t *);
368*7c478bd9Sstevel@tonic-gate extern int	ip_hdr_complete_v6(ip6_t *, zoneid_t);
369*7c478bd9Sstevel@tonic-gate extern boolean_t	ip_hdr_length_nexthdr_v6(mblk_t *, ip6_t *,
370*7c478bd9Sstevel@tonic-gate 		    uint16_t *, uint8_t **);
371*7c478bd9Sstevel@tonic-gate extern int	ip_hdr_length_v6(mblk_t *, ip6_t *);
372*7c478bd9Sstevel@tonic-gate extern uint32_t	ip_massage_options_v6(ip6_t *, ip6_rthdr_t *);
373*7c478bd9Sstevel@tonic-gate extern void	ip_wput_frag_v6(mblk_t *, ire_t *, uint_t, conn_t *,
374*7c478bd9Sstevel@tonic-gate 		    boolean_t, int);
375*7c478bd9Sstevel@tonic-gate extern void 	ip_wput_ipsec_out_v6(queue_t *, mblk_t *, ip6_t *, ill_t *,
376*7c478bd9Sstevel@tonic-gate     ire_t *);
377*7c478bd9Sstevel@tonic-gate extern int	ip_total_hdrs_len_v6(ip6_pkt_t *);
378*7c478bd9Sstevel@tonic-gate extern int	ipsec_ah_get_hdr_size_v6(mblk_t *, boolean_t);
379*7c478bd9Sstevel@tonic-gate extern void	ip_wput_local_v6(queue_t *, ill_t *, ip6_t *, mblk_t *,
380*7c478bd9Sstevel@tonic-gate 		    ire_t *, int);
381*7c478bd9Sstevel@tonic-gate extern void	ip_wput_md_v6(queue_t *, mblk_t *, conn_t *);
382*7c478bd9Sstevel@tonic-gate extern void	ip_output_v6(void *, mblk_t *, void *, int);
383*7c478bd9Sstevel@tonic-gate extern void	ip_xmit_v6(mblk_t *, ire_t *, uint_t, conn_t *, int,
384*7c478bd9Sstevel@tonic-gate 			struct ipsec_out_s *);
385*7c478bd9Sstevel@tonic-gate extern void	ip_rput_data_v6(queue_t *, ill_t *, mblk_t *, ip6_t *,
386*7c478bd9Sstevel@tonic-gate 		    uint_t, mblk_t *);
387*7c478bd9Sstevel@tonic-gate extern void	mld_input(queue_t *, mblk_t *, ill_t *);
388*7c478bd9Sstevel@tonic-gate extern void	mld_joingroup(ilm_t *);
389*7c478bd9Sstevel@tonic-gate extern void	mld_leavegroup(ilm_t *);
390*7c478bd9Sstevel@tonic-gate extern void	mld_timeout_handler(void *);
391*7c478bd9Sstevel@tonic-gate extern void	mld_timeout_start(int);
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate extern void	pr_addr_dbg(char *, int, const void *);
394*7c478bd9Sstevel@tonic-gate extern ipif_t	*ip_newroute_get_src_ipif_v6(ipif_t *, boolean_t,
395*7c478bd9Sstevel@tonic-gate 		const in6_addr_t *);
396*7c478bd9Sstevel@tonic-gate extern int	ip_multirt_apply_membership_v6(int (*fn)(conn_t *, boolean_t,
397*7c478bd9Sstevel@tonic-gate 		const in6_addr_t *, int, mcast_record_t, const in6_addr_t *,
398*7c478bd9Sstevel@tonic-gate 		mblk_t *), ire_t *, conn_t *, boolean_t, const in6_addr_t *,
399*7c478bd9Sstevel@tonic-gate 		mcast_record_t, const in6_addr_t *, mblk_t *);
400*7c478bd9Sstevel@tonic-gate extern void	ip_newroute_ipif_v6(queue_t *, mblk_t *, ipif_t *,
401*7c478bd9Sstevel@tonic-gate 		in6_addr_t, int, zoneid_t);
402*7c478bd9Sstevel@tonic-gate extern void	ip_newroute_v6(queue_t *, mblk_t *, const in6_addr_t *,
403*7c478bd9Sstevel@tonic-gate 		const in6_addr_t *, ill_t *, zoneid_t);
404*7c478bd9Sstevel@tonic-gate extern void	ip6_kstat_init(void);
405*7c478bd9Sstevel@tonic-gate extern size_t	ip6_get_src_preferences(conn_t *, uint32_t *);
406*7c478bd9Sstevel@tonic-gate extern int	ip6_set_src_preferences(conn_t *, uint32_t);
407*7c478bd9Sstevel@tonic-gate extern int	ip6_set_pktinfo(cred_t *, conn_t *, struct in6_pktinfo *,
408*7c478bd9Sstevel@tonic-gate     mblk_t *);
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
413*7c478bd9Sstevel@tonic-gate }
414*7c478bd9Sstevel@tonic-gate #endif
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate #endif	/* _INET_IP6_H */
417