[BACK]Return to ip6_input.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet6

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/netinet6/ip6_input.c between version 1.35 and 1.41.2.2

version 1.35, 2001/02/10 04:14:28 version 1.41.2.2, 2002/01/10 20:03:20
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
 /*      $KAME: ip6_input.c,v 1.174 2001/02/09 06:17:41 jinmei Exp $     */  /*      $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
   
 /*  /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.   * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Line 65 
Line 65 
  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94   *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
  */   */
   
   #include <sys/cdefs.h>
   __KERNEL_RCSID(0, "$NetBSD$");
   
 #include "opt_inet.h"  #include "opt_inet.h"
 #include "opt_ipsec.h"  #include "opt_ipsec.h"
 #include "opt_pfil_hooks.h"  #include "opt_pfil_hooks.h"
Line 82 
Line 85 
 #include <sys/kernel.h>  #include <sys/kernel.h>
 #include <sys/syslog.h>  #include <sys/syslog.h>
 #include <sys/proc.h>  #include <sys/proc.h>
   #include <sys/sysctl.h>
   
 #include <net/if.h>  #include <net/if.h>
 #include <net/if_types.h>  #include <net/if_types.h>
Line 97 
Line 101 
 #ifdef INET  #ifdef INET
 #include <netinet/ip.h>  #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>  #include <netinet/ip_icmp.h>
 #endif /*INET*/  #endif /* INET */
 #include <netinet/ip6.h>  #include <netinet/ip6.h>
 #include <netinet6/in6_var.h>  #include <netinet6/in6_var.h>
 #include <netinet6/ip6_var.h>  #include <netinet6/ip6_var.h>
Line 107 
Line 111 
 #include <netinet6/nd6.h>  #include <netinet6/nd6.h>
 #include <netinet6/in6_prefix.h>  #include <netinet6/in6_prefix.h>
   
   #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. */
 #include "loop.h"  #include "loop.h"
 #include "faith.h"  #include "faith.h"
   
 #include "gif.h"  #include "gif.h"
 #include "bpfilter.h"  #include "bpfilter.h"
   
   #if NGIF > 0
   #include <netinet6/in6_gif.h>
   #endif
   
 #include <net/net_osdep.h>  #include <net/net_osdep.h>
   
 extern struct domain inet6domain;  extern struct domain inet6domain;
Line 212  ip6intr()
Line 223  ip6intr()
         struct mbuf *m;          struct mbuf *m;
   
         for (;;) {          for (;;) {
                 s = splimp();                  s = splnet();
                 IF_DEQUEUE(&ip6intrq, m);                  IF_DEQUEUE(&ip6intrq, m);
                 splx(s);                  splx(s);
                 if (m == 0)                  if (m == 0)
Line 239  ip6_input(m)
Line 250  ip6_input(m)
          * should the inner packet be considered authentic?           * should the inner packet be considered authentic?
          * see comment in ah4_input().           * see comment in ah4_input().
          */           */
         if (m) {          m->m_flags &= ~M_AUTHIPHDR;
                 m->m_flags &= ~M_AUTHIPHDR;          m->m_flags &= ~M_AUTHIPDGM;
                 m->m_flags &= ~M_AUTHIPDGM;  
         }  
 #endif  #endif
   
         /*          /*
          * mbuf statistics by kazu           * mbuf statistics
          */           */
         if (m->m_flags & M_EXT) {          if (m->m_flags & M_EXT) {
                 if (m->m_next)                  if (m->m_next)
Line 254  ip6_input(m)
Line 263  ip6_input(m)
                 else                  else
                         ip6stat.ip6s_mext1++;                          ip6stat.ip6s_mext1++;
         } else {          } else {
   #define M2MMAX  (sizeof(ip6stat.ip6s_m2m)/sizeof(ip6stat.ip6s_m2m[0]))
                 if (m->m_next) {                  if (m->m_next) {
                         if (m->m_flags & M_LOOP) {                          if (m->m_flags & M_LOOP) {
                                 ip6stat.ip6s_m2m[loif[0].if_index]++;   /*XXX*/                                  ip6stat.ip6s_m2m[loif[0].if_index]++; /* XXX */
                         } else if (m->m_pkthdr.rcvif->if_index <= 31)                          } else if (m->m_pkthdr.rcvif->if_index < M2MMAX)
                                 ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;                                  ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
                         else                          else
                                 ip6stat.ip6s_m2m[0]++;                                  ip6stat.ip6s_m2m[0]++;
                 } else                  } else
                         ip6stat.ip6s_m1++;                          ip6stat.ip6s_m1++;
   #undef M2MMAX
         }          }
   
         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);          in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);
Line 299  ip6_input(m)
Line 310  ip6_input(m)
          * Note that filters must _never_ set this flag, as another filter           * Note that filters must _never_ set this flag, as another filter
          * in the list may have previously cleared it.           * in the list may have previously cleared it.
          */           */
         if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif,          /*
                            PFIL_IN) != 0)           * let ipfilter look at packet on the wire,
                 return;           * not the decapsulated packet.
         if (m == NULL)           */
                 return;  #ifdef IPSEC
         ip6 = mtod(m, struct ip6_hdr *);          if (!ipsec_getnhist(m))
   #else
           if (1)
   #endif
           {
                   if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif,
                                      PFIL_IN) != 0)
                           return;
                   if (m == NULL)
                           return;
                   ip6 = mtod(m, struct ip6_hdr *);
           }
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
   
   
         ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;          ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
   
 #ifdef ALTQ  #ifdef ALTQ
         /* XXX Temporary until ALTQ is changed to use a pfil hook */  
         if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {          if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
                 /* packet is dropped by traffic conditioner */                  /* packet is dropped by traffic conditioner */
                 return;                  return;
Line 319  ip6_input(m)
Line 339  ip6_input(m)
 #endif  #endif
   
         /*          /*
          * Scope check           * Check against address spoofing/corruption.
          */           */
         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||          if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
             IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {              IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
Line 328  ip6_input(m)
Line 348  ip6_input(m)
                 goto bad;                  goto bad;
         }          }
         /*          /*
          * The following check is not documented in the spec.  Malicious party           * The following check is not documented in specs.  A malicious
          * may be able to use IPv4 mapped addr to confuse tcp/udp stack and           * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
          * bypass security checks (act as if it was from 127.0.0.1 by using           * 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.           * IPv6 src ::ffff:127.0.0.1).  Be cautious.
          *           *
          * This check chokes if we are in SIIT cloud.  As none of BSDs support           * This check chokes if we are in an SIIT cloud.  As none of BSDs
          * IPv4-less kernel compilation, we cannot support SIIT environment           * support IPv4-less kernel compilation, we cannot support SIIT
          * at all.  So, it makes more sense for us to reject any malicious           * environment at all.  So, it makes more sense for us to reject any
          * packets for non-SIIT environment, than try to do a partical support           * malicious packets for non-SIIT environment, than try to do a
          * for SIIT environment.           * partical support for SIIT environment.
          */           */
         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||          if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {              IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
Line 374  ip6_input(m)
Line 394  ip6_input(m)
                 }                  }
         }          }
   
 #ifndef FAKE_LOOPBACK_IF          /* drop packets if interface ID portion is already filled */
         if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0)          if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
 #else                  if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src) &&
         if (1)                      ip6->ip6_src.s6_addr16[1]) {
 #endif                          ip6stat.ip6s_badscope++;
         {                          goto bad;
                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))                  }
                         ip6->ip6_src.s6_addr16[1]                  if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst) &&
                                 = htons(m->m_pkthdr.rcvif->if_index);                      ip6->ip6_dst.s6_addr16[1]) {
                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))                          ip6stat.ip6s_badscope++;
                         ip6->ip6_dst.s6_addr16[1]                          goto bad;
                                 = htons(m->m_pkthdr.rcvif->if_index);                  }
         }          }
   
         /*          if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
          * XXX we need this since we do not have "goto ours" hack route                  ip6->ip6_src.s6_addr16[1]
          * for some of our ifaddrs on loopback interface.                          = htons(m->m_pkthdr.rcvif->if_index);
          * we should correct it by changing in6_ifattach to install          if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
          * "goto ours" hack route.                  ip6->ip6_dst.s6_addr16[1]
          */                          = htons(m->m_pkthdr.rcvif->if_index);
         if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0) {  
                 if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) {          /*
                         ours = 1;           * We use rt->rt_ifp to determine if the address is ours or not.
                         deliverifp = m->m_pkthdr.rcvif;           * If rt_ifp is lo0, the address is ours.
                         goto hbhcheck;           * The problem here is, rt->rt_ifp for fe80::%lo0/64 is set to lo0,
            * so any address under fe80::%lo0/64 will be mistakenly considered
            * local.  The special case is supplied to handle the case properly
            * by actually looking at interface addresses
            * (using in6ifa_ifpwithaddr).
            */
           if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0 &&
               IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) {
                   if (!in6ifa_ifpwithaddr(m->m_pkthdr.rcvif, &ip6->ip6_dst)) {
                           icmp6_error(m, ICMP6_DST_UNREACH,
                               ICMP6_DST_UNREACH_ADDR, 0);
                           /* m is already freed */
                           return;
                 }                  }
   
                   ours = 1;
                   deliverifp = m->m_pkthdr.rcvif;
                   goto hbhcheck;
         }          }
   
         /*          /*
Line 510  ip6_input(m)
Line 546  ip6_input(m)
                  && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {                   && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {
                         /* XXX do we need more sanity checks? */                          /* XXX do we need more sanity checks? */
                         ours = 1;                          ours = 1;
                         deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /*faith*/                          deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /* faith */
                         goto hbhcheck;                          goto hbhcheck;
                 }                  }
         }          }
Line 571  ip6_input(m)
Line 607  ip6_input(m)
                 ip6 = mtod(m, struct ip6_hdr *);                  ip6 = mtod(m, struct ip6_hdr *);
   
                 /*                  /*
                  * if the payload length field is 0 and the next header field                   * if the payload length field is 0 and the next header field
                  * indicates Hop-by-Hop Options header, then a Jumbo Payload                   * indicates Hop-by-Hop Options header, then a Jumbo Payload
                  * option MUST be included.                   * option MUST be included.
                  */                   */
Line 688  ip6_input(m)
Line 724  ip6_input(m)
         ip6stat.ip6s_delivered++;          ip6stat.ip6s_delivered++;
         in6_ifstat_inc(deliverifp, ifs6_in_deliver);          in6_ifstat_inc(deliverifp, ifs6_in_deliver);
         nest = 0;          nest = 0;
   
         while (nxt != IPPROTO_DONE) {          while (nxt != IPPROTO_DONE) {
                 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {                  if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
                         ip6stat.ip6s_toomanyhdr++;                          ip6stat.ip6s_toomanyhdr++;
Line 704  ip6_input(m)
Line 741  ip6_input(m)
                         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 1162  ip6_savecontrol(in6p, mp, ip6, m)
Line 1212  ip6_savecontrol(in6p, mp, ip6, m)
                         nxt = ip6e->ip6e_nxt;                          nxt = ip6e->ip6e_nxt;
                 }                  }
           loopend:            loopend:
                   ;
         }          }
         if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) {          if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) {
                 /* to be done */                  /* to be done */
Line 1275  ip6_nexthdr(m, off, proto, nxtp)
Line 1326  ip6_nexthdr(m, off, proto, nxtp)
                 if (nxtp)                  if (nxtp)
                         *nxtp = ip6e.ip6e_nxt;                          *nxtp = ip6e.ip6e_nxt;
                 off += (ip6e.ip6e_len + 2) << 2;                  off += (ip6e.ip6e_len + 2) << 2;
                   if (m->m_pkthdr.len < off)
                           return -1;
                 return off;                  return off;
   
         case IPPROTO_HOPOPTS:          case IPPROTO_HOPOPTS:
Line 1286  ip6_nexthdr(m, off, proto, nxtp)
Line 1339  ip6_nexthdr(m, off, proto, nxtp)
                 if (nxtp)                  if (nxtp)
                         *nxtp = ip6e.ip6e_nxt;                          *nxtp = ip6e.ip6e_nxt;
                 off += (ip6e.ip6e_len + 1) << 3;                  off += (ip6e.ip6e_len + 1) << 3;
                   if (m->m_pkthdr.len < off)
                           return -1;
                 return off;                  return off;
   
         case IPPROTO_NONE:          case IPPROTO_NONE:
Line 1345  u_char inet6ctlerrmap[PRC_NCMDS] = {
Line 1400  u_char inet6ctlerrmap[PRC_NCMDS] = {
         ENOPROTOOPT          ENOPROTOOPT
 };  };
   
 #include <uvm/uvm_extern.h>  
 #include <sys/sysctl.h>  
   
 int  int
 ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen)  ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
         int *name;          int *name;
Line 1395  ip6_sysctl(name, namelen, oldp, oldlenp,
Line 1447  ip6_sysctl(name, namelen, oldp, oldlenp,
         case IPV6CTL_DEFMCASTHLIM:          case IPV6CTL_DEFMCASTHLIM:
                 return sysctl_int(oldp, oldlenp, newp, newlen,                  return sysctl_int(oldp, oldlenp, newp, newlen,
                                 &ip6_defmcasthlim);                                  &ip6_defmcasthlim);
   #if NGIF > 0
         case IPV6CTL_GIF_HLIM:          case IPV6CTL_GIF_HLIM:
                 return sysctl_int(oldp, oldlenp, newp, newlen,                  return sysctl_int(oldp, oldlenp, newp, newlen,
                                 &ip6_gif_hlim);                                  &ip6_gif_hlim);
   #endif
         case IPV6CTL_KAME_VERSION:          case IPV6CTL_KAME_VERSION:
                 return sysctl_rdstring(oldp, oldlenp, newp, __KAME_VERSION);                  return sysctl_rdstring(oldp, oldlenp, newp, __KAME_VERSION);
         case IPV6CTL_USE_DEPRECATED:          case IPV6CTL_USE_DEPRECATED:
Line 1405  ip6_sysctl(name, namelen, oldp, oldlenp,
Line 1459  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);
 #ifndef INET6_BINDV6ONLY          case IPV6CTL_V6ONLY:
         case IPV6CTL_BINDV6ONLY:  #ifdef INET6_BINDV6ONLY
                 return sysctl_int(oldp, oldlenp, newp, newlen,                  return sysctl_rdint(oldp, oldlenp, newp, ip6_v6only);
                                 &ip6_bindv6only);  #else
                   return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_v6only);
 #endif  #endif
         case IPV6CTL_ANONPORTMIN:          case IPV6CTL_ANONPORTMIN:
                 old = ip6_anonportmin;                  old = ip6_anonportmin;

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.41.2.2

CVSweb <webmaster@jp.NetBSD.org>