| version 1.11, 2000/01/06 06:41:19 |
version 1.12, 2000/01/06 15:46:09 |
|
|
| * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 |
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94 |
| */ |
*/ |
| |
|
| #ifdef __FreeBSD__ |
|
| #include "opt_ip6fw.h" |
|
| #endif |
|
| #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__) |
|
| #include "opt_inet.h" |
#include "opt_inet.h" |
| #ifdef __NetBSD__ /*XXX*/ |
|
| #include "opt_ipsec.h" |
#include "opt_ipsec.h" |
| #endif |
|
| #endif |
|
| |
|
| #include <sys/param.h> |
#include <sys/param.h> |
| #include <sys/systm.h> |
#include <sys/systm.h> |
|
|
| #include <sys/time.h> |
#include <sys/time.h> |
| #include <sys/kernel.h> |
#include <sys/kernel.h> |
| #include <sys/syslog.h> |
#include <sys/syslog.h> |
| #if !defined(__bsdi__) && !(defined(__FreeBSD__) && __FreeBSD__ < 3) |
|
| #include <sys/proc.h> |
#include <sys/proc.h> |
| #endif |
|
| |
|
| #include <net/if.h> |
#include <net/if.h> |
| #include <net/if_types.h> |
#include <net/if_types.h> |
|
|
| #include <netinet/ip.h> |
#include <netinet/ip.h> |
| #include <netinet/ip_icmp.h> |
#include <netinet/ip_icmp.h> |
| #endif /*INET*/ |
#endif /*INET*/ |
| #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__OpenBSD__) || (defined(__bsdi__) && _BSDI_VERSION >= 199802) |
|
| #include <netinet/in_pcb.h> |
|
| #endif |
|
| #include <netinet6/ip6.h> |
#include <netinet6/ip6.h> |
| #include <netinet6/in6_var.h> |
#include <netinet6/in6_var.h> |
| #include <netinet6/ip6_var.h> |
#include <netinet6/ip6_var.h> |
| #if !((defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__OpenBSD__) || (defined(__bsdi__) && _BSDI_VERSION >= 199802)) |
|
| #include <netinet6/in6_pcb.h> |
#include <netinet6/in6_pcb.h> |
| #endif |
|
| #include <netinet6/icmp6.h> |
#include <netinet6/icmp6.h> |
| #include <netinet6/in6_ifattach.h> |
#include <netinet6/in6_ifattach.h> |
| #include <netinet6/nd6.h> |
#include <netinet6/nd6.h> |
|
|
| #include <netinet6/ip6protosw.h> |
#include <netinet6/ip6protosw.h> |
| |
|
| /* we need it for NLOOP. */ |
/* we need it for NLOOP. */ |
| #ifndef __bsdi__ |
|
| #include "loop.h" |
#include "loop.h" |
| #endif |
|
| #include "faith.h" |
#include "faith.h" |
| |
|
| #include "gif.h" |
#include "gif.h" |
|
|
| |
|
| #include <net/net_osdep.h> |
#include <net/net_osdep.h> |
| |
|
| #ifdef __OpenBSD__ /*KAME IPSEC*/ |
|
| #undef IPSEC |
|
| #endif |
|
| |
|
| extern struct domain inet6domain; |
extern struct domain inet6domain; |
| extern struct ip6protosw inet6sw[]; |
extern struct ip6protosw inet6sw[]; |
| #ifdef __bsdi__ |
|
| #if _BSDI_VERSION < 199802 |
|
| extern struct ifnet loif; |
|
| #else |
|
| extern struct ifnet *loifp; |
|
| #endif |
|
| #endif |
|
| |
|
| u_char ip6_protox[IPPROTO_MAX]; |
u_char ip6_protox[IPPROTO_MAX]; |
| static int ip6qmaxlen = IFQ_MAXLEN; |
static int ip6qmaxlen = IFQ_MAXLEN; |
| struct in6_ifaddr *in6_ifaddr; |
struct in6_ifaddr *in6_ifaddr; |
| struct ifqueue ip6intrq; |
struct ifqueue ip6intrq; |
| |
|
| #if defined(__NetBSD__) || defined(__OpenBSD__) |
|
| extern struct ifnet loif[NLOOP]; |
extern struct ifnet loif[NLOOP]; |
| #endif |
|
| int ip6_forward_srcrt; /* XXX */ |
int ip6_forward_srcrt; /* XXX */ |
| int ip6_sourcecheck; /* XXX */ |
int ip6_sourcecheck; /* XXX */ |
| int ip6_sourcecheck_interval; /* XXX */ |
int ip6_sourcecheck_interval; /* XXX */ |
| Line 171 static void ip6_init2 __P((void *)); |
|
| Line 142 static void ip6_init2 __P((void *)); |
|
| |
|
| static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *)); |
static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *)); |
| |
|
| #if defined(PTR) |
#ifdef PTR |
| extern int ip6_protocol_tr; |
extern int ip6_protocol_tr; |
| |
|
| int ptr_in6 __P((struct mbuf *, struct mbuf **)); |
int ptr_in6 __P((struct mbuf *, struct mbuf **)); |
|
|
| microtime(&tv); |
microtime(&tv); |
| ip6_flow_seq = random() ^ tv.tv_usec; |
ip6_flow_seq = random() ^ tv.tv_usec; |
| |
|
| #ifndef __FreeBSD__ |
|
| ip6_init2((void *)0); |
ip6_init2((void *)0); |
| #endif |
|
| } |
} |
| |
|
| static void |
static void |
| Line 222 ip6_init2(dummy) |
|
| Line 191 ip6_init2(dummy) |
|
| void *dummy; |
void *dummy; |
| { |
{ |
| int ret; |
int ret; |
| #if defined(__bsdi__) && _BSDI_VERSION < 199802 |
|
| struct ifnet *loifp = &loif; |
|
| #endif |
|
| |
|
| /* get EUI64 from somewhere */ |
/* get EUI64 from somewhere */ |
| ret = in6_ifattach_getifid(NULL); |
ret = in6_ifattach_getifid(NULL); |
| Line 233 ip6_init2(dummy) |
|
| Line 199 ip6_init2(dummy) |
|
| * to route local address of p2p link to loopback, |
* to route local address of p2p link to loopback, |
| * assign loopback address first. |
* assign loopback address first. |
| */ |
*/ |
| #ifdef __bsdi__ |
|
| in6_ifattach(loifp, IN6_IFT_LOOP, NULL, 0); |
|
| #else |
|
| in6_ifattach(&loif[0], IN6_IFT_LOOP, NULL, 0); |
in6_ifattach(&loif[0], IN6_IFT_LOOP, NULL, 0); |
| #endif |
|
| |
|
| /* nd6_timer_init */ |
/* nd6_timer_init */ |
| timeout(nd6_timer, (caddr_t)0, hz); |
timeout(nd6_timer, (caddr_t)0, hz); |
| Line 245 ip6_init2(dummy) |
|
| Line 207 ip6_init2(dummy) |
|
| timeout(in6_rr_timer, (caddr_t)0, hz); |
timeout(in6_rr_timer, (caddr_t)0, hz); |
| } |
} |
| |
|
| #ifdef __FreeBSD__ |
|
| /* cheat */ |
|
| SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_init2, NULL); |
|
| #endif |
|
| |
|
| /* |
/* |
| * IP6 input interrupt handling. Just pass the packet to ip6_input. |
* IP6 input interrupt handling. Just pass the packet to ip6_input. |
| */ |
*/ |
|
|
| } |
} |
| } |
} |
| |
|
| #ifdef __FreeBSD__ |
|
| NETISR_SET(NETISR_IPV6, ip6intr); |
|
| #endif |
|
| |
|
| extern struct route_in6 ip6_forward_rt; |
extern struct route_in6 ip6_forward_rt; |
| |
|
| void |
void |
|
|
| u_int32_t rtalert = ~0; |
u_int32_t rtalert = ~0; |
| int nxt, ours = 0; |
int nxt, ours = 0; |
| struct ifnet *deliverifp = NULL; |
struct ifnet *deliverifp = NULL; |
| #if defined(__bsdi__) && _BSDI_VERSION < 199802 |
|
| struct ifnet *loifp = &loif; |
|
| #endif |
|
| |
|
| #ifdef IPSEC |
#ifdef IPSEC |
| /* |
/* |
|
|
| } else { |
} else { |
| if (m->m_next) { |
if (m->m_next) { |
| if (m->m_flags & M_LOOP) { |
if (m->m_flags & M_LOOP) { |
| #ifdef __bsdi__ |
|
| ip6stat.ip6s_m2m[loifp->if_index]++; /*XXX*/ |
|
| #else |
|
| ip6stat.ip6s_m2m[loif[0].if_index]++; /*XXX*/ |
ip6stat.ip6s_m2m[loif[0].if_index]++; /*XXX*/ |
| #endif |
|
| } |
} |
| else if (m->m_pkthdr.rcvif->if_index <= 31) |
else if (m->m_pkthdr.rcvif->if_index <= 31) |
| ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++; |
ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++; |
|
|
| = htons(m->m_pkthdr.rcvif->if_index); |
= htons(m->m_pkthdr.rcvif->if_index); |
| } |
} |
| |
|
| #if defined(PTR) |
#ifdef PTR |
| /* |
/* |
| * |
* |
| */ |
*/ |
|
|
| ip6_forward_rt.ro_dst.sin6_family = AF_INET6; |
ip6_forward_rt.ro_dst.sin6_family = AF_INET6; |
| ip6_forward_rt.ro_dst.sin6_addr = ip6->ip6_dst; |
ip6_forward_rt.ro_dst.sin6_addr = ip6->ip6_dst; |
| |
|
| #ifdef __FreeBSD__ |
|
| rtalloc_ign((struct route *)&ip6_forward_rt, RTF_PRCLONING); |
|
| #else |
|
| rtalloc((struct route *)&ip6_forward_rt); |
rtalloc((struct route *)&ip6_forward_rt); |
| #endif |
|
| } |
} |
| |
|
| #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) |
#define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) |
|
|
| /* |
/* |
| * Tell launch routine the next header |
* Tell launch routine the next header |
| */ |
*/ |
| #if defined(__NetBSD__) && defined(IFA_STATS) |
#ifdef IFA_STATS |
| if (IFA_STATS && deliverifp != NULL) { |
if (IFA_STATS && deliverifp != NULL) { |
| struct in6_ifaddr *ia6; |
struct in6_ifaddr *ia6; |
| ip6 = mtod(m, struct ip6_hdr *); |
ip6 = mtod(m, struct ip6_hdr *); |
| Line 915 ip6_unknown_opt(optp, m, off) |
|
| Line 857 ip6_unknown_opt(optp, m, off) |
|
| */ |
*/ |
| void |
void |
| ip6_savecontrol(in6p, mp, ip6, m) |
ip6_savecontrol(in6p, mp, ip6, m) |
| #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(HAVE_NRL_INPCB) |
|
| register struct inpcb *in6p; |
|
| #else |
|
| register struct in6pcb *in6p; |
register struct in6pcb *in6p; |
| #endif |
|
| register struct mbuf **mp; |
register struct mbuf **mp; |
| register struct ip6_hdr *ip6; |
register struct ip6_hdr *ip6; |
| register struct mbuf *m; |
register struct mbuf *m; |
| { |
{ |
| #ifdef HAVE_NRL_INPCB |
|
| # define in6p_flags inp_flags |
|
| #endif |
|
| #if defined(__NetBSD__) || (defined(__FreeBSD__) && __FreeBSD__ >= 3) |
|
| struct proc *p = curproc; /* XXX */ |
struct proc *p = curproc; /* XXX */ |
| #endif |
|
| #ifdef __bsdi__ |
|
| # define sbcreatecontrol so_cmsg |
|
| #endif |
|
| int privileged; |
int privileged; |
| |
|
| privileged = 0; |
privileged = 0; |
| #if defined(__NetBSD__) || (defined(__FreeBSD__) && __FreeBSD__ >= 3) |
|
| if (p && !suser(p->p_ucred, &p->p_acflag)) |
if (p && !suser(p->p_ucred, &p->p_acflag)) |
| privileged++; |
privileged++; |
| #else |
|
| #ifdef HAVE_NRL_INPCB |
|
| if ((in6p->inp_socket->so_state & SS_PRIV) != 0) |
|
| privileged++; |
|
| #else |
|
| if ((in6p->in6p_socket->so_state & SS_PRIV) != 0) |
|
| privileged++; |
|
| #endif |
|
| #endif |
|
| |
|
| #ifdef SO_TIMESTAMP |
#ifdef SO_TIMESTAMP |
| if (in6p->in6p_socket->so_options & SO_TIMESTAMP) { |
if (in6p->in6p_socket->so_options & SO_TIMESTAMP) { |
| Line 1152 ip6_savecontrol(in6p, mp, ip6, m) |
|
| Line 1072 ip6_savecontrol(in6p, mp, ip6, m) |
|
| } |
} |
| /* IN6P_RTHDR - to be done */ |
/* IN6P_RTHDR - to be done */ |
| |
|
| #ifdef __bsdi__ |
|
| # undef sbcreatecontrol |
|
| #endif |
|
| #ifdef __OpenBSD__ |
|
| # undef in6p_flags |
|
| #endif |
|
| } |
} |
| |
|
| /* |
/* |
| Line 1223 u_char inet6ctlerrmap[PRC_NCMDS] = { |
|
| Line 1137 u_char inet6ctlerrmap[PRC_NCMDS] = { |
|
| ENOPROTOOPT |
ENOPROTOOPT |
| }; |
}; |
| |
|
| #if defined(__NetBSD__) || defined(__OpenBSD__) |
|
| #include <vm/vm.h> |
#include <vm/vm.h> |
| #include <sys/sysctl.h> |
#include <sys/sysctl.h> |
| |
|
| Line 1282 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1195 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| &ip6_use_deprecated); |
&ip6_use_deprecated); |
| case IPV6CTL_RR_PRUNE: |
case IPV6CTL_RR_PRUNE: |
| return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune); |
return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune); |
| #if defined(__NetBSD__) && !defined(INET6_BINDV6ONLY) |
#ifndef INET6_BINDV6ONLY |
| case IPV6CTL_BINDV6ONLY: |
case IPV6CTL_BINDV6ONLY: |
| return sysctl_int(oldp, oldlenp, newp, newlen, |
return sysctl_int(oldp, oldlenp, newp, newlen, |
| &ip6_bindv6only); |
&ip6_bindv6only); |
| Line 1292 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1205 ip6_sysctl(name, namelen, oldp, oldlenp, |
|
| } |
} |
| /* NOTREACHED */ |
/* NOTREACHED */ |
| } |
} |
| #endif /* __NetBSD__ || __OpenBSD__ */ |
|
| |
|
| #ifdef __bsdi__ |
|
| int *ip6_sysvars[] = IPV6CTL_VARS; |
|
| |
|
| int |
|
| ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen) |
|
| int *name; |
|
| u_int namelen; |
|
| void *oldp; |
|
| size_t *oldlenp; |
|
| void *newp; |
|
| size_t newlen; |
|
| { |
|
| if (name[0] >= IPV6CTL_MAXID) |
|
| return (EOPNOTSUPP); |
|
| |
|
| switch (name[0]) { |
|
| case IPV6CTL_STATS: |
|
| return sysctl_rdtrunc(oldp, oldlenp, newp, &ip6stat, |
|
| sizeof(ip6stat)); |
|
| case IPV6CTL_KAME_VERSION: |
|
| return sysctl_rdstring(oldp, oldlenp, newp, __KAME_VERSION); |
|
| default: |
|
| return (sysctl_int_arr(ip6_sysvars, name, namelen, |
|
| oldp, oldlenp, newp, newlen)); |
|
| } |
|
| } |
|
| #endif /* __bsdi__ */ |
|