Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet6/ip6_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet6/ip6_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.9 retrieving revision 1.15 diff -u -p -r1.9 -r1.15 --- src/sys/netinet6/ip6_input.c 1999/12/13 15:17:22 1.9 +++ src/sys/netinet6/ip6_input.c 2000/02/17 10:59:39 1.15 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_input.c,v 1.9 1999/12/13 15:17:22 itojun Exp $ */ +/* $NetBSD: ip6_input.c,v 1.15 2000/02/17 10:59:39 darrenr Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -64,15 +64,9 @@ * @(#)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" -#ifdef __NetBSD__ /*XXX*/ #include "opt_ipsec.h" -#endif -#endif +#include "opt_pfil_hooks.h" #include #include @@ -86,15 +80,16 @@ #include #include #include -#if !defined(__bsdi__) && !(defined(__FreeBSD__) && __FreeBSD__ < 3) #include -#endif #include #include #include #include #include +#ifdef PFIL_HOOKS +#include +#endif #include #include @@ -102,16 +97,11 @@ #include #include #endif /*INET*/ -#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__OpenBSD__) || (defined(__bsdi__) && _BSDI_VERSION >= 199802) -#include -#endif +#include #include -#include -#if !((defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__OpenBSD__) || (defined(__bsdi__) && _BSDI_VERSION >= 199802)) -#include -#endif #include -#include +#include +#include #include #include #include @@ -123,9 +113,7 @@ #include /* we need it for NLOOP. */ -#ifndef __bsdi__ #include "loop.h" -#endif #include "faith.h" #include "gif.h" @@ -133,28 +121,14 @@ #include -#ifdef __OpenBSD__ /*KAME IPSEC*/ -#undef IPSEC -#endif - extern struct domain inet6domain; -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]; static int ip6qmaxlen = IFQ_MAXLEN; struct in6_ifaddr *in6_ifaddr; struct ifqueue ip6intrq; -#if defined(__NetBSD__) || defined(__OpenBSD__) extern struct ifnet loif[NLOOP]; -#endif int ip6_forward_srcrt; /* XXX */ int ip6_sourcecheck; /* XXX */ int ip6_sourcecheck_interval; /* XXX */ @@ -171,7 +145,7 @@ static void ip6_init2 __P((void *)); 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; int ptr_in6 __P((struct mbuf *, struct mbuf **)); @@ -212,9 +186,7 @@ ip6_init() microtime(&tv); ip6_flow_seq = random() ^ tv.tv_usec; -#ifndef __FreeBSD__ ip6_init2((void *)0); -#endif } static void @@ -222,9 +194,6 @@ ip6_init2(dummy) void *dummy; { int ret; -#if defined(__bsdi__) && _BSDI_VERSION < 199802 - struct ifnet *loifp = &loif; -#endif /* get EUI64 from somewhere */ ret = in6_ifattach_getifid(NULL); @@ -233,11 +202,7 @@ ip6_init2(dummy) * to route local address of p2p link to loopback, * assign loopback address first. */ -#ifdef __bsdi__ - in6_ifattach(loifp, IN6_IFT_LOOP, NULL, 0); -#else in6_ifattach(&loif[0], IN6_IFT_LOOP, NULL, 0); -#endif /* nd6_timer_init */ timeout(nd6_timer, (caddr_t)0, hz); @@ -245,11 +210,6 @@ ip6_init2(dummy) 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. */ @@ -269,10 +229,6 @@ ip6intr() } } -#ifdef __FreeBSD__ -NETISR_SET(NETISR_IPV6, ip6intr); -#endif - extern struct route_in6 ip6_forward_rt; void @@ -285,9 +241,11 @@ ip6_input(m) u_int32_t rtalert = ~0; int nxt, ours = 0; struct ifnet *deliverifp = NULL; -#if defined(__bsdi__) && _BSDI_VERSION < 199802 - struct ifnet *loifp = &loif; -#endif +#ifdef PFIL_HOOKS + struct packet_filter_hook *pfh; + struct mbuf *m0; + int rv; +#endif /* PFIL_HOOKS */ #ifdef IPSEC /* @@ -311,11 +269,7 @@ ip6_input(m) } else { if (m->m_next) { if (m->m_flags & M_LOOP) { -#ifdef __bsdi__ - ip6stat.ip6s_m2m[loifp->if_index]++; /*XXX*/ -#else ip6stat.ip6s_m2m[loif[0].if_index]++; /*XXX*/ -#endif } else if (m->m_pkthdr.rcvif->if_index <= 31) ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++; @@ -351,6 +305,30 @@ ip6_input(m) goto bad; } +#ifdef PFIL_HOOKS + /* + * Run through list of hooks for input packets. If there are any + * filters which require that additional packets in the flow are + * not fast-forwarded, they must clear the M_CANFASTFWD flag. + * Note that filters must _never_ set this flag, as another filter + * in the list may have previously cleared it. + */ + m0 = m; + pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IPV6]]); + for (; pfh; pfh = pfh->pfil_link.tqe_next) + if (pfh->pfil_func) { + rv = pfh->pfil_func(ip6, sizeof(*ip6), + m->m_pkthdr.rcvif, 0, &m0); + if (rv) + return; + m = m0; + if (m == NULL) + return; + ip6 = mtod(m, struct ip6_hdr *); + } +#endif /* PFIL_HOOKS */ + + ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; #ifdef IPV6FIREWALL @@ -379,6 +357,29 @@ ip6_input(m) in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); goto bad; } + /* + * The following check is not documented in the spec. Malicious party + * may be able to use IPv4 mapped addr to confuse tcp/udp stack and + * bypass security checks (act as if it was from 127.0.0.1 by using + * IPv6 src ::ffff:127.0.0.1). Be cautious. + */ + if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || + IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { + ip6stat.ip6s_badscope++; + in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); + goto bad; + } +#if 1 + /* + * We don't support it, so it is strange to get this. + */ + if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || + IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { + ip6stat.ip6s_badscope++; + in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); + goto bad; + } +#endif if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) { if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) { @@ -407,7 +408,7 @@ ip6_input(m) = htons(m->m_pkthdr.rcvif->if_index); } -#if defined(PTR) +#ifdef PTR /* * */ @@ -472,11 +473,7 @@ ip6_input(m) ip6_forward_rt.ro_dst.sin6_family = AF_INET6; 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); -#endif } #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) @@ -656,7 +653,7 @@ ip6_input(m) /* * Tell launch routine the next header */ -#if defined(__NetBSD__) && defined(IFA_STATS) +#ifdef IFA_STATS if (IFA_STATS && deliverifp != NULL) { struct in6_ifaddr *ia6; ip6 = mtod(m, struct ip6_hdr *); @@ -915,39 +912,17 @@ ip6_unknown_opt(optp, m, off) */ void ip6_savecontrol(in6p, mp, ip6, m) -#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(HAVE_NRL_INPCB) - register struct inpcb *in6p; -#else register struct in6pcb *in6p; -#endif register struct mbuf **mp; register struct ip6_hdr *ip6; 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 */ -#endif -#ifdef __bsdi__ -# define sbcreatecontrol so_cmsg -#endif int privileged; privileged = 0; -#if defined(__NetBSD__) || (defined(__FreeBSD__) && __FreeBSD__ >= 3) if (p && !suser(p->p_ucred, &p->p_acflag)) 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 if (in6p->in6p_socket->so_options & SO_TIMESTAMP) { @@ -1152,12 +1127,6 @@ ip6_savecontrol(in6p, mp, ip6, m) } /* IN6P_RTHDR - to be done */ -#ifdef __bsdi__ -# undef sbcreatecontrol -#endif -#ifdef __OpenBSD__ -# undef in6p_flags -#endif } /* @@ -1223,7 +1192,6 @@ u_char inet6ctlerrmap[PRC_NCMDS] = { ENOPROTOOPT }; -#if defined(__NetBSD__) || defined(__OpenBSD__) #include #include @@ -1280,37 +1248,15 @@ ip6_sysctl(name, namelen, oldp, oldlenp, case IPV6CTL_USE_DEPRECATED: return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_use_deprecated); + case IPV6CTL_RR_PRUNE: + return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune); +#ifndef INET6_BINDV6ONLY + case IPV6CTL_BINDV6ONLY: + return sysctl_int(oldp, oldlenp, newp, newlen, + &ip6_bindv6only); +#endif default: return EOPNOTSUPP; } /* 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__ */