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

          Line data    Source code
       1             : /*      $OpenBSD: ip6_input.c,v 1.215 2018/05/21 15:52:22 bluhm Exp $   */
       2             : /*      $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
       3             : 
       4             : /*
       5             :  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
       6             :  * 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 project 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 PROJECT 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 PROJECT 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             : 
      33             : /*
      34             :  * Copyright (c) 1982, 1986, 1988, 1993
      35             :  *      The Regents of the University of California.  All rights reserved.
      36             :  *
      37             :  * Redistribution and use in source and binary forms, with or without
      38             :  * modification, are permitted provided that the following conditions
      39             :  * are met:
      40             :  * 1. Redistributions of source code must retain the above copyright
      41             :  *    notice, this list of conditions and the following disclaimer.
      42             :  * 2. Redistributions in binary form must reproduce the above copyright
      43             :  *    notice, this list of conditions and the following disclaimer in the
      44             :  *    documentation and/or other materials provided with the distribution.
      45             :  * 3. Neither the name of the University nor the names of its contributors
      46             :  *    may be used to endorse or promote products derived from this software
      47             :  *    without specific prior written permission.
      48             :  *
      49             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      50             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      51             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      52             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      53             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      54             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      55             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      56             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      57             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      58             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      59             :  * SUCH DAMAGE.
      60             :  *
      61             :  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
      62             :  */
      63             : 
      64             : #include "pf.h"
      65             : #include "carp.h"
      66             : 
      67             : #include <sys/param.h>
      68             : #include <sys/systm.h>
      69             : #include <sys/mbuf.h>
      70             : #include <sys/domain.h>
      71             : #include <sys/sysctl.h>
      72             : #include <sys/protosw.h>
      73             : #include <sys/socket.h>
      74             : #include <sys/socketvar.h>
      75             : #include <sys/errno.h>
      76             : #include <sys/time.h>
      77             : #include <sys/timeout.h>
      78             : #include <sys/kernel.h>
      79             : #include <sys/syslog.h>
      80             : #include <sys/task.h>
      81             : 
      82             : #include <net/if.h>
      83             : #include <net/if_var.h>
      84             : #include <net/if_types.h>
      85             : #include <net/route.h>
      86             : #include <net/netisr.h>
      87             : 
      88             : #include <netinet/in.h>
      89             : 
      90             : #include <netinet/ip.h>
      91             : 
      92             : #include <netinet/in_pcb.h>
      93             : #include <netinet/ip_var.h>
      94             : #include <netinet6/in6_var.h>
      95             : #include <netinet6/in6_ifattach.h>
      96             : #include <netinet/ip6.h>
      97             : #include <netinet6/ip6_var.h>
      98             : #include <netinet/icmp6.h>
      99             : #include <netinet6/nd6.h>
     100             : 
     101             : #include <netinet6/ip6protosw.h>
     102             : 
     103             : #include "gif.h"
     104             : #include "bpfilter.h"
     105             : 
     106             : #ifdef MROUTING
     107             : #include <netinet6/ip6_mroute.h>
     108             : #endif
     109             : 
     110             : #if NPF > 0
     111             : #include <net/pfvar.h>
     112             : #endif
     113             : 
     114             : #if NCARP > 0
     115             : #include <netinet/ip_carp.h>
     116             : #endif
     117             : 
     118             : struct niqueue ip6intrq = NIQUEUE_INITIALIZER(IPQ_MAXLEN, NETISR_IPV6);
     119             : 
     120             : struct cpumem *ip6counters;
     121             : 
     122             : uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
     123             : 
     124             : int ip6_ours(struct mbuf **, int *, int, int);
     125             : int ip6_local(struct mbuf **, int *, int, int);
     126             : int ip6_check_rh0hdr(struct mbuf *, int *);
     127             : int ip6_hbhchcheck(struct mbuf *, int *, int *, int *);
     128             : int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
     129             : struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
     130             : int ip6_sysctl_soiikey(void *, size_t *, void *, size_t);
     131             : 
     132             : static struct mbuf_queue        ip6send_mq;
     133             : 
     134             : static void ip6_send_dispatch(void *);
     135             : static struct task ip6send_task =
     136             :         TASK_INITIALIZER(ip6_send_dispatch, &ip6send_mq);
     137             : 
     138             : /*
     139             :  * IP6 initialization: fill in IP6 protocol switch table.
     140             :  * All protocols not implemented in kernel go to raw IP6 protocol handler.
     141             :  */
     142             : void
     143           0 : ip6_init(void)
     144             : {
     145             :         const struct protosw *pr;
     146             :         int i;
     147             : 
     148           0 :         pr = pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
     149           0 :         if (pr == NULL)
     150           0 :                 panic("ip6_init");
     151           0 :         for (i = 0; i < IPPROTO_MAX; i++)
     152           0 :                 ip6_protox[i] = pr - inet6sw;
     153           0 :         for (pr = inet6domain.dom_protosw;
     154           0 :             pr < inet6domain.dom_protoswNPROTOSW; pr++)
     155           0 :                 if (pr->pr_domain->dom_family == PF_INET6 &&
     156           0 :                     pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW &&
     157           0 :                     pr->pr_protocol < IPPROTO_MAX)
     158           0 :                         ip6_protox[pr->pr_protocol] = pr - inet6sw;
     159           0 :         ip6_randomid_init();
     160           0 :         nd6_init();
     161           0 :         frag6_init();
     162             : 
     163           0 :         mq_init(&ip6send_mq, 64, IPL_SOFTNET);
     164             : 
     165           0 :         ip6counters = counters_alloc(ip6s_ncounters);
     166           0 : }
     167             : 
     168             : /*
     169             :  * Enqueue packet for local delivery.  Queuing is used as a boundary
     170             :  * between the network layer (input/forward path) running without
     171             :  * KERNEL_LOCK() and the transport layer still needing it.
     172             :  */
     173             : int
     174           0 : ip6_ours(struct mbuf **mp, int *offp, int nxt, int af)
     175             : {
     176             :         /* We are already in a IPv4/IPv6 local deliver loop. */
     177           0 :         if (af != AF_UNSPEC)
     178           0 :                 return ip6_local(mp, offp, nxt, af);
     179             : 
     180           0 :         niq_enqueue(&ip6intrq, *mp);
     181           0 :         *mp = NULL;
     182           0 :         return IPPROTO_DONE;
     183           0 : }
     184             : 
     185             : /*
     186             :  * Dequeue and process locally delivered packets.
     187             :  */
     188             : void
     189           0 : ip6intr(void)
     190             : {
     191           0 :         struct mbuf *m;
     192           0 :         int off, nxt;
     193             : 
     194           0 :         while ((m = niq_dequeue(&ip6intrq)) != NULL) {
     195             : #ifdef DIAGNOSTIC
     196           0 :                 if ((m->m_flags & M_PKTHDR) == 0)
     197           0 :                         panic("ip6intr no HDR");
     198             : #endif
     199           0 :                 off = 0;
     200           0 :                 nxt = ip6_local(&m, &off, IPPROTO_IPV6, AF_UNSPEC);
     201           0 :                 KASSERT(nxt == IPPROTO_DONE);
     202             :         }
     203           0 : }
     204             : 
     205             : void
     206           0 : ipv6_input(struct ifnet *ifp, struct mbuf *m)
     207             : {
     208           0 :         int off, nxt;
     209             : 
     210           0 :         off = 0;
     211           0 :         nxt = ip6_input_if(&m, &off, IPPROTO_IPV6, AF_UNSPEC, ifp);
     212           0 :         KASSERT(nxt == IPPROTO_DONE);
     213           0 : }
     214             : 
     215             : int
     216           0 : ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
     217             : {
     218           0 :         struct mbuf *m = *mp;
     219             :         struct ip6_hdr *ip6;
     220           0 :         struct sockaddr_in6 sin6;
     221             :         struct rtentry *rt = NULL;
     222           0 :         int ours = 0;
     223             :         u_int16_t src_scope, dst_scope;
     224             : #if NPF > 0
     225           0 :         struct in6_addr odst;
     226             : #endif
     227             :         int srcrt = 0;
     228             : 
     229           0 :         KASSERT(*offp == 0);
     230             : 
     231           0 :         ip6stat_inc(ip6s_total);
     232             : 
     233           0 :         if (m->m_len < sizeof(struct ip6_hdr)) {
     234           0 :                 if ((m = *mp = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
     235           0 :                         ip6stat_inc(ip6s_toosmall);
     236           0 :                         goto bad;
     237             :                 }
     238             :         }
     239             : 
     240           0 :         ip6 = mtod(m, struct ip6_hdr *);
     241             : 
     242           0 :         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
     243           0 :                 ip6stat_inc(ip6s_badvers);
     244           0 :                 goto bad;
     245             :         }
     246             : 
     247             : #if NCARP > 0
     248           0 :         if (carp_lsdrop(ifp, m, AF_INET6, ip6->ip6_src.s6_addr32,
     249           0 :             ip6->ip6_dst.s6_addr32, (ip6->ip6_nxt == IPPROTO_ICMPV6 ? 0 : 1)))
     250             :                 goto bad;
     251             : #endif
     252           0 :         ip6stat_inc(ip6s_nxthist + ip6->ip6_nxt);
     253             : 
     254             :         /*
     255             :          * Check against address spoofing/corruption.
     256             :          */
     257           0 :         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
     258           0 :             IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
     259             :                 /*
     260             :                  * XXX: "badscope" is not very suitable for a multicast source.
     261             :                  */
     262           0 :                 ip6stat_inc(ip6s_badscope);
     263           0 :                 goto bad;
     264             :         }
     265           0 :         if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
     266           0 :             IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) &&
     267           0 :             (ifp->if_flags & IFF_LOOPBACK) == 0) {
     268           0 :                     ip6stat_inc(ip6s_badscope);
     269           0 :                     goto bad;
     270             :         }
     271             :         /* Drop packets if interface ID portion is already filled. */
     272           0 :         if (((IN6_IS_SCOPE_EMBED(&ip6->ip6_src) && ip6->ip6_src.s6_addr16[1]) ||
     273           0 :             (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst) && ip6->ip6_dst.s6_addr16[1])) &&
     274           0 :             (ifp->if_flags & IFF_LOOPBACK) == 0) {
     275           0 :                 ip6stat_inc(ip6s_badscope);
     276           0 :                 goto bad;
     277             :         }
     278           0 :         if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) &&
     279           0 :             !(m->m_flags & M_LOOP)) {
     280             :                 /*
     281             :                  * In this case, the packet should come from the loopback
     282             :                  * interface.  However, we cannot just check the if_flags,
     283             :                  * because ip6_mloopback() passes the "actual" interface
     284             :                  * as the outgoing/incoming interface.
     285             :                  */
     286           0 :                 ip6stat_inc(ip6s_badscope);
     287           0 :                 goto bad;
     288             :         }
     289             : 
     290             :         /*
     291             :          * The following check is not documented in specs.  A malicious
     292             :          * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
     293             :          * and bypass security checks (act as if it was from 127.0.0.1 by using
     294             :          * IPv6 src ::ffff:127.0.0.1).  Be cautious.
     295             :          *
     296             :          * This check chokes if we are in an SIIT cloud.  As none of BSDs
     297             :          * support IPv4-less kernel compilation, we cannot support SIIT
     298             :          * environment at all.  So, it makes more sense for us to reject any
     299             :          * malicious packets for non-SIIT environment, than try to do a
     300             :          * partial support for SIIT environment.
     301             :          */
     302           0 :         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
     303           0 :             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
     304           0 :                 ip6stat_inc(ip6s_badscope);
     305           0 :                 goto bad;
     306             :         }
     307             : 
     308             :         /*
     309             :          * Reject packets with IPv4 compatible addresses (auto tunnel).
     310             :          *
     311             :          * The code forbids automatic tunneling as per RFC4213.
     312             :          */
     313           0 :         if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
     314           0 :             IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
     315           0 :                 ip6stat_inc(ip6s_badscope);
     316           0 :                 goto bad;
     317             :         }
     318             : 
     319             :         /*
     320             :          * If the packet has been received on a loopback interface it
     321             :          * can be destinated to any local address, not necessarily to
     322             :          * an address configured on `ifp'.
     323             :          */
     324           0 :         if (ifp->if_flags & IFF_LOOPBACK) {
     325           0 :                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
     326           0 :                         src_scope = ip6->ip6_src.s6_addr16[1];
     327           0 :                         ip6->ip6_src.s6_addr16[1] = 0;
     328           0 :                 }
     329           0 :                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
     330           0 :                         dst_scope = ip6->ip6_dst.s6_addr16[1];
     331           0 :                         ip6->ip6_dst.s6_addr16[1] = 0;
     332           0 :                 }
     333             :         }
     334             : 
     335             : #if NPF > 0
     336             :         /*
     337             :          * Packet filter
     338             :          */
     339           0 :         odst = ip6->ip6_dst;
     340           0 :         if (pf_test(AF_INET6, PF_IN, ifp, mp) != PF_PASS)
     341             :                 goto bad;
     342           0 :         m = *mp;
     343           0 :         if (m == NULL)
     344             :                 goto bad;
     345             : 
     346           0 :         ip6 = mtod(m, struct ip6_hdr *);
     347           0 :         srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
     348             : #endif
     349             : 
     350             :         /*
     351             :          * Without embedded scope ID we cannot find link-local
     352             :          * addresses in the routing table.
     353             :          */
     354           0 :         if (ifp->if_flags & IFF_LOOPBACK) {
     355           0 :                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
     356           0 :                         ip6->ip6_src.s6_addr16[1] = src_scope;
     357           0 :                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
     358           0 :                         ip6->ip6_dst.s6_addr16[1] = dst_scope;
     359             :         } else {
     360           0 :                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
     361           0 :                         ip6->ip6_src.s6_addr16[1] = htons(ifp->if_index);
     362           0 :                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
     363           0 :                         ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index);
     364             :         }
     365             : 
     366             :         /*
     367             :          * Be more secure than RFC5095 and scan for type 0 routing headers.
     368             :          * If pf has already scanned the header chain, do not do it twice.
     369             :          */
     370           0 :         if (!(m->m_pkthdr.pf.flags & PF_TAG_PROCESSED) &&
     371           0 :             ip6_check_rh0hdr(m, offp)) {
     372           0 :                 ip6stat_inc(ip6s_badoptions);
     373           0 :                 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, *offp);
     374           0 :                 m = *mp = NULL;
     375           0 :                 goto bad;
     376             :         }
     377             : 
     378           0 :         if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
     379           0 :             IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) {
     380           0 :                 nxt = ip6_ours(mp, offp, nxt, af);
     381           0 :                 goto out;
     382             :         }
     383             : 
     384             : #if NPF > 0
     385           0 :         if (pf_ouraddr(m) == 1) {
     386           0 :                 nxt = ip6_ours(mp, offp, nxt, af);
     387           0 :                 goto out;
     388             :         }
     389             : #endif
     390             : 
     391             :         /*
     392             :          * Multicast check
     393             :          */
     394           0 :         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
     395             :                 /*
     396             :                  * Make sure M_MCAST is set.  It should theoretically
     397             :                  * already be there, but let's play safe because upper
     398             :                  * layers check for this flag.
     399             :                  */
     400           0 :                 m->m_flags |= M_MCAST;
     401             : 
     402             :                 /*
     403             :                  * See if we belong to the destination multicast group on the
     404             :                  * arrival interface.
     405             :                  */
     406           0 :                 if (in6_hasmulti(&ip6->ip6_dst, ifp))
     407           0 :                         ours = 1;
     408             : 
     409             : #ifdef MROUTING
     410           0 :                 if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain]) {
     411             :                         int error;
     412             : 
     413           0 :                         if (ip6_hbhchcheck(m, offp, &nxt, &ours))
     414           0 :                                 goto out;
     415             : 
     416           0 :                         ip6 = mtod(m, struct ip6_hdr *);
     417             : 
     418             :                         /*
     419             :                          * If we are acting as a multicast router, all
     420             :                          * incoming multicast packets are passed to the
     421             :                          * kernel-level multicast forwarding function.
     422             :                          * The packet is returned (relatively) intact; if
     423             :                          * ip6_mforward() returns a non-zero value, the packet
     424             :                          * must be discarded, else it may be accepted below.
     425             :                          */
     426           0 :                         KERNEL_LOCK();
     427           0 :                         error = ip6_mforward(ip6, ifp, m);
     428           0 :                         KERNEL_UNLOCK();
     429           0 :                         if (error) {
     430           0 :                                 ip6stat_inc(ip6s_cantforward);
     431           0 :                                 goto bad;
     432             :                         }
     433             : 
     434           0 :                         if (ours) {
     435           0 :                                 if (af == AF_UNSPEC) {
     436           0 :                                         KERNEL_LOCK();
     437           0 :                                         nxt = ip_deliver(mp, offp, nxt,
     438             :                                             AF_INET6);
     439           0 :                                         KERNEL_UNLOCK();
     440           0 :                                 }
     441           0 :                                 goto out;
     442             :                         }
     443           0 :                         goto bad;
     444             :                 }
     445             : #endif
     446           0 :                 if (!ours) {
     447           0 :                         ip6stat_inc(ip6s_notmember);
     448           0 :                         if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst))
     449           0 :                                 ip6stat_inc(ip6s_cantforward);
     450             :                         goto bad;
     451             :                 }
     452           0 :                 nxt = ip6_ours(mp, offp, nxt, af);
     453           0 :                 goto out;
     454             :         }
     455             : 
     456             : 
     457             :         /*
     458             :          *  Unicast check
     459             :          */
     460           0 :         memset(&sin6, 0, sizeof(struct sockaddr_in6));
     461           0 :         sin6.sin6_len = sizeof(struct sockaddr_in6);
     462           0 :         sin6.sin6_family = AF_INET6;
     463           0 :         sin6.sin6_addr = ip6->ip6_dst;
     464           0 :         rt = rtalloc_mpath(sin6tosa(&sin6), &ip6->ip6_src.s6_addr32[0],
     465           0 :             m->m_pkthdr.ph_rtableid);
     466             : 
     467             :         /*
     468             :          * Accept the packet if the route to the destination is marked
     469             :          * as local.
     470             :          */
     471           0 :         if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)) {
     472           0 :                 struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa);
     473           0 :                 if (ia6->ia6_flags & IN6_IFF_ANYCAST)
     474           0 :                         m->m_flags |= M_ACAST;
     475             :                 /*
     476             :                  * packets to a tentative, duplicated, or somehow invalid
     477             :                  * address must not be accepted.
     478             :                  */
     479           0 :                 if ((ia6->ia6_flags & (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED))) {
     480           0 :                         char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
     481             : 
     482           0 :                         inet_ntop(AF_INET6, &ip6->ip6_src, src, sizeof(src));
     483           0 :                         inet_ntop(AF_INET6, &ip6->ip6_dst, dst, sizeof(dst));
     484             :                         /* address is not ready, so discard the packet. */
     485           0 :                         nd6log((LOG_INFO,
     486             :                             "%s: packet to an unready address %s->%s\n",
     487             :                             __func__, src, dst));
     488             : 
     489             :                         goto bad;
     490           0 :                 } else {
     491           0 :                         nxt = ip6_ours(mp, offp, nxt, af);
     492           0 :                         goto out;
     493             :                 }
     494             :         }
     495             : 
     496             : #if NCARP > 0
     497           0 :         if (ip6->ip6_nxt == IPPROTO_ICMPV6 &&
     498           0 :             carp_lsdrop(ifp, m, AF_INET6, ip6->ip6_src.s6_addr32,
     499           0 :             ip6->ip6_dst.s6_addr32, 1))
     500             :                 goto bad;
     501             : #endif
     502             :         /*
     503             :          * Now there is no reason to process the packet if it's not our own
     504             :          * and we're not a router.
     505             :          */
     506           0 :         if (!ip6_forwarding) {
     507           0 :                 ip6stat_inc(ip6s_cantforward);
     508           0 :                 goto bad;
     509             :         }
     510             : 
     511           0 :         if (ip6_hbhchcheck(m, offp, &nxt, &ours))
     512             :                 goto out;
     513             : 
     514           0 :         if (ours) {
     515           0 :                 if (af == AF_UNSPEC) {
     516           0 :                         KERNEL_LOCK();
     517           0 :                         nxt = ip_deliver(mp, offp, nxt, AF_INET6);
     518           0 :                         KERNEL_UNLOCK();
     519           0 :                 }
     520             :                 goto out;
     521             :         }
     522             : 
     523             : #ifdef IPSEC
     524           0 :         if (ipsec_in_use) {
     525             :                 int rv;
     526             : 
     527           0 :                 rv = ipsec_forward_check(m, *offp, AF_INET6);
     528           0 :                 if (rv != 0) {
     529           0 :                         ip6stat_inc(ip6s_cantforward);
     530           0 :                         goto bad;
     531             :                 }
     532             :                 /*
     533             :                  * Fall through, forward packet. Outbound IPsec policy
     534             :                  * checking will occur in ip6_forward().
     535             :                  */
     536           0 :         }
     537             : #endif /* IPSEC */
     538             : 
     539           0 :         ip6_forward(m, rt, srcrt);
     540           0 :         *mp = NULL;
     541           0 :         return IPPROTO_DONE;
     542             :  bad:
     543           0 :         nxt = IPPROTO_DONE;
     544           0 :         m_freemp(mp);
     545             :  out:
     546           0 :         rtfree(rt);
     547           0 :         return nxt;
     548           0 : }
     549             : 
     550             : int
     551           0 : ip6_local(struct mbuf **mp, int *offp, int nxt, int af)
     552             : {
     553           0 :         if (ip6_hbhchcheck(*mp, offp, &nxt, NULL))
     554           0 :                 return IPPROTO_DONE;
     555             : 
     556             :         /* Check wheter we are already in a IPv4/IPv6 local deliver loop. */
     557           0 :         if (af == AF_UNSPEC)
     558           0 :                 nxt = ip_deliver(mp, offp, nxt, AF_INET6);
     559           0 :         return nxt;
     560           0 : }
     561             : 
     562             : int
     563           0 : ip6_hbhchcheck(struct mbuf *m, int *offp, int *nxtp, int *oursp)
     564             : {
     565             :         struct ip6_hdr *ip6;
     566           0 :         u_int32_t plen, rtalert = ~0;
     567             : 
     568           0 :         ip6 = mtod(m, struct ip6_hdr *);
     569             : 
     570             :         /*
     571             :          * Process Hop-by-Hop options header if it's contained.
     572             :          * m may be modified in ip6_hopopts_input().
     573             :          * If a JumboPayload option is included, plen will also be modified.
     574             :          */
     575           0 :         plen = (u_int32_t)ntohs(ip6->ip6_plen);
     576           0 :         *offp = sizeof(struct ip6_hdr);
     577           0 :         if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
     578             :                 struct ip6_hbh *hbh;
     579             : 
     580           0 :                 if (ip6_hopopts_input(&plen, &rtalert, &m, offp)) {
     581           0 :                         goto bad;       /* m have already been freed */
     582             :                 }
     583             : 
     584             :                 /* adjust pointer */
     585           0 :                 ip6 = mtod(m, struct ip6_hdr *);
     586             : 
     587             :                 /*
     588             :                  * if the payload length field is 0 and the next header field
     589             :                  * indicates Hop-by-Hop Options header, then a Jumbo Payload
     590             :                  * option MUST be included.
     591             :                  */
     592           0 :                 if (ip6->ip6_plen == 0 && plen == 0) {
     593             :                         /*
     594             :                          * Note that if a valid jumbo payload option is
     595             :                          * contained, ip6_hopopts_input() must set a valid
     596             :                          * (non-zero) payload length to the variable plen.
     597             :                          */
     598           0 :                         ip6stat_inc(ip6s_badoptions);
     599           0 :                         icmp6_error(m, ICMP6_PARAM_PROB,
     600             :                                     ICMP6_PARAMPROB_HEADER,
     601           0 :                                     (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
     602           0 :                         goto bad;
     603             :                 }
     604           0 :                 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
     605             :                         sizeof(struct ip6_hbh));
     606           0 :                 if (hbh == NULL) {
     607           0 :                         ip6stat_inc(ip6s_tooshort);
     608           0 :                         goto bad;
     609             :                 }
     610           0 :                 *nxtp = hbh->ip6h_nxt;
     611             : 
     612             :                 /*
     613             :                  * accept the packet if a router alert option is included
     614             :                  * and we act as an IPv6 router.
     615             :                  */
     616           0 :                 if (rtalert != ~0 && ip6_forwarding && oursp != NULL)
     617           0 :                         *oursp = 1;
     618           0 :         } else
     619           0 :                 *nxtp = ip6->ip6_nxt;
     620             : 
     621             :         /*
     622             :          * Check that the amount of data in the buffers
     623             :          * is as at least much as the IPv6 header would have us expect.
     624             :          * Trim mbufs if longer than we expect.
     625             :          * Drop packet if shorter than we expect.
     626             :          */
     627           0 :         if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
     628           0 :                 ip6stat_inc(ip6s_tooshort);
     629           0 :                 m_freem(m);
     630           0 :                 goto bad;
     631             :         }
     632           0 :         if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
     633           0 :                 if (m->m_len == m->m_pkthdr.len) {
     634           0 :                         m->m_len = sizeof(struct ip6_hdr) + plen;
     635           0 :                         m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
     636           0 :                 } else {
     637           0 :                         m_adj(m,
     638           0 :                             sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
     639             :                 }
     640             :         }
     641             : 
     642           0 :         return (0);
     643             : 
     644             :  bad:
     645           0 :         *nxtp = IPPROTO_DONE;
     646           0 :         return (-1);
     647           0 : }
     648             : 
     649             : /* scan packet for RH0 routing header. Mostly stolen from pf.c:pf_test() */
     650             : int
     651           0 : ip6_check_rh0hdr(struct mbuf *m, int *offp)
     652             : {
     653           0 :         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
     654           0 :         struct ip6_rthdr rthdr;
     655           0 :         struct ip6_ext opt6;
     656           0 :         u_int8_t proto = ip6->ip6_nxt;
     657             :         int done = 0, lim, off, rh_cnt = 0;
     658             : 
     659           0 :         off = ((caddr_t)ip6 - m->m_data) + sizeof(struct ip6_hdr);
     660           0 :         lim = min(m->m_pkthdr.len, ntohs(ip6->ip6_plen) + sizeof(*ip6));
     661           0 :         do {
     662           0 :                 switch (proto) {
     663             :                 case IPPROTO_ROUTING:
     664           0 :                         *offp = off;
     665           0 :                         if (rh_cnt++) {
     666             :                                 /* more than one rh header present */
     667           0 :                                 return (1);
     668             :                         }
     669             : 
     670           0 :                         if (off + sizeof(rthdr) > lim) {
     671             :                                 /* packet to short to make sense */
     672           0 :                                 return (1);
     673             :                         }
     674             : 
     675           0 :                         m_copydata(m, off, sizeof(rthdr), (caddr_t)&rthdr);
     676             : 
     677           0 :                         if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
     678           0 :                                 *offp += offsetof(struct ip6_rthdr, ip6r_type);
     679           0 :                                 return (1);
     680             :                         }
     681             : 
     682           0 :                         off += (rthdr.ip6r_len + 1) * 8;
     683           0 :                         proto = rthdr.ip6r_nxt;
     684           0 :                         break;
     685             :                 case IPPROTO_AH:
     686             :                 case IPPROTO_HOPOPTS:
     687             :                 case IPPROTO_DSTOPTS:
     688             :                         /* get next header and header length */
     689           0 :                         if (off + sizeof(opt6) > lim) {
     690             :                                 /*
     691             :                                  * Packet to short to make sense, we could
     692             :                                  * reject the packet but as a router we
     693             :                                  * should not do that so forward it.
     694             :                                  */
     695           0 :                                 return (0);
     696             :                         }
     697             : 
     698           0 :                         m_copydata(m, off, sizeof(opt6), (caddr_t)&opt6);
     699             : 
     700           0 :                         if (proto == IPPROTO_AH)
     701           0 :                                 off += (opt6.ip6e_len + 2) * 4;
     702             :                         else
     703           0 :                                 off += (opt6.ip6e_len + 1) * 8;
     704           0 :                         proto = opt6.ip6e_nxt;
     705           0 :                         break;
     706             :                 case IPPROTO_FRAGMENT:
     707             :                 default:
     708             :                         /* end of header stack */
     709             :                         done = 1;
     710           0 :                         break;
     711             :                 }
     712           0 :         } while (!done);
     713             : 
     714           0 :         return (0);
     715           0 : }
     716             : 
     717             : /*
     718             :  * Hop-by-Hop options header processing. If a valid jumbo payload option is
     719             :  * included, the real payload length will be stored in plenp.
     720             :  *
     721             :  * rtalertp - XXX: should be stored in a more smart way
     722             :  */
     723             : int
     724           0 : ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp,
     725             :     int *offp)
     726             : {
     727           0 :         struct mbuf *m = *mp;
     728           0 :         int off = *offp, hbhlen;
     729             :         struct ip6_hbh *hbh;
     730             : 
     731             :         /* validation of the length of the header */
     732           0 :         IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
     733             :                 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
     734           0 :         if (hbh == NULL) {
     735           0 :                 ip6stat_inc(ip6s_tooshort);
     736           0 :                 return -1;
     737             :         }
     738           0 :         hbhlen = (hbh->ip6h_len + 1) << 3;
     739           0 :         IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
     740             :                 hbhlen);
     741           0 :         if (hbh == NULL) {
     742           0 :                 ip6stat_inc(ip6s_tooshort);
     743           0 :                 return -1;
     744             :         }
     745           0 :         off += hbhlen;
     746           0 :         hbhlen -= sizeof(struct ip6_hbh);
     747             : 
     748           0 :         if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
     749           0 :                                 hbhlen, rtalertp, plenp) < 0)
     750           0 :                 return (-1);
     751             : 
     752           0 :         *offp = off;
     753           0 :         *mp = m;
     754           0 :         return (0);
     755           0 : }
     756             : 
     757             : /*
     758             :  * Search header for all Hop-by-hop options and process each option.
     759             :  * This function is separate from ip6_hopopts_input() in order to
     760             :  * handle a case where the sending node itself process its hop-by-hop
     761             :  * options header. In such a case, the function is called from ip6_output().
     762             :  *
     763             :  * The function assumes that hbh header is located right after the IPv6 header
     764             :  * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
     765             :  * opthead + hbhlen is located in continuous memory region.
     766             :  */
     767             : int
     768           0 : ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
     769             :     u_int32_t *rtalertp, u_int32_t *plenp)
     770             : {
     771             :         struct ip6_hdr *ip6;
     772             :         int optlen = 0;
     773             :         u_int8_t *opt = opthead;
     774             :         u_int16_t rtalert_val;
     775             :         u_int32_t jumboplen;
     776             :         const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
     777             : 
     778           0 :         for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
     779           0 :                 switch (*opt) {
     780             :                 case IP6OPT_PAD1:
     781             :                         optlen = 1;
     782           0 :                         break;
     783             :                 case IP6OPT_PADN:
     784           0 :                         if (hbhlen < IP6OPT_MINLEN) {
     785           0 :                                 ip6stat_inc(ip6s_toosmall);
     786           0 :                                 goto bad;
     787             :                         }
     788           0 :                         optlen = *(opt + 1) + 2;
     789           0 :                         break;
     790             :                 case IP6OPT_ROUTER_ALERT:
     791             :                         /* XXX may need check for alignment */
     792           0 :                         if (hbhlen < IP6OPT_RTALERT_LEN) {
     793           0 :                                 ip6stat_inc(ip6s_toosmall);
     794           0 :                                 goto bad;
     795             :                         }
     796           0 :                         if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
     797             :                                 /* XXX stat */
     798           0 :                                 icmp6_error(m, ICMP6_PARAM_PROB,
     799             :                                     ICMP6_PARAMPROB_HEADER,
     800           0 :                                     erroff + opt + 1 - opthead);
     801           0 :                                 return (-1);
     802             :                         }
     803             :                         optlen = IP6OPT_RTALERT_LEN;
     804           0 :                         memcpy((caddr_t)&rtalert_val, (caddr_t)(opt + 2), 2);
     805           0 :                         *rtalertp = ntohs(rtalert_val);
     806           0 :                         break;
     807             :                 case IP6OPT_JUMBO:
     808             :                         /* XXX may need check for alignment */
     809           0 :                         if (hbhlen < IP6OPT_JUMBO_LEN) {
     810           0 :                                 ip6stat_inc(ip6s_toosmall);
     811           0 :                                 goto bad;
     812             :                         }
     813           0 :                         if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
     814             :                                 /* XXX stat */
     815           0 :                                 icmp6_error(m, ICMP6_PARAM_PROB,
     816             :                                     ICMP6_PARAMPROB_HEADER,
     817           0 :                                     erroff + opt + 1 - opthead);
     818           0 :                                 return (-1);
     819             :                         }
     820             :                         optlen = IP6OPT_JUMBO_LEN;
     821             : 
     822             :                         /*
     823             :                          * IPv6 packets that have non 0 payload length
     824             :                          * must not contain a jumbo payload option.
     825             :                          */
     826           0 :                         ip6 = mtod(m, struct ip6_hdr *);
     827           0 :                         if (ip6->ip6_plen) {
     828           0 :                                 ip6stat_inc(ip6s_badoptions);
     829           0 :                                 icmp6_error(m, ICMP6_PARAM_PROB,
     830             :                                     ICMP6_PARAMPROB_HEADER,
     831           0 :                                     erroff + opt - opthead);
     832           0 :                                 return (-1);
     833             :                         }
     834             : 
     835             :                         /*
     836             :                          * We may see jumbolen in unaligned location, so
     837             :                          * we'd need to perform memcpy().
     838             :                          */
     839           0 :                         memcpy(&jumboplen, opt + 2, sizeof(jumboplen));
     840           0 :                         jumboplen = (u_int32_t)htonl(jumboplen);
     841             : 
     842             : #if 1
     843             :                         /*
     844             :                          * if there are multiple jumbo payload options,
     845             :                          * *plenp will be non-zero and the packet will be
     846             :                          * rejected.
     847             :                          * the behavior may need some debate in ipngwg -
     848             :                          * multiple options does not make sense, however,
     849             :                          * there's no explicit mention in specification.
     850             :                          */
     851           0 :                         if (*plenp != 0) {
     852           0 :                                 ip6stat_inc(ip6s_badoptions);
     853           0 :                                 icmp6_error(m, ICMP6_PARAM_PROB,
     854             :                                     ICMP6_PARAMPROB_HEADER,
     855           0 :                                     erroff + opt + 2 - opthead);
     856           0 :                                 return (-1);
     857             :                         }
     858             : #endif
     859             : 
     860             :                         /*
     861             :                          * jumbo payload length must be larger than 65535.
     862             :                          */
     863           0 :                         if (jumboplen <= IPV6_MAXPACKET) {
     864           0 :                                 ip6stat_inc(ip6s_badoptions);
     865           0 :                                 icmp6_error(m, ICMP6_PARAM_PROB,
     866             :                                     ICMP6_PARAMPROB_HEADER,
     867           0 :                                     erroff + opt + 2 - opthead);
     868           0 :                                 return (-1);
     869             :                         }
     870           0 :                         *plenp = jumboplen;
     871             : 
     872           0 :                         break;
     873             :                 default:                /* unknown option */
     874           0 :                         if (hbhlen < IP6OPT_MINLEN) {
     875           0 :                                 ip6stat_inc(ip6s_toosmall);
     876           0 :                                 goto bad;
     877             :                         }
     878           0 :                         optlen = ip6_unknown_opt(opt, m,
     879           0 :                             erroff + opt - opthead);
     880           0 :                         if (optlen == -1)
     881           0 :                                 return (-1);
     882           0 :                         optlen += 2;
     883           0 :                         break;
     884             :                 }
     885             :         }
     886             : 
     887           0 :         return (0);
     888             : 
     889             :   bad:
     890           0 :         m_freem(m);
     891           0 :         return (-1);
     892           0 : }
     893             : 
     894             : /*
     895             :  * Unknown option processing.
     896             :  * The third argument `off' is the offset from the IPv6 header to the option,
     897             :  * which allows returning an ICMPv6 error even if the IPv6 header and the
     898             :  * option header are not continuous.
     899             :  */
     900             : int
     901           0 : ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
     902             : {
     903             :         struct ip6_hdr *ip6;
     904             : 
     905           0 :         switch (IP6OPT_TYPE(*optp)) {
     906             :         case IP6OPT_TYPE_SKIP: /* ignore the option */
     907           0 :                 return ((int)*(optp + 1));
     908             :         case IP6OPT_TYPE_DISCARD:       /* silently discard */
     909           0 :                 m_freem(m);
     910           0 :                 return (-1);
     911             :         case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
     912           0 :                 ip6stat_inc(ip6s_badoptions);
     913           0 :                 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
     914           0 :                 return (-1);
     915             :         case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
     916           0 :                 ip6stat_inc(ip6s_badoptions);
     917           0 :                 ip6 = mtod(m, struct ip6_hdr *);
     918           0 :                 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
     919           0 :                     (m->m_flags & (M_BCAST|M_MCAST)))
     920           0 :                         m_freem(m);
     921             :                 else
     922           0 :                         icmp6_error(m, ICMP6_PARAM_PROB,
     923             :                                     ICMP6_PARAMPROB_OPTION, off);
     924           0 :                 return (-1);
     925             :         }
     926             : 
     927             :         m_freem(m);             /* XXX: NOTREACHED */
     928             :         return (-1);
     929           0 : }
     930             : 
     931             : /*
     932             :  * Create the "control" list for this pcb.
     933             :  *
     934             :  * The routine will be called from upper layer handlers like udp_input().
     935             :  * Thus the routine assumes that the caller (udp_input) have already
     936             :  * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
     937             :  * very first mbuf on the mbuf chain.
     938             :  * We may want to add some infinite loop prevention or sanity checks for safety.
     939             :  * (This applies only when you are using KAME mbuf chain restriction, i.e.
     940             :  * you are using IP6_EXTHDR_CHECK() not m_pulldown())
     941             :  */
     942             : void
     943           0 : ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
     944             : {
     945           0 :         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
     946             : 
     947           0 :         if (in6p->inp_socket->so_options & SO_TIMESTAMP) {
     948           0 :                 struct timeval tv;
     949             : 
     950           0 :                 microtime(&tv);
     951           0 :                 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
     952             :                     SCM_TIMESTAMP, SOL_SOCKET);
     953           0 :                 if (*mp)
     954           0 :                         mp = &(*mp)->m_next;
     955           0 :         }
     956             : 
     957             :         /* RFC 2292 sec. 5 */
     958           0 :         if ((in6p->inp_flags & IN6P_PKTINFO) != 0) {
     959           0 :                 struct in6_pktinfo pi6;
     960           0 :                 memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr));
     961           0 :                 if (IN6_IS_SCOPE_EMBED(&pi6.ipi6_addr))
     962           0 :                         pi6.ipi6_addr.s6_addr16[1] = 0;
     963           0 :                 pi6.ipi6_ifindex = m ? m->m_pkthdr.ph_ifidx : 0;
     964           0 :                 *mp = sbcreatecontrol((caddr_t) &pi6,
     965             :                     sizeof(struct in6_pktinfo),
     966             :                     IPV6_PKTINFO, IPPROTO_IPV6);
     967           0 :                 if (*mp)
     968           0 :                         mp = &(*mp)->m_next;
     969           0 :         }
     970             : 
     971           0 :         if ((in6p->inp_flags & IN6P_HOPLIMIT) != 0) {
     972           0 :                 int hlim = ip6->ip6_hlim & 0xff;
     973           0 :                 *mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int),
     974             :                     IPV6_HOPLIMIT, IPPROTO_IPV6);
     975           0 :                 if (*mp)
     976           0 :                         mp = &(*mp)->m_next;
     977           0 :         }
     978             : 
     979           0 :         if ((in6p->inp_flags & IN6P_TCLASS) != 0) {
     980             :                 u_int32_t flowinfo;
     981           0 :                 int tclass;
     982             : 
     983           0 :                 flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK);
     984           0 :                 flowinfo >>= 20;
     985             : 
     986           0 :                 tclass = flowinfo & 0xff;
     987           0 :                 *mp = sbcreatecontrol((caddr_t)&tclass, sizeof(tclass),
     988             :                     IPV6_TCLASS, IPPROTO_IPV6);
     989           0 :                 if (*mp)
     990           0 :                         mp = &(*mp)->m_next;
     991           0 :         }
     992             : 
     993             :         /*
     994             :          * IPV6_HOPOPTS socket option.  Recall that we required super-user
     995             :          * privilege for the option (see ip6_ctloutput), but it might be too
     996             :          * strict, since there might be some hop-by-hop options which can be
     997             :          * returned to normal user.
     998             :          * See also RFC 2292 section 6 (or RFC 3542 section 8).
     999             :          */
    1000           0 :         if ((in6p->inp_flags & IN6P_HOPOPTS) != 0) {
    1001             :                 /*
    1002             :                  * Check if a hop-by-hop options header is contained in the
    1003             :                  * received packet, and if so, store the options as ancillary
    1004             :                  * data. Note that a hop-by-hop options header must be
    1005             :                  * just after the IPv6 header, which is assured through the
    1006             :                  * IPv6 input processing.
    1007             :                  */
    1008           0 :                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
    1009           0 :                 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
    1010             :                         struct ip6_hbh *hbh;
    1011             :                         int hbhlen = 0;
    1012             :                         struct mbuf *ext;
    1013             : 
    1014           0 :                         ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
    1015             :                             ip6->ip6_nxt);
    1016           0 :                         if (ext == NULL) {
    1017           0 :                                 ip6stat_inc(ip6s_tooshort);
    1018           0 :                                 return;
    1019             :                         }
    1020           0 :                         hbh = mtod(ext, struct ip6_hbh *);
    1021           0 :                         hbhlen = (hbh->ip6h_len + 1) << 3;
    1022           0 :                         if (hbhlen != ext->m_len) {
    1023           0 :                                 m_freem(ext);
    1024           0 :                                 ip6stat_inc(ip6s_tooshort);
    1025           0 :                                 return;
    1026             :                         }
    1027             : 
    1028             :                         /*
    1029             :                          * XXX: We copy the whole header even if a
    1030             :                          * jumbo payload option is included, the option which
    1031             :                          * is to be removed before returning according to
    1032             :                          * RFC2292.
    1033             :                          * Note: this constraint is removed in RFC3542.
    1034             :                          */
    1035           0 :                         *mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
    1036             :                             IPV6_HOPOPTS,
    1037             :                             IPPROTO_IPV6);
    1038           0 :                         if (*mp)
    1039           0 :                                 mp = &(*mp)->m_next;
    1040           0 :                         m_freem(ext);
    1041           0 :                 }
    1042           0 :         }
    1043             : 
    1044             :         /* IPV6_DSTOPTS and IPV6_RTHDR socket options */
    1045           0 :         if ((in6p->inp_flags & (IN6P_RTHDR | IN6P_DSTOPTS)) != 0) {
    1046           0 :                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
    1047           0 :                 int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);
    1048             : 
    1049             :                 /*
    1050             :                  * Search for destination options headers or routing
    1051             :                  * header(s) through the header chain, and stores each
    1052             :                  * header as ancillary data.
    1053             :                  * Note that the order of the headers remains in
    1054             :                  * the chain of ancillary data.
    1055             :                  */
    1056           0 :                 while (1) {     /* is explicit loop prevention necessary? */
    1057             :                         struct ip6_ext *ip6e = NULL;
    1058             :                         int elen;
    1059             :                         struct mbuf *ext = NULL;
    1060             : 
    1061             :                         /*
    1062             :                          * if it is not an extension header, don't try to
    1063             :                          * pull it from the chain.
    1064             :                          */
    1065           0 :                         switch (nxt) {
    1066             :                         case IPPROTO_DSTOPTS:
    1067             :                         case IPPROTO_ROUTING:
    1068             :                         case IPPROTO_HOPOPTS:
    1069             :                         case IPPROTO_AH: /* is it possible? */
    1070             :                                 break;
    1071             :                         default:
    1072           0 :                                 goto loopend;
    1073             :                         }
    1074             : 
    1075           0 :                         ext = ip6_pullexthdr(m, off, nxt);
    1076           0 :                         if (ext == NULL) {
    1077           0 :                                 ip6stat_inc(ip6s_tooshort);
    1078           0 :                                 return;
    1079             :                         }
    1080           0 :                         ip6e = mtod(ext, struct ip6_ext *);
    1081           0 :                         if (nxt == IPPROTO_AH)
    1082           0 :                                 elen = (ip6e->ip6e_len + 2) << 2;
    1083             :                         else
    1084           0 :                                 elen = (ip6e->ip6e_len + 1) << 3;
    1085           0 :                         if (elen != ext->m_len) {
    1086           0 :                                 m_freem(ext);
    1087           0 :                                 ip6stat_inc(ip6s_tooshort);
    1088           0 :                                 return;
    1089             :                         }
    1090             : 
    1091           0 :                         switch (nxt) {
    1092             :                         case IPPROTO_DSTOPTS:
    1093           0 :                                 if (!(in6p->inp_flags & IN6P_DSTOPTS))
    1094             :                                         break;
    1095             : 
    1096           0 :                                 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
    1097             :                                     IPV6_DSTOPTS,
    1098             :                                     IPPROTO_IPV6);
    1099           0 :                                 if (*mp)
    1100           0 :                                         mp = &(*mp)->m_next;
    1101             :                                 break;
    1102             : 
    1103             :                         case IPPROTO_ROUTING:
    1104           0 :                                 if (!(in6p->inp_flags & IN6P_RTHDR))
    1105             :                                         break;
    1106             : 
    1107           0 :                                 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
    1108             :                                     IPV6_RTHDR,
    1109             :                                     IPPROTO_IPV6);
    1110           0 :                                 if (*mp)
    1111           0 :                                         mp = &(*mp)->m_next;
    1112             :                                 break;
    1113             : 
    1114             :                         case IPPROTO_HOPOPTS:
    1115             :                         case IPPROTO_AH: /* is it possible? */
    1116             :                                 break;
    1117             : 
    1118             :                         default:
    1119             :                                 /*
    1120             :                                  * other cases have been filtered in the above.
    1121             :                                  * none will visit this case.  here we supply
    1122             :                                  * the code just in case (nxt overwritten or
    1123             :                                  * other cases).
    1124             :                                  */
    1125           0 :                                 m_freem(ext);
    1126           0 :                                 goto loopend;
    1127             : 
    1128             :                         }
    1129             : 
    1130             :                         /* proceed with the next header. */
    1131           0 :                         off += elen;
    1132           0 :                         nxt = ip6e->ip6e_nxt;
    1133             :                         ip6e = NULL;
    1134           0 :                         m_freem(ext);
    1135             :                         ext = NULL;
    1136           0 :                 }
    1137             : loopend:
    1138             :                 ;
    1139           0 :         }
    1140           0 : }
    1141             : 
    1142             : /*
    1143             :  * pull single extension header from mbuf chain.  returns single mbuf that
    1144             :  * contains the result, or NULL on error.
    1145             :  */
    1146             : struct mbuf *
    1147           0 : ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
    1148             : {
    1149           0 :         struct ip6_ext ip6e;
    1150             :         size_t elen;
    1151             :         struct mbuf *n;
    1152             : 
    1153             : #ifdef DIAGNOSTIC
    1154           0 :         switch (nxt) {
    1155             :         case IPPROTO_DSTOPTS:
    1156             :         case IPPROTO_ROUTING:
    1157             :         case IPPROTO_HOPOPTS:
    1158             :         case IPPROTO_AH: /* is it possible? */
    1159             :                 break;
    1160             :         default:
    1161           0 :                 printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
    1162           0 :         }
    1163             : #endif
    1164             : 
    1165           0 :         m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
    1166           0 :         if (nxt == IPPROTO_AH)
    1167           0 :                 elen = (ip6e.ip6e_len + 2) << 2;
    1168             :         else
    1169           0 :                 elen = (ip6e.ip6e_len + 1) << 3;
    1170             : 
    1171           0 :         MGET(n, M_DONTWAIT, MT_DATA);
    1172           0 :         if (n && elen >= MLEN) {
    1173           0 :                 MCLGET(n, M_DONTWAIT);
    1174           0 :                 if ((n->m_flags & M_EXT) == 0) {
    1175           0 :                         m_free(n);
    1176             :                         n = NULL;
    1177           0 :                 }
    1178             :         }
    1179           0 :         if (!n)
    1180           0 :                 return NULL;
    1181             : 
    1182           0 :         n->m_len = 0;
    1183           0 :         if (elen >= M_TRAILINGSPACE(n)) {
    1184           0 :                 m_free(n);
    1185           0 :                 return NULL;
    1186             :         }
    1187             : 
    1188           0 :         m_copydata(m, off, elen, mtod(n, caddr_t));
    1189           0 :         n->m_len = elen;
    1190           0 :         return n;
    1191           0 : }
    1192             : 
    1193             : /*
    1194             :  * Get offset to the previous header followed by the header
    1195             :  * currently processed.
    1196             :  */
    1197             : int
    1198           0 : ip6_get_prevhdr(struct mbuf *m, int off)
    1199             : {
    1200           0 :         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
    1201             : 
    1202           0 :         if (off == sizeof(struct ip6_hdr)) {
    1203           0 :                 return offsetof(struct ip6_hdr, ip6_nxt);
    1204           0 :         } else if (off < sizeof(struct ip6_hdr)) {
    1205           0 :                 panic("%s: off < sizeof(struct ip6_hdr)", __func__);
    1206             :         } else {
    1207             :                 int len, nlen, nxt;
    1208           0 :                 struct ip6_ext ip6e;
    1209             : 
    1210           0 :                 nxt = ip6->ip6_nxt;
    1211             :                 len = sizeof(struct ip6_hdr);
    1212             :                 nlen = 0;
    1213           0 :                 while (len < off) {
    1214           0 :                         m_copydata(m, len, sizeof(ip6e), (caddr_t)&ip6e);
    1215             : 
    1216           0 :                         switch (nxt) {
    1217             :                         case IPPROTO_FRAGMENT:
    1218             :                                 nlen = sizeof(struct ip6_frag);
    1219           0 :                                 break;
    1220             :                         case IPPROTO_AH:
    1221           0 :                                 nlen = (ip6e.ip6e_len + 2) << 2;
    1222           0 :                                 break;
    1223             :                         default:
    1224           0 :                                 nlen = (ip6e.ip6e_len + 1) << 3;
    1225           0 :                                 break;
    1226             :                         }
    1227           0 :                         len += nlen;
    1228           0 :                         nxt = ip6e.ip6e_nxt;
    1229             :                 }
    1230             : 
    1231           0 :                 return (len - nlen);
    1232           0 :         }
    1233           0 : }
    1234             : 
    1235             : /*
    1236             :  * get next header offset.  m will be retained.
    1237             :  */
    1238             : int
    1239           0 : ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp)
    1240             : {
    1241           0 :         struct ip6_hdr ip6;
    1242           0 :         struct ip6_ext ip6e;
    1243           0 :         struct ip6_frag fh;
    1244             : 
    1245             :         /* just in case */
    1246           0 :         if (m == NULL)
    1247           0 :                 panic("ip6_nexthdr: m == NULL");
    1248           0 :         if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off)
    1249           0 :                 return -1;
    1250             : 
    1251           0 :         switch (proto) {
    1252             :         case IPPROTO_IPV6:
    1253           0 :                 if (m->m_pkthdr.len < off + sizeof(ip6))
    1254           0 :                         return -1;
    1255           0 :                 m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6);
    1256           0 :                 if (nxtp)
    1257           0 :                         *nxtp = ip6.ip6_nxt;
    1258           0 :                 off += sizeof(ip6);
    1259           0 :                 return off;
    1260             : 
    1261             :         case IPPROTO_FRAGMENT:
    1262             :                 /*
    1263             :                  * terminate parsing if it is not the first fragment,
    1264             :                  * it does not make sense to parse through it.
    1265             :                  */
    1266           0 :                 if (m->m_pkthdr.len < off + sizeof(fh))
    1267           0 :                         return -1;
    1268           0 :                 m_copydata(m, off, sizeof(fh), (caddr_t)&fh);
    1269           0 :                 if ((fh.ip6f_offlg & IP6F_OFF_MASK) != 0)
    1270           0 :                         return -1;
    1271           0 :                 if (nxtp)
    1272           0 :                         *nxtp = fh.ip6f_nxt;
    1273           0 :                 off += sizeof(struct ip6_frag);
    1274           0 :                 return off;
    1275             : 
    1276             :         case IPPROTO_AH:
    1277           0 :                 if (m->m_pkthdr.len < off + sizeof(ip6e))
    1278           0 :                         return -1;
    1279           0 :                 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
    1280           0 :                 if (nxtp)
    1281           0 :                         *nxtp = ip6e.ip6e_nxt;
    1282           0 :                 off += (ip6e.ip6e_len + 2) << 2;
    1283           0 :                 if (m->m_pkthdr.len < off)
    1284           0 :                         return -1;
    1285           0 :                 return off;
    1286             : 
    1287             :         case IPPROTO_HOPOPTS:
    1288             :         case IPPROTO_ROUTING:
    1289             :         case IPPROTO_DSTOPTS:
    1290           0 :                 if (m->m_pkthdr.len < off + sizeof(ip6e))
    1291           0 :                         return -1;
    1292           0 :                 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
    1293           0 :                 if (nxtp)
    1294           0 :                         *nxtp = ip6e.ip6e_nxt;
    1295           0 :                 off += (ip6e.ip6e_len + 1) << 3;
    1296           0 :                 if (m->m_pkthdr.len < off)
    1297           0 :                         return -1;
    1298           0 :                 return off;
    1299             : 
    1300             :         case IPPROTO_NONE:
    1301             :         case IPPROTO_ESP:
    1302             :         case IPPROTO_IPCOMP:
    1303             :                 /* give up */
    1304           0 :                 return -1;
    1305             : 
    1306             :         default:
    1307           0 :                 return -1;
    1308             :         }
    1309             : 
    1310             :         return -1;
    1311           0 : }
    1312             : 
    1313             : /*
    1314             :  * get offset for the last header in the chain.  m will be kept untainted.
    1315             :  */
    1316             : int
    1317           0 : ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp)
    1318             : {
    1319             :         int newoff;
    1320           0 :         int nxt;
    1321             : 
    1322           0 :         if (!nxtp) {
    1323           0 :                 nxt = -1;
    1324             :                 nxtp = &nxt;
    1325           0 :         }
    1326           0 :         while (1) {
    1327           0 :                 newoff = ip6_nexthdr(m, off, proto, nxtp);
    1328           0 :                 if (newoff < 0)
    1329           0 :                         return off;
    1330           0 :                 else if (newoff < off)
    1331           0 :                         return -1;      /* invalid */
    1332           0 :                 else if (newoff == off)
    1333           0 :                         return newoff;
    1334             : 
    1335             :                 off = newoff;
    1336           0 :                 proto = *nxtp;
    1337             :         }
    1338           0 : }
    1339             : 
    1340             : /*
    1341             :  * System control for IP6
    1342             :  */
    1343             : 
    1344             : const u_char inet6ctlerrmap[PRC_NCMDS] = {
    1345             :         0,              0,              0,              0,
    1346             :         0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
    1347             :         EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
    1348             :         EMSGSIZE,       EHOSTUNREACH,   0,              0,
    1349             :         0,              0,              0,              0,
    1350             :         ENOPROTOOPT
    1351             : };
    1352             : 
    1353             : int *ipv6ctl_vars[IPV6CTL_MAXID] = IPV6CTL_VARS;
    1354             : 
    1355             : int
    1356           0 : ip6_sysctl_ip6stat(void *oldp, size_t *oldlenp, void *newp)
    1357             : {
    1358             :         struct ip6stat *ip6stat;
    1359             :         int ret;
    1360             : 
    1361             :         CTASSERT(sizeof(*ip6stat) == (ip6s_ncounters * sizeof(uint64_t)));
    1362             : 
    1363           0 :         ip6stat = malloc(sizeof(*ip6stat), M_TEMP, M_WAITOK);
    1364           0 :         counters_read(ip6counters, (uint64_t *)ip6stat, ip6s_ncounters);
    1365           0 :         ret = sysctl_rdstruct(oldp, oldlenp, newp,
    1366             :             ip6stat, sizeof(*ip6stat));
    1367           0 :         free(ip6stat, M_TEMP, sizeof(*ip6stat));
    1368             : 
    1369           0 :         return (ret);
    1370             : }
    1371             : 
    1372             : int
    1373           0 : ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
    1374             : {
    1375             :         struct ifnet *ifp;
    1376           0 :         uint8_t oldkey[IP6_SOIIKEY_LEN];
    1377             :         int error;
    1378             : 
    1379           0 :         error = suser(curproc);
    1380           0 :         if (error != 0)
    1381           0 :                 return (error);
    1382             : 
    1383           0 :         memcpy(oldkey, ip6_soiikey, sizeof(oldkey));
    1384             : 
    1385           0 :         error = sysctl_struct(oldp, oldlenp, newp, newlen, ip6_soiikey,
    1386             :             sizeof(ip6_soiikey));
    1387             : 
    1388           0 :         if (!error && memcmp(ip6_soiikey, oldkey, sizeof(oldkey)) != 0) {
    1389           0 :                 TAILQ_FOREACH(ifp, &ifnet, if_list) {
    1390           0 :                         if (ifp->if_flags & IFF_LOOPBACK)
    1391             :                                 continue;
    1392           0 :                         NET_LOCK();
    1393           0 :                         in6_soiiupdate(ifp);
    1394           0 :                         NET_UNLOCK();
    1395           0 :                 }
    1396             :         }
    1397             : 
    1398           0 :         return (error);
    1399           0 : }
    1400             : 
    1401             : int
    1402           0 : ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
    1403             :     void *newp, size_t newlen)
    1404             : {
    1405             : #ifdef MROUTING
    1406             :         extern int ip6_mrtproto;
    1407             :         extern struct mrt6stat mrt6stat;
    1408             : #endif
    1409             :         int error;
    1410             : 
    1411             :         /* Almost all sysctl names at this level are terminal. */
    1412           0 :         if (namelen != 1 && name[0] != IPV6CTL_IFQUEUE)
    1413           0 :                 return (ENOTDIR);
    1414             : 
    1415           0 :         switch (name[0]) {
    1416             :         case IPV6CTL_DAD_PENDING:
    1417           0 :                 return sysctl_rdint(oldp, oldlenp, newp, ip6_dad_pending);
    1418             :         case IPV6CTL_STATS:
    1419           0 :                 return (ip6_sysctl_ip6stat(oldp, oldlenp, newp));
    1420             : #ifdef MROUTING
    1421             :         case IPV6CTL_MRTSTATS:
    1422           0 :                 if (newp != NULL)
    1423           0 :                         return (EPERM);
    1424           0 :                 NET_LOCK();
    1425           0 :                 error = sysctl_struct(oldp, oldlenp, newp, newlen,
    1426             :                     &mrt6stat, sizeof(mrt6stat));
    1427           0 :                 NET_UNLOCK();
    1428           0 :                 return (error);
    1429             :         case IPV6CTL_MRTPROTO:
    1430           0 :                 return sysctl_rdint(oldp, oldlenp, newp, ip6_mrtproto);
    1431             :         case IPV6CTL_MRTMIF:
    1432           0 :                 if (newp)
    1433           0 :                         return (EPERM);
    1434           0 :                 NET_LOCK();
    1435           0 :                 error = mrt6_sysctl_mif(oldp, oldlenp);
    1436           0 :                 NET_UNLOCK();
    1437           0 :                 return (error);
    1438             :         case IPV6CTL_MRTMFC:
    1439           0 :                 if (newp)
    1440           0 :                         return (EPERM);
    1441           0 :                 NET_LOCK();
    1442           0 :                 error = mrt6_sysctl_mfc(oldp, oldlenp);
    1443           0 :                 NET_UNLOCK();
    1444           0 :                 return (error);
    1445             : #else
    1446             :         case IPV6CTL_MRTSTATS:
    1447             :         case IPV6CTL_MRTPROTO:
    1448             :         case IPV6CTL_MRTMIF:
    1449             :         case IPV6CTL_MRTMFC:
    1450             :                 return (EOPNOTSUPP);
    1451             : #endif
    1452             :         case IPV6CTL_MTUDISCTIMEOUT:
    1453           0 :                 NET_LOCK();
    1454           0 :                 error = sysctl_int(oldp, oldlenp, newp, newlen,
    1455             :                     &ip6_mtudisc_timeout);
    1456           0 :                 if (icmp6_mtudisc_timeout_q != NULL)
    1457           0 :                         rt_timer_queue_change(icmp6_mtudisc_timeout_q,
    1458           0 :                             ip6_mtudisc_timeout);
    1459           0 :                 NET_UNLOCK();
    1460           0 :                 return (error);
    1461             :         case IPV6CTL_IFQUEUE:
    1462           0 :                 return (sysctl_niq(name + 1, namelen - 1,
    1463             :                     oldp, oldlenp, newp, newlen, &ip6intrq));
    1464             :         case IPV6CTL_SOIIKEY:
    1465           0 :                 return (ip6_sysctl_soiikey(oldp, oldlenp, newp, newlen));
    1466             :         default:
    1467           0 :                 if (name[0] < IPV6CTL_MAXID) {
    1468           0 :                         NET_LOCK();
    1469           0 :                         error = sysctl_int_arr(ipv6ctl_vars, name, namelen,
    1470             :                             oldp, oldlenp, newp, newlen);
    1471           0 :                         NET_UNLOCK();
    1472           0 :                         return (error);
    1473             :                 }
    1474           0 :                 return (EOPNOTSUPP);
    1475             :         }
    1476             :         /* NOTREACHED */
    1477           0 : }
    1478             : 
    1479             : void
    1480           0 : ip6_send_dispatch(void *xmq)
    1481             : {
    1482           0 :         struct mbuf_queue *mq = xmq;
    1483             :         struct mbuf *m;
    1484           0 :         struct mbuf_list ml;
    1485             : 
    1486           0 :         mq_delist(mq, &ml);
    1487           0 :         if (ml_empty(&ml))
    1488           0 :                 return;
    1489             : 
    1490           0 :         NET_RLOCK();
    1491           0 :         while ((m = ml_dequeue(&ml)) != NULL) {
    1492             :                 /*
    1493             :                  * To avoid a "too big" situation at an intermediate router and
    1494             :                  * the path MTU discovery process, specify the IPV6_MINMTU
    1495             :                  * flag.  Note that only echo and node information replies are
    1496             :                  * affected, since the length of ICMP6 errors is limited to the
    1497             :                  * minimum MTU.
    1498             :                  */
    1499           0 :                 ip6_output(m, NULL, NULL, IPV6_MINMTU, NULL, NULL);
    1500             :         }
    1501           0 :         NET_RUNLOCK();
    1502           0 : }
    1503             : 
    1504             : void
    1505           0 : ip6_send(struct mbuf *m)
    1506             : {
    1507           0 :         mq_enqueue(&ip6send_mq, m);
    1508           0 :         task_add(net_tq(0), &ip6send_task);
    1509           0 : }

Generated by: LCOV version 1.13