xref: /illumos-gate/usr/src/uts/common/netinet/icmp6.h (revision 7c478bd9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_NETINET_ICMP6_H
28 #define	_NETINET_ICMP6_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #include <sys/types.h>
37 
38 /*
39  * Type and code definitions for ICMPv6.
40  * Based on RFC2292.
41  */
42 
43 #define	ICMP6_INFOMSG_MASK		0x80 /* all informational messages */
44 
45 /* Minimum ICMPv6 header length. */
46 #define	ICMP6_MINLEN	8
47 
48 typedef struct icmp6_hdr {
49 	uint8_t	 icmp6_type;	/* type field */
50 	uint8_t	 icmp6_code;	/* code field */
51 	uint16_t icmp6_cksum;	/* checksum field */
52 	union {
53 		uint32_t icmp6_un_data32[1];	/* type-specific field */
54 		uint16_t icmp6_un_data16[2];	/* type-specific field */
55 		uint8_t	 icmp6_un_data8[4];	/* type-specific field */
56 	} icmp6_dataun;
57 } icmp6_t;
58 
59 #define	icmp6_data32	icmp6_dataun.icmp6_un_data32
60 #define	icmp6_data16	icmp6_dataun.icmp6_un_data16
61 #define	icmp6_data8	icmp6_dataun.icmp6_un_data8
62 #define	icmp6_pptr	icmp6_data32[0]	/* parameter prob */
63 #define	icmp6_mtu	icmp6_data32[0]	/* packet too big */
64 #define	icmp6_id	icmp6_data16[0]	/* echo request/reply */
65 #define	icmp6_seq	icmp6_data16[1]	/* echo request/reply */
66 #define	icmp6_maxdelay	icmp6_data16[0]	/* mcast group membership */
67 
68 /* Multicast Listener Discovery messages (RFC 3542 (v1), RFC 3810 (v2)). */
69 
70 #define	MLD_MINLEN		24
71 #define	MLD_V2_QUERY_MINLEN	28
72 
73 /* Query Header, common to v1 and v2 */
74 typedef struct mld_hdr {
75 	struct icmp6_hdr	mld_icmp6_hdr;
76 	struct in6_addr		mld_addr; /* multicast address */
77 } mld_hdr_t;
78 
79 #define	mld_type	mld_icmp6_hdr.icmp6_type
80 #define	mld_code	mld_icmp6_hdr.icmp6_code
81 #define	mld_cksum	mld_icmp6_hdr.icmp6_cksum
82 #define	mld_maxdelay	mld_icmp6_hdr.icmp6_data16[0]
83 #define	mld_reserved	mld_icmp6_hdr.icmp6_data16[1]
84 
85 /* MLDv2 query */
86 typedef struct mld2q {
87 	mld_hdr_t	mld2q_hdr;
88 	uint8_t		mld2q_sqrv;	/* S Flag, Q's Robustness Variable  */
89 	uint8_t		mld2q_qqic;	/* Querier's Query Interval Code    */
90 	uint16_t	mld2q_numsrc;	/* number of sources		    */
91 } mld2q_t;
92 
93 #define	mld2q_type	mld2q_hdr.mld_icmp6_hdr.icmp6_type
94 #define	mld2q_code	mld2q_hdr.mld_icmp6_hdr.icmp6_code
95 #define	mld2q_cksum	mld2q_hdr.mld_icmp6_hdr.icmp6_cksum
96 #define	mld2q_mxrc	mld2q_hdr.mld_icmp6_hdr.icmp6_data16[0]
97 #define	mld2q_addr	mld2q_hdr.mld_addr
98 
99 #define	MLD_V2_SFLAG_MASK		0x8	/* mask off s part of sqrv */
100 #define	MLD_V2_RV_MASK			0x7	/* mask off qrv part of sqrv */
101 
102 /* definitions used to extract max response delay from mrc field */
103 #define	MLD_V2_MAXRT_FPMIN	0x8000
104 #define	MLD_V2_MAXRT_MANT_MASK	0x0fff
105 #define	MLD_V2_MAXRT_EXP_MASK	0x7000
106 
107 /* definitions used to extract querier's query interval from qqic field */
108 #define	MLD_V2_QQI_FPMIN	0x80
109 #define	MLD_V2_QQI_MANT_MASK	0x0f
110 #define	MLD_V2_QQI_EXP_MASK	0x70
111 
112 /* MLDv2 response */
113 typedef icmp6_t		mld2r_t;
114 
115 #define	mld2r_type	icmp6_type
116 #define	mld2r_res	icmp6_code
117 #define	mld2r_cksum	icmp6_cksum
118 #define	mld2r_res1	icmp6_data16[0]
119 #define	mld2r_nummar	icmp6_data16[1]
120 
121 /* MLDv2 multicast address record */
122 typedef struct mld2mar {
123 	uint8_t		mld2mar_type;	/* type of record		    */
124 	uint8_t		mld2mar_auxlen;	/* auxiliary data length	    */
125 	uint16_t	mld2mar_numsrc;	/* number of sources		    */
126 	struct in6_addr	mld2mar_group;	/* group address being reported	    */
127 } mld2mar_t;
128 
129 
130 /* For router renumbering. */
131 struct icmp6_router_renum {	/* router renumbering header */
132 	struct icmp6_hdr	rr_hdr;
133 	uint8_t			rr_segnum;
134 	uint8_t			rr_flags;
135 	uint16_t		rr_maxdelay;
136 	uint32_t		rr_reserved;
137 };
138 
139 #define	rr_type		rr_hdr.icmp6_type
140 #define	rr_code		rr_hdr.icmp6_code
141 #define	rr_cksum	rr_hdr.icmp6_cksum
142 #define	rr_seqnum	rr_hdr.icmp6_data32[0]
143 
144 /* Router renumbering flags */
145 #define	ICMP6_RR_FLAGS_TEST		0x80
146 #define	ICMP6_RR_FLAGS_REQRESULT	0x40
147 #define	ICMP6_RR_FLAGS_FORCEAPPLY	0x20
148 #define	ICMP6_RR_FLAGS_SPECSITE		0x10
149 #define	ICMP6_RR_FLAGS_PREVDONE		0x08
150 
151 struct rr_pco_match {	/* match prefix part */
152 	uint8_t			rpm_code;
153 	uint8_t			rpm_len;
154 	uint8_t			rpm_ordinal;
155 	uint8_t			rpm_matchlen;
156 	uint8_t			rpm_minlen;
157 	uint8_t			rpm_maxlen;
158 	uint16_t		rpm_reserved;
159 	struct in6_addr		rpm_prefix;
160 };
161 
162 /* PCO code values */
163 #define	RPM_PCO_ADD			1
164 #define	RPM_PCO_CHANGE			2
165 #define	RPM_PCO_SETGLOBAL		3
166 
167 struct rr_pco_use {	/* use prefix part */
168 	uint8_t			rpu_uselen;
169 	uint8_t			rpu_keeplen;
170 	uint8_t			rpu_ramask;
171 	uint8_t			rpu_raflags;
172 	uint32_t		rpu_vltime;
173 	uint32_t		rpu_pltime;
174 	uint32_t		rpu_flags;
175 	struct in6_addr		rpu_prefix;
176 };
177 
178 #define	ICMP6_RR_PCOUSE_RAFLAGS_ONLINK	0x20
179 #define	ICMP6_RR_PCOUSE_RAFLAGS_AUTO	0x10
180 
181 #ifdef _BIG_ENDIAN
182 #define	ICMP_RR_PCOUSE_FLAGS_DECRVLTIME	0x80000000
183 #define	ICMP_RR_PCOUSE_FLAGS_DECRPLTIME	0x40000000
184 #else /* _BIG_ENDIAN */
185 #define	ICMP_RR_PCOUSE_FLAGS_DECRVLTIME	0x80
186 #define	ICMP_RR_PCOUSE_FLAGS_DECRPLTIME	0x40
187 #endif /* _BIG_ENDIAN */
188 
189 struct rr_result {	/* router renumbering result message */
190 	uint16_t		rrr_flags;
191 	uint8_t			rrr_ordinal;
192 	uint8_t			rrr_matchedlen;
193 	uint32_t		rrr_ifid;
194 	struct in6_addr		rrr_prefix;
195 };
196 
197 #ifdef _BIG_ENDIAN
198 #define	ICMP6_RR_RESULT_FLAGS_OOB	0x0002
199 #define	ICMP6_RR_RESULT_FLAGS_FORBIDDEN	0x0001
200 #else /* _BIG_ENDIAN */
201 #define	ICMP6_RR_RESULT_FLAGS_OOB	0x0200
202 #define	ICMP6_RR_RESULT_FLAGS_FORBIDDEN	0x0100
203 #endif /* _BIG_ENDIAN */
204 
205 /* ICMPv6 error types */
206 #define	ICMP6_DST_UNREACH		1
207 #define	ICMP6_PACKET_TOO_BIG		2
208 #define	ICMP6_TIME_EXCEEDED		3
209 #define	ICMP6_PARAM_PROB		4
210 
211 #define	ICMP6_INFOMSG_MASK		0x80 /* all informational messages */
212 
213 /* ICMPv6 query types */
214 #define	ICMP6_ECHO_REQUEST		128
215 #define	ICMP6_ECHO_REPLY		129
216 
217 /*
218  * ICMPv6 group membership types
219  * ICMP6_MEMBERSHIP* types are the older names for these constants and should
220  * not be used in new code.
221  */
222 #define	MLD_LISTENER_QUERY		130
223 #define	ICMP6_MEMBERSHIP_QUERY		130
224 #define	MLD_LISTENER_REPORT		131
225 #define	ICMP6_MEMBERSHIP_REPORT		131
226 #define	MLD_LISTENER_REDUCTION		132
227 #define	ICMP6_MEMBERSHIP_REDUCTION	132
228 #define	MLD_V2_LISTENER_REPORT		143
229 
230 /* types for neighbor discovery */
231 #define	ND_ROUTER_SOLICIT		133
232 #define	ND_ROUTER_ADVERT		134
233 #define	ND_NEIGHBOR_SOLICIT		135
234 #define	ND_NEIGHBOR_ADVERT		136
235 #define	ND_REDIRECT			137
236 
237 /* router renumbering */
238 #define	ICMP6_ROUTER_RENUMBERING	138
239 
240 #define	ICMP6_MAX_INFO_TYPE		138
241 
242 #define	ICMP6_IS_ERROR(x) ((x) < 128)
243 
244 /* codes for ICMP6_DST_UNREACH */
245 #define	ICMP6_DST_UNREACH_NOROUTE	0 /* no route to destination */
246 #define	ICMP6_DST_UNREACH_ADMIN		1 /* communication with destination */
247 					/* administratively prohibited */
248 #define	ICMP6_DST_UNREACH_NOTNEIGHBOR	2 /* not a neighbor */
249 #define	ICMP6_DST_UNREACH_BEYONDSCOPE	2 /* beyond scope of source */
250 #define	ICMP6_DST_UNREACH_ADDR		3 /* address unreachable */
251 #define	ICMP6_DST_UNREACH_NOPORT	4 /* bad port */
252 
253 /* codes for ICMP6_TIME_EXCEEDED */
254 #define	ICMP6_TIME_EXCEED_TRANSIT	0 /* Hop Limit == 0 in transit */
255 #define	ICMP6_TIME_EXCEED_REASSEMBLY	1 /* Reassembly time out */
256 
257 /* codes for ICMP6_PARAM_PROB */
258 #define	ICMP6_PARAMPROB_HEADER		0 /* erroneous header field */
259 #define	ICMP6_PARAMPROB_NEXTHEADER	1 /* unrecognized Next Header */
260 #define	ICMP6_PARAMPROB_OPTION		2 /* unrecognized IPv6 option */
261 
262 /* Default MLD max report delay value */
263 #define	ICMP6_MAX_HOST_REPORT_DELAY	10	/* max delay for response to */
264 						/* query (in seconds)   */
265 
266 typedef struct nd_router_solicit {	/* router solicitation */
267 	icmp6_t		nd_rs_hdr;
268 	/* could be followed by options */
269 } nd_router_solicit_t;
270 
271 #define	nd_rs_type	nd_rs_hdr.icmp6_type
272 #define	nd_rs_code	nd_rs_hdr.icmp6_code
273 #define	nd_rs_cksum	nd_rs_hdr.icmp6_cksum
274 #define	nd_rs_reserved	nd_rs_hdr.icmp6_data32[0]
275 
276 typedef struct nd_router_advert {	/* router advertisement */
277 	icmp6_t		nd_ra_hdr;
278 	uint32_t	nd_ra_reachable;   /* reachable time */
279 	uint32_t	nd_ra_retransmit;  /* retransmit timer */
280 	/* could be followed by options */
281 } nd_router_advert_t;
282 
283 #define	nd_ra_type		nd_ra_hdr.icmp6_type
284 #define	nd_ra_code		nd_ra_hdr.icmp6_code
285 #define	nd_ra_cksum		nd_ra_hdr.icmp6_cksum
286 #define	nd_ra_curhoplimit	nd_ra_hdr.icmp6_data8[0]
287 #define	nd_ra_flags_reserved	nd_ra_hdr.icmp6_data8[1]
288 
289 #define	ND_RA_FLAG_OTHER	0x40
290 #define	ND_RA_FLAG_MANAGED	0x80
291 
292 #define	nd_ra_router_lifetime    nd_ra_hdr.icmp6_data16[1]
293 
294 typedef struct nd_neighbor_solicit {   /* neighbor solicitation */
295 	icmp6_t		nd_ns_hdr;
296 	struct in6_addr nd_ns_target; /* target address */
297 	/* could be followed by options */
298 } nd_neighbor_solicit_t;
299 
300 #define	nd_ns_type		nd_ns_hdr.icmp6_type
301 #define	nd_ns_code		nd_ns_hdr.icmp6_code
302 #define	nd_ns_cksum		nd_ns_hdr.icmp6_cksum
303 #define	nd_ns_reserved		nd_ns_hdr.icmp6_data32[0]
304 
305 typedef struct nd_neighbor_advert {	/* neighbor advertisement */
306 	icmp6_t		  nd_na_hdr;
307 	struct in6_addr   nd_na_target; /* target address */
308 	/* could be followed by options */
309 } nd_neighbor_advert_t;
310 
311 #define	nd_na_type	nd_na_hdr.icmp6_type
312 #define	nd_na_code	nd_na_hdr.icmp6_code
313 #define	nd_na_cksum	nd_na_hdr.icmp6_cksum
314 
315 #define	nd_na_flags_reserved	nd_na_hdr.icmp6_data32[0]
316 
317 /*
318  * The first three bits of the flgs_reserved field of the ND structure are
319  * defined in this order:
320  *	Router flag
321  *	Solicited flag
322  * 	Override flag
323  */
324 
325 /* Save valuable htonl() cycles on little-endian boxen. */
326 
327 #ifdef _BIG_ENDIAN
328 
329 #define	ND_NA_FLAG_ROUTER	0x80000000
330 #define	ND_NA_FLAG_SOLICITED	0x40000000
331 #define	ND_NA_FLAG_OVERRIDE	0x20000000
332 
333 #else /* _BIG_ENDIAN */
334 
335 #define	ND_NA_FLAG_ROUTER	0x80
336 #define	ND_NA_FLAG_SOLICITED	0x40
337 #define	ND_NA_FLAG_OVERRIDE	0x20
338 
339 #endif /* _BIG_ENDIAN */
340 
341 typedef struct nd_redirect {	/* redirect */
342 	icmp6_t		nd_rd_hdr;
343 	struct in6_addr	nd_rd_target; /* target address */
344 	struct in6_addr	nd_rd_dst;    /* destination address */
345 	/* could be followed by options */
346 } nd_redirect_t;
347 
348 #define	nd_rd_type	nd_rd_hdr.icmp6_type
349 #define	nd_rd_code	nd_rd_hdr.icmp6_code
350 #define	nd_rd_cksum	nd_rd_hdr.icmp6_cksum
351 #define	nd_rd_reserved	nd_rd_hdr.icmp6_data32[0]
352 
353 typedef struct nd_opt_hdr {	/* Neighbor discovery option header */
354 	uint8_t	nd_opt_type;
355 	uint8_t	nd_opt_len;	/* in units of 8 octets */
356 	/* followed by option specific data */
357 } nd_opt_hdr_t;
358 
359 /* Neighbor discovery option types */
360 #define	ND_OPT_SOURCE_LINKADDR		1
361 #define	ND_OPT_TARGET_LINKADDR		2
362 #define	ND_OPT_PREFIX_INFORMATION	3
363 #define	ND_OPT_REDIRECTED_HEADER	4
364 #define	ND_OPT_MTU			5
365 
366 typedef struct nd_opt_prefix_info {	/* prefix information */
367 	uint8_t   nd_opt_pi_type;
368 	uint8_t   nd_opt_pi_len;
369 	uint8_t   nd_opt_pi_prefix_len;
370 	uint8_t   nd_opt_pi_flags_reserved;
371 	uint32_t  nd_opt_pi_valid_time;
372 	uint32_t  nd_opt_pi_preferred_time;
373 	uint32_t  nd_opt_pi_reserved2;
374 	struct in6_addr  nd_opt_pi_prefix;
375 } nd_opt_prefix_info_t;
376 
377 #define	ND_OPT_PI_FLAG_AUTO	0x40
378 #define	ND_OPT_PI_FLAG_ONLINK	0x80
379 
380 typedef struct nd_opt_rd_hdr {	/* redirected header */
381 	uint8_t   nd_opt_rh_type;
382 	uint8_t   nd_opt_rh_len;
383 	uint16_t  nd_opt_rh_reserved1;
384 	uint32_t  nd_opt_rh_reserved2;
385 	/* followed by IP header and data */
386 } nd_opt_rd_hdr_t;
387 
388 typedef struct nd_opt_mtu {	/* MTU option */
389 	uint8_t   nd_opt_mtu_type;
390 	uint8_t   nd_opt_mtu_len;
391 	uint16_t  nd_opt_mtu_reserved;
392 	uint32_t  nd_opt_mtu_mtu;
393 } nd_opt_mtu_t;
394 
395 /* Note: the option is variable length (at least 8 bytes long) */
396 #ifndef ND_MAX_HDW_LEN
397 #define	ND_MAX_HDW_LEN	64
398 #endif
399 struct nd_opt_lla {
400 	uint8_t	nd_opt_lla_type;
401 	uint8_t	nd_opt_lla_len;	/* in units of 8 octets */
402 	uint8_t	nd_opt_lla_hdw_addr[ND_MAX_HDW_LEN];
403 };
404 
405 
406 /* Neighbor discovery protocol constants */
407 
408 /* Router constants */
409 #define	ND_MAX_INITIAL_RTR_ADVERT_INTERVAL	16000	/* milliseconds */
410 #define	ND_MAX_INITIAL_RTR_ADVERTISEMENTS	3	/* transmissions */
411 #define	ND_MAX_FINAL_RTR_ADVERTISEMENTS		3	/* transmissions */
412 #define	ND_MIN_DELAY_BETWEEN_RAS		3000	/* milliseconds */
413 #define	ND_MAX_RA_DELAY_TIME			500	/* milliseconds */
414 
415 /* Host constants */
416 #define	ND_MAX_RTR_SOLICITATION_DELAY		1000	/* milliseconds */
417 #define	ND_RTR_SOLICITATION_INTERVAL		4000	/* milliseconds */
418 #define	ND_MAX_RTR_SOLICITATIONS		3	/* transmissions */
419 
420 /* Node constants */
421 #define	ND_MAX_MULTICAST_SOLICIT		3	/* transmissions */
422 #define	ND_MAX_UNICAST_SOLICIT			3	/* transmissions */
423 #define	ND_MAX_ANYCAST_DELAY_TIME		1000	/* milliseconds */
424 #define	ND_MAX_NEIGHBOR_ADVERTISEMENT		3	/* transmissions */
425 #define	ND_REACHABLE_TIME			30000	/* milliseconds */
426 #define	ND_RETRANS_TIMER			1000	/* milliseconds */
427 #define	ND_DELAY_FIRST_PROBE_TIME		5000	/* milliseconds */
428 #define	ND_MIN_RANDOM_FACTOR			.5
429 #define	ND_MAX_RANDOM_FACTOR			1.5
430 
431 #define	ND_MAX_REACHTIME			3600000	/* milliseconds */
432 #define	ND_MAX_REACHRETRANSTIME			100000	/* milliseconds */
433 
434 /*
435  * ICMPv6 type filtering for IPPROTO_ICMPV6 ICMP6_FILTER socket option
436  */
437 #define	ICMP6_FILTER	0x01	/* Set filter */
438 
439 typedef struct icmp6_filter {
440 	uint32_t	__icmp6_filt[8];
441 } icmp6_filter_t;
442 
443 /* Pass all ICMPv6 messages to the application */
444 #define	ICMP6_FILTER_SETPASSALL(filterp) ( \
445 	((filterp)->__icmp6_filt[0] = 0xFFFFFFFFU), \
446 	((filterp)->__icmp6_filt[1] = 0xFFFFFFFFU), \
447 	((filterp)->__icmp6_filt[2] = 0xFFFFFFFFU), \
448 	((filterp)->__icmp6_filt[3] = 0xFFFFFFFFU), \
449 	((filterp)->__icmp6_filt[4] = 0xFFFFFFFFU), \
450 	((filterp)->__icmp6_filt[5] = 0xFFFFFFFFU), \
451 	((filterp)->__icmp6_filt[6] = 0xFFFFFFFFU), \
452 	((filterp)->__icmp6_filt[7] = 0xFFFFFFFFU))
453 
454 /* ICMPv6 messages are blocked from being passed to the application */
455 #define	ICMP6_FILTER_SETBLOCKALL(filterp) ( \
456 	((filterp)->__icmp6_filt[0] = 0x0), \
457 	((filterp)->__icmp6_filt[1] = 0x0), \
458 	((filterp)->__icmp6_filt[2] = 0x0), \
459 	((filterp)->__icmp6_filt[3] = 0x0), \
460 	((filterp)->__icmp6_filt[4] = 0x0), \
461 	((filterp)->__icmp6_filt[5] = 0x0), \
462 	((filterp)->__icmp6_filt[6] = 0x0), \
463 	((filterp)->__icmp6_filt[7] = 0x0))
464 
465 /* Pass messages of a given type to the application */
466 #define	ICMP6_FILTER_SETPASS(type, filterp) \
467 	((((filterp)->__icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31))))
468 
469 /* Block messages of a given type from being passed to the application */
470 #define	ICMP6_FILTER_SETBLOCK(type, filterp) \
471 	((((filterp)->__icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
472 
473 /* Test if message of a given type will be passed to an application */
474 #define	ICMP6_FILTER_WILLPASS(type, filterp) \
475 	((((filterp)->__icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
476 
477 /*
478  * Test if message of a given type will blocked from
479  * being passed to an application
480  */
481 #define	ICMP6_FILTER_WILLBLOCK(type, filterp) \
482 	((((filterp)->__icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
483 
484 
485 #ifdef	__cplusplus
486 }
487 #endif
488 
489 #endif /* _NETINET_ICMP6_H */
490