The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet6/ipsec.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ipsec.c,v 1.133 2008/10/11 13:40:58 pooka Exp $        */
    2 /*      $KAME: ipsec.c,v 1.136 2002/05/19 00:36:39 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  * IPsec controller part.
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.133 2008/10/11 13:40:58 pooka Exp $");
   39 
   40 #include "opt_inet.h"
   41 #include "opt_ipsec.h"
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/malloc.h>
   46 #include <sys/mbuf.h>
   47 #include <sys/domain.h>
   48 #include <sys/protosw.h>
   49 #include <sys/socket.h>
   50 #include <sys/socketvar.h>
   51 #include <sys/errno.h>
   52 #include <sys/time.h>
   53 #include <sys/kernel.h>
   54 #include <sys/syslog.h>
   55 #include <sys/sysctl.h>
   56 #include <sys/once.h>
   57 #include <sys/uidinfo.h>
   58 
   59 #include <net/if.h>
   60 #include <net/route.h>
   61 
   62 #include <netinet/in.h>
   63 #include <netinet/in_systm.h>
   64 #include <netinet/ip.h>
   65 #include <netinet/ip_var.h>
   66 #include <netinet/ip_private.h>
   67 #include <netinet/in_var.h>
   68 #include <netinet/udp.h>
   69 #include <netinet/udp_var.h>
   70 #include <netinet/ip_ecn.h>
   71 #include <netinet/tcp.h>
   72 #include <netinet/ip_icmp.h>
   73 
   74 #include <netinet/ip6.h>
   75 #ifdef INET6
   76 #include <netinet6/ip6_var.h>
   77 #include <netinet6/ip6_private.h>
   78 #endif
   79 #include <netinet/in_pcb.h>
   80 #ifdef INET6
   81 #include <netinet6/in6_pcb.h>
   82 #include <netinet/icmp6.h>
   83 #include <netinet6/scope6_var.h>
   84 #endif
   85 
   86 #include <netinet6/ipsec.h>
   87 #include <netinet6/ipsec_private.h>
   88 #include <netinet6/ah.h>
   89 #ifdef IPSEC_ESP
   90 #include <netinet6/esp.h>
   91 #endif
   92 #include <netinet6/ipcomp.h>
   93 #include <netkey/key.h>
   94 #include <netkey/keydb.h>
   95 #include <netkey/key_debug.h>
   96 
   97 #include <net/net_osdep.h>
   98 
   99 #ifdef IPSEC_DEBUG
  100 int ipsec_debug = 1;
  101 #else
  102 int ipsec_debug = 0;
  103 #endif
  104 
  105 percpu_t *ipsecstat_percpu;
  106 int ip4_ah_cleartos = 1;
  107 int ip4_ah_offsetmask = 0;      /* maybe IP_DF? */
  108 int ip4_ipsec_dfbit = 2;        /* DF bit on encap. 0: clear 1: set 2: copy */
  109 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
  110 int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
  111 int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
  112 int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
  113 struct secpolicy *ip4_def_policy;
  114 int ip4_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
  115 
  116 #ifdef INET6
  117 percpu_t *ipsec6stat_percpu;
  118 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
  119 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
  120 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
  121 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
  122 struct secpolicy *ip6_def_policy;
  123 int ip6_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
  124 
  125 #endif /* INET6 */
  126 
  127 u_int ipsec_spdgen = 1;         /* SPD generation # */
  128 
  129 #ifdef SADB_X_EXT_TAG
  130 static struct pf_tag *ipsec_get_tag __P((struct mbuf *));
  131 #endif
  132 static struct secpolicy *ipsec_checkpcbcache __P((struct mbuf *,
  133         struct inpcbpolicy *, int));
  134 static int ipsec_fillpcbcache __P((struct inpcbpolicy *, struct mbuf *,
  135         struct secpolicy *, int));
  136 static int ipsec_invalpcbcache __P((struct inpcbpolicy *, int));
  137 static int ipsec_setspidx_mbuf
  138         __P((struct secpolicyindex *, int, struct mbuf *, int));
  139 static int ipsec_setspidx __P((struct mbuf *, struct secpolicyindex *, int));
  140 static void ipsec4_get_ulp __P((struct mbuf *, struct secpolicyindex *, int));
  141 static int ipsec4_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
  142 #ifdef INET6
  143 static void ipsec6_get_ulp __P((struct mbuf *, struct secpolicyindex *, int));
  144 static int ipsec6_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
  145 #endif
  146 static struct inpcbpolicy *ipsec_newpcbpolicy __P((void));
  147 static void ipsec_delpcbpolicy __P((struct inpcbpolicy *));
  148 #if 0
  149 static int ipsec_deepcopy_pcbpolicy __P((struct inpcbpolicy *));
  150 #endif
  151 static struct secpolicy *ipsec_deepcopy_policy __P((struct secpolicy *));
  152 static int ipsec_set_policy
  153         __P((struct secpolicy **, int, void *, size_t, int));
  154 static int ipsec_get_policy __P((struct secpolicy *, struct mbuf **));
  155 static void vshiftl __P((unsigned char *, int, int));
  156 static int ipsec_in_reject __P((struct secpolicy *, struct mbuf *));
  157 static size_t ipsec_hdrsiz __P((struct secpolicy *));
  158 #ifdef INET
  159 static struct mbuf *ipsec4_splithdr __P((struct mbuf *));
  160 #endif
  161 #ifdef INET6
  162 static struct mbuf *ipsec6_splithdr __P((struct mbuf *));
  163 #endif
  164 #ifdef INET
  165 static int ipsec4_encapsulate __P((struct mbuf *, struct secasvar *));
  166 #endif
  167 #ifdef INET6
  168 static int ipsec6_encapsulate __P((struct mbuf *, struct secasvar *));
  169 #endif
  170 static struct m_tag *ipsec_addaux __P((struct mbuf *));
  171 static struct m_tag *ipsec_findaux __P((struct mbuf *));
  172 static void ipsec_optaux __P((struct mbuf *, struct m_tag *));
  173 #ifdef INET
  174 static int ipsec4_checksa __P((struct ipsecrequest *,
  175         struct ipsec_output_state *));
  176 #endif
  177 #ifdef INET6
  178 static int ipsec6_checksa __P((struct ipsecrequest *,
  179         struct ipsec_output_state *, int));
  180 #endif
  181 
  182 #ifdef INET
  183 static int
  184 ipsec4_do_init(void)
  185 {
  186 
  187         ipsecstat_percpu = percpu_alloc(sizeof(uint64_t) * IPSEC_NSTATS);
  188         return (0);
  189 }
  190 
  191 void
  192 ipsec4_init(void)
  193 {
  194         static ONCE_DECL(ipsec4_init_once);
  195 
  196         RUN_ONCE(&ipsec4_init_once, ipsec4_do_init);
  197 }
  198 #endif /* INET */
  199 
  200 #ifdef INET6
  201 static int
  202 ipsec6_do_init(void)
  203 {
  204 
  205         ipsec6stat_percpu = percpu_alloc(sizeof(uint64_t) * IPSEC_NSTATS);
  206         return (0);
  207 }
  208 
  209 void
  210 ipsec6_init(void)
  211 {
  212         static ONCE_DECL(ipsec6_init_once);
  213 
  214         RUN_ONCE(&ipsec6_init_once, ipsec6_do_init);
  215 }
  216 #endif /* INET6 */
  217 
  218 /*
  219  * try to validate and use cached policy on a pcb.
  220  */
  221 static struct secpolicy *
  222 ipsec_checkpcbcache(struct mbuf *m, struct inpcbpolicy *pcbsp, int dir)
  223 {
  224         struct secpolicyindex spidx;
  225         struct bintime bt;
  226 
  227         switch (dir) {
  228         case IPSEC_DIR_INBOUND:
  229         case IPSEC_DIR_OUTBOUND:
  230         case IPSEC_DIR_ANY:
  231                 break;
  232         default:
  233                 return NULL;
  234         }
  235 #ifdef DIAGNOSTIC
  236         if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
  237                 panic("dir too big in ipsec_checkpcbcache");
  238 #endif
  239         /* SPD table change invalidates all the caches */
  240         if (ipsec_spdgen != pcbsp->sp_cache[dir].cachegen) {
  241                 ipsec_invalpcbcache(pcbsp, dir);
  242                 return NULL;
  243         }
  244         if (!pcbsp->sp_cache[dir].cachesp)
  245                 return NULL;
  246         if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) {
  247                 ipsec_invalpcbcache(pcbsp, dir);
  248                 return NULL;
  249         }
  250         if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) {
  251                 if (!pcbsp->sp_cache[dir].cachesp)
  252                         return NULL;
  253                 if (ipsec_setspidx(m, &spidx, 1) != 0)
  254                         return NULL;
  255 
  256                 /*
  257          * We have to make an exact match here since the cached rule
  258          * might have lower priority than a rule that would otherwise
  259          * have matched the packet. 
  260          */
  261 
  262                 if (bcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx, sizeof(spidx))) 
  263                         return NULL;
  264                 
  265         } else {
  266                 /*
  267                  * The pcb is connected, and the L4 code is sure that:
  268                  * - outgoing side uses inp_[lf]addr
  269                  * - incoming side looks up policy after inpcb lookup
  270                  * and address pair is known to be stable.  We do not need
  271                  * to generate spidx again, nor check the address match again.
  272                  *
  273                  * For IPv4/v6 SOCK_STREAM sockets, this assumption holds
  274                  * and there are calls to ipsec_pcbconn() from in_pcbconnect().
  275                  */
  276         }
  277 
  278         getbinuptime(&bt);
  279         pcbsp->sp_cache[dir].cachesp->lastused = bt.sec;
  280         pcbsp->sp_cache[dir].cachesp->refcnt++;
  281         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  282                 printf("DP ipsec_checkpcbcache cause refcnt++:%d SP:%p\n",
  283                 pcbsp->sp_cache[dir].cachesp->refcnt,
  284                 pcbsp->sp_cache[dir].cachesp));
  285         return pcbsp->sp_cache[dir].cachesp;
  286 }
  287 
  288 static int
  289 ipsec_fillpcbcache(struct inpcbpolicy *pcbsp, struct mbuf *m, 
  290         struct secpolicy *sp, int dir)
  291 {
  292 
  293         switch (dir) {
  294         case IPSEC_DIR_INBOUND:
  295         case IPSEC_DIR_OUTBOUND:
  296                 break;
  297         default:
  298                 return EINVAL;
  299         }
  300 #ifdef DIAGNOSTIC
  301         if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
  302                 panic("dir too big in ipsec_checkpcbcache");
  303 #endif
  304 
  305         if (pcbsp->sp_cache[dir].cachesp)
  306                 key_freesp(pcbsp->sp_cache[dir].cachesp);
  307         pcbsp->sp_cache[dir].cachesp = NULL;
  308         pcbsp->sp_cache[dir].cachehint = IPSEC_PCBHINT_MAYBE;
  309         if (ipsec_setspidx(m, &pcbsp->sp_cache[dir].cacheidx, 1) != 0) {
  310                 return EINVAL;
  311         }
  312         pcbsp->sp_cache[dir].cachesp = sp;
  313         if (pcbsp->sp_cache[dir].cachesp) {
  314                 pcbsp->sp_cache[dir].cachesp->refcnt++;
  315                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  316                         printf("DP ipsec_fillpcbcache cause refcnt++:%d SP:%p\n",
  317                         pcbsp->sp_cache[dir].cachesp->refcnt,
  318                         pcbsp->sp_cache[dir].cachesp));
  319 
  320                 /*
  321                  * If the PCB is connected, we can remember a hint to
  322                  * possibly short-circuit IPsec processing in other places.
  323                  */
  324                 if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) {
  325                         switch (pcbsp->sp_cache[dir].cachesp->policy) {
  326                         case IPSEC_POLICY_NONE:
  327                         case IPSEC_POLICY_BYPASS:
  328                                 pcbsp->sp_cache[dir].cachehint =
  329                                     IPSEC_PCBHINT_NO;
  330                                 break;
  331                         default:
  332                                 pcbsp->sp_cache[dir].cachehint =
  333                                     IPSEC_PCBHINT_YES;
  334                         }
  335                 }
  336         }
  337         pcbsp->sp_cache[dir].cachegen = ipsec_spdgen;
  338 
  339         return 0;
  340 }
  341 
  342 static int
  343 ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir)
  344 {
  345         int i;
  346 
  347         for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) {
  348                 if (dir != IPSEC_DIR_ANY && i != dir)
  349                         continue;
  350                 if (pcbsp->sp_cache[i].cachesp)
  351                         key_freesp(pcbsp->sp_cache[i].cachesp);
  352                 pcbsp->sp_cache[i].cachesp = NULL;
  353                 pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_MAYBE;
  354                 pcbsp->sp_cache[i].cachegen = 0;
  355                 bzero(&pcbsp->sp_cache[i].cacheidx,
  356                       sizeof(pcbsp->sp_cache[i].cacheidx));
  357         }
  358         return 0;
  359 }
  360 
  361 int
  362 ipsec_pcbconn(struct inpcbpolicy *pcbsp)
  363 {
  364 
  365         pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED;
  366         ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
  367         return 0;
  368 }
  369 
  370 int
  371 ipsec_pcbdisconn(struct inpcbpolicy *pcbsp)
  372 {
  373 
  374         pcbsp->sp_cacheflags &= ~IPSEC_PCBSP_CONNECTED;
  375         ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
  376         return 0;
  377 }
  378 
  379 void
  380 ipsec_invalpcbcacheall()
  381 {
  382 
  383         if (ipsec_spdgen == UINT_MAX)
  384                 ipsec_spdgen = 1;
  385         else
  386                 ipsec_spdgen++;
  387 }
  388 
  389 #ifdef SADB_X_EXT_TAG
  390 static struct pf_tag *
  391 ipsec_get_tag(struct mbuf *m)
  392 {
  393         struct m_tag    *mtag;
  394 
  395         if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL)
  396                 return ((struct pf_tag *)(mtag + 1));
  397         else
  398                 return (NULL);
  399 }
  400 #endif
  401 
  402 /*
  403  * For OUTBOUND packet having a socket. Searching SPD for packet,
  404  * and return a pointer to SP.
  405  * OUT: NULL:   no apropreate SP found, the following value is set to error.
  406  *              0       : bypass
  407  *              EACCES  : discard packet.
  408  *              ENOENT  : ipsec_acquire() in progress, maybe.
  409  *              others  : error occurred.
  410  *      others: a pointer to SP
  411  *
  412  * NOTE: IPv6 mapped address concern is implemented here.
  413  */
  414 struct secpolicy *
  415 ipsec4_getpolicybysock(struct mbuf *m, u_int dir, struct socket *so, 
  416         int *error)
  417 {
  418         struct inpcbpolicy *pcbsp = NULL;
  419         struct secpolicy *currsp = NULL;        /* policy on socket */
  420         struct secpolicy *kernsp = NULL;        /* policy on kernel */
  421         struct secpolicyindex spidx;
  422 #ifdef SADB_X_EXT_TAG
  423         struct pf_tag *t;
  424 #endif
  425         u_int16_t tag;
  426 
  427         /* sanity check */
  428         if (m == NULL || so == NULL || error == NULL)
  429                 panic("ipsec4_getpolicybysock: NULL pointer was passed.");
  430 
  431         switch (so->so_proto->pr_domain->dom_family) {
  432         case AF_INET:
  433                 pcbsp = sotoinpcb(so)->inp_sp;
  434                 break;
  435 #ifdef INET6
  436         case AF_INET6:
  437                 pcbsp = sotoin6pcb(so)->in6p_sp;
  438                 break;
  439 #endif
  440         default:
  441                 panic("ipsec4_getpolicybysock: unsupported address family");
  442         }
  443 
  444 #ifdef DIAGNOSTIC
  445         if (pcbsp == NULL)
  446                 panic("ipsec4_getpolicybysock: pcbsp is NULL.");
  447 #endif
  448 
  449 #ifdef SADB_X_EXT_TAG
  450         t = ipsec_get_tag(m);
  451         tag = t ? t->tag : 0;
  452 #else
  453         tag = 0;
  454 #endif
  455 
  456         /* if we have a cached entry, and if it is still valid, use it. */
  457         IPSEC_STATINC(IPSEC_STAT_SPDCACHELOOKUP);
  458         currsp = ipsec_checkpcbcache(m, pcbsp, dir);
  459         if (currsp) {
  460                 *error = 0;
  461                 return currsp;
  462         }
  463         IPSEC_STATINC(IPSEC_STAT_SPDCACHEMISS);
  464 
  465         switch (dir) {
  466         case IPSEC_DIR_INBOUND:
  467                 currsp = pcbsp->sp_in;
  468                 break;
  469         case IPSEC_DIR_OUTBOUND:
  470                 currsp = pcbsp->sp_out;
  471                 break;
  472         default:
  473                 panic("ipsec4_getpolicybysock: illegal direction.");
  474         }
  475 
  476         /* sanity check */
  477         if (currsp == NULL)
  478                 panic("ipsec4_getpolicybysock: currsp is NULL.");
  479 
  480         /* when privileged socket */
  481         if (pcbsp->priv) {
  482                 switch (currsp->policy) {
  483                 case IPSEC_POLICY_BYPASS:
  484                         currsp->refcnt++;
  485                         *error = 0;
  486                         ipsec_fillpcbcache(pcbsp, m, currsp, dir);
  487                         return currsp;
  488 
  489                 case IPSEC_POLICY_ENTRUST:
  490                         /* look for a policy in SPD */
  491                         if (ipsec_setspidx_mbuf(&spidx, AF_INET, m, 1) == 0 &&
  492                             (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
  493                                 /* SP found */
  494                                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  495                                         printf("DP ipsec4_getpolicybysock called "
  496                                                "to allocate SP:%p\n", kernsp));
  497                                 *error = 0;
  498                                 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
  499                                 return kernsp;
  500                         }
  501 
  502                         /* no SP found */
  503                         ip4_def_policy->refcnt++;
  504                         *error = 0;
  505                         ipsec_fillpcbcache(pcbsp, m, ip4_def_policy, dir);
  506                         return ip4_def_policy;
  507 
  508                 case IPSEC_POLICY_IPSEC:
  509                         currsp->refcnt++;
  510                         *error = 0;
  511                         ipsec_fillpcbcache(pcbsp, m, currsp, dir);
  512                         return currsp;
  513 
  514                 default:
  515                         ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
  516                               "Invalid policy for PCB %d\n", currsp->policy));
  517                         *error = EINVAL;
  518                         return NULL;
  519                 }
  520                 /* NOTREACHED */
  521         }
  522 
  523         /* when non-privileged socket */
  524         /* look for a policy in SPD */
  525         if (ipsec_setspidx_mbuf(&spidx, AF_INET, m, 1) == 0 &&
  526             (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
  527                 /* SP found */
  528                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  529                         printf("DP ipsec4_getpolicybysock called "
  530                                "to allocate SP:%p\n", kernsp));
  531                 *error = 0;
  532                 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
  533                 return kernsp;
  534         }
  535 
  536         /* no SP found */
  537         switch (currsp->policy) {
  538         case IPSEC_POLICY_BYPASS:
  539                 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
  540                        "Illegal policy for non-privileged defined %d\n",
  541                         currsp->policy));
  542                 *error = EINVAL;
  543                 return NULL;
  544 
  545         case IPSEC_POLICY_ENTRUST:
  546                 ip4_def_policy->refcnt++;
  547                 *error = 0;
  548                 ipsec_fillpcbcache(pcbsp, m, ip4_def_policy, dir);
  549                 return ip4_def_policy;
  550 
  551         case IPSEC_POLICY_IPSEC:
  552                 currsp->refcnt++;
  553                 *error = 0;
  554                 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
  555                 return currsp;
  556 
  557         default:
  558                 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
  559                    "Invalid policy for PCB %d\n", currsp->policy));
  560                 *error = EINVAL;
  561                 return NULL;
  562         }
  563         /* NOTREACHED */
  564 }
  565 
  566 /*
  567  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
  568  * and return a pointer to SP.
  569  * OUT: positive: a pointer to the entry for security policy leaf matched.
  570  *      NULL:   no apropreate SP found, the following value is set to error.
  571  *              0       : bypass
  572  *              EACCES  : discard packet.
  573  *              ENOENT  : ipsec_acquire() in progress, maybe.
  574  *              others  : error occurred.
  575  */
  576 struct secpolicy *
  577 ipsec4_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
  578 {
  579         struct secpolicy *sp = NULL;
  580 #ifdef SADB_X_EXT_TAG
  581         struct pf_tag *t;
  582 #endif
  583         u_int16_t tag;
  584 
  585         /* sanity check */
  586         if (m == NULL || error == NULL)
  587                 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.");
  588 
  589         /* get a policy entry matched with the packet */
  590     {
  591         struct secpolicyindex spidx;
  592 
  593         bzero(&spidx, sizeof(spidx));
  594 
  595         /* make an index to look for a policy */
  596         *error = ipsec_setspidx_mbuf(&spidx, AF_INET, m,
  597             (flag & IP_FORWARDING) ? 0 : 1);
  598 
  599         if (*error != 0)
  600                 return NULL;
  601 
  602 #ifdef SADB_X_EXT_TAG
  603         t = ipsec_get_tag(m);
  604         tag = t ? t->tag : 0;
  605 #else
  606         tag = 0;
  607 #endif
  608 
  609         sp = key_allocsp(tag, &spidx, dir);
  610     }
  611 
  612         /* SP found */
  613         if (sp != NULL) {
  614                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  615                         printf("DP ipsec4_getpolicybyaddr called "
  616                                "to allocate SP:%p\n", sp));
  617                 *error = 0;
  618                 return sp;
  619         }
  620 
  621         /* no SP found */
  622         ip4_def_policy->refcnt++;
  623         *error = 0;
  624         return ip4_def_policy;
  625 }
  626 
  627 #ifdef INET6
  628 /*
  629  * For OUTBOUND packet having a socket. Searching SPD for packet,
  630  * and return a pointer to SP.
  631  * OUT: NULL:   no apropreate SP found, the following value is set to error.
  632  *              0       : bypass
  633  *              EACCES  : discard packet.
  634  *              ENOENT  : ipsec_acquire() in progress, maybe.
  635  *              others  : error occurred.
  636  *      others: a pointer to SP
  637  */
  638 struct secpolicy *
  639 ipsec6_getpolicybysock(struct mbuf *m, u_int dir, struct socket *so, 
  640         int *error)
  641 {
  642         struct inpcbpolicy *pcbsp = NULL;
  643         struct secpolicy *currsp = NULL;        /* policy on socket */
  644         struct secpolicy *kernsp = NULL;        /* policy on kernel */
  645         struct secpolicyindex spidx;
  646 #ifdef SADB_X_EXT_TAG
  647         struct pf_tag *t;
  648 #endif
  649         u_int16_t tag;
  650 
  651         /* sanity check */
  652         if (m == NULL || so == NULL || error == NULL)
  653                 panic("ipsec6_getpolicybysock: NULL pointer was passed.");
  654 
  655 #ifdef DIAGNOSTIC
  656         if (so->so_proto->pr_domain->dom_family != AF_INET6)
  657                 panic("ipsec6_getpolicybysock: socket domain != inet6");
  658 #endif
  659 
  660         pcbsp = sotoin6pcb(so)->in6p_sp;
  661 
  662 #ifdef DIAGNOSTIC
  663         if (pcbsp == NULL)
  664                 panic("ipsec6_getpolicybysock: pcbsp is NULL.");
  665 #endif
  666 
  667 #ifdef SADB_X_EXT_TAG
  668         t = ipsec_get_tag(m);
  669         tag = t ? t->tag : 0;
  670 #else
  671         tag = 0;
  672 #endif
  673 
  674         /* if we have a cached entry, and if it is still valid, use it. */
  675         IPSEC6_STATINC(IPSEC_STAT_SPDCACHELOOKUP);
  676         currsp = ipsec_checkpcbcache(m, pcbsp, dir);
  677         if (currsp) {
  678                 *error = 0;
  679                 return currsp;
  680         }
  681         IPSEC6_STATINC(IPSEC_STAT_SPDCACHEMISS);
  682 
  683         switch (dir) {
  684         case IPSEC_DIR_INBOUND:
  685                 currsp = pcbsp->sp_in;
  686                 break;
  687         case IPSEC_DIR_OUTBOUND:
  688                 currsp = pcbsp->sp_out;
  689                 break;
  690         default:
  691                 panic("ipsec6_getpolicybysock: illegal direction.");
  692         }
  693 
  694         /* sanity check */
  695         if (currsp == NULL)
  696                 panic("ipsec6_getpolicybysock: currsp is NULL.");
  697 
  698         /* when privileged socket */
  699         if (pcbsp->priv) {
  700                 switch (currsp->policy) {
  701                 case IPSEC_POLICY_BYPASS:
  702                         currsp->refcnt++;
  703                         *error = 0;
  704                         ipsec_fillpcbcache(pcbsp, m, currsp, dir);
  705                         return currsp;
  706 
  707                 case IPSEC_POLICY_ENTRUST:
  708                         /* look for a policy in SPD */
  709                         if (ipsec_setspidx_mbuf(&spidx, AF_INET6, m, 1) == 0 &&
  710                             (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
  711                                 /* SP found */
  712                                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  713                                         printf("DP ipsec6_getpolicybysock called "
  714                                                "to allocate SP:%p\n", kernsp));
  715                                 *error = 0;
  716                                 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
  717                                 return kernsp;
  718                         }
  719 
  720                         /* no SP found */
  721                         ip6_def_policy->refcnt++;
  722                         *error = 0;
  723                         ipsec_fillpcbcache(pcbsp, m, ip6_def_policy, dir);
  724                         return ip6_def_policy;
  725 
  726                 case IPSEC_POLICY_IPSEC:
  727                         currsp->refcnt++;
  728                         *error = 0;
  729                         ipsec_fillpcbcache(pcbsp, m, currsp, dir);
  730                         return currsp;
  731 
  732                 default:
  733                         ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
  734                             "Invalid policy for PCB %d\n", currsp->policy));
  735                         *error = EINVAL;
  736                         return NULL;
  737                 }
  738                 /* NOTREACHED */
  739         }
  740 
  741         /* when non-privileged socket */
  742         /* look for a policy in SPD */
  743         if (ipsec_setspidx_mbuf(&spidx, AF_INET6, m, 1) == 0 &&
  744             (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
  745                 /* SP found */
  746                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  747                         printf("DP ipsec6_getpolicybysock called "
  748                                "to allocate SP:%p\n", kernsp));
  749                 *error = 0;
  750                 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
  751                 return kernsp;
  752         }
  753 
  754         /* no SP found */
  755         switch (currsp->policy) {
  756         case IPSEC_POLICY_BYPASS:
  757                 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
  758                     "Illegal policy for non-privileged defined %d\n",
  759                     currsp->policy));
  760                 *error = EINVAL;
  761                 return NULL;
  762 
  763         case IPSEC_POLICY_ENTRUST:
  764                 ip6_def_policy->refcnt++;
  765                 *error = 0;
  766                 ipsec_fillpcbcache(pcbsp, m, ip6_def_policy, dir);
  767                 return ip6_def_policy;
  768 
  769         case IPSEC_POLICY_IPSEC:
  770                 currsp->refcnt++;
  771                 *error = 0;
  772                 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
  773                 return currsp;
  774 
  775         default:
  776                 ipseclog((LOG_ERR,
  777                     "ipsec6_policybysock: Invalid policy for PCB %d\n",
  778                     currsp->policy));
  779                 *error = EINVAL;
  780                 return NULL;
  781         }
  782         /* NOTREACHED */
  783 }
  784 
  785 /*
  786  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
  787  * and return a pointer to SP.
  788  * `flag' means that packet is to be forwarded whether or not.
  789  *      flag = 1: forwad
  790  * OUT: positive: a pointer to the entry for security policy leaf matched.
  791  *      NULL:   no apropreate SP found, the following value is set to error.
  792  *              0       : bypass
  793  *              EACCES  : discard packet.
  794  *              ENOENT  : ipsec_acquire() in progress, maybe.
  795  *              others  : error occurred.
  796  */
  797 #ifndef IP_FORWARDING
  798 #define IP_FORWARDING 1
  799 #endif
  800 
  801 struct secpolicy *
  802 ipsec6_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
  803 {
  804         struct secpolicy *sp = NULL;
  805 #ifdef SADB_X_EXT_TAG
  806         struct pf_tag *t;
  807 #endif
  808         u_int16_t tag;
  809 
  810         /* sanity check */
  811         if (m == NULL || error == NULL)
  812                 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.");
  813 
  814         /* get a policy entry matched with the packet */
  815     {
  816         struct secpolicyindex spidx;
  817 
  818         bzero(&spidx, sizeof(spidx));
  819 
  820         /* make an index to look for a policy */
  821         *error = ipsec_setspidx_mbuf(&spidx, AF_INET6, m,
  822             (flag & IP_FORWARDING) ? 0 : 1);
  823 
  824         if (*error != 0)
  825                 return NULL;
  826 
  827 #ifdef SADB_X_EXT_TAG
  828         t = ipsec_get_tag(m);
  829         tag = t ? t->tag : 0;
  830 #else
  831         tag = 0;
  832 #endif
  833 
  834         sp = key_allocsp(tag, &spidx, dir);
  835     }
  836 
  837         /* SP found */
  838         if (sp != NULL) {
  839                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  840                         printf("DP ipsec6_getpolicybyaddr called "
  841                                "to allocate SP:%p\n", sp));
  842                 *error = 0;
  843                 return sp;
  844         }
  845 
  846         /* no SP found */
  847         ip6_def_policy->refcnt++;
  848         *error = 0;
  849         return ip6_def_policy;
  850 }
  851 #endif /* INET6 */
  852 
  853 /*
  854  * set IP address into spidx from mbuf.
  855  * When Forwarding packet and ICMP echo reply, this function is used.
  856  *
  857  * IN:  get the followings from mbuf.
  858  *      protocol family, src, dst, next protocol
  859  * OUT:
  860  *      0:      success.
  861  *      other:  failure, and set errno.
  862  */
  863 int
  864 ipsec_setspidx_mbuf(struct secpolicyindex *spidx, int family,
  865     struct mbuf *m, int needport)
  866 {
  867         int error;
  868 
  869         /* sanity check */
  870         if (spidx == NULL || m == NULL)
  871                 panic("ipsec_setspidx_mbuf: NULL pointer was passed.");
  872 
  873         bzero(spidx, sizeof(*spidx));
  874 
  875         error = ipsec_setspidx(m, spidx, needport);
  876         if (error)
  877                 goto bad;
  878 
  879         return 0;
  880 
  881     bad:
  882         /* XXX initialize */
  883         bzero(spidx, sizeof(*spidx));
  884         return EINVAL;
  885 }
  886 
  887 /*
  888  * configure security policy index (src/dst/proto/sport/dport)
  889  * by looking at the content of mbuf.
  890  * the caller is responsible for error recovery (like clearing up spidx).
  891  */
  892 static int
  893 ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport)
  894 {
  895         struct ip *ip = NULL;
  896         struct ip ipbuf;
  897         u_int v;
  898         struct mbuf *n;
  899         int len;
  900         int error;
  901 
  902         if (m == NULL)
  903                 panic("ipsec_setspidx: m == 0 passed.");
  904 
  905         bzero(spidx, sizeof(*spidx));
  906 
  907         /*
  908          * validate m->m_pkthdr.len.  we see incorrect length if we
  909          * mistakenly call this function with inconsistent mbuf chain
  910          * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
  911          */
  912         len = 0;
  913         for (n = m; n; n = n->m_next)
  914                 len += n->m_len;
  915         if (m->m_pkthdr.len != len) {
  916                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  917                         printf("ipsec_setspidx: "
  918                                "total of m_len(%d) != pkthdr.len(%d), "
  919                                "ignored.\n",
  920                                 len, m->m_pkthdr.len));
  921                 return EINVAL;
  922         }
  923 
  924         if (m->m_pkthdr.len < sizeof(struct ip)) {
  925                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  926                         printf("ipsec_setspidx: "
  927                             "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
  928                             m->m_pkthdr.len));
  929                 return EINVAL;
  930         }
  931 
  932         if (m->m_len >= sizeof(*ip))
  933                 ip = mtod(m, struct ip *);
  934         else {
  935                 m_copydata(m, 0, sizeof(ipbuf), (void *)&ipbuf);
  936                 ip = &ipbuf;
  937         }
  938         v = ip->ip_v;
  939         switch (v) {
  940         case 4:
  941                 error = ipsec4_setspidx_ipaddr(m, spidx);
  942                 if (error)
  943                         return error;
  944                 ipsec4_get_ulp(m, spidx, needport);
  945                 return 0;
  946 #ifdef INET6
  947         case 6:
  948                 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
  949                         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  950                                 printf("ipsec_setspidx: "
  951                                     "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
  952                                     "ignored.\n", m->m_pkthdr.len));
  953                         return EINVAL;
  954                 }
  955                 error = ipsec6_setspidx_ipaddr(m, spidx);
  956                 if (error)
  957                         return error;
  958                 ipsec6_get_ulp(m, spidx, needport);
  959                 return 0;
  960 #endif
  961         default:
  962                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  963                         printf("ipsec_setspidx: "
  964                             "unknown IP version %u, ignored.\n", v));
  965                 return EINVAL;
  966         }
  967 }
  968 
  969 static void
  970 ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
  971 {
  972         struct ip ip;
  973         struct ip6_ext ip6e;
  974         u_int8_t nxt;
  975         int off;
  976         struct tcphdr th;
  977         struct udphdr uh;
  978         struct icmp icmph;
  979 
  980         /* sanity check */
  981         if (m == NULL)
  982                 panic("ipsec4_get_ulp: NULL pointer was passed.");
  983         if (m->m_pkthdr.len < sizeof(ip))
  984                 panic("ipsec4_get_ulp: too short");
  985 
  986         /* set default */
  987         spidx->ul_proto = IPSEC_ULPROTO_ANY;
  988         ((struct sockaddr_in *)&spidx->src)->sin_port = IPSEC_PORT_ANY;
  989         ((struct sockaddr_in *)&spidx->dst)->sin_port = IPSEC_PORT_ANY;
  990 
  991         m_copydata(m, 0, sizeof(ip), (void *)&ip);
  992         if (ip.ip_off & htons(IP_MF | IP_OFFMASK))
  993                 return;
  994 
  995         nxt = ip.ip_p;
  996         off = ip.ip_hl << 2;
  997         while (off < m->m_pkthdr.len) {
  998                 switch (nxt) {
  999                 case IPPROTO_TCP:
 1000                         spidx->ul_proto = nxt;
 1001                         if (!needport)
 1002                                 return;
 1003                         if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
 1004                                 return;
 1005                         m_copydata(m, off, sizeof(th), (void *)&th);
 1006                         ((struct sockaddr_in *)&spidx->src)->sin_port =
 1007                             th.th_sport;
 1008                         ((struct sockaddr_in *)&spidx->dst)->sin_port =
 1009                             th.th_dport;
 1010                         return;
 1011                 case IPPROTO_UDP:
 1012                         spidx->ul_proto = nxt;
 1013                         if (!needport)
 1014                                 return;
 1015                         if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
 1016                                 return;
 1017                         m_copydata(m, off, sizeof(uh), (void *)&uh);
 1018                         ((struct sockaddr_in *)&spidx->src)->sin_port =
 1019                             uh.uh_sport;
 1020                         ((struct sockaddr_in *)&spidx->dst)->sin_port =
 1021                             uh.uh_dport;
 1022                         return;
 1023                 case IPPROTO_AH:
 1024                         if (off + sizeof(ip6e) > m->m_pkthdr.len)
 1025                                 return;
 1026                         m_copydata(m, off, sizeof(ip6e), (void *)&ip6e);
 1027                         off += (ip6e.ip6e_len + 2) << 2;
 1028                         nxt = ip6e.ip6e_nxt;
 1029                         break;
 1030                 case IPPROTO_ICMP:
 1031                         spidx->ul_proto = nxt;
 1032                         if (off + sizeof(struct icmp) > m->m_pkthdr.len)
 1033                                 return;
 1034                         m_copydata(m, off, sizeof(icmph), &icmph);
 1035                         ((struct sockaddr_in *)&spidx->src)->sin_port =
 1036                             htons((uint16_t)icmph.icmp_type);
 1037                         ((struct sockaddr_in *)&spidx->dst)->sin_port =
 1038                             htons((uint16_t)icmph.icmp_code);
 1039                         return;
 1040                 default:
 1041                         /* XXX intermediate headers??? */
 1042                         spidx->ul_proto = nxt;
 1043                         return;
 1044                 }
 1045         }
 1046 }
 1047 
 1048 /* assumes that m is sane */
 1049 static int
 1050 ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
 1051 {
 1052         struct ip *ip = NULL;
 1053         struct ip ipbuf;
 1054         struct sockaddr_in *sin;
 1055 
 1056         if (m->m_len >= sizeof(*ip))
 1057                 ip = mtod(m, struct ip *);
 1058         else {
 1059                 m_copydata(m, 0, sizeof(ipbuf), (void *)&ipbuf);
 1060                 ip = &ipbuf;
 1061         }
 1062 
 1063         sin = (struct sockaddr_in *)&spidx->src;
 1064         bzero(sin, sizeof(*sin));
 1065         sin->sin_family = AF_INET;
 1066         sin->sin_len = sizeof(struct sockaddr_in);
 1067         bcopy(&ip->ip_src, &sin->sin_addr, sizeof(ip->ip_src));
 1068         spidx->prefs = sizeof(struct in_addr) << 3;
 1069 
 1070         sin = (struct sockaddr_in *)&spidx->dst;
 1071         bzero(sin, sizeof(*sin));
 1072         sin->sin_family = AF_INET;
 1073         sin->sin_len = sizeof(struct sockaddr_in);
 1074         bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst));
 1075         spidx->prefd = sizeof(struct in_addr) << 3;
 1076         return 0;
 1077 }
 1078 
 1079 #ifdef INET6
 1080 static void
 1081 ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
 1082 {
 1083         int off, nxt;
 1084         struct tcphdr th;
 1085         struct udphdr uh;
 1086         struct icmp6_hdr icmph;
 1087 
 1088         /* sanity check */
 1089         if (m == NULL)
 1090                 panic("ipsec6_get_ulp: NULL pointer was passed.");
 1091 
 1092         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1093                 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
 1094 
 1095         /* set default */
 1096         spidx->ul_proto = IPSEC_ULPROTO_ANY;
 1097         ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
 1098         ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
 1099 
 1100         nxt = -1;
 1101         off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
 1102         if (off < 0 || m->m_pkthdr.len < off)
 1103                 return;
 1104 
 1105         switch (nxt) {
 1106         case IPPROTO_TCP:
 1107                 spidx->ul_proto = nxt;
 1108                 if (!needport)
 1109                         break;
 1110                 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
 1111                         break;
 1112                 m_copydata(m, off, sizeof(th), (void *)&th);
 1113                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
 1114                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
 1115                 break;
 1116         case IPPROTO_UDP:
 1117                 spidx->ul_proto = nxt;
 1118                 if (!needport)
 1119                         break;
 1120                 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
 1121                         break;
 1122                 m_copydata(m, off, sizeof(uh), (void *)&uh);
 1123                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
 1124                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
 1125                 break;
 1126         case IPPROTO_ICMPV6:
 1127                 spidx->ul_proto = nxt;
 1128                 if (off + sizeof(struct icmp6_hdr) > m->m_pkthdr.len)
 1129                         break;
 1130                 m_copydata(m, off, sizeof(icmph), &icmph);
 1131                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port =
 1132                     htons((uint16_t)icmph.icmp6_type);
 1133                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
 1134                     htons((uint16_t)icmph.icmp6_code);
 1135                 break;
 1136         default:
 1137                 /* XXX intermediate headers??? */
 1138                 spidx->ul_proto = nxt;
 1139                 break;
 1140         }
 1141 }
 1142 
 1143 /* assumes that m is sane */
 1144 static int
 1145 ipsec6_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
 1146 {
 1147         struct ip6_hdr *ip6 = NULL;
 1148         struct ip6_hdr ip6buf;
 1149         struct sockaddr_in6 *sin6;
 1150 
 1151         if (m->m_len >= sizeof(*ip6))
 1152                 ip6 = mtod(m, struct ip6_hdr *);
 1153         else {
 1154                 m_copydata(m, 0, sizeof(ip6buf), (void *)&ip6buf);
 1155                 ip6 = &ip6buf;
 1156         }
 1157 
 1158         sin6 = (struct sockaddr_in6 *)&spidx->src;
 1159         bzero(sin6, sizeof(*sin6));
 1160         sin6->sin6_family = AF_INET6;
 1161         sin6->sin6_len = sizeof(struct sockaddr_in6);
 1162         sin6->sin6_addr = ip6->ip6_src;
 1163         spidx->prefs = sizeof(struct in6_addr) << 3;
 1164 
 1165         sin6 = (struct sockaddr_in6 *)&spidx->dst;
 1166         bzero(sin6, sizeof(*sin6));
 1167         sin6->sin6_family = AF_INET6;
 1168         sin6->sin6_len = sizeof(struct sockaddr_in6);
 1169         sin6->sin6_addr = ip6->ip6_dst;
 1170         spidx->prefd = sizeof(struct in6_addr) << 3;
 1171 
 1172         return 0;
 1173 }
 1174 #endif
 1175 
 1176 static struct inpcbpolicy *
 1177 ipsec_newpcbpolicy()
 1178 {
 1179         struct inpcbpolicy *p;
 1180 
 1181         p = (struct inpcbpolicy *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
 1182         return p;
 1183 }
 1184 
 1185 static void
 1186 ipsec_delpcbpolicy(struct inpcbpolicy *p)
 1187 {
 1188 
 1189         free(p, M_SECA);
 1190 }
 1191 
 1192 /* initialize policy in PCB */
 1193 int
 1194 ipsec_init_pcbpolicy(struct socket *so, struct inpcbpolicy **pcb_sp)
 1195 {
 1196         struct inpcbpolicy *new;
 1197         static int initialized = 0;
 1198         static struct secpolicy *in = NULL, *out = NULL;
 1199 
 1200         /* sanity check. */
 1201         if (so == NULL || pcb_sp == NULL)
 1202                 panic("ipsec_init_pcbpolicy: NULL pointer was passed.");
 1203 
 1204         if (!initialized) {
 1205                 if ((in = key_newsp(0)) == NULL)
 1206                         return ENOBUFS;
 1207                 if ((out = key_newsp(0)) == NULL) {
 1208                         key_freesp(in);
 1209                         in = NULL;
 1210                         return ENOBUFS;
 1211                 }
 1212 
 1213                 in->state = IPSEC_SPSTATE_ALIVE;
 1214                 in->policy = IPSEC_POLICY_ENTRUST;
 1215                 in->dir = IPSEC_DIR_INBOUND;
 1216                 in->readonly = 1;
 1217                 in->persist = 1;
 1218                 in->so = NULL;
 1219 
 1220                 out->state = IPSEC_SPSTATE_ALIVE;
 1221                 out->policy = IPSEC_POLICY_ENTRUST;
 1222                 out->dir = IPSEC_DIR_OUTBOUND;
 1223                 out->readonly = 1;
 1224                 out->persist = 1;
 1225                 out->so = NULL;
 1226 
 1227                 initialized++;
 1228         }
 1229 
 1230         new = ipsec_newpcbpolicy();
 1231         if (new == NULL) {
 1232                 ipseclog((LOG_DEBUG, "ipsec_init_pcbpolicy: No more memory.\n"));
 1233                 return ENOBUFS;
 1234         }
 1235         bzero(new, sizeof(*new));
 1236 
 1237         if (so->so_uidinfo->ui_uid == 0)        /* XXX */
 1238                 new->priv = 1;
 1239         else
 1240                 new->priv = 0;
 1241 
 1242         new->sp_in = in;
 1243         new->sp_in->refcnt++;
 1244         new->sp_out = out;
 1245         new->sp_out->refcnt++;
 1246 
 1247         *pcb_sp = new;
 1248 
 1249         return 0;
 1250 }
 1251 
 1252 /* copy old ipsec policy into new */
 1253 int
 1254 ipsec_copy_pcbpolicy(struct inpcbpolicy *old, struct inpcbpolicy *new)
 1255 {
 1256 
 1257         if (new->sp_in)
 1258                 key_freesp(new->sp_in);
 1259         if (old->sp_in->policy == IPSEC_POLICY_IPSEC)
 1260                 new->sp_in = ipsec_deepcopy_policy(old->sp_in);
 1261         else {
 1262                 new->sp_in = old->sp_in;
 1263                 new->sp_in->refcnt++;
 1264         }
 1265 
 1266         if (new->sp_out)
 1267                 key_freesp(new->sp_out);
 1268         if (old->sp_out->policy == IPSEC_POLICY_IPSEC)
 1269                 new->sp_out = ipsec_deepcopy_policy(old->sp_out);
 1270         else {
 1271                 new->sp_out = old->sp_out;
 1272                 new->sp_out->refcnt++;
 1273         }
 1274 
 1275         new->priv = old->priv;
 1276 
 1277         return 0;
 1278 }
 1279 
 1280 #if 0
 1281 static int
 1282 ipsec_deepcopy_pcbpolicy(struct inpcbpolicy *pcb_sp)
 1283 {
 1284         struct secpolicy *sp;
 1285 
 1286         sp = ipsec_deepcopy_policy(pcb_sp->sp_in);
 1287         if (sp) {
 1288                 key_freesp(pcb_sp->sp_in);
 1289                 pcb_sp->sp_in = sp;
 1290         } else
 1291                 return ENOBUFS;
 1292 
 1293         sp = ipsec_deepcopy_policy(pcb_sp->sp_out);
 1294         if (sp) {
 1295                 key_freesp(pcb_sp->sp_out);
 1296                 pcb_sp->sp_out = sp;
 1297         } else
 1298                 return ENOBUFS;
 1299 
 1300         return 0;
 1301 }
 1302 #endif
 1303 
 1304 /* deep-copy a policy in PCB */
 1305 static struct secpolicy *
 1306 ipsec_deepcopy_policy(struct secpolicy *src)
 1307 {
 1308         struct ipsecrequest *newchain = NULL;
 1309         struct ipsecrequest *p;
 1310         struct ipsecrequest **q;
 1311         struct ipsecrequest *r;
 1312         struct secpolicy *dst;
 1313 
 1314         if (src == NULL)
 1315                 return NULL;
 1316 
 1317         dst = key_newsp(0);
 1318         if (dst == NULL)
 1319                 return NULL;
 1320 
 1321         /*
 1322          * deep-copy IPsec request chain.  This is required since struct
 1323          * ipsecrequest is not reference counted.
 1324          */
 1325         q = &newchain;
 1326         for (p = src->req; p; p = p->next) {
 1327                 *q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
 1328                         M_SECA, M_NOWAIT);
 1329                 if (*q == NULL)
 1330                         goto fail;
 1331                 bzero(*q, sizeof(**q));
 1332                 (*q)->next = NULL;
 1333 
 1334                 (*q)->saidx.proto = p->saidx.proto;
 1335                 (*q)->saidx.mode = p->saidx.mode;
 1336                 (*q)->level = p->level;
 1337                 (*q)->saidx.reqid = p->saidx.reqid;
 1338 
 1339                 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
 1340                 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
 1341 
 1342                 (*q)->sav = NULL;
 1343                 (*q)->sp = dst;
 1344 
 1345                 q = &((*q)->next);
 1346         }
 1347 
 1348         if (src->spidx)
 1349                 if (keydb_setsecpolicyindex(dst, src->spidx) != 0)
 1350                         goto fail;
 1351 
 1352         dst->req = newchain;
 1353         dst->state = src->state;
 1354         dst->policy = src->policy;
 1355         dst->dir = src->dir;
 1356         dst->so = src->so;
 1357         /* do not touch the refcnt fields */
 1358 
 1359         return dst;
 1360 
 1361 fail:
 1362         for (p = newchain; p; p = r) {
 1363                 r = p->next;
 1364                 free(p, M_SECA);
 1365                 p = NULL;
 1366         }
 1367         key_freesp(dst);
 1368         return NULL;
 1369 }
 1370 
 1371 /* set policy and ipsec request if present. */
 1372 static int
 1373 ipsec_set_policy(struct secpolicy **spp, int optname, void *request,
 1374     size_t len, int priv)
 1375 {
 1376         struct sadb_x_policy *xpl;
 1377         struct secpolicy *newsp = NULL;
 1378         int error;
 1379 
 1380         /* sanity check. */
 1381         if (spp == NULL || *spp == NULL || request == NULL)
 1382                 return EINVAL;
 1383         if (len < sizeof(*xpl))
 1384                 return EINVAL;
 1385         xpl = (struct sadb_x_policy *)request;
 1386 
 1387         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1388                 printf("ipsec_set_policy: passed policy\n");
 1389                 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
 1390 
 1391         /* check policy type */
 1392         /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
 1393         if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD ||
 1394             xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
 1395                 return EINVAL;
 1396 
 1397         /* check privileged socket */
 1398         if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
 1399                 return EACCES;
 1400 
 1401         /* allocation new SP entry */
 1402         if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
 1403                 return error;
 1404 
 1405         newsp->state = IPSEC_SPSTATE_ALIVE;
 1406 
 1407         /* clear old SP and set new SP */
 1408         key_freesp(*spp);
 1409         *spp = newsp;
 1410         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1411                 printf("ipsec_set_policy: new policy\n");
 1412                 kdebug_secpolicy(newsp));
 1413 
 1414         return 0;
 1415 }
 1416 
 1417 static int
 1418 ipsec_get_policy(struct secpolicy *sp, struct mbuf **mp)
 1419 {
 1420 
 1421         /* sanity check. */
 1422         if (sp == NULL || mp == NULL)
 1423                 return EINVAL;
 1424 
 1425         *mp = key_sp2msg(sp);
 1426         if (!*mp) {
 1427                 ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
 1428                 return ENOBUFS;
 1429         }
 1430 
 1431         (*mp)->m_type = MT_SOOPTS;
 1432         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1433                 printf("ipsec_get_policy:\n");
 1434                 kdebug_mbuf(*mp));
 1435 
 1436         return 0;
 1437 }
 1438 
 1439 int
 1440 ipsec4_set_policy(struct inpcb *inp, int optname, void *request, 
 1441         size_t len, int priv)
 1442 {
 1443         struct sadb_x_policy *xpl;
 1444         struct secpolicy **spp;
 1445 
 1446         /* sanity check. */
 1447         if (inp == NULL || request == NULL)
 1448                 return EINVAL;
 1449         if (len < sizeof(*xpl))
 1450                 return EINVAL;
 1451         xpl = (struct sadb_x_policy *)request;
 1452 
 1453         /* select direction */
 1454         switch (xpl->sadb_x_policy_dir) {
 1455         case IPSEC_DIR_INBOUND:
 1456                 spp = &inp->inp_sp->sp_in;
 1457                 break;
 1458         case IPSEC_DIR_OUTBOUND:
 1459                 spp = &inp->inp_sp->sp_out;
 1460                 break;
 1461         default:
 1462                 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
 1463                         xpl->sadb_x_policy_dir));
 1464                 return EINVAL;
 1465         }
 1466 
 1467         ipsec_invalpcbcache(inp->inp_sp, IPSEC_DIR_ANY);
 1468         return ipsec_set_policy(spp, optname, request, len, priv);
 1469 }
 1470 
 1471 int
 1472 ipsec4_get_policy(struct inpcb *inp, void *request, size_t len, 
 1473         struct mbuf **mp)
 1474 {
 1475         struct sadb_x_policy *xpl;
 1476         struct secpolicy *sp;
 1477 
 1478         /* sanity check. */
 1479         if (inp == NULL || request == NULL || mp == NULL)
 1480                 return EINVAL;
 1481         if (inp->inp_sp == NULL)
 1482                 panic("policy in PCB is NULL");
 1483         if (len < sizeof(*xpl))
 1484                 return EINVAL;
 1485         xpl = (struct sadb_x_policy *)request;
 1486 
 1487         /* select direction */
 1488         switch (xpl->sadb_x_policy_dir) {
 1489         case IPSEC_DIR_INBOUND:
 1490                 sp = inp->inp_sp->sp_in;
 1491                 break;
 1492         case IPSEC_DIR_OUTBOUND:
 1493                 sp = inp->inp_sp->sp_out;
 1494                 break;
 1495         default:
 1496                 ipseclog((LOG_ERR, "ipsec4_get_policy: invalid direction=%u\n",
 1497                         xpl->sadb_x_policy_dir));
 1498                 return EINVAL;
 1499         }
 1500 
 1501         return ipsec_get_policy(sp, mp);
 1502 }
 1503 
 1504 /* delete policy in PCB */
 1505 int
 1506 ipsec4_delete_pcbpolicy(struct inpcb *inp)
 1507 {
 1508         /* sanity check. */
 1509         if (inp == NULL)
 1510                 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.");
 1511 
 1512         if (inp->inp_sp == NULL)
 1513                 return 0;
 1514 
 1515         if (inp->inp_sp->sp_in != NULL) {
 1516                 key_freesp(inp->inp_sp->sp_in);
 1517                 inp->inp_sp->sp_in = NULL;
 1518         }
 1519 
 1520         if (inp->inp_sp->sp_out != NULL) {
 1521                 key_freesp(inp->inp_sp->sp_out);
 1522                 inp->inp_sp->sp_out = NULL;
 1523         }
 1524 
 1525         ipsec_invalpcbcache(inp->inp_sp, IPSEC_DIR_ANY);
 1526 
 1527         ipsec_delpcbpolicy(inp->inp_sp);
 1528         inp->inp_sp = NULL;
 1529 
 1530         return 0;
 1531 }
 1532 
 1533 #ifdef INET6
 1534 int
 1535 ipsec6_set_policy(struct in6pcb *in6p, int optname, void *request, 
 1536         size_t len, int priv)
 1537 {
 1538         struct sadb_x_policy *xpl;
 1539         struct secpolicy **spp;
 1540 
 1541         /* sanity check. */
 1542         if (in6p == NULL || request == NULL)
 1543                 return EINVAL;
 1544         if (len < sizeof(*xpl))
 1545                 return EINVAL;
 1546         xpl = (struct sadb_x_policy *)request;
 1547 
 1548         /* select direction */
 1549         switch (xpl->sadb_x_policy_dir) {
 1550         case IPSEC_DIR_INBOUND:
 1551                 spp = &in6p->in6p_sp->sp_in;
 1552                 break;
 1553         case IPSEC_DIR_OUTBOUND:
 1554                 spp = &in6p->in6p_sp->sp_out;
 1555                 break;
 1556         default:
 1557                 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
 1558                         xpl->sadb_x_policy_dir));
 1559                 return EINVAL;
 1560         }
 1561 
 1562         ipsec_invalpcbcache(in6p->in6p_sp, IPSEC_DIR_ANY);
 1563         return ipsec_set_policy(spp, optname, request, len, priv);
 1564 }
 1565 
 1566 int
 1567 ipsec6_get_policy(struct in6pcb *in6p, void *request, size_t len, 
 1568         struct mbuf **mp)
 1569 {
 1570         struct sadb_x_policy *xpl;
 1571         struct secpolicy *sp;
 1572 
 1573         /* sanity check. */
 1574         if (in6p == NULL || request == NULL || mp == NULL)
 1575                 return EINVAL;
 1576         if (in6p->in6p_sp == NULL)
 1577                 panic("policy in PCB is NULL");
 1578         if (len < sizeof(*xpl))
 1579                 return EINVAL;
 1580         xpl = (struct sadb_x_policy *)request;
 1581 
 1582         /* select direction */
 1583         switch (xpl->sadb_x_policy_dir) {
 1584         case IPSEC_DIR_INBOUND:
 1585                 sp = in6p->in6p_sp->sp_in;
 1586                 break;
 1587         case IPSEC_DIR_OUTBOUND:
 1588                 sp = in6p->in6p_sp->sp_out;
 1589                 break;
 1590         default:
 1591                 ipseclog((LOG_ERR, "ipsec6_get_policy: invalid direction=%u\n",
 1592                         xpl->sadb_x_policy_dir));
 1593                 return EINVAL;
 1594         }
 1595 
 1596         return ipsec_get_policy(sp, mp);
 1597 }
 1598 
 1599 int
 1600 ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
 1601 {
 1602         /* sanity check. */
 1603         if (in6p == NULL)
 1604                 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.");
 1605 
 1606         if (in6p->in6p_sp == NULL)
 1607                 return 0;
 1608 
 1609         if (in6p->in6p_sp->sp_in != NULL) {
 1610                 key_freesp(in6p->in6p_sp->sp_in);
 1611                 in6p->in6p_sp->sp_in = NULL;
 1612         }
 1613 
 1614         if (in6p->in6p_sp->sp_out != NULL) {
 1615                 key_freesp(in6p->in6p_sp->sp_out);
 1616                 in6p->in6p_sp->sp_out = NULL;
 1617         }
 1618 
 1619         ipsec_invalpcbcache(in6p->in6p_sp, IPSEC_DIR_ANY);
 1620 
 1621         ipsec_delpcbpolicy(in6p->in6p_sp);
 1622         in6p->in6p_sp = NULL;
 1623 
 1624         return 0;
 1625 }
 1626 #endif
 1627 
 1628 /*
 1629  * return current level.
 1630  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
 1631  */
 1632 u_int
 1633 ipsec_get_reqlevel(struct ipsecrequest *isr, int af)
 1634 {
 1635         u_int level = 0;
 1636         u_int esp_trans_deflev, esp_net_deflev, ah_trans_deflev, ah_net_deflev;
 1637 
 1638         /* sanity check */
 1639         if (isr == NULL || isr->sp == NULL)
 1640                 panic("ipsec_get_reqlevel: NULL pointer is passed.");
 1641 
 1642         /* set default level */
 1643         switch (af) {
 1644 #ifdef INET
 1645         case AF_INET:
 1646                 esp_trans_deflev = ip4_esp_trans_deflev;
 1647                 esp_net_deflev = ip4_esp_net_deflev;
 1648                 ah_trans_deflev = ip4_ah_trans_deflev;
 1649                 ah_net_deflev = ip4_ah_net_deflev;
 1650                 break;
 1651 #endif
 1652 #ifdef INET6
 1653         case AF_INET6:
 1654                 esp_trans_deflev = ip6_esp_trans_deflev;
 1655                 esp_net_deflev = ip6_esp_net_deflev;
 1656                 ah_trans_deflev = ip6_ah_trans_deflev;
 1657                 ah_net_deflev = ip6_ah_net_deflev;
 1658                 break;
 1659 #endif /* INET6 */
 1660         default:
 1661                 panic("key_get_reqlevel: Unknown family. %d",
 1662                         ((struct sockaddr *)&isr->sp->spidx->src)->sa_family);
 1663         }
 1664 
 1665         /* set level */
 1666         switch (isr->level) {
 1667         case IPSEC_LEVEL_DEFAULT:
 1668                 switch (isr->saidx.proto) {
 1669                 case IPPROTO_ESP:
 1670                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1671                                 level = esp_net_deflev;
 1672                         else
 1673                                 level = esp_trans_deflev;
 1674                         break;
 1675                 case IPPROTO_AH:
 1676                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1677                                 level = ah_net_deflev;
 1678                         else
 1679                                 level = ah_trans_deflev;
 1680                         break;
 1681                 case IPPROTO_IPCOMP:
 1682                         /*
 1683                          * we don't really care, as IPcomp document says that
 1684                          * we shouldn't compress small packets
 1685                          */
 1686                         level = IPSEC_LEVEL_USE;
 1687                         break;
 1688                 case IPPROTO_IPV4:
 1689                 case IPPROTO_IPV6:
 1690                         /* should never go into here */
 1691                         level = IPSEC_LEVEL_REQUIRE;
 1692                         break;
 1693                 default:
 1694                         panic("ipsec_get_reqlevel: "
 1695                                 "Illegal protocol defined %u\n",
 1696                                 isr->saidx.proto);
 1697                 }
 1698                 break;
 1699 
 1700         case IPSEC_LEVEL_USE:
 1701         case IPSEC_LEVEL_REQUIRE:
 1702                 level = isr->level;
 1703                 break;
 1704         case IPSEC_LEVEL_UNIQUE:
 1705                 level = IPSEC_LEVEL_REQUIRE;
 1706                 break;
 1707 
 1708         default:
 1709                 panic("ipsec_get_reqlevel: Illegal IPsec level %u",
 1710                         isr->level);
 1711         }
 1712 
 1713         return level;
 1714 }
 1715 
 1716 /*
 1717  * Check AH/ESP integrity.
 1718  * OUT:
 1719  *      0: valid
 1720  *      1: invalid
 1721  */
 1722 static int
 1723 ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
 1724 {
 1725         struct ipsecrequest *isr;
 1726         u_int level;
 1727         int need_auth, need_conf, need_icv;
 1728 
 1729         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1730                 printf("ipsec_in_reject: using SP\n");
 1731                 kdebug_secpolicy(sp));
 1732 
 1733         /* check policy */
 1734         switch (sp->policy) {
 1735         case IPSEC_POLICY_DISCARD:
 1736                 return 1;
 1737         case IPSEC_POLICY_BYPASS:
 1738         case IPSEC_POLICY_NONE:
 1739                 return 0;
 1740 
 1741         case IPSEC_POLICY_IPSEC:
 1742                 break;
 1743 
 1744         case IPSEC_POLICY_ENTRUST:
 1745         default:
 1746                 panic("ipsec_in_reject: Invalid policy found. %d", sp->policy);
 1747         }
 1748 
 1749         need_auth = 0;
 1750         need_conf = 0;
 1751         need_icv = 0;
 1752 
 1753         /* XXX should compare policy against ipsec header history */
 1754 
 1755         for (isr = sp->req; isr != NULL; isr = isr->next) {
 1756                 /* get current level */
 1757                 level = ipsec_get_reqlevel(isr, AF_INET);
 1758 
 1759                 switch (isr->saidx.proto) {
 1760                 case IPPROTO_ESP:
 1761                         if (level == IPSEC_LEVEL_REQUIRE) {
 1762                                 need_conf++;
 1763 
 1764                                 if (isr->sav != NULL
 1765                                  && isr->sav->flags == SADB_X_EXT_NONE
 1766                                  && isr->sav->alg_auth != SADB_AALG_NONE)
 1767                                         need_icv++;
 1768                         }
 1769                         break;
 1770                 case IPPROTO_AH:
 1771                         if (level == IPSEC_LEVEL_REQUIRE) {
 1772                                 need_auth++;
 1773                                 need_icv++;
 1774                         }
 1775                         break;
 1776                 case IPPROTO_IPCOMP:
 1777                         /*
 1778                          * we don't really care, as IPcomp document says that
 1779                          * we shouldn't compress small packets, IPComp policy
 1780                          * should always be treated as being in "use" level.
 1781                          */
 1782                         break;
 1783                 case IPPROTO_IPV4:
 1784                 case IPPROTO_IPV6:
 1785                         /*
 1786                          * XXX what shall we do, until introducing more complex
 1787                          * policy checking code?
 1788                          */
 1789                         break;
 1790                 }
 1791         }
 1792 
 1793         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1794                 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
 1795                         need_auth, need_conf, need_icv, m->m_flags));
 1796 
 1797         if ((need_conf && !(m->m_flags & M_DECRYPTED))
 1798          || (!need_auth && need_icv && !(m->m_flags & M_AUTHIPDGM))
 1799          || (need_auth && !(m->m_flags & M_AUTHIPHDR)))
 1800                 return 1;
 1801 
 1802         return 0;
 1803 }
 1804 
 1805 /*
 1806  * Check AH/ESP integrity.
 1807  * This function is called from tcp_input(), udp_input(),
 1808  * and {ah,esp}4_input for tunnel mode
 1809  */
 1810 int
 1811 ipsec4_in_reject_so(struct mbuf *m, struct socket *so)
 1812 {
 1813         struct secpolicy *sp = NULL;
 1814         int error;
 1815         int result;
 1816 
 1817         /* sanity check */
 1818         if (m == NULL)
 1819                 return 0;       /* XXX should be panic ? */
 1820 
 1821         /* get SP for this packet.
 1822          * When we are called from ip_forward(), we call
 1823          * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
 1824          */
 1825         if (so == NULL)
 1826                 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
 1827                     IP_FORWARDING, &error);
 1828         else
 1829                 sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
 1830 
 1831         /* XXX should be panic ? -> No, there may be error. */
 1832         if (sp == NULL)
 1833                 return 0;
 1834 
 1835         result = ipsec_in_reject(sp, m);
 1836         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 1837                 printf("DP ipsec4_in_reject_so call free SP:%p\n", sp));
 1838         key_freesp(sp);
 1839 
 1840         return result;
 1841 }
 1842 
 1843 int
 1844 ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
 1845 {
 1846         if (inp == NULL)
 1847                 return ipsec4_in_reject_so(m, NULL);
 1848         if (inp->inp_socket)
 1849                 return ipsec4_in_reject_so(m, inp->inp_socket);
 1850         else
 1851                 panic("ipsec4_in_reject: invalid inpcb/socket");
 1852 }
 1853 
 1854 #ifdef INET6
 1855 /*
 1856  * Check AH/ESP integrity.
 1857  * This function is called from tcp6_input(), udp6_input(),
 1858  * and {ah,esp}6_input for tunnel mode
 1859  */
 1860 int
 1861 ipsec6_in_reject_so(struct mbuf *m, struct socket *so)
 1862 {
 1863         struct secpolicy *sp = NULL;
 1864         int error;
 1865         int result;
 1866 
 1867         /* sanity check */
 1868         if (m == NULL)
 1869                 return 0;       /* XXX should be panic ? */
 1870 
 1871         /* get SP for this packet.
 1872          * When we are called from ip_forward(), we call
 1873          * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
 1874          */
 1875         if (so == NULL)
 1876                 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
 1877                     IP_FORWARDING, &error);
 1878         else
 1879                 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
 1880 
 1881         if (sp == NULL)
 1882                 return 0;       /* XXX should be panic ? */
 1883 
 1884         result = ipsec_in_reject(sp, m);
 1885         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 1886                 printf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
 1887         key_freesp(sp);
 1888 
 1889         return result;
 1890 }
 1891 
 1892 int
 1893 ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
 1894 {
 1895         if (in6p == NULL)
 1896                 return ipsec6_in_reject_so(m, NULL);
 1897         if (in6p->in6p_socket)
 1898                 return ipsec6_in_reject_so(m, in6p->in6p_socket);
 1899         else
 1900                 panic("ipsec6_in_reject: invalid in6p/socket");
 1901 }
 1902 #endif
 1903 
 1904 /*
 1905  * compute the byte size to be occupied by IPsec header.
 1906  * in case it is tunneled, it includes the size of outer IP header.
 1907  * NOTE: SP passed is free in this function.
 1908  */
 1909 static size_t
 1910 ipsec_hdrsiz(struct secpolicy *sp)
 1911 {
 1912         struct ipsecrequest *isr;
 1913         size_t siz, clen;
 1914 
 1915         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1916                 printf("ipsec_hdrsiz: using SP\n");
 1917                 kdebug_secpolicy(sp));
 1918 
 1919         /* check policy */
 1920         switch (sp->policy) {
 1921         case IPSEC_POLICY_DISCARD:
 1922         case IPSEC_POLICY_BYPASS:
 1923         case IPSEC_POLICY_NONE:
 1924                 return 0;
 1925 
 1926         case IPSEC_POLICY_IPSEC:
 1927                 break;
 1928 
 1929         case IPSEC_POLICY_ENTRUST:
 1930         default:
 1931                 panic("ipsec_hdrsiz: Invalid policy found. %d", sp->policy);
 1932         }
 1933 
 1934         siz = 0;
 1935 
 1936         for (isr = sp->req; isr != NULL; isr = isr->next) {
 1937 
 1938                 clen = 0;
 1939 
 1940                 switch (isr->saidx.proto) {
 1941                 case IPPROTO_ESP:
 1942 #ifdef IPSEC_ESP
 1943                         clen = esp_hdrsiz(isr);
 1944 #else
 1945                         clen = 0;       /* XXX */
 1946 #endif
 1947                         break;
 1948                 case IPPROTO_AH:
 1949                         clen = ah_hdrsiz(isr);
 1950                         break;
 1951                 case IPPROTO_IPCOMP:
 1952                         clen = sizeof(struct ipcomp);
 1953                         break;
 1954                 case IPPROTO_IPV4:
 1955                 case IPPROTO_IPV6:
 1956                         /* the next "if" clause will compute it */
 1957                         clen = 0;
 1958                         break;
 1959                 }
 1960 
 1961                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 1962                         switch (((struct sockaddr *)&isr->saidx.dst)->sa_family) {
 1963                         case AF_INET:
 1964                                 clen += sizeof(struct ip);
 1965                                 break;
 1966 #ifdef INET6
 1967                         case AF_INET6:
 1968                                 clen += sizeof(struct ip6_hdr);
 1969                                 break;
 1970 #endif
 1971                         default:
 1972                                 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
 1973                                     "unknown AF %d in IPsec tunnel SA\n",
 1974                                     ((struct sockaddr *)&isr->saidx.dst)->sa_family));
 1975                                 break;
 1976                         }
 1977                 }
 1978                 siz += clen;
 1979         }
 1980 
 1981         return siz;
 1982 }
 1983 
 1984 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
 1985 size_t
 1986 ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
 1987 {
 1988         struct secpolicy *sp = NULL;
 1989         int error;
 1990         size_t size;
 1991 
 1992         /* sanity check */
 1993         if (m == NULL)
 1994                 return 0;       /* XXX should be panic ? */
 1995         if (inp != NULL && inp->inp_socket == NULL)
 1996                 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
 1997 
 1998         /* get SP for this packet.
 1999          * When we are called from ip_forward(), we call
 2000          * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
 2001          */
 2002         if (inp == NULL)
 2003                 sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 2004         else
 2005                 sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
 2006 
 2007         if (sp == NULL)
 2008                 return 0;       /* XXX should be panic ? */
 2009 
 2010         size = ipsec_hdrsiz(sp);
 2011         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 2012                 printf("DP ipsec4_hdrsiz call free SP:%p\n", sp));
 2013         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 2014                 printf("ipsec4_hdrsiz: size:%lu.\n", (unsigned long)size));
 2015         key_freesp(sp);
 2016 
 2017         return size;
 2018 }
 2019 
 2020 #ifdef INET6
 2021 /* This function is called from ipsec6_hdrsize_tcp(),
 2022  * and maybe from ip6_forward.()
 2023  */
 2024 size_t
 2025 ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
 2026 {
 2027         struct secpolicy *sp = NULL;
 2028         int error;
 2029         size_t size;
 2030 
 2031         /* sanity check */
 2032         if (m == NULL)
 2033                 return 0;       /* XXX should be panic ? */
 2034         if (in6p != NULL && in6p->in6p_socket == NULL)
 2035                 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
 2036 
 2037         /* get SP for this packet */
 2038         /* XXX Is it right to call with IP_FORWARDING. */
 2039         if (in6p == NULL)
 2040                 sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 2041         else
 2042                 sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
 2043 
 2044         if (sp == NULL)
 2045                 return 0;
 2046         size = ipsec_hdrsiz(sp);
 2047         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 2048                 printf("DP ipsec6_hdrsiz call free SP:%p\n", sp));
 2049         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 2050                 printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
 2051         key_freesp(sp);
 2052 
 2053         return size;
 2054 }
 2055 #endif /* INET6 */
 2056 
 2057 #ifdef INET
 2058 /*
 2059  * encapsulate for ipsec tunnel.
 2060  * ip->ip_src must be fixed later on.
 2061  */
 2062 static int
 2063 ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
 2064 {
 2065         struct ip *oip;
 2066         struct ip *ip;
 2067         size_t hlen;
 2068         size_t plen;
 2069 
 2070         /* can't tunnel between different AFs */
 2071         if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
 2072                 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
 2073          || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
 2074                 m_freem(m);
 2075                 return EINVAL;
 2076         }
 2077 #if 0
 2078         /* XXX if the dst is myself, perform nothing. */
 2079         if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
 2080                 m_freem(m);
 2081                 return EINVAL;
 2082         }
 2083 #endif
 2084 
 2085         if (m->m_len < sizeof(*ip))
 2086                 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
 2087 
 2088         ip = mtod(m, struct ip *);
 2089         hlen = ip->ip_hl << 2;
 2090 
 2091         if (m->m_len != hlen)
 2092                 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
 2093 
 2094         /* generate header checksum */
 2095         ip->ip_sum = 0;
 2096         ip->ip_sum = in_cksum(m, hlen);
 2097 
 2098         plen = m->m_pkthdr.len;
 2099 
 2100         /*
 2101          * grow the mbuf to accomodate the new IPv4 header.
 2102          * NOTE: IPv4 options will never be copied.
 2103          */
 2104         if (M_LEADINGSPACE(m->m_next) < hlen) {
 2105                 struct mbuf *n;
 2106                 MGET(n, M_DONTWAIT, MT_DATA);
 2107                 if (!n) {
 2108                         m_freem(m);
 2109                         return ENOBUFS;
 2110                 }
 2111                 n->m_len = hlen;
 2112                 n->m_next = m->m_next;
 2113                 m->m_next = n;
 2114         } else {
 2115                 m->m_next->m_len += hlen;
 2116                 m->m_next->m_data -= hlen;
 2117         }
 2118         oip = mtod(m->m_next, struct ip *);
 2119         m->m_pkthdr.len += hlen;
 2120         ip = mtod(m, struct ip *);
 2121         ovbcopy((void *)ip, (void *)oip, hlen);
 2122         m->m_len = sizeof(struct ip);
 2123         m->m_pkthdr.len -= (hlen - sizeof(struct ip));
 2124 
 2125         /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
 2126         /* ECN consideration. */
 2127         ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
 2128         ip->ip_hl = sizeof(struct ip) >> 2;
 2129         ip->ip_off &= htons(~IP_OFFMASK);
 2130         ip->ip_off &= htons(~IP_MF);
 2131         switch (ip4_ipsec_dfbit) {
 2132         case 0: /* clear DF bit */
 2133                 ip->ip_off &= htons(~IP_DF);
 2134                 break;
 2135         case 1: /* set DF bit */
 2136                 ip->ip_off |= htons(IP_DF);
 2137                 break;
 2138         default:        /* copy DF bit */
 2139                 break;
 2140         }
 2141         ip->ip_p = IPPROTO_IPIP;
 2142         if (plen + sizeof(struct ip) < IP_MAXPACKET)
 2143                 ip->ip_len = htons(plen + sizeof(struct ip));
 2144         else {
 2145                 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
 2146                     "leave ip_len as is (invalid packet)\n"));
 2147         }
 2148         ip->ip_id = ip_newid(NULL);
 2149         bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
 2150                 &ip->ip_src, sizeof(ip->ip_src));
 2151         bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
 2152                 &ip->ip_dst, sizeof(ip->ip_dst));
 2153         ip->ip_ttl = IPDEFTTL;
 2154 
 2155         /* XXX Should ip_src be updated later ? */
 2156 
 2157         return 0;
 2158 }
 2159 #endif /* INET */
 2160 
 2161 #ifdef INET6
 2162 static int
 2163 ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
 2164 {
 2165         struct ip6_hdr *oip6;
 2166         struct ip6_hdr *ip6;
 2167         size_t plen;
 2168         int error;
 2169         struct sockaddr_in6 sa6;
 2170 
 2171         /* can't tunnel between different AFs */
 2172         if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
 2173                 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
 2174          || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET6) {
 2175                 m_freem(m);
 2176                 return EINVAL;
 2177         }
 2178 #if 0
 2179         /* XXX if the dst is myself, perform nothing. */
 2180         if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
 2181                 m_freem(m);
 2182                 return EINVAL;
 2183         }
 2184 #endif
 2185 
 2186         plen = m->m_pkthdr.len;
 2187 
 2188         /*
 2189          * grow the mbuf to accomodate the new IPv6 header.
 2190          */
 2191         if (m->m_len != sizeof(struct ip6_hdr))
 2192                 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
 2193         if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
 2194                 struct mbuf *n;
 2195                 MGET(n, M_DONTWAIT, MT_DATA);
 2196                 if (!n) {
 2197                         m_freem(m);
 2198                         return ENOBUFS;
 2199                 }
 2200                 n->m_len = sizeof(struct ip6_hdr);
 2201                 n->m_next = m->m_next;
 2202                 m->m_next = n;
 2203                 m->m_pkthdr.len += sizeof(struct ip6_hdr);
 2204                 oip6 = mtod(n, struct ip6_hdr *);
 2205         } else {
 2206                 m->m_next->m_len += sizeof(struct ip6_hdr);
 2207                 m->m_next->m_data -= sizeof(struct ip6_hdr);
 2208                 m->m_pkthdr.len += sizeof(struct ip6_hdr);
 2209                 oip6 = mtod(m->m_next, struct ip6_hdr *);
 2210         }
 2211         ip6 = mtod(m, struct ip6_hdr *);
 2212         ovbcopy((void *)ip6, (void *)oip6, sizeof(struct ip6_hdr));
 2213 
 2214         /* Fake link-local scope-class addresses */
 2215         in6_clearscope(&oip6->ip6_src);
 2216         in6_clearscope(&oip6->ip6_dst);
 2217 
 2218         /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
 2219         /* ECN consideration. */
 2220         ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
 2221         if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr))
 2222                 ip6->ip6_plen = htons(plen);
 2223         else {
 2224                 /* ip6->ip6_plen will be updated in ip6_output() */
 2225         }
 2226         ip6->ip6_nxt = IPPROTO_IPV6;
 2227 
 2228         sa6 = *(struct sockaddr_in6 *)&sav->sah->saidx.src;
 2229         if ((error = sa6_embedscope(&sa6, 0)) != 0)
 2230                 return (error);
 2231         ip6->ip6_src = sa6.sin6_addr;
 2232 
 2233         sa6 = *(struct sockaddr_in6 *)&sav->sah->saidx.dst;
 2234         if ((error = sa6_embedscope(&sa6, 0)) != 0)
 2235                 return (error);
 2236         ip6->ip6_dst = sa6.sin6_addr;
 2237 
 2238         ip6->ip6_hlim = IPV6_DEFHLIM;
 2239 
 2240         /* XXX Should ip6_src be updated later ? */
 2241 
 2242         return 0;
 2243 }
 2244 #endif /* INET6 */
 2245 
 2246 /*
 2247  * Check the variable replay window.
 2248  * ipsec_chkreplay() performs replay check before ICV verification.
 2249  * ipsec_updatereplay() updates replay bitmap.  This must be called after
 2250  * ICV verification (it also performs replay check, which is usually done
 2251  * beforehand).
 2252  * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
 2253  *
 2254  * based on RFC 2401.
 2255  *
 2256  * XXX need to update for 64bit sequence number - 2401bis
 2257  */
 2258 int
 2259 ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
 2260 {
 2261         const struct secreplay *replay;
 2262         u_int32_t diff;
 2263         int fr;
 2264         u_int32_t wsizeb;       /* constant: bits of window size */
 2265         int frlast;             /* constant: last frame */
 2266 
 2267         /* sanity check */
 2268         if (sav == NULL)
 2269                 panic("ipsec_chkreplay: NULL pointer was passed.");
 2270 
 2271         replay = sav->replay;
 2272 
 2273         if (replay->wsize == 0)
 2274                 return 1;       /* no need to check replay. */
 2275 
 2276         /* constant */
 2277         frlast = replay->wsize - 1;
 2278         wsizeb = replay->wsize << 3;
 2279 
 2280         /* sequence number of 0 is invalid */
 2281         if (seq == 0)
 2282                 return 0;
 2283 
 2284         /* first time is always okay */
 2285         if (replay->count == 0)
 2286                 return 1;
 2287 
 2288         if (seq > replay->lastseq) {
 2289                 /* larger sequences are okay */
 2290                 return 1;
 2291         } else {
 2292                 /* seq is equal or less than lastseq. */
 2293                 diff = replay->lastseq - seq;
 2294 
 2295                 /* over range to check, i.e. too old or wrapped */
 2296                 if (diff >= wsizeb)
 2297                         return 0;
 2298 
 2299                 fr = frlast - diff / 8;
 2300 
 2301                 /* this packet already seen ? */
 2302                 if (replay->bitmap[fr] & (1 << (diff % 8)))
 2303                         return 0;
 2304 
 2305                 /* out of order but good */
 2306                 return 1;
 2307         }
 2308 }
 2309 
 2310 /*
 2311  * check replay counter whether to update or not.
 2312  * OUT: 0:      OK
 2313  *      1:      NG
 2314  * XXX need to update for 64bit sequence number - 2401bis
 2315  */
 2316 int
 2317 ipsec_updatereplay(u_int32_t seq, struct secasvar *sav)
 2318 {
 2319         struct secreplay *replay;
 2320         u_int64_t diff;
 2321         int fr;
 2322         u_int32_t wsizeb;       /* constant: bits of window size */
 2323         int frlast;             /* constant: last frame */
 2324 
 2325         /* sanity check */
 2326         if (sav == NULL)
 2327                 panic("ipsec_chkreplay: NULL pointer was passed.");
 2328 
 2329         replay = sav->replay;
 2330 
 2331         if (replay->wsize == 0)
 2332                 goto ok;        /* no need to check replay. */
 2333 
 2334         /* constant */
 2335         frlast = replay->wsize - 1;
 2336         wsizeb = replay->wsize << 3;
 2337 
 2338         /* sequence number of 0 is invalid */
 2339         if (seq == 0)
 2340                 return 1;
 2341 
 2342         /* first time */
 2343         if (replay->count == 0) {
 2344                 replay->lastseq = seq;
 2345                 bzero(replay->bitmap, replay->wsize);
 2346                 replay->bitmap[frlast] = 1;
 2347                 goto ok;
 2348         }
 2349 
 2350         if (seq > replay->lastseq) {
 2351                 /* seq is larger than lastseq. */
 2352                 diff = seq - replay->lastseq;
 2353 
 2354                 /* new larger sequence number */
 2355                 if (diff < wsizeb) {
 2356                         /* In window */
 2357                         /* set bit for this packet */
 2358                         vshiftl(replay->bitmap, diff, replay->wsize);
 2359                         replay->bitmap[frlast] |= 1;
 2360                 } else {
 2361                         /* this packet has a "way larger" */
 2362                         bzero(replay->bitmap, replay->wsize);
 2363                         replay->bitmap[frlast] = 1;
 2364                 }
 2365                 replay->lastseq = seq;
 2366 
 2367                 /* larger is good */
 2368         } else {
 2369                 /* seq is equal or less than lastseq. */
 2370                 diff = replay->lastseq - seq;
 2371 
 2372                 /* over range to check, i.e. too old or wrapped */
 2373                 if (diff >= wsizeb)
 2374                         return 1;
 2375 
 2376                 fr = frlast - diff / 8;
 2377 
 2378                 /* this packet already seen ? */
 2379                 if (replay->bitmap[fr] & (1 << (diff % 8)))
 2380                         return 1;
 2381 
 2382                 /* mark as seen */
 2383                 replay->bitmap[fr] |= (1 << (diff % 8));
 2384 
 2385                 /* out of order but good */
 2386         }
 2387 
 2388 ok:
 2389         if (replay->count == 0xffffffff) {
 2390 
 2391                 /* set overflow flag */
 2392                 replay->overflow++;
 2393 
 2394                 /* don't increment, no more packets accepted */
 2395                 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
 2396                         return 1;
 2397 
 2398                 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
 2399                     replay->overflow, ipsec_logsastr(sav)));
 2400         }
 2401 
 2402         replay->count++;
 2403 
 2404         return 0;
 2405 }
 2406 
 2407 /*
 2408  * shift variable length buffer to left.
 2409  * IN:  bitmap: pointer to the buffer
 2410  *      nbit:   the number of to shift.
 2411  *      wsize:  buffer size (bytes).
 2412  */
 2413 static void
 2414 vshiftl(unsigned char *bitmap, int nbit, int wsize)
 2415 {
 2416         int s, j, i;
 2417         unsigned char over;
 2418 
 2419         for (j = 0; j < nbit; j += 8) {
 2420                 s = (nbit - j < 8) ? (nbit - j): 8;
 2421                 bitmap[0] <<= s;
 2422                 for (i = 1; i < wsize; i++) {
 2423                         over = (bitmap[i] >> (8 - s));
 2424                         bitmap[i] <<= s;
 2425                         bitmap[i - 1] |= over;
 2426                 }
 2427         }
 2428 
 2429         return;
 2430 }
 2431 
 2432 const char *
 2433 ipsec4_logpacketstr(struct ip *ip, u_int32_t spi)
 2434 {
 2435         static char buf[256];
 2436         char *p;
 2437         u_int8_t *s, *d;
 2438 
 2439         s = (u_int8_t *)(&ip->ip_src);
 2440         d = (u_int8_t *)(&ip->ip_dst);
 2441 
 2442         p = buf;
 2443         snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
 2444         while (p && *p)
 2445                 p++;
 2446         snprintf(p, sizeof(buf) - (p - buf), "src=%u.%u.%u.%u",
 2447                 s[0], s[1], s[2], s[3]);
 2448         while (p && *p)
 2449                 p++;
 2450         snprintf(p, sizeof(buf) - (p - buf), " dst=%u.%u.%u.%u",
 2451                 d[0], d[1], d[2], d[3]);
 2452         while (p && *p)
 2453                 p++;
 2454         snprintf(p, sizeof(buf) - (p - buf), ")");
 2455 
 2456         return buf;
 2457 }
 2458 
 2459 #ifdef INET6
 2460 const char *
 2461 ipsec6_logpacketstr(struct ip6_hdr *ip6, u_int32_t spi)
 2462 {
 2463         static char buf[256];
 2464         char *p;
 2465 
 2466         p = buf;
 2467         snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
 2468         while (p && *p)
 2469                 p++;
 2470         snprintf(p, sizeof(buf) - (p - buf), "src=%s",
 2471                 ip6_sprintf(&ip6->ip6_src));
 2472         while (p && *p)
 2473                 p++;
 2474         snprintf(p, sizeof(buf) - (p - buf), " dst=%s",
 2475                 ip6_sprintf(&ip6->ip6_dst));
 2476         while (p && *p)
 2477                 p++;
 2478         snprintf(p, sizeof(buf) - (p - buf), ")");
 2479 
 2480         return buf;
 2481 }
 2482 #endif /* INET6 */
 2483 
 2484 const char *
 2485 ipsec_logsastr(struct secasvar *sav)
 2486 {
 2487         static char buf[256];
 2488         char *p;
 2489         struct secasindex *saidx = &sav->sah->saidx;
 2490 
 2491         /* validity check */
 2492         if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
 2493                         != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family)
 2494                 panic("ipsec_logsastr: family mismatched.");
 2495 
 2496         p = buf;
 2497         snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
 2498         while (p && *p)
 2499                 p++;
 2500         if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET) {
 2501                 u_int8_t *s, *d;
 2502                 s = (u_int8_t *)&((struct sockaddr_in *)&saidx->src)->sin_addr;
 2503                 d = (u_int8_t *)&((struct sockaddr_in *)&saidx->dst)->sin_addr;
 2504                 snprintf(p, sizeof(buf) - (p - buf),
 2505                         "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
 2506                         s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
 2507         }
 2508 #ifdef INET6
 2509         else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
 2510                 snprintf(p, sizeof(buf) - (p - buf),
 2511                         "src=%s",
 2512                         ip6_sprintf(&((struct sockaddr_in6 *)&saidx->src)->sin6_addr));
 2513                 while (p && *p)
 2514                         p++;
 2515                 snprintf(p, sizeof(buf) - (p - buf),
 2516                         " dst=%s",
 2517                         ip6_sprintf(&((struct sockaddr_in6 *)&saidx->dst)->sin6_addr));
 2518         }
 2519 #endif
 2520         while (p && *p)
 2521                 p++;
 2522         snprintf(p, sizeof(buf) - (p - buf), ")");
 2523 
 2524         return buf;
 2525 }
 2526 
 2527 void
 2528 ipsec_dumpmbuf(struct mbuf *m)
 2529 {
 2530         int totlen;
 2531         int i;
 2532         u_char *p;
 2533 
 2534         totlen = 0;
 2535         printf("---\n");
 2536         while (m) {
 2537                 p = mtod(m, u_char *);
 2538                 for (i = 0; i < m->m_len; i++) {
 2539                         printf("%02x ", p[i]);
 2540                         totlen++;
 2541                         if (totlen % 16 == 0)
 2542                                 printf("\n");
 2543                 }
 2544                 m = m->m_next;
 2545         }
 2546         if (totlen % 16 != 0)
 2547                 printf("\n");
 2548         printf("---\n");
 2549 }
 2550 
 2551 #ifdef INET
 2552 static int
 2553 ipsec4_checksa(struct ipsecrequest *isr, 
 2554         struct ipsec_output_state *state)
 2555 {
 2556         struct ip *ip;
 2557         struct secasindex saidx;
 2558         struct sockaddr_in *sin;
 2559 
 2560         /* make SA index for search proper SA */
 2561         ip = mtod(state->m, struct ip *);
 2562         bcopy(&isr->saidx, &saidx, sizeof(saidx));
 2563         saidx.mode = isr->saidx.mode;
 2564         saidx.reqid = isr->saidx.reqid;
 2565         sin = (struct sockaddr_in *)&saidx.src;
 2566         if (sin->sin_len == 0) {
 2567                 bzero(sin, sizeof(*sin));
 2568                 sin->sin_len = sizeof(*sin);
 2569                 sin->sin_family = AF_INET;
 2570                 sin->sin_port = IPSEC_PORT_ANY;
 2571                 bcopy(&ip->ip_src, &sin->sin_addr, sizeof(sin->sin_addr));
 2572         }
 2573         sin = (struct sockaddr_in *)&saidx.dst;
 2574         if (sin->sin_len == 0) {
 2575                 bzero(sin, sizeof(*sin));
 2576                 sin->sin_len = sizeof(*sin);
 2577                 sin->sin_family = AF_INET;
 2578                 sin->sin_port = IPSEC_PORT_ANY;
 2579                 bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(sin->sin_addr));
 2580         }
 2581 
 2582         return key_checkrequest(isr, &saidx);
 2583 }
 2584 /*
 2585  * IPsec output logic for IPv4.
 2586  */
 2587 int
 2588 ipsec4_output(struct ipsec_output_state *state, struct secpolicy *sp, int flags)
 2589 {
 2590         struct rtentry *rt;
 2591         struct ip *ip = NULL;
 2592         struct ipsecrequest *isr = NULL;
 2593         int s;
 2594         int error;
 2595         union {
 2596                 struct sockaddr         dst;
 2597                 struct sockaddr_in      dst4;
 2598         } u;
 2599 
 2600         if (!state)
 2601                 panic("state == NULL in ipsec4_output");
 2602         if (!state->m)
 2603                 panic("state->m == NULL in ipsec4_output");
 2604         if (!state->ro)
 2605                 panic("state->ro == NULL in ipsec4_output");
 2606         if (!state->dst)
 2607                 panic("state->dst == NULL in ipsec4_output");
 2608         state->encap = 0;
 2609 
 2610         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 2611                 printf("ipsec4_output: applyed SP\n");
 2612                 kdebug_secpolicy(sp));
 2613 
 2614         for (isr = sp->req; isr != NULL; isr = isr->next) {
 2615 
 2616 #if 0   /* give up to check restriction of transport mode */
 2617         /* XXX but should be checked somewhere */
 2618                 /*
 2619                  * some of the IPsec operation must be performed only in
 2620                  * originating case.
 2621                  */
 2622                 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT
 2623                  && (flags & IP_FORWARDING))
 2624                         continue;
 2625 #endif
 2626                 error = ipsec4_checksa(isr, state);
 2627                 if (error != 0) {
 2628                         /*
 2629                          * IPsec processing is required, but no SA found.
 2630                          * I assume that key_acquire() had been called
 2631                          * to get/establish the SA. Here I discard
 2632                          * this packet because it is responsibility for
 2633                          * upper layer to retransmit the packet.
 2634                          */
 2635                         IPSEC_STATINC(IPSEC_STAT_OUT_NOSA);
 2636                         goto bad;
 2637                 }
 2638 
 2639                 /* validity check */
 2640                 if (isr->sav == NULL) {
 2641                         switch (ipsec_get_reqlevel(isr, AF_INET)) {
 2642                         case IPSEC_LEVEL_USE:
 2643                                 continue;
 2644                         case IPSEC_LEVEL_REQUIRE:
 2645                                 if (isr->saidx.proto == AF_INET ||
 2646                                     isr->saidx.proto == AF_INET6)
 2647                                         break;
 2648                                 /* must be not reached here. */
 2649                                 panic("ipsec4_output: no SA found, but required.");
 2650                         }
 2651                 }
 2652 
 2653                 /*
 2654                  * If there is no valid SA, we give up to process any
 2655                  * more.  In such a case, the SA's status is changed
 2656                  * from DYING to DEAD after allocating.  If a packet
 2657                  * send to the receiver by dead SA, the receiver can
 2658                  * not decode a packet because SA has been dead.
 2659                  */
 2660                 if (isr->sav->state != SADB_SASTATE_MATURE
 2661                  && isr->sav->state != SADB_SASTATE_DYING) {
 2662                         IPSEC_STATINC(IPSEC_STAT_OUT_NOSA);
 2663                         error = EINVAL;
 2664                         goto bad;
 2665                 }
 2666 
 2667                 /*
 2668                  * There may be the case that SA status will be changed when
 2669                  * we are refering to one. So calling splsoftnet().
 2670                  */
 2671                 s = splsoftnet();
 2672 
 2673                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 2674                         /*
 2675                          * build IPsec tunnel.
 2676                          */
 2677                         /* XXX should be processed with other familiy */
 2678                         if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET) {
 2679                                 ipseclog((LOG_ERR, "ipsec4_output: "
 2680                                     "family mismatched between inner and outer spi=%u\n",
 2681                                     (u_int32_t)ntohl(isr->sav->spi)));
 2682                                 splx(s);
 2683                                 error = EAFNOSUPPORT;
 2684                                 goto bad;
 2685                         }
 2686 
 2687                         state->m = ipsec4_splithdr(state->m);
 2688                         if (!state->m) {
 2689                                 splx(s);
 2690                                 error = ENOMEM;
 2691                                 goto bad;
 2692                         }
 2693                         error = ipsec4_encapsulate(state->m, isr->sav);
 2694                         splx(s);
 2695                         if (error) {
 2696                                 state->m = NULL;
 2697                                 goto bad;
 2698                         }
 2699                         ip = mtod(state->m, struct ip *);
 2700 
 2701                         state->ro = &isr->sav->sah->sa_route;
 2702 
 2703                         sockaddr_in_init(&u.dst4, &ip->ip_dst, 0);
 2704                         if ((rt = rtcache_lookup(state->ro, &u.dst)) == NULL) {
 2705                                 rtcache_free(state->ro);
 2706                                 IP_STATINC(IP_STAT_NOROUTE);
 2707                                 error = EHOSTUNREACH;
 2708                                 goto bad;
 2709                         }
 2710 
 2711                         /* XXX state->dst will dangle if the rtentry goes
 2712                          * away!  I suggest sockaddr_dup()'ing it.  --dyoung
 2713                          */
 2714                         /* adjust state->dst if tunnel endpoint is offlink */
 2715                         if (rt->rt_flags & RTF_GATEWAY) {
 2716                                 state->dst = rt->rt_gateway;
 2717                         } else {
 2718                                 state->dst = rtcache_getdst(state->ro);
 2719                         }
 2720 
 2721                         state->encap++;
 2722                 } else
 2723                         splx(s);
 2724 
 2725                 state->m = ipsec4_splithdr(state->m);
 2726                 if (!state->m) {
 2727                         error = ENOMEM;
 2728                         goto bad;
 2729                 }
 2730                 switch (isr->saidx.proto) {
 2731                 case IPPROTO_ESP:
 2732 #ifdef IPSEC_ESP
 2733                         if ((error = esp4_output(state->m, isr)) != 0) {
 2734                                 state->m = NULL;
 2735                                 goto bad;
 2736                         }
 2737                         break;
 2738 #else
 2739                         m_freem(state->m);
 2740                         state->m = NULL;
 2741                         error = EINVAL;
 2742                         goto bad;
 2743 #endif
 2744                 case IPPROTO_AH:
 2745                         if ((error = ah4_output(state->m, isr)) != 0) {
 2746                                 state->m = NULL;
 2747                                 goto bad;
 2748                         }
 2749                         break;
 2750                 case IPPROTO_IPCOMP:
 2751                         if ((error = ipcomp4_output(state->m, isr)) != 0) {
 2752                                 state->m = NULL;
 2753                                 goto bad;
 2754                         }
 2755                         break;
 2756                 case IPPROTO_IPV4:
 2757                         break;
 2758                 case IPPROTO_IPV6:
 2759                         ipseclog((LOG_ERR, "ipsec4_output: "
 2760                             "family mismatched between inner and outer "
 2761                             "header\n"));
 2762                         error = EAFNOSUPPORT;
 2763                         goto bad;
 2764                 default:
 2765                         ipseclog((LOG_ERR,
 2766                             "ipsec4_output: unknown ipsec protocol %d\n",
 2767                             isr->saidx.proto));
 2768                         m_freem(state->m);
 2769                         state->m = NULL;
 2770                         error = EINVAL;
 2771                         goto bad;
 2772                 }
 2773 
 2774                 if (state->m == 0) {
 2775                         error = ENOMEM;
 2776                         goto bad;
 2777                 }
 2778                 ip = mtod(state->m, struct ip *);
 2779         }
 2780 
 2781         return 0;
 2782 
 2783 bad:
 2784         m_freem(state->m);
 2785         state->m = NULL;
 2786         return error;
 2787 }
 2788 #endif
 2789 
 2790 #ifdef INET6
 2791 static int
 2792 ipsec6_checksa(struct ipsecrequest *isr, 
 2793         struct ipsec_output_state *state, int tunnel)
 2794 {
 2795         struct ip6_hdr *ip6;
 2796         struct secasindex saidx;
 2797         struct sockaddr_in6 *sin6;
 2798 
 2799         if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 2800 #ifdef DIAGNOSTIC
 2801                 if (!tunnel)
 2802                         panic("ipsec6_checksa/inconsistent tunnel attribute");
 2803 #endif
 2804                 /* When tunnel mode, SA peers must be specified. */
 2805                 return key_checkrequest(isr, &isr->saidx);
 2806         }
 2807 
 2808         /* make SA index for search proper SA */
 2809         ip6 = mtod(state->m, struct ip6_hdr *);
 2810         if (tunnel) {
 2811                 bzero(&saidx, sizeof(saidx));
 2812                 saidx.proto = isr->saidx.proto;
 2813         } else
 2814                 bcopy(&isr->saidx, &saidx, sizeof(saidx));
 2815         saidx.mode = isr->saidx.mode;
 2816         saidx.reqid = isr->saidx.reqid;
 2817         sin6 = (struct sockaddr_in6 *)&saidx.src;
 2818         if (sin6->sin6_len == 0 || tunnel) {
 2819                 bzero(sin6, sizeof(*sin6));
 2820                 sin6->sin6_len = sizeof(*sin6);
 2821                 sin6->sin6_family = AF_INET6;
 2822                 sin6->sin6_port = IPSEC_PORT_ANY;
 2823                 sin6->sin6_addr = ip6->ip6_src;
 2824         }
 2825         sin6 = (struct sockaddr_in6 *)&saidx.dst;
 2826         if (sin6->sin6_len == 0 || tunnel) {
 2827                 bzero(sin6, sizeof(*sin6));
 2828                 sin6->sin6_len = sizeof(*sin6);
 2829                 sin6->sin6_family = AF_INET6;
 2830                 sin6->sin6_port = IPSEC_PORT_ANY;
 2831                 sin6->sin6_addr = ip6->ip6_dst;
 2832         }
 2833 
 2834         return key_checkrequest(isr, &saidx);
 2835 }
 2836 /*
 2837  * IPsec output logic for IPv6, transport mode.
 2838  */
 2839 int
 2840 ipsec6_output_trans(struct ipsec_output_state *state, u_char *nexthdrp,
 2841     struct mbuf *mprev, struct secpolicy *sp, int flags, int *tun)
 2842 {
 2843         struct ip6_hdr *ip6;
 2844         struct ipsecrequest *isr = NULL;
 2845         int error = 0;
 2846         int plen;
 2847 
 2848         if (!state)
 2849                 panic("state == NULL in ipsec6_output_trans");
 2850         if (!state->m)
 2851                 panic("state->m == NULL in ipsec6_output_trans");
 2852         if (!nexthdrp)
 2853                 panic("nexthdrp == NULL in ipsec6_output_trans");
 2854         if (!mprev)
 2855                 panic("mprev == NULL in ipsec6_output_trans");
 2856         if (!sp)
 2857                 panic("sp == NULL in ipsec6_output_trans");
 2858         if (!tun)
 2859                 panic("tun == NULL in ipsec6_output_trans");
 2860 
 2861         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 2862                 printf("ipsec6_output_trans: applyed SP\n");
 2863                 kdebug_secpolicy(sp));
 2864 
 2865         *tun = 0;
 2866         for (isr = sp->req; isr; isr = isr->next) {
 2867                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 2868                         /* the rest will be handled by ipsec6_output_tunnel() */
 2869                         break;
 2870                 }
 2871 
 2872                 error = ipsec6_checksa(isr, state, 0);
 2873                 if (error == ENOENT) {
 2874                         /*
 2875                          * IPsec processing is required, but no SA found.
 2876                          * I assume that key_acquire() had been called
 2877                          * to get/establish the SA. Here I discard
 2878                          * this packet because it is responsibility for
 2879                          * upper layer to retransmit the packet.
 2880                          */
 2881                         IPSEC6_STATINC(IPSEC_STAT_OUT_NOSA);
 2882 
 2883                         /*
 2884                          * Notify the fact that the packet is discarded
 2885                          * to ourselves. I believe this is better than
 2886                          * just silently discarding. (jinmei@kame.net)
 2887                          * XXX: should we restrict the error to TCP packets?
 2888                          * XXX: should we directly notify sockets via
 2889                          *      pfctlinputs?
 2890                          *
 2891                          * Noone have initialized rcvif until this point,
 2892                          * so clear it.
 2893                          */
 2894                         if ((state->m->m_flags & M_PKTHDR) != 0)
 2895                                 state->m->m_pkthdr.rcvif = NULL;
 2896                         icmp6_error(state->m, ICMP6_DST_UNREACH,
 2897                                     ICMP6_DST_UNREACH_ADMIN, 0);
 2898                         state->m = NULL; /* icmp6_error freed the mbuf */
 2899                         goto bad;
 2900                 }
 2901 
 2902                 /* validity check */
 2903                 if (isr->sav == NULL) {
 2904                         switch (ipsec_get_reqlevel(isr, AF_INET6)) {
 2905                         case IPSEC_LEVEL_USE:
 2906                                 continue;
 2907                         case IPSEC_LEVEL_REQUIRE:
 2908                                 /* must be not reached here. */
 2909                                 panic("ipsec6_output_trans: no SA found, but required.");
 2910                         }
 2911                 }
 2912 
 2913                 /*
 2914                  * If there is no valid SA, we give up to process.
 2915                  * see same place at ipsec4_output().
 2916                  */
 2917                 if (isr->sav->state != SADB_SASTATE_MATURE
 2918                  && isr->sav->state != SADB_SASTATE_DYING) {
 2919                         IPSEC6_STATINC(IPSEC_STAT_OUT_NOSA);
 2920                         error = EINVAL;
 2921                         goto bad;
 2922                 }
 2923 
 2924                 switch (isr->saidx.proto) {
 2925                 case IPPROTO_ESP:
 2926 #ifdef IPSEC_ESP
 2927                         error = esp6_output(state->m, nexthdrp, mprev->m_next, isr);
 2928 #else
 2929                         m_freem(state->m);
 2930                         error = EINVAL;
 2931 #endif
 2932                         break;
 2933                 case IPPROTO_AH:
 2934                         error = ah6_output(state->m, nexthdrp, mprev->m_next, isr);
 2935                         break;
 2936                 case IPPROTO_IPCOMP:
 2937                         error = ipcomp6_output(state->m, nexthdrp, mprev->m_next, isr);
 2938                         break;
 2939                 default:
 2940                         ipseclog((LOG_ERR, "ipsec6_output_trans: "
 2941                             "unknown ipsec protocol %d\n", isr->saidx.proto));
 2942                         m_freem(state->m);
 2943                         IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
 2944                         error = EINVAL;
 2945                         break;
 2946                 }
 2947                 if (error) {
 2948                         state->m = NULL;
 2949                         goto bad;
 2950                 }
 2951                 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
 2952                 if (plen > IPV6_MAXPACKET) {
 2953                         ipseclog((LOG_ERR, "ipsec6_output_trans: "
 2954                             "IPsec with IPv6 jumbogram is not supported\n"));
 2955                         IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
 2956                         error = EINVAL; /* XXX */
 2957                         goto bad;
 2958                 }
 2959                 ip6 = mtod(state->m, struct ip6_hdr *);
 2960                 ip6->ip6_plen = htons(plen);
 2961         }
 2962 
 2963         /* if we have more to go, we need a tunnel mode processing */
 2964         if (isr != NULL)
 2965                 *tun = 1;
 2966 
 2967         return 0;
 2968 
 2969 bad:
 2970         m_freem(state->m);
 2971         state->m = NULL;
 2972         return error;
 2973 }
 2974 
 2975 /*
 2976  * IPsec output logic for IPv6, tunnel mode.
 2977  */
 2978 int
 2979 ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp,
 2980     int flags)
 2981 {
 2982         struct rtentry *rt;
 2983         struct ip6_hdr *ip6;
 2984         struct ipsecrequest *isr = NULL;
 2985         int error = 0;
 2986         int plen;
 2987         int s;
 2988 
 2989         if (!state)
 2990                 panic("state == NULL in ipsec6_output_tunnel");
 2991         if (!state->m)
 2992                 panic("state->m == NULL in ipsec6_output_tunnel");
 2993         if (!sp)
 2994                 panic("sp == NULL in ipsec6_output_tunnel");
 2995 
 2996         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 2997                 printf("ipsec6_output_tunnel: applyed SP\n");
 2998                 kdebug_secpolicy(sp));
 2999 
 3000         /*
 3001          * transport mode ipsec (before the 1st tunnel mode) is already
 3002          * processed by ipsec6_output_trans().
 3003          */
 3004         for (isr = sp->req; isr; isr = isr->next) {
 3005                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 3006                         break;
 3007         }
 3008 
 3009         for (/* already initialized */; isr; isr = isr->next) {
 3010                 error = ipsec6_checksa(isr, state, 1);
 3011                 if (error == ENOENT) {
 3012                         /*
 3013                          * IPsec processing is required, but no SA found.
 3014                          * I assume that key_acquire() had been called
 3015                          * to get/establish the SA. Here I discard
 3016                          * this packet because it is responsibility for
 3017                          * upper layer to retransmit the packet.
 3018                          */
 3019                         IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
 3020                         error = ENOENT;
 3021                         goto bad;
 3022                 }
 3023 
 3024                 /* validity check */
 3025                 if (isr->sav == NULL) {
 3026                         switch (ipsec_get_reqlevel(isr, AF_INET6)) {
 3027                         case IPSEC_LEVEL_USE:
 3028                                 continue;
 3029                         case IPSEC_LEVEL_REQUIRE:
 3030                                 /* must be not reached here. */
 3031                                 panic("ipsec6_output_tunnel: no SA found, but required.");
 3032                         }
 3033                 }
 3034 
 3035                 /*
 3036                  * If there is no valid SA, we give up to process.
 3037                  * see same place at ipsec4_output().
 3038                  */
 3039                 if (isr->sav->state != SADB_SASTATE_MATURE
 3040                  && isr->sav->state != SADB_SASTATE_DYING) {
 3041                         IPSEC6_STATINC(IPSEC_STAT_OUT_NOSA);
 3042                         error = EINVAL;
 3043                         goto bad;
 3044                 }
 3045 
 3046                 /*
 3047                  * There may be the case that SA status will be changed when
 3048                  * we are refering to one. So calling splsoftnet().
 3049                  */
 3050                 s = splsoftnet();
 3051 
 3052                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 3053                         /*
 3054                          * build IPsec tunnel.
 3055                          */
 3056                         /* XXX should be processed with other familiy */
 3057                         if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET6) {
 3058                                 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
 3059                                     "family mismatched between inner and outer, spi=%u\n",
 3060                                     (u_int32_t)ntohl(isr->sav->spi)));
 3061                                 splx(s);
 3062                                 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
 3063                                 error = EAFNOSUPPORT;
 3064                                 goto bad;
 3065                         }
 3066 
 3067                         state->m = ipsec6_splithdr(state->m);
 3068                         if (!state->m) {
 3069                                 splx(s);
 3070                                 IPSEC6_STATINC(IPSEC_STAT_OUT_NOMEM);
 3071                                 error = ENOMEM;
 3072                                 goto bad;
 3073                         }
 3074                         error = ipsec6_encapsulate(state->m, isr->sav);
 3075                         splx(s);
 3076                         if (error) {
 3077                                 state->m = 0;
 3078                                 goto bad;
 3079                         }
 3080                         ip6 = mtod(state->m, struct ip6_hdr *);
 3081 
 3082                         state->ro = &isr->sav->sah->sa_route;
 3083                         union {
 3084                                 struct sockaddr         dst;
 3085                                 struct sockaddr_in6     dst6;
 3086                         } u;
 3087 
 3088                         sockaddr_in6_init(&u.dst6, &ip6->ip6_dst, 0, 0, 0);
 3089                         if ((rt = rtcache_lookup(state->ro, &u.dst)) == NULL) {
 3090                                 rtcache_free(state->ro);
 3091                                 IP6_STATINC(IP6_STAT_NOROUTE);
 3092                                 IPSEC6_STATINC(IPSEC_STAT_OUT_NOROUTE);
 3093                                 error = EHOSTUNREACH;
 3094                                 goto bad;
 3095                         }
 3096 
 3097                         /* XXX state->dst will dangle if the rtentry goes
 3098                          * away!  I suggest sockaddr_dup()'ing it.  --dyoung
 3099                          */
 3100                         /* adjust state->dst if tunnel endpoint is offlink */
 3101                         if (rt->rt_flags & RTF_GATEWAY) {
 3102                                 state->dst = rt->rt_gateway;
 3103                         } else
 3104                                 state->dst = rtcache_getdst(state->ro);
 3105                 } else
 3106                         splx(s);
 3107 
 3108                 state->m = ipsec6_splithdr(state->m);
 3109                 if (!state->m) {
 3110                         IPSEC6_STATINC(IPSEC_STAT_OUT_NOMEM);
 3111                         error = ENOMEM;
 3112                         goto bad;
 3113                 }
 3114                 ip6 = mtod(state->m, struct ip6_hdr *);
 3115                 switch (isr->saidx.proto) {
 3116                 case IPPROTO_ESP:
 3117 #ifdef IPSEC_ESP
 3118                         error = esp6_output(state->m, &ip6->ip6_nxt,
 3119                                             state->m->m_next, isr);
 3120 #else
 3121                         m_freem(state->m);
 3122                         error = EINVAL;
 3123 #endif
 3124                         break;
 3125                 case IPPROTO_AH:
 3126                         error = ah6_output(state->m, &ip6->ip6_nxt,
 3127                                            state->m->m_next, isr);
 3128                         break;
 3129                 case IPPROTO_IPCOMP:
 3130                         /* XXX code should be here */
 3131                         /* FALLTHROUGH */
 3132                 default:
 3133                         ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
 3134                             "unknown ipsec protocol %d\n", isr->saidx.proto));
 3135                         m_freem(state->m);
 3136                         IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
 3137                         error = EINVAL;
 3138                         break;
 3139                 }
 3140                 if (error) {
 3141                         state->m = NULL;
 3142                         goto bad;
 3143                 }
 3144                 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
 3145                 if (plen > IPV6_MAXPACKET) {
 3146                         ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
 3147                             "IPsec with IPv6 jumbogram is not supported\n"));
 3148                         IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
 3149                         error = EINVAL; /* XXX */
 3150                         goto bad;
 3151                 }
 3152                 ip6 = mtod(state->m, struct ip6_hdr *);
 3153                 ip6->ip6_plen = htons(plen);
 3154         }
 3155 
 3156         return 0;
 3157 
 3158 bad:
 3159         m_freem(state->m);
 3160         state->m = NULL;
 3161         return error;
 3162 }
 3163 #endif /* INET6 */
 3164 
 3165 #ifdef INET
 3166 /*
 3167  * Chop IP header and option off from the payload.
 3168  */
 3169 static struct mbuf *
 3170 ipsec4_splithdr(struct mbuf *m)
 3171 {
 3172         struct mbuf *mh;
 3173         struct ip *ip;
 3174         int hlen;
 3175 
 3176         if (m->m_len < sizeof(struct ip)) {
 3177                 /* XXX Print and drop until we understand. */
 3178                 printf("ipsec4_splithdr: m->m_len %d m_length %d < %zu\n",
 3179                        m->m_len, m_length(m), sizeof(struct ip));
 3180                 m_freem(m);
 3181                 return NULL;
 3182 #if 0
 3183                 panic("ipsec4_splithdr: first mbuf too short");
 3184 #endif
 3185         }
 3186         ip = mtod(m, struct ip *);
 3187         hlen = ip->ip_hl << 2;
 3188         if (m->m_len > hlen) {
 3189                 MGETHDR(mh, M_DONTWAIT, MT_HEADER);
 3190                 if (!mh) {
 3191                         m_freem(m);
 3192                         return NULL;
 3193                 }
 3194                 M_MOVE_PKTHDR(mh, m);
 3195                 MH_ALIGN(mh, hlen);
 3196                 m->m_len -= hlen;
 3197                 m->m_data += hlen;
 3198                 mh->m_next = m;
 3199                 m = mh;
 3200                 m->m_len = hlen;
 3201                 bcopy((void *)ip, mtod(m, void *), hlen);
 3202         } else if (m->m_len < hlen) {
 3203                 m = m_pullup(m, hlen);
 3204                 if (!m)
 3205                         return NULL;
 3206         }
 3207         return m;
 3208 }
 3209 #endif
 3210 
 3211 #ifdef INET6
 3212 static struct mbuf *
 3213 ipsec6_splithdr(struct mbuf *m)
 3214 {
 3215         struct mbuf *mh;
 3216         struct ip6_hdr *ip6;
 3217         int hlen;
 3218 
 3219         if (m->m_len < sizeof(struct ip6_hdr))
 3220                 panic("ipsec6_splithdr: first mbuf too short");
 3221         ip6 = mtod(m, struct ip6_hdr *);
 3222         hlen = sizeof(struct ip6_hdr);
 3223         if (m->m_len > hlen) {
 3224                 MGETHDR(mh, M_DONTWAIT, MT_HEADER);
 3225                 if (!mh) {
 3226                         m_freem(m);
 3227                         return NULL;
 3228                 }
 3229                 M_MOVE_PKTHDR(mh, m);
 3230                 MH_ALIGN(mh, hlen);
 3231                 m->m_len -= hlen;
 3232                 m->m_data += hlen;
 3233                 mh->m_next = m;
 3234                 m = mh;
 3235                 m->m_len = hlen;
 3236                 bcopy((void *)ip6, mtod(m, void *), hlen);
 3237         } else if (m->m_len < hlen) {
 3238                 m = m_pullup(m, hlen);
 3239                 if (!m)
 3240                         return NULL;
 3241         }
 3242         return m;
 3243 }
 3244 #endif
 3245 
 3246 /* validate inbound IPsec tunnel packet. */
 3247 int
 3248 ipsec4_tunnel_validate(struct ip *ip, u_int nxt0, 
 3249         struct secasvar *sav)
 3250 {
 3251         u_int8_t nxt = nxt0 & 0xff;
 3252         struct sockaddr_in *sin;
 3253         int hlen;
 3254 
 3255         if (nxt != IPPROTO_IPV4)
 3256                 return 0;
 3257         /* do not decapsulate if the SA is for transport mode only */
 3258         if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
 3259                 return 0;
 3260         hlen = ip->ip_hl << 2;
 3261         if (hlen != sizeof(struct ip))
 3262                 return 0;
 3263         switch (((struct sockaddr *)&sav->sah->saidx.dst)->sa_family) {
 3264         case AF_INET:
 3265                 sin = (struct sockaddr_in *)&sav->sah->saidx.dst;
 3266                 if (bcmp(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst)) != 0)
 3267                         return 0;
 3268                 break;
 3269 #ifdef INET6
 3270         case AF_INET6:
 3271                 /* should be supported, but at this moment we don't. */
 3272                 /*FALLTHROUGH*/
 3273 #endif
 3274         default:
 3275                 return 0;
 3276         }
 3277 
 3278         return 1;
 3279 }
 3280 
 3281 #ifdef INET6
 3282 /* validate inbound IPsec tunnel packet. */
 3283 int
 3284 ipsec6_tunnel_validate(struct ip6_hdr *ip6, u_int nxt0, 
 3285         struct secasvar *sav)
 3286 {
 3287         u_int8_t nxt = nxt0 & 0xff;
 3288         struct sockaddr_in6 sin6;
 3289 
 3290         if (nxt != IPPROTO_IPV6)
 3291                 return 0;
 3292         /* do not decapsulate if the SA is for transport mode only */
 3293         if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
 3294                 return 0;
 3295         switch (((struct sockaddr *)&sav->sah->saidx.dst)->sa_family) {
 3296         case AF_INET6:
 3297                 sin6 = *((struct sockaddr_in6 *)&sav->sah->saidx.dst);
 3298                 if (sa6_embedscope(&sin6, 0) != 0)
 3299                         return 0;
 3300                 if (!IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &sin6.sin6_addr))
 3301                         return 0;
 3302                 break;
 3303         case AF_INET:
 3304                 /* should be supported, but at this moment we don't. */
 3305                 /*FALLTHROUGH*/
 3306         default:
 3307                 return 0;
 3308         }
 3309 
 3310         return 1;
 3311 }
 3312 #endif
 3313 
 3314 /*
 3315  * Make a mbuf chain for encryption.
 3316  * If the original mbuf chain contains a mbuf with a cluster,
 3317  * allocate a new cluster and copy the data to the new cluster.
 3318  * XXX: this hack is inefficient, but is necessary to handle cases
 3319  * of TCP retransmission...
 3320  */
 3321 struct mbuf *
 3322 ipsec_copypkt(struct mbuf *m)
 3323 {
 3324         struct mbuf *n, **mpp, *mnew;
 3325 
 3326         for (n = m, mpp = &m; n; n = n->m_next) {
 3327                 if (n->m_flags & M_EXT) {
 3328                         /*
 3329                          * Make a copy only if there is more than one
 3330                          * references to the cluster.
 3331                          * XXX: is this approach effective?
 3332                          */
 3333                         if (M_READONLY(n))
 3334                         {
 3335                                 int remain, copied;
 3336                                 struct mbuf *mm;
 3337 
 3338                                 if (n->m_flags & M_PKTHDR) {
 3339                                         MGETHDR(mnew, M_DONTWAIT, MT_HEADER);
 3340                                         if (mnew == NULL)
 3341                                                 goto fail;
 3342                                         mnew->m_pkthdr = n->m_pkthdr;
 3343 #if 0
 3344                                         /* XXX: convert to m_tag or delete? */
 3345                                         if (n->m_pkthdr.aux) {
 3346                                                 mnew->m_pkthdr.aux =
 3347                                                     m_copym(n->m_pkthdr.aux,
 3348                                                     0, M_COPYALL, M_DONTWAIT);
 3349                                         }
 3350 #endif
 3351                                         M_MOVE_PKTHDR(mnew, n);
 3352                                 }
 3353                                 else {
 3354                                         MGET(mnew, M_DONTWAIT, MT_DATA);
 3355                                         if (mnew == NULL)
 3356                                                 goto fail;
 3357                                 }
 3358                                 mnew->m_len = 0;
 3359                                 mm = mnew;
 3360 
 3361                                 /*
 3362                                  * Copy data. If we don't have enough space to
 3363                                  * store the whole data, allocate a cluster
 3364                                  * or additional mbufs.
 3365                                  * XXX: we don't use m_copyback(), since the
 3366                                  * function does not use clusters and thus is
 3367                                  * inefficient.
 3368                                  */
 3369                                 remain = n->m_len;
 3370                                 copied = 0;
 3371                                 while (1) {
 3372                                         int len;
 3373                                         struct mbuf *mn;
 3374 
 3375                                         if (remain <= (mm->m_flags & M_PKTHDR ? MHLEN : MLEN))
 3376                                                 len = remain;
 3377                                         else { /* allocate a cluster */
 3378                                                 MCLGET(mm, M_DONTWAIT);
 3379                                                 if (!(mm->m_flags & M_EXT)) {
 3380                                                         m_free(mm);
 3381                                                         goto fail;
 3382                                                 }
 3383                                                 len = remain < MCLBYTES ?
 3384                                                         remain : MCLBYTES;
 3385                                         }
 3386 
 3387                                         bcopy(n->m_data + copied, mm->m_data,
 3388                                               len);
 3389 
 3390                                         copied += len;
 3391                                         remain -= len;
 3392                                         mm->m_len = len;
 3393 
 3394                                         if (remain <= 0) /* completed? */
 3395                                                 break;
 3396 
 3397                                         /* need another mbuf */
 3398                                         MGETHDR(mn, M_DONTWAIT, MT_HEADER);
 3399                                         if (mn == NULL)
 3400                                                 goto fail;
 3401                                         mn->m_pkthdr.rcvif = NULL;
 3402                                         mm->m_next = mn;
 3403                                         mm = mn;
 3404                                 }
 3405 
 3406                                 /* adjust chain */
 3407                                 mm->m_next = m_free(n);
 3408                                 n = mm;
 3409                                 *mpp = mnew;
 3410                                 mpp = &n->m_next;
 3411 
 3412                                 continue;
 3413                         }
 3414                 }
 3415                 *mpp = n;
 3416                 mpp = &n->m_next;
 3417         }
 3418 
 3419         return (m);
 3420   fail:
 3421         m_freem(m);
 3422         return (NULL);
 3423 }
 3424 
 3425 static struct m_tag *
 3426 ipsec_addaux(struct mbuf *m)
 3427 {
 3428         struct m_tag *mtag;
 3429 
 3430         mtag = m_tag_find(m, PACKET_TAG_ESP, NULL);
 3431         if (mtag == NULL) {
 3432                 mtag = m_tag_get(PACKET_TAG_ESP, sizeof(struct ipsecaux),
 3433                     M_NOWAIT);
 3434                 if (mtag != NULL)
 3435                         m_tag_prepend(m, mtag);
 3436         }
 3437         if (mtag == NULL)
 3438                 return NULL;    /* ENOBUFS */
 3439         /* XXX is this necessary? */
 3440         bzero((void *)(mtag + 1), sizeof(struct ipsecaux));
 3441         return mtag;
 3442 }
 3443 
 3444 static struct m_tag *
 3445 ipsec_findaux(struct mbuf *m)
 3446 {
 3447         return m_tag_find(m, PACKET_TAG_ESP, NULL);
 3448 }
 3449 
 3450 void
 3451 ipsec_delaux(struct mbuf *m)
 3452 {
 3453         struct m_tag *mtag;
 3454 
 3455         mtag = m_tag_find(m, PACKET_TAG_ESP, NULL);
 3456         if (mtag != NULL)
 3457                 m_tag_delete(m, mtag);
 3458 }
 3459 
 3460 /* if the aux buffer is unnecessary, nuke it. */
 3461 static void
 3462 ipsec_optaux(struct mbuf *m, struct m_tag *mtag)
 3463 {
 3464         struct ipsecaux *aux;
 3465 
 3466         if (mtag == NULL)
 3467                 return;
 3468         aux = (struct ipsecaux *)(mtag + 1);
 3469         if (!aux->so && !aux->sp)
 3470                 ipsec_delaux(m);
 3471 }
 3472 
 3473 int
 3474 ipsec_addhist(struct mbuf *m, int proto, u_int32_t spi)
 3475 {
 3476         struct m_tag *mtag;
 3477         struct ipsecaux *aux;
 3478 
 3479         mtag = ipsec_addaux(m);
 3480         if (mtag == NULL)
 3481                 return ENOBUFS;
 3482         aux = (struct ipsecaux *)(mtag + 1);
 3483         aux->hdrs++;
 3484         return 0;
 3485 }
 3486 
 3487 int
 3488 ipsec_getnhist(struct mbuf *m)
 3489 {
 3490         struct m_tag *mtag;
 3491         struct ipsecaux *aux;
 3492 
 3493         mtag = ipsec_findaux(m);
 3494         if (mtag == NULL)
 3495                 return 0;
 3496         aux = (struct ipsecaux *)(mtag + 1);
 3497         return aux->hdrs;
 3498 }
 3499 
 3500 struct ipsec_history *
 3501 ipsec_gethist(struct mbuf *m, int *lenp)
 3502 {
 3503 
 3504         panic("ipsec_gethist: obsolete API");
 3505 }
 3506 
 3507 void
 3508 ipsec_clearhist(struct mbuf *m)
 3509 {
 3510         struct m_tag *mtag;
 3511 
 3512         mtag = ipsec_findaux(m);
 3513         ipsec_optaux(m, mtag);
 3514 }
 3515 
 3516 /*
 3517  * System control for IPSEC
 3518  */
 3519 u_char  ipsecctlermap[PRC_NCMDS] = {
 3520         0,              0,              0,              0,
 3521         0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
 3522         EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
 3523         EMSGSIZE,       EHOSTUNREACH,   0,              0,
 3524         0,              0,              0,              0,
 3525         ENOPROTOOPT
 3526 };
 3527 
 3528 /*
 3529  * sysctl helper routine for some net.inet.ipsec and net.inet6.ipnet6
 3530  * nodes.  ensures that the given value is correct and clears the
 3531  * ipsec cache accordingly.
 3532  */
 3533 static int
 3534 sysctl_ipsec(SYSCTLFN_ARGS)
 3535 {
 3536         int error, t;
 3537         struct sysctlnode node;
 3538 
 3539         node = *rnode;
 3540         if (rnode->sysctl_num == IPSECCTL_DEF_POLICY)
 3541                 t = (*((struct secpolicy**)rnode->sysctl_data))->policy;
 3542         else
 3543                 t = *(int*)rnode->sysctl_data;
 3544         node.sysctl_data = &t;
 3545         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 3546         if (error || newp == NULL)
 3547                 return (error);
 3548 
 3549         switch (rnode->sysctl_num) {
 3550         case IPSECCTL_DEF_ESP_TRANSLEV:
 3551         case IPSECCTL_DEF_ESP_NETLEV:
 3552         case IPSECCTL_DEF_AH_TRANSLEV:
 3553         case IPSECCTL_DEF_AH_NETLEV:
 3554                 if (t != IPSEC_LEVEL_USE &&
 3555                     t != IPSEC_LEVEL_REQUIRE)
 3556                         return (EINVAL);
 3557                 ipsec_invalpcbcacheall();
 3558                 break;
 3559         case IPSECCTL_DEF_POLICY:
 3560                 if (t != IPSEC_POLICY_DISCARD &&
 3561                     t != IPSEC_POLICY_NONE)
 3562                         return (EINVAL);
 3563                 ipsec_invalpcbcacheall();
 3564                 break;
 3565         default:
 3566                 return (EINVAL);
 3567         }
 3568 
 3569         if (rnode->sysctl_num == IPSECCTL_DEF_POLICY)
 3570                 (*((struct secpolicy**)rnode->sysctl_data))->policy = t;
 3571         else
 3572                 *(int*)rnode->sysctl_data = t;
 3573 
 3574         return (0);
 3575 }
 3576 
 3577 static int
 3578 sysctl_net_inet_ipsec_stats(SYSCTLFN_ARGS)
 3579 {
 3580 
 3581         return (NETSTAT_SYSCTL(ipsecstat_percpu, IPSEC_NSTATS));
 3582 }
 3583 
 3584 SYSCTL_SETUP(sysctl_net_inet_ipsec_setup, "sysctl net.inet.ipsec subtree setup")
 3585 {
 3586 
 3587         sysctl_createv(clog, 0, NULL, NULL,
 3588                        CTLFLAG_PERMANENT,
 3589                        CTLTYPE_NODE, "net", NULL,
 3590                        NULL, 0, NULL, 0,
 3591                        CTL_NET, CTL_EOL);
 3592         sysctl_createv(clog, 0, NULL, NULL,
 3593                        CTLFLAG_PERMANENT,
 3594                        CTLTYPE_NODE, "inet", NULL,
 3595                        NULL, 0, NULL, 0,
 3596                        CTL_NET, PF_INET, CTL_EOL);
 3597         sysctl_createv(clog, 0, NULL, NULL,
 3598                        CTLFLAG_PERMANENT,
 3599                        CTLTYPE_NODE, "ipsec",
 3600                        SYSCTL_DESCR("IPv4 related IPSec settings"),
 3601                        NULL, 0, NULL, 0,
 3602                        CTL_NET, PF_INET, IPPROTO_AH, CTL_EOL);
 3603 
 3604         sysctl_createv(clog, 0, NULL, NULL,
 3605                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3606                        CTLTYPE_STRUCT, "stats",
 3607                        SYSCTL_DESCR("IPSec statistics and counters"),
 3608                        sysctl_net_inet_ipsec_stats, 0, NULL, 0,
 3609                        CTL_NET, PF_INET, IPPROTO_AH,
 3610                        IPSECCTL_STATS, CTL_EOL);
 3611         sysctl_createv(clog, 0, NULL, NULL,
 3612                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3613                        CTLTYPE_INT, "def_policy",
 3614                        SYSCTL_DESCR("Default action for non-IPSec packets"),
 3615                        sysctl_ipsec, 0, &ip4_def_policy, 0,
 3616                        CTL_NET, PF_INET, IPPROTO_AH,
 3617                        IPSECCTL_DEF_POLICY, CTL_EOL);
 3618         sysctl_createv(clog, 0, NULL, NULL,
 3619                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3620                        CTLTYPE_INT, "esp_trans_deflev",
 3621                        SYSCTL_DESCR("Default required security level for "
 3622                                     "transport mode traffic"),
 3623                        sysctl_ipsec, 0, &ip4_esp_trans_deflev, 0,
 3624                        CTL_NET, PF_INET, IPPROTO_AH,
 3625                        IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
 3626         sysctl_createv(clog, 0, NULL, NULL,
 3627                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3628                        CTLTYPE_INT, "esp_net_deflev",
 3629                        SYSCTL_DESCR("Default required security level for "
 3630                                     "tunneled traffic"),
 3631                        sysctl_ipsec, 0, &ip4_esp_net_deflev, 0,
 3632                        CTL_NET, PF_INET, IPPROTO_AH,
 3633                        IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
 3634         sysctl_createv(clog, 0, NULL, NULL,
 3635                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3636                        CTLTYPE_INT, "ah_trans_deflev",
 3637                        SYSCTL_DESCR("Default required security level for "
 3638                                     "transport mode headers"),
 3639                        sysctl_ipsec, 0, &ip4_ah_trans_deflev, 0,
 3640                        CTL_NET, PF_INET, IPPROTO_AH,
 3641                        IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
 3642         sysctl_createv(clog, 0, NULL, NULL,
 3643                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3644                        CTLTYPE_INT, "ah_net_deflev",
 3645                        SYSCTL_DESCR("Default required security level for "
 3646                                     "tunneled headers"),
 3647                        sysctl_ipsec, 0, &ip4_ah_net_deflev, 0,
 3648                        CTL_NET, PF_INET, IPPROTO_AH,
 3649                        IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
 3650 #if 0 /* obsolete, do not reuse */
 3651         sysctl_createv(clog, 0, NULL, NULL,
 3652                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3653                        CTLTYPE_INT, "inbound_call_ike", NULL,
 3654                        NULL, 0, &ip4_inbound_call_ike, 0,
 3655                        CTL_NET, PF_INET, IPPROTO_AH,
 3656                        IPSECCTL_INBOUND_CALL_IKE, CTL_EOL);
 3657 #endif
 3658         sysctl_createv(clog, 0, NULL, NULL,
 3659                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3660                        CTLTYPE_INT, "ah_cleartos",
 3661                        SYSCTL_DESCR("Clear IP TOS field before calculating AH"),
 3662                        NULL, 0, &ip4_ah_cleartos, 0,
 3663                        CTL_NET, PF_INET, IPPROTO_AH,
 3664                        IPSECCTL_AH_CLEARTOS, CTL_EOL);
 3665         sysctl_createv(clog, 0, NULL, NULL,
 3666                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3667                        CTLTYPE_INT, "ah_offsetmask",
 3668                        SYSCTL_DESCR("Mask for IP fragment offset field when "
 3669                                     "calculating AH"),
 3670                        NULL, 0, &ip4_ah_offsetmask, 0,
 3671                        CTL_NET, PF_INET, IPPROTO_AH,
 3672                        IPSECCTL_AH_OFFSETMASK, CTL_EOL);
 3673         sysctl_createv(clog, 0, NULL, NULL,
 3674                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3675                        CTLTYPE_INT, "dfbit",
 3676                        SYSCTL_DESCR("IP header DF bit setting for tunneled "
 3677                                     "traffic"),
 3678                        NULL, 0, &ip4_ipsec_dfbit, 0,
 3679                        CTL_NET, PF_INET, IPPROTO_AH,
 3680                        IPSECCTL_DFBIT, CTL_EOL);
 3681         sysctl_createv(clog, 0, NULL, NULL,
 3682                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3683                        CTLTYPE_INT, "ecn",
 3684                        SYSCTL_DESCR("Behavior of ECN for tunneled traffic"),
 3685                        NULL, 0, &ip4_ipsec_ecn, 0,
 3686                        CTL_NET, PF_INET, IPPROTO_AH,
 3687                        IPSECCTL_ECN, CTL_EOL);
 3688         sysctl_createv(clog, 0, NULL, NULL,
 3689                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3690                        CTLTYPE_INT, "debug",
 3691                        SYSCTL_DESCR("Enable IPSec debugging output"),
 3692                        NULL, 0, &ipsec_debug, 0,
 3693                        CTL_NET, PF_INET, IPPROTO_AH,
 3694                        IPSECCTL_DEBUG, CTL_EOL);
 3695 
 3696         /*
 3697          * "aliases" for the ipsec subtree
 3698          */
 3699         sysctl_createv(clog, 0, NULL, NULL,
 3700                        CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
 3701                        CTLTYPE_NODE, "esp", NULL,
 3702                        NULL, IPPROTO_AH, NULL, 0,
 3703                        CTL_NET, PF_INET, IPPROTO_ESP, CTL_EOL);
 3704         sysctl_createv(clog, 0, NULL, NULL,
 3705                        CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
 3706                        CTLTYPE_NODE, "ipcomp", NULL,
 3707                        NULL, IPPROTO_AH, NULL, 0,
 3708                        CTL_NET, PF_INET, IPPROTO_IPCOMP, CTL_EOL);
 3709         sysctl_createv(clog, 0, NULL, NULL,
 3710                        CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
 3711                        CTLTYPE_NODE, "ah", NULL,
 3712                        NULL, IPPROTO_AH, NULL, 0,
 3713                        CTL_NET, PF_INET, CTL_CREATE, CTL_EOL);
 3714 }
 3715 
 3716 #ifdef INET6
 3717 /*
 3718  * System control for IPSEC6
 3719  */
 3720 u_char  ipsec6ctlermap[PRC_NCMDS] = {
 3721         0,              0,              0,              0,
 3722         0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
 3723         EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
 3724         EMSGSIZE,       EHOSTUNREACH,   0,              0,
 3725         0,              0,              0,              0,
 3726         ENOPROTOOPT
 3727 };
 3728 
 3729 static int
 3730 sysctl_net_inet6_ipsec6_stats(SYSCTLFN_ARGS)
 3731 {
 3732 
 3733         return (NETSTAT_SYSCTL(ipsec6stat_percpu, IPSEC_NSTATS));
 3734 }
 3735 
 3736 SYSCTL_SETUP(sysctl_net_inet6_ipsec6_setup,
 3737              "sysctl net.inet6.ipsec6 subtree setup")
 3738 {
 3739 
 3740         sysctl_createv(clog, 0, NULL, NULL,
 3741                        CTLFLAG_PERMANENT,
 3742                        CTLTYPE_NODE, "net", NULL,
 3743                        NULL, 0, NULL, 0,
 3744                        CTL_NET, CTL_EOL);
 3745         sysctl_createv(clog, 0, NULL, NULL,
 3746                        CTLFLAG_PERMANENT,
 3747                        CTLTYPE_NODE, "inet6", NULL,
 3748                        NULL, 0, NULL, 0,
 3749                        CTL_NET, PF_INET6, CTL_EOL);
 3750         sysctl_createv(clog, 0, NULL, NULL,
 3751                        CTLFLAG_PERMANENT,
 3752                        CTLTYPE_NODE, "ipsec6",
 3753                        SYSCTL_DESCR("IPv6 related IPSec settings"),
 3754                        NULL, 0, NULL, 0,
 3755                        CTL_NET, PF_INET6, IPPROTO_AH, CTL_EOL);
 3756 
 3757         sysctl_createv(clog, 0, NULL, NULL,
 3758                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3759                        CTLTYPE_STRUCT, "stats",
 3760                        SYSCTL_DESCR("IPSec statistics and counters"),
 3761                        sysctl_net_inet6_ipsec6_stats, 0, NULL, 0,
 3762                        CTL_NET, PF_INET6, IPPROTO_AH,
 3763                        IPSECCTL_STATS, CTL_EOL);
 3764         sysctl_createv(clog, 0, NULL, NULL,
 3765                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3766                        CTLTYPE_INT, "def_policy",
 3767                        SYSCTL_DESCR("Default action for non-IPSec packets"),
 3768                        sysctl_ipsec, 0, &ip6_def_policy, 0,
 3769                        CTL_NET, PF_INET6, IPPROTO_AH,
 3770                        IPSECCTL_DEF_POLICY, CTL_EOL);
 3771         sysctl_createv(clog, 0, NULL, NULL,
 3772                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3773                        CTLTYPE_INT, "esp_trans_deflev",
 3774                        SYSCTL_DESCR("Default required security level for "
 3775                                     "transport mode traffic"),
 3776                        sysctl_ipsec, 0, &ip6_esp_trans_deflev, 0,
 3777                        CTL_NET, PF_INET6, IPPROTO_AH,
 3778                        IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
 3779         sysctl_createv(clog, 0, NULL, NULL,
 3780                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3781                        CTLTYPE_INT, "esp_net_deflev",
 3782                        SYSCTL_DESCR("Default required security level for "
 3783                                     "tunneled traffic"),
 3784                        sysctl_ipsec, 0, &ip6_esp_net_deflev, 0,
 3785                        CTL_NET, PF_INET6, IPPROTO_AH,
 3786                        IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
 3787         sysctl_createv(clog, 0, NULL, NULL,
 3788                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3789                        CTLTYPE_INT, "ah_trans_deflev",
 3790                        SYSCTL_DESCR("Default required security level for "
 3791                                     "transport mode headers"),
 3792                        sysctl_ipsec, 0, &ip6_ah_trans_deflev, 0,
 3793                        CTL_NET, PF_INET6, IPPROTO_AH,
 3794                        IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
 3795         sysctl_createv(clog, 0, NULL, NULL,
 3796                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3797                        CTLTYPE_INT, "ah_net_deflev",
 3798                        SYSCTL_DESCR("Default required security level for "
 3799                                     "tunneled headers"),
 3800                        sysctl_ipsec, 0, &ip6_ah_net_deflev, 0,
 3801                        CTL_NET, PF_INET6, IPPROTO_AH,
 3802                        IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
 3803         sysctl_createv(clog, 0, NULL, NULL,
 3804                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3805                        CTLTYPE_INT, "ecn",
 3806                        SYSCTL_DESCR("Behavior of ECN for tunneled traffic"),
 3807                        NULL, 0, &ip6_ipsec_ecn, 0,
 3808                        CTL_NET, PF_INET6, IPPROTO_AH,
 3809                        IPSECCTL_ECN, CTL_EOL);
 3810         sysctl_createv(clog, 0, NULL, NULL,
 3811                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 3812                        CTLTYPE_INT, "debug",
 3813                        SYSCTL_DESCR("Enable IPSec debugging output"),
 3814                        NULL, 0, &ipsec_debug, 0,
 3815                        CTL_NET, PF_INET6, IPPROTO_AH,
 3816                        IPSECCTL_DEBUG, CTL_EOL);
 3817 
 3818         /*
 3819          * "aliases" for the ipsec6 subtree
 3820          */
 3821         sysctl_createv(clog, 0, NULL, NULL,
 3822                        CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
 3823                        CTLTYPE_NODE, "esp6", NULL,
 3824                        NULL, IPPROTO_AH, NULL, 0,
 3825                        CTL_NET, PF_INET6, IPPROTO_ESP, CTL_EOL);
 3826         sysctl_createv(clog, 0, NULL, NULL,
 3827                        CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
 3828                        CTLTYPE_NODE, "ipcomp6", NULL,
 3829                        NULL, IPPROTO_AH, NULL, 0,
 3830                        CTL_NET, PF_INET6, IPPROTO_IPCOMP, CTL_EOL);
 3831         sysctl_createv(clog, 0, NULL, NULL,
 3832                        CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
 3833                        CTLTYPE_NODE, "ah6", NULL,
 3834                        NULL, IPPROTO_AH, NULL, 0,
 3835                        CTL_NET, PF_INET6, CTL_CREATE, CTL_EOL);
 3836 }
 3837 #endif /* INET6 */

Cache object: 40dc2ac7124ab681865764c90b6ea804


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.