1/*
2 * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*	$KAME: icmp6.h,v 1.46 2001/04/27 15:09:48 itojun Exp $	*/
29
30/*
31 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
36 * are met:
37 * 1. Redistributions of source code must retain the above copyright
38 *    notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 *    notice, this list of conditions and the following disclaimer in the
41 *    documentation and/or other materials provided with the distribution.
42 * 3. Neither the name of the project nor the names of its contributors
43 *    may be used to endorse or promote products derived from this software
44 *    without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 */
58
59/*
60 * Copyright (c) 1982, 1986, 1993
61 *	The Regents of the University of California.  All rights reserved.
62 *
63 * Redistribution and use in source and binary forms, with or without
64 * modification, are permitted provided that the following conditions
65 * are met:
66 * 1. Redistributions of source code must retain the above copyright
67 *    notice, this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in the
70 *    documentation and/or other materials provided with the distribution.
71 * 3. All advertising materials mentioning features or use of this software
72 *    must display the following acknowledgement:
73 *	This product includes software developed by the University of
74 *	California, Berkeley and its contributors.
75 * 4. Neither the name of the University nor the names of its contributors
76 *    may be used to endorse or promote products derived from this software
77 *    without specific prior written permission.
78 *
79 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
80 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89 * SUCH DAMAGE.
90 *
91 *	@(#)ip_icmp.h	8.1 (Berkeley) 6/10/93
92 */
93
94#ifndef _NETINET_ICMP6_H_
95#define _NETINET_ICMP6_H_
96#include <sys/appleapiopts.h>
97
98#define ICMPV6_PLD_MAXLEN	1232	/* IPV6_MMTU - sizeof(struct ip6_hdr)
99					   - sizeof(struct icmp6_hdr) */
100
101struct icmp6_hdr {
102	u_int8_t	icmp6_type;	/* type field */
103	u_int8_t	icmp6_code;	/* code field */
104	u_int16_t	icmp6_cksum;	/* checksum field */
105	union {
106		u_int32_t	icmp6_un_data32[1]; /* type-specific field */
107		u_int16_t	icmp6_un_data16[2]; /* type-specific field */
108		u_int8_t	icmp6_un_data8[4];  /* type-specific field */
109	} icmp6_dataun;
110} __attribute__((__packed__));
111
112#define icmp6_data32	icmp6_dataun.icmp6_un_data32
113#define icmp6_data16	icmp6_dataun.icmp6_un_data16
114#define icmp6_data8	icmp6_dataun.icmp6_un_data8
115#define icmp6_pptr	icmp6_data32[0]		/* parameter prob */
116#define icmp6_mtu	icmp6_data32[0]		/* packet too big */
117#define icmp6_id	icmp6_data16[0]		/* echo request/reply */
118#define icmp6_seq	icmp6_data16[1]		/* echo request/reply */
119#define icmp6_maxdelay	icmp6_data16[0]		/* mcast group membership */
120
121#define ICMP6_DST_UNREACH		1	/* dest unreachable, codes: */
122#define ICMP6_PACKET_TOO_BIG		2	/* packet too big */
123#define ICMP6_TIME_EXCEEDED		3	/* time exceeded, code: */
124#define ICMP6_PARAM_PROB		4	/* ip6 header bad */
125
126#define ICMP6_ECHO_REQUEST		128	/* echo service */
127#define ICMP6_ECHO_REPLY		129	/* echo reply */
128#define MLD_LISTENER_QUERY		130 	/* multicast listener query */
129#define MLD_LISTENER_REPORT		131	/* multicast listener report */
130#define MLD_LISTENER_DONE		132	/* multicast listener done */
131#define MLD_LISTENER_REDUCTION MLD_LISTENER_DONE /* RFC3542 definition */
132
133/* RFC2292 decls */
134#define ICMP6_MEMBERSHIP_QUERY		130	/* group membership query */
135#define ICMP6_MEMBERSHIP_REPORT		131	/* group membership report */
136#define ICMP6_MEMBERSHIP_REDUCTION	132	/* group membership termination */
137
138#ifndef KERNEL
139/* the followings are for backward compatibility to old KAME apps. */
140#define MLD6_LISTENER_QUERY	MLD_LISTENER_QUERY
141#define MLD6_LISTENER_REPORT	MLD_LISTENER_REPORT
142#define MLD6_LISTENER_DONE	MLD_LISTENER_DONE
143#endif
144
145#define ND_ROUTER_SOLICIT		133	/* router solicitation */
146#define ND_ROUTER_ADVERT		134	/* router advertisement */
147#define ND_NEIGHBOR_SOLICIT		135	/* neighbor solicitation */
148#define ND_NEIGHBOR_ADVERT		136	/* neighbor advertisement */
149#define ND_REDIRECT			137	/* redirect */
150
151#define ICMP6_ROUTER_RENUMBERING	138	/* router renumbering */
152
153#define ICMP6_WRUREQUEST		139	/* who are you request */
154#define ICMP6_WRUREPLY			140	/* who are you reply */
155#define ICMP6_FQDN_QUERY		139	/* FQDN query */
156#define ICMP6_FQDN_REPLY		140	/* FQDN reply */
157#define ICMP6_NI_QUERY			139	/* node information request */
158#define ICMP6_NI_REPLY			140	/* node information reply */
159#define MLDV2_LISTENER_REPORT	143	/* RFC3810 listener report */
160
161/* The definitions below are experimental. TBA */
162#define MLD_MTRACE_RESP			200	/* mtrace resp (to sender) */
163#define MLD_MTRACE			201	/* mtrace messages */
164
165#ifndef KERNEL
166#define MLD6_MTRACE_RESP	MLD_MTRACE_RESP
167#define MLD6_MTRACE		MLD_MTRACE
168#endif
169
170#define ICMP6_MAXTYPE			201
171
172#define ICMP6_DST_UNREACH_NOROUTE	0	/* no route to destination */
173#define ICMP6_DST_UNREACH_ADMIN	 	1	/* administratively prohibited */
174#define ICMP6_DST_UNREACH_NOTNEIGHBOR	2	/* not a neighbor(obsolete) */
175#define ICMP6_DST_UNREACH_BEYONDSCOPE	2	/* beyond scope of source address */
176#define ICMP6_DST_UNREACH_ADDR		3	/* address unreachable */
177#define ICMP6_DST_UNREACH_NOPORT	4	/* port unreachable */
178
179#define ICMP6_TIME_EXCEED_TRANSIT 	0	/* ttl==0 in transit */
180#define ICMP6_TIME_EXCEED_REASSEMBLY	1	/* ttl==0 in reass */
181
182#define ICMP6_PARAMPROB_HEADER 	 	0	/* erroneous header field */
183#define ICMP6_PARAMPROB_NEXTHEADER	1	/* unrecognized next header */
184#define ICMP6_PARAMPROB_OPTION		2	/* unrecognized option */
185
186#define ICMP6_INFOMSG_MASK		0x80	/* all informational messages */
187
188#define ICMP6_NI_SUBJ_IPV6	0	/* Query Subject is an IPv6 address */
189#define ICMP6_NI_SUBJ_FQDN	1	/* Query Subject is a Domain name */
190#define ICMP6_NI_SUBJ_IPV4	2	/* Query Subject is an IPv4 address */
191
192#define ICMP6_NI_SUCCESS	0	/* node information successful reply */
193#define ICMP6_NI_REFUSED	1	/* node information request is refused */
194#define ICMP6_NI_UNKNOWN	2	/* unknown Qtype */
195
196#define ICMP6_ROUTER_RENUMBERING_COMMAND  0	/* rr command */
197#define ICMP6_ROUTER_RENUMBERING_RESULT   1	/* rr result */
198#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET   255	/* rr seq num reset */
199
200/* Used in kernel only */
201#define ND_REDIRECT_ONLINK	0	/* redirect to an on-link node */
202#define ND_REDIRECT_ROUTER	1	/* redirect to a better router */
203
204/*
205 * Multicast Listener Discovery
206 */
207struct mld_hdr {
208	struct icmp6_hdr	mld_icmp6_hdr;
209	struct in6_addr		mld_addr; /* multicast address */
210} __attribute__((__packed__));
211
212/* definitions to provide backward compatibility to old KAME applications */
213#ifndef KERNEL
214#define mld6_hdr	mld_hdr
215#define mld6_type	mld_type
216#define mld6_code	mld_code
217#define mld6_cksum	mld_cksum
218#define mld6_maxdelay	mld_maxdelay
219#define mld6_reserved	mld_reserved
220#define mld6_addr	mld_addr
221#endif
222
223/* shortcut macro definitions */
224#define mld_type	mld_icmp6_hdr.icmp6_type
225#define mld_code	mld_icmp6_hdr.icmp6_code
226#define mld_cksum	mld_icmp6_hdr.icmp6_cksum
227#define mld_maxdelay	mld_icmp6_hdr.icmp6_data16[0]
228#define mld_reserved	mld_icmp6_hdr.icmp6_data16[1]
229#define mld_v2_reserved	mld_icmp6_hdr.icmp6_data16[0]
230#define mld_v2_numrecs	mld_icmp6_hdr.icmp6_data16[1]
231
232/*
233 * Neighbor Discovery
234 */
235
236struct nd_router_solicit {	/* router solicitation */
237	struct icmp6_hdr 	nd_rs_hdr;
238	/* could be followed by options */
239}__attribute__((__packed__));
240
241#define nd_rs_type	nd_rs_hdr.icmp6_type
242#define nd_rs_code	nd_rs_hdr.icmp6_code
243#define nd_rs_cksum	nd_rs_hdr.icmp6_cksum
244#define nd_rs_reserved	nd_rs_hdr.icmp6_data32[0]
245
246struct nd_router_advert {	/* router advertisement */
247	struct icmp6_hdr	nd_ra_hdr;
248	u_int32_t		nd_ra_reachable;	/* reachable time */
249	u_int32_t		nd_ra_retransmit;	/* retransmit timer */
250	/* could be followed by options */
251} __attribute__((__packed__));
252
253#define nd_ra_type		nd_ra_hdr.icmp6_type
254#define nd_ra_code		nd_ra_hdr.icmp6_code
255#define nd_ra_cksum		nd_ra_hdr.icmp6_cksum
256#define nd_ra_curhoplimit	nd_ra_hdr.icmp6_data8[0]
257#define nd_ra_flags_reserved	nd_ra_hdr.icmp6_data8[1]
258#define ND_RA_FLAG_MANAGED	0x80
259#define ND_RA_FLAG_OTHER	0x40
260#define ND_RA_FLAG_HA		0x20
261
262/*
263 * Router preference values based on draft-draves-ipngwg-router-selection-01.
264 * These are non-standard definitions.
265 */
266#define ND_RA_FLAG_RTPREF_MASK	0x18 /* 00011000 */
267
268#define ND_RA_FLAG_RTPREF_HIGH	0x08 /* 00001000 */
269#define ND_RA_FLAG_RTPREF_MEDIUM	0x00 /* 00000000 */
270#define ND_RA_FLAG_RTPREF_LOW	0x18 /* 00011000 */
271#define ND_RA_FLAG_RTPREF_RSV	0x10 /* 00010000 */
272
273#define nd_ra_router_lifetime	nd_ra_hdr.icmp6_data16[1]
274
275struct nd_neighbor_solicit {	/* neighbor solicitation */
276	struct icmp6_hdr	nd_ns_hdr;
277	struct in6_addr		nd_ns_target;	/*target address */
278	/* could be followed by options */
279}__attribute__((__packed__));
280
281#define nd_ns_type		nd_ns_hdr.icmp6_type
282#define nd_ns_code		nd_ns_hdr.icmp6_code
283#define nd_ns_cksum		nd_ns_hdr.icmp6_cksum
284#define nd_ns_reserved		nd_ns_hdr.icmp6_data32[0]
285
286struct nd_neighbor_advert {	/* neighbor advertisement */
287	struct icmp6_hdr	nd_na_hdr;
288	struct in6_addr		nd_na_target;	/* target address */
289	/* could be followed by options */
290}__attribute__((__packed__));
291
292#define nd_na_type		nd_na_hdr.icmp6_type
293#define nd_na_code		nd_na_hdr.icmp6_code
294#define nd_na_cksum		nd_na_hdr.icmp6_cksum
295#define nd_na_flags_reserved	nd_na_hdr.icmp6_data32[0]
296#if BYTE_ORDER == BIG_ENDIAN
297#define ND_NA_FLAG_ROUTER		0x80000000
298#define ND_NA_FLAG_SOLICITED		0x40000000
299#define ND_NA_FLAG_OVERRIDE		0x20000000
300#else
301#if BYTE_ORDER == LITTLE_ENDIAN
302#define ND_NA_FLAG_ROUTER		0x80
303#define ND_NA_FLAG_SOLICITED		0x40
304#define ND_NA_FLAG_OVERRIDE		0x20
305#endif
306#endif
307
308struct nd_redirect {		/* redirect */
309	struct icmp6_hdr	nd_rd_hdr;
310	struct in6_addr		nd_rd_target;	/* target address */
311	struct in6_addr		nd_rd_dst;	/* destination address */
312	/* could be followed by options */
313}__attribute__((__packed__));
314
315#define nd_rd_type		nd_rd_hdr.icmp6_type
316#define nd_rd_code		nd_rd_hdr.icmp6_code
317#define nd_rd_cksum		nd_rd_hdr.icmp6_cksum
318#define nd_rd_reserved		nd_rd_hdr.icmp6_data32[0]
319
320struct nd_opt_hdr {		/* Neighbor discovery option header */
321	u_int8_t	nd_opt_type;
322	u_int8_t	nd_opt_len;
323	/* followed by option specific data*/
324}__attribute__((__packed__));
325
326#define ND_OPT_SOURCE_LINKADDR		1
327#define ND_OPT_TARGET_LINKADDR		2
328#define ND_OPT_PREFIX_INFORMATION	3
329#define ND_OPT_REDIRECTED_HEADER	4
330#define ND_OPT_MTU			5
331#define ND_OPT_RDNSS			25	/* RFC 5006 */
332#define ND_OPT_DNSSL			31	/* RFC 6106 */
333
334#define ND_OPT_ROUTE_INFO		200	/* draft-ietf-ipngwg-router-preference, not officially assigned yet */
335
336struct nd_opt_prefix_info {	/* prefix information */
337	u_int8_t	nd_opt_pi_type;
338	u_int8_t	nd_opt_pi_len;
339	u_int8_t	nd_opt_pi_prefix_len;
340	u_int8_t	nd_opt_pi_flags_reserved;
341	u_int32_t	nd_opt_pi_valid_time;
342	u_int32_t	nd_opt_pi_preferred_time;
343	u_int32_t	nd_opt_pi_reserved2;
344	struct in6_addr	nd_opt_pi_prefix;
345}__attribute__((__packed__));
346
347#define ND_OPT_PI_FLAG_ONLINK		0x80
348#define ND_OPT_PI_FLAG_AUTO		0x40
349
350struct nd_opt_rd_hdr {		/* redirected header */
351	u_int8_t	nd_opt_rh_type;
352	u_int8_t	nd_opt_rh_len;
353	u_int16_t	nd_opt_rh_reserved1;
354	u_int32_t	nd_opt_rh_reserved2;
355	/* followed by IP header and data */
356} __attribute__((__packed__));
357
358struct nd_opt_mtu {		/* MTU option */
359	u_int8_t	nd_opt_mtu_type;
360	u_int8_t	nd_opt_mtu_len;
361	u_int16_t	nd_opt_mtu_reserved;
362	u_int32_t	nd_opt_mtu_mtu;
363}__attribute__((__packed__));
364
365struct nd_opt_route_info {	/* route info */
366	u_int8_t	nd_opt_rti_type;
367	u_int8_t	nd_opt_rti_len;
368	u_int8_t	nd_opt_rti_prefixlen;
369	u_int8_t	nd_opt_rti_flags;
370	u_int32_t	nd_opt_rti_lifetime;
371	/* prefix follows */
372}__attribute__((__packed__));
373
374struct nd_opt_rdnss {	/* recursive domain name system servers */
375    u_int8_t		nd_opt_rdnss_type;
376    u_int8_t		nd_opt_rdnss_len;
377    u_int16_t		nd_opt_rdnss_reserved;
378    u_int32_t		nd_opt_rdnss_lifetime;
379    struct in6_addr	nd_opt_rdnss_addr[1];
380} __attribute__((__packed__));
381
382struct nd_opt_dnssl {	/* domain name search list */
383    u_int8_t		nd_opt_dnssl_type;
384    u_int8_t		nd_opt_dnssl_len;
385    u_int16_t 		nd_opt_dnssl_reserved;
386    u_int32_t		nd_opt_dnssl_lifetime;
387    u_int8_t		nd_opt_dnssl_domains[8];
388} __attribute__((__packed__));
389
390/*
391 * icmp6 namelookup
392 */
393
394struct icmp6_namelookup {
395	struct icmp6_hdr 	icmp6_nl_hdr;
396	u_int8_t	icmp6_nl_nonce[8];
397	int32_t		icmp6_nl_ttl;
398#if 0
399	u_int8_t	icmp6_nl_len;
400	u_int8_t	icmp6_nl_name[3];
401#endif
402	/* could be followed by options */
403}__attribute__((__packed__));
404
405/*
406 * icmp6 node information
407 */
408struct icmp6_nodeinfo {
409	struct icmp6_hdr icmp6_ni_hdr;
410	u_int8_t icmp6_ni_nonce[8];
411	/* could be followed by reply data */
412}__attribute__((__packed__));
413
414#define ni_type		icmp6_ni_hdr.icmp6_type
415#define ni_code		icmp6_ni_hdr.icmp6_code
416#define ni_cksum	icmp6_ni_hdr.icmp6_cksum
417#define ni_qtype	icmp6_ni_hdr.icmp6_data16[0]
418#define ni_flags	icmp6_ni_hdr.icmp6_data16[1]
419
420#define NI_QTYPE_NOOP		0 /* NOOP  */
421#define NI_QTYPE_SUPTYPES	1 /* Supported Qtypes */
422#define NI_QTYPE_FQDN		2 /* FQDN (draft 04) */
423#define NI_QTYPE_DNSNAME	2 /* DNS Name */
424#define NI_QTYPE_NODEADDR	3 /* Node Addresses */
425#define NI_QTYPE_IPV4ADDR	4 /* IPv4 Addresses */
426
427#if BYTE_ORDER == BIG_ENDIAN
428#define NI_SUPTYPE_FLAG_COMPRESS	0x1
429#define NI_FQDN_FLAG_VALIDTTL		0x1
430#elif BYTE_ORDER == LITTLE_ENDIAN
431#define NI_SUPTYPE_FLAG_COMPRESS	0x0100
432#define NI_FQDN_FLAG_VALIDTTL		0x0100
433#endif
434
435#ifdef NAME_LOOKUPS_04
436#if BYTE_ORDER == BIG_ENDIAN
437#define NI_NODEADDR_FLAG_LINKLOCAL	0x1
438#define NI_NODEADDR_FLAG_SITELOCAL	0x2
439#define NI_NODEADDR_FLAG_GLOBAL		0x4
440#define NI_NODEADDR_FLAG_ALL		0x8
441#define NI_NODEADDR_FLAG_TRUNCATE	0x10
442#define NI_NODEADDR_FLAG_ANYCAST	0x20 /* just experimental. not in spec */
443#elif BYTE_ORDER == LITTLE_ENDIAN
444#define NI_NODEADDR_FLAG_LINKLOCAL	0x0100
445#define NI_NODEADDR_FLAG_SITELOCAL	0x0200
446#define NI_NODEADDR_FLAG_GLOBAL		0x0400
447#define NI_NODEADDR_FLAG_ALL		0x0800
448#define NI_NODEADDR_FLAG_TRUNCATE	0x1000
449#define NI_NODEADDR_FLAG_ANYCAST	0x2000 /* just experimental. not in spec */
450#endif
451#else  /* draft-ietf-ipngwg-icmp-name-lookups-05 (and later?) */
452#if BYTE_ORDER == BIG_ENDIAN
453#define NI_NODEADDR_FLAG_TRUNCATE	0x1
454#define NI_NODEADDR_FLAG_ALL		0x2
455#define NI_NODEADDR_FLAG_COMPAT		0x4
456#define NI_NODEADDR_FLAG_LINKLOCAL	0x8
457#define NI_NODEADDR_FLAG_SITELOCAL	0x10
458#define NI_NODEADDR_FLAG_GLOBAL		0x20
459#define NI_NODEADDR_FLAG_ANYCAST	0x40 /* just experimental. not in spec */
460#elif BYTE_ORDER == LITTLE_ENDIAN
461#define NI_NODEADDR_FLAG_TRUNCATE	0x0100
462#define NI_NODEADDR_FLAG_ALL		0x0200
463#define NI_NODEADDR_FLAG_COMPAT		0x0400
464#define NI_NODEADDR_FLAG_LINKLOCAL	0x0800
465#define NI_NODEADDR_FLAG_SITELOCAL	0x1000
466#define NI_NODEADDR_FLAG_GLOBAL		0x2000
467#define NI_NODEADDR_FLAG_ANYCAST	0x4000 /* just experimental. not in spec */
468#endif
469#endif
470
471struct ni_reply_fqdn {
472	u_int32_t ni_fqdn_ttl;	/* TTL */
473	u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */
474	u_int8_t ni_fqdn_name[3]; /* XXX: alignment */
475}__attribute__((__packed__));
476
477/*
478 * Router Renumbering. as router-renum-08.txt
479 */
480struct icmp6_router_renum {	/* router renumbering header */
481	struct icmp6_hdr	rr_hdr;
482	u_int8_t	rr_segnum;
483	u_int8_t	rr_flags;
484	u_int16_t	rr_maxdelay;
485	u_int32_t	rr_reserved;
486} __attribute__((__packed__));
487
488#define ICMP6_RR_FLAGS_TEST		0x80
489#define ICMP6_RR_FLAGS_REQRESULT	0x40
490#define ICMP6_RR_FLAGS_FORCEAPPLY	0x20
491#define ICMP6_RR_FLAGS_SPECSITE		0x10
492#define ICMP6_RR_FLAGS_PREVDONE		0x08
493
494#define rr_type		rr_hdr.icmp6_type
495#define rr_code		rr_hdr.icmp6_code
496#define rr_cksum	rr_hdr.icmp6_cksum
497#define rr_seqnum 	rr_hdr.icmp6_data32[0]
498
499struct rr_pco_match {		/* match prefix part */
500	u_int8_t	rpm_code;
501	u_int8_t	rpm_len;
502	u_int8_t	rpm_ordinal;
503	u_int8_t	rpm_matchlen;
504	u_int8_t	rpm_minlen;
505	u_int8_t	rpm_maxlen;
506	u_int16_t	rpm_reserved;
507	struct	in6_addr	rpm_prefix;
508} __attribute__((__packed__));
509
510#define RPM_PCO_ADD		1
511#define RPM_PCO_CHANGE		2
512#define RPM_PCO_SETGLOBAL	3
513#define RPM_PCO_MAX		4
514
515struct rr_pco_use {		/* use prefix part */
516	u_int8_t	rpu_uselen;
517	u_int8_t	rpu_keeplen;
518	u_int8_t	rpu_ramask;
519	u_int8_t	rpu_raflags;
520	u_int32_t	rpu_vltime;
521	u_int32_t	rpu_pltime;
522	u_int32_t	rpu_flags;
523	struct	in6_addr rpu_prefix;
524} __attribute__((__packed__));
525#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK	0x80
526#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO	0x40
527
528#if BYTE_ORDER == BIG_ENDIAN
529#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME     0x80000000
530#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME     0x40000000
531#elif BYTE_ORDER == LITTLE_ENDIAN
532#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME     0x80
533#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME     0x40
534#endif
535
536struct rr_result {		/* router renumbering result message */
537	u_int16_t	rrr_flags;
538	u_int8_t	rrr_ordinal;
539	u_int8_t	rrr_matchedlen;
540	u_int32_t	rrr_ifid;
541	struct	in6_addr rrr_prefix;
542} __attribute__((__packed__));
543#if BYTE_ORDER == BIG_ENDIAN
544#define ICMP6_RR_RESULT_FLAGS_OOB		0x0002
545#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN		0x0001
546#elif BYTE_ORDER == LITTLE_ENDIAN
547#define ICMP6_RR_RESULT_FLAGS_OOB		0x0200
548#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN		0x0100
549#endif
550
551/*
552 * icmp6 filter structures.
553 */
554
555struct icmp6_filter {
556	u_int32_t icmp6_filt[8];
557};
558
559#ifdef KERNEL
560#define	ICMP6_FILTER_SETPASSALL(filterp) \
561do {								\
562	int i; u_char *ptr;					\
563	ptr = (u_char *)filterp;					\
564	for (i = 0; i < sizeof(struct icmp6_filter); i++)	\
565		ptr[i] = 0xff;					\
566} while (0)
567#define	ICMP6_FILTER_SETBLOCKALL(filterp) \
568	bzero(filterp, sizeof(struct icmp6_filter))
569#else /* KERNEL */
570#define	ICMP6_FILTER_SETPASSALL(filterp) \
571	memset(filterp, 0xff, sizeof(struct icmp6_filter))
572#define	ICMP6_FILTER_SETBLOCKALL(filterp) \
573	memset(filterp, 0x00, sizeof(struct icmp6_filter))
574#endif /* KERNEL */
575
576#define	ICMP6_FILTER_SETPASS(type, filterp) \
577	(((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))
578#define	ICMP6_FILTER_SETBLOCK(type, filterp) \
579	(((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))
580#define	ICMP6_FILTER_WILLPASS(type, filterp) \
581	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
582#define	ICMP6_FILTER_WILLBLOCK(type, filterp) \
583	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
584
585/*
586 * Variables related to this implementation
587 * of the internet control message protocol version 6.
588 */
589struct icmp6errstat {
590	u_quad_t icp6errs_dst_unreach_noroute;
591	u_quad_t icp6errs_dst_unreach_admin;
592	u_quad_t icp6errs_dst_unreach_beyondscope;
593	u_quad_t icp6errs_dst_unreach_addr;
594	u_quad_t icp6errs_dst_unreach_noport;
595	u_quad_t icp6errs_packet_too_big;
596	u_quad_t icp6errs_time_exceed_transit;
597	u_quad_t icp6errs_time_exceed_reassembly;
598	u_quad_t icp6errs_paramprob_header;
599	u_quad_t icp6errs_paramprob_nextheader;
600	u_quad_t icp6errs_paramprob_option;
601	u_quad_t icp6errs_redirect; /* we regard redirect as an error here */
602	u_quad_t icp6errs_unknown;
603};
604
605struct icmp6stat {
606/* statistics related to icmp6 packets generated */
607	u_quad_t icp6s_error;		/* # of calls to icmp6_error */
608	u_quad_t icp6s_canterror;	/* no error 'cuz old was icmp */
609	u_quad_t icp6s_toofreq;		/* no error 'cuz rate limitation */
610	u_quad_t icp6s_outhist[256];
611/* statistics related to input message processed */
612	u_quad_t icp6s_badcode;		/* icmp6_code out of range */
613	u_quad_t icp6s_tooshort;	/* packet < sizeof(struct icmp6_hdr) */
614	u_quad_t icp6s_checksum;	/* bad checksum */
615	u_quad_t icp6s_badlen;		/* calculated bound mismatch */
616	u_quad_t icp6s_reflect;		/* number of responses */
617	u_quad_t icp6s_inhist[256];
618	u_quad_t icp6s_nd_toomanyopt;	/* too many ND options */
619	struct icmp6errstat icp6s_outerrhist;
620#define icp6s_odst_unreach_noroute \
621	icp6s_outerrhist.icp6errs_dst_unreach_noroute
622#define icp6s_odst_unreach_admin icp6s_outerrhist.icp6errs_dst_unreach_admin
623#define icp6s_odst_unreach_beyondscope \
624	icp6s_outerrhist.icp6errs_dst_unreach_beyondscope
625#define icp6s_odst_unreach_addr icp6s_outerrhist.icp6errs_dst_unreach_addr
626#define icp6s_odst_unreach_noport icp6s_outerrhist.icp6errs_dst_unreach_noport
627#define icp6s_opacket_too_big icp6s_outerrhist.icp6errs_packet_too_big
628#define icp6s_otime_exceed_transit \
629	icp6s_outerrhist.icp6errs_time_exceed_transit
630#define icp6s_otime_exceed_reassembly \
631	icp6s_outerrhist.icp6errs_time_exceed_reassembly
632#define icp6s_oparamprob_header icp6s_outerrhist.icp6errs_paramprob_header
633#define icp6s_oparamprob_nextheader \
634	icp6s_outerrhist.icp6errs_paramprob_nextheader
635#define icp6s_oparamprob_option icp6s_outerrhist.icp6errs_paramprob_option
636#define icp6s_oredirect icp6s_outerrhist.icp6errs_redirect
637#define icp6s_ounknown icp6s_outerrhist.icp6errs_unknown
638	u_quad_t icp6s_pmtuchg;		/* path MTU changes */
639	u_quad_t icp6s_nd_badopt;	/* bad ND options */
640	u_quad_t icp6s_badns;		/* bad neighbor solicitation */
641	u_quad_t icp6s_badna;		/* bad neighbor advertisement */
642	u_quad_t icp6s_badrs;		/* bad router advertisement */
643	u_quad_t icp6s_badra;		/* bad router advertisement */
644	u_quad_t icp6s_badredirect;	/* bad redirect message */
645};
646
647/*
648 * Names for ICMP sysctl objects
649 */
650#define ICMPV6CTL_STATS				1
651#define ICMPV6CTL_REDIRACCEPT		2	/* accept/process redirects */
652#define ICMPV6CTL_REDIRTIMEOUT		3	/* redirect cache time */
653#if 0	/*obsoleted*/
654#define ICMPV6CTL_ERRRATELIMIT		5	/* ICMPv6 error rate limitation */
655#endif
656#define ICMPV6CTL_ND6_PRUNE		6
657#define ICMPV6CTL_ND6_DELAY		8
658#define ICMPV6CTL_ND6_UMAXTRIES		9
659#define ICMPV6CTL_ND6_MMAXTRIES		10
660#define ICMPV6CTL_ND6_USELOOPBACK	11
661/*#define ICMPV6CTL_ND6_PROXYALL	12	obsoleted, do not reuse here */
662#define ICMPV6CTL_NODEINFO		13
663#define ICMPV6CTL_ERRPPSLIMIT		14	/* ICMPv6 error pps limitation */
664#define ICMPV6CTL_ND6_MAXNUDHINT	15
665#define ICMPV6CTL_MTUDISC_HIWAT		16
666#define ICMPV6CTL_MTUDISC_LOWAT		17
667#define ICMPV6CTL_ND6_DEBUG		18
668#define ICMPV6CTL_ND6_DRLIST		19
669#define ICMPV6CTL_ND6_PRLIST		20
670#define ICMPV6CTL_MLD_MAXSRCFILTER	21
671#define ICMPV6CTL_MLD_SOMAXSRC		22
672#define ICMPV6CTL_MLD_VERSION		23
673#define ICMPV6CTL_ND6_MAXQLEN		24
674#define ICMPV6CTL_ND6_ACCEPT_6TO4	25
675#define ICMPV6CTL_ND6_OPTIMISTIC_DAD	26	/* RFC 4429 */
676#define ICMPV6CTL_MAXID			27
677
678#ifdef BSD_KERNEL_PRIVATE
679#define ICMPV6CTL_NAMES { \
680	{ 0, 0 }, \
681	{ 0, 0 }, \
682	{ "rediraccept", CTLTYPE_INT }, \
683	{ "redirtimeout", CTLTYPE_INT }, \
684	{ 0, 0 }, \
685	{ 0, 0 }, \
686	{ "nd6_prune", CTLTYPE_INT }, \
687	{ 0, 0 }, \
688	{ "nd6_delay", CTLTYPE_INT }, \
689	{ "nd6_umaxtries", CTLTYPE_INT }, \
690	{ "nd6_mmaxtries", CTLTYPE_INT }, \
691	{ "nd6_useloopback", CTLTYPE_INT }, \
692	{ 0, 0 }, \
693	{ "nodeinfo", CTLTYPE_INT }, \
694	{ "errppslimit", CTLTYPE_INT }, \
695	{ "nd6_maxnudhint", CTLTYPE_INT }, \
696	{ "mtudisc_hiwat", CTLTYPE_INT }, \
697	{ "mtudisc_lowat", CTLTYPE_INT }, \
698	{ "nd6_debug", CTLTYPE_INT }, \
699	{ 0, 0 }, \
700	{ 0, 0 }, \
701	{ 0, 0 }, \
702	{ 0, 0 }, \
703	{ 0, 0 }, \
704	{ 0, 0 }, \
705	{ "nd6_accept_6to4", CTLTYPE_INT }, \
706	{ "nd6_optimistic_dad", CTLTYPE_INT }, \
707}
708
709# ifdef __STDC__
710struct	rtentry;
711struct	rttimer;
712struct	in6_multi;
713# endif
714struct ip6protosw;
715void	icmp6_init(struct ip6protosw *, struct domain *);
716void	icmp6_paramerror(struct mbuf *, int);
717void	icmp6_error(struct mbuf *, int, int, int);
718void	icmp6_error2(struct mbuf *, int, int, int, struct ifnet *);
719int	icmp6_input(struct mbuf **, int *, int);
720void	icmp6_reflect(struct mbuf *, size_t);
721void	icmp6_prepare(struct mbuf *);
722void	icmp6_redirect_input(struct mbuf *, int);
723void	icmp6_redirect_output(struct mbuf *, struct rtentry *);
724
725struct	ip6ctlparam;
726void	icmp6_mtudisc_update(struct ip6ctlparam *, int);
727
728extern lck_rw_t icmp6_ifs_rwlock;
729/* XXX: is this the right place for these macros? */
730/* N.B.: if_inet6data is never freed once set, so we don't need to lock */
731#define icmp6_ifstat_inc(_ifp, _tag) do {			\
732	if (_ifp != NULL && IN6_IFEXTRA(_ifp) != NULL) {	\
733		IN6_IFEXTRA(_ifp)->icmp6_ifstat._tag++;		\
734	}							\
735} while (0)
736
737#define icmp6_ifoutstat_inc(ifp, type, code) do {		\
738	icmp6_ifstat_inc(ifp, ifs6_out_msg);			\
739	if (type < ICMP6_INFOMSG_MASK)				\
740 		icmp6_ifstat_inc(ifp, ifs6_out_error);		\
741	switch (type) {						\
742	case ICMP6_DST_UNREACH:					\
743		icmp6_ifstat_inc(ifp, ifs6_out_dstunreach);	\
744		if (code == ICMP6_DST_UNREACH_ADMIN)		\
745			icmp6_ifstat_inc(ifp, ifs6_out_adminprohib);\
746		 break;						\
747	case ICMP6_PACKET_TOO_BIG:				\
748		icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig);	\
749		break;						\
750	case ICMP6_TIME_EXCEEDED:				\
751		icmp6_ifstat_inc(ifp, ifs6_out_timeexceed);	\
752		break;						\
753	case ICMP6_PARAM_PROB:					\
754		icmp6_ifstat_inc(ifp, ifs6_out_paramprob);	\
755		break;						\
756	case ICMP6_ECHO_REQUEST:				\
757		icmp6_ifstat_inc(ifp, ifs6_out_echo);		\
758		break;						\
759	case ICMP6_ECHO_REPLY:					\
760		icmp6_ifstat_inc(ifp, ifs6_out_echoreply);	\
761		break;						\
762	case MLD_LISTENER_QUERY:				\
763		icmp6_ifstat_inc(ifp, ifs6_out_mldquery);	\
764		break;						\
765	case MLD_LISTENER_REPORT:				\
766		icmp6_ifstat_inc(ifp, ifs6_out_mldreport);	\
767		break;						\
768	case MLD_LISTENER_DONE:					\
769		icmp6_ifstat_inc(ifp, ifs6_out_mlddone);	\
770		break;						\
771	case ND_ROUTER_SOLICIT:					\
772		icmp6_ifstat_inc(ifp, ifs6_out_routersolicit);	\
773		break;						\
774	case ND_ROUTER_ADVERT:					\
775		icmp6_ifstat_inc(ifp, ifs6_out_routeradvert);	\
776		break;						\
777	case ND_NEIGHBOR_SOLICIT:				\
778		icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);\
779		break;						\
780	case ND_NEIGHBOR_ADVERT:				\
781		icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);	\
782		break;						\
783	case ND_REDIRECT:					\
784		icmp6_ifstat_inc(ifp, ifs6_out_redirect);	\
785		break;						\
786	}							\
787} while (0)
788
789extern int	icmp6_rediraccept;	/* accept/process redirects */
790extern int	icmp6_redirtimeout;	/* cache time for redirect routes */
791
792#define ICMP6_NODEINFO_FQDNOK		0x1
793#define ICMP6_NODEINFO_NODEADDROK	0x2
794#define ICMP6_NODEINFO_TMPADDROK	0x4
795#define ICMP6_NODEINFO_GLOBALOK		0x8
796
797#endif /* BSD_KERNEL_PRIVATE */
798
799#endif /* !_NETINET_ICMP6_H_ */
800