1/*
2 * Copyright (c) 2000-2014 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
29/*	$FreeBSD: src/sys/netinet6/icmp6.c,v 1.6.2.6 2001/07/10 09:44:16 ume Exp $	*/
30/*	$KAME: icmp6.c,v 1.211 2001/04/04 05:56:20 itojun Exp $	*/
31
32/*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 *    notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 *    notice, this list of conditions and the following disclaimer in the
43 *    documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 *    may be used to endorse or promote products derived from this software
46 *    without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61/*
62 * Copyright (c) 1982, 1986, 1988, 1993
63 *	The Regents of the University of California.  All rights reserved.
64 *
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
67 * are met:
68 * 1. Redistributions of source code must retain the above copyright
69 *    notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 *    notice, this list of conditions and the following disclaimer in the
72 *    documentation and/or other materials provided with the distribution.
73 * 3. All advertising materials mentioning features or use of this software
74 *    must display the following acknowledgement:
75 *	This product includes software developed by the University of
76 *	California, Berkeley and its contributors.
77 * 4. Neither the name of the University nor the names of its contributors
78 *    may be used to endorse or promote products derived from this software
79 *    without specific prior written permission.
80 *
81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * SUCH DAMAGE.
92 *
93 *	@(#)ip_icmp.c	8.2 (Berkeley) 1/4/94
94 */
95
96
97#include <sys/param.h>
98#include <sys/systm.h>
99#include <sys/lock.h>
100#include <sys/malloc.h>
101#include <sys/mcache.h>
102#include <sys/mbuf.h>
103#include <sys/protosw.h>
104#include <sys/socket.h>
105#include <sys/socketvar.h>
106#include <sys/time.h>
107#include <sys/kernel.h>
108#include <sys/syslog.h>
109#include <sys/domain.h>
110#include <sys/kauth.h>
111
112#include <net/if.h>
113#include <net/route.h>
114#include <net/if_dl.h>
115#include <net/if_types.h>
116
117#include <netinet/in.h>
118#include <netinet/in_var.h>
119#include <netinet/ip6.h>
120#include <netinet6/ip6_var.h>
121#include <netinet/icmp6.h>
122#include <netinet6/mld6_var.h>
123#include <netinet/in_pcb.h>
124#include <netinet6/in6_pcb.h>
125#include <netinet6/in6_var.h>
126#include <netinet6/nd6.h>
127#include <netinet6/in6_ifattach.h>
128#include <netinet6/ip6protosw.h>
129#include <netinet6/scope6_var.h>
130
131#if IPSEC
132#include <netinet6/ipsec.h>
133#include <netkey/key.h>
134#endif
135
136#include <net/net_osdep.h>
137
138#if NECP
139#include <net/necp.h>
140#endif
141
142extern struct ip6protosw *ip6_protox[];
143
144extern uint32_t rip_sendspace;
145extern uint32_t rip_recvspace;
146
147struct icmp6stat icmp6stat;
148
149extern struct inpcbhead ripcb;
150extern int icmp6errppslim;
151extern int icmp6rappslim;
152static int icmp6errpps_count = 0;
153static int icmp6rapps_count = 0;
154static struct timeval icmp6errppslim_last;
155static struct timeval icmp6rappslim_last;
156extern int icmp6_nodeinfo;
157extern struct inpcbinfo ripcbinfo;
158
159static void icmp6_errcount(struct icmp6errstat *, int, int);
160static int icmp6_rip6_input(struct mbuf **, int);
161static int icmp6_ratelimit(const struct in6_addr *, const int, const int);
162static const char *icmp6_redirect_diag(struct in6_addr *,
163	struct in6_addr *, struct in6_addr *);
164static struct mbuf *ni6_input(struct mbuf *, int);
165static struct mbuf *ni6_nametodns(const char *, int, int);
166static int ni6_dnsmatch(const char *, int, const char *, int);
167static int ni6_addrs(struct icmp6_nodeinfo *,
168			  struct ifnet **, char *);
169static int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
170				struct ifnet *, int);
171static int icmp6_notify_error(struct mbuf *, int, int, int);
172
173
174
175void
176icmp6_init(struct ip6protosw *pp, struct domain *dp)
177{
178#pragma unused(dp)
179	static int icmp6_initialized = 0;
180
181	/* Also called from ip6_init() without pp */
182	VERIFY(pp == NULL ||
183	    (pp->pr_flags & (PR_INITIALIZED|PR_ATTACHED)) == PR_ATTACHED);
184
185	/* This gets called by more than one protocols, so initialize once */
186	if (!icmp6_initialized) {
187		icmp6_initialized = 1;
188		mld_init();
189	}
190}
191
192static void
193icmp6_errcount(stat, type, code)
194	struct icmp6errstat *stat;
195	int type, code;
196{
197	switch (type) {
198	case ICMP6_DST_UNREACH:
199		switch (code) {
200		case ICMP6_DST_UNREACH_NOROUTE:
201			stat->icp6errs_dst_unreach_noroute++;
202			return;
203		case ICMP6_DST_UNREACH_ADMIN:
204			stat->icp6errs_dst_unreach_admin++;
205			return;
206		case ICMP6_DST_UNREACH_BEYONDSCOPE:
207			stat->icp6errs_dst_unreach_beyondscope++;
208			return;
209		case ICMP6_DST_UNREACH_ADDR:
210			stat->icp6errs_dst_unreach_addr++;
211			return;
212		case ICMP6_DST_UNREACH_NOPORT:
213			stat->icp6errs_dst_unreach_noport++;
214			return;
215		}
216		break;
217	case ICMP6_PACKET_TOO_BIG:
218		stat->icp6errs_packet_too_big++;
219		return;
220	case ICMP6_TIME_EXCEEDED:
221		switch (code) {
222		case ICMP6_TIME_EXCEED_TRANSIT:
223			stat->icp6errs_time_exceed_transit++;
224			return;
225		case ICMP6_TIME_EXCEED_REASSEMBLY:
226			stat->icp6errs_time_exceed_reassembly++;
227			return;
228		}
229		break;
230	case ICMP6_PARAM_PROB:
231		switch (code) {
232		case ICMP6_PARAMPROB_HEADER:
233			stat->icp6errs_paramprob_header++;
234			return;
235		case ICMP6_PARAMPROB_NEXTHEADER:
236			stat->icp6errs_paramprob_nextheader++;
237			return;
238		case ICMP6_PARAMPROB_OPTION:
239			stat->icp6errs_paramprob_option++;
240			return;
241		}
242		break;
243	case ND_REDIRECT:
244		stat->icp6errs_redirect++;
245		return;
246	}
247	stat->icp6errs_unknown++;
248}
249
250/*
251 * A wrapper function for icmp6_error() necessary when the erroneous packet
252 * may not contain enough scope zone information.
253 */
254void
255icmp6_error2(struct mbuf *m, int type, int code, int param,
256    struct ifnet *ifp)
257{
258	struct ip6_hdr *ip6;
259
260	if (ifp == NULL)
261		return;
262
263#ifndef PULLDOWN_TEST
264	IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr),return );
265#else
266	if (m->m_len < sizeof(struct ip6_hdr)) {
267		m = m_pullup(m, sizeof(struct ip6_hdr));
268		if (m == NULL)
269			return;
270	}
271#endif
272
273	ip6 = mtod(m, struct ip6_hdr *);
274
275	if (in6_setscope(&ip6->ip6_src, ifp, NULL) != 0)
276		return;
277	if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0)
278		return;
279
280	icmp6_error(m, type, code, param);
281}
282
283/*
284 * Generate an error packet of type error in response to bad IP6 packet.
285 */
286void
287icmp6_error(struct mbuf *m, int type, int code, int param)
288{
289	struct ip6_hdr *oip6, *nip6;
290	struct icmp6_hdr *icmp6;
291	u_int preplen;
292	int off;
293	int nxt;
294
295	icmp6stat.icp6s_error++;
296
297	/* count per-type-code statistics */
298	icmp6_errcount(&icmp6stat.icp6s_outerrhist, type, code);
299
300#ifdef M_DECRYPTED	/*not openbsd*/
301	if (m->m_flags & M_DECRYPTED) {
302		icmp6stat.icp6s_canterror++;
303		goto freeit;
304	}
305#endif
306
307#ifndef PULLDOWN_TEST
308	IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), return);
309#else
310	if (m->m_len < sizeof(struct ip6_hdr)) {
311		m = m_pullup(m, sizeof(struct ip6_hdr));
312		if (m == NULL)
313			return;
314	}
315#endif
316	oip6 = mtod(m, struct ip6_hdr *);
317
318	/*
319	 * If the destination address of the erroneous packet is a multicast
320	 * address, or the packet was sent using link-layer multicast,
321	 * we should basically suppress sending an error (RFC 2463, Section
322	 * 2.4).
323	 * We have two exceptions (the item e.2 in that section):
324	 * - the Pakcet Too Big message can be sent for path MTU discovery.
325	 * - the Parameter Problem Message that can be allowed an icmp6 error
326	 *   in the option type field.  This check has been done in
327	 *   ip6_unknown_opt(), so we can just check the type and code.
328	 */
329	if ((m->m_flags & (M_BCAST|M_MCAST) ||
330	     IN6_IS_ADDR_MULTICAST(&oip6->ip6_dst)) &&
331	    (type != ICMP6_PACKET_TOO_BIG &&
332	     (type != ICMP6_PARAM_PROB ||
333	      code != ICMP6_PARAMPROB_OPTION)))
334		goto freeit;
335
336	/*
337	 * RFC 2463, 2.4 (e.5): source address check.
338	 * XXX: the case of anycast source?
339	 */
340	if (IN6_IS_ADDR_UNSPECIFIED(&oip6->ip6_src) ||
341	    IN6_IS_ADDR_MULTICAST(&oip6->ip6_src))
342		goto freeit;
343
344	/*
345	 * If we are about to send ICMPv6 against ICMPv6 error/redirect,
346	 * don't do it.
347	 */
348	nxt = -1;
349	off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
350	if (off >= 0 && nxt == IPPROTO_ICMPV6) {
351		struct icmp6_hdr *icp;
352
353#ifndef PULLDOWN_TEST
354		IP6_EXTHDR_CHECK(m, 0, off + sizeof(struct icmp6_hdr), return);
355		icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
356#else
357		IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off,
358			sizeof(*icp));
359		if (icp == NULL) {
360			icmp6stat.icp6s_tooshort++;
361			return;
362		}
363#endif
364		if (icp->icmp6_type < ICMP6_ECHO_REQUEST ||
365		    icp->icmp6_type == ND_REDIRECT) {
366			/*
367			 * ICMPv6 error
368			 * Special case: for redirect (which is
369			 * informational) we must not send icmp6 error.
370			 */
371			icmp6stat.icp6s_canterror++;
372			goto freeit;
373		} else {
374			/* ICMPv6 informational - send the error */
375		}
376	} else {
377		/* non-ICMPv6 - send the error */
378	}
379
380	oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */
381
382	/* Finally, do rate limitation check. */
383	if (icmp6_ratelimit(&oip6->ip6_src, type, code)) {
384		icmp6stat.icp6s_toofreq++;
385		goto freeit;
386	}
387
388	/*
389	 * OK, ICMP6 can be generated.
390	 */
391
392	if (m->m_pkthdr.len >= ICMPV6_PLD_MAXLEN)
393		m_adj(m, ICMPV6_PLD_MAXLEN - m->m_pkthdr.len);
394
395	preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
396	M_PREPEND(m, preplen, M_DONTWAIT);
397	if (m && m->m_len < preplen)
398		m = m_pullup(m, preplen);
399	if (m == NULL) {
400		nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__));
401		return;
402	}
403
404	nip6 = mtod(m, struct ip6_hdr *);
405	nip6->ip6_src  = oip6->ip6_src;
406	nip6->ip6_dst  = oip6->ip6_dst;
407
408	in6_clearscope(&oip6->ip6_src);
409	in6_clearscope(&oip6->ip6_dst);
410
411	icmp6 = (struct icmp6_hdr *)(nip6 + 1);
412	icmp6->icmp6_type = type;
413	icmp6->icmp6_code = code;
414	icmp6->icmp6_pptr = htonl((u_int32_t)param);
415
416	/*
417	 * icmp6_reflect() is designed to be in the input path.
418	 * icmp6_error() can be called from both input and output path,
419	 * and if we are in output path rcvif could contain bogus value.
420	 * clear m->m_pkthdr.rcvif for safety, we should have enough scope
421	 * information in ip header (nip6).
422	 */
423	m->m_pkthdr.rcvif = NULL;
424
425	icmp6stat.icp6s_outhist[type]++;
426	icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */
427
428	return;
429
430  freeit:
431	/*
432	 * If we can't tell whether or not we can generate ICMP6, free it.
433	 */
434	m_freem(m);
435}
436
437/*
438 * Process a received ICMP6 message.
439 */
440int
441icmp6_input(struct mbuf **mp, int *offp, int proto)
442{
443#pragma unused(proto)
444	struct mbuf *m = *mp, *n;
445	struct ifnet *ifp;
446	struct ip6_hdr *ip6, *nip6;
447	struct icmp6_hdr *icmp6, *nicmp6;
448	int off = *offp;
449	int icmp6len = m->m_pkthdr.len - *offp;
450	int code, sum, noff, proxy = 0;
451
452	ifp = m->m_pkthdr.rcvif;
453
454#ifndef PULLDOWN_TEST
455	IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), return IPPROTO_DONE);
456	/* m might change if M_LOOP.  So, call mtod after this */
457#endif
458
459	/* Expect 32-bit aligned data pointer on strict-align platforms */
460	MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
461
462	/*
463	 * Locate icmp6 structure in mbuf, and check
464	 * that not corrupted and of at least minimum length
465	 */
466	ip6 = mtod(m, struct ip6_hdr *);
467	if (icmp6len < sizeof(struct icmp6_hdr)) {
468		icmp6stat.icp6s_tooshort++;
469		goto freeit;
470	}
471
472#ifndef PULLDOWN_TEST
473	icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
474#else
475	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
476	if (icmp6 == NULL) {
477		icmp6stat.icp6s_tooshort++;
478		return IPPROTO_DONE;
479	}
480#endif
481	code = icmp6->icmp6_code;
482
483	/* Apply rate limit before checksum validation. */
484	if (icmp6_ratelimit(&ip6->ip6_dst, icmp6->icmp6_type, code)) {
485		icmp6stat.icp6s_toofreq++;
486		goto freeit;
487	}
488
489	/*
490	 * Check multicast group membership.
491	 * Note: SSM filters are not applied for ICMPv6 traffic.
492	 */
493	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
494		struct in6_multi	*inm;
495
496		in6_multihead_lock_shared();
497		IN6_LOOKUP_MULTI(&ip6->ip6_dst, ifp, inm);
498		in6_multihead_lock_done();
499
500		if (inm == NULL) {
501			/*
502			 * Don't discard if this is a Neighbor Solicitation
503			 * that needs to be proxied (see check down below.)
504			 */
505			if (!(m->m_pkthdr.pkt_flags & PKTF_PROXY_DST)) {
506				ip6stat.ip6s_notmember++;
507				in6_ifstat_inc(m->m_pkthdr.rcvif,
508				    ifs6_in_discard);
509				goto freeit;
510			}
511		} else {
512			IN6M_REMREF(inm);
513		}
514	}
515
516	/*
517	 * calculate the checksum
518	 */
519	if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) {
520		nd6log((LOG_ERR,
521		    "ICMP6 checksum error(%d|%x) %s\n",
522		    icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src)));
523		icmp6stat.icp6s_checksum++;
524		goto freeit;
525	}
526
527	if (m->m_pkthdr.pkt_flags & PKTF_PROXY_DST) {
528		/*
529		 * This is the special case of proxying NS (dst is either
530		 * solicited-node multicast or unicast); process it locally
531		 * but don't deliver it to sockets.  It practically lets us
532		 * steer the packet to nd6_prproxy_ns_input, where more
533		 * specific tests and actions will be taken.
534		 */
535		switch (icmp6->icmp6_type) {
536		case ND_NEIGHBOR_SOLICIT:
537			proxy = 1;
538			break;
539		default:
540			goto freeit;
541		}
542	}
543
544	icmp6stat.icp6s_inhist[icmp6->icmp6_type]++;
545	icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_msg);
546	if (icmp6->icmp6_type < ICMP6_INFOMSG_MASK)
547		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error);
548
549	switch (icmp6->icmp6_type) {
550	case ICMP6_DST_UNREACH:
551		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_dstunreach);
552		switch (code) {
553		case ICMP6_DST_UNREACH_NOROUTE:
554			code = PRC_UNREACH_NET;
555			break;
556		case ICMP6_DST_UNREACH_ADMIN:
557			icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_adminprohib);
558			code = PRC_UNREACH_PROTOCOL; /* is this a good code? */
559			break;
560		case ICMP6_DST_UNREACH_ADDR:
561			code = PRC_HOSTDEAD;
562			break;
563		case ICMP6_DST_UNREACH_BEYONDSCOPE:
564			/* I mean "source address was incorrect." */
565			code = PRC_PARAMPROB;
566			break;
567		case ICMP6_DST_UNREACH_NOPORT:
568			code = PRC_UNREACH_PORT;
569			break;
570		default:
571			goto badcode;
572		}
573		goto deliver;
574		break;
575
576	case ICMP6_PACKET_TOO_BIG:
577		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_pkttoobig);
578
579		code = PRC_MSGSIZE;
580
581		/*
582		 * Updating the path MTU will be done after examining
583		 * intermediate extension headers.
584		 */
585		goto deliver;
586		break;
587
588	case ICMP6_TIME_EXCEEDED:
589		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_timeexceed);
590		switch (code) {
591		case ICMP6_TIME_EXCEED_TRANSIT:
592			code = PRC_TIMXCEED_INTRANS;
593			break;
594		case ICMP6_TIME_EXCEED_REASSEMBLY:
595			code = PRC_TIMXCEED_REASS;
596			break;
597		default:
598			goto badcode;
599		}
600		goto deliver;
601		break;
602
603	case ICMP6_PARAM_PROB:
604		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_paramprob);
605		switch (code) {
606		case ICMP6_PARAMPROB_NEXTHEADER:
607			code = PRC_UNREACH_PROTOCOL;
608			break;
609		case ICMP6_PARAMPROB_HEADER:
610		case ICMP6_PARAMPROB_OPTION:
611			code = PRC_PARAMPROB;
612			break;
613		default:
614			goto badcode;
615		}
616		goto deliver;
617		break;
618
619	case ICMP6_ECHO_REQUEST:
620		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echo);
621		if (code != 0)
622			goto badcode;
623
624		if ((n = m_copy(m, 0, M_COPYALL)) == NULL) {
625			/* Give up remote */
626			goto rate_limit_checked;
627			break;
628		}
629		if ((n->m_flags & M_EXT) != 0
630		 || n->m_len < off + sizeof(struct icmp6_hdr)) {
631			struct mbuf *n0 = n;
632			const int maxlen = sizeof(*nip6) + sizeof(*nicmp6);
633
634			/*
635			 * Prepare an internal mbuf. m_pullup() doesn't
636			 * always copy the length we specified.
637			 */
638			if (maxlen >= MCLBYTES) {
639				/* Give up remote */
640				m_freem(n0);
641				goto rate_limit_checked;
642				break;
643			}
644			MGETHDR(n, M_DONTWAIT, n0->m_type);	/* MAC-OK */
645			if (n && maxlen >= MHLEN) {
646				MCLGET(n, M_DONTWAIT);
647				if ((n->m_flags & M_EXT) == 0) {
648					m_free(n);
649					n = NULL;
650				}
651			}
652			if (n == NULL) {
653				/* Give up remote */
654				m_freem(n0);
655				goto rate_limit_checked;
656				break;
657			}
658			M_COPY_PKTHDR(n, n0);
659			/*
660			 * Copy IPv6 and ICMPv6 only.
661			 */
662			nip6 = mtod(n, struct ip6_hdr *);
663			bcopy(ip6, nip6, sizeof(struct ip6_hdr));
664			nicmp6 = (struct icmp6_hdr *)(nip6 + 1);
665			bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
666			noff = sizeof(struct ip6_hdr);
667			n->m_pkthdr.len = n->m_len =
668				noff + sizeof(struct icmp6_hdr);
669			/*
670			 * Adjust mbuf. ip6_plen will be adjusted in
671			 * ip6_output().
672			 */
673			m_adj(n0, off + sizeof(struct icmp6_hdr));
674			n->m_pkthdr.len += n0->m_pkthdr.len;
675			n->m_next = n0;
676			n0->m_flags &= ~M_PKTHDR;
677		} else {
678			nip6 = mtod(n, struct ip6_hdr *);
679			IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off,
680				sizeof(*nicmp6));
681			noff = off;
682		}
683		if(nicmp6 == NULL)
684			panic("nicmp6 is NULL in %s, which isn't good!\n", __FUNCTION__);
685		else {
686			nicmp6->icmp6_type = ICMP6_ECHO_REPLY;
687			nicmp6->icmp6_code = 0;
688		}
689		if (n) {
690			icmp6stat.icp6s_reflect++;
691			icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++;
692			icmp6_reflect(n, noff);
693		}
694		goto rate_limit_checked;
695		break;
696
697	case ICMP6_ECHO_REPLY:
698		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echoreply);
699		if (code != 0)
700			goto badcode;
701		break;
702
703	case MLD_LISTENER_QUERY:
704	case MLD_LISTENER_REPORT:
705
706		if (icmp6len < sizeof(struct mld_hdr))
707			goto badlen;
708		if (icmp6->icmp6_type == MLD_LISTENER_QUERY) /* XXX: ugly... */
709			icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldquery);
710		else
711			icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldreport);
712
713		if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
714			/* give up local */
715			if (mld_input(m, off, icmp6len) == IPPROTO_DONE)
716				m = NULL;
717			goto freeit;
718		}
719		if (mld_input(n, off, icmp6len) != IPPROTO_DONE)
720			m_freem(n);
721		/* m stays. */
722		goto rate_limit_checked;
723		break;
724
725	case MLD_LISTENER_DONE:
726		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mlddone);
727		if (icmp6len < sizeof(struct mld_hdr))	/* necessary? */
728			goto badlen;
729		break;		/* nothing to be done in kernel */
730
731	case MLD_MTRACE_RESP:
732	case MLD_MTRACE:
733		/* XXX: these two are experimental.  not officially defined. */
734		/* XXX: per-interface statistics? */
735		break;		/* just pass it to applications */
736
737	case ICMP6_NI_QUERY:
738		if (!icmp6_nodeinfo)
739			break;
740//### LD 10/20 Check fbsd differences here. Not sure we're more advanced or not.
741		/* By RFC 4620 refuse to answer queries from global scope addresses */
742		if ((icmp6_nodeinfo & 8) != 8 && in6_addrscope(&ip6->ip6_src) == IPV6_ADDR_SCOPE_GLOBAL)
743			break;
744
745		if (icmp6len < sizeof(struct icmp6_nodeinfo))
746			goto badlen;
747
748#ifndef PULLDOWN_TEST
749		IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo),
750				 return IPPROTO_DONE);
751#endif
752
753		n = m_copy(m, 0, M_COPYALL);
754		if (n)
755			n = ni6_input(n, off);
756		if (n) {
757			noff = sizeof(struct ip6_hdr);
758			icmp6stat.icp6s_reflect++;
759			icmp6stat.icp6s_outhist[ICMP6_WRUREPLY]++;
760			icmp6_reflect(n, noff);
761		}
762		goto rate_limit_checked;
763		break;
764
765	case ICMP6_WRUREPLY:
766		if (code != 0)
767			goto badcode;
768		break;
769
770	case ND_ROUTER_SOLICIT:
771		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_routersolicit);
772		if (code != 0)
773			goto badcode;
774		if (icmp6len < sizeof(struct nd_router_solicit))
775			goto badlen;
776
777		if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
778			/* give up local */
779			nd6_rs_input(m, off, icmp6len);
780			m = NULL;
781			goto freeit;
782		}
783		nd6_rs_input(n, off, icmp6len);
784		/* m stays. */
785		goto rate_limit_checked;
786		break;
787
788	case ND_ROUTER_ADVERT:
789		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_routeradvert);
790		if (code != 0)
791			goto badcode;
792		if (icmp6len < sizeof(struct nd_router_advert))
793			goto badlen;
794
795		if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
796			/* give up local */
797			nd6_ra_input(m, off, icmp6len);
798			m = NULL;
799			goto freeit;
800		}
801		nd6_ra_input(n, off, icmp6len);
802		/* m stays. */
803		goto rate_limit_checked;
804		break;
805
806	case ND_NEIGHBOR_SOLICIT:
807		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_neighborsolicit);
808		if (code != 0)
809			goto badcode;
810		if (icmp6len < sizeof(struct nd_neighbor_solicit))
811			goto badlen;
812
813		if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
814			/* give up local */
815			nd6_ns_input(m, off, icmp6len);
816			m = NULL;
817			goto freeit;
818		}
819		nd6_ns_input(n, off, icmp6len);
820		/* m stays. */
821		goto rate_limit_checked;
822		break;
823
824	case ND_NEIGHBOR_ADVERT:
825		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_neighboradvert);
826		if (code != 0)
827			goto badcode;
828		if (icmp6len < sizeof(struct nd_neighbor_advert))
829			goto badlen;
830
831		if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
832			/* give up local */
833			nd6_na_input(m, off, icmp6len);
834			m = NULL;
835			goto freeit;
836		}
837		nd6_na_input(n, off, icmp6len);
838		/* m stays. */
839		goto rate_limit_checked;
840		break;
841
842	case ND_REDIRECT:
843		icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_redirect);
844		if (code != 0)
845			goto badcode;
846		if (icmp6len < sizeof(struct nd_redirect))
847			goto badlen;
848
849		if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
850			/* give up local */
851			icmp6_redirect_input(m, off);
852			m = NULL;
853			goto freeit;
854		}
855		icmp6_redirect_input(n, off);
856		/* m stays. */
857		goto rate_limit_checked;
858		break;
859
860	case ICMP6_ROUTER_RENUMBERING:
861		if (code != ICMP6_ROUTER_RENUMBERING_COMMAND &&
862		    code != ICMP6_ROUTER_RENUMBERING_RESULT)
863			goto badcode;
864		if (icmp6len < sizeof(struct icmp6_router_renum))
865			goto badlen;
866		break;
867
868	default:
869		nd6log((LOG_DEBUG,
870		    "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n",
871		    icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src),
872		    ip6_sprintf(&ip6->ip6_dst),
873		    m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0));
874		if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) {
875			/* ICMPv6 error: MUST deliver it by spec... */
876			code = PRC_NCMDS;
877			/* deliver */
878		} else {
879			/* ICMPv6 informational: MUST not deliver */
880			goto rate_limit_checked;
881			break;
882		}
883	deliver:
884		if (icmp6_notify_error(m, off, icmp6len, code)) {
885			/* In this case, m should've been freed. */
886			return(IPPROTO_DONE);
887		}
888		break;
889
890	badcode:
891		icmp6stat.icp6s_badcode++;
892		break;
893
894	badlen:
895		icmp6stat.icp6s_badlen++;
896		break;
897	}
898
899rate_limit_checked:
900	/* deliver the packet to appropriate sockets (unless proxying) */
901	if (!proxy) {
902		icmp6_rip6_input(&m, *offp);
903		return IPPROTO_DONE;
904	}
905
906freeit:
907	m_freem(m);
908	return IPPROTO_DONE;
909}
910
911static int
912icmp6_notify_error(m, off, icmp6len, code)
913	struct mbuf *m;
914	int off, icmp6len, code;
915{
916	struct icmp6_hdr *icmp6;
917	struct ip6_hdr *eip6;
918	u_int32_t notifymtu;
919	struct sockaddr_in6 icmp6src, icmp6dst;
920
921	if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) {
922		icmp6stat.icp6s_tooshort++;
923		goto freeit;
924	}
925#ifndef PULLDOWN_TEST
926	IP6_EXTHDR_CHECK(m, off,
927			 sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr),
928			 return -1);
929	icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
930#else
931	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
932		       sizeof(*icmp6) + sizeof(struct ip6_hdr));
933	if (icmp6 == NULL) {
934		icmp6stat.icp6s_tooshort++;
935		return(-1);
936	}
937#endif
938	eip6 = (struct ip6_hdr *)(icmp6 + 1);
939
940	/* Detect the upper level protocol */
941	{
942		void (*ctlfunc)(int, struct sockaddr *, void *);
943		u_int8_t nxt = eip6->ip6_nxt;
944		int eoff = off + sizeof(struct icmp6_hdr) +
945			sizeof(struct ip6_hdr);
946		struct ip6ctlparam ip6cp;
947		struct in6_addr *finaldst = NULL;
948		int icmp6type = icmp6->icmp6_type;
949		struct ip6_frag *fh;
950		struct ip6_rthdr *rth;
951		struct ip6_rthdr0 *rth0;
952		int rthlen;
953
954		while (1) { /* XXX: should avoid infinite loop explicitly? */
955			struct ip6_ext *eh;
956
957			switch (nxt) {
958			case IPPROTO_HOPOPTS:
959			case IPPROTO_DSTOPTS:
960			case IPPROTO_AH:
961#ifndef PULLDOWN_TEST
962				IP6_EXTHDR_CHECK(m, 0, eoff +
963						 sizeof(struct ip6_ext),
964						 return -1);
965				eh = (struct ip6_ext *)(mtod(m, caddr_t)
966							+ eoff);
967#else
968				IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
969					       eoff, sizeof(*eh));
970				if (eh == NULL) {
971					icmp6stat.icp6s_tooshort++;
972					return(-1);
973				}
974#endif
975
976				if (nxt == IPPROTO_AH)
977					eoff += (eh->ip6e_len + 2) << 2;
978				else
979					eoff += (eh->ip6e_len + 1) << 3;
980				nxt = eh->ip6e_nxt;
981				break;
982			case IPPROTO_ROUTING:
983				/*
984				 * When the erroneous packet contains a
985				 * routing header, we should examine the
986				 * header to determine the final destination.
987				 * Otherwise, we can't properly update
988				 * information that depends on the final
989				 * destination (e.g. path MTU).
990				 */
991#ifndef PULLDOWN_TEST
992				IP6_EXTHDR_CHECK(m, 0, eoff + sizeof(*rth),
993						 return -1);
994				rth = (struct ip6_rthdr *)(mtod(m, caddr_t)
995							   + eoff);
996#else
997				IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
998					       eoff, sizeof(*rth));
999				if (rth == NULL) {
1000					icmp6stat.icp6s_tooshort++;
1001					return(-1);
1002				}
1003#endif
1004				rthlen = (rth->ip6r_len + 1) << 3;
1005				/*
1006				 * XXX: currently there is no
1007				 * officially defined type other
1008				 * than type-0.
1009				 * Note that if the segment left field
1010				 * is 0, all intermediate hops must
1011				 * have been passed.
1012				 */
1013				if (rth->ip6r_segleft &&
1014				    rth->ip6r_type == IPV6_RTHDR_TYPE_0) {
1015					int hops;
1016
1017#ifndef PULLDOWN_TEST
1018					IP6_EXTHDR_CHECK(m, 0, eoff + rthlen,
1019							 return -1);
1020					rth0 = (struct ip6_rthdr0 *)(mtod(m, caddr_t) + eoff);
1021#else
1022					IP6_EXTHDR_GET(rth0,
1023						       struct ip6_rthdr0 *, m,
1024						       eoff, rthlen);
1025					if (rth0 == NULL) {
1026						icmp6stat.icp6s_tooshort++;
1027						return(-1);
1028					}
1029#endif
1030					/* just ignore a bogus header */
1031					if ((rth0->ip6r0_len % 2) == 0 &&
1032					    (hops = rth0->ip6r0_len/2))
1033						finaldst = (struct in6_addr *)(void *)(rth0 + 1) + (hops - 1);
1034				}
1035				eoff += rthlen;
1036				nxt = rth->ip6r_nxt;
1037				break;
1038			case IPPROTO_FRAGMENT:
1039#ifndef PULLDOWN_TEST
1040				IP6_EXTHDR_CHECK(m, 0, eoff +
1041						 sizeof(struct ip6_frag),
1042						 return -1);
1043				fh = (struct ip6_frag *)(mtod(m, caddr_t)
1044							 + eoff);
1045#else
1046				IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
1047					       eoff, sizeof(*fh));
1048				if (fh == NULL) {
1049					icmp6stat.icp6s_tooshort++;
1050					return (-1);
1051				}
1052#endif
1053				/*
1054				 * Data after a fragment header is meaningless
1055				 * unless it is the first fragment, but
1056				 * we'll go to the notify label for path MTU
1057				 * discovery.
1058				 */
1059				if (fh->ip6f_offlg & IP6F_OFF_MASK)
1060					goto notify;
1061
1062				eoff += sizeof(struct ip6_frag);
1063				nxt = fh->ip6f_nxt;
1064				break;
1065			default:
1066				/*
1067				 * This case includes ESP and the No Next
1068				 * Header.  In such cases going to the notify
1069				 * label does not have any meaning
1070				 * (i.e. ctlfunc will be NULL), but we go
1071				 * anyway since we might have to update
1072				 * path MTU information.
1073				 */
1074				goto notify;
1075			}
1076		}
1077	  notify:
1078#ifndef PULLDOWN_TEST
1079		icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
1080#else
1081		IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
1082		    sizeof(*icmp6) + sizeof(struct ip6_hdr));
1083		if (icmp6 == NULL) {
1084			icmp6stat.icp6s_tooshort++;
1085			return (-1);
1086		}
1087#endif
1088
1089		/*
1090		 * retrieve parameters from the inner IPv6 header, and convert
1091		 * them into sockaddr structures.
1092		 * XXX: there is no guarantee that the source or destination
1093		 * addresses of the inner packet are in the same scope as
1094		 * the addresses of the icmp packet.  But there is no other
1095		 * way to determine the zone.
1096		 */
1097		eip6 = (struct ip6_hdr *)(icmp6 + 1);
1098
1099		bzero(&icmp6dst, sizeof(icmp6dst));
1100		icmp6dst.sin6_len = sizeof(struct sockaddr_in6);
1101		icmp6dst.sin6_family = AF_INET6;
1102		if (finaldst == NULL)
1103			icmp6dst.sin6_addr = eip6->ip6_dst;
1104		else
1105			icmp6dst.sin6_addr = *finaldst;
1106		if (in6_setscope(&icmp6dst.sin6_addr, m->m_pkthdr.rcvif, NULL))
1107			goto freeit;
1108		bzero(&icmp6src, sizeof(icmp6src));
1109		icmp6src.sin6_len = sizeof(struct sockaddr_in6);
1110		icmp6src.sin6_family = AF_INET6;
1111		icmp6src.sin6_addr = eip6->ip6_src;
1112		if (in6_setscope(&icmp6src.sin6_addr, m->m_pkthdr.rcvif, NULL))
1113			goto freeit;
1114		icmp6src.sin6_flowinfo =
1115		    (eip6->ip6_flow & IPV6_FLOWLABEL_MASK);
1116
1117		if (finaldst == NULL)
1118			finaldst = &eip6->ip6_dst;
1119		ip6cp.ip6c_m = m;
1120		ip6cp.ip6c_icmp6 = icmp6;
1121		ip6cp.ip6c_ip6 = (struct ip6_hdr *)(icmp6 + 1);
1122		ip6cp.ip6c_off = eoff;
1123		ip6cp.ip6c_finaldst = finaldst;
1124		ip6cp.ip6c_src = &icmp6src;
1125		ip6cp.ip6c_nxt = nxt;
1126
1127		if (icmp6type == ICMP6_PACKET_TOO_BIG) {
1128			notifymtu = ntohl(icmp6->icmp6_mtu);
1129			ip6cp.ip6c_cmdarg = (void *)&notifymtu;
1130			icmp6_mtudisc_update(&ip6cp, 1);	/*XXX*/
1131		}
1132
1133		ctlfunc = (void (*)(int, struct sockaddr *, void *))
1134			(ip6_protox[nxt]->pr_ctlinput);
1135		if (ctlfunc) {
1136			(void) (*ctlfunc)(code, (struct sockaddr *)&icmp6dst,
1137					  &ip6cp);
1138		}
1139	}
1140	return(0);
1141
1142freeit:
1143	m_freem(m);
1144	return(-1);
1145}
1146
1147void
1148icmp6_mtudisc_update(ip6cp, validated)
1149	struct ip6ctlparam *ip6cp;
1150	int validated;
1151{
1152	struct in6_addr *dst = ip6cp->ip6c_finaldst;
1153	struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6;
1154	struct mbuf *m = ip6cp->ip6c_m;	/* will be necessary for scope issue */
1155	u_int mtu = ntohl(icmp6->icmp6_mtu);
1156	struct rtentry *rt = NULL;
1157	struct sockaddr_in6 sin6;
1158	/*
1159	 * we reject ICMPv6 too big with abnormally small value.
1160	 * XXX what is the good definition of "abnormally small"?
1161	 */
1162	if (mtu < sizeof(struct ip6_hdr) + sizeof(struct ip6_frag) + 8)
1163		return;
1164
1165	if (!validated)
1166		return;
1167
1168	/*
1169	 * In case the suggested mtu is less than IPV6_MMTU, we
1170	 * only need to remember that it was for above mentioned
1171	 * "alwaysfrag" case.
1172	 * Try to be as close to the spec as possible.
1173	 */
1174	if (mtu < IPV6_MMTU)
1175		mtu = IPV6_MMTU - 8;
1176
1177	bzero(&sin6, sizeof(sin6));
1178	sin6.sin6_family = PF_INET6;
1179	sin6.sin6_len = sizeof(struct sockaddr_in6);
1180	sin6.sin6_addr = *dst;
1181	/* XXX normally, this won't happen */
1182	if (IN6_IS_ADDR_LINKLOCAL(dst)) {
1183		sin6.sin6_addr.s6_addr16[1] =
1184		    htons(m->m_pkthdr.rcvif->if_index);
1185	}
1186	/* sin6.sin6_scope_id = XXX: should be set if DST is a scoped addr */
1187	rt = rtalloc1_scoped((struct sockaddr *)&sin6, 0,
1188	    RTF_CLONING | RTF_PRCLONING, m->m_pkthdr.rcvif->if_index);
1189	if (rt != NULL) {
1190		RT_LOCK(rt);
1191		if ((rt->rt_flags & RTF_HOST) &&
1192		    !(rt->rt_rmx.rmx_locks & RTV_MTU) &&
1193		    mtu < IN6_LINKMTU(rt->rt_ifp) &&
1194		    rt->rt_rmx.rmx_mtu > mtu) {
1195			icmp6stat.icp6s_pmtuchg++;
1196			rt->rt_rmx.rmx_mtu = mtu;
1197		}
1198		RT_UNLOCK(rt);
1199		rtfree(rt);
1200	}
1201}
1202
1203/*
1204 * Process a Node Information Query packet, based on
1205 * draft-ietf-ipngwg-icmp-name-lookups-07.
1206 *
1207 * Spec incompatibilities:
1208 * - IPv6 Subject address handling
1209 * - IPv4 Subject address handling support missing
1210 * - Proxy reply (answer even if it's not for me)
1211 * - joins NI group address at in6_ifattach() time only, does not cope
1212 *   with hostname changes by sethostname(3)
1213 */
1214#define hostnamelen	strlen(hostname)
1215static struct mbuf *
1216ni6_input(m, off)
1217	struct mbuf *m;
1218	int off;
1219{
1220	struct icmp6_nodeinfo *ni6, *nni6;
1221	struct mbuf *n = NULL;
1222	u_int16_t qtype;
1223	int subjlen;
1224	int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
1225	struct ni_reply_fqdn *fqdn;
1226	int addrs;		/* for NI_QTYPE_NODEADDR */
1227	struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */
1228	struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */
1229	struct sockaddr_in6 sin6_d; /* XXX: we should retrieve this from m_aux */
1230	struct ip6_hdr *ip6;
1231	int oldfqdn = 0;	/* if 1, return pascal string (03 draft) */
1232	char *subj = NULL;
1233
1234	ip6 = mtod(m, struct ip6_hdr *);
1235#ifndef PULLDOWN_TEST
1236	ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off);
1237#else
1238	IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6));
1239	if (ni6 == NULL) {
1240		/* m is already reclaimed */
1241		return (NULL);
1242	}
1243#endif
1244
1245	/*
1246	 * Validate IPv6 source address.
1247	 * The default configuration MUST be to refuse answering queries from
1248	 * global-scope addresses according to RFC4602.
1249	 * Notes:
1250	 *  - it's not very clear what "refuse" means; this implementation
1251	 *    simply drops it.
1252	 *  - it's not very easy to identify global-scope (unicast) addresses
1253	 *    since there are many prefixes for them.  It should be safer
1254	 *    and in practice sufficient to check "all" but loopback and
1255	 *    link-local (note that site-local unicast was deprecated and
1256	 *    ULA is defined as global scope-wise)
1257	 */
1258	if ((icmp6_nodeinfo & ICMP6_NODEINFO_GLOBALOK) == 0 &&
1259	    !IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) &&
1260	    !IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src))
1261		goto bad;
1262
1263	/*
1264	 * Validate IPv6 destination address.
1265	 *
1266	 * The Responder must discard the Query without further processing
1267	 * unless it is one of the Responder's unicast or anycast addresses, or
1268	 * a link-local scope multicast address which the Responder has joined.
1269	 * [RFC4602, Section 5.]
1270	 */
1271	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
1272		if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst))
1273			goto bad;
1274		/* else it's a link-local multicast, fine */
1275	} else {		/* unicast or anycast */
1276		uint32_t ia6_flags;
1277
1278		if (ip6_getdstifaddr_info(m, NULL, &ia6_flags) != 0)
1279			goto bad; /* XXX impossible */
1280
1281		if ((ia6_flags & IN6_IFF_TEMPORARY) &&
1282		    !(icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) {
1283			nd6log((LOG_DEBUG, "ni6_input: ignore node info to "
1284				"a temporary address in %s:%d",
1285			       __FILE__, __LINE__));
1286			goto bad;
1287		}
1288	}
1289
1290	/* validate query Subject field. */
1291	qtype = ntohs(ni6->ni_qtype);
1292	subjlen = m->m_pkthdr.len - off - sizeof(struct icmp6_nodeinfo);
1293	switch (qtype) {
1294	case NI_QTYPE_NOOP:
1295	case NI_QTYPE_SUPTYPES:
1296		/* 07 draft */
1297		if (ni6->ni_code == ICMP6_NI_SUBJ_FQDN && subjlen == 0)
1298			break;
1299		/* FALLTHROUGH */
1300	case NI_QTYPE_FQDN:
1301	case NI_QTYPE_NODEADDR:
1302	case NI_QTYPE_IPV4ADDR:
1303		switch (ni6->ni_code) {
1304		case ICMP6_NI_SUBJ_IPV6:
1305#if ICMP6_NI_SUBJ_IPV6 != 0
1306		case 0:
1307#endif
1308			/*
1309			 * backward compatibility - try to accept 03 draft
1310			 * format, where no Subject is present.
1311			 */
1312			if (qtype == NI_QTYPE_FQDN && ni6->ni_code == 0 &&
1313			    subjlen == 0) {
1314				oldfqdn++;
1315				break;
1316			}
1317#if ICMP6_NI_SUBJ_IPV6 != 0
1318			if (ni6->ni_code != ICMP6_NI_SUBJ_IPV6)
1319				goto bad;
1320#endif
1321
1322			if (subjlen != sizeof(struct in6_addr))
1323				goto bad;
1324
1325			/*
1326			 * Validate Subject address.
1327			 *
1328			 * Not sure what exactly "address belongs to the node"
1329			 * means in the spec, is it just unicast, or what?
1330			 *
1331			 * At this moment we consider Subject address as
1332			 * "belong to the node" if the Subject address equals
1333			 * to the IPv6 destination address; validation for
1334			 * IPv6 destination address should have done enough
1335			 * check for us.
1336			 *
1337			 * We do not do proxy at this moment.
1338			 */
1339			/* m_pulldown instead of copy? */
1340			m_copydata(m, off + sizeof(struct icmp6_nodeinfo),
1341			    subjlen, (caddr_t)&sin6.sin6_addr);
1342			sin6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
1343							      &sin6.sin6_addr);
1344			in6_embedscope(&sin6.sin6_addr, &sin6, NULL, NULL,
1345			    NULL);
1346			bzero(&sin6_d, sizeof(sin6_d));
1347			sin6_d.sin6_family = AF_INET6; /* not used, actually */
1348			sin6_d.sin6_len = sizeof(sin6_d); /* ditto */
1349			sin6_d.sin6_addr = ip6->ip6_dst;
1350			sin6_d.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
1351								&ip6->ip6_dst);
1352			in6_embedscope(&sin6_d.sin6_addr, &sin6_d, NULL, NULL,
1353			    NULL);
1354			subj = (char *)&sin6;
1355			if (SA6_ARE_ADDR_EQUAL(&sin6, &sin6_d))
1356				break;
1357
1358			/*
1359			 * XXX if we are to allow other cases, we should really
1360			 * be careful about scope here.
1361			 * basically, we should disallow queries toward IPv6
1362			 * destination X with subject Y,
1363			 * if scope(X) > scope(Y).
1364			 * if we allow scope(X) > scope(Y), it will result in
1365			 * information leakage across scope boundary.
1366			 */
1367			goto bad;
1368
1369		case ICMP6_NI_SUBJ_FQDN:
1370			/*
1371			 * Validate Subject name with gethostname(3).
1372			 *
1373			 * The behavior may need some debate, since:
1374			 * - we are not sure if the node has FQDN as
1375			 *   hostname (returned by gethostname(3)).
1376			 * - the code does wildcard match for truncated names.
1377			 *   however, we are not sure if we want to perform
1378			 *   wildcard match, if gethostname(3) side has
1379			 *   truncated hostname.
1380			 */
1381			n = ni6_nametodns(hostname, hostnamelen, 0);
1382			if (!n || n->m_next || n->m_len == 0)
1383				goto bad;
1384			IP6_EXTHDR_GET(subj, char *, m,
1385			    off + sizeof(struct icmp6_nodeinfo), subjlen);
1386			if (subj == NULL)
1387				goto bad;
1388			if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *),
1389					n->m_len)) {
1390				goto bad;
1391			}
1392			m_freem(n);
1393			n = NULL;
1394			break;
1395
1396		case ICMP6_NI_SUBJ_IPV4:	/* XXX: to be implemented? */
1397		default:
1398			goto bad;
1399		}
1400		break;
1401	}
1402
1403	/* refuse based on configuration.  XXX ICMP6_NI_REFUSED? */
1404	switch (qtype) {
1405	case NI_QTYPE_FQDN:
1406		if ((icmp6_nodeinfo & ICMP6_NODEINFO_FQDNOK) == 0)
1407			goto bad;
1408		break;
1409	case NI_QTYPE_NODEADDR:
1410	case NI_QTYPE_IPV4ADDR:
1411		if ((icmp6_nodeinfo & ICMP6_NODEINFO_NODEADDROK) == 0)
1412			goto bad;
1413		break;
1414	}
1415
1416	/* guess reply length */
1417	switch (qtype) {
1418	case NI_QTYPE_NOOP:
1419		break;		/* no reply data */
1420	case NI_QTYPE_SUPTYPES:
1421		replylen += sizeof(u_int32_t);
1422		break;
1423	case NI_QTYPE_FQDN:
1424		/* XXX will append an mbuf */
1425		replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen);
1426		break;
1427	case NI_QTYPE_NODEADDR:
1428		addrs = ni6_addrs(ni6, &ifp, subj);
1429		if ((replylen += addrs * (sizeof(struct in6_addr) +
1430		    sizeof(u_int32_t))) > MCLBYTES)
1431			replylen = MCLBYTES; /* XXX: will truncate pkt later */
1432		break;
1433	case NI_QTYPE_IPV4ADDR:
1434		/* unsupported - should respond with unknown Qtype? */
1435		break;
1436	default:
1437		/*
1438		 * XXX: We must return a reply with the ICMP6 code
1439		 * `unknown Qtype' in this case.  However we regard the case
1440		 * as an FQDN query for backward compatibility.
1441		 * Older versions set a random value to this field,
1442		 * so it rarely varies in the defined qtypes.
1443		 * But the mechanism is not reliable...
1444		 * maybe we should obsolete older versions.
1445		 */
1446		qtype = NI_QTYPE_FQDN;
1447		/* XXX will append an mbuf */
1448		replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen);
1449		oldfqdn++;
1450		break;
1451	}
1452
1453	/* allocate an mbuf to reply. */
1454	MGETHDR(n, M_DONTWAIT, m->m_type);	/* MAC-OK */
1455	if (n == NULL) {
1456		m_freem(m);
1457		if (ifp != NULL)
1458			ifnet_release(ifp);
1459		return (NULL);
1460	}
1461	M_COPY_PKTHDR(n, m); /* just for recvif */
1462	if (replylen > MHLEN) {
1463		if (replylen > MCLBYTES) {
1464			/*
1465			 * XXX: should we try to allocate more? But MCLBYTES
1466			 * is probably much larger than IPV6_MMTU...
1467			 */
1468			goto bad;
1469		}
1470		MCLGET(n, M_DONTWAIT);
1471		if ((n->m_flags & M_EXT) == 0) {
1472			goto bad;
1473		}
1474	}
1475	n->m_pkthdr.len = n->m_len = replylen;
1476
1477	/* copy mbuf header and IPv6 + Node Information base headers */
1478	bcopy(mtod(m, caddr_t), mtod(n, caddr_t), sizeof(struct ip6_hdr));
1479	nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1);
1480	bcopy((caddr_t)ni6, (caddr_t)nni6, sizeof(struct icmp6_nodeinfo));
1481
1482	/* qtype dependent procedure */
1483	switch (qtype) {
1484	case NI_QTYPE_NOOP:
1485		nni6->ni_code = ICMP6_NI_SUCCESS;
1486		nni6->ni_flags = 0;
1487		break;
1488	case NI_QTYPE_SUPTYPES:
1489	{
1490		u_int32_t v;
1491		nni6->ni_code = ICMP6_NI_SUCCESS;
1492		nni6->ni_flags = htons(0x0000);	/* raw bitmap */
1493		/* supports NOOP, SUPTYPES, FQDN, and NODEADDR */
1494		v = (u_int32_t)htonl(0x0000000f);
1495		bcopy(&v, nni6 + 1, sizeof(u_int32_t));
1496		break;
1497	}
1498	case NI_QTYPE_FQDN:
1499		nni6->ni_code = ICMP6_NI_SUCCESS;
1500		fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) +
1501						sizeof(struct ip6_hdr) +
1502						sizeof(struct icmp6_nodeinfo));
1503		nni6->ni_flags = 0; /* XXX: meaningless TTL */
1504		fqdn->ni_fqdn_ttl = 0;	/* ditto. */
1505		/*
1506		 * XXX do we really have FQDN in variable "hostname"?
1507		 */
1508		n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn);
1509		if (n->m_next == NULL)
1510			goto bad;
1511		/* XXX we assume that n->m_next is not a chain */
1512		if (n->m_next->m_next != NULL)
1513			goto bad;
1514		n->m_pkthdr.len += n->m_next->m_len;
1515		break;
1516	case NI_QTYPE_NODEADDR:
1517	{
1518		int lenlim, copied;
1519
1520		nni6->ni_code = ICMP6_NI_SUCCESS;
1521		n->m_pkthdr.len = n->m_len =
1522		    sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
1523		lenlim = M_TRAILINGSPACE(n);
1524		copied = ni6_store_addrs(ni6, nni6, ifp, lenlim);
1525		/* XXX: reset mbuf length */
1526		n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
1527			sizeof(struct icmp6_nodeinfo) + copied;
1528		break;
1529	}
1530	default:
1531		break;		/* XXX impossible! */
1532	}
1533
1534	nni6->ni_type = ICMP6_NI_REPLY;
1535	m_freem(m);
1536	if (ifp != NULL)
1537		ifnet_release(ifp);
1538	return (n);
1539
1540bad:
1541	m_freem(m);
1542	if (n)
1543		m_freem(n);
1544	if (ifp != NULL)
1545		ifnet_release(ifp);
1546	return (NULL);
1547}
1548#undef hostnamelen
1549
1550/*
1551 * make a mbuf with DNS-encoded string.  no compression support.
1552 *
1553 * XXX names with less than 2 dots (like "foo" or "foo.section") will be
1554 * treated as truncated name (two \0 at the end).  this is a wild guess.
1555 */
1556static struct mbuf *
1557ni6_nametodns(name, namelen, old)
1558	const char *name;
1559	int namelen;
1560	int old;	/* return pascal string if non-zero */
1561{
1562	struct mbuf *m;
1563	char *cp, *ep;
1564	const char *p, *q;
1565	int i, len, nterm;
1566
1567	if (old)
1568		len = namelen + 1;
1569	else
1570		len = MCLBYTES;
1571
1572	/* because MAXHOSTNAMELEN is usually 256, we use cluster mbuf */
1573	MGET(m, M_DONTWAIT, MT_DATA);
1574	if (m && len > MLEN) {
1575		MCLGET(m, M_DONTWAIT);
1576		if ((m->m_flags & M_EXT) == 0)
1577			goto fail;
1578	}
1579	if (!m)
1580		goto fail;
1581	m->m_next = NULL;
1582
1583	if (old) {
1584		m->m_len = len;
1585		*mtod(m, char *) = namelen;
1586		bcopy(name, mtod(m, char *) + 1, namelen);
1587		return m;
1588	} else {
1589		m->m_len = 0;
1590		cp = mtod(m, char *);
1591		ep = mtod(m, char *) + M_TRAILINGSPACE(m);
1592
1593		/* if not certain about my name, return empty buffer */
1594		if (namelen == 0)
1595			return m;
1596
1597		/*
1598		 * guess if it looks like shortened hostname, or FQDN.
1599		 * shortened hostname needs two trailing "\0".
1600		 */
1601		i = 0;
1602		for (p = name; p < name + namelen; p++) {
1603			if (*p && *p == '.')
1604				i++;
1605		}
1606		if (i < 2)
1607			nterm = 2;
1608		else
1609			nterm = 1;
1610
1611		p = name;
1612		while (cp < ep && p < name + namelen) {
1613			i = 0;
1614			for (q = p; q < name + namelen && *q && *q != '.'; q++)
1615				i++;
1616			/* result does not fit into mbuf */
1617			if (cp + i + 1 >= ep)
1618				goto fail;
1619			/*
1620			 * DNS label length restriction, RFC1035 page 8.
1621			 * "i == 0" case is included here to avoid returning
1622			 * 0-length label on "foo..bar".
1623			 */
1624			if (i <= 0 || i >= 64)
1625				goto fail;
1626			*cp++ = i;
1627			bcopy(p, cp, i);
1628			cp += i;
1629			p = q;
1630			if (p < name + namelen && *p == '.')
1631				p++;
1632		}
1633		/* termination */
1634		if (cp + nterm >= ep)
1635			goto fail;
1636		while (nterm-- > 0)
1637			*cp++ = '\0';
1638		m->m_len = cp - mtod(m, char *);
1639		return m;
1640	}
1641
1642	panic("should not reach here");
1643	/* NOTREACHED */
1644
1645 fail:
1646	if (m)
1647		m_freem(m);
1648	return NULL;
1649}
1650
1651/*
1652 * check if two DNS-encoded string matches.  takes care of truncated
1653 * form (with \0\0 at the end).  no compression support.
1654 * XXX upper/lowercase match (see RFC2065)
1655 */
1656static int
1657ni6_dnsmatch(a, alen, b, blen)
1658	const char *a;
1659	int alen;
1660	const char *b;
1661	int blen;
1662{
1663	const char *a0, *b0;
1664	int l;
1665
1666	/* simplest case - need validation? */
1667	if (alen == blen && bcmp(a, b, alen) == 0)
1668		return 1;
1669
1670	a0 = a;
1671	b0 = b;
1672
1673	/* termination is mandatory */
1674	if (alen < 2 || blen < 2)
1675		return 0;
1676	if (a0[alen - 1] != '\0' || b0[blen - 1] != '\0')
1677		return 0;
1678	alen--;
1679	blen--;
1680
1681	while (a - a0 < alen && b - b0 < blen) {
1682		if (a - a0 + 1 > alen || b - b0 + 1 > blen)
1683			return 0;
1684
1685		if ((signed char)a[0] < 0 || (signed char)b[0] < 0)
1686			return 0;
1687		/* we don't support compression yet */
1688		if (a[0] >= 64 || b[0] >= 64)
1689			return 0;
1690
1691		/* truncated case */
1692		if (a[0] == 0 && a - a0 == alen - 1)
1693			return 1;
1694		if (b[0] == 0 && b - b0 == blen - 1)
1695			return 1;
1696		if (a[0] == 0 || b[0] == 0)
1697			return 0;
1698
1699		if (a[0] != b[0])
1700			return 0;
1701		l = a[0];
1702		if (a - a0 + 1 + l > alen || b - b0 + 1 + l > blen)
1703			return 0;
1704		if (bcmp(a + 1, b + 1, l) != 0)
1705			return 0;
1706
1707		a += 1 + l;
1708		b += 1 + l;
1709	}
1710
1711	if (a - a0 == alen && b - b0 == blen)
1712		return 1;
1713	else
1714		return 0;
1715}
1716
1717/*
1718 * calculate the number of addresses to be returned in the node info reply.
1719 */
1720static int
1721ni6_addrs(ni6, ifpp, subj)
1722	struct icmp6_nodeinfo *ni6;
1723	struct ifnet **ifpp;
1724	char *subj;
1725{
1726	struct ifnet *ifp;
1727	struct in6_ifaddr *ifa6;
1728	struct ifaddr *ifa;
1729	struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
1730	int addrs = 0, addrsofif, iffound = 0;
1731	int niflags = ni6->ni_flags;
1732
1733	if (ifpp != NULL)
1734		*ifpp = NULL;
1735
1736	if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) {
1737		switch (ni6->ni_code) {
1738		case ICMP6_NI_SUBJ_IPV6:
1739			if (subj == NULL) /* must be impossible... */
1740				return(0);
1741			subj_ip6 = (struct sockaddr_in6 *)(void *)subj;
1742			break;
1743		default:
1744			/*
1745			 * XXX: we only support IPv6 subject address for
1746			 * this Qtype.
1747			 */
1748			return (0);
1749		}
1750	}
1751
1752	ifnet_head_lock_shared();
1753	TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
1754		addrsofif = 0;
1755		ifnet_lock_shared(ifp);
1756		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1757		{
1758			IFA_LOCK(ifa);
1759			if (ifa->ifa_addr->sa_family != AF_INET6) {
1760				IFA_UNLOCK(ifa);
1761				continue;
1762			}
1763			ifa6 = (struct in6_ifaddr *)ifa;
1764
1765			if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 &&
1766			    IN6_ARE_ADDR_EQUAL(&subj_ip6->sin6_addr,
1767					       &ifa6->ia_addr.sin6_addr))
1768				iffound = 1;
1769
1770			/*
1771			 * IPv4-mapped addresses can only be returned by a
1772			 * Node Information proxy, since they represent
1773			 * addresses of IPv4-only nodes, which perforce do
1774			 * not implement this protocol.
1775			 * [icmp-name-lookups-07, Section 5.4]
1776			 * So we don't support NI_NODEADDR_FLAG_COMPAT in
1777			 * this function at this moment.
1778			 */
1779
1780			/* What do we have to do about ::1? */
1781			switch (in6_addrscope(&ifa6->ia_addr.sin6_addr)) {
1782			case IPV6_ADDR_SCOPE_LINKLOCAL:
1783				if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) {
1784					IFA_UNLOCK(ifa);
1785					continue;
1786				}
1787				break;
1788			case IPV6_ADDR_SCOPE_SITELOCAL:
1789				if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) {
1790					IFA_UNLOCK(ifa);
1791					continue;
1792				}
1793				break;
1794			case IPV6_ADDR_SCOPE_GLOBAL:
1795				if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) {
1796					IFA_UNLOCK(ifa);
1797					continue;
1798				}
1799				break;
1800			default:
1801				IFA_UNLOCK(ifa);
1802				continue;
1803			}
1804
1805			/*
1806			 * check if anycast is okay.
1807			 * XXX: just experimental.  not in the spec.
1808			 */
1809			if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
1810			    (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) {
1811				IFA_UNLOCK(ifa);
1812				continue; /* we need only unicast addresses */
1813			}
1814			if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
1815			    (icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) {
1816				IFA_UNLOCK(ifa);
1817				continue;
1818			}
1819			addrsofif++; /* count the address */
1820			IFA_UNLOCK(ifa);
1821		}
1822		ifnet_lock_done(ifp);
1823		if (iffound) {
1824			if (ifpp != NULL) {
1825				*ifpp = ifp;
1826				ifnet_reference(ifp);
1827			}
1828			ifnet_head_done();
1829			return(addrsofif);
1830		}
1831
1832		addrs += addrsofif;
1833	}
1834	ifnet_head_done();
1835
1836	return (addrs);
1837}
1838
1839static int
1840ni6_store_addrs(ni6, nni6, ifp0, resid)
1841	struct icmp6_nodeinfo *ni6, *nni6;
1842	struct ifnet *ifp0;
1843	int resid;
1844{
1845	struct ifnet *ifp = ifp0;
1846	struct in6_ifaddr *ifa6;
1847	struct ifaddr *ifa;
1848	struct ifnet *ifp_dep = NULL;
1849	int copied = 0, allow_deprecated = 0;
1850	u_char *cp = (u_char *)(nni6 + 1);
1851	int niflags = ni6->ni_flags;
1852	u_int32_t ltime;
1853	uint64_t now = net_uptime();
1854
1855	if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL))
1856		return (0);	/* needless to copy */
1857
1858  again:
1859
1860	ifnet_head_lock_shared();
1861	if (ifp == NULL)
1862		ifp = TAILQ_FIRST(&ifnet_head);
1863
1864	for (; ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
1865		ifnet_lock_shared(ifp);
1866		for (ifa = ifp->if_addrlist.tqh_first; ifa;
1867		     ifa = ifa->ifa_list.tqe_next) {
1868			struct in6_addrlifetime_i *lt;
1869
1870			IFA_LOCK(ifa);
1871			if (ifa->ifa_addr->sa_family != AF_INET6) {
1872				IFA_UNLOCK(ifa);
1873				continue;
1874			}
1875			ifa6 = (struct in6_ifaddr *)ifa;
1876
1877			if ((ifa6->ia6_flags & IN6_IFF_DEPRECATED) != 0 &&
1878			    allow_deprecated == 0) {
1879				/*
1880				 * prefererred address should be put before
1881				 * deprecated addresses.
1882				 */
1883
1884				/* record the interface for later search */
1885				if (ifp_dep == NULL)
1886					ifp_dep = ifp;
1887
1888				IFA_UNLOCK(ifa);
1889				continue;
1890			} else if ((ifa6->ia6_flags & IN6_IFF_DEPRECATED) == 0 &&
1891			    allow_deprecated != 0) {
1892				IFA_UNLOCK(ifa);
1893				continue; /* we now collect deprecated addrs */
1894			}
1895			/* What do we have to do about ::1? */
1896			switch (in6_addrscope(&ifa6->ia_addr.sin6_addr)) {
1897			case IPV6_ADDR_SCOPE_LINKLOCAL:
1898				if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) {
1899					IFA_UNLOCK(ifa);
1900					continue;
1901				}
1902				break;
1903			case IPV6_ADDR_SCOPE_SITELOCAL:
1904				if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) {
1905					IFA_UNLOCK(ifa);
1906					continue;
1907				}
1908				break;
1909			case IPV6_ADDR_SCOPE_GLOBAL:
1910				if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) {
1911					IFA_UNLOCK(ifa);
1912					continue;
1913				}
1914				break;
1915			default:
1916				IFA_UNLOCK(ifa);
1917				continue;
1918			}
1919
1920			/*
1921			 * check if anycast is okay.
1922			 * XXX: just experimental.  not in the spec.
1923			 */
1924			if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
1925			    (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) {
1926				IFA_UNLOCK(ifa);
1927				continue;
1928			}
1929			if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
1930			    (icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) {
1931				IFA_UNLOCK(ifa);
1932				continue;
1933			}
1934
1935			/* now we can copy the address */
1936			if (resid < sizeof(struct in6_addr) +
1937			    sizeof(u_int32_t)) {
1938				IFA_UNLOCK(ifa);
1939				/*
1940				 * We give up much more copy.
1941				 * Set the truncate flag and return.
1942				 */
1943				nni6->ni_flags |=
1944					NI_NODEADDR_FLAG_TRUNCATE;
1945				ifnet_lock_done(ifp);
1946				ifnet_head_done();
1947				return(copied);
1948			}
1949
1950			/*
1951			 * Set the TTL of the address.
1952			 * The TTL value should be one of the following
1953			 * according to the specification:
1954			 *
1955			 * 1. The remaining lifetime of a DHCP lease on the
1956			 *    address, or
1957			 * 2. The remaining Valid Lifetime of a prefix from
1958			 *    which the address was derived through Stateless
1959			 *    Autoconfiguration.
1960			 *
1961			 * Note that we currently do not support stateful
1962			 * address configuration by DHCPv6, so the former
1963			 * case can't happen.
1964			 */
1965			lt = &ifa6->ia6_lifetime;
1966			if (lt->ia6ti_expire == 0) {
1967				ltime = ND6_INFINITE_LIFETIME;
1968			} else {
1969				if (lt->ia6ti_expire > now)
1970					ltime = htonl(lt->ia6ti_expire - now);
1971				else
1972					ltime = 0;
1973			}
1974
1975			bcopy(&ltime, cp, sizeof(u_int32_t));
1976			cp += sizeof(u_int32_t);
1977
1978			/* copy the address itself */
1979			bcopy(&ifa6->ia_addr.sin6_addr, cp,
1980			      sizeof(struct in6_addr));
1981			/* XXX: KAME link-local hack; remove ifindex */
1982			if (IN6_IS_ADDR_LINKLOCAL(&ifa6->ia_addr.sin6_addr))
1983				((struct in6_addr *)(void *)cp)->s6_addr16[1] = 0;
1984			cp += sizeof(struct in6_addr);
1985
1986			resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t));
1987			copied += (sizeof(struct in6_addr) +
1988				   sizeof(u_int32_t));
1989			IFA_UNLOCK(ifa);
1990		}
1991		ifnet_lock_done(ifp);
1992		if (ifp0)	/* we need search only on the specified IF */
1993			break;
1994	}
1995	ifnet_head_done();
1996
1997	if (allow_deprecated == 0 && ifp_dep != NULL) {
1998		ifp = ifp_dep;
1999		allow_deprecated = 1;
2000
2001		goto again;
2002	}
2003
2004	return(copied);
2005}
2006
2007/*
2008 * XXX almost dup'ed code with rip6_input.
2009 */
2010static int
2011icmp6_rip6_input(mp, off)
2012	struct	mbuf **mp;
2013	int	off;
2014{
2015	struct mbuf *m = *mp;
2016	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
2017	struct in6pcb *in6p;
2018	struct in6pcb *last = NULL;
2019	struct sockaddr_in6 rip6src;
2020	struct icmp6_hdr *icmp6;
2021	struct mbuf *opts = NULL;
2022	int ret = 0;
2023	struct ifnet *ifp = m->m_pkthdr.rcvif;
2024
2025#ifndef PULLDOWN_TEST
2026	/* this is assumed to be safe. */
2027	icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
2028#else
2029	IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
2030	if (icmp6 == NULL) {
2031		/* m is already reclaimed */
2032		return IPPROTO_DONE;
2033	}
2034#endif
2035
2036	/*
2037	 * XXX: the address may have embedded scope zone ID, which should be
2038	 * hidden from applications.
2039	 */
2040	bzero(&rip6src, sizeof(rip6src));
2041	rip6src.sin6_family = AF_INET6;
2042	rip6src.sin6_len = sizeof(struct sockaddr_in6);
2043	rip6src.sin6_addr = ip6->ip6_src;
2044	if (sa6_recoverscope(&rip6src, TRUE))
2045		return (IPPROTO_DONE);
2046
2047	lck_rw_lock_shared(ripcbinfo.ipi_lock);
2048	LIST_FOREACH(in6p, &ripcb, inp_list)
2049	{
2050		if ((in6p->inp_vflag & INP_IPV6) == 0)
2051			continue;
2052		if (in6p->in6p_ip6_nxt != IPPROTO_ICMPV6)
2053			continue;
2054		if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
2055		   !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
2056			continue;
2057		if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
2058		   !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
2059			continue;
2060		if (in6p->in6p_icmp6filt
2061		    && ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type,
2062				 in6p->in6p_icmp6filt))
2063			continue;
2064
2065		if (inp_restricted_recv(in6p, ifp))
2066			continue;
2067
2068		if (last) {
2069			struct	mbuf *n;
2070			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
2071				if ((last->in6p_flags & INP_CONTROLOPTS) != 0 ||
2072				    (last->in6p_socket->so_options & SO_TIMESTAMP) != 0 ||
2073				    (last->in6p_socket->so_options & SO_TIMESTAMP_MONOTONIC) != 0) {
2074					ret = ip6_savecontrol(last, n, &opts);
2075					if (ret != 0) {
2076						m_freem(n);
2077						m_freem(opts);
2078						last = in6p;
2079						continue;
2080					}
2081				}
2082				/* strip intermediate headers */
2083				m_adj(n, off);
2084				so_recv_data_stat(last->in6p_socket, m, 0);
2085				if (sbappendaddr(&last->in6p_socket->so_rcv,
2086						 (struct sockaddr *)&rip6src,
2087						 n, opts, NULL) != 0) {
2088					sorwakeup(last->in6p_socket);
2089				}
2090				opts = NULL;
2091			}
2092		}
2093		last = in6p;
2094	}
2095	if (last) {
2096		if ((last->in6p_flags & INP_CONTROLOPTS) != 0 ||
2097		    (last->in6p_socket->so_options & SO_TIMESTAMP) != 0 ||
2098		    (last->in6p_socket->so_options & SO_TIMESTAMP_MONOTONIC) != 0) {
2099			ret = ip6_savecontrol(last, m, &opts);
2100			if (ret != 0) {
2101				goto error;
2102			}
2103		}
2104		/* strip intermediate headers */
2105		m_adj(m, off);
2106		so_recv_data_stat(last->in6p_socket, m, 0);
2107		if (sbappendaddr(&last->in6p_socket->so_rcv,
2108				 (struct sockaddr *)&rip6src, m, opts, NULL) != 0) {
2109			sorwakeup(last->in6p_socket);
2110		}
2111	} else {
2112		goto error;
2113	}
2114	lck_rw_done(ripcbinfo.ipi_lock);
2115	return IPPROTO_DONE;
2116
2117error:
2118	lck_rw_done(ripcbinfo.ipi_lock);
2119	m_freem(m);
2120	m_freem(opts);
2121	ip6stat.ip6s_delivered--;
2122	return IPPROTO_DONE;
2123}
2124
2125/*
2126 * Reflect the ip6 packet back to the source.
2127 * OFF points to the icmp6 header, counted from the top of the mbuf.
2128 */
2129void
2130icmp6_reflect(m, off)
2131	struct	mbuf *m;
2132	size_t off;
2133{
2134	struct mbuf *m_ip6hdr = m;
2135	struct ip6_hdr *ip6;
2136	struct icmp6_hdr *icmp6;
2137	struct in6_ifaddr *ia;
2138	struct in6_addr t, src_storage, *src = 0;
2139	int plen;
2140	int type, code;
2141	struct ifnet *outif = NULL;
2142	struct sockaddr_in6 sa6_src, sa6_dst;
2143	struct nd_ifinfo *ndi;
2144	u_int32_t oflow;
2145	struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 },
2146	    IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR, 0 };
2147
2148	if (!(m->m_pkthdr.pkt_flags & PKTF_LOOP) && m->m_pkthdr.rcvif != NULL) {
2149		ip6oa.ip6oa_boundif = m->m_pkthdr.rcvif->if_index;
2150		ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
2151	}
2152
2153	/* too short to reflect */
2154	if (off < sizeof(struct ip6_hdr)) {
2155		nd6log((LOG_DEBUG,
2156		    "sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n",
2157		    (u_int32_t)off, (u_int32_t)sizeof(struct ip6_hdr),
2158		    __FILE__, __LINE__));
2159		goto bad;
2160	}
2161
2162	/*
2163	 * If there are extra headers between IPv6 and ICMPv6, strip
2164	 * off that header first.
2165	 */
2166	if (off > sizeof(struct ip6_hdr)) {
2167		size_t l;
2168		struct ip6_hdr nip6;
2169
2170		l = off - sizeof(struct ip6_hdr);
2171		m_copydata(m, 0, sizeof(nip6), (caddr_t)&nip6);
2172		m_adj(m, l);
2173		l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
2174		if (m->m_len < l) {
2175			if ((m_ip6hdr = m_pulldown(m, 0, l, NULL)) == NULL)
2176				return;
2177		}
2178		bcopy((caddr_t)&nip6, mtod(m, caddr_t), sizeof(nip6));
2179	} else /* off == sizeof(struct ip6_hdr) */ {
2180		size_t l;
2181		l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
2182		if (m->m_len < l) {
2183			if ((m_ip6hdr = m_pulldown(m, 0, l, NULL)) == NULL)
2184				return;
2185		}
2186	}
2187	plen = m->m_pkthdr.len - sizeof(struct ip6_hdr);
2188	ip6 = mtod(m_ip6hdr, struct ip6_hdr *);
2189	ip6->ip6_nxt = IPPROTO_ICMPV6;
2190	icmp6 = (struct icmp6_hdr *)(ip6 + 1);
2191	type = icmp6->icmp6_type; /* keep type for statistics */
2192	code = icmp6->icmp6_code; /* ditto. */
2193
2194	t = ip6->ip6_dst;
2195	/*
2196	 * ip6_input() drops a packet if its src is multicast.
2197	 * So, the src is never multicast.
2198	 */
2199	ip6->ip6_dst = ip6->ip6_src;
2200
2201	/*
2202	 * XXX: make sure to embed scope zone information, using
2203	 * already embedded IDs or the received interface (if any).
2204	 * Note that rcvif may be NULL.
2205	 */
2206	bzero(&sa6_src, sizeof(sa6_src));
2207	sa6_src.sin6_family = AF_INET6;
2208	sa6_src.sin6_len = sizeof(sa6_src);
2209	sa6_src.sin6_addr = ip6->ip6_dst;
2210	in6_recoverscope(&sa6_src, &ip6->ip6_dst, m->m_pkthdr.rcvif);
2211	in6_embedscope(&ip6->ip6_dst, &sa6_src, NULL, NULL, NULL);
2212	bzero(&sa6_dst, sizeof(sa6_dst));
2213	sa6_dst.sin6_family = AF_INET6;
2214	sa6_dst.sin6_len = sizeof(sa6_dst);
2215	sa6_dst.sin6_addr = t;
2216	in6_recoverscope(&sa6_dst, &t, m->m_pkthdr.rcvif);
2217	in6_embedscope(&t, &sa6_dst, NULL, NULL, NULL);
2218
2219	/*
2220	 * If the incoming packet was addressed directly to us(i.e. unicast),
2221	 * use dst as the src for the reply.
2222	 * The IN6_IFF_NOTREADY case should be VERY rare, but is possible
2223	 * (for example) when we encounter an error while forwarding procedure
2224	 * destined to a duplicated address of ours.
2225	 * Note that ip6_getdstifaddr() may fail if we are in an error handling
2226	 * procedure of an outgoing packet of our own, in which case we need
2227	 * to search in the ifaddr list.
2228	 */
2229	lck_rw_lock_shared(&in6_ifaddr_rwlock);
2230	for (ia = in6_ifaddrs; ia; ia = ia->ia_next) {
2231		IFA_LOCK(&ia->ia_ifa);
2232		if (IN6_ARE_ADDR_EQUAL(&t, &ia->ia_addr.sin6_addr) &&
2233		    (ia->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)) == 0) {
2234			IFA_UNLOCK(&ia->ia_ifa);
2235			src = &t;
2236			break;
2237		}
2238		IFA_UNLOCK(&ia->ia_ifa);
2239	}
2240	lck_rw_done(&in6_ifaddr_rwlock);
2241	if (ia == NULL && IN6_IS_ADDR_LINKLOCAL(&t) &&
2242	    ((m->m_flags & M_LOOP) || (m->m_pkthdr.pkt_flags & PKTF_LOOP))) {
2243		/*
2244		 * This is the case if the dst is our link-local address
2245		 * and the sender is also ourselves.  Here we test for both
2246		 * M_LOOP and PKTF_LOOP, since the former may have been set
2247		 * in ip6_output() and that we get here as part of callling
2248		 * ip6_process_hopopts().  See comments in <sys/mbuf.h>
2249		 */
2250		src = &t;
2251	}
2252
2253	if (src == NULL) {
2254		int e;
2255		struct sockaddr_in6 sin6;
2256		struct route_in6 ro;
2257
2258		/*
2259		 * This case matches to multicasts, our anycast, or unicasts
2260		 * that we do not own.  Select a source address based on the
2261		 * source address of the erroneous packet.
2262		 */
2263		bzero(&sin6, sizeof(sin6));
2264		sin6.sin6_family = AF_INET6;
2265		sin6.sin6_len = sizeof(sin6);
2266		sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */
2267
2268		bzero(&ro, sizeof(ro));
2269		/*
2270		 * in6_selectsrc() might return outif with its reference held
2271		 * even in the error case, so we always need to release it
2272		 * if non-NULL.
2273		 */
2274		src = in6_selectsrc(&sin6, NULL, NULL, &ro, &outif,
2275		    &src_storage, ip6oa.ip6oa_boundif, &e);
2276		ROUTE_RELEASE(&ro);
2277		if (src == NULL) {
2278			nd6log((LOG_DEBUG,
2279			    "icmp6_reflect: source can't be determined: "
2280			    "dst=%s, error=%d\n",
2281			    ip6_sprintf(&sa6_src.sin6_addr), e));
2282			goto bad;
2283		}
2284	}
2285	oflow = ip6->ip6_flow; /* Save for later */
2286	ip6->ip6_src = *src;
2287	ip6->ip6_flow = 0;
2288	ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
2289	ip6->ip6_vfc |= IPV6_VERSION;
2290	if (icmp6->icmp6_type == ICMP6_ECHO_REPLY && icmp6->icmp6_code == 0) {
2291		ip6->ip6_flow |= (oflow & htonl(0x0ff00000));
2292	}
2293	ip6->ip6_nxt = IPPROTO_ICMPV6;
2294	lck_rw_lock_shared(nd_if_rwlock);
2295	if (outif != NULL && (ndi = ND_IFINFO(outif)) != NULL &&
2296	    ndi->initialized) {
2297		lck_mtx_lock(&ndi->lock);
2298		ip6->ip6_hlim = ndi->chlim;
2299		lck_mtx_unlock(&ndi->lock);
2300	}
2301	if (m->m_pkthdr.rcvif != NULL &&
2302	    (ndi = ND_IFINFO(m->m_pkthdr.rcvif)) != NULL &&
2303	    ndi->initialized) {
2304		/* XXX: This may not be the outgoing interface */
2305		lck_mtx_lock(&ndi->lock);
2306		ip6->ip6_hlim = ndi->chlim;
2307		lck_mtx_unlock(&ndi->lock);
2308	} else {
2309		ip6->ip6_hlim = ip6_defhlim;
2310	}
2311	lck_rw_done(nd_if_rwlock);
2312	/* Use the same traffic class as in the request to match IPv4 */
2313	icmp6->icmp6_cksum = 0;
2314	icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6,
2315					sizeof(struct ip6_hdr), plen);
2316
2317	/*
2318	 * XXX option handling
2319	 */
2320
2321	m->m_flags &= ~(M_BCAST|M_MCAST);
2322
2323	if (outif != NULL) {
2324		ifnet_release(outif);
2325		outif = NULL;
2326	}
2327	m->m_pkthdr.rcvif = NULL;
2328	m->m_pkthdr.csum_data = 0;
2329	m->m_pkthdr.csum_flags = 0;
2330	ip6_output(m, NULL, NULL, IPV6_OUTARGS, NULL, &outif, &ip6oa);
2331	if (outif != NULL) {
2332		icmp6_ifoutstat_inc(outif, type, code);
2333		ifnet_release(outif);
2334	}
2335	return;
2336
2337bad:
2338	m_freem(m);
2339	if (outif != NULL)
2340		ifnet_release(outif);
2341	return;
2342}
2343
2344static const char *
2345icmp6_redirect_diag(src6, dst6, tgt6)
2346	struct in6_addr *src6;
2347	struct in6_addr *dst6;
2348	struct in6_addr *tgt6;
2349{
2350	static char buf[1024];
2351	snprintf(buf, sizeof(buf), "(src=%s dst=%s tgt=%s)",
2352		ip6_sprintf(src6), ip6_sprintf(dst6), ip6_sprintf(tgt6));
2353	return buf;
2354}
2355
2356void
2357icmp6_redirect_input(m, off)
2358	struct mbuf *m;
2359	int off;
2360{
2361	struct ifnet *ifp = m->m_pkthdr.rcvif;
2362	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
2363	struct nd_redirect *nd_rd;
2364	int icmp6len = ntohs(ip6->ip6_plen);
2365	char *lladdr = NULL;
2366	int lladdrlen = 0;
2367	u_char *redirhdr = NULL;
2368	int redirhdrlen = 0;
2369	struct rtentry *rt = NULL;
2370	int is_router;
2371	int is_onlink;
2372	struct in6_addr src6 = ip6->ip6_src;
2373	struct in6_addr redtgt6;
2374	struct in6_addr reddst6;
2375	union nd_opts ndopts;
2376
2377	if (!m || !ifp)
2378		return;
2379
2380	/*
2381	 * If we are an advertising router on this interface,
2382	 * don't update route by icmp6 redirect.
2383	 */
2384	if (ifp->if_eflags & IFEF_IPV6_ROUTER)
2385		goto freeit;
2386	if (!icmp6_rediraccept)
2387		goto freeit;
2388
2389#ifndef PULLDOWN_TEST
2390	IP6_EXTHDR_CHECK(m, off, icmp6len, return);
2391	nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
2392#else
2393	IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len);
2394	if (nd_rd == NULL) {
2395		icmp6stat.icp6s_tooshort++;
2396		return;
2397	}
2398#endif
2399	redtgt6 = nd_rd->nd_rd_target;
2400	reddst6 = nd_rd->nd_rd_dst;
2401
2402	if (in6_setscope(&redtgt6, m->m_pkthdr.rcvif, NULL) ||
2403	    in6_setscope(&reddst6, m->m_pkthdr.rcvif, NULL)) {
2404		goto freeit;
2405	}
2406
2407	/* validation */
2408	if (!IN6_IS_ADDR_LINKLOCAL(&src6)) {
2409		nd6log((LOG_ERR,
2410			"ICMP6 redirect sent from %s rejected; "
2411			"must be from linklocal\n", ip6_sprintf(&src6)));
2412		goto bad;
2413	}
2414	if (ip6->ip6_hlim != 255) {
2415		nd6log((LOG_ERR,
2416			"ICMP6 redirect sent from %s rejected; "
2417			"hlim=%d (must be 255)\n",
2418			ip6_sprintf(&src6), ip6->ip6_hlim));
2419		goto bad;
2420	}
2421    {
2422	/* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */
2423	struct sockaddr_in6 sin6;
2424	struct in6_addr *gw6;
2425
2426	bzero(&sin6, sizeof(sin6));
2427	sin6.sin6_family = AF_INET6;
2428	sin6.sin6_len = sizeof(struct sockaddr_in6);
2429	bcopy(&reddst6, &sin6.sin6_addr, sizeof(reddst6));
2430	rt = rtalloc1_scoped((struct sockaddr *)&sin6, 0, 0, ifp->if_index);
2431	if (rt) {
2432		RT_LOCK(rt);
2433		if (rt->rt_gateway == NULL ||
2434		    rt->rt_gateway->sa_family != AF_INET6) {
2435			nd6log((LOG_ERR,
2436			    "ICMP6 redirect rejected; no route "
2437			    "with inet6 gateway found for redirect dst: %s\n",
2438			    icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2439			RT_UNLOCK(rt);
2440			rtfree(rt);
2441			goto bad;
2442		}
2443
2444		gw6 = &(((struct sockaddr_in6 *)(void *)
2445		    rt->rt_gateway)->sin6_addr);
2446		if (bcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) {
2447			nd6log((LOG_ERR,
2448				"ICMP6 redirect rejected; "
2449				"not equal to gw-for-src=%s (must be same): "
2450				"%s\n",
2451				ip6_sprintf(gw6),
2452				icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2453			RT_UNLOCK(rt);
2454			rtfree(rt);
2455			goto bad;
2456		}
2457	} else {
2458		nd6log((LOG_ERR,
2459			"ICMP6 redirect rejected; "
2460			"no route found for redirect dst: %s\n",
2461			icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2462		goto bad;
2463	}
2464	RT_UNLOCK(rt);
2465	rtfree(rt);
2466	rt = NULL;
2467    }
2468	if (IN6_IS_ADDR_MULTICAST(&reddst6)) {
2469		nd6log((LOG_ERR,
2470			"ICMP6 redirect rejected; "
2471			"redirect dst must be unicast: %s\n",
2472			icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2473		goto bad;
2474	}
2475
2476	is_router = is_onlink = 0;
2477	if (IN6_IS_ADDR_LINKLOCAL(&redtgt6))
2478		is_router = 1;	/* router case */
2479	if (bcmp(&redtgt6, &reddst6, sizeof(redtgt6)) == 0)
2480		is_onlink = 1;	/* on-link destination case */
2481	if (!is_router && !is_onlink) {
2482		nd6log((LOG_ERR,
2483			"ICMP6 redirect rejected; "
2484			"neither router case nor onlink case: %s\n",
2485			icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2486		goto bad;
2487	}
2488	/* validation passed */
2489
2490	icmp6len -= sizeof(*nd_rd);
2491	nd6_option_init(nd_rd + 1, icmp6len, &ndopts);
2492	if (nd6_options(&ndopts) < 0) {
2493		nd6log((LOG_INFO, "icmp6_redirect_input: "
2494			"invalid ND option, rejected: %s\n",
2495			icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2496		/* nd6_options have incremented stats */
2497		goto freeit;
2498	}
2499
2500	if (ndopts.nd_opts_tgt_lladdr) {
2501		lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
2502		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
2503	}
2504
2505	if (ndopts.nd_opts_rh) {
2506		redirhdrlen = ndopts.nd_opts_rh->nd_opt_rh_len;
2507		redirhdr = (u_char *)(ndopts.nd_opts_rh + 1); /* xxx */
2508	}
2509
2510	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
2511		nd6log((LOG_INFO,
2512			"icmp6_redirect_input: lladdrlen mismatch for %s "
2513			"(if %d, icmp6 packet %d): %s\n",
2514			ip6_sprintf(&redtgt6), ifp->if_addrlen, lladdrlen - 2,
2515			icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
2516		goto bad;
2517	}
2518
2519	/* RFC 2461 8.3 */
2520	nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT,
2521			 is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER);
2522
2523	if (!is_onlink) {	/* better router case.  perform rtredirect. */
2524		/* perform rtredirect */
2525		struct sockaddr_in6 sdst;
2526		struct sockaddr_in6 sgw;
2527		struct sockaddr_in6 ssrc;
2528
2529		bzero(&sdst, sizeof(sdst));
2530		bzero(&sgw, sizeof(sgw));
2531		bzero(&ssrc, sizeof(ssrc));
2532		sdst.sin6_family = sgw.sin6_family = ssrc.sin6_family = AF_INET6;
2533		sdst.sin6_len = sgw.sin6_len = ssrc.sin6_len =
2534			sizeof(struct sockaddr_in6);
2535		bcopy(&redtgt6, &sgw.sin6_addr, sizeof(struct in6_addr));
2536		bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr));
2537		bcopy(&src6, &ssrc.sin6_addr, sizeof(struct in6_addr));
2538		rtredirect(ifp, (struct sockaddr *)&sdst,
2539		    (struct sockaddr *)&sgw, NULL, RTF_GATEWAY | RTF_HOST,
2540		    (struct sockaddr *)&ssrc, NULL);
2541	}
2542	/* finally update cached route in each socket via pfctlinput */
2543    {
2544	struct sockaddr_in6 sdst;
2545
2546	bzero(&sdst, sizeof(sdst));
2547	sdst.sin6_family = AF_INET6;
2548	sdst.sin6_len = sizeof(struct sockaddr_in6);
2549	bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr));
2550
2551	pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&sdst);
2552#if IPSEC
2553	key_sa_routechange((struct sockaddr *)&sdst);
2554#endif
2555    }
2556
2557 freeit:
2558	m_freem(m);
2559	return;
2560
2561 bad:
2562	icmp6stat.icp6s_badredirect++;
2563	m_freem(m);
2564}
2565
2566void
2567icmp6_redirect_output(m0, rt)
2568	struct mbuf *m0;
2569	struct rtentry *rt;
2570{
2571	struct ifnet *ifp;	/* my outgoing interface */
2572	struct in6_addr ifp_ll6;
2573	struct in6_addr *router_ll6;
2574	struct ip6_hdr *sip6;	/* m0 as struct ip6_hdr */
2575	struct mbuf *m = NULL;	/* newly allocated one */
2576	struct ip6_hdr *ip6;	/* m as struct ip6_hdr */
2577	struct nd_redirect *nd_rd;
2578	size_t maxlen;
2579	u_char *p;
2580	struct ifnet *outif = NULL;
2581	struct sockaddr_in6 src_sa;
2582	struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 },
2583	    IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR, 0 };
2584
2585	icmp6_errcount(&icmp6stat.icp6s_outerrhist, ND_REDIRECT, 0);
2586
2587	if (rt != NULL)
2588		RT_LOCK(rt);
2589
2590	/* sanity check */
2591	if (!m0 || !rt || !(rt->rt_flags & RTF_UP) || !(ifp = rt->rt_ifp))
2592		goto fail;
2593
2594	/*
2595	 * If we are not a router to begin with, or not an advertising
2596	 * router on this interface, don't send icmp6 redirect.
2597	 */
2598	if (!ip6_forwarding || !(ifp->if_eflags & IFEF_IPV6_ROUTER))
2599		goto fail;
2600
2601	/*
2602	 * Address check:
2603	 *  the source address must identify a neighbor, and
2604	 *  the destination address must not be a multicast address
2605	 *  [RFC 2461, sec 8.2]
2606	 */
2607	sip6 = mtod(m0, struct ip6_hdr *);
2608	bzero(&src_sa, sizeof(src_sa));
2609	src_sa.sin6_family = AF_INET6;
2610	src_sa.sin6_len = sizeof(src_sa);
2611	src_sa.sin6_addr = sip6->ip6_src;
2612	/* we don't currently use sin6_scope_id, but eventually use it */
2613	src_sa.sin6_scope_id = in6_addr2scopeid(ifp, &sip6->ip6_src);
2614	RT_UNLOCK(rt);
2615	if (nd6_is_addr_neighbor(&src_sa, ifp, 0) == 0) {
2616		/* already unlocked */
2617		rt = NULL;
2618		goto fail;
2619	}
2620	RT_LOCK(rt);
2621	if (IN6_IS_ADDR_MULTICAST(&sip6->ip6_dst))
2622		goto fail;	/* what should we do here? */
2623
2624	/* rate limit */
2625	if (icmp6_ratelimit(&sip6->ip6_src, ND_REDIRECT, 0))
2626		goto fail;
2627
2628	/*
2629	 * Since we are going to append up to 1280 bytes (= IPV6_MMTU),
2630	 * we almost always ask for an mbuf cluster for simplicity.
2631	 * (MHLEN < IPV6_MMTU is almost always true)
2632	 */
2633#if IPV6_MMTU >= MCLBYTES
2634# error assumption failed about IPV6_MMTU and MCLBYTES
2635#endif
2636	MGETHDR(m, M_DONTWAIT, MT_HEADER);	/* MAC-OK */
2637	if (m && IPV6_MMTU >= MHLEN)
2638		MCLGET(m, M_DONTWAIT);
2639	if (!m)
2640		goto fail;
2641	m->m_pkthdr.rcvif = NULL;
2642	m->m_len = 0;
2643	maxlen = M_TRAILINGSPACE(m);
2644	maxlen = min(IPV6_MMTU, maxlen);
2645	/* just for safety */
2646	if (maxlen < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) +
2647	    ((sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7)) {
2648		goto fail;
2649	}
2650
2651	{
2652		/* get ip6 linklocal address for ifp(my outgoing interface). */
2653		struct in6_ifaddr *ia;
2654		if ((ia = in6ifa_ifpforlinklocal(ifp,
2655						 IN6_IFF_NOTREADY|
2656						 IN6_IFF_ANYCAST)) == NULL)
2657			goto fail;
2658		IFA_LOCK(&ia->ia_ifa);
2659		ifp_ll6 = ia->ia_addr.sin6_addr;
2660		IFA_UNLOCK(&ia->ia_ifa);
2661		IFA_REMREF(&ia->ia_ifa);
2662	}
2663
2664	/* get ip6 linklocal address for the router. */
2665	if (rt->rt_gateway && (rt->rt_flags & RTF_GATEWAY)) {
2666		struct sockaddr_in6 *sin6;
2667		sin6 = (struct sockaddr_in6 *)(void *)rt->rt_gateway;
2668		router_ll6 = &sin6->sin6_addr;
2669		if (!IN6_IS_ADDR_LINKLOCAL(router_ll6))
2670			router_ll6 = (struct in6_addr *)NULL;
2671	} else
2672		router_ll6 = (struct in6_addr *)NULL;
2673
2674	/* ip6 */
2675	ip6 = mtod(m, struct ip6_hdr *);
2676	ip6->ip6_flow = 0;
2677	ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
2678	ip6->ip6_vfc |= IPV6_VERSION;
2679	/* ip6->ip6_plen will be set later */
2680	ip6->ip6_nxt = IPPROTO_ICMPV6;
2681	ip6->ip6_hlim = 255;
2682	/* ip6->ip6_src must be linklocal addr for my outgoing if. */
2683	bcopy(&ifp_ll6, &ip6->ip6_src, sizeof(struct in6_addr));
2684	bcopy(&sip6->ip6_src, &ip6->ip6_dst, sizeof(struct in6_addr));
2685
2686	/* ND Redirect */
2687	nd_rd = (struct nd_redirect *)(ip6 + 1);
2688	nd_rd->nd_rd_type = ND_REDIRECT;
2689	nd_rd->nd_rd_code = 0;
2690	nd_rd->nd_rd_reserved = 0;
2691	if (rt->rt_flags & RTF_GATEWAY) {
2692		/*
2693		 * nd_rd->nd_rd_target must be a link-local address in
2694		 * better router cases.
2695		 */
2696		if (!router_ll6)
2697			goto fail;
2698		bcopy(router_ll6, &nd_rd->nd_rd_target,
2699		      sizeof(nd_rd->nd_rd_target));
2700		bcopy(&sip6->ip6_dst, &nd_rd->nd_rd_dst,
2701		      sizeof(nd_rd->nd_rd_dst));
2702	} else {
2703		/* make sure redtgt == reddst */
2704		bcopy(&sip6->ip6_dst, &nd_rd->nd_rd_target,
2705		      sizeof(nd_rd->nd_rd_target));
2706		bcopy(&sip6->ip6_dst, &nd_rd->nd_rd_dst,
2707		      sizeof(nd_rd->nd_rd_dst));
2708	}
2709	RT_UNLOCK(rt);
2710	rt = NULL;
2711
2712	p = (u_char *)(nd_rd + 1);
2713
2714	if (!router_ll6)
2715		goto nolladdropt;
2716
2717	{
2718		/* target lladdr option */
2719		struct rtentry *rt_router = NULL;
2720		int len;
2721		struct sockaddr_dl *sdl;
2722		struct nd_opt_hdr *nd_opt;
2723		char *lladdr;
2724
2725		/* Callee returns a locked route upon success */
2726		rt_router = nd6_lookup(router_ll6, 0, ifp, 0);
2727		if (!rt_router)
2728			goto nolladdropt;
2729		RT_LOCK_ASSERT_HELD(rt_router);
2730		len = sizeof(*nd_opt) + ifp->if_addrlen;
2731		len = (len + 7) & ~7;	/* round by 8 */
2732		/* safety check */
2733		if (len + (p - (u_char *)ip6) > maxlen) {
2734			RT_REMREF_LOCKED(rt_router);
2735			RT_UNLOCK(rt_router);
2736			goto nolladdropt;
2737		}
2738
2739		if (!(rt_router->rt_flags & RTF_GATEWAY) &&
2740			(rt_router->rt_flags & RTF_LLINFO) &&
2741			(rt_router->rt_gateway->sa_family == AF_LINK) &&
2742			(sdl = (struct sockaddr_dl *)(void *)
2743			rt_router->rt_gateway) && sdl->sdl_alen) {
2744				nd_opt = (struct nd_opt_hdr *)p;
2745				nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
2746				nd_opt->nd_opt_len = len >> 3;
2747				lladdr = (char *)(nd_opt + 1);
2748				bcopy(LLADDR(sdl), lladdr, ifp->if_addrlen);
2749				p += len;
2750		}
2751		RT_REMREF_LOCKED(rt_router);
2752		RT_UNLOCK(rt_router);
2753	}
2754
2755nolladdropt:;
2756
2757	m->m_pkthdr.len = m->m_len = p - (u_char *)ip6;
2758
2759	/* just to be safe */
2760#ifdef M_DECRYPTED	/*not openbsd*/
2761	if (m0->m_flags & M_DECRYPTED)
2762		goto noredhdropt;
2763#endif
2764	if (p - (u_char *)ip6 > maxlen)
2765		goto noredhdropt;
2766
2767    {
2768	/* redirected header option */
2769	int len;
2770	struct nd_opt_rd_hdr *nd_opt_rh;
2771
2772	/*
2773	 * compute the maximum size for icmp6 redirect header option.
2774	 * XXX room for auth header?
2775	 */
2776	len = maxlen - (p - (u_char *)ip6);
2777	len &= ~7;
2778
2779	/* This is just for simplicity. */
2780	if (m0->m_pkthdr.len != m0->m_len) {
2781		if (m0->m_next) {
2782			m_freem(m0->m_next);
2783			m0->m_next = NULL;
2784		}
2785		m0->m_pkthdr.len = m0->m_len;
2786	}
2787
2788	/*
2789	 * Redirected header option spec (RFC2461 4.6.3) talks nothing
2790	 * about padding/truncate rule for the original IP packet.
2791	 * From the discussion on IPv6imp in Feb 1999, the consensus was:
2792	 * - "attach as much as possible" is the goal
2793	 * - pad if not aligned (original size can be guessed by original
2794	 *   ip6 header)
2795	 * Following code adds the padding if it is simple enough,
2796	 * and truncates if not.
2797	 */
2798	if (m0->m_next || m0->m_pkthdr.len != m0->m_len)
2799		panic("assumption failed in %s:%d\n", __FILE__, __LINE__);
2800
2801	if (len - sizeof(*nd_opt_rh) < m0->m_pkthdr.len) {
2802		/* not enough room, truncate */
2803		m0->m_pkthdr.len = m0->m_len = len - sizeof(*nd_opt_rh);
2804	} else {
2805		/* enough room, pad or truncate */
2806		size_t extra;
2807
2808		extra = m0->m_pkthdr.len % 8;
2809		if (extra) {
2810			/* pad if easy enough, truncate if not */
2811			if (8 - extra <= M_TRAILINGSPACE(m0)) {
2812				/* pad */
2813				m0->m_len += (8 - extra);
2814				m0->m_pkthdr.len += (8 - extra);
2815			} else {
2816				/* truncate */
2817				m0->m_pkthdr.len -= extra;
2818				m0->m_len -= extra;
2819			}
2820		}
2821		len = m0->m_pkthdr.len + sizeof(*nd_opt_rh);
2822		m0->m_pkthdr.len = m0->m_len = len - sizeof(*nd_opt_rh);
2823	}
2824
2825	nd_opt_rh = (struct nd_opt_rd_hdr *)p;
2826	bzero(nd_opt_rh, sizeof(*nd_opt_rh));
2827	nd_opt_rh->nd_opt_rh_type = ND_OPT_REDIRECTED_HEADER;
2828	nd_opt_rh->nd_opt_rh_len = len >> 3;
2829	p += sizeof(*nd_opt_rh);
2830	m->m_pkthdr.len = m->m_len = p - (u_char *)ip6;
2831
2832	/* connect m0 to m */
2833	m->m_next = m0;
2834	m->m_pkthdr.len = m->m_len + m0->m_len;
2835    }
2836noredhdropt:;
2837
2838	/* XXX: clear embedded link IDs in the inner header */
2839	in6_clearscope(&sip6->ip6_src);
2840	in6_clearscope(&sip6->ip6_dst);
2841	in6_clearscope(&nd_rd->nd_rd_target);
2842	in6_clearscope(&nd_rd->nd_rd_dst);
2843
2844	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
2845
2846	nd_rd->nd_rd_cksum = 0;
2847	nd_rd->nd_rd_cksum
2848		= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), ntohs(ip6->ip6_plen));
2849
2850	/* send the packet to outside... */
2851	ip6oa.ip6oa_boundif = ifp->if_index;
2852	ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
2853
2854	ip6_output(m, NULL, NULL, IPV6_OUTARGS, NULL, &outif, &ip6oa);
2855	if (outif) {
2856		icmp6_ifstat_inc(outif, ifs6_out_msg);
2857		icmp6_ifstat_inc(outif, ifs6_out_redirect);
2858		ifnet_release(outif);
2859	}
2860	icmp6stat.icp6s_outhist[ND_REDIRECT]++;
2861
2862	return;
2863
2864fail:
2865	if (rt != NULL)
2866		RT_UNLOCK(rt);
2867	if (m)
2868		m_freem(m);
2869	if (m0)
2870		m_freem(m0);
2871}
2872
2873/*
2874 * ICMPv6 socket option processing.
2875 */
2876int
2877icmp6_ctloutput(so, sopt)
2878	struct socket *so;
2879	struct sockopt *sopt;
2880{
2881	int error = 0;
2882	int optlen;
2883	struct inpcb *inp = sotoinpcb(so);
2884	int level, op, optname;
2885
2886	if (sopt) {
2887		level = sopt->sopt_level;
2888		op = sopt->sopt_dir;
2889		optname = sopt->sopt_name;
2890		optlen = sopt->sopt_valsize;
2891	} else
2892		level = op = optname = optlen = 0;
2893
2894	if (level != IPPROTO_ICMPV6) {
2895		return EINVAL;
2896	}
2897
2898	switch (op) {
2899	case PRCO_SETOPT:
2900		switch (optname) {
2901		case ICMP6_FILTER:
2902		    {
2903			struct icmp6_filter *p;
2904
2905			if (optlen != 0 && optlen != sizeof(*p)) {
2906				error = EMSGSIZE;
2907				break;
2908			}
2909			if (inp->in6p_icmp6filt == NULL) {
2910				error = EINVAL;
2911				break;
2912			}
2913
2914			if (optlen == 0) {
2915				/* According to RFC 3542, an installed filter can be
2916				 * cleared by issuing a setsockopt for ICMP6_FILTER
2917				 * with a zero length.
2918				 */
2919				ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt);
2920			} else {
2921				error = sooptcopyin(sopt, inp->in6p_icmp6filt, optlen,
2922					optlen);
2923			}
2924			break;
2925		    }
2926
2927		default:
2928			error = ENOPROTOOPT;
2929			break;
2930		}
2931		break;
2932
2933	case PRCO_GETOPT:
2934		switch (optname) {
2935		case ICMP6_FILTER:
2936		    {
2937			if (inp->in6p_icmp6filt == NULL) {
2938				error = EINVAL;
2939				break;
2940			}
2941			error = sooptcopyout(sopt, inp->in6p_icmp6filt,
2942					min(sizeof(struct icmp6_filter), optlen));
2943			break;
2944		    }
2945
2946		default:
2947			error = ENOPROTOOPT;
2948			break;
2949		}
2950		break;
2951	}
2952
2953	return(error);
2954}
2955
2956/*
2957 * ICMPv6 socket datagram option processing.
2958 */
2959int
2960icmp6_dgram_ctloutput(struct socket *so, struct sockopt *sopt)
2961{
2962	if (kauth_cred_issuser(so->so_cred))
2963		return icmp6_ctloutput(so, sopt);
2964
2965	if (sopt->sopt_level == IPPROTO_ICMPV6) {
2966		switch (sopt->sopt_name) {
2967			case ICMP6_FILTER:
2968				return icmp6_ctloutput(so, sopt);
2969			default:
2970				return EPERM;
2971		}
2972	}
2973
2974	if (sopt->sopt_level != IPPROTO_IPV6)
2975		return EINVAL;
2976
2977	switch (sopt->sopt_name) {
2978		case IPV6_UNICAST_HOPS:
2979		case IPV6_CHECKSUM:
2980		case IPV6_V6ONLY:
2981		case IPV6_USE_MIN_MTU:
2982		case IPV6_RECVRTHDR:
2983		case IPV6_RECVPKTINFO:
2984		case IPV6_RECVHOPLIMIT:
2985		case IPV6_PATHMTU:
2986		case IPV6_PKTINFO:
2987		case IPV6_HOPLIMIT:
2988		case IPV6_HOPOPTS:
2989		case IPV6_DSTOPTS:
2990		case IPV6_MULTICAST_IF:
2991		case IPV6_MULTICAST_HOPS:
2992		case IPV6_MULTICAST_LOOP:
2993		case IPV6_JOIN_GROUP:
2994		case IPV6_LEAVE_GROUP:
2995		case IPV6_PORTRANGE:
2996		case IPV6_IPSEC_POLICY:
2997		case IPV6_RECVTCLASS:
2998		case IPV6_TCLASS:
2999		case IPV6_2292PKTOPTIONS:
3000		case IPV6_2292PKTINFO:
3001		case IPV6_2292HOPLIMIT:
3002		case IPV6_2292HOPOPTS:
3003		case IPV6_2292DSTOPTS:
3004		case IPV6_2292RTHDR:
3005		case IPV6_BOUND_IF:
3006		case IPV6_NO_IFT_CELLULAR:
3007
3008			return ip6_ctloutput(so, sopt);
3009
3010		default:
3011			return EPERM;
3012	}
3013}
3014
3015__private_extern__ int
3016icmp6_dgram_send(struct socket *so, int flags, struct mbuf *m,
3017    struct sockaddr *nam, struct mbuf *control, struct proc *p)
3018{
3019#pragma unused(flags, p)
3020	int error = 0;
3021	struct inpcb *inp = sotoinpcb(so);
3022	struct sockaddr_in6 tmp;
3023	struct sockaddr_in6 *dst = (struct sockaddr_in6 *)(void *)nam;
3024	struct icmp6_hdr *icmp6;
3025
3026	if (inp == NULL
3027#if NECP
3028		|| (necp_socket_should_use_flow_divert(inp))
3029#endif /* NECP */
3030		) {
3031		error = (inp == NULL ? EINVAL : EPROTOTYPE);
3032		goto bad;
3033	}
3034
3035	if (kauth_cred_issuser(so->so_cred))
3036		return (rip6_output(m, so, SIN6(nam), control, 0));
3037
3038	/* always copy sockaddr to avoid overwrites */
3039	if (so->so_state & SS_ISCONNECTED) {
3040		if (nam != NULL) {
3041			error = EISCONN;
3042			goto bad;
3043		}
3044		/* XXX */
3045		bzero(&tmp, sizeof(tmp));
3046		tmp.sin6_family = AF_INET6;
3047		tmp.sin6_len = sizeof(struct sockaddr_in6);
3048		bcopy(&inp->in6p_faddr, &tmp.sin6_addr,
3049			  sizeof(struct in6_addr));
3050		dst = &tmp;
3051	} else {
3052		if (nam == NULL) {
3053			error = ENOTCONN;
3054			goto bad;
3055		}
3056		tmp = *(struct sockaddr_in6 *)(void *)nam;
3057		dst = &tmp;
3058	}
3059
3060	/*
3061	 * For an ICMPv6 packet, we should know its type and code
3062	 */
3063	if (SOCK_PROTO(so) == IPPROTO_ICMPV6) {
3064		if (m->m_len < sizeof(struct icmp6_hdr) &&
3065			(m = m_pullup(m, sizeof(struct icmp6_hdr))) == NULL) {
3066				error = ENOBUFS;
3067				goto bad;
3068		}
3069		icmp6 = mtod(m, struct icmp6_hdr *);
3070
3071		/*
3072		 * Allow only to send echo request and node information request
3073		 * See RFC 2463 for Echo Request Message format
3074		 */
3075		if ((icmp6->icmp6_type == ICMP6_ECHO_REQUEST &&
3076		    icmp6->icmp6_code == 0) ||
3077		    (icmp6->icmp6_type == ICMP6_NI_QUERY &&
3078		    (icmp6->icmp6_code == ICMP6_NI_SUBJ_IPV6 ||
3079		    icmp6->icmp6_code == ICMP6_NI_SUBJ_FQDN))) {
3080			/* Good */
3081			;
3082		} else {
3083			error = EPERM;
3084			goto bad;
3085		}
3086	}
3087
3088#if ENABLE_DEFAULT_SCOPE
3089	if (dst->sin6_scope_id == 0) {  /* not change if specified  */
3090		dst->sin6_scope_id = scope6_addr2default(&dst->sin6_addr);
3091	}
3092#endif
3093
3094	return (rip6_output(m, so, dst, control, 0));
3095bad:
3096	VERIFY(error != 0);
3097
3098	if (m != NULL)
3099		m_freem(m);
3100	if (control != NULL)
3101		m_freem(control);
3102
3103	return (error);
3104}
3105
3106/* Like rip6_attach but without root privilege enforcement */
3107__private_extern__ int
3108icmp6_dgram_attach(struct socket *so, int proto, struct proc *p)
3109{
3110        struct inpcb *inp;
3111        int error;
3112
3113        inp = sotoinpcb(so);
3114        if (inp)
3115                panic("icmp6_dgram_attach");
3116
3117		if (proto != IPPROTO_ICMPV6)
3118			return EINVAL;
3119
3120        error = soreserve(so, rip_sendspace, rip_recvspace);
3121        if (error)
3122                return error;
3123        error = in_pcballoc(so, &ripcbinfo, p);
3124        if (error)
3125                return error;
3126        inp = (struct inpcb *)so->so_pcb;
3127        inp->inp_vflag |= INP_IPV6;
3128        inp->in6p_ip6_nxt = IPPROTO_ICMPV6;
3129        inp->in6p_hops = -1;    /* use kernel default */
3130        inp->in6p_cksum = -1;
3131        MALLOC(inp->in6p_icmp6filt, struct icmp6_filter *,
3132               sizeof(struct icmp6_filter), M_PCB, M_WAITOK);
3133        if (inp->in6p_icmp6filt == NULL)
3134                return (ENOMEM);
3135        ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt);
3136        return 0;
3137}
3138
3139
3140/*
3141 * Perform rate limit check.
3142 * Returns 0 if it is okay to send the icmp6 packet.
3143 * Returns 1 if the router SHOULD NOT send this icmp6 packet due to rate
3144 * limitation.
3145 *
3146 * XXX per-destination check necessary?
3147 */
3148static int
3149icmp6_ratelimit(
3150	__unused const struct in6_addr *dst,	/* not used at this moment */
3151	const int type,
3152	__unused const int code)
3153{
3154	int ret;
3155
3156	ret = 0;	/* okay to send */
3157
3158	/* PPS limit */
3159	if (type == ND_ROUTER_ADVERT) {
3160		if (!ppsratecheck(&icmp6rappslim_last, &icmp6rapps_count,
3161		    icmp6rappslim))
3162			ret++;
3163	} else if (!ppsratecheck(&icmp6errppslim_last, &icmp6errpps_count,
3164	    icmp6errppslim)) {
3165		/* The packet is subject to rate limit */
3166		ret++;
3167	}
3168
3169	return ret;
3170}
3171