[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.193 and 1.193.2.7

version 1.193, 2018/02/24 07:37:09 version 1.193.2.7, 2019/01/18 08:50:58
Line 123  __KERNEL_RCSID(0, "$NetBSD$");
Line 123  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include "faith.h"  #include "faith.h"
   
 #include <net/net_osdep.h>  
   
 extern struct domain inet6domain;  extern struct domain inet6domain;
   
 u_char ip6_protox[IPPROTO_MAX];  u_char ip6_protox[IPPROTO_MAX];
Line 138  percpu_t *ip6_forward_rt_percpu __cachel
Line 136  percpu_t *ip6_forward_rt_percpu __cachel
   
 static void ip6_init2(void);  static void ip6_init2(void);
 static void ip6intr(void *);  static void ip6intr(void *);
   static bool ip6_badaddr(struct ip6_hdr *);
 static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);  static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);
   
 static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,  static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
Line 320  ip6_input(struct mbuf *m, struct ifnet *
Line 319  ip6_input(struct mbuf *m, struct ifnet *
                 goto bad;                  goto bad;
         }          }
   
           if (ip6_badaddr(ip6)) {
                   IP6_STATINC(IP6_STAT_BADSCOPE);
                   in6_ifstat_inc(rcvif, ifs6_in_addrerr);
                   goto bad;
           }
   
         /*          /*
          * Assume that we can create a fast-forward IP flow entry           * Assume that we can create a fast-forward IP flow entry
          * based on this packet.           * based on this packet.
Line 332  ip6_input(struct mbuf *m, struct ifnet *
Line 337  ip6_input(struct mbuf *m, struct ifnet *
          * not fast-forwarded, they must clear the M_CANFASTFWD flag.           * not fast-forwarded, they must clear the M_CANFASTFWD flag.
          * 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.
          */           *
         /*           * Don't call hooks if the packet has already been processed by
          * let ipfilter look at packet on the wire,           * IPsec (encapsulated, tunnel mode).
          * not the decapsulated packet.  
          */           */
 #if defined(IPSEC)  #if defined(IPSEC)
         if (!ipsec_used || !ipsec_indone(m))          if (!ipsec_used || !ipsec_skip_pfil(m))
 #else  #else
         if (1)          if (1)
 #endif  #endif
Line 350  ip6_input(struct mbuf *m, struct ifnet *
Line 354  ip6_input(struct mbuf *m, struct ifnet *
                         return;                          return;
                 if (m == NULL)                  if (m == NULL)
                         return;                          return;
                   KASSERT(m->m_len >= sizeof(struct ip6_hdr));
                 ip6 = mtod(m, struct ip6_hdr *);                  ip6 = mtod(m, struct ip6_hdr *);
                 srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);                  srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
         }          }
Line 369  ip6_input(struct mbuf *m, struct ifnet *
Line 374  ip6_input(struct mbuf *m, struct ifnet *
 #endif  #endif
   
         /*          /*
          * Check against address spoofing/corruption.  
          */  
         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||  
             IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {  
                 /*  
                  * XXX: "badscope" is not very suitable for a multicast source.  
                  */  
                 IP6_STATINC(IP6_STAT_BADSCOPE);  
                 in6_ifstat_inc(rcvif, ifs6_in_addrerr);  
                 goto bad;  
         }  
   
         /*  
          * The following check is not documented in specs.  A 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.  
          *  
          * This check chokes if we are in an SIIT cloud.  As none of BSDs  
          * support IPv4-less kernel compilation, we cannot support SIIT  
          * environment at all.  So, it makes more sense for us to reject any  
          * malicious packets for non-SIIT environment, than try to do a  
          * partial support for SIIT environment.  
          */  
         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||  
             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {  
                 IP6_STATINC(IP6_STAT_BADSCOPE);  
                 in6_ifstat_inc(rcvif, ifs6_in_addrerr);  
                 goto bad;  
         }  
   
 #if 0  
         /*  
          * Reject packets with IPv4 compatible addresses (auto tunnel).  
          *  
          * The code forbids auto tunnel relay case in RFC1933 (the check is  
          * stronger than RFC1933).  We may want to re-enable it if mech-xx  
          * is revised to forbid relaying case.  
          */  
         if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||  
             IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {  
                 IP6_STATINC(IP6_STAT_BADSCOPE);  
                 in6_ifstat_inc(rcvif, ifs6_in_addrerr);  
                 goto bad;  
         }  
 #endif  
   
         /*  
          * Disambiguate address scope zones (if there is ambiguity).           * Disambiguate address scope zones (if there is ambiguity).
          * We first make sure that the original source or destination address           * We first make sure that the original source or destination address
          * is not in our internal form for scoped addresses.  Such addresses           * is not in our internal form for scoped addresses.  Such addresses
Line 749  hbhcheck:
Line 706  hbhcheck:
                         goto bad;                          goto bad;
                 }                  }
   
                   M_VERIFY_PACKET(m);
   
                 /*                  /*
                  * protection against faulty packet - there should be                   * protection against faulty packet - there should be
                  * more sanity checks in header chain processing.                   * more sanity checks in header chain processing.
Line 780  hbhcheck:
Line 739  hbhcheck:
                          * header. Note that we do not visit this with                           * header. Note that we do not visit this with
                          * protocols with pcb layer code - like udp/tcp/raw ip.                           * protocols with pcb layer code - like udp/tcp/raw ip.
                          */                           */
                         if ((inet6sw[ip_protox[nxt]].pr_flags                          if ((inet6sw[ip6_protox[nxt]].pr_flags
                             & PR_LASTHDR) != 0) {                              & PR_LASTHDR) != 0) {
                                 int error;                                  int error;
   
                                 error = ipsec6_input(m);                                  error = ipsec_ip_input(m, false);
                                 if (error)                                  if (error)
                                         goto bad;                                          goto bad;
                         }                          }
Line 803  bad:
Line 762  bad:
         return;          return;
 }  }
   
   static bool
   ip6_badaddr(struct ip6_hdr *ip6)
   {
           /* Check against address spoofing/corruption. */
           if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
               IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
                   return true;
           }
   
           /*
            * The following check is not documented in specs.  A 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.
            *
            * This check chokes if we are in an SIIT cloud.  As none of BSDs
            * support IPv4-less kernel compilation, we cannot support SIIT
            * environment at all.  So, it makes more sense for us to reject any
            * malicious packets for non-SIIT environment, than try to do a
            * partial support for SIIT environment.
            */
           if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
               IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
                   return true;
           }
   
           /*
            * Reject packets with IPv4-compatible IPv6 addresses (RFC4291).
            */
           if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
               IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
                   return true;
           }
   
           return false;
   }
   
 /*  /*
  * set/grab in6_ifaddr correspond to IPv6 destination address.   * set/grab in6_ifaddr correspond to IPv6 destination address.
  */   */
Line 1054  ip6_unknown_opt(u_int8_t *optp, struct m
Line 1050  ip6_unknown_opt(u_int8_t *optp, struct m
         return (-1);          return (-1);
 }  }
   
 /*  
  * Create the "control" list for this pcb.  
  *  
  * The routine will be called from upper layer handlers like tcp6_input().  
  * Thus the routine assumes that the caller (tcp6_input) have already  
  * called IP6_EXTHDR_CHECK() and all the extension headers are located in the  
  * very first mbuf on the mbuf chain.  
  * We may want to add some infinite loop prevention or sanity checks for safety.  
  * (This applies only when you are using KAME mbuf chain restriction, i.e.  
  * you are using IP6_EXTHDR_CHECK() not m_pulldown())  
  */  
 void  void
 ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp,  ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp,
         struct ip6_hdr *ip6, struct mbuf *m)          struct ip6_hdr *ip6, struct mbuf *m)
Line 1077  ip6_savecontrol(struct in6pcb *in6p, str
Line 1062  ip6_savecontrol(struct in6pcb *in6p, str
 #endif  #endif
   
         if (SOOPT_TIMESTAMP(so->so_options))          if (SOOPT_TIMESTAMP(so->so_options))
                 mp = sbsavetimestamp(so->so_options, m, mp);                  mp = sbsavetimestamp(so->so_options, mp);
   
         /* some OSes call this logic with IPv4 packet, for SO_TIMESTAMP */          /* some OSes call this logic with IPv4 packet, for SO_TIMESTAMP */
         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION)          if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION)
Line 1298  ip6_notify_pmtu(struct in6pcb *in6p, con
Line 1283  ip6_notify_pmtu(struct in6pcb *in6p, con
   
         if (sbappendaddr(&so->so_rcv, (const struct sockaddr *)dst, NULL, m_mtu)          if (sbappendaddr(&so->so_rcv, (const struct sockaddr *)dst, NULL, m_mtu)
             == 0) {              == 0) {
                   soroverflow(so);
                 m_freem(m_mtu);                  m_freem(m_mtu);
                 /* XXX: should count statistics */  
         } else          } else
                 sorwakeup(so);                  sorwakeup(so);
   
Line 1317  ip6_pullexthdr(struct mbuf *m, size_t of
Line 1302  ip6_pullexthdr(struct mbuf *m, size_t of
         size_t elen;          size_t elen;
         struct mbuf *n;          struct mbuf *n;
   
 #ifdef DIAGNOSTIC  
         switch (nxt) {  
         case IPPROTO_DSTOPTS:  
         case IPPROTO_ROUTING:  
         case IPPROTO_HOPOPTS:  
         case IPPROTO_AH: /* is it possible? */  
                 break;  
         default:  
                 printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);  
         }  
 #endif  
   
         m_copydata(m, off, sizeof(ip6e), (void *)&ip6e);          m_copydata(m, off, sizeof(ip6e), (void *)&ip6e);
         if (nxt == IPPROTO_AH)          if (nxt == IPPROTO_AH)
                 elen = (ip6e.ip6e_len + 2) << 2;                  elen = (ip6e.ip6e_len + 2) << 2;
Line 1510  ip6_addaux(struct mbuf *m)
Line 1483  ip6_addaux(struct mbuf *m)
 {  {
         struct m_tag *mtag;          struct m_tag *mtag;
   
         mtag = m_tag_find(m, PACKET_TAG_INET6, NULL);          mtag = m_tag_find(m, PACKET_TAG_INET6);
         if (!mtag) {          if (!mtag) {
                 mtag = m_tag_get(PACKET_TAG_INET6, sizeof(struct ip6aux),                  mtag = m_tag_get(PACKET_TAG_INET6, sizeof(struct ip6aux),
                     M_NOWAIT);                      M_NOWAIT);
Line 1527  ip6_findaux(struct mbuf *m)
Line 1500  ip6_findaux(struct mbuf *m)
 {  {
         struct m_tag *mtag;          struct m_tag *mtag;
   
         mtag = m_tag_find(m, PACKET_TAG_INET6, NULL);          mtag = m_tag_find(m, PACKET_TAG_INET6);
         return mtag;          return mtag;
 }  }
   
Line 1536  ip6_delaux(struct mbuf *m)
Line 1509  ip6_delaux(struct mbuf *m)
 {  {
         struct m_tag *mtag;          struct m_tag *mtag;
   
         mtag = m_tag_find(m, PACKET_TAG_INET6, NULL);          mtag = m_tag_find(m, PACKET_TAG_INET6);
         if (mtag)          if (mtag)
                 m_tag_delete(m, mtag);                  m_tag_delete(m, mtag);
 }  }

Legend:
Removed from v.1.193  
changed lines
  Added in v.1.193.2.7

CVSweb <webmaster@jp.NetBSD.org>