xref: /openbsd-src/sys/netinet6/ip6_input.c (revision 6f05df2d9be0954bec42d51d943d77bd250fb664)
1 /*	$OpenBSD: ip6_input.c,v 1.132 2014/11/20 13:54:24 mpi Exp $	*/
2 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1982, 1986, 1988, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)ip_input.c	8.2 (Berkeley) 1/4/94
62  */
63 
64 #include "pf.h"
65 #include "carp.h"
66 
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/mbuf.h>
70 #include <sys/domain.h>
71 #include <sys/sysctl.h>
72 #include <sys/protosw.h>
73 #include <sys/socket.h>
74 #include <sys/socketvar.h>
75 #include <sys/errno.h>
76 #include <sys/time.h>
77 #include <sys/timeout.h>
78 #include <sys/kernel.h>
79 #include <sys/syslog.h>
80 
81 #include <net/if.h>
82 #include <net/if_types.h>
83 #include <net/if_dl.h>
84 #include <net/route.h>
85 #include <net/netisr.h>
86 
87 #include <netinet/in.h>
88 
89 #ifdef INET
90 #include <netinet/ip.h>
91 #endif
92 
93 #include <netinet/in_pcb.h>
94 #include <netinet6/in6_var.h>
95 #include <netinet/ip6.h>
96 #include <netinet6/ip6_var.h>
97 #include <netinet/icmp6.h>
98 #include <netinet6/in6_ifattach.h>
99 #include <netinet6/nd6.h>
100 
101 #include <netinet6/ip6protosw.h>
102 
103 #include "gif.h"
104 #include "bpfilter.h"
105 
106 #ifdef MROUTING
107 #include <netinet6/ip6_mroute.h>
108 #endif
109 
110 #if NPF > 0
111 #include <net/pfvar.h>
112 #endif
113 
114 #if NCARP > 0
115 #include <netinet/ip_carp.h>
116 #endif
117 
118 struct in6_ifaddrhead in6_ifaddr;
119 struct ifqueue ip6intrq;
120 
121 struct ip6stat ip6stat;
122 
123 void ip6_init2(void *);
124 int ip6_check_rh0hdr(struct mbuf *, int *);
125 
126 int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
127 struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
128 
129 /*
130  * IP6 initialization: fill in IP6 protocol switch table.
131  * All protocols not implemented in kernel go to raw IP6 protocol handler.
132  */
133 void
134 ip6_init(void)
135 {
136 	struct ip6protosw *pr;
137 	int i;
138 
139 	pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
140 	if (pr == 0)
141 		panic("ip6_init");
142 	for (i = 0; i < IPPROTO_MAX; i++)
143 		ip6_protox[i] = pr - inet6sw;
144 	for (pr = (struct ip6protosw *)inet6domain.dom_protosw;
145 	    pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++)
146 		if (pr->pr_domain->dom_family == PF_INET6 &&
147 		    pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW &&
148 		    pr->pr_protocol < IPPROTO_MAX)
149 			ip6_protox[pr->pr_protocol] = pr - inet6sw;
150 	IFQ_SET_MAXLEN(&ip6intrq, IFQ_MAXLEN);
151 	TAILQ_INIT(&in6_ifaddr);
152 	ip6_randomid_init();
153 	nd6_init();
154 	frag6_init();
155 	ip6_init2((void *)0);
156 }
157 
158 void
159 ip6_init2(void *dummy)
160 {
161 
162 	/* nd6_timer_init */
163 	bzero(&nd6_timer_ch, sizeof(nd6_timer_ch));
164 	timeout_set(&nd6_timer_ch, nd6_timer, NULL);
165 	timeout_add_sec(&nd6_timer_ch, 1);
166 }
167 
168 /*
169  * IP6 input interrupt handling. Just pass the packet to ip6_input.
170  */
171 void
172 ip6intr(void)
173 {
174 	int s;
175 	struct mbuf *m;
176 
177 	for (;;) {
178 		s = splnet();
179 		IF_DEQUEUE(&ip6intrq, m);
180 		splx(s);
181 		if (m == NULL)
182 			return;
183 		ip6_input(m);
184 	}
185 }
186 
187 extern struct	route_in6 ip6_forward_rt;
188 
189 void
190 ip6_input(struct mbuf *m)
191 {
192 	struct ifnet *ifp;
193 	struct ip6_hdr *ip6;
194 	int off, nest;
195 	u_int32_t plen;
196 	u_int32_t rtalert = ~0;
197 	int nxt, ours = 0;
198 	struct ifnet *deliverifp = NULL;
199 #if NPF > 0
200 	struct in6_addr odst;
201 #endif
202 	int srcrt = 0, isanycast = 0;
203 	u_int rtableid = 0;
204 
205 	ifp = m->m_pkthdr.rcvif;
206 
207 	if (m->m_flags & M_EXT) {
208 		if (m->m_next)
209 			ip6stat.ip6s_mext2m++;
210 		else
211 			ip6stat.ip6s_mext1++;
212 	} else {
213 		if (m->m_next) {
214 			if (m->m_flags & M_LOOP) {
215 				ip6stat.ip6s_m2m[lo0ifp->if_index]++;	/*XXX*/
216 			} else if (ifp->if_index < nitems(ip6stat.ip6s_m2m))
217 				ip6stat.ip6s_m2m[ifp->if_index]++;
218 			else
219 				ip6stat.ip6s_m2m[0]++;
220 		} else
221 			ip6stat.ip6s_m1++;
222 	}
223 
224 	in6_ifstat_inc(ifp, ifs6_in_receive);
225 	ip6stat.ip6s_total++;
226 
227 	if (m->m_len < sizeof(struct ip6_hdr)) {
228 		if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
229 			ip6stat.ip6s_toosmall++;
230 			in6_ifstat_inc(ifp, ifs6_in_hdrerr);
231 			return;
232 		}
233 	}
234 
235 	ip6 = mtod(m, struct ip6_hdr *);
236 
237 	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
238 		ip6stat.ip6s_badvers++;
239 		in6_ifstat_inc(ifp, ifs6_in_hdrerr);
240 		goto bad;
241 	}
242 
243 #if NCARP > 0
244 	if (ifp->if_type == IFT_CARP && ip6->ip6_nxt != IPPROTO_ICMPV6 &&
245 	    carp_lsdrop(m, AF_INET6, ip6->ip6_src.s6_addr32,
246 	    ip6->ip6_dst.s6_addr32))
247 		goto bad;
248 #endif
249 	ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
250 
251 	/*
252 	 * Check against address spoofing/corruption.
253 	 */
254 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
255 	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
256 		/*
257 		 * XXX: "badscope" is not very suitable for a multicast source.
258 		 */
259 		ip6stat.ip6s_badscope++;
260 		in6_ifstat_inc(ifp, ifs6_in_addrerr);
261 		goto bad;
262 	}
263 	if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
264 	    IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) &&
265 	    (ifp->if_flags & IFF_LOOPBACK) == 0) {
266 		    ip6stat.ip6s_badscope++;
267 		    in6_ifstat_inc(ifp, ifs6_in_addrerr);
268 		    goto bad;
269 	}
270 	/* Drop packets if interface ID portion is already filled. */
271 	if (((IN6_IS_SCOPE_EMBED(&ip6->ip6_src) && ip6->ip6_src.s6_addr16[1]) ||
272 	    (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst) && ip6->ip6_dst.s6_addr16[1])) &&
273 	    (ifp->if_flags & IFF_LOOPBACK) == 0) {
274 		ip6stat.ip6s_badscope++;
275 		goto bad;
276 	}
277 	if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) &&
278 	    !(m->m_flags & M_LOOP)) {
279 		/*
280 		 * In this case, the packet should come from the loopback
281 		 * interface.  However, we cannot just check the if_flags,
282 		 * because ip6_mloopback() passes the "actual" interface
283 		 * as the outgoing/incoming interface.
284 		 */
285 		ip6stat.ip6s_badscope++;
286 		in6_ifstat_inc(ifp, ifs6_in_addrerr);
287 		goto bad;
288 	}
289 
290 	/*
291 	 * The following check is not documented in specs.  A malicious
292 	 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
293 	 * and bypass security checks (act as if it was from 127.0.0.1 by using
294 	 * IPv6 src ::ffff:127.0.0.1).  Be cautious.
295 	 *
296 	 * This check chokes if we are in an SIIT cloud.  As none of BSDs
297 	 * support IPv4-less kernel compilation, we cannot support SIIT
298 	 * environment at all.  So, it makes more sense for us to reject any
299 	 * malicious packets for non-SIIT environment, than try to do a
300 	 * partial support for SIIT environment.
301 	 */
302 	if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
303 	    IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
304 		ip6stat.ip6s_badscope++;
305 		in6_ifstat_inc(ifp, ifs6_in_addrerr);
306 		goto bad;
307 	}
308 #if 0
309 	/*
310 	 * Reject packets with IPv4 compatible addresses (auto tunnel).
311 	 *
312 	 * The code forbids auto tunnel relay case in RFC1933 (the check is
313 	 * stronger than RFC1933).  We may want to re-enable it if mech-xx
314 	 * is revised to forbid relaying case.
315 	 */
316 	if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
317 	    IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
318 		ip6stat.ip6s_badscope++;
319 		in6_ifstat_inc(ifp, ifs6_in_addrerr);
320 		goto bad;
321 	}
322 #endif
323 
324 	/*
325 	 * If the packet has been received on a loopback interface it
326 	 * can be destinated to any local address, not necessarily to
327 	 * an address configured on `ifp'.
328 	 */
329 	if ((ifp->if_flags & IFF_LOOPBACK) == 0) {
330 		if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
331 			ip6->ip6_src.s6_addr16[1] = htons(ifp->if_index);
332 		if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
333 			ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index);
334 	}
335 
336 #if NPF > 0
337         /*
338          * Packet filter
339          */
340 	odst = ip6->ip6_dst;
341 	if (pf_test(AF_INET6, PF_IN, ifp, &m, NULL) != PF_PASS)
342 		goto bad;
343 	if (m == NULL)
344 		return;
345 
346 	ip6 = mtod(m, struct ip6_hdr *);
347 	srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
348 #endif
349 
350 	/*
351 	 * Be more secure than RFC5095 and scan for type 0 routing headers.
352 	 * If pf has already scanned the header chain, do not do it twice.
353 	 */
354 	if (!(m->m_pkthdr.pf.flags & PF_TAG_PROCESSED) &&
355 	    ip6_check_rh0hdr(m, &off)) {
356 		ip6stat.ip6s_badoptions++;
357 		in6_ifstat_inc(ifp, ifs6_in_discard);
358 		in6_ifstat_inc(ifp, ifs6_in_hdrerr);
359 		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, off);
360 		/* m is already freed */
361 		return;
362 	}
363 
364 	if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
365 	    IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) {
366 		ours = 1;
367 		deliverifp = ifp;
368 		goto hbhcheck;
369 	}
370 
371 	if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
372 		ours = 1;
373 		deliverifp = ifp;
374 		goto hbhcheck;
375 	}
376 
377 	/*
378 	 * Multicast check
379 	 */
380 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
381 	  	struct	in6_multi *in6m = 0;
382 
383 		/*
384 		 * Make sure M_MCAST is set.  It should theoretically
385 		 * already be there, but let's play safe because upper
386 		 * layers check for this flag.
387 		 */
388 		m->m_flags |= M_MCAST;
389 
390 		in6_ifstat_inc(ifp, ifs6_in_mcast);
391 		/*
392 		 * See if we belong to the destination multicast group on the
393 		 * arrival interface.
394 		 */
395 		IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
396 		if (in6m)
397 			ours = 1;
398 #ifdef MROUTING
399 		else if (!ip6_mforwarding || !ip6_mrouter)
400 #else
401 		else
402 #endif
403 		{
404 			ip6stat.ip6s_notmember++;
405 			if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst))
406 				ip6stat.ip6s_cantforward++;
407 			in6_ifstat_inc(ifp, ifs6_in_discard);
408 			goto bad;
409 		}
410 		deliverifp = ifp;
411 		goto hbhcheck;
412 	}
413 
414 #if NPF > 0
415 	rtableid = m->m_pkthdr.ph_rtableid;
416 #endif
417 
418 	/*
419 	 *  Unicast check
420 	 */
421 	if (ip6_forward_rt.ro_rt != NULL &&
422 	    (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 &&
423 	    IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
424 			       &ip6_forward_rt.ro_dst.sin6_addr) &&
425 	    rtableid == ip6_forward_rt.ro_tableid)
426 		ip6stat.ip6s_forward_cachehit++;
427 	else {
428 		if (ip6_forward_rt.ro_rt) {
429 			/* route is down or destination is different */
430 			ip6stat.ip6s_forward_cachemiss++;
431 			rtfree(ip6_forward_rt.ro_rt);
432 			ip6_forward_rt.ro_rt = NULL;
433 		}
434 
435 		bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
436 		ip6_forward_rt.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
437 		ip6_forward_rt.ro_dst.sin6_family = AF_INET6;
438 		ip6_forward_rt.ro_dst.sin6_addr = ip6->ip6_dst;
439 		ip6_forward_rt.ro_tableid = rtableid;
440 
441 		ip6_forward_rt.ro_rt = rtalloc_mpath(
442 		    sin6tosa(&ip6_forward_rt.ro_dst),
443 		    &ip6->ip6_src.s6_addr32[0],
444 		    ip6_forward_rt.ro_tableid);
445 	}
446 
447 	/*
448 	 * Accept the packet if the route to the destination is marked
449 	 * as local.
450 	 */
451 	if (ip6_forward_rt.ro_rt &&
452 	    ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_LOCAL)) {
453 		struct in6_ifaddr *ia6 =
454 			ifatoia6(ip6_forward_rt.ro_rt->rt_ifa);
455 		if (ia6->ia6_flags & IN6_IFF_ANYCAST)
456 			isanycast = 1;
457 		/*
458 		 * packets to a tentative, duplicated, or somehow invalid
459 		 * address must not be accepted.
460 		 */
461 		if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
462 			/* this address is ready */
463 			ours = 1;
464 			deliverifp = ia6->ia_ifp;	/* correct? */
465 			goto hbhcheck;
466 		} else {
467 			char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
468 
469 			inet_ntop(AF_INET6, &ip6->ip6_src, src, sizeof(src));
470 			inet_ntop(AF_INET6, &ip6->ip6_dst, dst, sizeof(dst));
471 			/* address is not ready, so discard the packet. */
472 			nd6log((LOG_INFO,
473 			    "ip6_input: packet to an unready address %s->%s\n",
474 			    src, dst));
475 
476 			goto bad;
477 		}
478 	}
479 
480 #if NCARP > 0
481 	if (ifp->if_type == IFT_CARP && ip6->ip6_nxt == IPPROTO_ICMPV6 &&
482 	    carp_lsdrop(m, AF_INET6, ip6->ip6_src.s6_addr32,
483 	    ip6->ip6_dst.s6_addr32))
484 		goto bad;
485 #endif
486 	/*
487 	 * Now there is no reason to process the packet if it's not our own
488 	 * and we're not a router.
489 	 */
490 	if (!ip6_forwarding) {
491 		ip6stat.ip6s_cantforward++;
492 		in6_ifstat_inc(ifp, ifs6_in_discard);
493 		goto bad;
494 	}
495 
496   hbhcheck:
497 	/*
498 	 * Process Hop-by-Hop options header if it's contained.
499 	 * m may be modified in ip6_hopopts_input().
500 	 * If a JumboPayload option is included, plen will also be modified.
501 	 */
502 	plen = (u_int32_t)ntohs(ip6->ip6_plen);
503 	off = sizeof(struct ip6_hdr);
504 	if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
505 		struct ip6_hbh *hbh;
506 
507 		if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
508 #if 0	/*touches NULL pointer*/
509 			in6_ifstat_inc(ifp, ifs6_in_discard);
510 #endif
511 			return;	/* m have already been freed */
512 		}
513 
514 		/* adjust pointer */
515 		ip6 = mtod(m, struct ip6_hdr *);
516 
517 		/*
518 		 * if the payload length field is 0 and the next header field
519 		 * indicates Hop-by-Hop Options header, then a Jumbo Payload
520 		 * option MUST be included.
521 		 */
522 		if (ip6->ip6_plen == 0 && plen == 0) {
523 			/*
524 			 * Note that if a valid jumbo payload option is
525 			 * contained, ip6_hoptops_input() must set a valid
526 			 * (non-zero) payload length to the variable plen.
527 			 */
528 			ip6stat.ip6s_badoptions++;
529 			in6_ifstat_inc(ifp, ifs6_in_discard);
530 			in6_ifstat_inc(ifp, ifs6_in_hdrerr);
531 			icmp6_error(m, ICMP6_PARAM_PROB,
532 				    ICMP6_PARAMPROB_HEADER,
533 				    (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
534 			return;
535 		}
536 		IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
537 			sizeof(struct ip6_hbh));
538 		if (hbh == NULL) {
539 			ip6stat.ip6s_tooshort++;
540 			return;
541 		}
542 		nxt = hbh->ip6h_nxt;
543 
544 		/*
545 		 * accept the packet if a router alert option is included
546 		 * and we act as an IPv6 router.
547 		 */
548 		if (rtalert != ~0 && ip6_forwarding)
549 			ours = 1;
550 	} else
551 		nxt = ip6->ip6_nxt;
552 
553 	/*
554 	 * Check that the amount of data in the buffers
555 	 * is as at least much as the IPv6 header would have us expect.
556 	 * Trim mbufs if longer than we expect.
557 	 * Drop packet if shorter than we expect.
558 	 */
559 	if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
560 		ip6stat.ip6s_tooshort++;
561 		in6_ifstat_inc(ifp, ifs6_in_truncated);
562 		goto bad;
563 	}
564 	if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
565 		if (m->m_len == m->m_pkthdr.len) {
566 			m->m_len = sizeof(struct ip6_hdr) + plen;
567 			m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
568 		} else
569 			m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
570 	}
571 
572 	/*
573 	 * Forward if desirable.
574 	 */
575 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
576 		/*
577 		 * If we are acting as a multicast router, all
578 		 * incoming multicast packets are passed to the
579 		 * kernel-level multicast forwarding function.
580 		 * The packet is returned (relatively) intact; if
581 		 * ip6_mforward() returns a non-zero value, the packet
582 		 * must be discarded, else it may be accepted below.
583 		 */
584 #ifdef MROUTING
585 		if (ip6_mforwarding && ip6_mrouter &&
586 		    ip6_mforward(ip6, ifp, m)) {
587 			ip6stat.ip6s_cantforward++;
588 			m_freem(m);
589 			return;
590 		}
591 #endif
592 		if (!ours) {
593 			m_freem(m);
594 			return;
595 		}
596 	} else if (!ours) {
597 		ip6_forward(m, srcrt);
598 		return;
599 	}
600 
601 	/* pf might have changed things */
602 	in6_proto_cksum_out(m, NULL);
603 
604 	ip6 = mtod(m, struct ip6_hdr *);
605 
606 	/*
607 	 * Malicious party may be able to use IPv4 mapped addr to confuse
608 	 * tcp/udp stack and bypass security checks (act as if it was from
609 	 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1).  Be cautious.
610 	 *
611 	 * For SIIT end node behavior, you may want to disable the check.
612 	 * However, you will  become vulnerable to attacks using IPv4 mapped
613 	 * source.
614 	 */
615 	if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
616 	    IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
617 		ip6stat.ip6s_badscope++;
618 		in6_ifstat_inc(ifp, ifs6_in_addrerr);
619 		goto bad;
620 	}
621 
622 	/*
623 	 * Tell launch routine the next header
624 	 */
625 	ip6stat.ip6s_delivered++;
626 	in6_ifstat_inc(deliverifp, ifs6_in_deliver);
627 	nest = 0;
628 
629 	while (nxt != IPPROTO_DONE) {
630 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
631 			ip6stat.ip6s_toomanyhdr++;
632 			goto bad;
633 		}
634 
635 		/*
636 		 * protection against faulty packet - there should be
637 		 * more sanity checks in header chain processing.
638 		 */
639 		if (m->m_pkthdr.len < off) {
640 			ip6stat.ip6s_tooshort++;
641 			in6_ifstat_inc(ifp, ifs6_in_truncated);
642 			goto bad;
643 		}
644 
645 		/* draft-itojun-ipv6-tcp-to-anycast */
646 		if (isanycast && nxt == IPPROTO_TCP) {
647 			if (m->m_len >= sizeof(struct ip6_hdr)) {
648 				ip6 = mtod(m, struct ip6_hdr *);
649 				icmp6_error(m, ICMP6_DST_UNREACH,
650 					ICMP6_DST_UNREACH_ADDR,
651 					(caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
652 				break;
653 			} else
654 				goto bad;
655 		}
656 
657 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
658 	}
659 	return;
660  bad:
661 	m_freem(m);
662 }
663 
664 /* scan packet for RH0 routing header. Mostly stolen from pf.c:pf_test() */
665 int
666 ip6_check_rh0hdr(struct mbuf *m, int *offp)
667 {
668 	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
669 	struct ip6_rthdr rthdr;
670 	struct ip6_ext opt6;
671 	u_int8_t proto = ip6->ip6_nxt;
672 	int done = 0, lim, off, rh_cnt = 0;
673 
674 	off = ((caddr_t)ip6 - m->m_data) + sizeof(struct ip6_hdr);
675 	lim = min(m->m_pkthdr.len, ntohs(ip6->ip6_plen) + sizeof(*ip6));
676 	do {
677 		switch (proto) {
678 		case IPPROTO_ROUTING:
679 			*offp = off;
680 			if (rh_cnt++) {
681 				/* more then one rh header present */
682 				return (1);
683 			}
684 
685 			if (off + sizeof(rthdr) > lim) {
686 				/* packet to short to make sense */
687 				return (1);
688 			}
689 
690 			m_copydata(m, off, sizeof(rthdr), (caddr_t)&rthdr);
691 
692 			if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
693 				*offp += offsetof(struct ip6_rthdr, ip6r_type);
694 				return (1);
695 			}
696 
697 			off += (rthdr.ip6r_len + 1) * 8;
698 			proto = rthdr.ip6r_nxt;
699 			break;
700 		case IPPROTO_AH:
701 		case IPPROTO_HOPOPTS:
702 		case IPPROTO_DSTOPTS:
703 			/* get next header and header length */
704 			if (off + sizeof(opt6) > lim) {
705 				/*
706 				 * Packet to short to make sense, we could
707 				 * reject the packet but as a router we
708 				 * should not do that so forward it.
709 				 */
710 				return (0);
711 			}
712 
713 			m_copydata(m, off, sizeof(opt6), (caddr_t)&opt6);
714 
715 			if (proto == IPPROTO_AH)
716 				off += (opt6.ip6e_len + 2) * 4;
717 			else
718 				off += (opt6.ip6e_len + 1) * 8;
719 			proto = opt6.ip6e_nxt;
720 			break;
721 		case IPPROTO_FRAGMENT:
722 		default:
723 			/* end of header stack */
724 			done = 1;
725 			break;
726 		}
727 	} while (!done);
728 
729 	return (0);
730 }
731 
732 /*
733  * Hop-by-Hop options header processing. If a valid jumbo payload option is
734  * included, the real payload length will be stored in plenp.
735  *
736  * rtalertp - XXX: should be stored in a more smart way
737  */
738 int
739 ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp,
740     int *offp)
741 {
742 	struct mbuf *m = *mp;
743 	int off = *offp, hbhlen;
744 	struct ip6_hbh *hbh;
745 
746 	/* validation of the length of the header */
747 	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
748 		sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
749 	if (hbh == NULL) {
750 		ip6stat.ip6s_tooshort++;
751 		return -1;
752 	}
753 	hbhlen = (hbh->ip6h_len + 1) << 3;
754 	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
755 		hbhlen);
756 	if (hbh == NULL) {
757 		ip6stat.ip6s_tooshort++;
758 		return -1;
759 	}
760 	off += hbhlen;
761 	hbhlen -= sizeof(struct ip6_hbh);
762 
763 	if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
764 				hbhlen, rtalertp, plenp) < 0)
765 		return (-1);
766 
767 	*offp = off;
768 	*mp = m;
769 	return (0);
770 }
771 
772 /*
773  * Search header for all Hop-by-hop options and process each option.
774  * This function is separate from ip6_hopopts_input() in order to
775  * handle a case where the sending node itself process its hop-by-hop
776  * options header. In such a case, the function is called from ip6_output().
777  *
778  * The function assumes that hbh header is located right after the IPv6 header
779  * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
780  * opthead + hbhlen is located in continuous memory region.
781  */
782 int
783 ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
784     u_int32_t *rtalertp, u_int32_t *plenp)
785 {
786 	struct ip6_hdr *ip6;
787 	int optlen = 0;
788 	u_int8_t *opt = opthead;
789 	u_int16_t rtalert_val;
790 	u_int32_t jumboplen;
791 	const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
792 
793 	for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
794 		switch (*opt) {
795 		case IP6OPT_PAD1:
796 			optlen = 1;
797 			break;
798 		case IP6OPT_PADN:
799 			if (hbhlen < IP6OPT_MINLEN) {
800 				ip6stat.ip6s_toosmall++;
801 				goto bad;
802 			}
803 			optlen = *(opt + 1) + 2;
804 			break;
805 		case IP6OPT_ROUTER_ALERT:
806 			/* XXX may need check for alignment */
807 			if (hbhlen < IP6OPT_RTALERT_LEN) {
808 				ip6stat.ip6s_toosmall++;
809 				goto bad;
810 			}
811 			if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
812 				/* XXX stat */
813 				icmp6_error(m, ICMP6_PARAM_PROB,
814 				    ICMP6_PARAMPROB_HEADER,
815 				    erroff + opt + 1 - opthead);
816 				return (-1);
817 			}
818 			optlen = IP6OPT_RTALERT_LEN;
819 			bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2);
820 			*rtalertp = ntohs(rtalert_val);
821 			break;
822 		case IP6OPT_JUMBO:
823 			/* XXX may need check for alignment */
824 			if (hbhlen < IP6OPT_JUMBO_LEN) {
825 				ip6stat.ip6s_toosmall++;
826 				goto bad;
827 			}
828 			if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
829 				/* XXX stat */
830 				icmp6_error(m, ICMP6_PARAM_PROB,
831 				    ICMP6_PARAMPROB_HEADER,
832 				    erroff + opt + 1 - opthead);
833 				return (-1);
834 			}
835 			optlen = IP6OPT_JUMBO_LEN;
836 
837 			/*
838 			 * IPv6 packets that have non 0 payload length
839 			 * must not contain a jumbo payload option.
840 			 */
841 			ip6 = mtod(m, struct ip6_hdr *);
842 			if (ip6->ip6_plen) {
843 				ip6stat.ip6s_badoptions++;
844 				icmp6_error(m, ICMP6_PARAM_PROB,
845 				    ICMP6_PARAMPROB_HEADER,
846 				    erroff + opt - opthead);
847 				return (-1);
848 			}
849 
850 			/*
851 			 * We may see jumbolen in unaligned location, so
852 			 * we'd need to perform bcopy().
853 			 */
854 			bcopy(opt + 2, &jumboplen, sizeof(jumboplen));
855 			jumboplen = (u_int32_t)htonl(jumboplen);
856 
857 #if 1
858 			/*
859 			 * if there are multiple jumbo payload options,
860 			 * *plenp will be non-zero and the packet will be
861 			 * rejected.
862 			 * the behavior may need some debate in ipngwg -
863 			 * multiple options does not make sense, however,
864 			 * there's no explicit mention in specification.
865 			 */
866 			if (*plenp != 0) {
867 				ip6stat.ip6s_badoptions++;
868 				icmp6_error(m, ICMP6_PARAM_PROB,
869 				    ICMP6_PARAMPROB_HEADER,
870 				    erroff + opt + 2 - opthead);
871 				return (-1);
872 			}
873 #endif
874 
875 			/*
876 			 * jumbo payload length must be larger than 65535.
877 			 */
878 			if (jumboplen <= IPV6_MAXPACKET) {
879 				ip6stat.ip6s_badoptions++;
880 				icmp6_error(m, ICMP6_PARAM_PROB,
881 				    ICMP6_PARAMPROB_HEADER,
882 				    erroff + opt + 2 - opthead);
883 				return (-1);
884 			}
885 			*plenp = jumboplen;
886 
887 			break;
888 		default:		/* unknown option */
889 			if (hbhlen < IP6OPT_MINLEN) {
890 				ip6stat.ip6s_toosmall++;
891 				goto bad;
892 			}
893 			optlen = ip6_unknown_opt(opt, m,
894 			    erroff + opt - opthead);
895 			if (optlen == -1)
896 				return (-1);
897 			optlen += 2;
898 			break;
899 		}
900 	}
901 
902 	return (0);
903 
904   bad:
905 	m_freem(m);
906 	return (-1);
907 }
908 
909 /*
910  * Unknown option processing.
911  * The third argument `off' is the offset from the IPv6 header to the option,
912  * which allows returning an ICMPv6 error even if the IPv6 header and the
913  * option header are not continuous.
914  */
915 int
916 ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
917 {
918 	struct ip6_hdr *ip6;
919 
920 	switch (IP6OPT_TYPE(*optp)) {
921 	case IP6OPT_TYPE_SKIP: /* ignore the option */
922 		return ((int)*(optp + 1));
923 	case IP6OPT_TYPE_DISCARD:	/* silently discard */
924 		m_freem(m);
925 		return (-1);
926 	case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
927 		ip6stat.ip6s_badoptions++;
928 		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
929 		return (-1);
930 	case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
931 		ip6stat.ip6s_badoptions++;
932 		ip6 = mtod(m, struct ip6_hdr *);
933 		if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
934 		    (m->m_flags & (M_BCAST|M_MCAST)))
935 			m_freem(m);
936 		else
937 			icmp6_error(m, ICMP6_PARAM_PROB,
938 				    ICMP6_PARAMPROB_OPTION, off);
939 		return (-1);
940 	}
941 
942 	m_freem(m);		/* XXX: NOTREACHED */
943 	return (-1);
944 }
945 
946 /*
947  * Create the "control" list for this pcb.
948  *
949  * The routine will be called from upper layer handlers like tcp6_input().
950  * Thus the routine assumes that the caller (tcp6_input) have already
951  * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
952  * very first mbuf on the mbuf chain.
953  * We may want to add some infinite loop prevention or sanity checks for safety.
954  * (This applies only when you are using KAME mbuf chain restriction, i.e.
955  * you are using IP6_EXTHDR_CHECK() not m_pulldown())
956  */
957 void
958 ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
959 {
960 #define IS2292(x, y)	((in6p->inp_flags & IN6P_RFC2292) ? (x) : (y))
961 	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
962 
963 #ifdef SO_TIMESTAMP
964 	if (in6p->inp_socket->so_options & SO_TIMESTAMP) {
965 		struct timeval tv;
966 
967 		microtime(&tv);
968 		*mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
969 		    SCM_TIMESTAMP, SOL_SOCKET);
970 		if (*mp)
971 			mp = &(*mp)->m_next;
972 	}
973 #endif
974 
975 	/* RFC 2292 sec. 5 */
976 	if ((in6p->inp_flags & IN6P_PKTINFO) != 0) {
977 		struct in6_pktinfo pi6;
978 		bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr));
979 		if (IN6_IS_SCOPE_EMBED(&pi6.ipi6_addr))
980 			pi6.ipi6_addr.s6_addr16[1] = 0;
981 		pi6.ipi6_ifindex =
982 		    (m && m->m_pkthdr.rcvif) ? m->m_pkthdr.rcvif->if_index : 0;
983 		*mp = sbcreatecontrol((caddr_t) &pi6,
984 		    sizeof(struct in6_pktinfo),
985 		    IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6);
986 		if (*mp)
987 			mp = &(*mp)->m_next;
988 	}
989 
990 	if ((in6p->inp_flags & IN6P_HOPLIMIT) != 0) {
991 		int hlim = ip6->ip6_hlim & 0xff;
992 		*mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int),
993 		    IS2292(IPV6_2292HOPLIMIT, IPV6_HOPLIMIT), IPPROTO_IPV6);
994 		if (*mp)
995 			mp = &(*mp)->m_next;
996 	}
997 
998 	if ((in6p->inp_flags & IN6P_TCLASS) != 0) {
999 		u_int32_t flowinfo;
1000 		int tclass;
1001 
1002 		flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK);
1003 		flowinfo >>= 20;
1004 
1005 		tclass = flowinfo & 0xff;
1006 		*mp = sbcreatecontrol((caddr_t)&tclass, sizeof(tclass),
1007 		    IPV6_TCLASS, IPPROTO_IPV6);
1008 		if (*mp)
1009 			mp = &(*mp)->m_next;
1010 	}
1011 
1012 	/*
1013 	 * IPV6_HOPOPTS socket option.  Recall that we required super-user
1014 	 * privilege for the option (see ip6_ctloutput), but it might be too
1015 	 * strict, since there might be some hop-by-hop options which can be
1016 	 * returned to normal user.
1017 	 * See also RFC 2292 section 6 (or RFC 3542 section 8).
1018 	 */
1019 	if ((in6p->inp_flags & IN6P_HOPOPTS) != 0) {
1020 		/*
1021 		 * Check if a hop-by-hop options header is contatined in the
1022 		 * received packet, and if so, store the options as ancillary
1023 		 * data. Note that a hop-by-hop options header must be
1024 		 * just after the IPv6 header, which is assured through the
1025 		 * IPv6 input processing.
1026 		 */
1027 		struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1028 		if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
1029 			struct ip6_hbh *hbh;
1030 			int hbhlen = 0;
1031 			struct mbuf *ext;
1032 
1033 			ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
1034 			    ip6->ip6_nxt);
1035 			if (ext == NULL) {
1036 				ip6stat.ip6s_tooshort++;
1037 				return;
1038 			}
1039 			hbh = mtod(ext, struct ip6_hbh *);
1040 			hbhlen = (hbh->ip6h_len + 1) << 3;
1041 			if (hbhlen != ext->m_len) {
1042 				m_freem(ext);
1043 				ip6stat.ip6s_tooshort++;
1044 				return;
1045 			}
1046 
1047 			/*
1048 			 * XXX: We copy the whole header even if a
1049 			 * jumbo payload option is included, the option which
1050 			 * is to be removed before returning according to
1051 			 * RFC2292.
1052 			 * Note: this constraint is removed in RFC3542.
1053 			 */
1054 			*mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
1055 			    IS2292(IPV6_2292HOPOPTS, IPV6_HOPOPTS),
1056 			    IPPROTO_IPV6);
1057 			if (*mp)
1058 				mp = &(*mp)->m_next;
1059 			m_freem(ext);
1060 		}
1061 	}
1062 
1063 	/* IPV6_DSTOPTS and IPV6_RTHDR socket options */
1064 	if ((in6p->inp_flags & (IN6P_RTHDR | IN6P_DSTOPTS)) != 0) {
1065 		struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1066 		int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);
1067 
1068 		/*
1069 		 * Search for destination options headers or routing
1070 		 * header(s) through the header chain, and stores each
1071 		 * header as ancillary data.
1072 		 * Note that the order of the headers remains in
1073 		 * the chain of ancillary data.
1074 		 */
1075 		while (1) {	/* is explicit loop prevention necessary? */
1076 			struct ip6_ext *ip6e = NULL;
1077 			int elen;
1078 			struct mbuf *ext = NULL;
1079 
1080 			/*
1081 			 * if it is not an extension header, don't try to
1082 			 * pull it from the chain.
1083 			 */
1084 			switch (nxt) {
1085 			case IPPROTO_DSTOPTS:
1086 			case IPPROTO_ROUTING:
1087 			case IPPROTO_HOPOPTS:
1088 			case IPPROTO_AH: /* is it possible? */
1089 				break;
1090 			default:
1091 				goto loopend;
1092 			}
1093 
1094 			ext = ip6_pullexthdr(m, off, nxt);
1095 			if (ext == NULL) {
1096 				ip6stat.ip6s_tooshort++;
1097 				return;
1098 			}
1099 			ip6e = mtod(ext, struct ip6_ext *);
1100 			if (nxt == IPPROTO_AH)
1101 				elen = (ip6e->ip6e_len + 2) << 2;
1102 			else
1103 				elen = (ip6e->ip6e_len + 1) << 3;
1104 			if (elen != ext->m_len) {
1105 				m_freem(ext);
1106 				ip6stat.ip6s_tooshort++;
1107 				return;
1108 			}
1109 
1110 			switch (nxt) {
1111 			case IPPROTO_DSTOPTS:
1112 				if (!(in6p->inp_flags & IN6P_DSTOPTS))
1113 					break;
1114 
1115 				*mp = sbcreatecontrol((caddr_t)ip6e, elen,
1116 				    IS2292(IPV6_2292DSTOPTS, IPV6_DSTOPTS),
1117 				    IPPROTO_IPV6);
1118 				if (*mp)
1119 					mp = &(*mp)->m_next;
1120 				break;
1121 
1122 			case IPPROTO_ROUTING:
1123 				if (!(in6p->inp_flags & IN6P_RTHDR))
1124 					break;
1125 
1126 				*mp = sbcreatecontrol((caddr_t)ip6e, elen,
1127 				    IS2292(IPV6_2292RTHDR, IPV6_RTHDR),
1128 				    IPPROTO_IPV6);
1129 				if (*mp)
1130 					mp = &(*mp)->m_next;
1131 				break;
1132 
1133 			case IPPROTO_HOPOPTS:
1134 			case IPPROTO_AH: /* is it possible? */
1135 				break;
1136 
1137 			default:
1138 				/*
1139 				 * other cases have been filtered in the above.
1140 				 * none will visit this case.  here we supply
1141 				 * the code just in case (nxt overwritten or
1142 				 * other cases).
1143 				 */
1144 				m_freem(ext);
1145 				goto loopend;
1146 
1147 			}
1148 
1149 			/* proceed with the next header. */
1150 			off += elen;
1151 			nxt = ip6e->ip6e_nxt;
1152 			ip6e = NULL;
1153 			m_freem(ext);
1154 			ext = NULL;
1155 		}
1156 	  loopend:
1157 	  	;
1158 	}
1159 }
1160 
1161 /*
1162  * pull single extension header from mbuf chain.  returns single mbuf that
1163  * contains the result, or NULL on error.
1164  */
1165 struct mbuf *
1166 ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
1167 {
1168 	struct ip6_ext ip6e;
1169 	size_t elen;
1170 	struct mbuf *n;
1171 
1172 #ifdef DIAGNOSTIC
1173 	switch (nxt) {
1174 	case IPPROTO_DSTOPTS:
1175 	case IPPROTO_ROUTING:
1176 	case IPPROTO_HOPOPTS:
1177 	case IPPROTO_AH: /* is it possible? */
1178 		break;
1179 	default:
1180 		printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
1181 	}
1182 #endif
1183 
1184 	m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1185 	if (nxt == IPPROTO_AH)
1186 		elen = (ip6e.ip6e_len + 2) << 2;
1187 	else
1188 		elen = (ip6e.ip6e_len + 1) << 3;
1189 
1190 	MGET(n, M_DONTWAIT, MT_DATA);
1191 	if (n && elen >= MLEN) {
1192 		MCLGET(n, M_DONTWAIT);
1193 		if ((n->m_flags & M_EXT) == 0) {
1194 			m_free(n);
1195 			n = NULL;
1196 		}
1197 	}
1198 	if (!n)
1199 		return NULL;
1200 
1201 	n->m_len = 0;
1202 	if (elen >= M_TRAILINGSPACE(n)) {
1203 		m_free(n);
1204 		return NULL;
1205 	}
1206 
1207 	m_copydata(m, off, elen, mtod(n, caddr_t));
1208 	n->m_len = elen;
1209 	return n;
1210 }
1211 
1212 /*
1213  * Get pointer to the previous header followed by the header
1214  * currently processed.
1215  * XXX: This function supposes that
1216  *	M includes all headers,
1217  *	the next header field and the header length field of each header
1218  *	are valid, and
1219  *	the sum of each header length equals to OFF.
1220  * Because of these assumptions, this function must be called very
1221  * carefully. Moreover, it will not be used in the near future when
1222  * we develop `neater' mechanism to process extension headers.
1223  */
1224 u_int8_t *
1225 ip6_get_prevhdr(struct mbuf *m, int off)
1226 {
1227 	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1228 
1229 	if (off == sizeof(struct ip6_hdr))
1230 		return (&ip6->ip6_nxt);
1231 	else {
1232 		int len, nxt;
1233 		struct ip6_ext *ip6e = NULL;
1234 
1235 		nxt = ip6->ip6_nxt;
1236 		len = sizeof(struct ip6_hdr);
1237 		while (len < off) {
1238 			ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len);
1239 
1240 			switch (nxt) {
1241 			case IPPROTO_FRAGMENT:
1242 				len += sizeof(struct ip6_frag);
1243 				break;
1244 			case IPPROTO_AH:
1245 				len += (ip6e->ip6e_len + 2) << 2;
1246 				break;
1247 			default:
1248 				len += (ip6e->ip6e_len + 1) << 3;
1249 				break;
1250 			}
1251 			nxt = ip6e->ip6e_nxt;
1252 		}
1253 		if (ip6e)
1254 			return (&ip6e->ip6e_nxt);
1255 		else
1256 			return NULL;
1257 	}
1258 }
1259 
1260 /*
1261  * get next header offset.  m will be retained.
1262  */
1263 int
1264 ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp)
1265 {
1266 	struct ip6_hdr ip6;
1267 	struct ip6_ext ip6e;
1268 	struct ip6_frag fh;
1269 
1270 	/* just in case */
1271 	if (m == NULL)
1272 		panic("ip6_nexthdr: m == NULL");
1273 	if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off)
1274 		return -1;
1275 
1276 	switch (proto) {
1277 	case IPPROTO_IPV6:
1278 		if (m->m_pkthdr.len < off + sizeof(ip6))
1279 			return -1;
1280 		m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6);
1281 		if (nxtp)
1282 			*nxtp = ip6.ip6_nxt;
1283 		off += sizeof(ip6);
1284 		return off;
1285 
1286 	case IPPROTO_FRAGMENT:
1287 		/*
1288 		 * terminate parsing if it is not the first fragment,
1289 		 * it does not make sense to parse through it.
1290 		 */
1291 		if (m->m_pkthdr.len < off + sizeof(fh))
1292 			return -1;
1293 		m_copydata(m, off, sizeof(fh), (caddr_t)&fh);
1294 		if ((fh.ip6f_offlg & IP6F_OFF_MASK) != 0)
1295 			return -1;
1296 		if (nxtp)
1297 			*nxtp = fh.ip6f_nxt;
1298 		off += sizeof(struct ip6_frag);
1299 		return off;
1300 
1301 	case IPPROTO_AH:
1302 		if (m->m_pkthdr.len < off + sizeof(ip6e))
1303 			return -1;
1304 		m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1305 		if (nxtp)
1306 			*nxtp = ip6e.ip6e_nxt;
1307 		off += (ip6e.ip6e_len + 2) << 2;
1308 		if (m->m_pkthdr.len < off)
1309 			return -1;
1310 		return off;
1311 
1312 	case IPPROTO_HOPOPTS:
1313 	case IPPROTO_ROUTING:
1314 	case IPPROTO_DSTOPTS:
1315 		if (m->m_pkthdr.len < off + sizeof(ip6e))
1316 			return -1;
1317 		m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1318 		if (nxtp)
1319 			*nxtp = ip6e.ip6e_nxt;
1320 		off += (ip6e.ip6e_len + 1) << 3;
1321 		if (m->m_pkthdr.len < off)
1322 			return -1;
1323 		return off;
1324 
1325 	case IPPROTO_NONE:
1326 	case IPPROTO_ESP:
1327 	case IPPROTO_IPCOMP:
1328 		/* give up */
1329 		return -1;
1330 
1331 	default:
1332 		return -1;
1333 	}
1334 
1335 	return -1;
1336 }
1337 
1338 /*
1339  * get offset for the last header in the chain.  m will be kept untainted.
1340  */
1341 int
1342 ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp)
1343 {
1344 	int newoff;
1345 	int nxt;
1346 
1347 	if (!nxtp) {
1348 		nxt = -1;
1349 		nxtp = &nxt;
1350 	}
1351 	while (1) {
1352 		newoff = ip6_nexthdr(m, off, proto, nxtp);
1353 		if (newoff < 0)
1354 			return off;
1355 		else if (newoff < off)
1356 			return -1;	/* invalid */
1357 		else if (newoff == off)
1358 			return newoff;
1359 
1360 		off = newoff;
1361 		proto = *nxtp;
1362 	}
1363 }
1364 
1365 /*
1366  * System control for IP6
1367  */
1368 
1369 u_char	inet6ctlerrmap[PRC_NCMDS] = {
1370 	0,		0,		0,		0,
1371 	0,		EMSGSIZE,	EHOSTDOWN,	EHOSTUNREACH,
1372 	EHOSTUNREACH,	EHOSTUNREACH,	ECONNREFUSED,	ECONNREFUSED,
1373 	EMSGSIZE,	EHOSTUNREACH,	0,		0,
1374 	0,		0,		0,		0,
1375 	ENOPROTOOPT
1376 };
1377 
1378 int *ipv6ctl_vars[IPV6CTL_MAXID] = IPV6CTL_VARS;
1379 
1380 int
1381 ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1382     void *newp, size_t newlen)
1383 {
1384 #ifdef MROUTING
1385 	extern int ip6_mrtproto;
1386 	extern struct mrt6stat mrt6stat;
1387 #endif
1388 	int error, s;
1389 
1390 	/* All sysctl names at this level are terminal. */
1391 	if (namelen != 1)
1392 		return ENOTDIR;
1393 
1394 	switch (name[0]) {
1395 	case IPV6CTL_V6ONLY:
1396 		return sysctl_rdint(oldp, oldlenp, newp, ip6_v6only);
1397 	case IPV6CTL_DAD_PENDING:
1398 		return sysctl_rdint(oldp, oldlenp, newp, ip6_dad_pending);
1399 	case IPV6CTL_STATS:
1400 		if (newp != NULL)
1401 			return (EPERM);
1402 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
1403 		    &ip6stat, sizeof(ip6stat)));
1404 	case IPV6CTL_MRTSTATS:
1405 #ifdef MROUTING
1406 		if (newp != NULL)
1407 			return (EPERM);
1408 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
1409 		    &mrt6stat, sizeof(mrt6stat)));
1410 #else
1411 		return (EOPNOTSUPP);
1412 #endif
1413 	case IPV6CTL_MRTPROTO:
1414 #ifdef MROUTING
1415 		return sysctl_rdint(oldp, oldlenp, newp, ip6_mrtproto);
1416 #else
1417 		return (EOPNOTSUPP);
1418 #endif
1419 	case IPV6CTL_MTUDISCTIMEOUT:
1420 		error = sysctl_int(oldp, oldlenp, newp, newlen,
1421 		   &ip6_mtudisc_timeout);
1422 		if (icmp6_mtudisc_timeout_q != NULL) {
1423 			s = splsoftnet();
1424 			rt_timer_queue_change(icmp6_mtudisc_timeout_q,
1425 					      ip6_mtudisc_timeout);
1426 			splx(s);
1427 		}
1428 		return (error);
1429 	default:
1430 		if (name[0] < IPV6CTL_MAXID)
1431 			return (sysctl_int_arr(ipv6ctl_vars, name, namelen,
1432 			    oldp, oldlenp, newp, newlen));
1433 		return (EOPNOTSUPP);
1434 	}
1435 	/* NOTREACHED */
1436 }
1437