| version 1.22, 2000/06/13 14:43:44 |
version 1.22.2.4, 2001/04/06 01:37:35 |
|
|
| /* $NetBSD$ */ |
/* $NetBSD$ */ |
| /* $KAME: ip6_input.c,v 1.94 2000/06/13 10:06:19 jinmei Exp $ */ |
/* $KAME: ip6_input.c,v 1.119 2000/08/26 10:00:45 itojun Exp $ */ |
| |
|
| /* |
/* |
| * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
|
|
| #include <netinet6/ip6_fw.h> |
#include <netinet6/ip6_fw.h> |
| #endif |
#endif |
| |
|
| |
#ifdef IPSEC |
| |
#include <netinet6/ipsec.h> |
| |
#endif |
| |
|
| #include <netinet6/ip6protosw.h> |
#include <netinet6/ip6protosw.h> |
| |
|
| /* we need it for NLOOP. */ |
/* we need it for NLOOP. */ |
|
|
| * in the list may have previously cleared it. |
* in the list may have previously cleared it. |
| */ |
*/ |
| m0 = m; |
m0 = m; |
| |
#ifdef IPSEC |
| |
if (ipsec_gethist(m, NULL)) |
| |
pfh = NULL; |
| |
else |
| |
pfh = pfil_hook_get(PFIL_IN, |
| |
&inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); |
| |
#else |
| pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); |
pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); |
| |
#endif |
| for (; pfh; pfh = pfh->pfil_link.tqe_next) |
for (; pfh; pfh = pfh->pfil_link.tqe_next) |
| if (pfh->pfil_func) { |
if (pfh->pfil_func) { |
| rv = pfh->pfil_func(ip6, sizeof(*ip6), |
rv = pfh->pfil_func(ip6, sizeof(*ip6), |
|
|
| ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) { |
ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) { |
| struct in6_ifaddr *ia6 = |
struct in6_ifaddr *ia6 = |
| (struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa; |
(struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa; |
| /* packet to tentative address must not be received */ |
|
| if (ia6->ia6_flags & IN6_IFF_ANYCAST) |
if (ia6->ia6_flags & IN6_IFF_ANYCAST) |
| m->m_flags |= M_ANYCAST6; |
m->m_flags |= M_ANYCAST6; |
| |
/* |
| |
* packets to a tentative, duplicated, or somehow invalid |
| |
* address must not be accepted. |
| |
*/ |
| if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { |
if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { |
| /* this interface is ready */ |
/* this address is ready */ |
| ours = 1; |
ours = 1; |
| deliverifp = ia6->ia_ifp; /* correct? */ |
deliverifp = ia6->ia_ifp; /* correct? */ |
| goto hbhcheck; |
goto hbhcheck; |
| } else { |
} else { |
| /* this interface is not ready, fall through */ |
/* address is not ready, so discard the packet. */ |
| |
log(LOG_INFO, |
| |
"ip6_input: packet to an unready address %s->%s", |
| |
ip6_sprintf(&ip6->ip6_src), |
| |
ip6_sprintf(&ip6->ip6_dst)); |
| |
|
| |
goto bad; |
| } |
} |
| } |
} |
| |
|
|
|
| goto bad; |
goto bad; |
| } |
} |
| |
|
| |
#ifdef IPSEC |
| |
/* |
| |
* enforce IPsec policy checking if we are seeing last header. |
| |
* note that we do not visit this with protocols with pcb layer |
| |
* code - like udp/tcp/raw ip. |
| |
*/ |
| |
if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && |
| |
ipsec6_in_reject(m, NULL)) { |
| |
ipsec6stat.in_polvio++; |
| |
goto bad; |
| |
} |
| |
#endif |
| |
|
| nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); |
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); |
| } |
} |
| return; |
return; |
| Line 1337 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1371 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| void *newp; |
void *newp; |
| size_t newlen; |
size_t newlen; |
| { |
{ |
| |
int old, error; |
| |
|
| /* All sysctl names at this level are terminal. */ |
/* All sysctl names at this level are terminal. */ |
| if (namelen != 1) |
if (namelen != 1) |
| return ENOTDIR; |
return ENOTDIR; |
| Line 1388 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1424 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| return sysctl_int(oldp, oldlenp, newp, newlen, |
return sysctl_int(oldp, oldlenp, newp, newlen, |
| &ip6_bindv6only); |
&ip6_bindv6only); |
| #endif |
#endif |
| |
case IPV6CTL_ANONPORTMIN: |
| |
old = ip6_anonportmin; |
| |
error = sysctl_int(oldp, oldlenp, newp, newlen, |
| |
&ip6_anonportmin); |
| |
if (ip6_anonportmin >= ip6_anonportmax || ip6_anonportmin < 0 || |
| |
ip6_anonportmin > 65535 |
| |
#ifndef IPNOPRIVPORTS |
| |
|| ip6_anonportmin < IPV6PORT_RESERVED |
| |
#endif |
| |
) { |
| |
ip6_anonportmin = old; |
| |
return (EINVAL); |
| |
} |
| |
return (error); |
| |
case IPV6CTL_ANONPORTMAX: |
| |
old = ip6_anonportmax; |
| |
error = sysctl_int(oldp, oldlenp, newp, newlen, |
| |
&ip6_anonportmax); |
| |
if (ip6_anonportmin >= ip6_anonportmax || ip6_anonportmax < 0 || |
| |
ip6_anonportmax > 65535 |
| |
#ifndef IPNOPRIVPORTS |
| |
|| ip6_anonportmax < IPV6PORT_RESERVED |
| |
#endif |
| |
) { |
| |
ip6_anonportmax = old; |
| |
return (EINVAL); |
| |
} |
| |
return (error); |
| |
#ifndef IPNOPRIVPORTS |
| |
case IPV6CTL_LOWPORTMIN: |
| |
old = ip6_lowportmin; |
| |
error = sysctl_int(oldp, oldlenp, newp, newlen, |
| |
&ip6_lowportmin); |
| |
if (ip6_lowportmin >= ip6_lowportmax || |
| |
ip6_lowportmin > IPV6PORT_RESERVEDMAX || |
| |
ip6_lowportmin < IPV6PORT_RESERVEDMIN) { |
| |
ip6_lowportmin = old; |
| |
return (EINVAL); |
| |
} |
| |
return (error); |
| |
case IPV6CTL_LOWPORTMAX: |
| |
old = ip6_lowportmax; |
| |
error = sysctl_int(oldp, oldlenp, newp, newlen, |
| |
&ip6_lowportmax); |
| |
if (ip6_lowportmin >= ip6_lowportmax || |
| |
ip6_lowportmax > IPV6PORT_RESERVEDMAX || |
| |
ip6_lowportmax < IPV6PORT_RESERVEDMIN) { |
| |
ip6_lowportmax = old; |
| |
return (EINVAL); |
| |
} |
| |
return (error); |
| |
#endif |
| default: |
default: |
| return EOPNOTSUPP; |
return EOPNOTSUPP; |
| } |
} |