[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.53.2.1 and 1.74

version 1.53.2.1, 1998/05/09 03:33:00 version 1.74, 1998/11/13 03:24:22
Line 35 
Line 35 
  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94   *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
  */   */
   
   /*-
    * Copyright (c) 1998 The NetBSD Foundation, Inc.
    * All rights reserved.
    *
    * This code is derived from software contributed to The NetBSD Foundation
    * by Public Access Networks Corporation ("Panix").  It was developed under
    * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    * 1. Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the distribution.
    * 3. All advertising materials mentioning features or use of this software
    *    must display the following acknowledgement:
    *      This product includes software developed by the NetBSD
    *      Foundation, Inc. and its contributors.
    * 4. Neither the name of The NetBSD Foundation nor the names of its
    *    contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
    * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
    * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    * POSSIBILITY OF SUCH DAMAGE.
    */
   
   #include "opt_gateway.h"
   #include "opt_pfil_hooks.h"
   #include "opt_mrouting.h"
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/malloc.h>  #include <sys/malloc.h>
Line 47 
Line 88 
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
 #include <sys/proc.h>  #include <sys/proc.h>
   #include <sys/pool.h>
   
 #include <vm/vm.h>  #include <vm/vm.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
Line 64 
Line 106 
 #include <netinet/ip_var.h>  #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>  #include <netinet/ip_icmp.h>
   
 /* XXX should really put this in libkern.h */  
 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))  
   
 #ifndef IPFORWARDING  #ifndef IPFORWARDING
 #ifdef GATEWAY  #ifdef GATEWAY
 #define IPFORWARDING    1       /* forward IP packets not for us */  #define IPFORWARDING    1       /* forward IP packets not for us */
Line 90 
Line 129 
 #define IPMTUDISCTIMEOUT (10 * 60)      /* as per RFC 1191 */  #define IPMTUDISCTIMEOUT (10 * 60)      /* as per RFC 1191 */
 #endif  #endif
   
   
 /*  /*
  * Note: DIRECTED_BROADCAST is handled this way so that previous   * Note: DIRECTED_BROADCAST is handled this way so that previous
  * configuration using this option will Just Work.   * configuration using this option will Just Work.
Line 121  extern struct protosw inetsw[];
Line 159  extern struct protosw inetsw[];
 u_char  ip_protox[IPPROTO_MAX];  u_char  ip_protox[IPPROTO_MAX];
 int     ipqmaxlen = IFQ_MAXLEN;  int     ipqmaxlen = IFQ_MAXLEN;
 struct  in_ifaddrhead in_ifaddr;  struct  in_ifaddrhead in_ifaddr;
   struct  in_ifaddrhashhead *in_ifaddrhashtbl;
 struct  ifqueue ipintrq;  struct  ifqueue ipintrq;
   struct  ipstat  ipstat;
   u_int16_t       ip_id;
   int     ip_defttl;
   struct ipqhead ipq;
   
   struct pool ipqent_pool;
   
 /*  /*
  * We need to save the IP options in case a protocol wants to respond   * We need to save the IP options in case a protocol wants to respond
Line 150  ip_init()
Line 195  ip_init()
         register struct protosw *pr;          register struct protosw *pr;
         register int i;          register int i;
   
           pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl",
               0, NULL, NULL, M_IPQ);
   
         pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);          pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
         if (pr == 0)          if (pr == 0)
                 panic("ip_init");                  panic("ip_init");
Line 164  ip_init()
Line 212  ip_init()
         ip_id = time.tv_sec & 0xffff;          ip_id = time.tv_sec & 0xffff;
         ipintrq.ifq_maxlen = ipqmaxlen;          ipintrq.ifq_maxlen = ipqmaxlen;
         TAILQ_INIT(&in_ifaddr);          TAILQ_INIT(&in_ifaddr);
           in_ifaddrhashtbl =
               hashinit(IN_IFADDR_HASH_SIZE, M_IFADDR, M_WAITOK, &in_ifaddrhash);
         if (ip_mtudisc != 0)          if (ip_mtudisc != 0)
                 ip_mtudisc_timeout_q =                  ip_mtudisc_timeout_q =
                     rt_timer_queue_create(ip_mtudisc_timeout);                      rt_timer_queue_create(ip_mtudisc_timeout);
   #ifdef GATEWAY
           ipflow_init();
   #endif
 }  }
   
 struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };  struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
Line 184  ipintr()
Line 236  ipintr()
         register struct mbuf *m;          register struct mbuf *m;
         register struct ipq *fp;          register struct ipq *fp;
         register struct in_ifaddr *ia;          register struct in_ifaddr *ia;
           register struct ifaddr *ifa;
         struct ipqent *ipqe;          struct ipqent *ipqe;
         int hlen = 0, mff, len, s;          int hlen = 0, mff, len, s;
 #ifdef PFIL_HOOKS  #ifdef PFIL_HOOKS
Line 266  next:
Line 319  next:
                         m_adj(m, len - m->m_pkthdr.len);                          m_adj(m, len - m->m_pkthdr.len);
         }          }
   
           /*
            * Assume that we can create a fast-forward IP flow entry
            * based on this packet.
            */
           m->m_flags |= M_CANFASTFWD;
   
 #ifdef PFIL_HOOKS  #ifdef PFIL_HOOKS
         /*          /*
          * Run through list of hooks for input packets.           * 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;          m0 = m;
         for (pfh = pfil_hook_get(PFIL_IN); pfh; pfh = pfh->pfil_link.le_next)          for (pfh = pfil_hook_get(PFIL_IN); pfh; pfh = pfh->pfil_link.tqe_next)
                 if (pfh->pfil_func) {                  if (pfh->pfil_func) {
                         rv = pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0);                          rv = pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0);
                         if (rv)                          if (rv)
                                 goto next;                                  goto next;
                         ip = mtod(m = m0, struct ip *);                          m = m0;
                           if (m == NULL)
                                   goto next;
                           ip = mtod(m, struct ip *);
                 }                  }
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
   
Line 293  next:
Line 359  next:
         /*          /*
          * Check our list of addresses, to see if the packet is for us.           * Check our list of addresses, to see if the packet is for us.
          */           */
         for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) {          INADDR_TO_IA(ip->ip_dst, ia);
                 if (in_hosteq(ip->ip_dst, ia->ia_addr.sin_addr))          if (ia != NULL) goto ours;
                         goto ours;          if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
                 if (((ip_directedbcast == 0) || (ip_directedbcast &&                  for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
                     ia->ia_ifp == m->m_pkthdr.rcvif)) &&                      ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
                     (ia->ia_ifp->if_flags & IFF_BROADCAST)) {                          if (ifa->ifa_addr->sa_family != AF_INET) continue;
                           ia = ifatoia(ifa);
                         if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) ||                          if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) ||
                             in_hosteq(ip->ip_dst, ia->ia_netbroadcast) ||                              in_hosteq(ip->ip_dst, ia->ia_netbroadcast) ||
                             /*                              /*
Line 308  next:
Line 375  next:
                             ip->ip_dst.s_addr == ia->ia_subnet ||                              ip->ip_dst.s_addr == ia->ia_subnet ||
                             ip->ip_dst.s_addr == ia->ia_net)                              ip->ip_dst.s_addr == ia->ia_net)
                                 goto ours;                                  goto ours;
                           /*
                            * An interface with IP address zero accepts
                            * all packets that arrive on that interface.
                            */
                           if (in_nullhost(ia->ia_addr.sin_addr))
                                   goto ours;
                 }                  }
                 /*  
                  * An interface with IP address zero accepts  
                  * all packets that arrive on that interface.  
                  */  
                 if ((ia->ia_ifp == m->m_pkthdr.rcvif) &&  
                     in_nullhost(ia->ia_addr.sin_addr))  
                         goto ours;  
         }          }
         if (IN_MULTICAST(ip->ip_dst.s_addr)) {          if (IN_MULTICAST(ip->ip_dst.s_addr)) {
                 struct in_multi *inm;                  struct in_multi *inm;
Line 435  found:
Line 501  found:
                  */                   */
                 if (mff || ip->ip_off) {                  if (mff || ip->ip_off) {
                         ipstat.ips_fragments++;                          ipstat.ips_fragments++;
                         MALLOC(ipqe, struct ipqent *, sizeof (struct ipqent),                          ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
                             M_IPQ, M_NOWAIT);  
                         if (ipqe == NULL) {                          if (ipqe == NULL) {
                                 ipstat.ips_rcvmemdrop++;                                  ipstat.ips_rcvmemdrop++;
                                 goto bad;                                  goto bad;
Line 449  found:
Line 514  found:
                                 goto next;                                  goto next;
                         ipstat.ips_reassembled++;                          ipstat.ips_reassembled++;
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
                           hlen = ip->ip_hl << 2;
                 } else                  } else
                         if (fp)                          if (fp)
                                 ip_freef(fp);                                  ip_freef(fp);
Line 552  ip_reass(ipqe, fp)
Line 618  ip_reass(ipqe, fp)
                 nq = q->ipqe_q.le_next;                  nq = q->ipqe_q.le_next;
                 m_freem(q->ipqe_m);                  m_freem(q->ipqe_m);
                 LIST_REMOVE(q, ipqe_q);                  LIST_REMOVE(q, ipqe_q);
                 FREE(q, M_IPQ);                  pool_put(&ipqent_pool, q);
         }          }
   
 insert:  insert:
Line 591  insert:
Line 657  insert:
         m->m_next = 0;          m->m_next = 0;
         m_cat(m, t);          m_cat(m, t);
         nq = q->ipqe_q.le_next;          nq = q->ipqe_q.le_next;
         FREE(q, M_IPQ);          pool_put(&ipqent_pool, q);
         for (q = nq; q != NULL; q = nq) {          for (q = nq; q != NULL; q = nq) {
                 t = q->ipqe_m;                  t = q->ipqe_m;
                 nq = q->ipqe_q.le_next;                  nq = q->ipqe_q.le_next;
                 FREE(q, M_IPQ);                  pool_put(&ipqent_pool, q);
                 m_cat(m, t);                  m_cat(m, t);
         }          }
   
Line 624  insert:
Line 690  insert:
 dropfrag:  dropfrag:
         ipstat.ips_fragdropped++;          ipstat.ips_fragdropped++;
         m_freem(m);          m_freem(m);
         FREE(ipqe, M_IPQ);          pool_put(&ipqent_pool, ipqe);
         return (0);          return (0);
 }  }
   
Line 642  ip_freef(fp)
Line 708  ip_freef(fp)
                 p = q->ipqe_q.le_next;                  p = q->ipqe_q.le_next;
                 m_freem(q->ipqe_m);                  m_freem(q->ipqe_m);
                 LIST_REMOVE(q, ipqe_q);                  LIST_REMOVE(q, ipqe_q);
                 FREE(q, M_IPQ);                  pool_put(&ipqent_pool, q);
         }          }
         LIST_REMOVE(fp, ipq_q);          LIST_REMOVE(fp, ipq_q);
         FREE(fp, M_FTABLE);          FREE(fp, M_FTABLE);
Line 666  ip_slowtimo()
Line 732  ip_slowtimo()
                         ip_freef(fp);                          ip_freef(fp);
                 }                  }
         }          }
   #ifdef GATEWAY
           ipflow_slowtimo();
   #endif
         splx(s);          splx(s);
 }  }
   
Line 835  ip_dooptions(m)
Line 904  ip_dooptions(m)
                                 break;                                  break;
   
                         case IPOPT_TS_TSANDADDR:                          case IPOPT_TS_TSANDADDR:
                                 if (ipt->ipt_ptr + sizeof(n_time) +                                  if (ipt->ipt_ptr - 1 + sizeof(n_time) +
                                     sizeof(struct in_addr) > ipt->ipt_len)                                      sizeof(struct in_addr) > ipt->ipt_len)
                                         goto bad;                                          goto bad;
                                 ipaddr.sin_addr = dst;                                  ipaddr.sin_addr = dst;
Line 849  ip_dooptions(m)
Line 918  ip_dooptions(m)
                                 break;                                  break;
   
                         case IPOPT_TS_PRESPEC:                          case IPOPT_TS_PRESPEC:
                                 if (ipt->ipt_ptr + sizeof(n_time) +                                  if (ipt->ipt_ptr - 1 + sizeof(n_time) +
                                     sizeof(struct in_addr) > ipt->ipt_len)                                      sizeof(struct in_addr) > ipt->ipt_len)
                                         goto bad;                                          goto bad;
                                 bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,                                  bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
Line 1071  ip_forward(m, srcrt)
Line 1140  ip_forward(m, srcrt)
         dest = 0;          dest = 0;
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (ipprintfs)          if (ipprintfs)
                 printf("forward: src %x dst %x ttl %x\n",                  printf("forward: src %2.2x dst %2.2x ttl %x\n",
                     ip->ip_src.s_addr, ip->ip_dst.s_addr, ip->ip_ttl);                      ntohl(ip->ip_src.s_addr),
                       ntohl(ip->ip_dst.s_addr), ip->ip_ttl);
 #endif  #endif
         if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {          if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {
                 ipstat.ips_cantforward++;                  ipstat.ips_cantforward++;
Line 1149  ip_forward(m, srcrt)
Line 1219  ip_forward(m, srcrt)
                 if (type)                  if (type)
                         ipstat.ips_redirectsent++;                          ipstat.ips_redirectsent++;
                 else {                  else {
                         if (mcopy)                          if (mcopy) {
   #ifdef GATEWAY
                                   if (mcopy->m_flags & M_CANFASTFWD)
                                           ipflow_create(&ipforward_rt, mcopy);
   #endif
                                 m_freem(mcopy);                                  m_freem(mcopy);
                           }
                         return;                          return;
                 }                  }
         }          }
Line 1259  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1334  ip_sysctl(name, namelen, oldp, oldlenp, 
         size_t newlen;          size_t newlen;
 {  {
         extern int subnetsarelocal;          extern int subnetsarelocal;
         int error;  
           int error, old;
   
         /* All sysctl names at this level are terminal. */          /* All sysctl names at this level are terminal. */
         if (namelen != 1)          if (namelen != 1)
Line 1305  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1381  ip_sysctl(name, namelen, oldp, oldlenp, 
                         ip_mtudisc_timeout_q = NULL;                          ip_mtudisc_timeout_q = NULL;
                 }                  }
                 return error;                  return error;
           case IPCTL_ANONPORTMIN:
                   old = anonportmin;
                   error = sysctl_int(oldp, oldlenp, newp, newlen, &anonportmin);
                   if (anonportmin >= anonportmax || anonportmin > 65535
   #ifndef IPNOPRIVPORTS
                       || anonportmin < IPPORT_RESERVED
   #endif
                       ) {
                           anonportmin = old;
                           return (EINVAL);
                   }
                   return (error);
           case IPCTL_ANONPORTMAX:
                   old = anonportmax;
                   error = sysctl_int(oldp, oldlenp, newp, newlen, &anonportmax);
                   if (anonportmin >= anonportmax || anonportmax > 65535
   #ifndef IPNOPRIVPORTS
                       || anonportmax < IPPORT_RESERVED
   #endif
                       ) {
                           anonportmax = old;
                           return (EINVAL);
                   }
                   return (error);
         case IPCTL_MTUDISCTIMEOUT:          case IPCTL_MTUDISCTIMEOUT:
                 error = sysctl_int(oldp, oldlenp, newp, newlen,                  error = sysctl_int(oldp, oldlenp, newp, newlen,
                    &ip_mtudisc_timeout);                     &ip_mtudisc_timeout);
                 if (ip_mtudisc_timeout_q != NULL)                  if (ip_mtudisc_timeout_q != NULL)
                         rt_timer_queue_change(ip_mtudisc_timeout_q,                          rt_timer_queue_change(ip_mtudisc_timeout_q,
                                               ip_mtudisc_timeout);                                                ip_mtudisc_timeout);
                 return (error);                  return (error);
   #ifdef GATEWAY
           case IPCTL_MAXFLOWS:
               {
                   int s;
   
                   error = sysctl_int(oldp, oldlenp, newp, newlen,
                      &ip_maxflows);
                   s = splsoftnet();
                   ipflow_reap(0);
                   splx(s);
                   return (error);
               }
   #endif
         default:          default:
                 return (EOPNOTSUPP);                  return (EOPNOTSUPP);
         }          }

Legend:
Removed from v.1.53.2.1  
changed lines
  Added in v.1.74

CVSweb <webmaster@jp.NetBSD.org>