[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.4.3 and 1.84

version 1.82.2.2.4.3, 1999/11/30 13:35:31 version 1.84, 1999/04/07 05:34:32
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 193  int ipprintfs = 0;
Line 154  int ipprintfs = 0;
   
 struct rttimer_queue *ip_mtudisc_timeout_q = NULL;  struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
   
 #ifdef ALTQ  
 int (*altq_input) __P((struct mbuf *, int)) = NULL;  
 #endif  
   
 extern  struct domain inetdomain;  extern  struct domain inetdomain;
 extern  struct protosw inetsw[];  extern  struct protosw inetsw[];
 u_char  ip_protox[IPPROTO_MAX];  u_char  ip_protox[IPPROTO_MAX];
Line 321  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 382  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 397  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 *);
         }          }
Line 406  ip_input(struct mbuf *m)
Line 345  ip_input(struct mbuf *m)
                 goto bad;                  goto bad;
         }          }
   
 #ifdef ALTQ  
         if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0)  
                 /* packet is dropped by traffic conditioner */  
                 return;  
 #endif  
         /*          /*
          * Convert fields to host representation.           * Convert fields to host representation.
          */           */
Line 421  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 445  ip_input(struct mbuf *m)
Line 378  ip_input(struct mbuf *m)
                         m_adj(m, len - m->m_pkthdr.len);                          m_adj(m, len - m->m_pkthdr.len);
         }          }
   
 #ifdef IPSEC  
         /* ipflow (IP fast fowarding) is not compatible with IPsec. */  
         m->m_flags &= ~M_CANFASTFWD;  
 #else  
         /*          /*
          * 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.
          */           */
         m->m_flags |= M_CANFASTFWD;          m->m_flags |= M_CANFASTFWD;
 #endif  
   
 #ifdef PFIL_HOOKS  #ifdef PFIL_HOOKS
         /*          /*
Line 469  ip_input(struct mbuf *m)
Line 397  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 485  ip_input(struct mbuf *m)
Line 413  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.
          */           */
         INADDR_TO_IA(ip->ip_dst, ia);          INADDR_TO_IA(ip->ip_dst, ia);
         if (ia != NULL)          if (ia != NULL) {
                 goto ours;                  if (ia->ia_ifp->if_flags & IFF_UP)
                           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) {
Line 523  ip_input(struct mbuf *m)
Line 453  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 544  ip_input(struct mbuf *m)
Line 474  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 565  ip_input(struct mbuf *m)
Line 495  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 581  ip_input(struct mbuf *m)
Line 511  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 645  found:
Line 575  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 664  found:
Line 594  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 816  insert:
Line 743  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 1155  save_rte(option, dst)
Line 1080  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 1295  ip_forward(m, srcrt)
Line 1220  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 1375  ip_forward(m, srcrt)
Line 1297  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 1419  ip_forward(m, srcrt)
Line 1338  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,  
                                                     IPSEC_DIR_OUTBOUND,  
                                                     IP_FORWARDING,  
                                                     &ipsecerror);  
   
                         if (sp == NULL)  
                                 destifp = ipforward_rt.ro_rt->rt_ifp;  
                         else {  
                                 /* count IPsec header size */  
                                 ipsechdr = ipsec4_hdrsiz(mcopy,  
                                                          IPSEC_DIR_OUTBOUND,  
                                                          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->sav != NULL  
                                  && sp->req->sav->sah != NULL) {  
                                         ro = &sp->req->sav->sah->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 1646  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1512  ip_sysctl(name, namelen, oldp, oldlenp, 
                 return (error);                  return (error);
             }              }
 #endif  #endif
 #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.4.3  
changed lines
  Added in v.1.84

CVSweb <webmaster@jp.NetBSD.org>