LCOV - code coverage report
Current view: top level - netinet - ip_input.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 792 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ip_input.c,v 1.341 2018/09/11 21:04:03 bluhm Exp $    */
       2             : /*      $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1982, 1986, 1988, 1993
       6             :  *      The Regents of the University of California.  All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer.
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  * 3. Neither the name of the University nor the names of its contributors
      17             :  *    may be used to endorse or promote products derived from this software
      18             :  *    without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      21             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      22             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      24             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      25             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      26             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      27             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      28             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      29             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      30             :  * SUCH DAMAGE.
      31             :  *
      32             :  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
      33             :  */
      34             : 
      35             : #include "pf.h"
      36             : #include "carp.h"
      37             : 
      38             : #include <sys/param.h>
      39             : #include <sys/systm.h>
      40             : #include <sys/mbuf.h>
      41             : #include <sys/domain.h>
      42             : #include <sys/mutex.h>
      43             : #include <sys/protosw.h>
      44             : #include <sys/socket.h>
      45             : #include <sys/socketvar.h>
      46             : #include <sys/sysctl.h>
      47             : #include <sys/pool.h>
      48             : #include <sys/task.h>
      49             : 
      50             : #include <net/if.h>
      51             : #include <net/if_var.h>
      52             : #include <net/if_dl.h>
      53             : #include <net/route.h>
      54             : #include <net/netisr.h>
      55             : 
      56             : #include <netinet/in.h>
      57             : #include <netinet/in_systm.h>
      58             : #include <netinet/if_ether.h>
      59             : #include <netinet/ip.h>
      60             : #include <netinet/in_pcb.h>
      61             : #include <netinet/in_var.h>
      62             : #include <netinet/ip_var.h>
      63             : #include <netinet/ip_icmp.h>
      64             : 
      65             : #ifdef INET6
      66             : #include <netinet6/ip6protosw.h>
      67             : #include <netinet6/ip6_var.h>
      68             : #endif
      69             : 
      70             : #if NPF > 0
      71             : #include <net/pfvar.h>
      72             : #endif
      73             : 
      74             : #ifdef MROUTING
      75             : #include <netinet/ip_mroute.h>
      76             : #endif
      77             : 
      78             : #ifdef IPSEC
      79             : #include <netinet/ip_ipsp.h>
      80             : #endif /* IPSEC */
      81             : 
      82             : #if NCARP > 0
      83             : #include <net/if_types.h>
      84             : #include <netinet/ip_carp.h>
      85             : #endif
      86             : 
      87             : /* values controllable via sysctl */
      88             : int     ipforwarding = 0;
      89             : int     ipmforwarding = 0;
      90             : int     ipmultipath = 0;
      91             : int     ipsendredirects = 1;
      92             : int     ip_dosourceroute = 0;
      93             : int     ip_defttl = IPDEFTTL;
      94             : int     ip_mtudisc = 1;
      95             : u_int   ip_mtudisc_timeout = IPMTUDISCTIMEOUT;
      96             : int     ip_directedbcast = 0;
      97             : 
      98             : struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
      99             : 
     100             : /* Protects `ipq' and `ip_frags'. */
     101             : struct mutex    ipq_mutex = MUTEX_INITIALIZER(IPL_SOFTNET);
     102             : 
     103             : /* IP reassembly queue */
     104             : LIST_HEAD(, ipq) ipq;
     105             : 
     106             : /* Keep track of memory used for reassembly */
     107             : int     ip_maxqueue = 300;
     108             : int     ip_frags = 0;
     109             : 
     110             : int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS;
     111             : 
     112             : struct niqueue ipintrq = NIQUEUE_INITIALIZER(IPQ_MAXLEN, NETISR_IP);
     113             : 
     114             : struct pool ipqent_pool;
     115             : struct pool ipq_pool;
     116             : 
     117             : struct cpumem *ipcounters;
     118             : 
     119             : int ip_sysctl_ipstat(void *, size_t *, void *);
     120             : 
     121             : static struct mbuf_queue        ipsend_mq;
     122             : 
     123             : int     ip_ours(struct mbuf **, int *, int, int);
     124             : int     ip_local(struct mbuf **, int *, int, int);
     125             : int     ip_dooptions(struct mbuf *, struct ifnet *);
     126             : int     in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **);
     127             : 
     128             : static void ip_send_dispatch(void *);
     129             : static struct task ipsend_task = TASK_INITIALIZER(ip_send_dispatch, &ipsend_mq);
     130             : /*
     131             :  * Used to save the IP options in case a protocol wants to respond
     132             :  * to an incoming packet over the same route if the packet got here
     133             :  * using IP source routing.  This allows connection establishment and
     134             :  * maintenance when the remote end is on a network that is not known
     135             :  * to us.
     136             :  */
     137             : struct ip_srcrt {
     138             :         int             isr_nhops;                 /* number of hops */
     139             :         struct in_addr  isr_dst;                   /* final destination */
     140             :         char            isr_nop;                   /* one NOP to align */
     141             :         char            isr_hdr[IPOPT_OFFSET + 1]; /* OPTVAL, OLEN & OFFSET */
     142             :         struct in_addr  isr_routes[MAX_IPOPTLEN/sizeof(struct in_addr)];
     143             : };
     144             : 
     145             : void save_rte(struct mbuf *, u_char *, struct in_addr);
     146             : 
     147             : /*
     148             :  * IP initialization: fill in IP protocol switch table.
     149             :  * All protocols not implemented in kernel go to raw IP protocol handler.
     150             :  */
     151             : void
     152           0 : ip_init(void)
     153             : {
     154             :         const struct protosw *pr;
     155             :         int i;
     156             :         const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP;
     157             :         const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP;
     158             :         const u_int16_t defrootonlyports_tcp[] = DEFROOTONLYPORTS_TCP;
     159             :         const u_int16_t defrootonlyports_udp[] = DEFROOTONLYPORTS_UDP;
     160             : 
     161           0 :         ipcounters = counters_alloc(ips_ncounters);
     162             : 
     163           0 :         pool_init(&ipqent_pool, sizeof(struct ipqent), 0,
     164             :             IPL_SOFTNET, 0, "ipqe",  NULL);
     165           0 :         pool_init(&ipq_pool, sizeof(struct ipq), 0,
     166             :             IPL_SOFTNET, 0, "ipq", NULL);
     167             : 
     168           0 :         pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
     169           0 :         if (pr == NULL)
     170           0 :                 panic("ip_init");
     171           0 :         for (i = 0; i < IPPROTO_MAX; i++)
     172           0 :                 ip_protox[i] = pr - inetsw;
     173           0 :         for (pr = inetdomain.dom_protosw;
     174           0 :             pr < inetdomain.dom_protoswNPROTOSW; pr++)
     175           0 :                 if (pr->pr_domain->dom_family == PF_INET &&
     176           0 :                     pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW &&
     177           0 :                     pr->pr_protocol < IPPROTO_MAX)
     178           0 :                         ip_protox[pr->pr_protocol] = pr - inetsw;
     179           0 :         LIST_INIT(&ipq);
     180           0 :         if (ip_mtudisc != 0)
     181           0 :                 ip_mtudisc_timeout_q =
     182           0 :                     rt_timer_queue_create(ip_mtudisc_timeout);
     183             : 
     184             :         /* Fill in list of ports not to allocate dynamically. */
     185           0 :         memset(&baddynamicports, 0, sizeof(baddynamicports));
     186           0 :         for (i = 0; defbaddynamicports_tcp[i] != 0; i++)
     187           0 :                 DP_SET(baddynamicports.tcp, defbaddynamicports_tcp[i]);
     188           0 :         for (i = 0; defbaddynamicports_udp[i] != 0; i++)
     189           0 :                 DP_SET(baddynamicports.udp, defbaddynamicports_udp[i]);
     190             : 
     191             :         /* Fill in list of ports only root can bind to. */
     192           0 :         memset(&rootonlyports, 0, sizeof(rootonlyports));
     193           0 :         for (i = 0; defrootonlyports_tcp[i] != 0; i++)
     194           0 :                 DP_SET(rootonlyports.tcp, defrootonlyports_tcp[i]);
     195           0 :         for (i = 0; defrootonlyports_udp[i] != 0; i++)
     196           0 :                 DP_SET(rootonlyports.udp, defrootonlyports_udp[i]);
     197             : 
     198           0 :         mq_init(&ipsend_mq, 64, IPL_SOFTNET);
     199             : 
     200             : #ifdef IPSEC
     201           0 :         ipsec_init();
     202             : #endif
     203           0 : }
     204             : 
     205             : /*
     206             :  * Enqueue packet for local delivery.  Queuing is used as a boundary
     207             :  * between the network layer (input/forward path) running without
     208             :  * KERNEL_LOCK() and the transport layer still needing it.
     209             :  */
     210             : int
     211           0 : ip_ours(struct mbuf **mp, int *offp, int nxt, int af)
     212             : {
     213             :         /* We are already in a IPv4/IPv6 local deliver loop. */
     214           0 :         if (af != AF_UNSPEC)
     215           0 :                 return ip_local(mp, offp, nxt, af);
     216             : 
     217           0 :         niq_enqueue(&ipintrq, *mp);
     218           0 :         *mp = NULL;
     219           0 :         return IPPROTO_DONE;
     220           0 : }
     221             : 
     222             : /*
     223             :  * Dequeue and process locally delivered packets.
     224             :  */
     225             : void
     226           0 : ipintr(void)
     227             : {
     228           0 :         struct mbuf *m;
     229           0 :         int off, nxt;
     230             : 
     231           0 :         while ((m = niq_dequeue(&ipintrq)) != NULL) {
     232             : #ifdef DIAGNOSTIC
     233           0 :                 if ((m->m_flags & M_PKTHDR) == 0)
     234           0 :                         panic("ipintr no HDR");
     235             : #endif
     236           0 :                 off = 0;
     237           0 :                 nxt = ip_local(&m, &off, IPPROTO_IPV4, AF_UNSPEC);
     238           0 :                 KASSERT(nxt == IPPROTO_DONE);
     239             :         }
     240           0 : }
     241             : 
     242             : /*
     243             :  * IPv4 input routine.
     244             :  *
     245             :  * Checksum and byte swap header.  Process options. Forward or deliver.
     246             :  */
     247             : void
     248           0 : ipv4_input(struct ifnet *ifp, struct mbuf *m)
     249             : {
     250           0 :         int off, nxt;
     251             : 
     252           0 :         off = 0;
     253           0 :         nxt = ip_input_if(&m, &off, IPPROTO_IPV4, AF_UNSPEC, ifp);
     254           0 :         KASSERT(nxt == IPPROTO_DONE);
     255           0 : }
     256             : 
     257             : int
     258           0 : ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
     259             : {
     260           0 :         struct mbuf     *m = *mp;
     261           0 :         struct rtentry  *rt = NULL;
     262             :         struct ip       *ip;
     263             :         int hlen, len;
     264             :         in_addr_t pfrdr = 0;
     265             : 
     266           0 :         KASSERT(*offp == 0);
     267             : 
     268           0 :         ipstat_inc(ips_total);
     269           0 :         if (m->m_len < sizeof (struct ip) &&
     270           0 :             (m = *mp = m_pullup(m, sizeof (struct ip))) == NULL) {
     271           0 :                 ipstat_inc(ips_toosmall);
     272           0 :                 goto bad;
     273             :         }
     274           0 :         ip = mtod(m, struct ip *);
     275           0 :         if (ip->ip_v != IPVERSION) {
     276           0 :                 ipstat_inc(ips_badvers);
     277           0 :                 goto bad;
     278             :         }
     279           0 :         hlen = ip->ip_hl << 2;
     280           0 :         if (hlen < sizeof(struct ip)) {      /* minimum header length */
     281           0 :                 ipstat_inc(ips_badhlen);
     282           0 :                 goto bad;
     283             :         }
     284           0 :         if (hlen > m->m_len) {
     285           0 :                 if ((m = *mp = m_pullup(m, hlen)) == NULL) {
     286           0 :                         ipstat_inc(ips_badhlen);
     287           0 :                         goto bad;
     288             :                 }
     289           0 :                 ip = mtod(m, struct ip *);
     290           0 :         }
     291             : 
     292             :         /* 127/8 must not appear on wire - RFC1122 */
     293           0 :         if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
     294           0 :             (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
     295           0 :                 if ((ifp->if_flags & IFF_LOOPBACK) == 0) {
     296           0 :                         ipstat_inc(ips_badaddr);
     297           0 :                         goto bad;
     298             :                 }
     299             :         }
     300             : 
     301           0 :         if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) {
     302           0 :                 if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) {
     303           0 :                         ipstat_inc(ips_badsum);
     304           0 :                         goto bad;
     305             :                 }
     306             : 
     307           0 :                 ipstat_inc(ips_inswcsum);
     308           0 :                 if (in_cksum(m, hlen) != 0) {
     309           0 :                         ipstat_inc(ips_badsum);
     310           0 :                         goto bad;
     311             :                 }
     312             :         }
     313             : 
     314             :         /* Retrieve the packet length. */
     315           0 :         len = ntohs(ip->ip_len);
     316             : 
     317             :         /*
     318             :          * Convert fields to host representation.
     319             :          */
     320           0 :         if (len < hlen) {
     321           0 :                 ipstat_inc(ips_badlen);
     322           0 :                 goto bad;
     323             :         }
     324             : 
     325             :         /*
     326             :          * Check that the amount of data in the buffers
     327             :          * is at least as much as the IP header would have us expect.
     328             :          * Trim mbufs if longer than we expect.
     329             :          * Drop packet if shorter than we expect.
     330             :          */
     331           0 :         if (m->m_pkthdr.len < len) {
     332           0 :                 ipstat_inc(ips_tooshort);
     333           0 :                 goto bad;
     334             :         }
     335           0 :         if (m->m_pkthdr.len > len) {
     336           0 :                 if (m->m_len == m->m_pkthdr.len) {
     337           0 :                         m->m_len = len;
     338           0 :                         m->m_pkthdr.len = len;
     339           0 :                 } else
     340           0 :                         m_adj(m, len - m->m_pkthdr.len);
     341             :         }
     342             : 
     343             : #if NCARP > 0
     344           0 :         if (carp_lsdrop(ifp, m, AF_INET, &ip->ip_src.s_addr,
     345           0 :             &ip->ip_dst.s_addr, (ip->ip_p == IPPROTO_ICMP ? 0 : 1)))
     346             :                 goto bad;
     347             : #endif
     348             : 
     349             : #if NPF > 0
     350             :         /*
     351             :          * Packet filter
     352             :          */
     353           0 :         pfrdr = ip->ip_dst.s_addr;
     354           0 :         if (pf_test(AF_INET, PF_IN, ifp, mp) != PF_PASS)
     355             :                 goto bad;
     356           0 :         m = *mp;
     357           0 :         if (m == NULL)
     358             :                 goto bad;
     359             : 
     360           0 :         ip = mtod(m, struct ip *);
     361           0 :         hlen = ip->ip_hl << 2;
     362           0 :         pfrdr = (pfrdr != ip->ip_dst.s_addr);
     363             : #endif
     364             : 
     365             :         /*
     366             :          * Process options and, if not destined for us,
     367             :          * ship it on.  ip_dooptions returns 1 when an
     368             :          * error was detected (causing an icmp message
     369             :          * to be sent and the original packet to be freed).
     370             :          */
     371           0 :         if (hlen > sizeof (struct ip) && ip_dooptions(m, ifp)) {
     372           0 :                 m = *mp = NULL;
     373           0 :                 goto bad;
     374             :         }
     375             : 
     376           0 :         if (ip->ip_dst.s_addr == INADDR_BROADCAST ||
     377           0 :             ip->ip_dst.s_addr == INADDR_ANY) {
     378           0 :                 nxt = ip_ours(mp, offp, nxt, af);
     379           0 :                 goto out;
     380             :         }
     381             : 
     382           0 :         if (in_ouraddr(m, ifp, &rt)) {
     383           0 :                 nxt = ip_ours(mp, offp, nxt, af);
     384           0 :                 goto out;
     385             :         }
     386             : 
     387           0 :         if (IN_MULTICAST(ip->ip_dst.s_addr)) {
     388             :                 /*
     389             :                  * Make sure M_MCAST is set.  It should theoretically
     390             :                  * already be there, but let's play safe because upper
     391             :                  * layers check for this flag.
     392             :                  */
     393           0 :                 m->m_flags |= M_MCAST;
     394             : 
     395             : #ifdef MROUTING
     396           0 :                 if (ipmforwarding && ip_mrouter[ifp->if_rdomain]) {
     397             :                         int error;
     398             : 
     399           0 :                         if (m->m_flags & M_EXT) {
     400           0 :                                 if ((m = *mp = m_pullup(m, hlen)) == NULL) {
     401           0 :                                         ipstat_inc(ips_toosmall);
     402           0 :                                         goto bad;
     403             :                                 }
     404           0 :                                 ip = mtod(m, struct ip *);
     405           0 :                         }
     406             :                         /*
     407             :                          * If we are acting as a multicast router, all
     408             :                          * incoming multicast packets are passed to the
     409             :                          * kernel-level multicast forwarding function.
     410             :                          * The packet is returned (relatively) intact; if
     411             :                          * ip_mforward() returns a non-zero value, the packet
     412             :                          * must be discarded, else it may be accepted below.
     413             :                          *
     414             :                          * (The IP ident field is put in the same byte order
     415             :                          * as expected when ip_mforward() is called from
     416             :                          * ip_output().)
     417             :                          */
     418           0 :                         KERNEL_LOCK();
     419           0 :                         error = ip_mforward(m, ifp);
     420           0 :                         KERNEL_UNLOCK();
     421           0 :                         if (error) {
     422           0 :                                 ipstat_inc(ips_cantforward);
     423           0 :                                 goto bad;
     424             :                         }
     425             : 
     426             :                         /*
     427             :                          * The process-level routing daemon needs to receive
     428             :                          * all multicast IGMP packets, whether or not this
     429             :                          * host belongs to their destination groups.
     430             :                          */
     431           0 :                         if (ip->ip_p == IPPROTO_IGMP) {
     432           0 :                                 nxt = ip_ours(mp, offp, nxt, af);
     433           0 :                                 goto out;
     434             :                         }
     435           0 :                         ipstat_inc(ips_forward);
     436           0 :                 }
     437             : #endif
     438             :                 /*
     439             :                  * See if we belong to the destination multicast group on the
     440             :                  * arrival interface.
     441             :                  */
     442           0 :                 if (!in_hasmulti(&ip->ip_dst, ifp)) {
     443           0 :                         ipstat_inc(ips_notmember);
     444           0 :                         if (!IN_LOCAL_GROUP(ip->ip_dst.s_addr))
     445           0 :                                 ipstat_inc(ips_cantforward);
     446             :                         goto bad;
     447             :                 }
     448           0 :                 nxt = ip_ours(mp, offp, nxt, af);
     449           0 :                 goto out;
     450             :         }
     451             : 
     452             : #if NCARP > 0
     453           0 :         if (ip->ip_p == IPPROTO_ICMP &&
     454           0 :             carp_lsdrop(ifp, m, AF_INET, &ip->ip_src.s_addr,
     455             :             &ip->ip_dst.s_addr, 1))
     456             :                 goto bad;
     457             : #endif
     458             :         /*
     459             :          * Not for us; forward if possible and desirable.
     460             :          */
     461           0 :         if (ipforwarding == 0) {
     462           0 :                 ipstat_inc(ips_cantforward);
     463           0 :                 goto bad;
     464             :         }
     465             : #ifdef IPSEC
     466           0 :         if (ipsec_in_use) {
     467             :                 int rv;
     468             : 
     469           0 :                 rv = ipsec_forward_check(m, hlen, AF_INET);
     470           0 :                 if (rv != 0) {
     471           0 :                         ipstat_inc(ips_cantforward);
     472           0 :                         goto bad;
     473             :                 }
     474             :                 /*
     475             :                  * Fall through, forward packet. Outbound IPsec policy
     476             :                  * checking will occur in ip_output().
     477             :                  */
     478           0 :         }
     479             : #endif /* IPSEC */
     480             : 
     481           0 :         ip_forward(m, ifp, rt, pfrdr);
     482           0 :         *mp = NULL;
     483           0 :         return IPPROTO_DONE;
     484             :  bad:
     485             :         nxt = IPPROTO_DONE;
     486           0 :         m_freemp(mp);
     487             :  out:
     488           0 :         rtfree(rt);
     489           0 :         return nxt;
     490           0 : }
     491             : 
     492             : /*
     493             :  * IPv4 local-delivery routine.
     494             :  *
     495             :  * If fragmented try to reassemble.  Pass to next level.
     496             :  */
     497             : int
     498           0 : ip_local(struct mbuf **mp, int *offp, int nxt, int af)
     499             : {
     500           0 :         struct mbuf *m = *mp;
     501           0 :         struct ip *ip = mtod(m, struct ip *);
     502             :         struct ipq *fp;
     503             :         struct ipqent *ipqe;
     504             :         int mff, hlen;
     505             : 
     506           0 :         hlen = ip->ip_hl << 2;
     507             : 
     508             :         /*
     509             :          * If offset or IP_MF are set, must reassemble.
     510             :          * Otherwise, nothing need be done.
     511             :          * (We could look in the reassembly queue to see
     512             :          * if the packet was previously fragmented,
     513             :          * but it's not worth the time; just let them time out.)
     514             :          */
     515           0 :         if (ip->ip_off &~ htons(IP_DF | IP_RF)) {
     516           0 :                 if (m->m_flags & M_EXT) {                /* XXX */
     517           0 :                         if ((m = *mp = m_pullup(m, hlen)) == NULL) {
     518           0 :                                 ipstat_inc(ips_toosmall);
     519           0 :                                 return IPPROTO_DONE;
     520             :                         }
     521           0 :                         ip = mtod(m, struct ip *);
     522           0 :                 }
     523             : 
     524           0 :                 mtx_enter(&ipq_mutex);
     525             : 
     526             :                 /*
     527             :                  * Look for queue of fragments
     528             :                  * of this datagram.
     529             :                  */
     530           0 :                 LIST_FOREACH(fp, &ipq, ipq_q) {
     531           0 :                         if (ip->ip_id == fp->ipq_id &&
     532           0 :                             ip->ip_src.s_addr == fp->ipq_src.s_addr &&
     533           0 :                             ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
     534           0 :                             ip->ip_p == fp->ipq_p)
     535             :                                 break;
     536             :                 }
     537             : 
     538             :                 /*
     539             :                  * Adjust ip_len to not reflect header,
     540             :                  * set ipqe_mff if more fragments are expected,
     541             :                  * convert offset of this to bytes.
     542             :                  */
     543           0 :                 ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
     544           0 :                 mff = (ip->ip_off & htons(IP_MF)) != 0;
     545           0 :                 if (mff) {
     546             :                         /*
     547             :                          * Make sure that fragments have a data length
     548             :                          * that's a non-zero multiple of 8 bytes.
     549             :                          */
     550           0 :                         if (ntohs(ip->ip_len) == 0 ||
     551           0 :                             (ntohs(ip->ip_len) & 0x7) != 0) {
     552           0 :                                 ipstat_inc(ips_badfrags);
     553           0 :                                 goto bad;
     554             :                         }
     555             :                 }
     556           0 :                 ip->ip_off = htons(ntohs(ip->ip_off) << 3);
     557             : 
     558             :                 /*
     559             :                  * If datagram marked as having more fragments
     560             :                  * or if this is not the first fragment,
     561             :                  * attempt reassembly; if it succeeds, proceed.
     562             :                  */
     563           0 :                 if (mff || ip->ip_off) {
     564           0 :                         ipstat_inc(ips_fragments);
     565           0 :                         if (ip_frags + 1 > ip_maxqueue) {
     566           0 :                                 ip_flush();
     567           0 :                                 ipstat_inc(ips_rcvmemdrop);
     568           0 :                                 goto bad;
     569             :                         }
     570             : 
     571           0 :                         ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
     572           0 :                         if (ipqe == NULL) {
     573           0 :                                 ipstat_inc(ips_rcvmemdrop);
     574           0 :                                 goto bad;
     575             :                         }
     576           0 :                         ip_frags++;
     577           0 :                         ipqe->ipqe_mff = mff;
     578           0 :                         ipqe->ipqe_m = m;
     579           0 :                         ipqe->ipqe_ip = ip;
     580           0 :                         m = *mp = ip_reass(ipqe, fp);
     581           0 :                         if (m == NULL)
     582             :                                 goto bad;
     583           0 :                         ipstat_inc(ips_reassembled);
     584           0 :                         ip = mtod(m, struct ip *);
     585           0 :                         hlen = ip->ip_hl << 2;
     586           0 :                         ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
     587           0 :                 } else
     588           0 :                         if (fp)
     589           0 :                                 ip_freef(fp);
     590             : 
     591           0 :                 mtx_leave(&ipq_mutex);
     592           0 :         }
     593             : 
     594           0 :         *offp = hlen;
     595           0 :         nxt = ip->ip_p;
     596             :         /* Check wheter we are already in a IPv4/IPv6 local deliver loop. */
     597           0 :         if (af == AF_UNSPEC)
     598           0 :                 nxt = ip_deliver(mp, offp, nxt, AF_INET);
     599           0 :         return nxt;
     600             :  bad:
     601           0 :         mtx_leave(&ipq_mutex);
     602           0 :         m_freemp(mp);
     603           0 :         return IPPROTO_DONE;
     604           0 : }
     605             : 
     606             : #ifndef INET6
     607             : #define IPSTAT_INC(name)        ipstat_inc(ips_##name)
     608             : #else
     609             : #define IPSTAT_INC(name)        (af == AF_INET ?        \
     610             :     ipstat_inc(ips_##name) : ip6stat_inc(ip6s_##name))
     611             : #endif
     612             : 
     613             : int
     614           0 : ip_deliver(struct mbuf **mp, int *offp, int nxt, int af)
     615             : {
     616             :         const struct protosw *psw;
     617             :         int naf = af;
     618             : #ifdef INET6
     619             :         int nest = 0;
     620             : #endif /* INET6 */
     621             : 
     622             :         /* pf might have modified stuff, might have to chksum */
     623           0 :         switch (af) {
     624             :         case AF_INET:
     625           0 :                 in_proto_cksum_out(*mp, NULL);
     626           0 :                 break;
     627             : #ifdef INET6
     628             :         case AF_INET6:
     629           0 :                 in6_proto_cksum_out(*mp, NULL);
     630           0 :                 break;
     631             : #endif /* INET6 */
     632             :         }
     633             : 
     634             :         /*
     635             :          * Tell launch routine the next header
     636             :          */
     637           0 :         IPSTAT_INC(delivered);
     638             : 
     639           0 :         while (nxt != IPPROTO_DONE) {
     640             : #ifdef INET6
     641           0 :                 if (af == AF_INET6 &&
     642           0 :                     ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
     643           0 :                         ip6stat_inc(ip6s_toomanyhdr);
     644           0 :                         goto bad;
     645             :                 }
     646             : #endif /* INET6 */
     647             : 
     648             :                 /*
     649             :                  * protection against faulty packet - there should be
     650             :                  * more sanity checks in header chain processing.
     651             :                  */
     652           0 :                 if ((*mp)->m_pkthdr.len < *offp) {
     653           0 :                         IPSTAT_INC(tooshort);
     654             :                         goto bad;
     655             :                 }
     656             : 
     657             : #ifdef INET6
     658             :                 /* draft-itojun-ipv6-tcp-to-anycast */
     659           0 :                 if (af == AF_INET6 &&
     660           0 :                     ISSET((*mp)->m_flags, M_ACAST) && (nxt == IPPROTO_TCP)) {
     661           0 :                         if ((*mp)->m_len >= sizeof(struct ip6_hdr)) {
     662           0 :                                 icmp6_error(*mp, ICMP6_DST_UNREACH,
     663             :                                         ICMP6_DST_UNREACH_ADDR,
     664             :                                         offsetof(struct ip6_hdr, ip6_dst));
     665           0 :                                 *mp = NULL;
     666           0 :                         }
     667             :                         goto bad;
     668             :                 }
     669             : #endif /* INET6 */
     670             : 
     671             : #ifdef IPSEC
     672           0 :                 if (ipsec_in_use) {
     673           0 :                         if (ipsec_local_check(*mp, *offp, nxt, af) != 0) {
     674           0 :                                 IPSTAT_INC(cantforward);
     675             :                                 goto bad;
     676             :                         }
     677             :                 }
     678             :                 /* Otherwise, just fall through and deliver the packet */
     679             : #endif /* IPSEC */
     680             : 
     681           0 :                 switch (nxt) {
     682             :                 case IPPROTO_IPV4:
     683             :                         naf = AF_INET;
     684           0 :                         ipstat_inc(ips_delivered);
     685           0 :                         break;
     686             : #ifdef INET6
     687             :                 case IPPROTO_IPV6:
     688             :                         naf = AF_INET6;
     689           0 :                         ip6stat_inc(ip6s_delivered);
     690           0 :                         break;
     691             : #endif /* INET6 */
     692             :                 }
     693           0 :                 switch (af) {
     694             :                 case AF_INET:
     695           0 :                         psw = &inetsw[ip_protox[nxt]];
     696           0 :                         break;
     697             : #ifdef INET6
     698             :                 case AF_INET6:
     699           0 :                         psw = &inet6sw[ip6_protox[nxt]];
     700           0 :                         break;
     701             : #endif /* INET6 */
     702             :                 }
     703           0 :                 nxt = (*psw->pr_input)(mp, offp, nxt, af);
     704             :                 af = naf;
     705             :         }
     706           0 :         return nxt;
     707             :  bad:
     708           0 :         m_freemp(mp);
     709           0 :         return IPPROTO_DONE;
     710           0 : }
     711             : #undef IPSTAT_INC
     712             : 
     713             : int
     714           0 : in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
     715             : {
     716             :         struct rtentry          *rt;
     717             :         struct ip               *ip;
     718           0 :         struct sockaddr_in       sin;
     719             :         int                      match = 0;
     720             : 
     721             : #if NPF > 0
     722           0 :         switch (pf_ouraddr(m)) {
     723             :         case 0:
     724           0 :                 return (0);
     725             :         case 1:
     726           0 :                 return (1);
     727             :         default:
     728             :                 /* pf does not know it */
     729             :                 break;
     730             :         }
     731             : #endif
     732             : 
     733           0 :         ip = mtod(m, struct ip *);
     734             : 
     735           0 :         memset(&sin, 0, sizeof(sin));
     736           0 :         sin.sin_len = sizeof(sin);
     737           0 :         sin.sin_family = AF_INET;
     738           0 :         sin.sin_addr = ip->ip_dst;
     739           0 :         rt = rtalloc_mpath(sintosa(&sin), &ip->ip_src.s_addr,
     740           0 :             m->m_pkthdr.ph_rtableid);
     741           0 :         if (rtisvalid(rt)) {
     742           0 :                 if (ISSET(rt->rt_flags, RTF_LOCAL))
     743           0 :                         match = 1;
     744             : 
     745             :                 /*
     746             :                  * If directedbcast is enabled we only consider it local
     747             :                  * if it is received on the interface with that address.
     748             :                  */
     749           0 :                 if (ISSET(rt->rt_flags, RTF_BROADCAST) &&
     750           0 :                     (!ip_directedbcast || rt->rt_ifidx == ifp->if_index)) {
     751             :                         match = 1;
     752             : 
     753             :                         /* Make sure M_BCAST is set */
     754           0 :                         m->m_flags |= M_BCAST;
     755           0 :                 }
     756             :         }
     757           0 :         *prt = rt;
     758             : 
     759           0 :         if (!match) {
     760             :                 struct ifaddr *ifa;
     761             : 
     762             :                 /*
     763             :                  * No local address or broadcast address found, so check for
     764             :                  * ancient classful broadcast addresses.
     765             :                  * It must have been broadcast on the link layer, and for an
     766             :                  * address on the interface it was received on.
     767             :                  */
     768           0 :                 if (!ISSET(m->m_flags, M_BCAST) ||
     769           0 :                     !IN_CLASSFULBROADCAST(ip->ip_dst.s_addr, ip->ip_dst.s_addr))
     770           0 :                         return (0);
     771             : 
     772           0 :                 if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid))
     773           0 :                         return (0);
     774             :                 /*
     775             :                  * The check in the loop assumes you only rx a packet on an UP
     776             :                  * interface, and that M_BCAST will only be set on a BROADCAST
     777             :                  * interface.
     778             :                  */
     779           0 :                 NET_ASSERT_LOCKED();
     780           0 :                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
     781           0 :                         if (ifa->ifa_addr->sa_family != AF_INET)
     782             :                                 continue;
     783             : 
     784           0 :                         if (IN_CLASSFULBROADCAST(ip->ip_dst.s_addr,
     785             :                             ifatoia(ifa)->ia_addr.sin_addr.s_addr)) {
     786             :                                 match = 1;
     787           0 :                                 break;
     788             :                         }
     789             :                 }
     790           0 :         }
     791             : 
     792           0 :         return (match);
     793           0 : }
     794             : 
     795             : /*
     796             :  * Take incoming datagram fragment and try to
     797             :  * reassemble it into whole datagram.  If a chain for
     798             :  * reassembly of this datagram already exists, then it
     799             :  * is given as fp; otherwise have to make a chain.
     800             :  */
     801             : struct mbuf *
     802           0 : ip_reass(struct ipqent *ipqe, struct ipq *fp)
     803             : {
     804           0 :         struct mbuf *m = ipqe->ipqe_m;
     805             :         struct ipqent *nq, *p, *q;
     806             :         struct ip *ip;
     807             :         struct mbuf *t;
     808           0 :         int hlen = ipqe->ipqe_ip->ip_hl << 2;
     809             :         int i, next;
     810             :         u_int8_t ecn, ecn0;
     811             : 
     812           0 :         MUTEX_ASSERT_LOCKED(&ipq_mutex);
     813             : 
     814             :         /*
     815             :          * Presence of header sizes in mbufs
     816             :          * would confuse code below.
     817             :          */
     818           0 :         m->m_data += hlen;
     819           0 :         m->m_len -= hlen;
     820             : 
     821             :         /*
     822             :          * If first fragment to arrive, create a reassembly queue.
     823             :          */
     824           0 :         if (fp == NULL) {
     825           0 :                 fp = pool_get(&ipq_pool, PR_NOWAIT);
     826           0 :                 if (fp == NULL)
     827             :                         goto dropfrag;
     828           0 :                 LIST_INSERT_HEAD(&ipq, fp, ipq_q);
     829           0 :                 fp->ipq_ttl = IPFRAGTTL;
     830           0 :                 fp->ipq_p = ipqe->ipqe_ip->ip_p;
     831           0 :                 fp->ipq_id = ipqe->ipqe_ip->ip_id;
     832           0 :                 LIST_INIT(&fp->ipq_fragq);
     833           0 :                 fp->ipq_src = ipqe->ipqe_ip->ip_src;
     834           0 :                 fp->ipq_dst = ipqe->ipqe_ip->ip_dst;
     835             :                 p = NULL;
     836           0 :                 goto insert;
     837             :         }
     838             : 
     839             :         /*
     840             :          * Handle ECN by comparing this segment with the first one;
     841             :          * if CE is set, do not lose CE.
     842             :          * drop if CE and not-ECT are mixed for the same packet.
     843             :          */
     844           0 :         ecn = ipqe->ipqe_ip->ip_tos & IPTOS_ECN_MASK;
     845           0 :         ecn0 = LIST_FIRST(&fp->ipq_fragq)->ipqe_ip->ip_tos & IPTOS_ECN_MASK;
     846           0 :         if (ecn == IPTOS_ECN_CE) {
     847           0 :                 if (ecn0 == IPTOS_ECN_NOTECT)
     848             :                         goto dropfrag;
     849           0 :                 if (ecn0 != IPTOS_ECN_CE)
     850           0 :                         LIST_FIRST(&fp->ipq_fragq)->ipqe_ip->ip_tos |=
     851             :                             IPTOS_ECN_CE;
     852             :         }
     853           0 :         if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT)
     854             :                 goto dropfrag;
     855             : 
     856             :         /*
     857             :          * Find a segment which begins after this one does.
     858             :          */
     859           0 :         for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq); q != NULL;
     860           0 :             p = q, q = LIST_NEXT(q, ipqe_q))
     861           0 :                 if (ntohs(q->ipqe_ip->ip_off) > ntohs(ipqe->ipqe_ip->ip_off))
     862             :                         break;
     863             : 
     864             :         /*
     865             :          * If there is a preceding segment, it may provide some of
     866             :          * our data already.  If so, drop the data from the incoming
     867             :          * segment.  If it provides all of our data, drop us.
     868             :          */
     869           0 :         if (p != NULL) {
     870           0 :                 i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) -
     871           0 :                     ntohs(ipqe->ipqe_ip->ip_off);
     872           0 :                 if (i > 0) {
     873           0 :                         if (i >= ntohs(ipqe->ipqe_ip->ip_len))
     874             :                                 goto dropfrag;
     875           0 :                         m_adj(ipqe->ipqe_m, i);
     876           0 :                         ipqe->ipqe_ip->ip_off =
     877           0 :                             htons(ntohs(ipqe->ipqe_ip->ip_off) + i);
     878           0 :                         ipqe->ipqe_ip->ip_len =
     879           0 :                             htons(ntohs(ipqe->ipqe_ip->ip_len) - i);
     880           0 :                 }
     881             :         }
     882             : 
     883             :         /*
     884             :          * While we overlap succeeding segments trim them or,
     885             :          * if they are completely covered, dequeue them.
     886             :          */
     887           0 :         for (; q != NULL &&
     888           0 :             ntohs(ipqe->ipqe_ip->ip_off) + ntohs(ipqe->ipqe_ip->ip_len) >
     889           0 :             ntohs(q->ipqe_ip->ip_off); q = nq) {
     890             :                 i = (ntohs(ipqe->ipqe_ip->ip_off) +
     891           0 :                     ntohs(ipqe->ipqe_ip->ip_len)) - ntohs(q->ipqe_ip->ip_off);
     892           0 :                 if (i < ntohs(q->ipqe_ip->ip_len)) {
     893           0 :                         q->ipqe_ip->ip_len =
     894           0 :                             htons(ntohs(q->ipqe_ip->ip_len) - i);
     895           0 :                         q->ipqe_ip->ip_off =
     896           0 :                             htons(ntohs(q->ipqe_ip->ip_off) + i);
     897           0 :                         m_adj(q->ipqe_m, i);
     898           0 :                         break;
     899             :                 }
     900           0 :                 nq = LIST_NEXT(q, ipqe_q);
     901           0 :                 m_freem(q->ipqe_m);
     902           0 :                 LIST_REMOVE(q, ipqe_q);
     903           0 :                 pool_put(&ipqent_pool, q);
     904           0 :                 ip_frags--;
     905             :         }
     906             : 
     907             : insert:
     908             :         /*
     909             :          * Stick new segment in its place;
     910             :          * check for complete reassembly.
     911             :          */
     912           0 :         if (p == NULL) {
     913           0 :                 LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q);
     914           0 :         } else {
     915           0 :                 LIST_INSERT_AFTER(p, ipqe, ipqe_q);
     916             :         }
     917             :         next = 0;
     918           0 :         for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq); q != NULL;
     919           0 :             p = q, q = LIST_NEXT(q, ipqe_q)) {
     920           0 :                 if (ntohs(q->ipqe_ip->ip_off) != next)
     921           0 :                         return (0);
     922           0 :                 next += ntohs(q->ipqe_ip->ip_len);
     923             :         }
     924           0 :         if (p->ipqe_mff)
     925           0 :                 return (0);
     926             : 
     927             :         /*
     928             :          * Reassembly is complete.  Check for a bogus message size and
     929             :          * concatenate fragments.
     930             :          */
     931           0 :         q = LIST_FIRST(&fp->ipq_fragq);
     932           0 :         ip = q->ipqe_ip;
     933           0 :         if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
     934           0 :                 ipstat_inc(ips_toolong);
     935           0 :                 ip_freef(fp);
     936           0 :                 return (0);
     937             :         }
     938           0 :         m = q->ipqe_m;
     939           0 :         t = m->m_next;
     940           0 :         m->m_next = 0;
     941           0 :         m_cat(m, t);
     942           0 :         nq = LIST_NEXT(q, ipqe_q);
     943           0 :         pool_put(&ipqent_pool, q);
     944           0 :         ip_frags--;
     945           0 :         for (q = nq; q != NULL; q = nq) {
     946           0 :                 t = q->ipqe_m;
     947           0 :                 nq = LIST_NEXT(q, ipqe_q);
     948           0 :                 pool_put(&ipqent_pool, q);
     949           0 :                 ip_frags--;
     950           0 :                 m_removehdr(t);
     951           0 :                 m_cat(m, t);
     952             :         }
     953             : 
     954             :         /*
     955             :          * Create header for new ip packet by
     956             :          * modifying header of first packet;
     957             :          * dequeue and discard fragment reassembly header.
     958             :          * Make header visible.
     959             :          */
     960           0 :         ip->ip_len = htons(next);
     961           0 :         ip->ip_src = fp->ipq_src;
     962           0 :         ip->ip_dst = fp->ipq_dst;
     963           0 :         LIST_REMOVE(fp, ipq_q);
     964           0 :         pool_put(&ipq_pool, fp);
     965           0 :         m->m_len += (ip->ip_hl << 2);
     966           0 :         m->m_data -= (ip->ip_hl << 2);
     967           0 :         m_calchdrlen(m);
     968           0 :         return (m);
     969             : 
     970             : dropfrag:
     971           0 :         ipstat_inc(ips_fragdropped);
     972           0 :         m_freem(m);
     973           0 :         pool_put(&ipqent_pool, ipqe);
     974           0 :         ip_frags--;
     975           0 :         return (NULL);
     976           0 : }
     977             : 
     978             : /*
     979             :  * Free a fragment reassembly header and all
     980             :  * associated datagrams.
     981             :  */
     982             : void
     983           0 : ip_freef(struct ipq *fp)
     984             : {
     985             :         struct ipqent *q;
     986             : 
     987           0 :         MUTEX_ASSERT_LOCKED(&ipq_mutex);
     988             : 
     989           0 :         while ((q = LIST_FIRST(&fp->ipq_fragq)) != NULL) {
     990           0 :                 LIST_REMOVE(q, ipqe_q);
     991           0 :                 m_freem(q->ipqe_m);
     992           0 :                 pool_put(&ipqent_pool, q);
     993           0 :                 ip_frags--;
     994             :         }
     995           0 :         LIST_REMOVE(fp, ipq_q);
     996           0 :         pool_put(&ipq_pool, fp);
     997           0 : }
     998             : 
     999             : /*
    1000             :  * IP timer processing;
    1001             :  * if a timer expires on a reassembly queue, discard it.
    1002             :  */
    1003             : void
    1004           0 : ip_slowtimo(void)
    1005             : {
    1006             :         struct ipq *fp, *nfp;
    1007             : 
    1008           0 :         mtx_enter(&ipq_mutex);
    1009           0 :         LIST_FOREACH_SAFE(fp, &ipq, ipq_q, nfp) {
    1010           0 :                 if (--fp->ipq_ttl == 0) {
    1011           0 :                         ipstat_inc(ips_fragtimeout);
    1012           0 :                         ip_freef(fp);
    1013           0 :                 }
    1014             :         }
    1015           0 :         mtx_leave(&ipq_mutex);
    1016           0 : }
    1017             : 
    1018             : /*
    1019             :  * Flush a bunch of datagram fragments, till we are down to 75%.
    1020             :  */
    1021             : void
    1022           0 : ip_flush(void)
    1023             : {
    1024             :         int max = 50;
    1025             : 
    1026           0 :         MUTEX_ASSERT_LOCKED(&ipq_mutex);
    1027             : 
    1028           0 :         while (!LIST_EMPTY(&ipq) && ip_frags > ip_maxqueue * 3 / 4 && --max) {
    1029           0 :                 ipstat_inc(ips_fragdropped);
    1030           0 :                 ip_freef(LIST_FIRST(&ipq));
    1031             :         }
    1032           0 : }
    1033             : 
    1034             : /*
    1035             :  * Do option processing on a datagram,
    1036             :  * possibly discarding it if bad options are encountered,
    1037             :  * or forwarding it if source-routed.
    1038             :  * Returns 1 if packet has been forwarded/freed,
    1039             :  * 0 if the packet should be processed further.
    1040             :  */
    1041             : int
    1042           0 : ip_dooptions(struct mbuf *m, struct ifnet *ifp)
    1043             : {
    1044           0 :         struct ip *ip = mtod(m, struct ip *);
    1045           0 :         unsigned int rtableid = m->m_pkthdr.ph_rtableid;
    1046             :         struct rtentry *rt;
    1047           0 :         struct sockaddr_in ipaddr;
    1048             :         u_char *cp;
    1049           0 :         struct ip_timestamp ipt;
    1050             :         struct in_ifaddr *ia;
    1051             :         int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;
    1052             :         struct in_addr sin, dst;
    1053             :         u_int32_t ntime;
    1054             : 
    1055           0 :         dst = ip->ip_dst;
    1056           0 :         cp = (u_char *)(ip + 1);
    1057           0 :         cnt = (ip->ip_hl << 2) - sizeof (struct ip);
    1058             : 
    1059           0 :         KERNEL_LOCK();
    1060           0 :         for (; cnt > 0; cnt -= optlen, cp += optlen) {
    1061           0 :                 opt = cp[IPOPT_OPTVAL];
    1062           0 :                 if (opt == IPOPT_EOL)
    1063             :                         break;
    1064           0 :                 if (opt == IPOPT_NOP)
    1065           0 :                         optlen = 1;
    1066             :                 else {
    1067           0 :                         if (cnt < IPOPT_OLEN + sizeof(*cp)) {
    1068           0 :                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
    1069           0 :                                 goto bad;
    1070             :                         }
    1071           0 :                         optlen = cp[IPOPT_OLEN];
    1072           0 :                         if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) {
    1073           0 :                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
    1074           0 :                                 goto bad;
    1075             :                         }
    1076             :                 }
    1077             : 
    1078           0 :                 switch (opt) {
    1079             : 
    1080             :                 default:
    1081             :                         break;
    1082             : 
    1083             :                 /*
    1084             :                  * Source routing with record.
    1085             :                  * Find interface with current destination address.
    1086             :                  * If none on this machine then drop if strictly routed,
    1087             :                  * or do nothing if loosely routed.
    1088             :                  * Record interface address and bring up next address
    1089             :                  * component.  If strictly routed make sure next
    1090             :                  * address is on directly accessible net.
    1091             :                  */
    1092             :                 case IPOPT_LSRR:
    1093             :                 case IPOPT_SSRR:
    1094           0 :                         if (!ip_dosourceroute) {
    1095             :                                 type = ICMP_UNREACH;
    1096             :                                 code = ICMP_UNREACH_SRCFAIL;
    1097           0 :                                 goto bad;
    1098             :                         }
    1099           0 :                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
    1100           0 :                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
    1101           0 :                                 goto bad;
    1102             :                         }
    1103           0 :                         memset(&ipaddr, 0, sizeof(ipaddr));
    1104           0 :                         ipaddr.sin_family = AF_INET;
    1105           0 :                         ipaddr.sin_len = sizeof(ipaddr);
    1106           0 :                         ipaddr.sin_addr = ip->ip_dst;
    1107           0 :                         ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr),
    1108           0 :                             m->m_pkthdr.ph_rtableid));
    1109           0 :                         if (ia == NULL) {
    1110           0 :                                 if (opt == IPOPT_SSRR) {
    1111             :                                         type = ICMP_UNREACH;
    1112             :                                         code = ICMP_UNREACH_SRCFAIL;
    1113           0 :                                         goto bad;
    1114             :                                 }
    1115             :                                 /*
    1116             :                                  * Loose routing, and not at next destination
    1117             :                                  * yet; nothing to do except forward.
    1118             :                                  */
    1119             :                                 break;
    1120             :                         }
    1121           0 :                         off--;                  /* 0 origin */
    1122           0 :                         if ((off + sizeof(struct in_addr)) > optlen) {
    1123             :                                 /*
    1124             :                                  * End of source route.  Should be for us.
    1125             :                                  */
    1126           0 :                                 save_rte(m, cp, ip->ip_src);
    1127           0 :                                 break;
    1128             :                         }
    1129             : 
    1130             :                         /*
    1131             :                          * locate outgoing interface
    1132             :                          */
    1133           0 :                         memset(&ipaddr, 0, sizeof(ipaddr));
    1134           0 :                         ipaddr.sin_family = AF_INET;
    1135           0 :                         ipaddr.sin_len = sizeof(ipaddr);
    1136           0 :                         memcpy(&ipaddr.sin_addr, cp + off,
    1137             :                             sizeof(ipaddr.sin_addr));
    1138             :                         /* keep packet in the virtual instance */
    1139           0 :                         rt = rtalloc(sintosa(&ipaddr), RT_RESOLVE, rtableid);
    1140           0 :                         if (!rtisvalid(rt) || ((opt == IPOPT_SSRR) &&
    1141           0 :                             ISSET(rt->rt_flags, RTF_GATEWAY))) {
    1142             :                                 type = ICMP_UNREACH;
    1143             :                                 code = ICMP_UNREACH_SRCFAIL;
    1144           0 :                                 rtfree(rt);
    1145           0 :                                 goto bad;
    1146             :                         }
    1147           0 :                         ia = ifatoia(rt->rt_ifa);
    1148           0 :                         memcpy(cp + off, &ia->ia_addr.sin_addr,
    1149             :                             sizeof(struct in_addr));
    1150           0 :                         rtfree(rt);
    1151           0 :                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);
    1152           0 :                         ip->ip_dst = ipaddr.sin_addr;
    1153             :                         /*
    1154             :                          * Let ip_intr's mcast routing check handle mcast pkts
    1155             :                          */
    1156           0 :                         forward = !IN_MULTICAST(ip->ip_dst.s_addr);
    1157           0 :                         break;
    1158             : 
    1159             :                 case IPOPT_RR:
    1160           0 :                         if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
    1161           0 :                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
    1162           0 :                                 goto bad;
    1163             :                         }
    1164           0 :                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
    1165           0 :                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
    1166           0 :                                 goto bad;
    1167             :                         }
    1168             : 
    1169             :                         /*
    1170             :                          * If no space remains, ignore.
    1171             :                          */
    1172           0 :                         off--;                  /* 0 origin */
    1173           0 :                         if ((off + sizeof(struct in_addr)) > optlen)
    1174             :                                 break;
    1175           0 :                         memset(&ipaddr, 0, sizeof(ipaddr));
    1176           0 :                         ipaddr.sin_family = AF_INET;
    1177           0 :                         ipaddr.sin_len = sizeof(ipaddr);
    1178           0 :                         ipaddr.sin_addr = ip->ip_dst;
    1179             :                         /*
    1180             :                          * locate outgoing interface; if we're the destination,
    1181             :                          * use the incoming interface (should be same).
    1182             :                          * Again keep the packet inside the virtual instance.
    1183             :                          */
    1184           0 :                         rt = rtalloc(sintosa(&ipaddr), RT_RESOLVE, rtableid);
    1185           0 :                         if (!rtisvalid(rt)) {
    1186             :                                 type = ICMP_UNREACH;
    1187             :                                 code = ICMP_UNREACH_HOST;
    1188           0 :                                 rtfree(rt);
    1189           0 :                                 goto bad;
    1190             :                         }
    1191           0 :                         ia = ifatoia(rt->rt_ifa);
    1192           0 :                         memcpy(cp + off, &ia->ia_addr.sin_addr,
    1193             :                             sizeof(struct in_addr));
    1194           0 :                         rtfree(rt);
    1195           0 :                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);
    1196           0 :                         break;
    1197             : 
    1198             :                 case IPOPT_TS:
    1199           0 :                         code = cp - (u_char *)ip;
    1200           0 :                         if (optlen < sizeof(struct ip_timestamp))
    1201             :                                 goto bad;
    1202           0 :                         memcpy(&ipt, cp, sizeof(struct ip_timestamp));
    1203           0 :                         if (ipt.ipt_ptr < 5 || ipt.ipt_len < 5)
    1204             :                                 goto bad;
    1205           0 :                         if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) > ipt.ipt_len) {
    1206           0 :                                 if (++ipt.ipt_oflw == 0)
    1207             :                                         goto bad;
    1208             :                                 break;
    1209             :                         }
    1210           0 :                         memcpy(&sin, cp + ipt.ipt_ptr - 1, sizeof sin);
    1211           0 :                         switch (ipt.ipt_flg) {
    1212             : 
    1213             :                         case IPOPT_TS_TSONLY:
    1214             :                                 break;
    1215             : 
    1216             :                         case IPOPT_TS_TSANDADDR:
    1217           0 :                                 if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) +
    1218           0 :                                     sizeof(struct in_addr) > ipt.ipt_len)
    1219             :                                         goto bad;
    1220           0 :                                 memset(&ipaddr, 0, sizeof(ipaddr));
    1221           0 :                                 ipaddr.sin_family = AF_INET;
    1222           0 :                                 ipaddr.sin_len = sizeof(ipaddr);
    1223           0 :                                 ipaddr.sin_addr = dst;
    1224           0 :                                 ia = ifatoia(ifaof_ifpforaddr(sintosa(&ipaddr),
    1225             :                                     ifp));
    1226           0 :                                 if (ia == NULL)
    1227             :                                         continue;
    1228           0 :                                 memcpy(&sin, &ia->ia_addr.sin_addr,
    1229             :                                     sizeof(struct in_addr));
    1230           0 :                                 ipt.ipt_ptr += sizeof(struct in_addr);
    1231           0 :                                 break;
    1232             : 
    1233             :                         case IPOPT_TS_PRESPEC:
    1234           0 :                                 if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) +
    1235           0 :                                     sizeof(struct in_addr) > ipt.ipt_len)
    1236             :                                         goto bad;
    1237           0 :                                 memset(&ipaddr, 0, sizeof(ipaddr));
    1238           0 :                                 ipaddr.sin_family = AF_INET;
    1239           0 :                                 ipaddr.sin_len = sizeof(ipaddr);
    1240           0 :                                 ipaddr.sin_addr = sin;
    1241           0 :                                 if (ifa_ifwithaddr(sintosa(&ipaddr),
    1242           0 :                                     m->m_pkthdr.ph_rtableid) == NULL)
    1243             :                                         continue;
    1244           0 :                                 ipt.ipt_ptr += sizeof(struct in_addr);
    1245           0 :                                 break;
    1246             : 
    1247             :                         default:
    1248             :                                 /* XXX can't take &ipt->ipt_flg */
    1249           0 :                                 code = (u_char *)&ipt.ipt_ptr -
    1250           0 :                                     (u_char *)ip + 1;
    1251           0 :                                 goto bad;
    1252             :                         }
    1253           0 :                         ntime = iptime();
    1254           0 :                         memcpy(cp + ipt.ipt_ptr - 1, &ntime, sizeof(u_int32_t));
    1255           0 :                         ipt.ipt_ptr += sizeof(u_int32_t);
    1256           0 :                 }
    1257             :         }
    1258           0 :         KERNEL_UNLOCK();
    1259           0 :         if (forward && ipforwarding) {
    1260           0 :                 ip_forward(m, ifp, NULL, 1);
    1261           0 :                 return (1);
    1262             :         }
    1263           0 :         return (0);
    1264             : bad:
    1265           0 :         KERNEL_UNLOCK();
    1266           0 :         icmp_error(m, type, code, 0, 0);
    1267           0 :         ipstat_inc(ips_badoptions);
    1268           0 :         return (1);
    1269           0 : }
    1270             : 
    1271             : /*
    1272             :  * Save incoming source route for use in replies,
    1273             :  * to be picked up later by ip_srcroute if the receiver is interested.
    1274             :  */
    1275             : void
    1276           0 : save_rte(struct mbuf *m, u_char *option, struct in_addr dst)
    1277             : {
    1278             :         struct ip_srcrt *isr;
    1279             :         struct m_tag *mtag;
    1280             :         unsigned olen;
    1281             : 
    1282           0 :         olen = option[IPOPT_OLEN];
    1283           0 :         if (olen > sizeof(isr->isr_hdr) + sizeof(isr->isr_routes))
    1284           0 :                 return;
    1285             : 
    1286           0 :         mtag = m_tag_get(PACKET_TAG_SRCROUTE, sizeof(*isr), M_NOWAIT);
    1287           0 :         if (mtag == NULL)
    1288           0 :                 return;
    1289           0 :         isr = (struct ip_srcrt *)(mtag + 1);
    1290             : 
    1291           0 :         memcpy(isr->isr_hdr, option, olen);
    1292           0 :         isr->isr_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);
    1293           0 :         isr->isr_dst = dst;
    1294           0 :         m_tag_prepend(m, mtag);
    1295           0 : }
    1296             : 
    1297             : /*
    1298             :  * Retrieve incoming source route for use in replies,
    1299             :  * in the same form used by setsockopt.
    1300             :  * The first hop is placed before the options, will be removed later.
    1301             :  */
    1302             : struct mbuf *
    1303           0 : ip_srcroute(struct mbuf *m0)
    1304             : {
    1305             :         struct in_addr *p, *q;
    1306             :         struct mbuf *m;
    1307             :         struct ip_srcrt *isr;
    1308             :         struct m_tag *mtag;
    1309             : 
    1310           0 :         if (!ip_dosourceroute)
    1311           0 :                 return (NULL);
    1312             : 
    1313           0 :         mtag = m_tag_find(m0, PACKET_TAG_SRCROUTE, NULL);
    1314           0 :         if (mtag == NULL)
    1315           0 :                 return (NULL);
    1316           0 :         isr = (struct ip_srcrt *)(mtag + 1);
    1317             : 
    1318           0 :         if (isr->isr_nhops == 0)
    1319           0 :                 return (NULL);
    1320           0 :         m = m_get(M_DONTWAIT, MT_SOOPTS);
    1321           0 :         if (m == NULL)
    1322           0 :                 return (NULL);
    1323             : 
    1324             : #define OPTSIZ  (sizeof(isr->isr_nop) + sizeof(isr->isr_hdr))
    1325             : 
    1326             :         /* length is (nhops+1)*sizeof(addr) + sizeof(nop + header) */
    1327           0 :         m->m_len = (isr->isr_nhops + 1) * sizeof(struct in_addr) + OPTSIZ;
    1328             : 
    1329             :         /*
    1330             :          * First save first hop for return route
    1331             :          */
    1332           0 :         p = &(isr->isr_routes[isr->isr_nhops - 1]);
    1333           0 :         *(mtod(m, struct in_addr *)) = *p--;
    1334             : 
    1335             :         /*
    1336             :          * Copy option fields and padding (nop) to mbuf.
    1337             :          */
    1338           0 :         isr->isr_nop = IPOPT_NOP;
    1339           0 :         isr->isr_hdr[IPOPT_OFFSET] = IPOPT_MINOFF;
    1340           0 :         memcpy(mtod(m, caddr_t) + sizeof(struct in_addr), &isr->isr_nop,
    1341             :             OPTSIZ);
    1342           0 :         q = (struct in_addr *)(mtod(m, caddr_t) +
    1343           0 :             sizeof(struct in_addr) + OPTSIZ);
    1344             : #undef OPTSIZ
    1345             :         /*
    1346             :          * Record return path as an IP source route,
    1347             :          * reversing the path (pointers are now aligned).
    1348             :          */
    1349           0 :         while (p >= isr->isr_routes) {
    1350           0 :                 *q++ = *p--;
    1351             :         }
    1352             :         /*
    1353             :          * Last hop goes to final destination.
    1354             :          */
    1355           0 :         *q = isr->isr_dst;
    1356           0 :         m_tag_delete(m0, (struct m_tag *)isr);
    1357           0 :         return (m);
    1358           0 : }
    1359             : 
    1360             : /*
    1361             :  * Strip out IP options, at higher level protocol in the kernel.
    1362             :  */
    1363             : void
    1364           0 : ip_stripoptions(struct mbuf *m)
    1365             : {
    1366             :         int i;
    1367           0 :         struct ip *ip = mtod(m, struct ip *);
    1368             :         caddr_t opts;
    1369             :         int olen;
    1370             : 
    1371           0 :         olen = (ip->ip_hl<<2) - sizeof (struct ip);
    1372           0 :         opts = (caddr_t)(ip + 1);
    1373           0 :         i = m->m_len - (sizeof (struct ip) + olen);
    1374           0 :         memmove(opts, opts  + olen, i);
    1375           0 :         m->m_len -= olen;
    1376           0 :         if (m->m_flags & M_PKTHDR)
    1377           0 :                 m->m_pkthdr.len -= olen;
    1378           0 :         ip->ip_hl = sizeof(struct ip) >> 2;
    1379           0 :         ip->ip_len = htons(ntohs(ip->ip_len) - olen);
    1380           0 : }
    1381             : 
    1382             : const u_char inetctlerrmap[PRC_NCMDS] = {
    1383             :         0,              0,              0,              0,
    1384             :         0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
    1385             :         EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
    1386             :         EMSGSIZE,       EHOSTUNREACH,   0,              0,
    1387             :         0,              0,              0,              0,
    1388             :         ENOPROTOOPT
    1389             : };
    1390             : 
    1391             : /*
    1392             :  * Forward a packet.  If some error occurs return the sender
    1393             :  * an icmp packet.  Note we can't always generate a meaningful
    1394             :  * icmp message because icmp doesn't have a large enough repertoire
    1395             :  * of codes and types.
    1396             :  *
    1397             :  * If not forwarding, just drop the packet.  This could be confusing
    1398             :  * if ipforwarding was zero but some routing protocol was advancing
    1399             :  * us as a gateway to somewhere.  However, we must let the routing
    1400             :  * protocol deal with that.
    1401             :  *
    1402             :  * The srcrt parameter indicates whether the packet is being forwarded
    1403             :  * via a source route.
    1404             :  */
    1405             : void
    1406           0 : ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
    1407             : {
    1408           0 :         struct mbuf mfake, *mcopy = NULL;
    1409           0 :         struct ip *ip = mtod(m, struct ip *);
    1410             :         struct sockaddr_in *sin;
    1411           0 :         struct route ro;
    1412             :         int error, type = 0, code = 0, destmtu = 0, fake = 0, len;
    1413             :         u_int32_t dest;
    1414             : 
    1415             :         dest = 0;
    1416           0 :         if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) {
    1417           0 :                 ipstat_inc(ips_cantforward);
    1418           0 :                 m_freem(m);
    1419           0 :                 goto freecopy;
    1420             :         }
    1421           0 :         if (ip->ip_ttl <= IPTTLDEC) {
    1422           0 :                 icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
    1423           0 :                 goto freecopy;
    1424             :         }
    1425             : 
    1426           0 :         sin = satosin(&ro.ro_dst);
    1427           0 :         memset(sin, 0, sizeof(*sin));
    1428           0 :         sin->sin_family = AF_INET;
    1429           0 :         sin->sin_len = sizeof(*sin);
    1430           0 :         sin->sin_addr = ip->ip_dst;
    1431             : 
    1432           0 :         if (!rtisvalid(rt)) {
    1433           0 :                 rtfree(rt);
    1434           0 :                 rt = rtalloc_mpath(sintosa(sin), &ip->ip_src.s_addr,
    1435           0 :                     m->m_pkthdr.ph_rtableid);
    1436           0 :                 if (rt == NULL) {
    1437           0 :                         icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
    1438           0 :                         return;
    1439             :                 }
    1440             :         }
    1441             : 
    1442             :         /*
    1443             :          * Save at most 68 bytes of the packet in case
    1444             :          * we need to generate an ICMP message to the src.
    1445             :          * The data is saved in the mbuf on the stack that
    1446             :          * acts as a temporary storage not intended to be
    1447             :          * passed down the IP stack or to the mfree.
    1448             :          */
    1449           0 :         memset(&mfake.m_hdr, 0, sizeof(mfake.m_hdr));
    1450           0 :         mfake.m_type = m->m_type;
    1451           0 :         if (m_dup_pkthdr(&mfake, m, M_DONTWAIT) == 0) {
    1452           0 :                 mfake.m_data = mfake.m_pktdat;
    1453           0 :                 len = min(ntohs(ip->ip_len), 68);
    1454           0 :                 m_copydata(m, 0, len, mfake.m_pktdat);
    1455           0 :                 mfake.m_pkthdr.len = mfake.m_len = len;
    1456             : #if NPF > 0
    1457           0 :                 pf_pkt_addr_changed(&mfake);
    1458             : #endif  /* NPF > 0 */
    1459             :                 fake = 1;
    1460           0 :         }
    1461             : 
    1462           0 :         ip->ip_ttl -= IPTTLDEC;
    1463             : 
    1464             :         /*
    1465             :          * If forwarding packet using same interface that it came in on,
    1466             :          * perhaps should send a redirect to sender to shortcut a hop.
    1467             :          * Only send redirect if source is sending directly to us,
    1468             :          * and if packet was not source routed (or has any options).
    1469             :          * Also, don't send redirect if forwarding using a default route
    1470             :          * or a route modified by a redirect.
    1471             :          * Don't send redirect if we advertise destination's arp address
    1472             :          * as ours (proxy arp).
    1473             :          */
    1474           0 :         if ((rt->rt_ifidx == ifp->if_index) &&
    1475           0 :             (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
    1476           0 :             satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
    1477           0 :             ipsendredirects && !srcrt &&
    1478           0 :             !arpproxy(satosin(rt_key(rt))->sin_addr, m->m_pkthdr.ph_rtableid)) {
    1479           0 :                 if ((ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_netmask) ==
    1480           0 :                     ifatoia(rt->rt_ifa)->ia_net) {
    1481           0 :                     if (rt->rt_flags & RTF_GATEWAY)
    1482           0 :                         dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
    1483             :                     else
    1484           0 :                         dest = ip->ip_dst.s_addr;
    1485             :                     /* Router requirements says to only send host redirects */
    1486             :                     type = ICMP_REDIRECT;
    1487             :                     code = ICMP_REDIRECT_HOST;
    1488           0 :                 }
    1489             :         }
    1490             : 
    1491           0 :         ro.ro_rt = rt;
    1492           0 :         ro.ro_tableid = m->m_pkthdr.ph_rtableid;
    1493           0 :         error = ip_output(m, NULL, &ro,
    1494           0 :             (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
    1495             :             NULL, NULL, 0);
    1496           0 :         rt = ro.ro_rt;
    1497           0 :         if (error)
    1498           0 :                 ipstat_inc(ips_cantforward);
    1499             :         else {
    1500           0 :                 ipstat_inc(ips_forward);
    1501           0 :                 if (type)
    1502           0 :                         ipstat_inc(ips_redirectsent);
    1503             :                 else
    1504             :                         goto freecopy;
    1505             :         }
    1506           0 :         if (!fake)
    1507             :                 goto freecopy;
    1508             : 
    1509           0 :         switch (error) {
    1510             : 
    1511             :         case 0:                         /* forwarded, but need redirect */
    1512             :                 /* type, code set above */
    1513             :                 break;
    1514             : 
    1515             :         case ENETUNREACH:               /* shouldn't happen, checked above */
    1516             :         case EHOSTUNREACH:
    1517             :         case ENETDOWN:
    1518             :         case EHOSTDOWN:
    1519             :         default:
    1520             :                 type = ICMP_UNREACH;
    1521             :                 code = ICMP_UNREACH_HOST;
    1522           0 :                 break;
    1523             : 
    1524             :         case EMSGSIZE:
    1525             :                 type = ICMP_UNREACH;
    1526             :                 code = ICMP_UNREACH_NEEDFRAG;
    1527             : 
    1528             : #ifdef IPSEC
    1529           0 :                 if (rt != NULL) {
    1530           0 :                         if (rt->rt_mtu)
    1531           0 :                                 destmtu = rt->rt_mtu;
    1532             :                         else {
    1533             :                                 struct ifnet *destifp;
    1534             : 
    1535           0 :                                 destifp = if_get(rt->rt_ifidx);
    1536           0 :                                 if (destifp != NULL)
    1537           0 :                                         destmtu = destifp->if_mtu;
    1538           0 :                                 if_put(destifp);
    1539             :                         }
    1540             :                 }
    1541             : #endif /*IPSEC*/
    1542           0 :                 ipstat_inc(ips_cantfrag);
    1543           0 :                 break;
    1544             : 
    1545             :         case EACCES:
    1546             :                 /*
    1547             :                  * pf(4) blocked the packet. There is no need to send an ICMP
    1548             :                  * packet back since pf(4) takes care of it.
    1549             :                  */
    1550             :                 goto freecopy;
    1551             :         case ENOBUFS:
    1552             :                 /*
    1553             :                  * a router should not generate ICMP_SOURCEQUENCH as
    1554             :                  * required in RFC1812 Requirements for IP Version 4 Routers.
    1555             :                  * source quench could be a big problem under DoS attacks,
    1556             :                  * or the underlying interface is rate-limited.
    1557             :                  */
    1558             :                 goto freecopy;
    1559             :         }
    1560             : 
    1561           0 :         mcopy = m_copym(&mfake, 0, len, M_DONTWAIT);
    1562           0 :         if (mcopy)
    1563           0 :                 icmp_error(mcopy, type, code, dest, destmtu);
    1564             : 
    1565             : freecopy:
    1566           0 :         if (fake)
    1567           0 :                 m_tag_delete_chain(&mfake);
    1568           0 :         rtfree(rt);
    1569           0 : }
    1570             : 
    1571             : int
    1572           0 : ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
    1573             :     size_t newlen)
    1574             : {
    1575             :         int error;
    1576             : #ifdef MROUTING
    1577             :         extern int ip_mrtproto;
    1578             :         extern struct mrtstat mrtstat;
    1579             : #endif
    1580             : 
    1581             :         /* Almost all sysctl names at this level are terminal. */
    1582           0 :         if (namelen != 1 && name[0] != IPCTL_IFQUEUE)
    1583           0 :                 return (ENOTDIR);
    1584             : 
    1585           0 :         switch (name[0]) {
    1586             :         case IPCTL_SOURCEROUTE:
    1587             :                 /*
    1588             :                  * Don't allow this to change in a secure environment.
    1589             :                  */
    1590           0 :                 if (newp && securelevel > 0)
    1591           0 :                         return (EPERM);
    1592           0 :                 NET_LOCK();
    1593           0 :                 error = sysctl_int(oldp, oldlenp, newp, newlen,
    1594             :                     &ip_dosourceroute);
    1595           0 :                 NET_UNLOCK();
    1596           0 :                 return (error);
    1597             :         case IPCTL_MTUDISC:
    1598           0 :                 NET_LOCK();
    1599           0 :                 error = sysctl_int(oldp, oldlenp, newp, newlen,
    1600             :                     &ip_mtudisc);
    1601           0 :                 if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) {
    1602           0 :                         ip_mtudisc_timeout_q =
    1603           0 :                             rt_timer_queue_create(ip_mtudisc_timeout);
    1604           0 :                 } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) {
    1605           0 :                         rt_timer_queue_destroy(ip_mtudisc_timeout_q);
    1606           0 :                         ip_mtudisc_timeout_q = NULL;
    1607           0 :                 }
    1608           0 :                 NET_UNLOCK();
    1609           0 :                 return error;
    1610             :         case IPCTL_MTUDISCTIMEOUT:
    1611           0 :                 NET_LOCK();
    1612           0 :                 error = sysctl_int(oldp, oldlenp, newp, newlen,
    1613             :                    &ip_mtudisc_timeout);
    1614           0 :                 if (ip_mtudisc_timeout_q != NULL)
    1615           0 :                         rt_timer_queue_change(ip_mtudisc_timeout_q,
    1616           0 :                                               ip_mtudisc_timeout);
    1617           0 :                 NET_UNLOCK();
    1618           0 :                 return (error);
    1619             : #ifdef IPSEC
    1620             :         case IPCTL_ENCDEBUG:
    1621             :         case IPCTL_IPSEC_STATS:
    1622             :         case IPCTL_IPSEC_EXPIRE_ACQUIRE:
    1623             :         case IPCTL_IPSEC_EMBRYONIC_SA_TIMEOUT:
    1624             :         case IPCTL_IPSEC_REQUIRE_PFS:
    1625             :         case IPCTL_IPSEC_SOFT_ALLOCATIONS:
    1626             :         case IPCTL_IPSEC_ALLOCATIONS:
    1627             :         case IPCTL_IPSEC_SOFT_BYTES:
    1628             :         case IPCTL_IPSEC_BYTES:
    1629             :         case IPCTL_IPSEC_TIMEOUT:
    1630             :         case IPCTL_IPSEC_SOFT_TIMEOUT:
    1631             :         case IPCTL_IPSEC_SOFT_FIRSTUSE:
    1632             :         case IPCTL_IPSEC_FIRSTUSE:
    1633             :         case IPCTL_IPSEC_ENC_ALGORITHM:
    1634             :         case IPCTL_IPSEC_AUTH_ALGORITHM:
    1635             :         case IPCTL_IPSEC_IPCOMP_ALGORITHM:
    1636           0 :                 return (ipsec_sysctl(name, namelen, oldp, oldlenp, newp,
    1637             :                     newlen));
    1638             : #endif
    1639             :         case IPCTL_IFQUEUE:
    1640           0 :                 return (sysctl_niq(name + 1, namelen - 1,
    1641             :                     oldp, oldlenp, newp, newlen, &ipintrq));
    1642             :         case IPCTL_STATS:
    1643           0 :                 return (ip_sysctl_ipstat(oldp, oldlenp, newp));
    1644             : #ifdef MROUTING
    1645             :         case IPCTL_MRTSTATS:
    1646           0 :                 return (sysctl_rdstruct(oldp, oldlenp, newp,
    1647             :                     &mrtstat, sizeof(mrtstat)));
    1648             :         case IPCTL_MRTPROTO:
    1649           0 :                 return (sysctl_rdint(oldp, oldlenp, newp, ip_mrtproto));
    1650             :         case IPCTL_MRTMFC:
    1651           0 :                 if (newp)
    1652           0 :                         return (EPERM);
    1653           0 :                 NET_LOCK();
    1654           0 :                 error = mrt_sysctl_mfc(oldp, oldlenp);
    1655           0 :                 NET_UNLOCK();
    1656           0 :                 return (error);
    1657             :         case IPCTL_MRTVIF:
    1658           0 :                 if (newp)
    1659           0 :                         return (EPERM);
    1660           0 :                 NET_LOCK();
    1661           0 :                 error = mrt_sysctl_vif(oldp, oldlenp);
    1662           0 :                 NET_UNLOCK();
    1663           0 :                 return (error);
    1664             : #else
    1665             :         case IPCTL_MRTPROTO:
    1666             :         case IPCTL_MRTSTATS:
    1667             :         case IPCTL_MRTMFC:
    1668             :         case IPCTL_MRTVIF:
    1669             :                 return (EOPNOTSUPP);
    1670             : #endif
    1671             :         default:
    1672           0 :                 if (name[0] < IPCTL_MAXID) {
    1673           0 :                         NET_LOCK();
    1674           0 :                         error = sysctl_int_arr(ipctl_vars, name, namelen,
    1675             :                             oldp, oldlenp, newp, newlen);
    1676           0 :                         NET_UNLOCK();
    1677           0 :                         return (error);
    1678             :                 }
    1679           0 :                 return (EOPNOTSUPP);
    1680             :         }
    1681             :         /* NOTREACHED */
    1682           0 : }
    1683             : 
    1684             : int
    1685           0 : ip_sysctl_ipstat(void *oldp, size_t *oldlenp, void *newp)
    1686             : {
    1687           0 :         uint64_t counters[ips_ncounters];
    1688           0 :         struct ipstat ipstat;
    1689           0 :         u_long *words = (u_long *)&ipstat;
    1690             :         int i;
    1691             : 
    1692             :         CTASSERT(sizeof(ipstat) == (nitems(counters) * sizeof(u_long)));
    1693           0 :         memset(&ipstat, 0, sizeof ipstat);
    1694           0 :         counters_read(ipcounters, counters, nitems(counters));
    1695             : 
    1696           0 :         for (i = 0; i < nitems(counters); i++)
    1697           0 :                 words[i] = (u_long)counters[i];
    1698             : 
    1699           0 :         return (sysctl_rdstruct(oldp, oldlenp, newp, &ipstat, sizeof(ipstat)));
    1700           0 : }
    1701             : 
    1702             : void
    1703           0 : ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
    1704             :     struct mbuf *m)
    1705             : {
    1706           0 :         if (inp->inp_socket->so_options & SO_TIMESTAMP) {
    1707           0 :                 struct timeval tv;
    1708             : 
    1709           0 :                 microtime(&tv);
    1710           0 :                 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
    1711             :                     SCM_TIMESTAMP, SOL_SOCKET);
    1712           0 :                 if (*mp)
    1713           0 :                         mp = &(*mp)->m_next;
    1714           0 :         }
    1715             : 
    1716           0 :         if (inp->inp_flags & INP_RECVDSTADDR) {
    1717           0 :                 *mp = sbcreatecontrol((caddr_t) &ip->ip_dst,
    1718             :                     sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
    1719           0 :                 if (*mp)
    1720           0 :                         mp = &(*mp)->m_next;
    1721             :         }
    1722             : #ifdef notyet
    1723             :         /* this code is broken and will probably never be fixed. */
    1724             :         /* options were tossed already */
    1725             :         if (inp->inp_flags & INP_RECVOPTS) {
    1726             :                 *mp = sbcreatecontrol((caddr_t) opts_deleted_above,
    1727             :                     sizeof(struct in_addr), IP_RECVOPTS, IPPROTO_IP);
    1728             :                 if (*mp)
    1729             :                         mp = &(*mp)->m_next;
    1730             :         }
    1731             :         /* ip_srcroute doesn't do what we want here, need to fix */
    1732             :         if (inp->inp_flags & INP_RECVRETOPTS) {
    1733             :                 *mp = sbcreatecontrol((caddr_t) ip_srcroute(m),
    1734             :                     sizeof(struct in_addr), IP_RECVRETOPTS, IPPROTO_IP);
    1735             :                 if (*mp)
    1736             :                         mp = &(*mp)->m_next;
    1737             :         }
    1738             : #endif
    1739           0 :         if (inp->inp_flags & INP_RECVIF) {
    1740           0 :                 struct sockaddr_dl sdl;
    1741             :                 struct ifnet *ifp;
    1742             : 
    1743           0 :                 ifp = if_get(m->m_pkthdr.ph_ifidx);
    1744           0 :                 if (ifp == NULL || ifp->if_sadl == NULL) {
    1745           0 :                         memset(&sdl, 0, sizeof(sdl));
    1746           0 :                         sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0]);
    1747           0 :                         sdl.sdl_family = AF_LINK;
    1748           0 :                         sdl.sdl_index = ifp != NULL ? ifp->if_index : 0;
    1749           0 :                         sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0;
    1750           0 :                         *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len,
    1751             :                             IP_RECVIF, IPPROTO_IP);
    1752           0 :                 } else {
    1753           0 :                         *mp = sbcreatecontrol((caddr_t) ifp->if_sadl,
    1754           0 :                             ifp->if_sadl->sdl_len, IP_RECVIF, IPPROTO_IP);
    1755             :                 }
    1756           0 :                 if (*mp)
    1757           0 :                         mp = &(*mp)->m_next;
    1758           0 :                 if_put(ifp);
    1759           0 :         }
    1760           0 :         if (inp->inp_flags & INP_RECVTTL) {
    1761           0 :                 *mp = sbcreatecontrol((caddr_t) &ip->ip_ttl,
    1762             :                     sizeof(u_int8_t), IP_RECVTTL, IPPROTO_IP);
    1763           0 :                 if (*mp)
    1764           0 :                         mp = &(*mp)->m_next;
    1765             :         }
    1766           0 :         if (inp->inp_flags & INP_RECVRTABLE) {
    1767           0 :                 u_int rtableid = inp->inp_rtableid;
    1768             : 
    1769             : #if NPF > 0
    1770           0 :                 if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
    1771             :                         struct pf_divert *divert;
    1772             : 
    1773           0 :                         divert = pf_find_divert(m);
    1774           0 :                         KASSERT(divert != NULL);
    1775           0 :                         rtableid = divert->rdomain;
    1776           0 :                 }
    1777             : #endif
    1778             : 
    1779           0 :                 *mp = sbcreatecontrol((caddr_t) &rtableid,
    1780             :                     sizeof(u_int), IP_RECVRTABLE, IPPROTO_IP);
    1781           0 :                 if (*mp)
    1782           0 :                         mp = &(*mp)->m_next;
    1783           0 :         }
    1784           0 : }
    1785             : 
    1786             : void
    1787           0 : ip_send_dispatch(void *xmq)
    1788             : {
    1789           0 :         struct mbuf_queue *mq = xmq;
    1790             :         struct mbuf *m;
    1791           0 :         struct mbuf_list ml;
    1792             : 
    1793           0 :         mq_delist(mq, &ml);
    1794           0 :         if (ml_empty(&ml))
    1795           0 :                 return;
    1796             : 
    1797           0 :         NET_RLOCK();
    1798           0 :         while ((m = ml_dequeue(&ml)) != NULL) {
    1799           0 :                 ip_output(m, NULL, NULL, 0, NULL, NULL, 0);
    1800             :         }
    1801           0 :         NET_RUNLOCK();
    1802           0 : }
    1803             : 
    1804             : void
    1805           0 : ip_send(struct mbuf *m)
    1806             : {
    1807           0 :         mq_enqueue(&ipsend_mq, m);
    1808           0 :         task_add(net_tq(0), &ipsend_task);
    1809           0 : }

Generated by: LCOV version 1.13