xref: /freebsd/sys/netinet6/ip6_input.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the project nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 /*
33  * Copyright (c) 1982, 1986, 1988, 1993
34  *	The Regents of the University of California.  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. All advertising materials mentioning features or use of this software
45  *    must display the following acknowledgement:
46  *	This product includes software developed by the University of
47  *	California, Berkeley and its contributors.
48  * 4. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  *
64  *	@(#)ip_input.c	8.2 (Berkeley) 1/4/94
65  */
66 
67 #include "opt_ipsec.h"
68 #include "opt_ip6fw.h"
69 
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/malloc.h>
73 #include <sys/mbuf.h>
74 #include <sys/domain.h>
75 #include <sys/protosw.h>
76 #include <sys/socket.h>
77 #include <sys/socketvar.h>
78 #include <sys/errno.h>
79 #include <sys/time.h>
80 #include <sys/kernel.h>
81 #include <sys/syslog.h>
82 #include <sys/proc.h>
83 
84 #include <net/if.h>
85 #include <net/if_types.h>
86 #include <net/if_dl.h>
87 #include <net/route.h>
88 #include <net/netisr.h>
89 #include <net/intrq.h>
90 
91 #include <netinet/in.h>
92 #include <netinet/in_systm.h>
93 #include <netinet/ip.h>
94 #include <netinet/ip_icmp.h>
95 #include <netinet/in_pcb.h>
96 #include <netinet6/in6_var.h>
97 #include <netinet6/ip6.h>
98 #include <netinet6/ip6_var.h>
99 #include <netinet6/icmp6.h>
100 #include <netinet6/in6_ifattach.h>
101 #include <netinet6/nd6.h>
102 #include <netinet6/in6_prefix.h>
103 
104 #ifdef IPV6FIREWALL
105 #include <netinet6/ip6_fw.h>
106 #endif
107 
108 #ifdef ALTQ
109 #include <netinet/altq_cdnr.h>
110 #endif
111 
112 #include <netinet6/ip6protosw.h>
113 
114 /* we need it for NLOOP. */
115 #include "loop.h"
116 
117 #include "faith.h"
118 #include "gif.h"
119 
120 #include <net/net_osdep.h>
121 
122 extern struct	domain inet6domain;
123 extern struct	ip6protosw inet6sw[];
124 
125 u_char	ip6_protox[IPPROTO_MAX];
126 static int	ip6qmaxlen = IFQ_MAXLEN;
127 struct	in6_ifaddr *in6_ifaddr;
128 
129 int	ip6_forward_srcrt;			/* XXX */
130 int	ip6_sourcecheck;			/* XXX */
131 int	ip6_sourcecheck_interval;		/* XXX */
132 
133 const int	int6intrq_present = 1;
134 
135 #ifdef IPV6FIREWALL
136 /* firewall hooks */
137 ip6_fw_chk_t	*ip6_fw_chk_ptr;
138 ip6_fw_ctl_t	*ip6_fw_ctl_ptr;
139 #endif
140 
141 struct	ip6stat ip6stat;
142 
143 static void	ip6_init2 __P((void *));
144 
145 static int	ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *));
146 
147 #if defined(PTR)
148 extern int	ip6_protocol_tr;
149 
150 int	ptr_in6		__P((struct mbuf *, struct mbuf **));
151 extern void	ip_forward __P((struct mbuf *, int));
152 #endif
153 
154 /*
155  * IP6 initialization: fill in IP6 protocol switch table.
156  * All protocols not implemented in kernel go to raw IP6 protocol handler.
157  */
158 void
159 ip6_init()
160 {
161 	register struct ip6protosw *pr;
162 	register int i;
163 	struct timeval tv;
164 
165 	pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
166 	if (pr == 0)
167 		panic("ip6_init");
168 	for (i = 0; i < IPPROTO_MAX; i++)
169 		ip6_protox[i] = pr - inet6sw;
170 	for (pr = (struct ip6protosw *)inet6domain.dom_protosw;
171 	    pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++)
172 		if (pr->pr_domain->dom_family == PF_INET6 &&
173 		    pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
174 			ip6_protox[pr->pr_protocol] = pr - inet6sw;
175 	ip6intrq.ifq_maxlen = ip6qmaxlen;
176 	register_netisr(NETISR_IPV6, ip6intr);
177 	nd6_init();
178 	frag6_init();
179 #ifdef IPV6FIREWALL
180 	ip6_fw_init();
181 #endif
182 	/*
183 	 * in many cases, random() here does NOT return random number
184 	 * as initialization during bootstrap time occur in fixed order.
185 	 */
186 	microtime(&tv);
187 	ip6_flow_seq = random() ^ tv.tv_usec;
188 }
189 
190 static void
191 ip6_init2(dummy)
192 	void *dummy;
193 {
194 	int i;
195 	int ret;
196 
197 	/* get EUI64 from somewhere */
198 	ret = in6_ifattach_getifid(NULL);
199 
200 	/*
201 	 * to route local address of p2p link to loopback,
202 	 * assign loopback address first.
203 	 */
204 	for (i = 0; i < NLOOP; i++)
205 		in6_ifattach(&loif[i], IN6_IFT_LOOP, NULL, 0);
206 
207 	/* attach pseudo interfaces */
208 	if (ret == 0)
209 		in6_ifattach_p2p();
210 
211 	/* nd6_timer_init */
212 	timeout(nd6_timer, (caddr_t)0, hz);
213 	/* router renumbering prefix list maintenance */
214 	timeout(in6_rr_timer, (caddr_t)0, hz);
215 }
216 
217 /* cheat */
218 /* This must be after route_init(), which is now SI_ORDER_THIRD */
219 SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL);
220 
221 /*
222  * IP6 input interrupt handling. Just pass the packet to ip6_input.
223  */
224 void
225 ip6intr()
226 {
227 	int s;
228 	struct mbuf *m;
229 
230 	for (;;) {
231 		s = splimp();
232 		IF_DEQUEUE(&ip6intrq, m);
233 		splx(s);
234 		if (m == 0)
235 			return;
236 		ip6_input(m);
237 	}
238 }
239 
240 extern struct	route_in6 ip6_forward_rt;
241 
242 void
243 ip6_input(m)
244 	struct mbuf *m;
245 {
246 	struct ip6_hdr *ip6;
247 	int off = sizeof(struct ip6_hdr), nest;
248 	u_int32_t plen;
249 	u_int32_t rtalert = ~0;
250 	int nxt, ours = 0;
251 	struct ifnet *deliverifp = NULL;
252 
253 #ifdef IPSEC
254 	/*
255 	 * should the inner packet be considered authentic?
256 	 * see comment in ah4_input().
257 	 */
258 	if (m) {
259 		m->m_flags &= ~M_AUTHIPHDR;
260 		m->m_flags &= ~M_AUTHIPDGM;
261 	}
262 #endif
263 
264 	/*
265 	 * mbuf statistics by kazu
266 	 */
267 	if (m->m_flags & M_EXT) {
268 		if (m->m_next)
269 			ip6stat.ip6s_mext2m++;
270 		else
271 			ip6stat.ip6s_mext1++;
272 	} else {
273 		if (m->m_next) {
274 			if (m->m_flags & M_LOOP) {
275 				ip6stat.ip6s_m2m[loif[0].if_index]++;	/*XXX*/
276 			} else if (m->m_pkthdr.rcvif->if_index <= 31)
277 				ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
278 			else
279 				ip6stat.ip6s_m2m[0]++;
280 		} else
281 			ip6stat.ip6s_m1++;
282 	}
283 
284 	in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);
285 	ip6stat.ip6s_total++;
286 
287 	IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /*nothing*/);
288 
289 	if (m->m_len < sizeof(struct ip6_hdr)) {
290 		struct ifnet *inifp;
291 		inifp = m->m_pkthdr.rcvif;
292 		if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) {
293 			ip6stat.ip6s_toosmall++;
294 			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
295 			return;
296 		}
297 	}
298 
299 	ip6 = mtod(m, struct ip6_hdr *);
300 
301 	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
302 		ip6stat.ip6s_badvers++;
303 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
304 		goto bad;
305 	}
306 
307 	ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
308 
309 #ifdef IPV6FIREWALL
310 	/*
311 	 * Check with the firewall...
312 	 */
313 	if (ip6_fw_chk_ptr) {
314 		u_short port = 0;
315 		/* If ipfw says divert, we have to just drop packet */
316 		/* use port as a dummy argument */
317 		if ((*ip6_fw_chk_ptr)(&ip6, NULL, &port, &m)) {
318 			m_freem(m);
319 			m = NULL;
320 		}
321 		if (!m)
322 			return;
323 	}
324 #endif
325 
326 #ifdef ALTQ
327 	if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
328 		/* packet is dropped by traffic conditioner */
329 		return;
330 	}
331 #endif
332 
333 	/*
334 	 * Scope check
335 	 */
336 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
337 	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
338 		ip6stat.ip6s_badscope++;
339 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
340 		goto bad;
341 	}
342 	if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
343 	    IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) {
344 		if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
345 			ip6stat.ip6s_badscope++;
346 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
347 			goto bad;
348 		}
349 	}
350 
351 	if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) {
352 		if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) {
353 			ours = 1;
354 			deliverifp = m->m_pkthdr.rcvif;
355 			goto hbhcheck;
356 		}
357 	} else {
358 		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
359 			ip6->ip6_src.s6_addr16[1]
360 				= htons(m->m_pkthdr.rcvif->if_index);
361 		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
362 			ip6->ip6_dst.s6_addr16[1]
363 				= htons(m->m_pkthdr.rcvif->if_index);
364 	}
365 
366 #if defined(PTR)
367 	/*
368 	 *
369 	 */
370 	if (ip6_protocol_tr)
371 	{
372 	    struct mbuf *m1 = NULL;
373 
374 	    switch (ptr_in6(m, &m1))
375 	    {
376 	      case IPPROTO_IP:					goto mcastcheck;
377 	      case IPPROTO_IPV4:	ip_forward(m1, 0);	break;
378 	      case IPPROTO_IPV6:	ip6_forward(m1, 0);	break;
379 	      case IPPROTO_MAX:			/* discard this packet	*/
380 	      default:
381 	    }
382 
383 	    if (m != m1)
384 		m_freem(m);
385 
386 	    return;
387 	}
388 
389   mcastcheck:
390 #endif
391 
392 	/*
393 	 * Multicast check
394 	 */
395 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
396 	  	struct	in6_multi *in6m = 0;
397 
398 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast);
399 		/*
400 		 * See if we belong to the destination multicast group on the
401 		 * arrival interface.
402 		 */
403 		IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m);
404 		if (in6m)
405 			ours = 1;
406 		else if (!ip6_mrouter) {
407 			ip6stat.ip6s_notmember++;
408 			ip6stat.ip6s_cantforward++;
409 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
410 			goto bad;
411 		}
412 		deliverifp = m->m_pkthdr.rcvif;
413 		goto hbhcheck;
414 	}
415 
416 	/*
417 	 *  Unicast check
418 	 */
419 	if (ip6_forward_rt.ro_rt == 0 ||
420 	    !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
421 				&ip6_forward_rt.ro_dst.sin6_addr)) {
422 		if (ip6_forward_rt.ro_rt) {
423 			RTFREE(ip6_forward_rt.ro_rt);
424 			ip6_forward_rt.ro_rt = 0;
425 		}
426 		bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
427 		ip6_forward_rt.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
428 		ip6_forward_rt.ro_dst.sin6_family = AF_INET6;
429 		ip6_forward_rt.ro_dst.sin6_addr = ip6->ip6_dst;
430 
431 		rtalloc_ign((struct route *)&ip6_forward_rt, RTF_PRCLONING);
432 	}
433 
434 #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))
435 
436 	/*
437 	 * Accept the packet if the forwarding interface to the destination
438 	 * according to the routing table is the loopback interface,
439 	 * unless the associated route has a gateway.
440 	 * Note that this approach causes to accept a packet if there is a
441 	 * route to the loopback interface for the destination of the packet.
442 	 * But we think it's even useful in some situations, e.g. when using
443 	 * a special daemon which wants to intercept the packet.
444 	 */
445 	if (ip6_forward_rt.ro_rt &&
446 	    (ip6_forward_rt.ro_rt->rt_flags &
447 	     (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
448 	    /*
449 	     * The comparison of the destination and the key of the rtentry
450 	     * has already done through looking up the routing table,
451 	     * so no need to do such a comparison here again.
452 	     */
453 	    ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) {
454 		struct in6_ifaddr *ia6 =
455 			(struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa;
456 		/* packet to tentative address must not be received */
457 		if (ia6->ia6_flags & IN6_IFF_ANYCAST)
458 			m->m_flags |= M_ANYCAST6;
459 		if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
460 			/* this interface is ready */
461 			ours = 1;
462 			deliverifp = ia6->ia_ifp;	/* correct? */
463 			goto hbhcheck;
464 		} else {
465 			/* this interface is not ready, fall through */
466 		}
467 	}
468 
469 	/*
470 	 * FAITH(Firewall Aided Internet Translator)
471 	 */
472 #if defined(NFAITH) && 0 < NFAITH
473 	if (ip6_keepfaith) {
474 		if (ip6_forward_rt.ro_rt && ip6_forward_rt.ro_rt->rt_ifp
475 		 && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {
476 			/* XXX do we need more sanity checks? */
477 			ours = 1;
478 			deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /*faith*/
479 			goto hbhcheck;
480 		}
481 	}
482 #endif
483 
484 	/*
485 	 * Now there is no reason to process the packet if it's not our own
486 	 * and we're not a router.
487 	 */
488 	if (!ip6_forwarding) {
489 		ip6stat.ip6s_cantforward++;
490 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
491 		goto bad;
492 	}
493 
494   hbhcheck:
495 	/*
496 	 * Process Hop-by-Hop options header if it's contained.
497 	 * m may be modified in ip6_hopopts_input().
498 	 * If a JumboPayload option is included, plen will also be modified.
499 	 */
500 	plen = (u_int32_t)ntohs(ip6->ip6_plen);
501 	if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
502 		if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
503 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
504 			return;	/* m have already been freed */
505 		}
506 		/* adjust pointer */
507 		ip6 = mtod(m, struct ip6_hdr *);
508 		nxt = ((struct ip6_hbh *)(ip6 + 1))->ip6h_nxt;
509 
510 		/*
511 		 * accept the packet if a router alert option is included
512 		 * and we act as an IPv6 router.
513 		 */
514 		if (rtalert != ~0 && ip6_forwarding)
515 			ours = 1;
516 	} else
517 		nxt = ip6->ip6_nxt;
518 
519 	/*
520 	 * Check that the amount of data in the buffers
521 	 * is as at least much as the IPv6 header would have us expect.
522 	 * Trim mbufs if longer than we expect.
523 	 * Drop packet if shorter than we expect.
524 	 */
525 	if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
526 		ip6stat.ip6s_tooshort++;
527 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
528 		goto bad;
529 	}
530 	if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
531 		if (m->m_len == m->m_pkthdr.len) {
532 			m->m_len = sizeof(struct ip6_hdr) + plen;
533 			m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
534 		} else
535 			m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
536 	}
537 
538 	/*
539 	 * Forward if desirable.
540 	 */
541 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
542 		/*
543 		 * If we are acting as a multicast router, all
544 		 * incoming multicast packets are passed to the
545 		 * kernel-level multicast forwarding function.
546 		 * The packet is returned (relatively) intact; if
547 		 * ip6_mforward() returns a non-zero value, the packet
548 		 * must be discarded, else it may be accepted below.
549 		 */
550 		if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
551 			ip6stat.ip6s_cantforward++;
552 			m_freem(m);
553 			return;
554 		}
555 		if (!ours) {
556 			m_freem(m);
557 			return;
558 		}
559 	} else if (!ours) {
560 		ip6_forward(m, 0);
561 		return;
562 	}
563 
564 	/*
565 	 * Tell launch routine the next header
566 	 */
567 #if defined(__NetBSD__) && defined(IFA_STATS)
568 	if (IFA_STATS && deliverifp != NULL) {
569 		struct in6_ifaddr *ia6;
570 		ip6 = mtod(m, struct ip6_hdr *);
571 		ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
572 		if (ia6)
573 			ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len;
574 	}
575 #endif
576 	ip6stat.ip6s_delivered++;
577 	in6_ifstat_inc(deliverifp, ifs6_in_deliver);
578 	nest = 0;
579 	while (nxt != IPPROTO_DONE) {
580 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
581 			ip6stat.ip6s_toomanyhdr++;
582 			goto bad;
583 		}
584 
585 		/*
586 		 * protection against faulty packet - there should be
587 		 * more sanity checks in header chain processing.
588 		 */
589 		if (m->m_pkthdr.len < off) {
590 			ip6stat.ip6s_tooshort++;
591 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
592 			goto bad;
593 		}
594 
595 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
596 	}
597 	return;
598  bad:
599 	m_freem(m);
600 }
601 
602 /*
603  * Hop-by-Hop options header processing. If a valid jumbo payload option is
604  * included, the real payload length will be stored in plenp.
605  */
606 static int
607 ip6_hopopts_input(plenp, rtalertp, mp, offp)
608 	u_int32_t *plenp;
609 	u_int32_t *rtalertp;	/* XXX: should be stored more smart way */
610 	struct mbuf **mp;
611 	int *offp;
612 {
613 	register struct mbuf *m = *mp;
614 	int off = *offp, hbhlen;
615 	struct ip6_hbh *hbh;
616 	u_int8_t *opt;
617 
618 	/* validation of the length of the header */
619 	IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1);
620 	hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
621 	hbhlen = (hbh->ip6h_len + 1) << 3;
622 
623 	IP6_EXTHDR_CHECK(m, off, hbhlen, -1);
624 	hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
625 	off += hbhlen;
626 	hbhlen -= sizeof(struct ip6_hbh);
627 	opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh);
628 
629 	if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
630 				hbhlen, rtalertp, plenp) < 0)
631 		return(-1);
632 
633 	*offp = off;
634 	*mp = m;
635 	return(0);
636 }
637 
638 /*
639  * Search header for all Hop-by-hop options and process each option.
640  * This function is separate from ip6_hopopts_input() in order to
641  * handle a case where the sending node itself process its hop-by-hop
642  * options header. In such a case, the function is called from ip6_output().
643  */
644 int
645 ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp)
646 	struct mbuf *m;
647 	u_int8_t *opthead;
648 	int hbhlen;
649 	u_int32_t *rtalertp;
650 	u_int32_t *plenp;
651 {
652 	struct ip6_hdr *ip6;
653 	int optlen = 0;
654 	u_int8_t *opt = opthead;
655 	u_int16_t rtalert_val;
656 
657 	for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
658 		switch(*opt) {
659 		 case IP6OPT_PAD1:
660 			 optlen = 1;
661 			 break;
662 		 case IP6OPT_PADN:
663 			 if (hbhlen < IP6OPT_MINLEN) {
664 				 ip6stat.ip6s_toosmall++;
665 				 goto bad;
666 			 }
667 			 optlen = *(opt + 1) + 2;
668 			 break;
669 		 case IP6OPT_RTALERT:
670 			 /* XXX may need check for alignment */
671 			 if (hbhlen < IP6OPT_RTALERT_LEN) {
672 				 ip6stat.ip6s_toosmall++;
673 				 goto bad;
674 			 }
675 			 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2)
676 				  /* XXX: should we discard the packet? */
677 				 log(LOG_ERR, "length of router alert opt is inconsitent(%d)",
678 				     *(opt + 1));
679 			 optlen = IP6OPT_RTALERT_LEN;
680 			 bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2);
681 			 *rtalertp = ntohs(rtalert_val);
682 			 break;
683 		 case IP6OPT_JUMBO:
684 			 /* XXX may need check for alignment */
685 			 if (hbhlen < IP6OPT_JUMBO_LEN) {
686 				 ip6stat.ip6s_toosmall++;
687 				 goto bad;
688 			 }
689 			 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2)
690 				  /* XXX: should we discard the packet? */
691 				 log(LOG_ERR, "length of jumbopayload opt "
692 				     "is inconsistent(%d)",
693 				     *(opt + 1));
694 			 optlen = IP6OPT_JUMBO_LEN;
695 
696 			 bcopy(opt + 2, plenp, sizeof(*plenp));
697 			 *plenp = htonl(*plenp);
698 			 if (*plenp <= IPV6_MAXPACKET) {
699 				 /*
700 				  * jumbo payload length must be larger
701 				  * than 65535
702 				  */
703 				 ip6stat.ip6s_badoptions++;
704 				 icmp6_error(m, ICMP6_PARAM_PROB,
705 					     ICMP6_PARAMPROB_HEADER,
706 					     sizeof(struct ip6_hdr) +
707 					     sizeof(struct ip6_hbh) +
708 					     opt + 2 - opthead);
709 				 return(-1);
710 			 }
711 
712 			 ip6 = mtod(m, struct ip6_hdr *);
713 			 if (ip6->ip6_plen) {
714 				 /*
715 				  * IPv6 packets that have non 0 payload length
716 				  * must not contain a jumbo paylod option.
717 				  */
718 				 ip6stat.ip6s_badoptions++;
719 				 icmp6_error(m, ICMP6_PARAM_PROB,
720 					     ICMP6_PARAMPROB_HEADER,
721 					     sizeof(struct ip6_hdr) +
722 					     sizeof(struct ip6_hbh) +
723 					     opt - opthead);
724 				 return(-1);
725 			 }
726 			 break;
727 		 default:		/* unknown option */
728 			 if (hbhlen < IP6OPT_MINLEN) {
729 				 ip6stat.ip6s_toosmall++;
730 				 goto bad;
731 			 }
732 			 if ((optlen = ip6_unknown_opt(opt, m,
733 						       sizeof(struct ip6_hdr) +
734 						       sizeof(struct ip6_hbh) +
735 						       opt - opthead)) == -1)
736 				 return(-1);
737 			 optlen += 2;
738 			 break;
739 		}
740 	}
741 
742 	return(0);
743 
744   bad:
745 	m_freem(m);
746 	return(-1);
747 }
748 
749 /*
750  * Unknown option processing.
751  * The third argument `off' is the offset from the IPv6 header to the option,
752  * which is necessary if the IPv6 header the and option header and IPv6 header
753  * is not continuous in order to return an ICMPv6 error.
754  */
755 int
756 ip6_unknown_opt(optp, m, off)
757 	u_int8_t *optp;
758 	struct mbuf *m;
759 	int off;
760 {
761 	struct ip6_hdr *ip6;
762 
763 	switch(IP6OPT_TYPE(*optp)) {
764 	 case IP6OPT_TYPE_SKIP: /* ignore the option */
765 		 return((int)*(optp + 1));
766 	 case IP6OPT_TYPE_DISCARD:	/* silently discard */
767 		 m_freem(m);
768 		 return(-1);
769 	 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
770 		 ip6stat.ip6s_badoptions++;
771 		 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
772 		 return(-1);
773 	 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
774 		 ip6stat.ip6s_badoptions++;
775 		 ip6 = mtod(m, struct ip6_hdr *);
776 		 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
777 		     (m->m_flags & (M_BCAST|M_MCAST)))
778 			 m_freem(m);
779 		 else
780 			 icmp6_error(m, ICMP6_PARAM_PROB,
781 				     ICMP6_PARAMPROB_OPTION, off);
782 		 return(-1);
783 	}
784 
785 	m_freem(m);		/* XXX: NOTREACHED */
786 	return(-1);
787 }
788 
789 /*
790  * Create the "control" list for this pcb
791  */
792 void
793 ip6_savecontrol(in6p, mp, ip6, m)
794 	register struct inpcb *in6p;
795 	register struct mbuf **mp;
796 	register struct ip6_hdr *ip6;
797 	register struct mbuf *m;
798 {
799 	struct proc *p = curproc;	/* XXX */
800 	int privileged;
801 
802 	privileged = 0;
803 	if (p && !suser(p))
804 		privileged++;
805 
806 	if (in6p->in6p_socket->so_options & SO_TIMESTAMP) {
807 		struct timeval tv;
808 
809 		microtime(&tv);
810 		*mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
811 			SCM_TIMESTAMP, SOL_SOCKET);
812 		if (*mp)
813 			mp = &(*mp)->m_next;
814 	}
815 	if (in6p->in6p_flags & IN6P_RECVDSTADDR) {
816 		*mp = sbcreatecontrol((caddr_t) &ip6->ip6_dst,
817 			sizeof(struct in6_addr), IPV6_RECVDSTADDR,
818 			IPPROTO_IPV6);
819 		if (*mp)
820 			mp = &(*mp)->m_next;
821 	}
822 
823 	/* RFC 2292 sec. 5 */
824 	if (in6p->in6p_flags & IN6P_PKTINFO) {
825 		struct in6_pktinfo pi6;
826 		bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr));
827 		if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr))
828 			pi6.ipi6_addr.s6_addr16[1] = 0;
829 		pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif)
830 					? m->m_pkthdr.rcvif->if_index
831 					: 0;
832 		*mp = sbcreatecontrol((caddr_t) &pi6,
833 			sizeof(struct in6_pktinfo), IPV6_PKTINFO,
834 			IPPROTO_IPV6);
835 		if (*mp)
836 			mp = &(*mp)->m_next;
837 	}
838 	if (in6p->in6p_flags & IN6P_HOPLIMIT) {
839 		int hlim = ip6->ip6_hlim & 0xff;
840 		*mp = sbcreatecontrol((caddr_t) &hlim,
841 			sizeof(int), IPV6_HOPLIMIT, IPPROTO_IPV6);
842 		if (*mp)
843 			mp = &(*mp)->m_next;
844 	}
845 	/* IN6P_NEXTHOP - for outgoing packet only */
846 
847 	/*
848 	 * IPV6_HOPOPTS socket option. We require super-user privilege
849 	 * for the option, but it might be too strict, since there might
850 	 * be some hop-by-hop options which can be returned to normal user.
851 	 * See RFC 2292 section 6.
852 	 */
853 	if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) {
854 		/*
855 		 * Check if a hop-by-hop options header is contatined in the
856 		 * received packet, and if so, store the options as ancillary
857 		 * data. Note that a hop-by-hop options header must be
858 		 * just after the IPv6 header, which fact is assured through
859 		 * the IPv6 input processing.
860 		 */
861 		struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
862 		if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
863 			struct ip6_hbh *hbh = (struct ip6_hbh *)(ip6 + 1);
864 
865 			/*
866 			 * XXX: We copy whole the header even if a jumbo
867 			 * payload option is included, which option is to
868 			 * be removed before returning in the RFC 2292.
869 			 * But it's too painful operation...
870 			 */
871 			*mp = sbcreatecontrol((caddr_t)hbh,
872 					      (hbh->ip6h_len + 1) << 3,
873 					      IPV6_HOPOPTS, IPPROTO_IPV6);
874 			if (*mp)
875 				mp = &(*mp)->m_next;
876 		}
877 	}
878 
879 	/* IPV6_DSTOPTS and IPV6_RTHDR socket options */
880 	if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) {
881 		struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
882 		int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);;
883 
884 		/*
885 		 * Search for destination options headers or routing
886 		 * header(s) through the header chain, and stores each
887 		 * header as ancillary data.
888 		 * Note that the order of the headers remains in
889 		 * the chain of ancillary data.
890 		 */
891 		while(1) {	/* is explicit loop prevention necessary? */
892 			struct ip6_ext *ip6e =
893 				(struct ip6_ext *)(mtod(m, caddr_t) + off);
894 
895 			switch(nxt) {
896 		         case IPPROTO_DSTOPTS:
897 				 if (!in6p->in6p_flags & IN6P_DSTOPTS)
898 					 break;
899 
900 				 /*
901 				  * We also require super-user privilege for
902 				  * the option.
903 				  * See the comments on IN6_HOPOPTS.
904 				  */
905 				 if (!privileged)
906 					 break;
907 
908 				 *mp = sbcreatecontrol((caddr_t)ip6e,
909 						       (ip6e->ip6e_len + 1) << 3,
910 						       IPV6_DSTOPTS,
911 						       IPPROTO_IPV6);
912 				 if (*mp)
913 					 mp = &(*mp)->m_next;
914 				 break;
915 
916 			 case IPPROTO_ROUTING:
917 				 if (!in6p->in6p_flags & IN6P_RTHDR)
918 					 break;
919 
920 				 *mp = sbcreatecontrol((caddr_t)ip6e,
921 						       (ip6e->ip6e_len + 1) << 3,
922 						       IPV6_RTHDR,
923 						       IPPROTO_IPV6);
924 				 if (*mp)
925 					 mp = &(*mp)->m_next;
926 				 break;
927 
928 			 case IPPROTO_UDP:
929 			 case IPPROTO_TCP:
930 			 case IPPROTO_ICMPV6:
931 			 default:
932 				 /*
933 				  * stop search if we encounter an upper
934 				  * layer protocol headers.
935 				  */
936 				 goto loopend;
937 
938 			 case IPPROTO_HOPOPTS:
939 			 case IPPROTO_AH: /* is it possible? */
940 				 break;
941 			}
942 
943 			/* proceed with the next header. */
944 			if (nxt == IPPROTO_AH)
945 				off += (ip6e->ip6e_len + 2) << 2;
946 			else
947 				off += (ip6e->ip6e_len + 1) << 3;
948 			nxt = ip6e->ip6e_nxt;
949 		}
950 	  loopend:
951 	}
952 	if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) {
953 		/* to be done */
954 	}
955 	if ((in6p->in6p_flags & IN6P_DSTOPTS) && privileged) {
956 		/* to be done */
957 	}
958 	/* IN6P_RTHDR - to be done */
959 }
960 
961 /*
962  * Get pointer to the previous header followed by the header
963  * currently processed.
964  * XXX: This function supposes that
965  *	M includes all headers,
966  *	the next header field and the header length field of each header
967  *	are valid, and
968  *	the sum of each header length equals to OFF.
969  * Because of these assumptions, this function must be called very
970  * carefully. Moreover, it will not be used in the near future when
971  * we develop `neater' mechanism to process extension headers.
972  */
973 char *
974 ip6_get_prevhdr(m, off)
975 	struct mbuf *m;
976 	int off;
977 {
978 	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
979 
980 	if (off == sizeof(struct ip6_hdr))
981 		return(&ip6->ip6_nxt);
982 	else {
983 		int len, nxt;
984 		struct ip6_ext *ip6e = NULL;
985 
986 		nxt = ip6->ip6_nxt;
987 		len = sizeof(struct ip6_hdr);
988 		while (len < off) {
989 			ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len);
990 
991 			switch(nxt) {
992 			case IPPROTO_FRAGMENT:
993 				len += sizeof(struct ip6_frag);
994 				break;
995 			case IPPROTO_AH:
996 				len += (ip6e->ip6e_len + 2) << 2;
997 				break;
998 			default:
999 				len += (ip6e->ip6e_len + 1) << 3;
1000 				break;
1001 			}
1002 			nxt = ip6e->ip6e_nxt;
1003 		}
1004 		if (ip6e)
1005 			return(&ip6e->ip6e_nxt);
1006 		else
1007 			return NULL;
1008 	}
1009 }
1010 
1011 /*
1012  * System control for IP6
1013  */
1014 
1015 u_char	inet6ctlerrmap[PRC_NCMDS] = {
1016 	0,		0,		0,		0,
1017 	0,		EMSGSIZE,	EHOSTDOWN,	EHOSTUNREACH,
1018 	EHOSTUNREACH,	EHOSTUNREACH,	ECONNREFUSED,	ECONNREFUSED,
1019 	EMSGSIZE,	EHOSTUNREACH,	0,		0,
1020 	0,		0,		0,		0,
1021 	ENOPROTOOPT
1022 };
1023