[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.74.2.1 and 1.82.2.4

version 1.74.2.1, 1998/12/11 04:53:08 version 1.82.2.4, 2000/02/12 18:10:24
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
   /*-
    * 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.
    */
   
 /*  /*
  * Copyright (c) 1982, 1986, 1988, 1993   * Copyright (c) 1982, 1986, 1988, 1993
  *      The Regents of the University of California.  All rights reserved.   *      The Regents of the University of California.  All rights reserved.
Line 35 
Line 72 
  *      @(#)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_gateway.h"
 #include "opt_pfil_hooks.h"  #include "opt_pfil_hooks.h"
 #include "opt_mrouting.h"  #include "opt_mrouting.h"
Line 164  struct ifqueue ipintrq;
Line 164  struct ifqueue ipintrq;
 struct  ipstat  ipstat;  struct  ipstat  ipstat;
 u_int16_t       ip_id;  u_int16_t       ip_id;
 int     ip_defttl;  int     ip_defttl;
   
 struct ipqhead ipq;  struct ipqhead ipq;
   int     ipq_locked;
   
   static __inline int ipq_lock_try __P((void));
   static __inline void ipq_unlock __P((void));
   
   static __inline int
   ipq_lock_try()
   {
           int s;
   
           s = splimp();
           if (ipq_locked) {
                   splx(s);
                   return (0);
           }
           ipq_locked = 1;
           splx(s);
           return (1);
   }
   
   static __inline void
   ipq_unlock()
   {
           int s;
   
           s = splimp();
           ipq_locked = 0;
           splx(s);
   }
   
   #ifdef DIAGNOSTIC
   #define IPQ_LOCK()                                                      \
   do {                                                                    \
           if (ipq_lock_try() == 0) {                                      \
                   printf("%s:%d: ipq already locked\n", __FILE__, __LINE__); \
                   panic("ipq_lock");                                      \
           }                                                               \
   } while (0)
   #define IPQ_LOCK_CHECK()                                                \
   do {                                                                    \
           if (ipq_locked == 0) {                                          \
                   printf("%s:%d: ipq lock not held\n", __FILE__, __LINE__); \
                   panic("ipq lock check");                                \
           }                                                               \
   } while (0)
   #else
   #define IPQ_LOCK()              (void) ipq_lock_try()
   #define IPQ_LOCK_CHECK()        /* nothing */
   #endif
   
   #define IPQ_UNLOCK()            ipq_unlock()
   
 struct pool ipqent_pool;  struct pool ipqent_pool;
   
Line 288  next:
Line 340  next:
                 }                  }
                 ip = mtod(m, struct ip *);                  ip = mtod(m, struct ip *);
         }          }
         if ((ip->ip_sum = in_cksum(m, hlen)) != 0) {  
           /*
            * RFC1122: packets with a multicast source address are
            * not allowed.
            */
           if (IN_MULTICAST(ip->ip_src.s_addr)) {
                   /* XXX stat */
                   goto bad;
           }
   
           if (in_cksum(m, hlen) != 0) {
                 ipstat.ips_badsum++;                  ipstat.ips_badsum++;
                 goto bad;                  goto bad;
         }          }
Line 297  next:
Line 359  next:
          * Convert fields to host representation.           * Convert fields to host representation.
          */           */
         NTOHS(ip->ip_len);          NTOHS(ip->ip_len);
         NTOHS(ip->ip_id);  
         NTOHS(ip->ip_off);          NTOHS(ip->ip_off);
         len = ip->ip_len;          len = ip->ip_len;
   
         /*          /*
            * Check for additional length bogosity
            */
           if (len < hlen)
           {
                   ipstat.ips_badlen++;
                   goto bad;
           }
   
           /*
          * Check that the amount of data in the buffers           * Check that the amount of data in the buffers
          * is as at least much as the IP header would have us expect.           * is as at least much as the IP header would have us expect.
          * Trim mbufs if longer than we expect.           * Trim mbufs if longer than we expect.
Line 359  next:
Line 429  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.
          */           */
         s = splimp();  
         INADDR_TO_IA(ip->ip_dst, ia);          INADDR_TO_IA(ip->ip_dst, ia);
         if (ia != NULL) {          if (ia != NULL)
                 ifa_delref(&ia->ia_ifa);  
                 splx(s);  
                 goto ours;                  goto ours;
         }  
         if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {          if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
                 for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;                  for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
                     ifa != NULL; ifa = ifa->ifa_list.tqe_next) {                      ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
                         if (ifa->ifa_addr->sa_family != AF_INET) continue;                          if (ifa->ifa_addr->sa_family != AF_INET) continue;
                         ia = ifatoia(ifa);                          ia = ifatoia(ifa);
                         /*  
                          * Don't ifa_addref ia as we don't use it after  
                          * we splx(s) below  
                          */  
                         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 382  next:
Line 444  next:
                              * either for subnet or net.                               * either for subnet or net.
                              */                               */
                             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)
                                 splx(s);  
                                 goto ours;                                  goto ours;
                         }  
                         /*                          /*
                          * An interface with IP address zero accepts                           * An interface with IP address zero accepts
                          * all packets that arrive on that interface.                           * all packets that arrive on that interface.
                          */                           */
                         if (in_nullhost(ia->ia_addr.sin_addr)) {                          if (in_nullhost(ia->ia_addr.sin_addr))
                                 splx(s);  
                                 goto ours;                                  goto ours;
                         }  
                 }                  }
         }          }
         splx(s);  
         if (IN_MULTICAST(ip->ip_dst.s_addr)) {          if (IN_MULTICAST(ip->ip_dst.s_addr)) {
                 struct in_multi *inm;                  struct in_multi *inm;
 #ifdef MROUTING  #ifdef MROUTING
Line 423  next:
Line 480  next:
                          * as expected when ip_mforward() is called from                           * as expected when ip_mforward() is called from
                          * ip_output().)                           * ip_output().)
                          */                           */
                         ip->ip_id = htons(ip->ip_id);  
                         if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {                          if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {
                                 ipstat.ips_cantforward++;                                  ipstat.ips_cantforward++;
                                 m_freem(m);                                  m_freem(m);
                                 goto next;                                  goto next;
                         }                          }
                         ip->ip_id = ntohs(ip->ip_id);  
   
                         /*                          /*
                          * The process-level routing demon needs to receive                           * The process-level routing demon needs to receive
Line 480  ours:
Line 535  ours:
                  * Look for queue of fragments                   * Look for queue of fragments
                  * of this datagram.                   * of this datagram.
                  */                   */
                   IPQ_LOCK();
                 for (fp = ipq.lh_first; fp != NULL; fp = fp->ipq_q.le_next)                  for (fp = ipq.lh_first; fp != NULL; fp = fp->ipq_q.le_next)
                         if (ip->ip_id == fp->ipq_id &&                          if (ip->ip_id == fp->ipq_id &&
                             in_hosteq(ip->ip_src, fp->ipq_src) &&                              in_hosteq(ip->ip_src, fp->ipq_src) &&
Line 503  found:
Line 559  found:
                          */                           */
                         if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {                          if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {
                                 ipstat.ips_badfrags++;                                  ipstat.ips_badfrags++;
                                   IPQ_UNLOCK();
                                 goto bad;                                  goto bad;
                         }                          }
                 }                  }
Line 518  found:
Line 575  found:
                         ipqe = pool_get(&ipqent_pool, PR_NOWAIT);                          ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
                         if (ipqe == NULL) {                          if (ipqe == NULL) {
                                 ipstat.ips_rcvmemdrop++;                                  ipstat.ips_rcvmemdrop++;
                                   IPQ_UNLOCK();
                                 goto bad;                                  goto bad;
                         }                          }
                         ipqe->ipqe_mff = mff;                          ipqe->ipqe_mff = mff;
                         ipqe->ipqe_m = m;                          ipqe->ipqe_m = m;
                         ipqe->ipqe_ip = ip;                          ipqe->ipqe_ip = ip;
                         m = ip_reass(ipqe, fp);                          m = ip_reass(ipqe, fp);
                         if (m == 0)                          if (m == 0) {
                                   IPQ_UNLOCK();
                                 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;                          hlen = ip->ip_hl << 2;
                           ip->ip_len += hlen;
                 } else                  } else
                         if (fp)                          if (fp)
                                 ip_freef(fp);                                  ip_freef(fp);
         } else                  IPQ_UNLOCK();
                 ip->ip_len -= hlen;          }
   
         /*          /*
          * Switch out to protocol's input routine.           * Switch out to protocol's input routine.
          */           */
   #if IFA_STATS
           ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len;
   #endif
         ipstat.ips_delivered++;          ipstat.ips_delivered++;
         (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);          (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
         goto next;          goto next;
Line 564  ip_reass(ipqe, fp)
Line 628  ip_reass(ipqe, fp)
         int hlen = ipqe->ipqe_ip->ip_hl << 2;          int hlen = ipqe->ipqe_ip->ip_hl << 2;
         int i, next;          int i, next;
   
           IPQ_LOCK_CHECK();
   
         /*          /*
          * Presence of header sizes in mbufs           * Presence of header sizes in mbufs
          * would confuse code below.           * would confuse code below.
Line 718  ip_freef(fp)
Line 784  ip_freef(fp)
 {  {
         register struct ipqent *q, *p;          register struct ipqent *q, *p;
   
           IPQ_LOCK_CHECK();
   
         for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {          for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {
                 p = q->ipqe_q.le_next;                  p = q->ipqe_q.le_next;
                 m_freem(q->ipqe_m);                  m_freem(q->ipqe_m);
Line 739  ip_slowtimo()
Line 807  ip_slowtimo()
         register struct ipq *fp, *nfp;          register struct ipq *fp, *nfp;
         int s = splsoftnet();          int s = splsoftnet();
   
           IPQ_LOCK();
         for (fp = ipq.lh_first; fp != NULL; fp = nfp) {          for (fp = ipq.lh_first; fp != NULL; fp = nfp) {
                 nfp = fp->ipq_q.le_next;                  nfp = fp->ipq_q.le_next;
                 if (--fp->ipq_ttl == 0) {                  if (--fp->ipq_ttl == 0) {
Line 746  ip_slowtimo()
Line 815  ip_slowtimo()
                         ip_freef(fp);                          ip_freef(fp);
                 }                  }
         }          }
           IPQ_UNLOCK();
 #ifdef GATEWAY  #ifdef GATEWAY
         ipflow_slowtimo();          ipflow_slowtimo();
 #endif  #endif
Line 759  void
Line 829  void
 ip_drain()  ip_drain()
 {  {
   
           /*
            * We may be called from a device's interrupt context.  If
            * the ipq is already busy, just bail out now.
            */
           if (ipq_lock_try() == 0)
                   return;
   
         while (ipq.lh_first != NULL) {          while (ipq.lh_first != NULL) {
                 ipstat.ips_fragdropped++;                  ipstat.ips_fragdropped++;
                 ip_freef(ipq.lh_first);                  ip_freef(ipq.lh_first);
         }          }
   
           IPQ_UNLOCK();
 }  }
   
 /*  /*
Line 845  ip_dooptions(m)
Line 924  ip_dooptions(m)
                                  * End of source route.  Should be for us.                                   * End of source route.  Should be for us.
                                  */                                   */
                                 save_rte(cp, ip->ip_src);                                  save_rte(cp, ip->ip_src);
                                 ifa_delref(&ia->ia_ifa);  
                                 break;                                  break;
                         }                          }
                         /*                          /*
Line 853  ip_dooptions(m)
Line 931  ip_dooptions(m)
                          */                           */
                         bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,                          bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
                             sizeof(ipaddr.sin_addr));                              sizeof(ipaddr.sin_addr));
                         ifa_delref(&ia->ia_ifa);  
                         if (opt == IPOPT_SSRR) {                          if (opt == IPOPT_SSRR) {
 #define INA     struct in_ifaddr *  #define INA     struct in_ifaddr *
 #define SA      struct sockaddr *  #define SA      struct sockaddr *
Line 873  ip_dooptions(m)
Line 950  ip_dooptions(m)
                          * Let ip_intr's mcast routing check handle mcast pkts                           * Let ip_intr's mcast routing check handle mcast pkts
                          */                           */
                         forward = !IN_MULTICAST(ip->ip_dst.s_addr);                          forward = !IN_MULTICAST(ip->ip_dst.s_addr);
                         ifa_delref(&ia->ia_ifa);  
                         break;                          break;
   
                 case IPOPT_RR:                  case IPOPT_RR:
Line 902  ip_dooptions(m)
Line 978  ip_dooptions(m)
                         bcopy((caddr_t)&ia->ia_addr.sin_addr,                          bcopy((caddr_t)&ia->ia_addr.sin_addr,
                             (caddr_t)(cp + off), sizeof(struct in_addr));                              (caddr_t)(cp + off), sizeof(struct in_addr));
                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);                          cp[IPOPT_OFFSET] += sizeof(struct in_addr);
                         ifa_delref(&ia->ia_ifa);  
                         break;                          break;
   
                 case IPOPT_TS:                  case IPOPT_TS:
Line 932  ip_dooptions(m)
Line 1007  ip_dooptions(m)
                                         continue;                                          continue;
                                 bcopy((caddr_t)&ia->ia_addr.sin_addr,                                  bcopy((caddr_t)&ia->ia_addr.sin_addr,
                                     (caddr_t)sin, sizeof(struct in_addr));                                      (caddr_t)sin, sizeof(struct in_addr));
                                 ifa_delref(&ia->ia_ifa);  
                                 ipt->ipt_ptr += sizeof(struct in_addr);                                  ipt->ipt_ptr += sizeof(struct in_addr);
                                 break;                                  break;
   
Line 942  ip_dooptions(m)
Line 1016  ip_dooptions(m)
                                         goto bad;                                          goto bad;
                                 bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,                                  bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
                                     sizeof(struct in_addr));                                      sizeof(struct in_addr));
                                 ia = (INA)ifa_ifwithaddr((SA)&ipaddr);                                  if (ifa_ifwithaddr((SA)&ipaddr) == 0)
                                 if (ia == 0)  
                                         continue;                                          continue;
                                 ifa_delref(&ia->ia_ifa);  
                                 ipt->ipt_ptr += sizeof(struct in_addr);                                  ipt->ipt_ptr += sizeof(struct in_addr);
                                 break;                                  break;
   
Line 969  ip_dooptions(m)
Line 1041  ip_dooptions(m)
         }          }
         return (0);          return (0);
 bad:  bad:
         ip->ip_len -= ip->ip_hl << 2;   /* XXX icmp_error adds in hdr length */  
         icmp_error(m, type, code, 0, 0);          icmp_error(m, type, code, 0, 0);
         ipstat.ips_badoptions++;          ipstat.ips_badoptions++;
         return (1);          return (1);
Line 984  ip_rtaddr(dst)
Line 1055  ip_rtaddr(dst)
          struct in_addr dst;           struct in_addr dst;
 {  {
         register struct sockaddr_in *sin;          register struct sockaddr_in *sin;
         struct in_ifaddr *ia;  
         int s;  
   
         sin = satosin(&ipforward_rt.ro_dst);          sin = satosin(&ipforward_rt.ro_dst);
   
Line 1002  ip_rtaddr(dst)
Line 1071  ip_rtaddr(dst)
         }          }
         if (ipforward_rt.ro_rt == 0)          if (ipforward_rt.ro_rt == 0)
                 return ((struct in_ifaddr *)0);                  return ((struct in_ifaddr *)0);
         s = splimp();          return (ifatoia(ipforward_rt.ro_rt->rt_ifa));
         ia = (ifatoia(ipforward_rt.ro_rt->rt_ifa));  
         ifa_addref(&ia->ia_ifa);  
         splx(s);  
         return ia;  
 }  }
   
 /*  /*
Line 1118  ip_stripoptions(m, mopt)
Line 1183  ip_stripoptions(m, mopt)
         register caddr_t opts;          register caddr_t opts;
         int olen;          int olen;
   
         olen = (ip->ip_hl<<2) - sizeof (struct ip);          olen = (ip->ip_hl << 2) - sizeof (struct ip);
         opts = (caddr_t)(ip + 1);          opts = (caddr_t)(ip + 1);
         i = m->m_len - (sizeof (struct ip) + olen);          i = m->m_len - (sizeof (struct ip) + olen);
         bcopy(opts  + olen, opts, (unsigned)i);          bcopy(opts  + olen, opts, (unsigned)i);
         m->m_len -= olen;          m->m_len -= olen;
         if (m->m_flags & M_PKTHDR)          if (m->m_flags & M_PKTHDR)
                 m->m_pkthdr.len -= olen;                  m->m_pkthdr.len -= olen;
         ip->ip_hl = sizeof(struct ip) >> 2;          ip->ip_len -= olen;
           ip->ip_hl = sizeof (struct ip) >> 2;
 }  }
   
 int inetctlerrmap[PRC_NCMDS] = {  int inetctlerrmap[PRC_NCMDS] = {
Line 1171  ip_forward(m, srcrt)
Line 1237  ip_forward(m, srcrt)
                     ntohl(ip->ip_src.s_addr),                      ntohl(ip->ip_src.s_addr),
                     ntohl(ip->ip_dst.s_addr), ip->ip_ttl);                      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|M_MCAST) || in_canforward(ip->ip_dst) == 0) {
                 ipstat.ips_cantforward++;                  ipstat.ips_cantforward++;
                 m_freem(m);                  m_freem(m);
                 return;                  return;
         }          }
         HTONS(ip->ip_id);  
         if (ip->ip_ttl <= IPTTLDEC) {          if (ip->ip_ttl <= IPTTLDEC) {
                 icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);                  icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
                 return;                  return;
Line 1223  ip_forward(m, srcrt)
Line 1288  ip_forward(m, srcrt)
                 if (rt->rt_ifa &&                  if (rt->rt_ifa &&
                     (ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) ==                      (ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) ==
                     ifatoia(rt->rt_ifa)->ia_subnet) {                      ifatoia(rt->rt_ifa)->ia_subnet) {
                     if (rt->rt_flags & RTF_GATEWAY)                          if (rt->rt_flags & RTF_GATEWAY)
                         dest = satosin(rt->rt_gateway)->sin_addr.s_addr;                                  dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
                     else                          else
                         dest = ip->ip_dst.s_addr;                                  dest = ip->ip_dst.s_addr;
                     /* Router requirements says to only send host redirects */                          /*
                     type = ICMP_REDIRECT;                           * Router requirements says to only send host
                     code = ICMP_REDIRECT_HOST;                           * redirects.
                            */
                           type = ICMP_REDIRECT;
                           code = ICMP_REDIRECT_HOST;
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
                     if (ipprintfs)                          if (ipprintfs)
                         printf("redirect (%d) to %x\n", code, (u_int32_t)dest);                                  printf("redirect (%d) to %x\n", code,
                                       (u_int32_t)dest);
 #endif  #endif
                 }                  }
         }          }

Legend:
Removed from v.1.74.2.1  
changed lines
  Added in v.1.82.2.4

CVSweb <webmaster@jp.NetBSD.org>