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