ip6_input.c revision 193219
119410Sguido/*-
219410Sguido * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
319410Sguido * All rights reserved.
419410Sguido *
519410Sguido * Redistribution and use in source and binary forms, with or without
619410Sguido * modification, are permitted provided that the following conditions
719410Sguido * are met:
819410Sguido * 1. Redistributions of source code must retain the above copyright
919410Sguido *    notice, this list of conditions and the following disclaimer.
1019410Sguido * 2. Redistributions in binary form must reproduce the above copyright
1119410Sguido *    notice, this list of conditions and the following disclaimer in the
1219410Sguido *    documentation and/or other materials provided with the distribution.
1319410Sguido * 3. Neither the name of the project nor the names of its contributors
1419410Sguido *    may be used to endorse or promote products derived from this software
1519410Sguido *    without specific prior written permission.
1619410Sguido *
1719410Sguido * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
1819410Sguido * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1919410Sguido * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2019410Sguido * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2119410Sguido * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2219410Sguido * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2319410Sguido * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2419410Sguido * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2519410Sguido * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2619410Sguido * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2719410Sguido * SUCH DAMAGE.
2819410Sguido *
2919410Sguido *	$KAME: ip6_input.c,v 1.259 2002/01/21 04:58:09 jinmei Exp $
3050477Speter */
3133707Sgpalmer
3219410Sguido/*-
3319410Sguido * Copyright (c) 1982, 1986, 1988, 1993
3419410Sguido *	The Regents of the University of California.  All rights reserved.
3519410Sguido *
3619410Sguido * Redistribution and use in source and binary forms, with or without
3719410Sguido * modification, are permitted provided that the following conditions
3819410Sguido * are met:
3919410Sguido * 1. Redistributions of source code must retain the above copyright
4019410Sguido *    notice, this list of conditions and the following disclaimer.
4119410Sguido * 2. Redistributions in binary form must reproduce the above copyright
4219410Sguido *    notice, this list of conditions and the following disclaimer in the
4319410Sguido *    documentation and/or other materials provided with the distribution.
4419410Sguido * 4. Neither the name of the University nor the names of its contributors
4519410Sguido *    may be used to endorse or promote products derived from this software
4619410Sguido *    without specific prior written permission.
4719410Sguido *
4819410Sguido * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4919410Sguido * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5019410Sguido * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5119410Sguido * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5219410Sguido * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5319410Sguido * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5419410Sguido * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5519410Sguido * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5619410Sguido * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5719410Sguido * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5819410Sguido * SUCH DAMAGE.
5919410Sguido *
6024204Sbde *	@(#)ip_input.c	8.2 (Berkeley) 1/4/94
6126640Sbde */
6219410Sguido
6319410Sguido#include <sys/cdefs.h>
6419410Sguido__FBSDID("$FreeBSD: head/sys/netinet6/ip6_input.c 193219 2009-06-01 10:41:38Z rwatson $");
6519410Sguido
6619410Sguido#include "opt_inet.h"
6732350Seivind#include "opt_inet6.h"
6832350Seivind#include "opt_ipsec.h"
6919410Sguido#include "opt_route.h"
7068417Swpaul
7168417Swpaul#include <sys/param.h>
7268417Swpaul#include <sys/systm.h>
7319410Sguido#include <sys/malloc.h>
7419410Sguido#include <sys/mbuf.h>
7519410Sguido#include <sys/proc.h>
7619410Sguido#include <sys/domain.h>
7719410Sguido#include <sys/protosw.h>
7819410Sguido#include <sys/socket.h>
7919410Sguido#include <sys/socketvar.h>
8019410Sguido#include <sys/errno.h>
8119410Sguido#include <sys/time.h>
8219410Sguido#include <sys/kernel.h>
8319410Sguido#include <sys/syslog.h>
8420096Sguido#include <sys/vimage.h>
8519410Sguido
8619410Sguido#include <net/if.h>
8719410Sguido#include <net/if_types.h>
8819410Sguido#include <net/if_dl.h>
8919410Sguido#include <net/route.h>
9019410Sguido#include <net/netisr.h>
9119410Sguido#include <net/pfil.h>
9219410Sguido#include <net/vnet.h>
9319410Sguido
9419410Sguido#include <netinet/in.h>
9519410Sguido#include <netinet/in_systm.h>
9619410Sguido#include <net/if_llatbl.h>
9719410Sguido#ifdef INET
9819410Sguido#include <netinet/ip.h>
9919410Sguido#include <netinet/ip_icmp.h>
10019410Sguido#include <netinet/vinet.h>
10119410Sguido#endif /* INET */
10219410Sguido#include <netinet/ip6.h>
10319410Sguido#include <netinet6/in6_var.h>
10419410Sguido#include <netinet6/ip6_var.h>
10519410Sguido#include <netinet/in_pcb.h>
10636735Sdfr#include <netinet/icmp6.h>
10719410Sguido#include <netinet6/scope6_var.h>
10819410Sguido#include <netinet6/in6_ifattach.h>
10919410Sguido#include <netinet6/nd6.h>
11019410Sguido#include <netinet6/vinet6.h>
11119410Sguido
11219410Sguido#ifdef IPSEC
11319410Sguido#include <netipsec/ipsec.h>
11419410Sguido#include <netinet6/ip6_ipsec.h>
11519410Sguido#include <netipsec/ipsec6.h>
11619410Sguido#endif /* IPSEC */
11719410Sguido
11819410Sguido#include <netinet6/ip6protosw.h>
11919410Sguido
12019410Sguidoextern struct domain inet6domain;
12119410Sguido
12219410Sguidou_char ip6_protox[IPPROTO_MAX];
12319410Sguido
12419410Sguidostatic struct netisr_handler ip6_nh = {
12519410Sguido	.nh_name = "ip6",
12619410Sguido	.nh_handler = ip6_input,
12719410Sguido	.nh_proto = NETISR_IPV6,
12868417Swpaul	.nh_policy = NETISR_POLICY_FLOW,
12919410Sguido};
13068417Swpaul
13119410Sguido#ifndef VIMAGE
13219410Sguido#ifndef VIMAGE_GLOBALS
13319410Sguidostruct vnet_inet6 vnet_inet6_0;
13419410Sguido#endif
13519410Sguido#endif
13619410Sguido
13719410Sguido#ifdef VIMAGE_GLOBALS
13819410Sguidostruct in6_ifaddr *in6_ifaddr;
13919410Sguidostruct ip6stat ip6stat;
14019410Sguido
14119410Sguidoextern struct callout in6_tmpaddrtimer_ch;
14219410Sguido
14368417Swpaulextern int dad_init;
14419410Sguidoextern int pmtu_expire;
14519410Sguidoextern int pmtu_probe;
14619410Sguidoextern u_long rip6_sendspace;
14768417Swpaulextern u_long rip6_recvspace;
14819410Sguidoextern int icmp6errppslim;
14919410Sguidoextern int icmp6_nodeinfo;
15019410Sguidoextern int udp6_sendspace;
15119410Sguidoextern int udp6_recvspace;
15219410Sguido#endif
15319410Sguido
15419410Sguidostruct pfil_head inet6_pfil_hook;
15519410Sguido
15619410Sguidostatic void ip6_init2(void *);
15756077Smdoddstatic struct ip6aux *ip6_setdstifaddr(struct mbuf *, struct in6_ifaddr *);
15819410Sguidostatic int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
15919410Sguido#ifdef PULLDOWN_TEST
16019410Sguidostatic struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
16119410Sguido#endif
16219410Sguido
16319410Sguido#ifndef VIMAGE_GLOBALS
16419410Sguidostatic void vnet_inet6_register(void);
16519410Sguido
16663090Sarchiestatic const vnet_modinfo_t vnet_inet6_modinfo = {
16719410Sguido	.vmi_id		= VNET_MOD_INET6,
16819410Sguido	.vmi_name	= "inet6",
16919410Sguido	.vmi_size	= sizeof(struct vnet_inet6),
17019410Sguido	.vmi_dependson	= VNET_MOD_INET	/* XXX revisit - TCP/UDP needs this? */
17119410Sguido};
17219410Sguido
17319410Sguidostatic void
17419410Sguidovnet_inet6_register(void)
17519410Sguido{
17619410Sguido
17719410Sguido	vnet_mod_register(&vnet_inet6_modinfo);
17819410Sguido}
17919410Sguido
18019410SguidoSYSINIT(inet6, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, vnet_inet6_register, 0);
18119410Sguido#endif
18219410Sguido
18319410Sguido/*
18419410Sguido * IP6 initialization: fill in IP6 protocol switch table.
18519410Sguido * All protocols not implemented in kernel go to raw IP6 protocol handler.
18619410Sguido */
18719410Sguidovoid
18819410Sguidoip6_init(void)
18919410Sguido{
19019410Sguido	INIT_VNET_INET6(curvnet);
19119410Sguido	struct ip6protosw *pr;
19219410Sguido	int i;
19319410Sguido
19468417Swpaul	V_in6_maxmtu = 0;
19519410Sguido#ifdef IP6_AUTO_LINKLOCAL
19668417Swpaul	V_ip6_auto_linklocal = IP6_AUTO_LINKLOCAL;
19719410Sguido#else
19868417Swpaul	V_ip6_auto_linklocal = 1;	/* enable by default */
19919410Sguido#endif
20019410Sguido	TUNABLE_INT_FETCH("net.inet6.ip6.auto_linklocal",
20119410Sguido	    &V_ip6_auto_linklocal);
20219410Sguido
20368417Swpaul#ifndef IPV6FORWARDING
20419410Sguido#ifdef GATEWAY6
20568417Swpaul#define IPV6FORWARDING	1	/* forward IP6 packets not for us */
20619410Sguido#else
20768417Swpaul#define IPV6FORWARDING	0	/* don't forward IP6 packets not for us */
20819410Sguido#endif /* GATEWAY6 */
20919410Sguido#endif /* !IPV6FORWARDING */
21019410Sguido
21119410Sguido#ifndef IPV6_SENDREDIRECTS
21219410Sguido#define IPV6_SENDREDIRECTS	1
21319410Sguido#endif
21419410Sguido
21519410Sguido	V_ip6_forwarding = IPV6FORWARDING; /* act as router? */
21668417Swpaul	V_ip6_sendredirects = IPV6_SENDREDIRECTS;
21719410Sguido	V_ip6_defhlim = IPV6_DEFHLIM;
21819410Sguido	V_ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
21919410Sguido	V_ip6_accept_rtadv = 0;	 /* "IPV6FORWARDING ? 0 : 1" is dangerous */
22019410Sguido	V_ip6_log_interval = 5;
22168417Swpaul	V_ip6_hdrnestlimit = 15; /* How many header options will we process? */
22268417Swpaul	V_ip6_dad_count = 1;	 /* DupAddrDetectionTransmits */
22319410Sguido	V_ip6_auto_flowlabel = 1;
22419410Sguido	V_ip6_use_deprecated = 1;/* allow deprecated addr (RFC2462 5.5.4) */
22519410Sguido	V_ip6_rr_prune = 5;	 /* router renumbering prefix
22619410Sguido                                  * walk list every 5 sec. */
22719410Sguido	V_ip6_mcast_pmtu = 0;	 /* enable pMTU discovery for multicast? */
22819410Sguido	V_ip6_v6only = 1;
22919410Sguido	V_ip6_keepfaith = 0;
23019410Sguido	V_ip6_log_time = (time_t)0L;
23119410Sguido#ifdef IPSTEALTH
23219410Sguido	V_ip6stealth = 0;
23319410Sguido#endif
23419410Sguido	V_nd6_onlink_ns_rfc4861 = 0; /* allow 'on-link' nd6 NS (RFC 4861) */
23519410Sguido
23619410Sguido	V_pmtu_expire = 60*10;
23719410Sguido	V_pmtu_probe = 60*2;
23819410Sguido
23921666Swollman	/* raw IP6 parameters */
24019410Sguido	/*
24168417Swpaul	 * Nominal space allocated to a raw ip socket.
24221666Swollman	 */
24321666Swollman#define RIPV6SNDQ	8192
24419410Sguido#define RIPV6RCVQ	8192
24519410Sguido	V_rip6_sendspace = RIPV6SNDQ;
24619410Sguido	V_rip6_recvspace = RIPV6RCVQ;
24719410Sguido
24819410Sguido	/* ICMPV6 parameters */
24919410Sguido	V_icmp6_rediraccept = 1;	/* accept and process redirects */
25019410Sguido	V_icmp6_redirtimeout = 10 * 60;	/* 10 minutes */
25119410Sguido	V_icmp6errppslim = 100;		/* 100pps */
25219410Sguido	/* control how to respond to NI queries */
25368417Swpaul	V_icmp6_nodeinfo = (ICMP6_NODEINFO_FQDNOK|ICMP6_NODEINFO_NODEADDROK);
25419410Sguido
25520096Sguido	/* UDP on IP6 parameters */
25619410Sguido	V_udp6_sendspace = 9216;	/* really max datagram size */
25719410Sguido	V_udp6_recvspace = 40 * (1024 + sizeof(struct sockaddr_in6));
25819410Sguido					/* 40 1K datagrams */
25920096Sguido	V_dad_init = 0;
26019410Sguido
26119410Sguido	scope6_init();
26219410Sguido	addrsel_policy_init();
26319410Sguido	nd6_init();
26419410Sguido	frag6_init();
26519410Sguido
26619410Sguido	V_ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR;
26719410Sguido
26868417Swpaul	/* Skip global initialization stuff for non-default instances. */
26919410Sguido	if (!IS_DEFAULT_VNET(curvnet))
27019410Sguido		return;
27119410Sguido
27219410Sguido#ifdef DIAGNOSTIC
27343295Sdillon	if (sizeof(struct protosw) != sizeof(struct ip6protosw))
27437618Sbde		panic("sizeof(protosw) != sizeof(ip6protosw)");
27519410Sguido#endif
27643295Sdillon	pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
27719410Sguido	if (pr == NULL)
27819410Sguido		panic("ip6_init");
27919410Sguido
28019410Sguido	/* Initialize the entire ip6_protox[] array to IPPROTO_RAW. */
28119410Sguido	for (i = 0; i < IPPROTO_MAX; i++)
28219410Sguido		ip6_protox[i] = pr - inet6sw;
28319410Sguido	/*
28419410Sguido	 * Cycle through IP protocols and put them into the appropriate place
28520096Sguido	 * in ip6_protox[].
28620096Sguido	 */
28720096Sguido	for (pr = (struct ip6protosw *)inet6domain.dom_protosw;
28820096Sguido	    pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++)
28919410Sguido		if (pr->pr_domain->dom_family == PF_INET6 &&
29020096Sguido		    pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) {
29120096Sguido			/* Be careful to only index valid IP protocols. */
29220096Sguido			if (pr->pr_protocol < IPPROTO_MAX)
29320096Sguido				ip6_protox[pr->pr_protocol] = pr - inet6sw;
29419410Sguido		}
29519410Sguido
29619410Sguido	/* Initialize packet filter hooks. */
29719410Sguido	inet6_pfil_hook.ph_type = PFIL_TYPE_AF;
29819410Sguido	inet6_pfil_hook.ph_af = AF_INET6;
29919410Sguido	if ((i = pfil_head_register(&inet6_pfil_hook)) != 0)
30019410Sguido		printf("%s: WARNING: unable to register pfil hook, "
30119410Sguido			"error %d\n", __func__, i);
30219410Sguido
30319410Sguido	netisr_register(&ip6_nh);
30419410Sguido}
30519410Sguido
30619410Sguidostatic int
30719410Sguidoip6_init2_vnet(const void *unused __unused)
30820096Sguido{
30919410Sguido	INIT_VNET_INET6(curvnet);
31020096Sguido
31120096Sguido	/* nd6_timer_init */
31220096Sguido	callout_init(&V_nd6_timer_ch, 0);
31320096Sguido	callout_reset(&V_nd6_timer_ch, hz, nd6_timer, curvnet);
31420096Sguido
31520096Sguido	/* timer for regeneranation of temporary addresses randomize ID */
31620096Sguido	callout_init(&V_in6_tmpaddrtimer_ch, 0);
31720096Sguido	callout_reset(&V_in6_tmpaddrtimer_ch,
31820096Sguido		      (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor -
31920096Sguido		       V_ip6_temp_regen_advance) * hz,
32020096Sguido		      in6_tmpaddrtimer, curvnet);
32120096Sguido
32220096Sguido	return (0);
32320096Sguido}
32420096Sguido
32520096Sguidostatic void
32620096Sguidoip6_init2(void *dummy)
32720096Sguido{
32820096Sguido
32920096Sguido	ip6_init2_vnet(NULL);
33020096Sguido}
33120096Sguido
33220096Sguido/* cheat */
33320096Sguido/* This must be after route_init(), which is now SI_ORDER_THIRD */
33420096SguidoSYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL);
33520096Sguido
33643295Sdillonvoid
33720096Sguidoip6_input(struct mbuf *m)
33820096Sguido{
33919410Sguido	INIT_VNET_NET(curvnet);
34019410Sguido	INIT_VNET_INET6(curvnet);
34120096Sguido	struct ip6_hdr *ip6;
34220096Sguido	int off = sizeof(struct ip6_hdr), nest;
34320096Sguido	u_int32_t plen;
34420096Sguido	u_int32_t rtalert = ~0;
34520096Sguido	int nxt, ours = 0;
34633705Sgpalmer	struct ifnet *deliverifp = NULL, *ifp = NULL;
34720096Sguido	struct in6_addr odst;
34820096Sguido	struct route_in6 rin6;
34920096Sguido	int srcrt = 0;
35020096Sguido	struct llentry *lle = NULL;
35120096Sguido	struct sockaddr_in6 dst6, *dst;
35220096Sguido
35319410Sguido	bzero(&rin6, sizeof(struct route_in6));
35468417Swpaul#ifdef IPSEC
35568417Swpaul	/*
35620096Sguido	 * should the inner packet be considered authentic?
35720096Sguido	 * see comment in ah4_input().
35868417Swpaul	 * NB: m cannot be NULL when passed to the input routine
35920096Sguido	 */
36020096Sguido
36168417Swpaul	m->m_flags &= ~M_AUTHIPHDR;
36220096Sguido	m->m_flags &= ~M_AUTHIPDGM;
36320096Sguido
36419410Sguido#endif /* IPSEC */
36519410Sguido
36620096Sguido	/*
36768417Swpaul	 * make sure we don't have onion peering information into m_tag.
36819410Sguido	 */
36919410Sguido	ip6_delaux(m);
37068417Swpaul
37120096Sguido	/*
37219410Sguido	 * mbuf statistics
37319410Sguido	 */
37419410Sguido	if (m->m_flags & M_EXT) {
37520096Sguido		if (m->m_next)
37668417Swpaul			V_ip6stat.ip6s_mext2m++;
37719410Sguido		else
37820096Sguido			V_ip6stat.ip6s_mext1++;
37919410Sguido	} else {
38019410Sguido#define M2MMAX	(sizeof(V_ip6stat.ip6s_m2m)/sizeof(V_ip6stat.ip6s_m2m[0]))
38119410Sguido		if (m->m_next) {
38220096Sguido			if (m->m_flags & M_LOOP) {
38320096Sguido				V_ip6stat.ip6s_m2m[V_loif[0].if_index]++; /* XXX */
38420096Sguido			} else if (m->m_pkthdr.rcvif->if_index < M2MMAX)
38519410Sguido				V_ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
38619410Sguido			else
38719410Sguido				V_ip6stat.ip6s_m2m[0]++;
38819410Sguido		} else
38919410Sguido			V_ip6stat.ip6s_m1++;
39019410Sguido#undef M2MMAX
39168417Swpaul	}
39219410Sguido
39319410Sguido	/* drop the packet if IPv6 operation is disabled on the IF */
39419410Sguido	if ((ND_IFINFO(m->m_pkthdr.rcvif)->flags & ND6_IFF_IFDISABLED)) {
39519410Sguido		m_freem(m);
39619410Sguido		return;
39719410Sguido	}
39819410Sguido
39919410Sguido	in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);
40019410Sguido	V_ip6stat.ip6s_total++;
40119410Sguido
40219410Sguido#ifndef PULLDOWN_TEST
40319410Sguido	/*
40419410Sguido	 * L2 bridge code and some other code can return mbuf chain
40519410Sguido	 * that does not conform to KAME requirement.  too bad.
40619410Sguido	 * XXX: fails to join if interface MTU > MCLBYTES.  jumbogram?
40719410Sguido	 */
40819410Sguido	if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) {
40919410Sguido		struct mbuf *n;
41019410Sguido
41119410Sguido		MGETHDR(n, M_DONTWAIT, MT_HEADER);
41219410Sguido		if (n)
41319410Sguido			M_MOVE_PKTHDR(n, m);
41419410Sguido		if (n && n->m_pkthdr.len > MHLEN) {
41519410Sguido			MCLGET(n, M_DONTWAIT);
41619410Sguido			if ((n->m_flags & M_EXT) == 0) {
41719410Sguido				m_freem(n);
41819410Sguido				n = NULL;
41919410Sguido			}
42019410Sguido		}
42119410Sguido		if (n == NULL) {
42219410Sguido			m_freem(m);
42319410Sguido			return;	/* ENOBUFS */
42420096Sguido		}
42568417Swpaul
42668417Swpaul		m_copydata(m, 0, n->m_pkthdr.len, mtod(n, caddr_t));
42719410Sguido		n->m_len = n->m_pkthdr.len;
42868417Swpaul		m_freem(m);
42920096Sguido		m = n;
43020096Sguido	}
43120096Sguido	IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /* nothing */);
43220096Sguido#endif
43319410Sguido
43468417Swpaul	if (m->m_len < sizeof(struct ip6_hdr)) {
43519410Sguido		struct ifnet *inifp;
43619410Sguido		inifp = m->m_pkthdr.rcvif;
43719410Sguido		if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
43819410Sguido			V_ip6stat.ip6s_toosmall++;
43919410Sguido			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
44020096Sguido			return;
44168417Swpaul		}
44219410Sguido	}
44319410Sguido
44419410Sguido	ip6 = mtod(m, struct ip6_hdr *);
44519410Sguido
44619410Sguido	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
44719410Sguido		V_ip6stat.ip6s_badvers++;
44819410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
44919410Sguido		goto bad;
45019410Sguido	}
45119410Sguido
45219410Sguido	V_ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
45319410Sguido
45468417Swpaul	/*
45519410Sguido	 * Check against address spoofing/corruption.
45619410Sguido	 */
45719410Sguido	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
45868417Swpaul	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
45968417Swpaul		/*
46019410Sguido		 * XXX: "badscope" is not very suitable for a multicast source.
46168417Swpaul		 */
46268417Swpaul		V_ip6stat.ip6s_badscope++;
46368417Swpaul		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
46419410Sguido		goto bad;
46519410Sguido	}
46619410Sguido	if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) &&
46719410Sguido	    !(m->m_flags & M_LOOP)) {
46868417Swpaul		/*
46919410Sguido		 * In this case, the packet should come from the loopback
47019410Sguido		 * interface.  However, we cannot just check the if_flags,
47119410Sguido		 * because ip6_mloopback() passes the "actual" interface
47219410Sguido		 * as the outgoing/incoming interface.
47319410Sguido		 */
47419410Sguido		V_ip6stat.ip6s_badscope++;
47519410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
47668417Swpaul		goto bad;
47719410Sguido	}
47819410Sguido
47968417Swpaul#ifdef ALTQ
48019410Sguido	if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
48119410Sguido		/* packet is dropped by traffic conditioner */
48219410Sguido		return;
48319410Sguido	}
48419410Sguido#endif
48519410Sguido	/*
48619410Sguido	 * The following check is not documented in specs.  A malicious
48719410Sguido	 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
48819410Sguido	 * and bypass security checks (act as if it was from 127.0.0.1 by using
48919410Sguido	 * IPv6 src ::ffff:127.0.0.1).  Be cautious.
49019410Sguido	 *
49119410Sguido	 * This check chokes if we are in an SIIT cloud.  As none of BSDs
49219410Sguido	 * support IPv4-less kernel compilation, we cannot support SIIT
49319410Sguido	 * environment at all.  So, it makes more sense for us to reject any
49419410Sguido	 * malicious packets for non-SIIT environment, than try to do a
49519410Sguido	 * partial support for SIIT environment.
49619410Sguido	 */
49719410Sguido	if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
49819410Sguido	    IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
49919410Sguido		V_ip6stat.ip6s_badscope++;
50019410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
50119410Sguido		goto bad;
50219410Sguido	}
50319410Sguido#if 0
50419410Sguido	/*
50519410Sguido	 * Reject packets with IPv4 compatible addresses (auto tunnel).
50619410Sguido	 *
50719410Sguido	 * The code forbids auto tunnel relay case in RFC1933 (the check is
50819410Sguido	 * stronger than RFC1933).  We may want to re-enable it if mech-xx
50919410Sguido	 * is revised to forbid relaying case.
51019410Sguido	 */
51119410Sguido	if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
51219410Sguido	    IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
51319410Sguido		V_ip6stat.ip6s_badscope++;
51419410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
51519410Sguido		goto bad;
51619410Sguido	}
51719410Sguido#endif
51868417Swpaul
51919410Sguido	/*
52019410Sguido	 * Run through list of hooks for input packets.
52119410Sguido	 *
52219410Sguido	 * NB: Beware of the destination address changing
52319410Sguido	 *     (e.g. by NAT rewriting).  When this happens,
52419410Sguido	 *     tell ip6_forward to do the right thing.
52519410Sguido	 */
52619410Sguido	odst = ip6->ip6_dst;
52719410Sguido
52819410Sguido	/* Jump over all PFIL processing if hooks are not active. */
52919410Sguido	if (!PFIL_HOOKED(&inet6_pfil_hook))
53019410Sguido		goto passin;
53119410Sguido
53219410Sguido	if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL))
53319410Sguido		return;
53419410Sguido	if (m == NULL)			/* consumed by filter */
53519410Sguido		return;
53619410Sguido	ip6 = mtod(m, struct ip6_hdr *);
53719410Sguido	srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
53819410Sguido
53919410Sguidopassin:
54019410Sguido	/*
54119410Sguido	 * Disambiguate address scope zones (if there is ambiguity).
54219410Sguido	 * We first make sure that the original source or destination address
54319410Sguido	 * is not in our internal form for scoped addresses.  Such addresses
54419410Sguido	 * are not necessarily invalid spec-wise, but we cannot accept them due
54519410Sguido	 * to the usage conflict.
54619410Sguido	 * in6_setscope() then also checks and rejects the cases where src or
54719410Sguido	 * dst are the loopback address and the receiving interface
54819410Sguido	 * is not loopback.
54919410Sguido	 */
55019410Sguido	if (in6_clearscope(&ip6->ip6_src) || in6_clearscope(&ip6->ip6_dst)) {
55119410Sguido		V_ip6stat.ip6s_badscope++; /* XXX */
55219410Sguido		goto bad;
55319410Sguido	}
55419410Sguido	if (in6_setscope(&ip6->ip6_src, m->m_pkthdr.rcvif, NULL) ||
55519410Sguido	    in6_setscope(&ip6->ip6_dst, m->m_pkthdr.rcvif, NULL)) {
55619410Sguido		V_ip6stat.ip6s_badscope++;
55719410Sguido		goto bad;
55819410Sguido	}
55919410Sguido
56068417Swpaul	/*
56168417Swpaul	 * Multicast check. Assume packet is for us to avoid
56219410Sguido	 * prematurely taking locks.
56319410Sguido	 */
56419410Sguido	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
56519410Sguido		ours = 1;
56619410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast);
56719410Sguido		deliverifp = m->m_pkthdr.rcvif;
56819410Sguido		goto hbhcheck;
56919410Sguido	}
57019410Sguido
57119410Sguido	/*
57219410Sguido	 *  Unicast check
57319410Sguido	 */
57419410Sguido
57519410Sguido	bzero(&dst6, sizeof(dst6));
57619410Sguido	dst6.sin6_family = AF_INET6;
57719410Sguido	dst6.sin6_len = sizeof(struct sockaddr_in6);
57819410Sguido	dst6.sin6_addr = ip6->ip6_dst;
57968417Swpaul	ifp = m->m_pkthdr.rcvif;
58019410Sguido	IF_AFDATA_LOCK(ifp);
58119410Sguido	lle = lla_lookup(LLTABLE6(ifp), 0,
58219410Sguido	     (struct sockaddr *)&dst6);
58319410Sguido	IF_AFDATA_UNLOCK(ifp);
58419410Sguido	if ((lle != NULL) && (lle->la_flags & LLE_IFADDR)) {
58519410Sguido		ours = 1;
58619410Sguido		deliverifp = ifp;
58742558Seivind		LLE_RUNLOCK(lle);
58842558Seivind		goto hbhcheck;
58919410Sguido	}
59019410Sguido	if (lle != NULL)
59142558Seivind		LLE_RUNLOCK(lle);
59219410Sguido
59319410Sguido	dst = &rin6.ro_dst;
59419410Sguido	dst->sin6_len = sizeof(struct sockaddr_in6);
59568417Swpaul	dst->sin6_family = AF_INET6;
59619410Sguido	dst->sin6_addr = ip6->ip6_dst;
59768417Swpaul	rin6.ro_rt = rtalloc1((struct sockaddr *)dst, 0, 0);
59819410Sguido	if (rin6.ro_rt)
59919410Sguido		RT_UNLOCK(rin6.ro_rt);
60019410Sguido
60119410Sguido#define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))
60219410Sguido
60319410Sguido	/*
60419410Sguido	 * Accept the packet if the forwarding interface to the destination
60519410Sguido	 * according to the routing table is the loopback interface,
60619410Sguido	 * unless the associated route has a gateway.
60719410Sguido	 * Note that this approach causes to accept a packet if there is a
60819410Sguido	 * route to the loopback interface for the destination of the packet.
60968417Swpaul	 * But we think it's even useful in some situations, e.g. when using
61019410Sguido	 * a special daemon which wants to intercept the packet.
61119410Sguido	 *
61219410Sguido	 * XXX: some OSes automatically make a cloned route for the destination
61319410Sguido	 * of an outgoing packet.  If the outgoing interface of the packet
61419410Sguido	 * is a loopback one, the kernel would consider the packet to be
61519410Sguido	 * accepted, even if we have no such address assinged on the interface.
61619410Sguido	 * We check the cloned flag of the route entry to reject such cases,
61719410Sguido	 * assuming that route entries for our own addresses are not made by
61819410Sguido	 * cloning (it should be true because in6_addloop explicitly installs
61919410Sguido	 * the host route).  However, we might have to do an explicit check
62019410Sguido	 * while it would be less efficient.  Or, should we rather install a
62119410Sguido	 * reject route for such a case?
62219410Sguido	 */
62319410Sguido	if (rin6.ro_rt &&
62419410Sguido	    (rin6.ro_rt->rt_flags &
62519410Sguido	     (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
62619410Sguido#ifdef RTF_WASCLONED
62719410Sguido	    !(rin6.ro_rt->rt_flags & RTF_WASCLONED) &&
62819410Sguido#endif
62919410Sguido#ifdef RTF_CLONED
63019410Sguido	    !(rin6.ro_rt->rt_flags & RTF_CLONED) &&
63119410Sguido#endif
63219410Sguido#if 0
63319410Sguido	    /*
63419410Sguido	     * The check below is redundant since the comparison of
63519410Sguido	     * the destination and the key of the rtentry has
63619410Sguido	     * already done through looking up the routing table.
63719410Sguido	     */
63819410Sguido	    IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
63919410Sguido	    &rt6_key(rin6.ro_rt)->sin6_addr)
64019410Sguido#endif
64119410Sguido	    rin6.ro_rt->rt_ifp->if_type == IFT_LOOP) {
64219410Sguido		struct in6_ifaddr *ia6 =
64319410Sguido			(struct in6_ifaddr *)rin6.ro_rt->rt_ifa;
64468417Swpaul
64519410Sguido		/*
64619410Sguido		 * record address information into m_tag.
64719410Sguido		 */
64819410Sguido		(void)ip6_setdstifaddr(m, ia6);
64919410Sguido
65019410Sguido		/*
65119410Sguido		 * packets to a tentative, duplicated, or somehow invalid
65219410Sguido		 * address must not be accepted.
65319410Sguido		 */
65419410Sguido		if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
65519410Sguido			/* this address is ready */
65619410Sguido			ours = 1;
65719410Sguido			deliverifp = ia6->ia_ifp;	/* correct? */
65819410Sguido			/* Count the packet in the ip address stats */
65919410Sguido			ia6->ia_ifa.if_ipackets++;
66019410Sguido			ia6->ia_ifa.if_ibytes += m->m_pkthdr.len;
66119410Sguido			goto hbhcheck;
66219410Sguido		} else {
66319410Sguido			char ip6bufs[INET6_ADDRSTRLEN];
66419410Sguido			char ip6bufd[INET6_ADDRSTRLEN];
66519410Sguido			/* address is not ready, so discard the packet. */
66619410Sguido			nd6log((LOG_INFO,
66719410Sguido			    "ip6_input: packet to an unready address %s->%s\n",
66819410Sguido			    ip6_sprintf(ip6bufs, &ip6->ip6_src),
66919410Sguido			    ip6_sprintf(ip6bufd, &ip6->ip6_dst)));
67019410Sguido
67119410Sguido			goto bad;
67219410Sguido		}
67319410Sguido	}
67419410Sguido
67519410Sguido	/*
67619410Sguido	 * FAITH (Firewall Aided Internet Translator)
67719410Sguido	 */
67819410Sguido	if (V_ip6_keepfaith) {
67919410Sguido		if (rin6.ro_rt && rin6.ro_rt->rt_ifp &&
68019410Sguido		    rin6.ro_rt->rt_ifp->if_type == IFT_FAITH) {
68119410Sguido			/* XXX do we need more sanity checks? */
68219410Sguido			ours = 1;
68319410Sguido			deliverifp = rin6.ro_rt->rt_ifp; /* faith */
68419410Sguido			goto hbhcheck;
68519410Sguido		}
68619410Sguido	}
68719410Sguido
68819410Sguido	/*
68919410Sguido	 * Now there is no reason to process the packet if it's not our own
69019410Sguido	 * and we're not a router.
69119410Sguido	 */
69219410Sguido	if (!V_ip6_forwarding) {
69319410Sguido		V_ip6stat.ip6s_cantforward++;
69422062Sphk		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
69522062Sphk		goto bad;
69622062Sphk	}
69722062Sphk
69822062Sphk  hbhcheck:
69960536Sarchie	/*
70060536Sarchie	 * record address information into m_tag, if we don't have one yet.
70122062Sphk	 * note that we are unable to record it, if the address is not listed
70260536Sarchie	 * as our interface address (e.g. multicast addresses, addresses
70319410Sguido	 * within FAITH prefixes and such).
70460536Sarchie	 */
70519410Sguido	if (deliverifp && !ip6_getdstifaddr(m)) {
70619410Sguido		struct in6_ifaddr *ia6;
70719410Sguido
70819410Sguido		ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
70919410Sguido		if (ia6) {
71019410Sguido			if (!ip6_setdstifaddr(m, ia6)) {
71119410Sguido				/*
71219410Sguido				 * XXX maybe we should drop the packet here,
71319410Sguido				 * as we could not provide enough information
71419410Sguido				 * to the upper layers.
71519410Sguido				 */
71619410Sguido			}
71719410Sguido		}
71819410Sguido	}
71919410Sguido
72019410Sguido	/*
72119410Sguido	 * Process Hop-by-Hop options header if it's contained.
72219410Sguido	 * m may be modified in ip6_hopopts_input().
72319410Sguido	 * If a JumboPayload option is included, plen will also be modified.
72419410Sguido	 */
72568417Swpaul	plen = (u_int32_t)ntohs(ip6->ip6_plen);
72619410Sguido	if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
72719410Sguido		struct ip6_hbh *hbh;
72819410Sguido
72919410Sguido		if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
73019410Sguido#if 0	/*touches NULL pointer*/
73119410Sguido			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
73219410Sguido#endif
73319410Sguido			goto out;	/* m have already been freed */
73419410Sguido		}
73519410Sguido
73619410Sguido		/* adjust pointer */
73719410Sguido		ip6 = mtod(m, struct ip6_hdr *);
73819410Sguido
73968417Swpaul		/*
74019410Sguido		 * if the payload length field is 0 and the next header field
74119410Sguido		 * indicates Hop-by-Hop Options header, then a Jumbo Payload
74219410Sguido		 * option MUST be included.
74319410Sguido		 */
74419410Sguido		if (ip6->ip6_plen == 0 && plen == 0) {
74519410Sguido			/*
74619410Sguido			 * Note that if a valid jumbo payload option is
74719410Sguido			 * contained, ip6_hopopts_input() must set a valid
74819410Sguido			 * (non-zero) payload length to the variable plen.
74919410Sguido			 */
75019410Sguido			V_ip6stat.ip6s_badoptions++;
75119410Sguido			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
75219410Sguido			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
75319410Sguido			icmp6_error(m, ICMP6_PARAM_PROB,
75419410Sguido				    ICMP6_PARAMPROB_HEADER,
75519410Sguido				    (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
75619410Sguido			goto out;
75719410Sguido		}
75819410Sguido#ifndef PULLDOWN_TEST
75919410Sguido		/* ip6_hopopts_input() ensures that mbuf is contiguous */
76029671Sgibbs		hbh = (struct ip6_hbh *)(ip6 + 1);
76129671Sgibbs#else
76229671Sgibbs		IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
76329671Sgibbs			sizeof(struct ip6_hbh));
76419410Sguido		if (hbh == NULL) {
76519410Sguido			V_ip6stat.ip6s_tooshort++;
76619410Sguido			goto out;
76719410Sguido		}
76862593Sitojun#endif
76919410Sguido		nxt = hbh->ip6h_nxt;
77019410Sguido
77119410Sguido		/*
77219410Sguido		 * If we are acting as a router and the packet contains a
77319410Sguido		 * router alert option, see if we know the option value.
77419410Sguido		 * Currently, we only support the option value for MLD, in which
77519410Sguido		 * case we should pass the packet to the multicast routing
77619410Sguido		 * daemon.
77719410Sguido		 */
77819410Sguido		if (rtalert != ~0) {
77919410Sguido			switch (rtalert) {
78019410Sguido			case IP6OPT_RTALERT_MLD:
78119410Sguido				if (V_ip6_forwarding)
78219410Sguido					ours = 1;
78330022Sitojun				break;
78430022Sitojun			default:
78530022Sitojun				/*
78630022Sitojun				 * RFC2711 requires unrecognized values must be
78730022Sitojun				 * silently ignored.
78830022Sitojun				 */
78919410Sguido				break;
79019410Sguido			}
79119410Sguido		}
79219410Sguido	} else
79319410Sguido		nxt = ip6->ip6_nxt;
79419410Sguido
79519410Sguido	/*
79619410Sguido	 * Check that the amount of data in the buffers
79719410Sguido	 * is as at least much as the IPv6 header would have us expect.
79819410Sguido	 * Trim mbufs if longer than we expect.
79919410Sguido	 * Drop packet if shorter than we expect.
80019410Sguido	 */
80119410Sguido	if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
80219410Sguido		V_ip6stat.ip6s_tooshort++;
80319410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
80419410Sguido		goto bad;
80519410Sguido	}
80630022Sitojun	if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
80730022Sitojun		if (m->m_len == m->m_pkthdr.len) {
80830022Sitojun			m->m_len = sizeof(struct ip6_hdr) + plen;
80919410Sguido			m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
81019410Sguido		} else
81130022Sitojun			m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
81268417Swpaul	}
81368417Swpaul
81430022Sitojun	/*
81568417Swpaul	 * Forward if desirable.
81668417Swpaul	 */
81730022Sitojun	if (V_ip6_mrouter &&
81830022Sitojun	    IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
81919410Sguido		/*
82019410Sguido		 * If we are acting as a multicast router, all
82119410Sguido		 * incoming multicast packets are passed to the
82219410Sguido		 * kernel-level multicast forwarding function.
82319410Sguido		 * The packet is returned (relatively) intact; if
82419410Sguido		 * ip6_mforward() returns a non-zero value, the packet
82568417Swpaul		 * must be discarded, else it may be accepted below.
82619410Sguido		 *
82719410Sguido		 * XXX TODO: Check hlim and multicast scope here to avoid
82819410Sguido		 * unnecessarily calling into ip6_mforward().
82919410Sguido		 */
83019410Sguido		if (ip6_mforward &&
83119410Sguido		    ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
83219410Sguido			IP6STAT_INC(ip6s_cantforward);
83319410Sguido			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
83419410Sguido			goto bad;
83519410Sguido		}
83636735Sdfr	} else if (!ours) {
83719410Sguido		ip6_forward(m, srcrt);
83819410Sguido		goto out;
83968417Swpaul	}
84019410Sguido
84119410Sguido	ip6 = mtod(m, struct ip6_hdr *);
84219410Sguido
84319410Sguido	/*
84419410Sguido	 * Malicious party may be able to use IPv4 mapped addr to confuse
84519410Sguido	 * tcp/udp stack and bypass security checks (act as if it was from
84619410Sguido	 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1).  Be cautious.
84719410Sguido	 *
84819410Sguido	 * For SIIT end node behavior, you may want to disable the check.
84919410Sguido	 * However, you will  become vulnerable to attacks using IPv4 mapped
85019410Sguido	 * source.
85119410Sguido	 */
85219410Sguido	if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
85319410Sguido	    IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
85419410Sguido		V_ip6stat.ip6s_badscope++;
85519410Sguido		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
85619410Sguido		goto bad;
85719410Sguido	}
85819410Sguido
85919410Sguido	/*
86019410Sguido	 * Tell launch routine the next header
86119410Sguido	 */
86219410Sguido	V_ip6stat.ip6s_delivered++;
86319410Sguido	in6_ifstat_inc(deliverifp, ifs6_in_deliver);
86419410Sguido	nest = 0;
86519410Sguido
86619410Sguido	while (nxt != IPPROTO_DONE) {
86719410Sguido		if (V_ip6_hdrnestlimit && (++nest > V_ip6_hdrnestlimit)) {
86819410Sguido			V_ip6stat.ip6s_toomanyhdr++;
86919410Sguido			goto bad;
87019410Sguido		}
87119410Sguido
87219410Sguido		/*
87319410Sguido		 * protection against faulty packet - there should be
87419410Sguido		 * more sanity checks in header chain processing.
87519410Sguido		 */
87619410Sguido		if (m->m_pkthdr.len < off) {
87719410Sguido			V_ip6stat.ip6s_tooshort++;
87819410Sguido			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
87919410Sguido			goto bad;
88019410Sguido		}
88119410Sguido
88219410Sguido#ifdef IPSEC
88319410Sguido		/*
88419410Sguido		 * enforce IPsec policy checking if we are seeing last header.
88519410Sguido		 * note that we do not visit this with protocols with pcb layer
88619410Sguido		 * code - like udp/tcp/raw ip.
88719410Sguido		 */
88819410Sguido		if (ip6_ipsec_input(m, nxt))
88919410Sguido			goto bad;
89019410Sguido#endif /* IPSEC */
89121666Swollman
89221666Swollman		/*
89321666Swollman		 * Use mbuf flags to propagate Router Alert option to
89421666Swollman		 * ICMPv6 layer, as hop-by-hop options have been stripped.
89521666Swollman		 */
89621666Swollman		if (nxt == IPPROTO_ICMPV6 && rtalert != ~0)
89719410Sguido			m->m_flags |= M_RTALERT_MLD;
89819410Sguido
89919410Sguido		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
90019410Sguido	}
90119410Sguido	goto out;
90219410Sguidobad:
90319410Sguido	m_freem(m);
90419410Sguidoout:
90519410Sguido	if (rin6.ro_rt)
90619410Sguido		RTFREE(rin6.ro_rt);
90719410Sguido}
90819410Sguido
90919410Sguido/*
91019410Sguido * set/grab in6_ifaddr correspond to IPv6 destination address.
91119410Sguido * XXX backward compatibility wrapper
91219410Sguido */
91319410Sguidostatic struct ip6aux *
91419410Sguidoip6_setdstifaddr(struct mbuf *m, struct in6_ifaddr *ia6)
91519410Sguido{
91619410Sguido	struct ip6aux *ip6a;
91719410Sguido
91819410Sguido	ip6a = ip6_addaux(m);
91919410Sguido	if (ip6a)
92019410Sguido		ip6a->ip6a_dstia6 = ia6;
92119410Sguido	return ip6a;	/* NULL if failed to set */
92219410Sguido}
92319410Sguido
92419410Sguidostruct in6_ifaddr *
92568417Swpaulip6_getdstifaddr(struct mbuf *m)
92619410Sguido{
92719410Sguido	struct ip6aux *ip6a;
92819410Sguido
92919410Sguido	ip6a = ip6_findaux(m);
93019410Sguido	if (ip6a)
93119410Sguido		return ip6a->ip6a_dstia6;
93219410Sguido	else
93319410Sguido		return NULL;
93419410Sguido}
93519410Sguido
93619410Sguido/*
93719410Sguido * Hop-by-Hop options header processing. If a valid jumbo payload option is
93819410Sguido * included, the real payload length will be stored in plenp.
93919410Sguido *
94019410Sguido * rtalertp - XXX: should be stored more smart way
94119410Sguido */
94268417Swpaulstatic int
94368417Swpaulip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
94419410Sguido    struct mbuf **mp, int *offp)
94568417Swpaul{
94668417Swpaul	INIT_VNET_INET6(curvnet);
94719410Sguido	struct mbuf *m = *mp;
94868417Swpaul	int off = *offp, hbhlen;
94919410Sguido	struct ip6_hbh *hbh;
95068417Swpaul	u_int8_t *opt;
95119410Sguido
95268417Swpaul	/* validation of the length of the header */
95368417Swpaul#ifndef PULLDOWN_TEST
95468417Swpaul	IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1);
95568417Swpaul	hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
95619410Sguido	hbhlen = (hbh->ip6h_len + 1) << 3;
95719410Sguido
95819410Sguido	IP6_EXTHDR_CHECK(m, off, hbhlen, -1);
95919410Sguido	hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
96019410Sguido#else
96119410Sguido	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
96219410Sguido		sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
96319410Sguido	if (hbh == NULL) {
96419410Sguido		V_ip6stat.ip6s_tooshort++;
96519410Sguido		return -1;
96619410Sguido	}
96768417Swpaul	hbhlen = (hbh->ip6h_len + 1) << 3;
96819410Sguido	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
96919410Sguido		hbhlen);
97019410Sguido	if (hbh == NULL) {
97119410Sguido		V_ip6stat.ip6s_tooshort++;
97219410Sguido		return -1;
97319410Sguido	}
97419410Sguido#endif
97519410Sguido	off += hbhlen;
97619410Sguido	hbhlen -= sizeof(struct ip6_hbh);
97719410Sguido	opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh);
97819410Sguido
97919410Sguido	if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
98019410Sguido				hbhlen, rtalertp, plenp) < 0)
98119410Sguido		return (-1);
98219410Sguido
98319410Sguido	*offp = off;
98419410Sguido	*mp = m;
98519410Sguido	return (0);
98619410Sguido}
98719410Sguido
98819410Sguido/*
98919410Sguido * Search header for all Hop-by-hop options and process each option.
99019410Sguido * This function is separate from ip6_hopopts_input() in order to
99119410Sguido * handle a case where the sending node itself process its hop-by-hop
99219410Sguido * options header. In such a case, the function is called from ip6_output().
99319410Sguido *
99419410Sguido * The function assumes that hbh header is located right after the IPv6 header
99519410Sguido * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
99619410Sguido * opthead + hbhlen is located in continuous memory region.
99719410Sguido */
99829671Sgibbsint
99929671Sgibbsip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
100029671Sgibbs    u_int32_t *rtalertp, u_int32_t *plenp)
100129671Sgibbs{
100229671Sgibbs	INIT_VNET_INET6(curvnet);
100329671Sgibbs	struct ip6_hdr *ip6;
100419410Sguido	int optlen = 0;
100519410Sguido	u_int8_t *opt = opthead;
100619410Sguido	u_int16_t rtalert_val;
100719410Sguido	u_int32_t jumboplen;
100819410Sguido	const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
100919410Sguido
101019410Sguido	for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
101119410Sguido		switch (*opt) {
101219410Sguido		case IP6OPT_PAD1:
101319410Sguido			optlen = 1;
101419410Sguido			break;
101519410Sguido		case IP6OPT_PADN:
101619410Sguido			if (hbhlen < IP6OPT_MINLEN) {
101719410Sguido				V_ip6stat.ip6s_toosmall++;
101819410Sguido				goto bad;
101919410Sguido			}
102019410Sguido			optlen = *(opt + 1) + 2;
102129671Sgibbs			break;
102229671Sgibbs		case IP6OPT_ROUTER_ALERT:
102319410Sguido			/* XXX may need check for alignment */
102419410Sguido			if (hbhlen < IP6OPT_RTALERT_LEN) {
1025				V_ip6stat.ip6s_toosmall++;
1026				goto bad;
1027			}
1028			if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
1029				/* XXX stat */
1030				icmp6_error(m, ICMP6_PARAM_PROB,
1031				    ICMP6_PARAMPROB_HEADER,
1032				    erroff + opt + 1 - opthead);
1033				return (-1);
1034			}
1035			optlen = IP6OPT_RTALERT_LEN;
1036			bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2);
1037			*rtalertp = ntohs(rtalert_val);
1038			break;
1039		case IP6OPT_JUMBO:
1040			/* XXX may need check for alignment */
1041			if (hbhlen < IP6OPT_JUMBO_LEN) {
1042				V_ip6stat.ip6s_toosmall++;
1043				goto bad;
1044			}
1045			if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
1046				/* XXX stat */
1047				icmp6_error(m, ICMP6_PARAM_PROB,
1048				    ICMP6_PARAMPROB_HEADER,
1049				    erroff + opt + 1 - opthead);
1050				return (-1);
1051			}
1052			optlen = IP6OPT_JUMBO_LEN;
1053
1054			/*
1055			 * IPv6 packets that have non 0 payload length
1056			 * must not contain a jumbo payload option.
1057			 */
1058			ip6 = mtod(m, struct ip6_hdr *);
1059			if (ip6->ip6_plen) {
1060				V_ip6stat.ip6s_badoptions++;
1061				icmp6_error(m, ICMP6_PARAM_PROB,
1062				    ICMP6_PARAMPROB_HEADER,
1063				    erroff + opt - opthead);
1064				return (-1);
1065			}
1066
1067			/*
1068			 * We may see jumbolen in unaligned location, so
1069			 * we'd need to perform bcopy().
1070			 */
1071			bcopy(opt + 2, &jumboplen, sizeof(jumboplen));
1072			jumboplen = (u_int32_t)htonl(jumboplen);
1073
1074#if 1
1075			/*
1076			 * if there are multiple jumbo payload options,
1077			 * *plenp will be non-zero and the packet will be
1078			 * rejected.
1079			 * the behavior may need some debate in ipngwg -
1080			 * multiple options does not make sense, however,
1081			 * there's no explicit mention in specification.
1082			 */
1083			if (*plenp != 0) {
1084				V_ip6stat.ip6s_badoptions++;
1085				icmp6_error(m, ICMP6_PARAM_PROB,
1086				    ICMP6_PARAMPROB_HEADER,
1087				    erroff + opt + 2 - opthead);
1088				return (-1);
1089			}
1090#endif
1091
1092			/*
1093			 * jumbo payload length must be larger than 65535.
1094			 */
1095			if (jumboplen <= IPV6_MAXPACKET) {
1096				V_ip6stat.ip6s_badoptions++;
1097				icmp6_error(m, ICMP6_PARAM_PROB,
1098				    ICMP6_PARAMPROB_HEADER,
1099				    erroff + opt + 2 - opthead);
1100				return (-1);
1101			}
1102			*plenp = jumboplen;
1103
1104			break;
1105		default:		/* unknown option */
1106			if (hbhlen < IP6OPT_MINLEN) {
1107				V_ip6stat.ip6s_toosmall++;
1108				goto bad;
1109			}
1110			optlen = ip6_unknown_opt(opt, m,
1111			    erroff + opt - opthead);
1112			if (optlen == -1)
1113				return (-1);
1114			optlen += 2;
1115			break;
1116		}
1117	}
1118
1119	return (0);
1120
1121  bad:
1122	m_freem(m);
1123	return (-1);
1124}
1125
1126/*
1127 * Unknown option processing.
1128 * The third argument `off' is the offset from the IPv6 header to the option,
1129 * which is necessary if the IPv6 header the and option header and IPv6 header
1130 * is not continuous in order to return an ICMPv6 error.
1131 */
1132int
1133ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
1134{
1135	INIT_VNET_INET6(curvnet);
1136	struct ip6_hdr *ip6;
1137
1138	switch (IP6OPT_TYPE(*optp)) {
1139	case IP6OPT_TYPE_SKIP: /* ignore the option */
1140		return ((int)*(optp + 1));
1141	case IP6OPT_TYPE_DISCARD:	/* silently discard */
1142		m_freem(m);
1143		return (-1);
1144	case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
1145		V_ip6stat.ip6s_badoptions++;
1146		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
1147		return (-1);
1148	case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
1149		V_ip6stat.ip6s_badoptions++;
1150		ip6 = mtod(m, struct ip6_hdr *);
1151		if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
1152		    (m->m_flags & (M_BCAST|M_MCAST)))
1153			m_freem(m);
1154		else
1155			icmp6_error(m, ICMP6_PARAM_PROB,
1156				    ICMP6_PARAMPROB_OPTION, off);
1157		return (-1);
1158	}
1159
1160	m_freem(m);		/* XXX: NOTREACHED */
1161	return (-1);
1162}
1163
1164/*
1165 * Create the "control" list for this pcb.
1166 * These functions will not modify mbuf chain at all.
1167 *
1168 * With KAME mbuf chain restriction:
1169 * The routine will be called from upper layer handlers like tcp6_input().
1170 * Thus the routine assumes that the caller (tcp6_input) have already
1171 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
1172 * very first mbuf on the mbuf chain.
1173 *
1174 * ip6_savecontrol_v4 will handle those options that are possible to be
1175 * set on a v4-mapped socket.
1176 * ip6_savecontrol will directly call ip6_savecontrol_v4 to handle those
1177 * options and handle the v6-only ones itself.
1178 */
1179struct mbuf **
1180ip6_savecontrol_v4(struct inpcb *inp, struct mbuf *m, struct mbuf **mp,
1181    int *v4only)
1182{
1183	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1184
1185#ifdef SO_TIMESTAMP
1186	if ((inp->inp_socket->so_options & SO_TIMESTAMP) != 0) {
1187		struct timeval tv;
1188
1189		microtime(&tv);
1190		*mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
1191		    SCM_TIMESTAMP, SOL_SOCKET);
1192		if (*mp)
1193			mp = &(*mp)->m_next;
1194	}
1195#endif
1196
1197	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
1198		if (v4only != NULL)
1199			*v4only = 1;
1200		return (mp);
1201	}
1202
1203#define IS2292(inp, x, y)	(((inp)->inp_flags & IN6P_RFC2292) ? (x) : (y))
1204	/* RFC 2292 sec. 5 */
1205	if ((inp->inp_flags & IN6P_PKTINFO) != 0) {
1206		struct in6_pktinfo pi6;
1207
1208		bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr));
1209		in6_clearscope(&pi6.ipi6_addr);	/* XXX */
1210		pi6.ipi6_ifindex =
1211		    (m && m->m_pkthdr.rcvif) ? m->m_pkthdr.rcvif->if_index : 0;
1212
1213		*mp = sbcreatecontrol((caddr_t) &pi6,
1214		    sizeof(struct in6_pktinfo),
1215		    IS2292(inp, IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6);
1216		if (*mp)
1217			mp = &(*mp)->m_next;
1218	}
1219
1220	if ((inp->inp_flags & IN6P_HOPLIMIT) != 0) {
1221		int hlim = ip6->ip6_hlim & 0xff;
1222
1223		*mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int),
1224		    IS2292(inp, IPV6_2292HOPLIMIT, IPV6_HOPLIMIT),
1225		    IPPROTO_IPV6);
1226		if (*mp)
1227			mp = &(*mp)->m_next;
1228	}
1229
1230	if (v4only != NULL)
1231		*v4only = 0;
1232	return (mp);
1233}
1234
1235void
1236ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
1237{
1238	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1239	int v4only = 0;
1240
1241	mp = ip6_savecontrol_v4(in6p, m, mp, &v4only);
1242	if (v4only)
1243		return;
1244
1245	if ((in6p->inp_flags & IN6P_TCLASS) != 0) {
1246		u_int32_t flowinfo;
1247		int tclass;
1248
1249		flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK);
1250		flowinfo >>= 20;
1251
1252		tclass = flowinfo & 0xff;
1253		*mp = sbcreatecontrol((caddr_t) &tclass, sizeof(tclass),
1254		    IPV6_TCLASS, IPPROTO_IPV6);
1255		if (*mp)
1256			mp = &(*mp)->m_next;
1257	}
1258
1259	/*
1260	 * IPV6_HOPOPTS socket option.  Recall that we required super-user
1261	 * privilege for the option (see ip6_ctloutput), but it might be too
1262	 * strict, since there might be some hop-by-hop options which can be
1263	 * returned to normal user.
1264	 * See also RFC 2292 section 6 (or RFC 3542 section 8).
1265	 */
1266	if ((in6p->inp_flags & IN6P_HOPOPTS) != 0) {
1267		/*
1268		 * Check if a hop-by-hop options header is contatined in the
1269		 * received packet, and if so, store the options as ancillary
1270		 * data. Note that a hop-by-hop options header must be
1271		 * just after the IPv6 header, which is assured through the
1272		 * IPv6 input processing.
1273		 */
1274		if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
1275			struct ip6_hbh *hbh;
1276			int hbhlen = 0;
1277#ifdef PULLDOWN_TEST
1278			struct mbuf *ext;
1279#endif
1280
1281#ifndef PULLDOWN_TEST
1282			hbh = (struct ip6_hbh *)(ip6 + 1);
1283			hbhlen = (hbh->ip6h_len + 1) << 3;
1284#else
1285			ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
1286			    ip6->ip6_nxt);
1287			if (ext == NULL) {
1288				V_ip6stat.ip6s_tooshort++;
1289				return;
1290			}
1291			hbh = mtod(ext, struct ip6_hbh *);
1292			hbhlen = (hbh->ip6h_len + 1) << 3;
1293			if (hbhlen != ext->m_len) {
1294				m_freem(ext);
1295				V_ip6stat.ip6s_tooshort++;
1296				return;
1297			}
1298#endif
1299
1300			/*
1301			 * XXX: We copy the whole header even if a
1302			 * jumbo payload option is included, the option which
1303			 * is to be removed before returning according to
1304			 * RFC2292.
1305			 * Note: this constraint is removed in RFC3542
1306			 */
1307			*mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
1308			    IS2292(in6p, IPV6_2292HOPOPTS, IPV6_HOPOPTS),
1309			    IPPROTO_IPV6);
1310			if (*mp)
1311				mp = &(*mp)->m_next;
1312#ifdef PULLDOWN_TEST
1313			m_freem(ext);
1314#endif
1315		}
1316	}
1317
1318	if ((in6p->inp_flags & (IN6P_RTHDR | IN6P_DSTOPTS)) != 0) {
1319		int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);
1320
1321		/*
1322		 * Search for destination options headers or routing
1323		 * header(s) through the header chain, and stores each
1324		 * header as ancillary data.
1325		 * Note that the order of the headers remains in
1326		 * the chain of ancillary data.
1327		 */
1328		while (1) {	/* is explicit loop prevention necessary? */
1329			struct ip6_ext *ip6e = NULL;
1330			int elen;
1331#ifdef PULLDOWN_TEST
1332			struct mbuf *ext = NULL;
1333#endif
1334
1335			/*
1336			 * if it is not an extension header, don't try to
1337			 * pull it from the chain.
1338			 */
1339			switch (nxt) {
1340			case IPPROTO_DSTOPTS:
1341			case IPPROTO_ROUTING:
1342			case IPPROTO_HOPOPTS:
1343			case IPPROTO_AH: /* is it possible? */
1344				break;
1345			default:
1346				goto loopend;
1347			}
1348
1349#ifndef PULLDOWN_TEST
1350			if (off + sizeof(*ip6e) > m->m_len)
1351				goto loopend;
1352			ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off);
1353			if (nxt == IPPROTO_AH)
1354				elen = (ip6e->ip6e_len + 2) << 2;
1355			else
1356				elen = (ip6e->ip6e_len + 1) << 3;
1357			if (off + elen > m->m_len)
1358				goto loopend;
1359#else
1360			ext = ip6_pullexthdr(m, off, nxt);
1361			if (ext == NULL) {
1362				V_ip6stat.ip6s_tooshort++;
1363				return;
1364			}
1365			ip6e = mtod(ext, struct ip6_ext *);
1366			if (nxt == IPPROTO_AH)
1367				elen = (ip6e->ip6e_len + 2) << 2;
1368			else
1369				elen = (ip6e->ip6e_len + 1) << 3;
1370			if (elen != ext->m_len) {
1371				m_freem(ext);
1372				V_ip6stat.ip6s_tooshort++;
1373				return;
1374			}
1375#endif
1376
1377			switch (nxt) {
1378			case IPPROTO_DSTOPTS:
1379				if (!(in6p->inp_flags & IN6P_DSTOPTS))
1380					break;
1381
1382				*mp = sbcreatecontrol((caddr_t)ip6e, elen,
1383				    IS2292(in6p,
1384					IPV6_2292DSTOPTS, IPV6_DSTOPTS),
1385				    IPPROTO_IPV6);
1386				if (*mp)
1387					mp = &(*mp)->m_next;
1388				break;
1389			case IPPROTO_ROUTING:
1390				if (!in6p->inp_flags & IN6P_RTHDR)
1391					break;
1392
1393				*mp = sbcreatecontrol((caddr_t)ip6e, elen,
1394				    IS2292(in6p, IPV6_2292RTHDR, IPV6_RTHDR),
1395				    IPPROTO_IPV6);
1396				if (*mp)
1397					mp = &(*mp)->m_next;
1398				break;
1399			case IPPROTO_HOPOPTS:
1400			case IPPROTO_AH: /* is it possible? */
1401				break;
1402
1403			default:
1404				/*
1405				 * other cases have been filtered in the above.
1406				 * none will visit this case.  here we supply
1407				 * the code just in case (nxt overwritten or
1408				 * other cases).
1409				 */
1410#ifdef PULLDOWN_TEST
1411				m_freem(ext);
1412#endif
1413				goto loopend;
1414
1415			}
1416
1417			/* proceed with the next header. */
1418			off += elen;
1419			nxt = ip6e->ip6e_nxt;
1420			ip6e = NULL;
1421#ifdef PULLDOWN_TEST
1422			m_freem(ext);
1423			ext = NULL;
1424#endif
1425		}
1426	  loopend:
1427		;
1428	}
1429}
1430#undef IS2292
1431
1432void
1433ip6_notify_pmtu(struct inpcb *in6p, struct sockaddr_in6 *dst, u_int32_t *mtu)
1434{
1435	struct socket *so;
1436	struct mbuf *m_mtu;
1437	struct ip6_mtuinfo mtuctl;
1438
1439	so =  in6p->inp_socket;
1440
1441	if (mtu == NULL)
1442		return;
1443
1444#ifdef DIAGNOSTIC
1445	if (so == NULL)		/* I believe this is impossible */
1446		panic("ip6_notify_pmtu: socket is NULL");
1447#endif
1448
1449	bzero(&mtuctl, sizeof(mtuctl));	/* zero-clear for safety */
1450	mtuctl.ip6m_mtu = *mtu;
1451	mtuctl.ip6m_addr = *dst;
1452	if (sa6_recoverscope(&mtuctl.ip6m_addr))
1453		return;
1454
1455	if ((m_mtu = sbcreatecontrol((caddr_t)&mtuctl, sizeof(mtuctl),
1456	    IPV6_PATHMTU, IPPROTO_IPV6)) == NULL)
1457		return;
1458
1459	if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu)
1460	    == 0) {
1461		m_freem(m_mtu);
1462		/* XXX: should count statistics */
1463	} else
1464		sorwakeup(so);
1465
1466	return;
1467}
1468
1469#ifdef PULLDOWN_TEST
1470/*
1471 * pull single extension header from mbuf chain.  returns single mbuf that
1472 * contains the result, or NULL on error.
1473 */
1474static struct mbuf *
1475ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
1476{
1477	struct ip6_ext ip6e;
1478	size_t elen;
1479	struct mbuf *n;
1480
1481#ifdef DIAGNOSTIC
1482	switch (nxt) {
1483	case IPPROTO_DSTOPTS:
1484	case IPPROTO_ROUTING:
1485	case IPPROTO_HOPOPTS:
1486	case IPPROTO_AH: /* is it possible? */
1487		break;
1488	default:
1489		printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
1490	}
1491#endif
1492
1493	m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1494	if (nxt == IPPROTO_AH)
1495		elen = (ip6e.ip6e_len + 2) << 2;
1496	else
1497		elen = (ip6e.ip6e_len + 1) << 3;
1498
1499	MGET(n, M_DONTWAIT, MT_DATA);
1500	if (n && elen >= MLEN) {
1501		MCLGET(n, M_DONTWAIT);
1502		if ((n->m_flags & M_EXT) == 0) {
1503			m_free(n);
1504			n = NULL;
1505		}
1506	}
1507	if (!n)
1508		return NULL;
1509
1510	n->m_len = 0;
1511	if (elen >= M_TRAILINGSPACE(n)) {
1512		m_free(n);
1513		return NULL;
1514	}
1515
1516	m_copydata(m, off, elen, mtod(n, caddr_t));
1517	n->m_len = elen;
1518	return n;
1519}
1520#endif
1521
1522/*
1523 * Get pointer to the previous header followed by the header
1524 * currently processed.
1525 * XXX: This function supposes that
1526 *	M includes all headers,
1527 *	the next header field and the header length field of each header
1528 *	are valid, and
1529 *	the sum of each header length equals to OFF.
1530 * Because of these assumptions, this function must be called very
1531 * carefully. Moreover, it will not be used in the near future when
1532 * we develop `neater' mechanism to process extension headers.
1533 */
1534char *
1535ip6_get_prevhdr(struct mbuf *m, int off)
1536{
1537	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1538
1539	if (off == sizeof(struct ip6_hdr))
1540		return (&ip6->ip6_nxt);
1541	else {
1542		int len, nxt;
1543		struct ip6_ext *ip6e = NULL;
1544
1545		nxt = ip6->ip6_nxt;
1546		len = sizeof(struct ip6_hdr);
1547		while (len < off) {
1548			ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len);
1549
1550			switch (nxt) {
1551			case IPPROTO_FRAGMENT:
1552				len += sizeof(struct ip6_frag);
1553				break;
1554			case IPPROTO_AH:
1555				len += (ip6e->ip6e_len + 2) << 2;
1556				break;
1557			default:
1558				len += (ip6e->ip6e_len + 1) << 3;
1559				break;
1560			}
1561			nxt = ip6e->ip6e_nxt;
1562		}
1563		if (ip6e)
1564			return (&ip6e->ip6e_nxt);
1565		else
1566			return NULL;
1567	}
1568}
1569
1570/*
1571 * get next header offset.  m will be retained.
1572 */
1573int
1574ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp)
1575{
1576	struct ip6_hdr ip6;
1577	struct ip6_ext ip6e;
1578	struct ip6_frag fh;
1579
1580	/* just in case */
1581	if (m == NULL)
1582		panic("ip6_nexthdr: m == NULL");
1583	if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off)
1584		return -1;
1585
1586	switch (proto) {
1587	case IPPROTO_IPV6:
1588		if (m->m_pkthdr.len < off + sizeof(ip6))
1589			return -1;
1590		m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6);
1591		if (nxtp)
1592			*nxtp = ip6.ip6_nxt;
1593		off += sizeof(ip6);
1594		return off;
1595
1596	case IPPROTO_FRAGMENT:
1597		/*
1598		 * terminate parsing if it is not the first fragment,
1599		 * it does not make sense to parse through it.
1600		 */
1601		if (m->m_pkthdr.len < off + sizeof(fh))
1602			return -1;
1603		m_copydata(m, off, sizeof(fh), (caddr_t)&fh);
1604		/* IP6F_OFF_MASK = 0xfff8(BigEndian), 0xf8ff(LittleEndian) */
1605		if (fh.ip6f_offlg & IP6F_OFF_MASK)
1606			return -1;
1607		if (nxtp)
1608			*nxtp = fh.ip6f_nxt;
1609		off += sizeof(struct ip6_frag);
1610		return off;
1611
1612	case IPPROTO_AH:
1613		if (m->m_pkthdr.len < off + sizeof(ip6e))
1614			return -1;
1615		m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1616		if (nxtp)
1617			*nxtp = ip6e.ip6e_nxt;
1618		off += (ip6e.ip6e_len + 2) << 2;
1619		return off;
1620
1621	case IPPROTO_HOPOPTS:
1622	case IPPROTO_ROUTING:
1623	case IPPROTO_DSTOPTS:
1624		if (m->m_pkthdr.len < off + sizeof(ip6e))
1625			return -1;
1626		m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1627		if (nxtp)
1628			*nxtp = ip6e.ip6e_nxt;
1629		off += (ip6e.ip6e_len + 1) << 3;
1630		return off;
1631
1632	case IPPROTO_NONE:
1633	case IPPROTO_ESP:
1634	case IPPROTO_IPCOMP:
1635		/* give up */
1636		return -1;
1637
1638	default:
1639		return -1;
1640	}
1641
1642	return -1;
1643}
1644
1645/*
1646 * get offset for the last header in the chain.  m will be kept untainted.
1647 */
1648int
1649ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp)
1650{
1651	int newoff;
1652	int nxt;
1653
1654	if (!nxtp) {
1655		nxt = -1;
1656		nxtp = &nxt;
1657	}
1658	while (1) {
1659		newoff = ip6_nexthdr(m, off, proto, nxtp);
1660		if (newoff < 0)
1661			return off;
1662		else if (newoff < off)
1663			return -1;	/* invalid */
1664		else if (newoff == off)
1665			return newoff;
1666
1667		off = newoff;
1668		proto = *nxtp;
1669	}
1670}
1671
1672struct ip6aux *
1673ip6_addaux(struct mbuf *m)
1674{
1675	struct m_tag *mtag;
1676
1677	mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
1678	if (!mtag) {
1679		mtag = m_tag_get(PACKET_TAG_IPV6_INPUT, sizeof(struct ip6aux),
1680		    M_NOWAIT);
1681		if (mtag) {
1682			m_tag_prepend(m, mtag);
1683			bzero(mtag + 1, sizeof(struct ip6aux));
1684		}
1685	}
1686	return mtag ? (struct ip6aux *)(mtag + 1) : NULL;
1687}
1688
1689struct ip6aux *
1690ip6_findaux(struct mbuf *m)
1691{
1692	struct m_tag *mtag;
1693
1694	mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
1695	return mtag ? (struct ip6aux *)(mtag + 1) : NULL;
1696}
1697
1698void
1699ip6_delaux(struct mbuf *m)
1700{
1701	struct m_tag *mtag;
1702
1703	mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
1704	if (mtag)
1705		m_tag_delete(m, mtag);
1706}
1707
1708/*
1709 * System control for IP6
1710 */
1711
1712u_char	inet6ctlerrmap[PRC_NCMDS] = {
1713	0,		0,		0,		0,
1714	0,		EMSGSIZE,	EHOSTDOWN,	EHOSTUNREACH,
1715	EHOSTUNREACH,	EHOSTUNREACH,	ECONNREFUSED,	ECONNREFUSED,
1716	EMSGSIZE,	EHOSTUNREACH,	0,		0,
1717	0,		0,		0,		0,
1718	ENOPROTOOPT
1719};
1720