[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.39 and 1.62

version 1.39, 1996/10/13 02:03:05 version 1.62, 1998/04/29 20:45:30
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
  */   */
   
   #include "opt_gateway.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 42 
Line 82 
 #include <sys/domain.h>  #include <sys/domain.h>
 #include <sys/protosw.h>  #include <sys/protosw.h>
 #include <sys/socket.h>  #include <sys/socket.h>
   #include <sys/socketvar.h>
 #include <sys/errno.h>  #include <sys/errno.h>
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
Line 51 
Line 92 
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   
 #include <net/if.h>  #include <net/if.h>
   #include <net/if_dl.h>
 #include <net/route.h>  #include <net/route.h>
   #include <net/pfil.h>
   
 #include <netinet/in.h>  #include <netinet/in.h>
 #include <netinet/in_systm.h>  #include <netinet/in_systm.h>
Line 61 
Line 104 
 #include <netinet/ip_var.h>  #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>  #include <netinet/ip_icmp.h>
   
 #ifdef PFIL_HOOKS  
 #include <net/pfil.h>  
 #endif /* PFIL_HOOKS */  
   
 #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 76 
Line 115 
 #define IPSENDREDIRECTS 1  #define IPSENDREDIRECTS 1
 #endif  #endif
 #ifndef IPFORWSRCRT  #ifndef IPFORWSRCRT
 #define IPFORWSRCRT     1       /* allow source-routed packets */  #define IPFORWSRCRT     1       /* forward source-routed packets */
   #endif
   #ifndef IPALLOWSRCRT
   #define IPALLOWSRCRT    1       /* allow source-routed packets */
   #endif
   #ifndef IPMTUDISC
   #define IPMTUDISC       0
   #endif
   #ifndef IPMTUDISCTIMEOUT
   #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 94  int ipsendredirects = IPSENDREDIRECTS;
Line 143  int ipsendredirects = IPSENDREDIRECTS;
 int     ip_defttl = IPDEFTTL;  int     ip_defttl = IPDEFTTL;
 int     ip_forwsrcrt = IPFORWSRCRT;  int     ip_forwsrcrt = IPFORWSRCRT;
 int     ip_directedbcast = IPDIRECTEDBCAST;  int     ip_directedbcast = IPDIRECTEDBCAST;
   int     ip_allowsrcrt = IPALLOWSRCRT;
   int     ip_mtudisc = IPMTUDISC;
   u_int   ip_mtudisc_timeout = IPMTUDISCTIMEOUT;
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
 int     ipprintfs = 0;  int     ipprintfs = 0;
 #endif  #endif
   
   struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
   
 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];
 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;
   
 /*  /*
Line 146  ip_init()
Line 201  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)
                   ip_mtudisc_timeout_q =
                       rt_timer_queue_create(ip_mtudisc_timeout);
 }  }
   
 struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };  struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
Line 162  ipintr()
Line 222  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
         struct packet_filter_hook *pfh;          struct packet_filter_hook *pfh;
         struct mbuf *m0;          struct mbuf *m0;
           int rv;
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
   
 next:  next:
Line 248  next:
Line 310  next:
          * Run through list of hooks for input packets.           * Run through list of hooks for input packets.
          */           */
         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) {
                         if (pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0))                          rv = pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0);
                                 goto bad;                          if (rv)
                                   goto next;
                         ip = mtod(m = m0, struct ip *);                          ip = mtod(m = m0, struct ip *);
                 }                  }
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
Line 269  next:
Line 332  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 284  next:
Line 348  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;
                 }                  }
         }          }
         if (IN_MULTICAST(ip->ip_dst.s_addr)) {          if (IN_MULTICAST(ip->ip_dst.s_addr)) {
Line 365  ours:
Line 435  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 & ~(IP_DF|IP_RF)) {          if (ip->ip_off & ~(IP_DF|IP_RF)) {
                 if (m->m_flags & M_EXT) {               /* XXX */  
                         if ((m = m_pullup(m, sizeof (struct ip))) == 0) {  
                                 ipstat.ips_toosmall++;  
                                 goto next;  
                         }  
                         ip = mtod(m, struct ip *);  
                 }  
                 /*                  /*
                  * Look for queue of fragments                   * Look for queue of fragments
                  * of this datagram.                   * of this datagram.
Line 418  found:
Line 481  found:
                                 goto bad;                                  goto bad;
                         }                          }
                         ipqe->ipqe_mff = mff;                          ipqe->ipqe_mff = mff;
                           ipqe->ipqe_m = m;
                         ipqe->ipqe_ip = ip;                          ipqe->ipqe_ip = ip;
                         ip = ip_reass(ipqe, fp);                          m = ip_reass(ipqe, fp);
                         if (ip == 0)                          if (m == 0)
                                 goto next;                                  goto next;
                         ipstat.ips_reassembled++;                          ipstat.ips_reassembled++;
                         m = dtom(ip);                          ip = mtod(m, struct ip *);
                 } else                  } else
                         if (fp)                          if (fp)
                                 ip_freef(fp);                                  ip_freef(fp);
Line 437  found:
Line 501  found:
         (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);          (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
         goto next;          goto next;
 bad:  bad:
 #ifdef PFIL_HOOKS  
         m0 = m;  
         for (pfh = pfil_hook_get(PFIL_BAD); pfh; pfh = pfh->pfil_link.le_next)  
                 if (pfh->pfil_func) {  
                         (void)pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 2, &m0);  
                         ip = mtod(m = m0, struct ip *);  
                 }  
 #endif /* PFIL_HOOKS */  
         m_freem(m);          m_freem(m);
         goto next;          goto next;
 }  }
Line 455  bad:
Line 511  bad:
  * reassembly of this datagram already exists, then it   * reassembly of this datagram already exists, then it
  * is given as fp; otherwise have to make a chain.   * is given as fp; otherwise have to make a chain.
  */   */
 struct ip *  struct mbuf *
 ip_reass(ipqe, fp)  ip_reass(ipqe, fp)
         register struct ipqent *ipqe;          register struct ipqent *ipqe;
         register struct ipq *fp;          register struct ipq *fp;
 {  {
         register struct mbuf *m = dtom(ipqe->ipqe_ip);          register struct mbuf *m = ipqe->ipqe_m;
         register struct ipqent *nq, *p, *q;          register struct ipqent *nq, *p, *q;
         struct ip *ip;          struct ip *ip;
         struct mbuf *t;          struct mbuf *t;
Line 478  ip_reass(ipqe, fp)
Line 534  ip_reass(ipqe, fp)
          * If first fragment to arrive, create a reassembly queue.           * If first fragment to arrive, create a reassembly queue.
          */           */
         if (fp == 0) {          if (fp == 0) {
                 if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)                  MALLOC(fp, struct ipq *, sizeof (struct ipq),
                       M_FTABLE, M_NOWAIT);
                   if (fp == NULL)
                         goto dropfrag;                          goto dropfrag;
                 fp = mtod(t, struct ipq *);  
                 LIST_INSERT_HEAD(&ipq, fp, ipq_q);                  LIST_INSERT_HEAD(&ipq, fp, ipq_q);
                 fp->ipq_ttl = IPFRAGTTL;                  fp->ipq_ttl = IPFRAGTTL;
                 fp->ipq_p = ipqe->ipqe_ip->ip_p;                  fp->ipq_p = ipqe->ipqe_ip->ip_p;
Line 511  ip_reass(ipqe, fp)
Line 568  ip_reass(ipqe, fp)
                 if (i > 0) {                  if (i > 0) {
                         if (i >= ipqe->ipqe_ip->ip_len)                          if (i >= ipqe->ipqe_ip->ip_len)
                                 goto dropfrag;                                  goto dropfrag;
                         m_adj(dtom(ipqe->ipqe_ip), i);                          m_adj(ipqe->ipqe_m, i);
                         ipqe->ipqe_ip->ip_off += i;                          ipqe->ipqe_ip->ip_off += i;
                         ipqe->ipqe_ip->ip_len -= i;                          ipqe->ipqe_ip->ip_len -= i;
                 }                  }
Line 528  ip_reass(ipqe, fp)
Line 585  ip_reass(ipqe, fp)
                 if (i < q->ipqe_ip->ip_len) {                  if (i < q->ipqe_ip->ip_len) {
                         q->ipqe_ip->ip_len -= i;                          q->ipqe_ip->ip_len -= i;
                         q->ipqe_ip->ip_off += i;                          q->ipqe_ip->ip_off += i;
                         m_adj(dtom(q->ipqe_ip), i);                          m_adj(q->ipqe_m, i);
                         break;                          break;
                 }                  }
                 nq = q->ipqe_q.le_next;                  nq = q->ipqe_q.le_next;
                 m_freem(dtom(q->ipqe_ip));                  m_freem(q->ipqe_m);
                 LIST_REMOVE(q, ipqe_q);                  LIST_REMOVE(q, ipqe_q);
                 FREE(q, M_IPQ);                  FREE(q, M_IPQ);
         }          }
Line 558  insert:
Line 615  insert:
                 return (0);                  return (0);
   
         /*          /*
          * Reassembly is complete; concatenate fragments.           * Reassembly is complete.  Check for a bogus message size and
            * concatenate fragments.
          */           */
         q = fp->ipq_fragq.lh_first;          q = fp->ipq_fragq.lh_first;
         ip = q->ipqe_ip;          ip = q->ipqe_ip;
         m = dtom(q->ipqe_ip);          if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
                   ipstat.ips_toolong++;
                   ip_freef(fp);
                   return (0);
           }
           m = q->ipqe_m;
         t = m->m_next;          t = m->m_next;
         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);          FREE(q, M_IPQ);
         for (q = nq; q != NULL; q = nq) {          for (q = nq; q != NULL; q = nq) {
                 t = dtom(q->ipqe_ip);                  t = q->ipqe_m;
                 nq = q->ipqe_q.le_next;                  nq = q->ipqe_q.le_next;
                 FREE(q, M_IPQ);                  FREE(q, M_IPQ);
                 m_cat(m, t);                  m_cat(m, t);
Line 585  insert:
Line 648  insert:
         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);
         (void) m_free(dtom(fp));          FREE(fp, M_FTABLE);
         m->m_len += (ip->ip_hl << 2);          m->m_len += (ip->ip_hl << 2);
         m->m_data -= (ip->ip_hl << 2);          m->m_data -= (ip->ip_hl << 2);
         /* some debugging cruft by sklower, below, will go away soon */          /* some debugging cruft by sklower, below, will go away soon */
         if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */          if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
                 register int plen = 0;                  register int plen = 0;
                 for (t = m; m; m = m->m_next)                  for (t = m; t; t = t->m_next)
                         plen += m->m_len;                          plen += t->m_len;
                 t->m_pkthdr.len = plen;                  m->m_pkthdr.len = plen;
         }          }
         return (ip);          return (m);
   
 dropfrag:  dropfrag:
         ipstat.ips_fragdropped++;          ipstat.ips_fragdropped++;
Line 616  ip_freef(fp)
Line 679  ip_freef(fp)
   
         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(dtom(q->ipqe_ip));                  m_freem(q->ipqe_m);
                 LIST_REMOVE(q, ipqe_q);                  LIST_REMOVE(q, ipqe_q);
                 FREE(q, M_IPQ);                  FREE(q, M_IPQ);
         }          }
         LIST_REMOVE(fp, ipq_q);          LIST_REMOVE(fp, ipq_q);
         (void) m_free(dtom(fp));          FREE(fp, M_FTABLE);
 }  }
   
 /*  /*
Line 709  ip_dooptions(m)
Line 772  ip_dooptions(m)
                  */                   */
                 case IPOPT_LSRR:                  case IPOPT_LSRR:
                 case IPOPT_SSRR:                  case IPOPT_SSRR:
                           if (ip_allowsrcrt == 0) {
                                   type = ICMP_UNREACH;
                                   code = ICMP_UNREACH_NET_PROHIB;
                                   goto bad;
                           }
                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {                          if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;                                  code = &cp[IPOPT_OFFSET] - (u_char *)ip;
                                 goto bad;                                  goto bad;
Line 1160  ip_forward(m, srcrt)
Line 1228  ip_forward(m, srcrt)
         icmp_error(mcopy, type, code, dest, destifp);          icmp_error(mcopy, type, code, dest, destifp);
 }  }
   
   void
   ip_savecontrol(inp, mp, ip, m)
           register struct inpcb *inp;
           register struct mbuf **mp;
           register struct ip *ip;
           register struct mbuf *m;
   {
   
           if (inp->inp_socket->so_options & SO_TIMESTAMP) {
                   struct timeval tv;
   
                   microtime(&tv);
                   *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
                       SCM_TIMESTAMP, SOL_SOCKET);
                   if (*mp)
                           mp = &(*mp)->m_next;
           }
           if (inp->inp_flags & INP_RECVDSTADDR) {
                   *mp = sbcreatecontrol((caddr_t) &ip->ip_dst,
                       sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
                   if (*mp)
                           mp = &(*mp)->m_next;
           }
   #ifdef notyet
           /*
            * XXX
            * Moving these out of udp_input() made them even more broken
            * than they already were.
            *      - fenner@parc.xerox.com
            */
           /* options were tossed already */
           if (inp->inp_flags & INP_RECVOPTS) {
                   *mp = sbcreatecontrol((caddr_t) opts_deleted_above,
                       sizeof(struct in_addr), IP_RECVOPTS, IPPROTO_IP);
                   if (*mp)
                           mp = &(*mp)->m_next;
           }
           /* ip_srcroute doesn't do what we want here, need to fix */
           if (inp->inp_flags & INP_RECVRETOPTS) {
                   *mp = sbcreatecontrol((caddr_t) ip_srcroute(),
                       sizeof(struct in_addr), IP_RECVRETOPTS, IPPROTO_IP);
                   if (*mp)
                           mp = &(*mp)->m_next;
           }
   #endif
           if (inp->inp_flags & INP_RECVIF) {
                   struct sockaddr_dl sdl;
   
                   sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0]);
                   sdl.sdl_family = AF_LINK;
                   sdl.sdl_index = m->m_pkthdr.rcvif ?
                       m->m_pkthdr.rcvif->if_index : 0;
                   sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0;
                   *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len,
                       IP_RECVIF, IPPROTO_IP);
                   if (*mp)
                           mp = &(*mp)->m_next;
           }
   }
   
 int  int
 ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)  ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
         int *name;          int *name;
Line 1169  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1297  ip_sysctl(name, namelen, oldp, oldlenp, 
         void *newp;          void *newp;
         size_t newlen;          size_t newlen;
 {  {
           extern int subnetsarelocal;
   
           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)
                 return (ENOTDIR);                  return (ENOTDIR);
Line 1186  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1318  ip_sysctl(name, namelen, oldp, oldlenp, 
                 return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu));                  return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu));
 #endif  #endif
         case IPCTL_FORWSRCRT:          case IPCTL_FORWSRCRT:
                 /*                  /* Don't allow this to change in a secure environment.  */
                  * Don't allow this to change in a secure environment.  
                  */  
                 if (securelevel > 0)                  if (securelevel > 0)
                         return (EPERM);                          return (sysctl_rdint(oldp, oldlenp, newp,
                 return (sysctl_int(oldp, oldlenp, newp, newlen,                              ip_forwsrcrt));
                     &ip_forwsrcrt));                  else
                           return (sysctl_int(oldp, oldlenp, newp, newlen,
                               &ip_forwsrcrt));
         case IPCTL_DIRECTEDBCAST:          case IPCTL_DIRECTEDBCAST:
                 return (sysctl_int(oldp, oldlenp, newp, newlen,                  return (sysctl_int(oldp, oldlenp, newp, newlen,
                     &ip_directedbcast));                      &ip_directedbcast));
           case IPCTL_ALLOWSRCRT:
                   return (sysctl_int(oldp, oldlenp, newp, newlen,
                       &ip_allowsrcrt));
           case IPCTL_SUBNETSARELOCAL:
                   return (sysctl_int(oldp, oldlenp, newp, newlen,
                       &subnetsarelocal));
           case IPCTL_MTUDISC:
                   error = sysctl_int(oldp, oldlenp, newp, newlen,
                       &ip_mtudisc);
                   if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) {
                           ip_mtudisc_timeout_q =
                               rt_timer_queue_create(ip_mtudisc_timeout);
                   } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) {
                           rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE);
                           ip_mtudisc_timeout_q = NULL;
                   }
                   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:
                   error = sysctl_int(oldp, oldlenp, newp, newlen,
                      &ip_mtudisc_timeout);
                   if (ip_mtudisc_timeout_q != NULL)
                           rt_timer_queue_change(ip_mtudisc_timeout_q,
                                                 ip_mtudisc_timeout);
                   return (error);
         default:          default:
                 return (EOPNOTSUPP);                  return (EOPNOTSUPP);
         }          }

Legend:
Removed from v.1.39  
changed lines
  Added in v.1.62

CVSweb <webmaster@jp.NetBSD.org>