[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.82.2.2.2.3 and 1.82.2.3

version 1.82.2.2.2.3, 1999/08/02 22:34:58 version 1.82.2.3, 1999/10/17 23:59:59
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*  
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.  
  * All rights reserved.  
  *  
  * 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. Neither the name of the project 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 PROJECT 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 PROJECT 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) 1998 The NetBSD Foundation, Inc.   * Copyright (c) 1998 The NetBSD Foundation, Inc.
  * All rights reserved.   * All rights reserved.
Line 103 
Line 74 
   
 #include "opt_gateway.h"  #include "opt_gateway.h"
 #include "opt_pfil_hooks.h"  #include "opt_pfil_hooks.h"
 #include "opt_ipsec.h"  
 #include "opt_mrouting.h"  #include "opt_mrouting.h"
   
 #include <sys/param.h>  #include <sys/param.h>
Line 135 
Line 105 
 #include <netinet/in_var.h>  #include <netinet/in_var.h>
 #include <netinet/ip_var.h>  #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>  #include <netinet/ip_icmp.h>
 /* just for gif_ttl */  
 #include <netinet/in_gif.h>  
 #include "gif.h"  
   
 #ifdef IPSEC  
 #include <netinet6/ipsec.h>  
 #include <netkey/key.h>  
 #include <netkey/key_debug.h>  
 #endif  
   
 #ifndef IPFORWARDING  #ifndef IPFORWARDING
 #ifdef GATEWAY  #ifdef GATEWAY
Line 317  struct sockaddr_in ipaddr = { sizeof(ipa
Line 278  struct sockaddr_in ipaddr = { sizeof(ipa
 struct  route ipforward_rt;  struct  route ipforward_rt;
   
 /*  /*
  * IP software interrupt routine  
  */  
 void  
 ipintr()  
 {  
         int s;  
         struct mbuf *m;  
   
         while (1) {  
                 s = splimp();  
                 IF_DEQUEUE(&ipintrq, m);  
                 splx(s);  
                 if (m == 0)  
                         return;  
                 ip_input(m);  
         }  
 }  
   
 /*  
  * Ip input routine.  Checksum and byte swap header.  If fragmented   * Ip input routine.  Checksum and byte swap header.  If fragmented
  * try to reassemble.  Process options.  Pass to next level.   * try to reassemble.  Process options.  Pass to next level.
  */   */
 void  void
 ip_input(struct mbuf *m)  ipintr()
 {  {
         register struct ip *ip = NULL;          register struct ip *ip = NULL;
           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;          register struct ifaddr *ifa;
         struct ipqent *ipqe;          struct ipqent *ipqe;
         int hlen = 0, mff, len;          int hlen = 0, mff, len, s;
 #ifdef PFIL_HOOKS  #ifdef PFIL_HOOKS
         struct packet_filter_hook *pfh;          struct packet_filter_hook *pfh;
         struct mbuf *m0;          struct mbuf *m0;
         int rv;          int rv;
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
   
   next:
           /*
            * Get next datagram off input queue and get IP header
            * in first mbuf.
            */
           s = splimp();
           IF_DEQUEUE(&ipintrq, m);
           splx(s);
           if (m == 0)
                   return;
 #ifdef  DIAGNOSTIC  #ifdef  DIAGNOSTIC
         if ((m->m_flags & M_PKTHDR) == 0)          if ((m->m_flags & M_PKTHDR) == 0)
                 panic("ipintr no HDR");                  panic("ipintr no HDR");
 #endif  #endif
 #ifdef IPSEC  
         /*  
          * should the inner packet be considered authentic?  
          * see comment in ah4_input().  
          */  
         if (m) {  
                 m->m_flags &= ~M_AUTHIPHDR;  
                 m->m_flags &= ~M_AUTHIPDGM;  
         }  
 #endif  
         /*          /*
          * If no IP addresses have been set yet but the interfaces           * If no IP addresses have been set yet but the interfaces
          * are receiving, can't do anything with incoming packets yet.           * are receiving, can't do anything with incoming packets yet.
Line 378  ip_input(struct mbuf *m)
Line 321  ip_input(struct mbuf *m)
         if (m->m_len < sizeof (struct ip) &&          if (m->m_len < sizeof (struct ip) &&
             (m = m_pullup(m, sizeof (struct ip))) == 0) {              (m = m_pullup(m, sizeof (struct ip))) == 0) {
                 ipstat.ips_toosmall++;                  ipstat.ips_toosmall++;
                 return;                  goto next;
         }          }
         ip = mtod(m, struct ip *);          ip = mtod(m, struct ip *);
         if (ip->ip_v != IPVERSION) {          if (ip->ip_v != IPVERSION) {
Line 393  ip_input(struct mbuf *m)
Line 336  ip_input(struct mbuf *m)
         if (hlen > m->m_len) {          if (hlen > m->m_len) {
                 if ((m = m_pullup(m, hlen)) == 0) {                  if ((m = m_pullup(m, hlen)) == 0) {
                         ipstat.ips_badhlen++;                          ipstat.ips_badhlen++;
                         return;                          goto next;
                 }                  }
                 ip = mtod(m, struct ip *);                  ip = mtod(m, struct ip *);
         }          }
         /*  
          * we drop packets that have a multicast address as source  
          * as wanted by rfc 1112  
          */  
         if (IN_MULTICAST(ip->ip_src.s_addr)) {  
                 goto bad;  
         }  
   
         if (in_cksum(m, hlen) != 0) {          if (in_cksum(m, hlen) != 0) {
                 ipstat.ips_badsum++;                  ipstat.ips_badsum++;
                 goto bad;                  goto bad;
Line 420  ip_input(struct mbuf *m)
Line 355  ip_input(struct mbuf *m)
         /*          /*
          * Check for additional length bogosity           * Check for additional length bogosity
          */           */
         if (len < hlen) {          if (len < hlen)
           {
                 ipstat.ips_badlen++;                  ipstat.ips_badlen++;
                 goto bad;                  goto bad;
         }          }
Line 462  ip_input(struct mbuf *m)
Line 398  ip_input(struct mbuf *m)
                 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)
                                 return;                                  goto next;
                         m = m0;                          m = m0;
                         if (m == NULL)                          if (m == NULL)
                                 return;                                  goto next;
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
                 }                  }
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
Line 478  ip_input(struct mbuf *m)
Line 414  ip_input(struct mbuf *m)
          */           */
         ip_nhops = 0;           /* for source routed packets */          ip_nhops = 0;           /* for source routed packets */
         if (hlen > sizeof (struct ip) && ip_dooptions(m))          if (hlen > sizeof (struct ip) && ip_dooptions(m))
                 return;                  goto 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.
Line 516  ip_input(struct mbuf *m)
Line 452  ip_input(struct mbuf *m)
                 if (m->m_flags & M_EXT) {                  if (m->m_flags & M_EXT) {
                         if ((m = m_pullup(m, hlen)) == 0) {                          if ((m = m_pullup(m, hlen)) == 0) {
                                 ipstat.ips_toosmall++;                                  ipstat.ips_toosmall++;
                                 return;                                  goto next;
                         }                          }
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
                 }                  }
Line 537  ip_input(struct mbuf *m)
Line 473  ip_input(struct mbuf *m)
                         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);
                                 return;                                  goto next;
                         }                          }
   
                         /*                          /*
Line 558  ip_input(struct mbuf *m)
Line 494  ip_input(struct mbuf *m)
                 if (inm == NULL) {                  if (inm == NULL) {
                         ipstat.ips_cantforward++;                          ipstat.ips_cantforward++;
                         m_freem(m);                          m_freem(m);
                         return;                          goto next;
                 }                  }
                 goto ours;                  goto ours;
         }          }
Line 574  ip_input(struct mbuf *m)
Line 510  ip_input(struct mbuf *m)
                 m_freem(m);                  m_freem(m);
         } else          } else
                 ip_forward(m, 0);                  ip_forward(m, 0);
         return;          goto next;
   
 ours:  ours:
         /*          /*
Line 638  found:
Line 574  found:
                         m = ip_reass(ipqe, fp);                          m = ip_reass(ipqe, fp);
                         if (m == 0) {                          if (m == 0) {
                                 IPQ_UNLOCK();                                  IPQ_UNLOCK();
                                 return;                                  goto next;
                         }                          }
                         ipstat.ips_reassembled++;                          ipstat.ips_reassembled++;
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
Line 657  found:
Line 593  found:
         ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len;          ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len;
 #endif  #endif
         ipstat.ips_delivered++;          ipstat.ips_delivered++;
     {          (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
         int off = hlen, nh = ip->ip_p;          goto next;
   
         (*inetsw[ip_protox[nh]].pr_input)(m, off, nh);  
         return;  
     }  
 bad:  bad:
         m_freem(m);          m_freem(m);
           goto next;
 }  }
   
 /*  /*
Line 809  insert:
Line 742  insert:
          * Make header visible.           * Make header visible.
          */           */
         ip->ip_len = next;          ip->ip_len = next;
         ip->ip_ttl = 0; /* xxx */  
         ip->ip_sum = 0;  
         ip->ip_src = fp->ipq_src;          ip->ip_src = fp->ipq_src;
         ip->ip_dst = fp->ipq_dst;          ip->ip_dst = fp->ipq_dst;
         LIST_REMOVE(fp, ipq_q);          LIST_REMOVE(fp, ipq_q);
Line 1148  save_rte(option, dst)
Line 1079  save_rte(option, dst)
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (ipprintfs)          if (ipprintfs)
                 printf("save_rte: olen %d\n", olen);                  printf("save_rte: olen %d\n", olen);
 #endif /* 0 */  #endif
         if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))          if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))
                 return;                  return;
         bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen);          bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen);
Line 1288  ip_forward(m, srcrt)
Line 1219  ip_forward(m, srcrt)
         struct mbuf *mcopy;          struct mbuf *mcopy;
         n_long dest;          n_long dest;
         struct ifnet *destifp;          struct ifnet *destifp;
 #ifdef IPSEC  
         struct ifnet dummyifp;  
 #endif  
   
         dest = 0;          dest = 0;
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
Line 1299  ip_forward(m, srcrt)
Line 1227  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;
Line 1368  ip_forward(m, srcrt)
Line 1296  ip_forward(m, srcrt)
                 }                  }
         }          }
   
 #ifdef IPSEC  
         m->m_pkthdr.rcvif = NULL;  
 #endif /*IPSEC*/  
         error = ip_output(m, (struct mbuf *)0, &ipforward_rt,          error = ip_output(m, (struct mbuf *)0, &ipforward_rt,
             (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0);              (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0);
         if (error)          if (error)
Line 1412  ip_forward(m, srcrt)
Line 1337  ip_forward(m, srcrt)
         case EMSGSIZE:          case EMSGSIZE:
                 type = ICMP_UNREACH;                  type = ICMP_UNREACH;
                 code = ICMP_UNREACH_NEEDFRAG;                  code = ICMP_UNREACH_NEEDFRAG;
 #ifndef IPSEC  
                 if (ipforward_rt.ro_rt)                  if (ipforward_rt.ro_rt)
                         destifp = ipforward_rt.ro_rt->rt_ifp;                          destifp = ipforward_rt.ro_rt->rt_ifp;
 #else  
                 /*  
                  * If the packet is routed over IPsec tunnel, tell the  
                  * originator the tunnel MTU.  
                  *      tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz  
                  * XXX quickhack!!!  
                  */  
                 if (ipforward_rt.ro_rt) {  
                         struct secpolicy *sp;  
                         int ipsecerror;  
                         int ipsechdr;  
                         struct route *ro;  
   
                         sp = ipsec4_getpolicybyaddr(mcopy,  
                                                     IP_FORWARDING,  
                                                     &ipsecerror);  
   
                         if (sp == NULL)  
                                 destifp = ipforward_rt.ro_rt->rt_ifp;  
                         else {  
                                 /* count IPsec header size */  
                                 ipsechdr = ipsec4_hdrsiz(mcopy, NULL);  
   
                                 /*  
                                  * find the correct route for outer IPv4  
                                  * header, compute tunnel MTU.  
                                  *  
                                  * XXX BUG ALERT  
                                  * The "dummyifp" code relies upon the fact  
                                  * that icmp_error() touches only ifp->if_mtu.  
                                  */  
                                 /*XXX*/  
                                 destifp = NULL;  
                                 if (sp->req != NULL  
                                  && sp->req->sa != NULL) {  
                                         ro = &sp->req->sa->saidx->sa_route;  
                                         if (ro->ro_rt && ro->ro_rt->rt_ifp) {  
                                                 dummyifp.if_mtu =  
                                                     ro->ro_rt->rt_ifp->if_mtu;  
                                                 dummyifp.if_mtu -= ipsechdr;  
                                                 destifp = &dummyifp;  
                                         }  
                                 }  
   
                                 key_freesp(sp);  
                         }  
                 }  
 #endif /*IPSEC*/  
                 ipstat.ips_cantfrag++;                  ipstat.ips_cantfrag++;
                 break;                  break;
   
Line 1543  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1419  ip_sysctl(name, namelen, oldp, oldlenp, 
         void *newp;          void *newp;
         size_t newlen;          size_t newlen;
 {  {
         extern int subnetsarelocal, hostzeroisbroadcast;          extern int subnetsarelocal;
   
         int error, old;          int error, old;
   
Line 1635  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1511  ip_sysctl(name, namelen, oldp, oldlenp, 
                 return (error);                  return (error);
             }              }
 #endif  #endif
         case IPCTL_HOSTZEROBROADCAST:  
                 return (sysctl_int(oldp, oldlenp, newp, newlen,  
                     &hostzeroisbroadcast));  
 #if NGIF > 0  
         case IPCTL_GIF_TTL:  
                 return(sysctl_int(oldp, oldlenp, newp, newlen,  
                                   &ip_gif_ttl));  
 #endif  
   
         default:          default:
                 return (EOPNOTSUPP);                  return (EOPNOTSUPP);
         }          }

Legend:
Removed from v.1.82.2.2.2.3  
changed lines
  Added in v.1.82.2.3

CVSweb <webmaster@jp.NetBSD.org>