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

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

Diff for /src/sys/netinet/ip_input.c between version 1.281 and 1.287

version 1.281, 2009/04/18 14:58:05 version 1.287, 2010/07/09 18:42:46
Line 231  u_long in_multihash;    /* size of hash 
Line 231  u_long in_multihash;    /* size of hash 
 int     in_multientries;                        /* total number of addrs */  int     in_multientries;                        /* total number of addrs */
 struct  in_multihashhead *in_multihashtbl;  struct  in_multihashhead *in_multihashtbl;
 struct  ifqueue ipintrq;  struct  ifqueue ipintrq;
   
 uint16_t ip_id;  uint16_t ip_id;
   
 percpu_t *ipstat_percpu;  percpu_t *ipstat_percpu;
Line 383  struct mowner ip_rx_mowner = MOWNER_INIT
Line 384  struct mowner ip_rx_mowner = MOWNER_INIT
 struct mowner ip_tx_mowner = MOWNER_INIT("internet", "tx");  struct mowner ip_tx_mowner = MOWNER_INIT("internet", "tx");
 #endif  #endif
   
   static void sysctl_net_inet_ip_setup(struct sysctllog **);
   
 /*  /*
  * Compute IP limits derived from the value of nmbclusters.   * Compute IP limits derived from the value of nmbclusters.
  */   */
Line 403  ip_init(void)
Line 406  ip_init(void)
         const struct protosw *pr;          const struct protosw *pr;
         int i;          int i;
   
           sysctl_net_inet_ip_setup(NULL);
   
         pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl",          pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl",
             NULL, IPL_SOFTNET);              NULL, IPL_SOFTNET);
         pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl",          pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl",
Line 470  ipintr(void)
Line 475  ipintr(void)
 {  {
         int s;          int s;
         struct mbuf *m;          struct mbuf *m;
           struct ifqueue lcl_intrq;
   
           memset(&lcl_intrq, 0, sizeof(lcl_intrq));
           ipintrq.ifq_maxlen = ipqmaxlen;
   
         mutex_enter(softnet_lock);          mutex_enter(softnet_lock);
         KERNEL_LOCK(1, NULL);          KERNEL_LOCK(1, NULL);
         while (!IF_IS_EMPTY(&ipintrq)) {          if (!IF_IS_EMPTY(&ipintrq)) {
                 s = splnet();                  s = splnet();
                 IF_DEQUEUE(&ipintrq, m);  
                   /* Take existing queue onto stack */
                   lcl_intrq = ipintrq;
   
                   /* Zero out global queue, preserving maxlen and drops */
                   ipintrq.ifq_head = NULL;
                   ipintrq.ifq_tail = NULL;
                   ipintrq.ifq_len = 0;
                   ipintrq.ifq_maxlen = lcl_intrq.ifq_maxlen;
                   ipintrq.ifq_drops = lcl_intrq.ifq_drops;
   
                 splx(s);                  splx(s);
           }
           KERNEL_UNLOCK_ONE(NULL);
           while (!IF_IS_EMPTY(&lcl_intrq)) {
                   IF_DEQUEUE(&lcl_intrq, m);
                 if (m == NULL)                  if (m == NULL)
                         break;                          break;
                 ip_input(m);                  ip_input(m);
         }          }
         KERNEL_UNLOCK_ONE(NULL);  
         mutex_exit(softnet_lock);          mutex_exit(softnet_lock);
 }  }
   
Line 908  ours:
Line 930  ours:
          * but it's not worth the time; just let them time out.)           * but it's not worth the time; just let them time out.)
          */           */
         if (ip->ip_off & ~htons(IP_DF|IP_RF)) {          if (ip->ip_off & ~htons(IP_DF|IP_RF)) {
                 uint16_t off;                  u_int off;
                 /*                  /*
                  * Prevent TCP blind data attacks by not allowing non-initial                   * Prevent TCP blind data attacks by not allowing non-initial
                  * fragments to start at less than 68 bytes (minimal fragment                   * fragments to start at less than 68 bytes (minimal fragment
Line 920  ours:
Line 942  ours:
                         IP_STATINC(IP_STAT_BADFRAGS);                          IP_STATINC(IP_STAT_BADFRAGS);
                         goto bad;                          goto bad;
                 }                  }
                 /*  
                  * Look for queue of fragments  
                  * of this datagram.  
                  */  
                 IPQ_LOCK();  
                 hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);  
                 LIST_FOREACH(fp, &ipq[hash], ipq_q) {  
                         if (ip->ip_id == fp->ipq_id &&  
                             in_hosteq(ip->ip_src, fp->ipq_src) &&  
                             in_hosteq(ip->ip_dst, fp->ipq_dst) &&  
                             ip->ip_p == fp->ipq_p) {  
                                 /*  
                                  * Make sure the TOS is matches previous  
                                  * fragments.  
                                  */  
                                 if (ip->ip_tos != fp->ipq_tos) {  
                                         IP_STATINC(IP_STAT_BADFRAGS);  
                                         IPQ_UNLOCK();  
                                         goto bad;  
                                 }  
                                 goto found;  
                         }  
                 }  
                 fp = 0;  
 found:  
   
                 /*                  /*
                  * Adjust ip_len to not reflect header,                   * Adjust ip_len to not reflect header,
Line 954  found:
Line 951  found:
                 ip->ip_len = htons(ntohs(ip->ip_len) - hlen);                  ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
                 mff = (ip->ip_off & htons(IP_MF)) != 0;                  mff = (ip->ip_off & htons(IP_MF)) != 0;
                 if (mff) {                  if (mff) {
                         /*                          /*
                          * Make sure that fragments have a data length                           * Make sure that fragments have a data length
                          * that's a non-zero multiple of 8 bytes.                           * that's a non-zero multiple of 8 bytes.
                          */                           */
                         if (ntohs(ip->ip_len) == 0 ||                          if (ntohs(ip->ip_len) == 0 ||
                             (ntohs(ip->ip_len) & 0x7) != 0) {                              (ntohs(ip->ip_len) & 0x7) != 0) {
                                 IP_STATINC(IP_STAT_BADFRAGS);                                  IP_STATINC(IP_STAT_BADFRAGS);
                                 IPQ_UNLOCK();  
                                 goto bad;                                  goto bad;
                         }                          }
                 }                  }
                 ip->ip_off = htons((ntohs(ip->ip_off) & IP_OFFMASK) << 3);                  ip->ip_off = htons((ntohs(ip->ip_off) & IP_OFFMASK) << 3);
   
                 /*                  /*
                    * Look for queue of fragments of this datagram.
                    */
                   IPQ_LOCK();
                   hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
                   LIST_FOREACH(fp, &ipq[hash], ipq_q) {
                           if (ip->ip_id != fp->ipq_id)
                                   continue;
                           if (!in_hosteq(ip->ip_src, fp->ipq_src))
                                   continue;
                           if (!in_hosteq(ip->ip_dst, fp->ipq_dst))
                                   continue;
                           if (ip->ip_p != fp->ipq_p)
                                   continue;
                           /*
                            * Make sure the TOS is matches previous fragments.
                            */
                           if (ip->ip_tos != fp->ipq_tos) {
                                   IP_STATINC(IP_STAT_BADFRAGS);
                                   IPQ_UNLOCK();
                                   goto bad;
                           }
                           break;
                   }
   
                   /*
                  * If datagram marked as having more fragments                   * If datagram marked as having more fragments
                  * or if this is not the first fragment,                   * or if this is not the first fragment,
                  * attempt reassembly; if it succeeds, proceed.                   * attempt reassembly; if it succeeds, proceed.
Line 986  found:
Line 1007  found:
                         ipqe->ipqe_m = m;                          ipqe->ipqe_m = m;
                         ipqe->ipqe_ip = ip;                          ipqe->ipqe_ip = ip;
                         m = ip_reass(ipqe, fp, &ipq[hash]);                          m = ip_reass(ipqe, fp, &ipq[hash]);
                         if (m == 0) {                          if (m == NULL) {
                                 IPQ_UNLOCK();                                  IPQ_UNLOCK();
                                 return;                                  return;
                         }                          }
Line 994  found:
Line 1015  found:
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
                         hlen = ip->ip_hl << 2;                          hlen = ip->ip_hl << 2;
                         ip->ip_len = htons(ntohs(ip->ip_len) + hlen);                          ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
                 } else                  } else if (fp) {
                         if (fp)                          ip_freef(fp);
                                 ip_freef(fp);                  }
                 IPQ_UNLOCK();                  IPQ_UNLOCK();
         }          }
   
Line 2057  ip_savecontrol(struct inpcb *inp, struct
Line 2078  ip_savecontrol(struct inpcb *inp, struct
     struct mbuf *m)      struct mbuf *m)
 {  {
   
         if (inp->inp_socket->so_options & SO_TIMESTAMP          if (inp->inp_socket->so_options & SO_TIMESTAMP
 #ifdef SO_OTIMESTAMP  #ifdef SO_OTIMESTAMP
             || inp->inp_socket->so_options & SO_OTIMESTAMP              || inp->inp_socket->so_options & SO_OTIMESTAMP
 #endif  #endif
             ) {              ) {
                 struct timeval tv;                  struct timeval tv;
Line 2118  ip_savecontrol(struct inpcb *inp, struct
Line 2139  ip_savecontrol(struct inpcb *inp, struct
                 if (*mp)                  if (*mp)
                         mp = &(*mp)->m_next;                          mp = &(*mp)->m_next;
         }          }
           if (inp->inp_flags & INP_RECVTTL) {
                   *mp = sbcreatecontrol((void *) &ip->ip_ttl,
                       sizeof(uint8_t), IP_RECVTTL, IPPROTO_IP);
                   if (*mp)
                           mp = &(*mp)->m_next;
           }
 }  }
   
 /*  /*
Line 2201  sysctl_net_inet_ip_maxflows(SYSCTLFN_ARG
Line 2228  sysctl_net_inet_ip_maxflows(SYSCTLFN_ARG
   
 static int  static int
 sysctl_net_inet_ip_hashsize(SYSCTLFN_ARGS)  sysctl_net_inet_ip_hashsize(SYSCTLFN_ARGS)
 {  {
         int error, tmp;          int error, tmp;
         struct sysctlnode node;          struct sysctlnode node;
   
Line 2229  sysctl_net_inet_ip_hashsize(SYSCTLFN_ARG
Line 2256  sysctl_net_inet_ip_hashsize(SYSCTLFN_ARG
                  * EINVAL if not a power of 2                   * EINVAL if not a power of 2
                  */                   */
                 error = EINVAL;                  error = EINVAL;
         }          }
   
         return error;          return error;
 }  }
Line 2242  sysctl_net_inet_ip_stats(SYSCTLFN_ARGS)
Line 2269  sysctl_net_inet_ip_stats(SYSCTLFN_ARGS)
         return (NETSTAT_SYSCTL(ipstat_percpu, IP_NSTATS));          return (NETSTAT_SYSCTL(ipstat_percpu, IP_NSTATS));
 }  }
   
 SYSCTL_SETUP(sysctl_net_inet_ip_setup, "sysctl net.inet.ip subtree setup")  static void
   sysctl_net_inet_ip_setup(struct sysctllog **clog)
 {  {
         extern int subnetsarelocal, hostzeroisbroadcast;          extern int subnetsarelocal, hostzeroisbroadcast;
   

Legend:
Removed from v.1.281  
changed lines
  Added in v.1.287

CVSweb <webmaster@jp.NetBSD.org>