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/netipsec/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.10.2.2 2007/12/01 17:33:14 bouyer Exp $    */
    2 /*      $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $       */
    3 /*      $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
    4 
    5 /*
    6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. Neither the name of the project nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.10.2.2 2007/12/01 17:33:14 bouyer Exp $");
   36 
   37 /*
   38  * IPsec controller part.
   39  */
   40 
   41 #include "opt_inet.h"
   42 #ifdef __FreeBSD__
   43 #include "opt_inet6.h"
   44 #endif
   45 #include "opt_ipsec.h"
   46 
   47 #include <sys/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/domain.h>
   52 #include <sys/protosw.h>
   53 #include <sys/socket.h>
   54 #include <sys/socketvar.h>
   55 #include <sys/errno.h>
   56 #include <sys/time.h>
   57 #include <sys/kernel.h>
   58 #include <sys/syslog.h>
   59 #include <sys/sysctl.h>
   60 #include <sys/proc.h>
   61 
   62 #include <net/if.h>
   63 #include <net/route.h>
   64 
   65 #include <netinet/in.h>
   66 #include <netinet/in_systm.h>
   67 #include <netinet/ip.h>
   68 #include <netinet/ip_var.h>
   69 #include <netinet/in_var.h>
   70 #include <netinet/udp.h>
   71 #include <netinet/udp_var.h>
   72 #include <netinet/tcp.h>
   73 #include <netinet/udp.h>
   74 
   75 #include <netinet/ip6.h>
   76 #ifdef INET6
   77 #include <netinet6/ip6_var.h>
   78 #endif
   79 #include <netinet/in_pcb.h>
   80 #ifdef INET6
   81 #include <netinet6/in6_pcb.h>
   82 #include <netinet/icmp6.h>
   83 #endif
   84 
   85 #include <netipsec/ipsec.h>
   86 #include <netipsec/ipsec_var.h>
   87 #ifdef INET6
   88 #include <netipsec/ipsec6.h>
   89 #endif
   90 #include <netipsec/ah_var.h>
   91 #include <netipsec/esp_var.h>
   92 #include <netipsec/ipcomp.h>            /*XXX*/
   93 #include <netipsec/ipcomp_var.h>
   94 
   95 #include <netipsec/key.h>
   96 #include <netipsec/keydb.h>
   97 #include <netipsec/key_debug.h>
   98 
   99 #include <netipsec/xform.h>
  100 
  101 #include <netipsec/ipsec_osdep.h>
  102 
  103 #include <net/net_osdep.h>
  104 
  105 #ifdef IPSEC_DEBUG
  106 int ipsec_debug = 1;
  107 #else
  108 int ipsec_debug = 0;
  109 #endif
  110 
  111 /* NB: name changed so netstat doesn't use it */
  112 struct newipsecstat newipsecstat;
  113 int ip4_ah_offsetmask = 0;      /* maybe IP_DF? */
  114 int ip4_ipsec_dfbit = 0;        /* DF bit on encap. 0: clear 1: set 2: copy */
  115 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
  116 int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
  117 int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
  118 int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
  119 struct secpolicy ip4_def_policy;
  120 int ip4_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
  121 int ip4_esp_randpad = -1;
  122 
  123 #ifdef __NetBSD__
  124 u_int ipsec_spdgen = 1;         /* SPD generation # */
  125 
  126 static struct secpolicy *ipsec_checkpcbcache __P((struct mbuf *,
  127         struct inpcbpolicy *, int));
  128 static int ipsec_fillpcbcache __P((struct inpcbpolicy *, struct mbuf *,
  129         struct secpolicy *, int));
  130 static int ipsec_invalpcbcache __P((struct inpcbpolicy *, int));
  131 #endif /* __NetBSD__ */
  132 
  133 /*
  134  * Crypto support requirements:
  135  *
  136  *  1   require hardware support
  137  * -1   require software support
  138  *  0   take anything
  139  */
  140 int     crypto_support = 0;
  141 
  142 static struct secpolicy *ipsec_getpolicybysock(struct mbuf *, u_int,
  143         PCB_T *, int *);
  144 
  145 #ifdef __FreeBSD__
  146 SYSCTL_DECL(_net_inet_ipsec);
  147 
  148 /* net.inet.ipsec */
  149 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
  150         def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
  151 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
  152         CTLFLAG_RW, &ip4_esp_trans_deflev,      0, "");
  153 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
  154         CTLFLAG_RW, &ip4_esp_net_deflev,        0, "");
  155 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
  156         CTLFLAG_RW, &ip4_ah_trans_deflev,       0, "");
  157 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
  158         CTLFLAG_RW, &ip4_ah_net_deflev, 0, "");
  159 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
  160         ah_cleartos, CTLFLAG_RW,        &ah_cleartos,   0, "");
  161 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
  162         ah_offsetmask, CTLFLAG_RW,      &ip4_ah_offsetmask,     0, "");
  163 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
  164         dfbit, CTLFLAG_RW,      &ip4_ipsec_dfbit,       0, "");
  165 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
  166         ecn, CTLFLAG_RW,        &ip4_ipsec_ecn, 0, "");
  167 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
  168         debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
  169 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
  170         esp_randpad, CTLFLAG_RW,        &ip4_esp_randpad,       0, "");
  171 SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
  172         crypto_support, CTLFLAG_RW,     &crypto_support,0, "");
  173 SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
  174         ipsecstats,     CTLFLAG_RD,     &newipsecstat,  newipsecstat, "");
  175 #endif /* __FreeBSD__ */
  176 
  177 #ifdef INET6
  178 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
  179 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
  180 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
  181 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
  182 struct secpolicy ip6_def_policy;
  183 int ip6_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
  184 int ip6_esp_randpad = -1;
  185 
  186 
  187 #ifdef __FreeBSD__
  188 SYSCTL_DECL(_net_inet6_ipsec6);
  189 
  190 /* net.inet6.ipsec6 */
  191 #ifdef COMPAT_KAME
  192 SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
  193         0,0, compat_ipsecstats_sysctl, "S", "");
  194 #endif /* COMPAT_KAME */
  195 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
  196         def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
  197 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
  198         CTLFLAG_RW, &ip6_esp_trans_deflev,      0, "");
  199 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
  200         CTLFLAG_RW, &ip6_esp_net_deflev,        0, "");
  201 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
  202         CTLFLAG_RW, &ip6_ah_trans_deflev,       0, "");
  203 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
  204         CTLFLAG_RW, &ip6_ah_net_deflev, 0, "");
  205 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
  206         ecn, CTLFLAG_RW,        &ip6_ipsec_ecn, 0, "");
  207 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
  208         debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
  209 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
  210         esp_randpad, CTLFLAG_RW,        &ip6_esp_randpad,       0, "");
  211 #endif /* INET6 */
  212 #endif /* __FreeBSD__ */
  213 
  214 static int ipsec4_setspidx_inpcb __P((struct mbuf *, struct inpcb *pcb));
  215 #ifdef INET6
  216 static int ipsec6_setspidx_in6pcb __P((struct mbuf *, struct in6pcb *pcb));
  217 #endif
  218 static int ipsec_setspidx __P((struct mbuf *, struct secpolicyindex *, int));
  219 static void ipsec4_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int));
  220 static int ipsec4_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
  221 #ifdef INET6
  222 static void ipsec6_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int));
  223 static int ipsec6_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
  224 #endif
  225 static void ipsec_delpcbpolicy __P((struct inpcbpolicy *));
  226 static struct secpolicy *ipsec_deepcopy_policy __P((struct secpolicy *src));
  227 static int ipsec_set_policy __P((struct secpolicy **pcb_sp,
  228         int optname, caddr_t request, size_t len, int priv));
  229 static int ipsec_get_policy __P((struct secpolicy *pcb_sp, struct mbuf **mp));
  230 static void vshiftl __P((unsigned char *, int, int));
  231 static size_t ipsec_hdrsiz __P((struct secpolicy *));
  232 
  233 #ifdef __NetBSD__
  234 /*
  235  * Try to validate and use cached policy on a PCB.
  236  */
  237 static struct secpolicy *
  238 ipsec_checkpcbcache(struct mbuf *m, struct inpcbpolicy *pcbsp, int dir)
  239 {
  240         struct secpolicyindex spidx;
  241 
  242         switch (dir) {
  243         case IPSEC_DIR_INBOUND:
  244         case IPSEC_DIR_OUTBOUND:
  245         case IPSEC_DIR_ANY:
  246                 break;
  247         default:
  248                 return NULL;
  249         }
  250 #ifdef DIAGNOSTIC
  251         if (pcbsp == NULL) {
  252                 printf("ipsec_checkpcbcache: NULL pcbsp\n");
  253                 /* XXX panic? */
  254                 return NULL;
  255         }
  256 #endif
  257 
  258 #ifdef DIAGNOSTIC
  259         if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
  260                 panic("dir too big in ipsec_checkpcbcache");
  261 #endif
  262         /* SPD table change invalidate all the caches. */
  263         if (ipsec_spdgen != pcbsp->sp_cache[dir].cachegen) {
  264                 ipsec_invalpcbcache(pcbsp, dir);
  265                 return NULL;
  266         }
  267         if (!pcbsp->sp_cache[dir].cachesp)
  268                 return NULL;
  269         if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) {
  270                 ipsec_invalpcbcache(pcbsp, dir);
  271                 return NULL;
  272         }
  273         if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) {
  274                 if (!pcbsp->sp_cache[dir].cachesp)
  275                         return NULL;
  276                 if (ipsec_setspidx(m, &spidx, 1) != 0)
  277                         return NULL;
  278                 if (bcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx,
  279                          sizeof(spidx))) {
  280                         if (!key_cmpspidx_withmask(&pcbsp->sp_cache[dir].cachesp->spidx,
  281                             &spidx))
  282                                 return NULL;
  283                         pcbsp->sp_cache[dir].cacheidx = spidx;
  284                 }
  285         } else {
  286                 /*
  287                  * The pcb is connected, and the L4 code is sure that:
  288                  * - outgoing side uses inp_[lf]addr
  289                  * - incoming side looks up policy after inpcb lookup
  290                  * and address pair is know to be stable.  We do not need
  291                  * to generate spidx again, nor check the address match again.
  292                  *
  293                  * For IPv4/v6 SOCK_STREAM sockets, this assumptions holds
  294                  * and there are calls to ipsec_pcbconn() from in_pcbconnect().
  295                  */
  296         }
  297 
  298         pcbsp->sp_cache[dir].cachesp->lastused = mono_time.tv_sec;
  299         pcbsp->sp_cache[dir].cachesp->refcnt++;
  300         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  301                 printf("DP ipsec_checkpcbcache cause refcnt++:%d SP:%p\n",
  302                 pcbsp->sp_cache[dir].cachesp->refcnt,
  303                 pcbsp->sp_cache[dir].cachesp));
  304         return pcbsp->sp_cache[dir].cachesp;
  305 }
  306 
  307 static int
  308 ipsec_fillpcbcache(struct inpcbpolicy *pcbsp, struct mbuf *m,
  309     struct secpolicy *sp, int dir)
  310 {
  311 
  312         switch (dir) {
  313         case IPSEC_DIR_INBOUND:
  314         case IPSEC_DIR_OUTBOUND:
  315                 break;
  316         default:
  317                 return EINVAL;
  318         }
  319 #ifdef DIAGNOSTIC
  320         if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
  321                 panic("dir too big in ipsec_fillpcbcache");
  322 #endif
  323 
  324         if (pcbsp->sp_cache[dir].cachesp)
  325                 KEY_FREESP(&pcbsp->sp_cache[dir].cachesp);
  326         pcbsp->sp_cache[dir].cachesp = NULL;
  327         pcbsp->sp_cache[dir].cachehint = IPSEC_PCBHINT_MAYBE;
  328         if (ipsec_setspidx(m, &pcbsp->sp_cache[dir].cacheidx, 1) != 0) {
  329                 return EINVAL;
  330         }
  331         pcbsp->sp_cache[dir].cachesp = sp;
  332         if (pcbsp->sp_cache[dir].cachesp) {
  333                 pcbsp->sp_cache[dir].cachesp->refcnt++;
  334                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  335                         printf("DP ipsec_fillpcbcache cause refcnt++:%d SP:%p\n",
  336                         pcbsp->sp_cache[dir].cachesp->refcnt,
  337                         pcbsp->sp_cache[dir].cachesp));
  338 
  339                 /*
  340                  * If the PCB is connected, we can remember a hint to
  341                  * possibly short-circuit IPsec processing in other places.
  342                  */
  343                 if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) {
  344                         switch (pcbsp->sp_cache[dir].cachesp->policy) {
  345                         case IPSEC_POLICY_NONE:
  346                         case IPSEC_POLICY_BYPASS:
  347                                 pcbsp->sp_cache[dir].cachehint =
  348                                     IPSEC_PCBHINT_NO;
  349                                 break;
  350                         default:
  351                                 pcbsp->sp_cache[dir].cachehint =
  352                                     IPSEC_PCBHINT_YES;
  353                         }
  354                 }
  355         }
  356         pcbsp->sp_cache[dir].cachegen = ipsec_spdgen;
  357 
  358         return 0;
  359 }
  360 
  361 static int
  362 ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir)
  363 {
  364         int i;
  365 
  366         for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) {
  367                 if (dir != IPSEC_DIR_ANY && i != dir)
  368                         continue;
  369                 if (pcbsp->sp_cache[i].cachesp)
  370                         KEY_FREESP(&pcbsp->sp_cache[i].cachesp);
  371                 pcbsp->sp_cache[i].cachesp = NULL;
  372                 pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_MAYBE;
  373                 pcbsp->sp_cache[i].cachegen = 0;
  374                 bzero(&pcbsp->sp_cache[i].cacheidx,
  375                       sizeof(pcbsp->sp_cache[i].cacheidx));
  376         }
  377         return 0;
  378 }
  379 
  380 void
  381 ipsec_pcbconn(struct inpcbpolicy *pcbsp)
  382 {
  383 
  384         pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED;
  385         ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
  386 }
  387 
  388 void
  389 ipsec_pcbdisconn(struct inpcbpolicy *pcbsp)
  390 {
  391 
  392         pcbsp->sp_cacheflags &= ~IPSEC_PCBSP_CONNECTED;
  393         ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
  394 }
  395 
  396 void
  397 ipsec_invalpcbcacheall(void)
  398 {
  399 
  400         if (ipsec_spdgen == UINT_MAX)
  401                 ipsec_spdgen = 1;
  402         else
  403                 ipsec_spdgen++;
  404 }
  405 #endif /* __NetBSD__ */
  406 
  407 /*
  408  * Return a held reference to the default SP.
  409  */
  410 static struct secpolicy *
  411 key_allocsp_default(const char* where, int tag)
  412 {
  413         struct secpolicy *sp;
  414 
  415         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  416                 printf("DP key_allocsp_default from %s:%u\n", where, tag));
  417 
  418         sp = &ip4_def_policy;
  419         if (sp->policy != IPSEC_POLICY_DISCARD &&
  420             sp->policy != IPSEC_POLICY_NONE) {
  421                 ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
  422                     sp->policy, IPSEC_POLICY_NONE));
  423                 sp->policy = IPSEC_POLICY_NONE;
  424         }
  425         sp->refcnt++;
  426 
  427         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  428                 printf("DP key_allocsp_default returns SP:%p (%u)\n",
  429                         sp, sp->refcnt));
  430         return sp;
  431 }
  432 #define KEY_ALLOCSP_DEFAULT() \
  433         key_allocsp_default(__FILE__, __LINE__)
  434 
  435 /*
  436  * For OUTBOUND packet having a socket. Searching SPD for packet,
  437  * and return a pointer to SP.
  438  * OUT: NULL:   no apropreate SP found, the following value is set to error.
  439  *              0       : bypass
  440  *              EACCES  : discard packet.
  441  *              ENOENT  : ipsec_acquire() in progress, maybe.
  442  *              others  : error occurred.
  443  *      others: a pointer to SP
  444  *
  445  * NOTE: IPv6 mapped adddress concern is implemented here.
  446  */
  447 struct secpolicy *
  448 ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
  449 {
  450         struct secpolicy *sp;
  451 
  452         IPSEC_ASSERT(tdbi != NULL, ("ipsec_getpolicy: null tdbi"));
  453         IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  454                 ("ipsec_getpolicy: invalid direction %u", dir));
  455 
  456         sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
  457         if (sp == NULL)                 /*XXX????*/
  458                 sp = KEY_ALLOCSP_DEFAULT();
  459         IPSEC_ASSERT(sp != NULL, ("ipsec_getpolicy: null SP"));
  460         return sp;
  461 }
  462 
  463 /*
  464  * For OUTBOUND packet having a socket. Searching SPD for packet,
  465  * and return a pointer to SP.
  466  * OUT: NULL:   no apropreate SP found, the following value is set to error.
  467  *              0       : bypass
  468  *              EACCES  : discard packet.
  469  *              ENOENT  : ipsec_acquire() in progress, maybe.
  470  *              others  : error occurred.
  471  *      others: a pointer to SP
  472  *
  473  * NOTE: IPv6 mapped adddress concern is implemented here.
  474  */
  475 static struct secpolicy *
  476 ipsec_getpolicybysock(m, dir, inp, error)
  477         struct mbuf *m;
  478         u_int dir;
  479         PCB_T *inp;
  480         int *error;
  481 {
  482         struct inpcbpolicy *pcbsp = NULL;
  483         struct secpolicy *currsp = NULL;        /* policy on socket */
  484         struct secpolicy *sp;
  485         int af;
  486 
  487         IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
  488         IPSEC_ASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
  489         IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
  490         IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  491                 ("ipsec_getpolicybysock: invalid direction %u", dir));
  492 
  493         IPSEC_ASSERT(PCB_SOCKET(inp) != NULL,
  494             ("ipsec_getppolicybysock: null socket\n"));
  495 
  496         /* XXX FIXME inpcb/in6pcb  vs socket*/
  497         af = PCB_FAMILY(inp);
  498         IPSEC_ASSERT(af == AF_INET || af == AF_INET6,
  499                 ("ipsec_getpolicybysock: unexpected protocol family %u", af));
  500 
  501 #ifdef __NetBSD__
  502         IPSEC_ASSERT(inp->inph_sp != NULL, ("null PCB policy cache"));
  503         /* If we have a cached entry, and if it is still valid, use it. */
  504         ipsecstat.ips_spdcache_lookup++;
  505         currsp = ipsec_checkpcbcache(m, /*inpcb_hdr*/inp->inph_sp, dir);
  506         if (currsp) {
  507                 *error = 0;
  508                 return currsp;
  509         }
  510         ipsecstat.ips_spdcache_miss++;
  511 #endif /* __NetBSD__ */
  512 
  513         switch (af) {
  514         case AF_INET: {
  515                 struct inpcb *in4p = PCB_TO_IN4PCB(inp);
  516                 /* set spidx in pcb */
  517                 *error = ipsec4_setspidx_inpcb(m, in4p);
  518                 pcbsp = in4p->inp_sp;
  519                 break;
  520                 }
  521 
  522 #if defined(INET6)
  523         case AF_INET6: {
  524                 struct in6pcb *in6p = PCB_TO_IN6PCB(inp);
  525                 /* set spidx in pcb */
  526                 *error = ipsec6_setspidx_in6pcb(m, in6p);
  527                 pcbsp = in6p->in6p_sp;
  528                 break;
  529                 }
  530 #endif
  531         default:
  532                 *error = EPFNOSUPPORT;
  533                 break;
  534         }
  535         if (*error)
  536                 return NULL;
  537 
  538         IPSEC_ASSERT(pcbsp != NULL, ("ipsec_getpolicybysock: null pcbsp"));
  539         switch (dir) {
  540         case IPSEC_DIR_INBOUND:
  541                 currsp = pcbsp->sp_in;
  542                 break;
  543         case IPSEC_DIR_OUTBOUND:
  544                 currsp = pcbsp->sp_out;
  545                 break;
  546         }
  547         IPSEC_ASSERT(currsp != NULL, ("ipsec_getpolicybysock: null currsp"));
  548 
  549         if (pcbsp->priv) {                      /* when privilieged socket */
  550                 switch (currsp->policy) {
  551                 case IPSEC_POLICY_BYPASS:
  552                 case IPSEC_POLICY_IPSEC:
  553                         currsp->refcnt++;
  554                         sp = currsp;
  555                         break;
  556 
  557                 case IPSEC_POLICY_ENTRUST:
  558                         /* look for a policy in SPD */
  559                         sp = KEY_ALLOCSP(&currsp->spidx, dir);
  560                         if (sp == NULL)         /* no SP found */
  561                                 sp = KEY_ALLOCSP_DEFAULT();
  562                         break;
  563 
  564                 default:
  565                         ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
  566                               "Invalid policy for PCB %d\n", currsp->policy));
  567                         *error = EINVAL;
  568                         return NULL;
  569                 }
  570         } else {                                /* unpriv, SPD has policy */
  571                 sp = KEY_ALLOCSP(&currsp->spidx, dir);
  572                 if (sp == NULL) {               /* no SP found */
  573                         switch (currsp->policy) {
  574                         case IPSEC_POLICY_BYPASS:
  575                                 ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
  576                                        "Illegal policy for non-priviliged defined %d\n",
  577                                         currsp->policy));
  578                                 *error = EINVAL;
  579                                 return NULL;
  580 
  581                         case IPSEC_POLICY_ENTRUST:
  582                                 sp = KEY_ALLOCSP_DEFAULT();
  583                                 break;
  584 
  585                         case IPSEC_POLICY_IPSEC:
  586                                 currsp->refcnt++;
  587                                 sp = currsp;
  588                                 break;
  589 
  590                         default:
  591                                 ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
  592                                    "Invalid policy for PCB %d\n", currsp->policy));
  593                                 *error = EINVAL;
  594                                 return NULL;
  595                         }
  596                 }
  597         }
  598         IPSEC_ASSERT(sp != NULL,
  599                 ("ipsec_getpolicybysock: null SP (priv %u policy %u",
  600                  pcbsp->priv, currsp->policy));
  601         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  602                 printf("DP ipsec_getpolicybysock (priv %u policy %u) allocates "
  603                        "SP:%p (refcnt %u)\n", pcbsp->priv, currsp->policy,
  604                        sp, sp->refcnt));
  605 #ifdef __NetBSD__
  606         ipsec_fillpcbcache(pcbsp, m, sp, dir);
  607 #endif /* __NetBSD__ */
  608         return sp;
  609 }
  610 
  611 /*
  612  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
  613  * and return a pointer to SP.
  614  * OUT: positive: a pointer to the entry for security policy leaf matched.
  615  *      NULL:   no apropreate SP found, the following value is set to error.
  616  *              0       : bypass
  617  *              EACCES  : discard packet.
  618  *              ENOENT  : ipsec_acquire() in progress, maybe.
  619  *              others  : error occurred.
  620  */
  621 struct secpolicy *
  622 ipsec_getpolicybyaddr(m, dir, flag, error)
  623         struct mbuf *m;
  624         u_int dir;
  625         int flag;
  626         int *error;
  627 {
  628         struct secpolicyindex spidx;
  629         struct secpolicy *sp;
  630 
  631         IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybyaddr: null mbuf"));
  632         IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybyaddr: null error"));
  633         IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  634                 ("ipsec4_getpolicybaddr: invalid direction %u", dir));
  635 
  636         sp = NULL;
  637         if (key_havesp(dir)) {
  638                 /* Make an index to look for a policy. */
  639                 *error = ipsec_setspidx(m, &spidx,
  640                                         (flag & IP_FORWARDING) ? 0 : 1);
  641                 if (*error != 0) {
  642                         DPRINTF(("ipsec_getpolicybyaddr: setpidx failed,"
  643                                 " dir %u flag %u\n", dir, flag));
  644                         bzero(&spidx, sizeof (spidx));
  645                         return NULL;
  646                 }
  647                 spidx.dir = dir;
  648 
  649                 sp = KEY_ALLOCSP(&spidx, dir);
  650         }
  651         if (sp == NULL)                 /* no SP found, use system default */
  652                 sp = KEY_ALLOCSP_DEFAULT();
  653         IPSEC_ASSERT(sp != NULL, ("ipsec_getpolicybyaddr: null SP"));
  654         return sp;
  655 }
  656 
  657 struct secpolicy *
  658 ipsec4_checkpolicy(m, dir, flag, error, inp)
  659         struct mbuf *m;
  660         u_int dir, flag;
  661         int *error;
  662         struct inpcb *inp;
  663 {
  664         struct secpolicy *sp;
  665 
  666         *error = 0;
  667 
  668 
  669         /* XXX KAME IPv6 calls us with non-null inp but bogus inp_socket? */
  670         if (inp == NULL || inp->inp_socket == NULL) {
  671                 sp = ipsec_getpolicybyaddr(m, dir, flag, error);
  672         } else
  673                 sp = ipsec_getpolicybysock(m, dir, IN4PCB_TO_PCB(inp), error);
  674         if (sp == NULL) {
  675                 IPSEC_ASSERT(*error != 0,
  676                         ("ipsec4_checkpolicy: getpolicy failed w/o error"));
  677                 newipsecstat.ips_out_inval++;
  678                 return NULL;
  679         }
  680         IPSEC_ASSERT(*error == 0,
  681                 ("ipsec4_checkpolicy: sp w/ error set to %u", *error));
  682         switch (sp->policy) {
  683         case IPSEC_POLICY_ENTRUST:
  684         default:
  685                 printf("ipsec4_checkpolicy: invalid policy %u\n", sp->policy);
  686                 /* fall thru... */
  687         case IPSEC_POLICY_DISCARD:
  688                 newipsecstat.ips_out_polvio++;
  689                 *error = -EINVAL;       /* packet is discarded by caller */
  690                 break;
  691         case IPSEC_POLICY_BYPASS:
  692         case IPSEC_POLICY_NONE:
  693                 KEY_FREESP(&sp);
  694                 sp = NULL;              /* NB: force NULL result */
  695                 break;
  696         case IPSEC_POLICY_IPSEC:
  697                 if (sp->req == NULL)    /* acquire an SA */
  698                         *error = key_spdacquire(sp);
  699                 break;
  700         }
  701         if (*error != 0) {
  702                 KEY_FREESP(&sp);
  703                 sp = NULL;
  704         }
  705         DPRINTF(("ipsecpol: done, sp %p error %d, \n", sp, *error));
  706         return sp;
  707 }
  708 
  709 static int
  710 ipsec4_setspidx_inpcb(m, pcb)
  711         struct mbuf *m;
  712         struct inpcb *pcb;
  713 {
  714         int error;
  715 
  716         IPSEC_ASSERT(pcb != NULL, ("ipsec4_setspidx_inpcb: null pcb"));
  717         IPSEC_ASSERT(pcb->inp_sp != NULL, ("ipsec4_setspidx_inpcb: null inp_sp"));
  718         IPSEC_ASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
  719                 ("ipsec4_setspidx_inpcb: null sp_in || sp_out"));
  720 
  721         error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
  722         if (error == 0) {
  723                 pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
  724                 pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
  725                 pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
  726         } else {
  727                 bzero(&pcb->inp_sp->sp_in->spidx,
  728                         sizeof (pcb->inp_sp->sp_in->spidx));
  729                 bzero(&pcb->inp_sp->sp_out->spidx,
  730                         sizeof (pcb->inp_sp->sp_in->spidx));
  731         }
  732         return error;
  733 }
  734 
  735 #ifdef INET6
  736 static int
  737 ipsec6_setspidx_in6pcb(m, pcb)
  738         struct mbuf *m;
  739         struct in6pcb *pcb;
  740 {
  741         struct secpolicyindex *spidx;
  742         int error;
  743 
  744         IPSEC_ASSERT(pcb != NULL, ("ipsec6_setspidx_in6pcb: null pcb"));
  745         IPSEC_ASSERT(pcb->in6p_sp != NULL, ("ipsec6_setspidx_in6pcb: null inp_sp"));
  746         IPSEC_ASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
  747                 ("ipsec6_setspidx_in6pcb: null sp_in || sp_out"));
  748 
  749         bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
  750         bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
  751 
  752         spidx = &pcb->in6p_sp->sp_in->spidx;
  753         error = ipsec_setspidx(m, spidx, 1);
  754         if (error)
  755                 goto bad;
  756         spidx->dir = IPSEC_DIR_INBOUND;
  757 
  758         spidx = &pcb->in6p_sp->sp_out->spidx;
  759         error = ipsec_setspidx(m, spidx, 1);
  760         if (error)
  761                 goto bad;
  762         spidx->dir = IPSEC_DIR_OUTBOUND;
  763 
  764         return 0;
  765 
  766 bad:
  767         bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
  768         bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
  769         return error;
  770 }
  771 #endif
  772 
  773 /*
  774  * configure security policy index (src/dst/proto/sport/dport)
  775  * by looking at the content of mbuf.
  776  * the caller is responsible for error recovery (like clearing up spidx).
  777  */
  778 static int
  779 ipsec_setspidx(m, spidx, needport)
  780         struct mbuf *m;
  781         struct secpolicyindex *spidx;
  782         int needport;
  783 {
  784         struct ip *ip = NULL;
  785         struct ip ipbuf;
  786         u_int v;
  787         struct mbuf *n;
  788         int len;
  789         int error;
  790 
  791         IPSEC_ASSERT(m != NULL, ("ipsec_setspidx: null mbuf"));
  792 
  793         /*
  794          * validate m->m_pkthdr.len.  we see incorrect length if we
  795          * mistakenly call this function with inconsistent mbuf chain
  796          * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
  797          */
  798         len = 0;
  799         for (n = m; n; n = n->m_next)
  800                 len += n->m_len;
  801         if (m->m_pkthdr.len != len) {
  802                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  803                         printf("ipsec_setspidx: "
  804                                "total of m_len(%d) != pkthdr.len(%d), "
  805                                "ignored.\n",
  806                                 len, m->m_pkthdr.len));
  807                 return EINVAL;
  808         }
  809 
  810         if (m->m_pkthdr.len < sizeof(struct ip)) {
  811                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  812                         printf("ipsec_setspidx: "
  813                             "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
  814                             m->m_pkthdr.len));
  815                 return EINVAL;
  816         }
  817 
  818         if (m->m_len >= sizeof(*ip))
  819                 ip = mtod(m, struct ip *);
  820         else {
  821                 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
  822                 ip = &ipbuf;
  823         }
  824 #ifdef _IP_VHL
  825         v = _IP_VHL_V(ip->ip_vhl);
  826 #else
  827         v = ip->ip_v;
  828 #endif
  829         switch (v) {
  830         case 4:
  831                 error = ipsec4_setspidx_ipaddr(m, spidx);
  832                 if (error)
  833                         return error;
  834                 ipsec4_get_ulp(m, spidx, needport);
  835                 return 0;
  836 #ifdef INET6
  837         case 6:
  838                 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
  839                         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  840                                 printf("ipsec_setspidx: "
  841                                     "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
  842                                     "ignored.\n", m->m_pkthdr.len));
  843                         return EINVAL;
  844                 }
  845                 error = ipsec6_setspidx_ipaddr(m, spidx);
  846                 if (error)
  847                         return error;
  848                 ipsec6_get_ulp(m, spidx, needport);
  849                 return 0;
  850 #endif
  851         default:
  852                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  853                         printf("ipsec_setspidx: "
  854                             "unknown IP version %u, ignored.\n", v));
  855                 return EINVAL;
  856         }
  857 }
  858 
  859 static void
  860 ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
  861 {
  862         u_int8_t nxt;
  863         int off;
  864 
  865         /* sanity check */
  866         IPSEC_ASSERT(m != NULL, ("ipsec4_get_ulp: null mbuf"));
  867         IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),
  868                 ("ipsec4_get_ulp: packet too short"));
  869 
  870         /* NB: ip_input() flips it into host endian XXX need more checking */
  871         if (m->m_len >= sizeof(struct ip)) {
  872                 struct ip *ip = mtod(m, struct ip *);
  873                 if (ip->ip_off & IP_OFF_CONVERT(IP_MF | IP_OFFMASK))
  874                         goto done;
  875 #ifdef _IP_VHL
  876                 off = _IP_VHL_HL(ip->ip_vhl) << 2;
  877 #else
  878                 off = ip->ip_hl << 2;
  879 #endif
  880                 nxt = ip->ip_p;
  881         } else {
  882                 struct ip ih;
  883 
  884                 m_copydata(m, 0, sizeof (struct ip), (caddr_t) &ih);
  885                 if (ih.ip_off & IP_OFF_CONVERT(IP_MF | IP_OFFMASK))
  886                         goto done;
  887 #ifdef _IP_VHL
  888                 off = _IP_VHL_HL(ih.ip_vhl) << 2;
  889 #else
  890                 off = ih.ip_hl << 2;
  891 #endif
  892                 nxt = ih.ip_p;
  893         }
  894 
  895         while (off < m->m_pkthdr.len) {
  896                 struct ip6_ext ip6e;
  897                 struct tcphdr th;
  898                 struct udphdr uh;
  899 
  900                 switch (nxt) {
  901                 case IPPROTO_TCP:
  902                         spidx->ul_proto = nxt;
  903                         if (!needport)
  904                                 goto done_proto;
  905                         if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
  906                                 goto done;
  907                         m_copydata(m, off, sizeof (th), (caddr_t) &th);
  908                         spidx->src.sin.sin_port = th.th_sport;
  909                         spidx->dst.sin.sin_port = th.th_dport;
  910                         return;
  911                 case IPPROTO_UDP:
  912                         spidx->ul_proto = nxt;
  913                         if (!needport)
  914                                 goto done_proto;
  915                         if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
  916                                 goto done;
  917                         m_copydata(m, off, sizeof (uh), (caddr_t) &uh);
  918                         spidx->src.sin.sin_port = uh.uh_sport;
  919                         spidx->dst.sin.sin_port = uh.uh_dport;
  920                         return;
  921                 case IPPROTO_AH:
  922                         if (m->m_pkthdr.len > off + sizeof(ip6e))
  923                                 goto done;
  924                         /* XXX sigh, this works but is totally bogus */
  925                         m_copydata(m, off, sizeof(ip6e), (caddr_t) &ip6e);
  926                         off += (ip6e.ip6e_len + 2) << 2;
  927                         nxt = ip6e.ip6e_nxt;
  928                         break;
  929                 case IPPROTO_ICMP:
  930                 default:
  931                         /* XXX intermediate headers??? */
  932                         spidx->ul_proto = nxt;
  933                         goto done_proto;
  934                 }
  935         }
  936 done:
  937         spidx->ul_proto = IPSEC_ULPROTO_ANY;
  938 done_proto:
  939         spidx->src.sin.sin_port = IPSEC_PORT_ANY;
  940         spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
  941 }
  942 
  943 /* assumes that m is sane */
  944 static int
  945 ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
  946 {
  947         static const struct sockaddr_in template = {
  948                 sizeof (struct sockaddr_in),
  949                 AF_INET,
  950                 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
  951         };
  952 
  953         spidx->src.sin = template;
  954         spidx->dst.sin = template;
  955 
  956         if (m->m_len < sizeof (struct ip)) {
  957                 m_copydata(m, offsetof(struct ip, ip_src),
  958                            sizeof (struct  in_addr),
  959                            (caddr_t) &spidx->src.sin.sin_addr);
  960                 m_copydata(m, offsetof(struct ip, ip_dst),
  961                            sizeof (struct  in_addr),
  962                            (caddr_t) &spidx->dst.sin.sin_addr);
  963         } else {
  964                 struct ip *ip = mtod(m, struct ip *);
  965                 spidx->src.sin.sin_addr = ip->ip_src;
  966                 spidx->dst.sin.sin_addr = ip->ip_dst;
  967         }
  968 
  969         spidx->prefs = sizeof(struct in_addr) << 3;
  970         spidx->prefd = sizeof(struct in_addr) << 3;
  971 
  972         return 0;
  973 }
  974 
  975 #ifdef INET6
  976 static void
  977 ipsec6_get_ulp(m, spidx, needport)
  978         struct mbuf *m;
  979         struct secpolicyindex *spidx;
  980         int needport;
  981 {
  982         int off, nxt;
  983         struct tcphdr th;
  984         struct udphdr uh;
  985 
  986         /* sanity check */
  987         if (m == NULL)
  988                 panic("ipsec6_get_ulp: NULL pointer was passed.\n");
  989 
  990         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  991                 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
  992 
  993         /* set default */
  994         spidx->ul_proto = IPSEC_ULPROTO_ANY;
  995         ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
  996         ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
  997 
  998         nxt = -1;
  999         off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
 1000         if (off < 0 || m->m_pkthdr.len < off)
 1001                 return;
 1002 
 1003         switch (nxt) {
 1004         case IPPROTO_TCP:
 1005                 spidx->ul_proto = nxt;
 1006                 if (!needport)
 1007                         break;
 1008                 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
 1009                         break;
 1010                 m_copydata(m, off, sizeof(th), (caddr_t)&th);
 1011                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
 1012                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
 1013                 break;
 1014         case IPPROTO_UDP:
 1015                 spidx->ul_proto = nxt;
 1016                 if (!needport)
 1017                         break;
 1018                 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
 1019                         break;
 1020                 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
 1021                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
 1022                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
 1023                 break;
 1024         case IPPROTO_ICMPV6:
 1025         default:
 1026                 /* XXX intermediate headers??? */
 1027                 spidx->ul_proto = nxt;
 1028                 break;
 1029         }
 1030 }
 1031 
 1032 /* assumes that m is sane */
 1033 static int
 1034 ipsec6_setspidx_ipaddr(m, spidx)
 1035         struct mbuf *m;
 1036         struct secpolicyindex *spidx;
 1037 {
 1038         struct ip6_hdr *ip6 = NULL;
 1039         struct ip6_hdr ip6buf;
 1040         struct sockaddr_in6 *sin6;
 1041 
 1042         if (m->m_len >= sizeof(*ip6))
 1043                 ip6 = mtod(m, struct ip6_hdr *);
 1044         else {
 1045                 m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
 1046                 ip6 = &ip6buf;
 1047         }
 1048 
 1049         sin6 = (struct sockaddr_in6 *)&spidx->src;
 1050         bzero(sin6, sizeof(*sin6));
 1051         sin6->sin6_family = AF_INET6;
 1052         sin6->sin6_len = sizeof(struct sockaddr_in6);
 1053         bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
 1054         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
 1055                 sin6->sin6_addr.s6_addr16[1] = 0;
 1056                 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
 1057         }
 1058         spidx->prefs = sizeof(struct in6_addr) << 3;
 1059 
 1060         sin6 = (struct sockaddr_in6 *)&spidx->dst;
 1061         bzero(sin6, sizeof(*sin6));
 1062         sin6->sin6_family = AF_INET6;
 1063         sin6->sin6_len = sizeof(struct sockaddr_in6);
 1064         bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
 1065         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
 1066                 sin6->sin6_addr.s6_addr16[1] = 0;
 1067                 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
 1068         }
 1069         spidx->prefd = sizeof(struct in6_addr) << 3;
 1070 
 1071         return 0;
 1072 }
 1073 #endif
 1074 
 1075 static void
 1076 ipsec_delpcbpolicy(p)
 1077         struct inpcbpolicy *p;
 1078 {
 1079         free(p, M_SECA);
 1080 }
 1081 
 1082 /* initialize policy in PCB */
 1083 int
 1084 ipsec_init_policy(so, pcb_sp)
 1085         struct socket *so;
 1086         struct inpcbpolicy **pcb_sp;
 1087 {
 1088         struct inpcbpolicy *new;
 1089 
 1090         /* sanity check. */
 1091         if (so == NULL || pcb_sp == NULL)
 1092                 panic("ipsec_init_policy: NULL pointer was passed.\n");
 1093 
 1094         new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
 1095                                             M_SECA, M_NOWAIT|M_ZERO);
 1096         if (new == NULL) {
 1097                 ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
 1098                 return ENOBUFS;
 1099         }
 1100 
 1101         if (IPSEC_PRIVILEGED_SO(so))
 1102                 new->priv = 1;
 1103         else
 1104                 new->priv = 0;
 1105 
 1106         if ((new->sp_in = KEY_NEWSP()) == NULL) {
 1107                 ipsec_delpcbpolicy(new);
 1108                 return ENOBUFS;
 1109         }
 1110         new->sp_in->state = IPSEC_SPSTATE_ALIVE;
 1111         new->sp_in->policy = IPSEC_POLICY_ENTRUST;
 1112 
 1113         if ((new->sp_out = KEY_NEWSP()) == NULL) {
 1114                 KEY_FREESP(&new->sp_in);
 1115                 ipsec_delpcbpolicy(new);
 1116                 return ENOBUFS;
 1117         }
 1118         new->sp_out->state = IPSEC_SPSTATE_ALIVE;
 1119         new->sp_out->policy = IPSEC_POLICY_ENTRUST;
 1120 
 1121         *pcb_sp = new;
 1122 
 1123         return 0;
 1124 }
 1125 
 1126 /* copy old ipsec policy into new */
 1127 int
 1128 ipsec_copy_policy(old, new)
 1129         struct inpcbpolicy *old, *new;
 1130 {
 1131         struct secpolicy *sp;
 1132 
 1133         sp = ipsec_deepcopy_policy(old->sp_in);
 1134         if (sp) {
 1135                 KEY_FREESP(&new->sp_in);
 1136                 new->sp_in = sp;
 1137         } else
 1138                 return ENOBUFS;
 1139 
 1140         sp = ipsec_deepcopy_policy(old->sp_out);
 1141         if (sp) {
 1142                 KEY_FREESP(&new->sp_out);
 1143                 new->sp_out = sp;
 1144         } else
 1145                 return ENOBUFS;
 1146 
 1147         new->priv = old->priv;
 1148 
 1149         return 0;
 1150 }
 1151 
 1152 /* deep-copy a policy in PCB */
 1153 static struct secpolicy *
 1154 ipsec_deepcopy_policy(src)
 1155         struct secpolicy *src;
 1156 {
 1157         struct ipsecrequest *newchain = NULL;
 1158         struct ipsecrequest *p;
 1159         struct ipsecrequest **q;
 1160         struct ipsecrequest *r;
 1161         struct secpolicy *dst;
 1162 
 1163         if (src == NULL)
 1164                 return NULL;
 1165         dst = KEY_NEWSP();
 1166         if (dst == NULL)
 1167                 return NULL;
 1168 
 1169         /*
 1170          * deep-copy IPsec request chain.  This is required since struct
 1171          * ipsecrequest is not reference counted.
 1172          */
 1173         q = &newchain;
 1174         for (p = src->req; p; p = p->next) {
 1175                 *q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
 1176                         M_SECA, M_NOWAIT);
 1177                 if (*q == NULL)
 1178                         goto fail;
 1179                 bzero(*q, sizeof(**q));
 1180                 (*q)->next = NULL;
 1181 
 1182                 (*q)->saidx.proto = p->saidx.proto;
 1183                 (*q)->saidx.mode = p->saidx.mode;
 1184                 (*q)->level = p->level;
 1185                 (*q)->saidx.reqid = p->saidx.reqid;
 1186 
 1187                 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
 1188                 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
 1189 
 1190                 (*q)->sav = NULL;
 1191                 (*q)->sp = dst;
 1192 
 1193                 q = &((*q)->next);
 1194         }
 1195 
 1196         dst->req = newchain;
 1197         dst->state = src->state;
 1198         dst->policy = src->policy;
 1199         /* do not touch the refcnt fields */
 1200 
 1201         return dst;
 1202 
 1203 fail:
 1204         for (p = newchain; p; p = r) {
 1205                 r = p->next;
 1206                 free(p, M_SECA);
 1207                 p = NULL;
 1208         }
 1209         return NULL;
 1210 }
 1211 
 1212 /* set policy and ipsec request if present. */
 1213 static int
 1214 ipsec_set_policy(pcb_sp, optname, request, len, priv)
 1215         struct secpolicy **pcb_sp;
 1216         int optname;
 1217         caddr_t request;
 1218         size_t len;
 1219         int priv;
 1220 {
 1221         struct sadb_x_policy *xpl;
 1222         struct secpolicy *newsp = NULL;
 1223         int error;
 1224 
 1225         /* sanity check. */
 1226         if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
 1227                 return EINVAL;
 1228         if (len < sizeof(*xpl))
 1229                 return EINVAL;
 1230         xpl = (struct sadb_x_policy *)request;
 1231 
 1232         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1233                 printf("ipsec_set_policy: passed policy\n");
 1234                 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
 1235 
 1236         /* check policy type */
 1237         /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
 1238         if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
 1239          || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
 1240                 return EINVAL;
 1241 
 1242         /* check privileged socket */
 1243         if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
 1244                 return EACCES;
 1245 
 1246         /* allocation new SP entry */
 1247         if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
 1248                 return error;
 1249 
 1250         newsp->state = IPSEC_SPSTATE_ALIVE;
 1251 
 1252         /* clear old SP and set new SP */
 1253         KEY_FREESP(pcb_sp);
 1254         *pcb_sp = newsp;
 1255         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1256                 printf("ipsec_set_policy: new policy\n");
 1257                 kdebug_secpolicy(newsp));
 1258 
 1259         return 0;
 1260 }
 1261 
 1262 static int
 1263 ipsec_get_policy(pcb_sp, mp)
 1264         struct secpolicy *pcb_sp;
 1265         struct mbuf **mp;
 1266 {
 1267 
 1268         /* sanity check. */
 1269         if (pcb_sp == NULL || mp == NULL)
 1270                 return EINVAL;
 1271 
 1272         *mp = key_sp2msg(pcb_sp);
 1273         if (!*mp) {
 1274                 ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
 1275                 return ENOBUFS;
 1276         }
 1277 
 1278         (*mp)->m_type = MT_DATA;
 1279         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1280                 printf("ipsec_get_policy:\n");
 1281                 kdebug_mbuf(*mp));
 1282 
 1283         return 0;
 1284 }
 1285 
 1286 int
 1287 ipsec4_set_policy(inp, optname, request, len, priv)
 1288         struct inpcb *inp;
 1289         int optname;
 1290         caddr_t request;
 1291         size_t len;
 1292         int priv;
 1293 {
 1294         struct sadb_x_policy *xpl;
 1295         struct secpolicy **pcb_sp;
 1296 
 1297         /* sanity check. */
 1298         if (inp == NULL || request == NULL)
 1299                 return EINVAL;
 1300         if (len < sizeof(*xpl))
 1301                 return EINVAL;
 1302         xpl = (struct sadb_x_policy *)request;
 1303 
 1304         IPSEC_ASSERT(inp->inp_sp != NULL,
 1305                      ("ipsec4_set_policy(): null inp->in_sp"));
 1306 
 1307         /* select direction */
 1308         switch (xpl->sadb_x_policy_dir) {
 1309         case IPSEC_DIR_INBOUND:
 1310                 pcb_sp = &inp->inp_sp->sp_in;
 1311                 break;
 1312         case IPSEC_DIR_OUTBOUND:
 1313                 pcb_sp = &inp->inp_sp->sp_out;
 1314                 break;
 1315         default:
 1316                 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
 1317                         xpl->sadb_x_policy_dir));
 1318                 return EINVAL;
 1319         }
 1320 
 1321         return ipsec_set_policy(pcb_sp, optname, request, len, priv);
 1322 }
 1323 
 1324 int
 1325 ipsec4_get_policy(inp, request, len, mp)
 1326         struct inpcb *inp;
 1327         caddr_t request;
 1328         size_t len;
 1329         struct mbuf **mp;
 1330 {
 1331         struct sadb_x_policy *xpl;
 1332         struct secpolicy *pcb_sp;
 1333 
 1334         /* sanity check. */
 1335         if (inp == NULL || request == NULL || mp == NULL)
 1336                 return EINVAL;
 1337         IPSEC_ASSERT(inp->inp_sp != NULL, ("ipsec4_get_policy: null inp_sp"));
 1338         if (len < sizeof(*xpl))
 1339                 return EINVAL;
 1340         xpl = (struct sadb_x_policy *)request;
 1341 
 1342         /* select direction */
 1343         switch (xpl->sadb_x_policy_dir) {
 1344         case IPSEC_DIR_INBOUND:
 1345                 pcb_sp = inp->inp_sp->sp_in;
 1346                 break;
 1347         case IPSEC_DIR_OUTBOUND:
 1348                 pcb_sp = inp->inp_sp->sp_out;
 1349                 break;
 1350         default:
 1351                 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
 1352                         xpl->sadb_x_policy_dir));
 1353                 return EINVAL;
 1354         }
 1355 
 1356         return ipsec_get_policy(pcb_sp, mp);
 1357 }
 1358 
 1359 /* delete policy in PCB */
 1360 int
 1361 ipsec4_delete_pcbpolicy(inp)
 1362         struct inpcb *inp;
 1363 {
 1364         IPSEC_ASSERT(inp != NULL, ("ipsec4_delete_pcbpolicy: null inp"));
 1365 
 1366         if (inp->inp_sp == NULL)
 1367                 return 0;
 1368 
 1369         if (inp->inp_sp->sp_in != NULL)
 1370                 KEY_FREESP(&inp->inp_sp->sp_in);
 1371 
 1372         if (inp->inp_sp->sp_out != NULL)
 1373                 KEY_FREESP(&inp->inp_sp->sp_out);
 1374 
 1375         ipsec_delpcbpolicy(inp->inp_sp);
 1376         inp->inp_sp = NULL;
 1377 
 1378         return 0;
 1379 }
 1380 
 1381 #ifdef INET6
 1382 int
 1383 ipsec6_set_policy(in6p, optname, request, len, priv)
 1384         struct in6pcb *in6p;
 1385         int optname;
 1386         caddr_t request;
 1387         size_t len;
 1388         int priv;
 1389 {
 1390         struct sadb_x_policy *xpl;
 1391         struct secpolicy **pcb_sp;
 1392 
 1393         /* sanity check. */
 1394         if (in6p == NULL || request == NULL)
 1395                 return EINVAL;
 1396         if (len < sizeof(*xpl))
 1397                 return EINVAL;
 1398         xpl = (struct sadb_x_policy *)request;
 1399 
 1400         /* select direction */
 1401         switch (xpl->sadb_x_policy_dir) {
 1402         case IPSEC_DIR_INBOUND:
 1403                 pcb_sp = &in6p->in6p_sp->sp_in;
 1404                 break;
 1405         case IPSEC_DIR_OUTBOUND:
 1406                 pcb_sp = &in6p->in6p_sp->sp_out;
 1407                 break;
 1408         default:
 1409                 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
 1410                         xpl->sadb_x_policy_dir));
 1411                 return EINVAL;
 1412         }
 1413 
 1414         return ipsec_set_policy(pcb_sp, optname, request, len, priv);
 1415 }
 1416 
 1417 int
 1418 ipsec6_get_policy(in6p, request, len, mp)
 1419         struct in6pcb *in6p;
 1420         caddr_t request;
 1421         size_t len;
 1422         struct mbuf **mp;
 1423 {
 1424         struct sadb_x_policy *xpl;
 1425         struct secpolicy *pcb_sp;
 1426 
 1427         /* sanity check. */
 1428         if (in6p == NULL || request == NULL || mp == NULL)
 1429                 return EINVAL;
 1430         IPSEC_ASSERT(in6p->in6p_sp != NULL, ("ipsec6_get_policy: null in6p_sp"));
 1431         if (len < sizeof(*xpl))
 1432                 return EINVAL;
 1433         xpl = (struct sadb_x_policy *)request;
 1434 
 1435         /* select direction */
 1436         switch (xpl->sadb_x_policy_dir) {
 1437         case IPSEC_DIR_INBOUND:
 1438                 pcb_sp = in6p->in6p_sp->sp_in;
 1439                 break;
 1440         case IPSEC_DIR_OUTBOUND:
 1441                 pcb_sp = in6p->in6p_sp->sp_out;
 1442                 break;
 1443         default:
 1444                 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
 1445                         xpl->sadb_x_policy_dir));
 1446                 return EINVAL;
 1447         }
 1448 
 1449         return ipsec_get_policy(pcb_sp, mp);
 1450 }
 1451 
 1452 int
 1453 ipsec6_delete_pcbpolicy(in6p)
 1454         struct in6pcb *in6p;
 1455 {
 1456         IPSEC_ASSERT(in6p != NULL, ("ipsec6_delete_pcbpolicy: null in6p"));
 1457 
 1458         if (in6p->in6p_sp == NULL)
 1459                 return 0;
 1460 
 1461         if (in6p->in6p_sp->sp_in != NULL)
 1462                 KEY_FREESP(&in6p->in6p_sp->sp_in);
 1463 
 1464         if (in6p->in6p_sp->sp_out != NULL)
 1465                 KEY_FREESP(&in6p->in6p_sp->sp_out);
 1466 
 1467         ipsec_delpcbpolicy(in6p->in6p_sp);
 1468         in6p->in6p_sp = NULL;
 1469 
 1470         return 0;
 1471 }
 1472 #endif
 1473 
 1474 /*
 1475  * return current level.
 1476  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
 1477  */
 1478 u_int
 1479 ipsec_get_reqlevel(isr)
 1480         struct ipsecrequest *isr;
 1481 {
 1482         u_int level = 0;
 1483         u_int esp_trans_deflev, esp_net_deflev;
 1484         u_int ah_trans_deflev, ah_net_deflev;
 1485 
 1486         IPSEC_ASSERT(isr != NULL && isr->sp != NULL,
 1487                 ("ipsec_get_reqlevel: null argument"));
 1488         IPSEC_ASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
 1489                 ("ipsec_get_reqlevel: af family mismatch, src %u, dst %u",
 1490                  isr->sp->spidx.src.sa.sa_family,
 1491                  isr->sp->spidx.dst.sa.sa_family));
 1492 
 1493 /* XXX note that we have ipseclog() expanded here - code sync issue */
 1494 #define IPSEC_CHECK_DEFAULT(lev) \
 1495         (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE            \
 1496                         && (lev) != IPSEC_LEVEL_UNIQUE)                       \
 1497                 ? (ipsec_debug                                                \
 1498                         ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
 1499                                 (lev), IPSEC_LEVEL_REQUIRE)                   \
 1500                         : 0),                                                 \
 1501                         (lev) = IPSEC_LEVEL_REQUIRE,                          \
 1502                         (lev)                                                 \
 1503                 : (lev))
 1504 
 1505         /* set default level */
 1506         switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
 1507 #ifdef INET
 1508         case AF_INET:
 1509                 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
 1510                 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
 1511                 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
 1512                 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
 1513                 break;
 1514 #endif
 1515 #ifdef INET6
 1516         case AF_INET6:
 1517                 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
 1518                 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
 1519                 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
 1520                 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
 1521                 break;
 1522 #endif /* INET6 */
 1523         default:
 1524                 panic("key_get_reqlevel: unknown af %u",
 1525                         isr->sp->spidx.src.sa.sa_family);
 1526         }
 1527 
 1528 #undef IPSEC_CHECK_DEFAULT
 1529 
 1530         /* set level */
 1531         switch (isr->level) {
 1532         case IPSEC_LEVEL_DEFAULT:
 1533                 switch (isr->saidx.proto) {
 1534                 case IPPROTO_ESP:
 1535                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1536                                 level = esp_net_deflev;
 1537                         else
 1538                                 level = esp_trans_deflev;
 1539                         break;
 1540                 case IPPROTO_AH:
 1541                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1542                                 level = ah_net_deflev;
 1543                         else
 1544                                 level = ah_trans_deflev;
 1545                 case IPPROTO_IPCOMP:
 1546                         /*
 1547                          * we don't really care, as IPcomp document says that
 1548                          * we shouldn't compress small packets
 1549                          */
 1550                         level = IPSEC_LEVEL_USE;
 1551                         break;
 1552                 default:
 1553                         panic("ipsec_get_reqlevel: "
 1554                                 "Illegal protocol defined %u\n",
 1555                                 isr->saidx.proto);
 1556                 }
 1557                 break;
 1558 
 1559         case IPSEC_LEVEL_USE:
 1560         case IPSEC_LEVEL_REQUIRE:
 1561                 level = isr->level;
 1562                 break;
 1563         case IPSEC_LEVEL_UNIQUE:
 1564                 level = IPSEC_LEVEL_REQUIRE;
 1565                 break;
 1566 
 1567         default:
 1568                 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
 1569                         isr->level);
 1570         }
 1571 
 1572         return level;
 1573 }
 1574 
 1575 /*
 1576  * Check security policy requirements against the actual
 1577  * packet contents.  Return one if the packet should be
 1578  * reject as "invalid"; otherwiser return zero to have the
 1579  * packet treated as "valid".
 1580  *
 1581  * OUT:
 1582  *      0: valid
 1583  *      1: invalid
 1584  */
 1585 int
 1586 ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
 1587 {
 1588         struct ipsecrequest *isr;
 1589         int need_auth;
 1590 
 1591         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1592                 printf("ipsec_in_reject: using SP\n");
 1593                 kdebug_secpolicy(sp));
 1594 
 1595         /* check policy */
 1596         switch (sp->policy) {
 1597         case IPSEC_POLICY_DISCARD:
 1598                 return 1;
 1599         case IPSEC_POLICY_BYPASS:
 1600         case IPSEC_POLICY_NONE:
 1601                 return 0;
 1602         }
 1603 
 1604         IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
 1605                 ("ipsec_in_reject: invalid policy %u", sp->policy));
 1606 
 1607         /* XXX should compare policy against ipsec header history */
 1608 
 1609         need_auth = 0;
 1610         for (isr = sp->req; isr != NULL; isr = isr->next) {
 1611                 if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
 1612                         continue;
 1613                 switch (isr->saidx.proto) {
 1614                 case IPPROTO_ESP:
 1615                         if ((m->m_flags & M_DECRYPTED) == 0) {
 1616                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1617                                     printf("ipsec_in_reject: ESP m_flags:%x\n",
 1618                                             m->m_flags));
 1619                                 return 1;
 1620                         }
 1621 
 1622                         if (!need_auth &&
 1623                             isr->sav != NULL &&
 1624                             isr->sav->tdb_authalgxform != NULL &&
 1625                             (m->m_flags & M_AUTHIPDGM) == 0) {
 1626                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1627                                     printf("ipsec_in_reject: ESP/AH m_flags:%x\n",
 1628                                             m->m_flags));
 1629                                 return 1;
 1630                         }
 1631                         break;
 1632                 case IPPROTO_AH:
 1633                         need_auth = 1;
 1634                         if ((m->m_flags & M_AUTHIPHDR) == 0) {
 1635                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1636                                     printf("ipsec_in_reject: AH m_flags:%x\n",
 1637                                             m->m_flags));
 1638                                 return 1;
 1639                         }
 1640                         break;
 1641                 case IPPROTO_IPCOMP:
 1642                         /*
 1643                          * we don't really care, as IPcomp document
 1644                          * says that we shouldn't compress small
 1645                          * packets, IPComp policy should always be
 1646                          * treated as being in "use" level.
 1647                          */
 1648                         break;
 1649                 }
 1650         }
 1651         return 0;               /* valid */
 1652 }
 1653 
 1654 /*
 1655  * Check AH/ESP integrity.
 1656  * This function is called from tcp_input(), udp_input(),
 1657  * and {ah,esp}4_input for tunnel mode
 1658  */
 1659 int
 1660 ipsec4_in_reject(m, inp)
 1661         struct mbuf *m;
 1662         struct inpcb *inp;
 1663 {
 1664         struct secpolicy *sp;
 1665         int error;
 1666         int result;
 1667 
 1668         IPSEC_ASSERT(m != NULL, ("ipsec4_in_reject_so: null mbuf"));
 1669 
 1670         /* get SP for this packet.
 1671          * When we are called from ip_forward(), we call
 1672          * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 1673          */
 1674         if (inp == NULL)
 1675                 sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
 1676         else
 1677                 sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
 1678                                            IN4PCB_TO_PCB(inp), &error);
 1679 
 1680         if (sp != NULL) {
 1681                 result = ipsec_in_reject(sp, m);
 1682                 if (result)
 1683                         newipsecstat.ips_in_polvio++;
 1684                 KEY_FREESP(&sp);
 1685         } else {
 1686                 result = 0;     /* XXX should be panic ?
 1687                                  * -> No, there may be error. */
 1688         }
 1689         return result;
 1690 }
 1691 
 1692 
 1693 #ifdef INET6
 1694 /*
 1695  * Check AH/ESP integrity.
 1696  * This function is called from tcp6_input(), udp6_input(),
 1697  * and {ah,esp}6_input for tunnel mode
 1698  */
 1699 int
 1700 ipsec6_in_reject(m, in6p)
 1701         struct mbuf *m;
 1702         struct in6pcb *in6p;
 1703 {
 1704         struct secpolicy *sp = NULL;
 1705         int error;
 1706         int result;
 1707 
 1708         /* sanity check */
 1709         if (m == NULL)
 1710                 return 0;       /* XXX should be panic ? */
 1711 
 1712         /* get SP for this packet.
 1713          * When we are called from ip_forward(), we call
 1714          * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 1715          */
 1716         if (in6p == NULL)
 1717                 sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
 1718         else
 1719                 sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
 1720                         IN6PCB_TO_PCB(in6p),
 1721                         &error);
 1722 
 1723         if (sp != NULL) {
 1724                 result = ipsec_in_reject(sp, m);
 1725                 if (result)
 1726                         newipsecstat.ips_in_polvio++;
 1727                 KEY_FREESP(&sp);
 1728         } else {
 1729                 result = 0;
 1730         }
 1731         return result;
 1732 }
 1733 #endif
 1734 
 1735 /*
 1736  * compute the byte size to be occupied by IPsec header.
 1737  * in case it is tunneled, it includes the size of outer IP header.
 1738  * NOTE: SP passed is free in this function.
 1739  */
 1740 static size_t
 1741 ipsec_hdrsiz(struct secpolicy *sp)
 1742 {
 1743         struct ipsecrequest *isr;
 1744         size_t siz;
 1745 
 1746         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1747                 printf("ipsec_hdrsiz: using SP\n");
 1748                 kdebug_secpolicy(sp));
 1749 
 1750         switch (sp->policy) {
 1751         case IPSEC_POLICY_DISCARD:
 1752         case IPSEC_POLICY_BYPASS:
 1753         case IPSEC_POLICY_NONE:
 1754                 return 0;
 1755         }
 1756 
 1757         IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
 1758                 ("ipsec_hdrsiz: invalid policy %u", sp->policy));
 1759 
 1760         siz = 0;
 1761         for (isr = sp->req; isr != NULL; isr = isr->next) {
 1762                 size_t clen = 0;
 1763 
 1764                 switch (isr->saidx.proto) {
 1765                 case IPPROTO_ESP:
 1766                         clen = esp_hdrsiz(isr->sav);
 1767                         break;
 1768                 case IPPROTO_AH:
 1769                         clen = ah_hdrsiz(isr->sav);
 1770                         break;
 1771                 case IPPROTO_IPCOMP:
 1772                         clen = sizeof(struct ipcomp);
 1773                         break;
 1774                 }
 1775 
 1776                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 1777                         switch (isr->saidx.dst.sa.sa_family) {
 1778                         case AF_INET:
 1779                                 clen += sizeof(struct ip);
 1780                                 break;
 1781 #ifdef INET6
 1782                         case AF_INET6:
 1783                                 clen += sizeof(struct ip6_hdr);
 1784                                 break;
 1785 #endif
 1786                         default:
 1787                                 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
 1788                                     "unknown AF %d in IPsec tunnel SA\n",
 1789                                     ((struct sockaddr *)&isr->saidx.dst)->sa_family));
 1790                                 break;
 1791                         }
 1792                 }
 1793                 siz += clen;
 1794         }
 1795 
 1796         return siz;
 1797 }
 1798 
 1799 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
 1800 size_t
 1801 ipsec4_hdrsiz(m, dir, inp)
 1802         struct mbuf *m;
 1803         u_int dir;
 1804         struct inpcb *inp;
 1805 {
 1806         struct secpolicy *sp;
 1807         int error;
 1808         size_t size;
 1809 
 1810         IPSEC_ASSERT(m != NULL, ("ipsec4_hdrsiz: null mbuf"));
 1811         IPSEC_ASSERT(inp == NULL || inp->inp_socket != NULL,
 1812                 ("ipsec4_hdrsize: socket w/o inpcb"));
 1813 
 1814         /* get SP for this packet.
 1815          * When we are called from ip_forward(), we call
 1816          * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 1817          */
 1818         if (inp == NULL)
 1819                 sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 1820         else
 1821                 sp = ipsec_getpolicybysock(m, dir,
 1822                                            IN4PCB_TO_PCB(inp), &error);
 1823 
 1824         if (sp != NULL) {
 1825                 size = ipsec_hdrsiz(sp);
 1826                 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1827                         printf("ipsec4_hdrsiz: size:%lu.\n",
 1828                                 (unsigned long)size));
 1829 
 1830                 KEY_FREESP(&sp);
 1831         } else {
 1832                 size = 0;       /* XXX should be panic ? */
 1833         }
 1834         return size;
 1835 }
 1836 
 1837 #ifdef INET6
 1838 /* This function is called from ipsec6_hdrsize_tcp(),
 1839  * and maybe from ip6_forward.()
 1840  */
 1841 size_t
 1842 ipsec6_hdrsiz(m, dir, in6p)
 1843         struct mbuf *m;
 1844         u_int dir;
 1845         struct in6pcb *in6p;
 1846 {
 1847         struct secpolicy *sp;
 1848         int error;
 1849         size_t size;
 1850 
 1851         IPSEC_ASSERT(m != NULL, ("ipsec6_hdrsiz: null mbuf"));
 1852         IPSEC_ASSERT(in6p == NULL || in6p->in6p_socket != NULL,
 1853                 ("ipsec6_hdrsize: socket w/o inpcb"));
 1854 
 1855         /* get SP for this packet */
 1856         /* XXX Is it right to call with IP_FORWARDING. */
 1857         if (in6p == NULL)
 1858                 sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 1859         else
 1860                 sp = ipsec_getpolicybysock(m, dir, 
 1861                         IN6PCB_TO_PCB(in6p),
 1862                         &error);
 1863 
 1864         if (sp == NULL)
 1865                 return 0;
 1866         size = ipsec_hdrsiz(sp);
 1867         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1868                 printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
 1869         KEY_FREESP(&sp);
 1870 
 1871         return size;
 1872 }
 1873 #endif /*INET6*/
 1874 
 1875 /*
 1876  * Check the variable replay window.
 1877  * ipsec_chkreplay() performs replay check before ICV verification.
 1878  * ipsec_updatereplay() updates replay bitmap.  This must be called after
 1879  * ICV verification (it also performs replay check, which is usually done
 1880  * beforehand).
 1881  * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
 1882  *
 1883  * based on RFC 2401.
 1884  */
 1885 int
 1886 ipsec_chkreplay(seq, sav)
 1887         u_int32_t seq;
 1888         struct secasvar *sav;
 1889 {
 1890         const struct secreplay *replay;
 1891         u_int32_t diff;
 1892         int fr;
 1893         u_int32_t wsizeb;       /* constant: bits of window size */
 1894         int frlast;             /* constant: last frame */
 1895 
 1896         IPSEC_SPLASSERT_SOFTNET("ipsec_chkreplay");
 1897 
 1898         IPSEC_ASSERT(sav != NULL, ("ipsec_chkreplay: Null SA"));
 1899         IPSEC_ASSERT(sav->replay != NULL, ("ipsec_chkreplay: Null replay state"));
 1900 
 1901         replay = sav->replay;
 1902 
 1903         if (replay->wsize == 0)
 1904                 return 1;       /* no need to check replay. */
 1905 
 1906         /* constant */
 1907         frlast = replay->wsize - 1;
 1908         wsizeb = replay->wsize << 3;
 1909 
 1910         /* sequence number of 0 is invalid */
 1911         if (seq == 0)
 1912                 return 0;
 1913 
 1914         /* first time is always okay */
 1915         if (replay->count == 0)
 1916                 return 1;
 1917 
 1918         if (seq > replay->lastseq) {
 1919                 /* larger sequences are okay */
 1920                 return 1;
 1921         } else {
 1922                 /* seq is equal or less than lastseq. */
 1923                 diff = replay->lastseq - seq;
 1924 
 1925                 /* over range to check, i.e. too old or wrapped */
 1926                 if (diff >= wsizeb)
 1927                         return 0;
 1928 
 1929                 fr = frlast - diff / 8;
 1930 
 1931                 /* this packet already seen ? */
 1932                 if ((replay->bitmap)[fr] & (1 << (diff % 8)))
 1933                         return 0;
 1934 
 1935                 /* out of order but good */
 1936                 return 1;
 1937         }
 1938 }
 1939 
 1940 /*
 1941  * check replay counter whether to update or not.
 1942  * OUT: 0:      OK
 1943  *      1:      NG
 1944  */
 1945 int
 1946 ipsec_updatereplay(seq, sav)
 1947         u_int32_t seq;
 1948         struct secasvar *sav;
 1949 {
 1950         struct secreplay *replay;
 1951         u_int32_t diff;
 1952         int fr;
 1953         u_int32_t wsizeb;       /* constant: bits of window size */
 1954         int frlast;             /* constant: last frame */
 1955 
 1956         IPSEC_SPLASSERT_SOFTNET("ipsec_updatereplay");
 1957 
 1958         IPSEC_ASSERT(sav != NULL, ("ipsec_updatereplay: Null SA"));
 1959         IPSEC_ASSERT(sav->replay != NULL, ("ipsec_updatereplay: Null replay state"));
 1960 
 1961         replay = sav->replay;
 1962 
 1963         if (replay->wsize == 0)
 1964                 goto ok;        /* no need to check replay. */
 1965 
 1966         /* constant */
 1967         frlast = replay->wsize - 1;
 1968         wsizeb = replay->wsize << 3;
 1969 
 1970         /* sequence number of 0 is invalid */
 1971         if (seq == 0)
 1972                 return 1;
 1973 
 1974         /* first time */
 1975         if (replay->count == 0) {
 1976                 replay->lastseq = seq;
 1977                 bzero(replay->bitmap, replay->wsize);
 1978                 (replay->bitmap)[frlast] = 1;
 1979                 goto ok;
 1980         }
 1981 
 1982         if (seq > replay->lastseq) {
 1983                 /* seq is larger than lastseq. */
 1984                 diff = seq - replay->lastseq;
 1985 
 1986                 /* new larger sequence number */
 1987                 if (diff < wsizeb) {
 1988                         /* In window */
 1989                         /* set bit for this packet */
 1990                         vshiftl(replay->bitmap, diff, replay->wsize);
 1991                         (replay->bitmap)[frlast] |= 1;
 1992                 } else {
 1993                         /* this packet has a "way larger" */
 1994                         bzero(replay->bitmap, replay->wsize);
 1995                         (replay->bitmap)[frlast] = 1;
 1996                 }
 1997                 replay->lastseq = seq;
 1998 
 1999                 /* larger is good */
 2000         } else {
 2001                 /* seq is equal or less than lastseq. */
 2002                 diff = replay->lastseq - seq;
 2003 
 2004                 /* over range to check, i.e. too old or wrapped */
 2005                 if (diff >= wsizeb)
 2006                         return 1;
 2007 
 2008                 fr = frlast - diff / 8;
 2009 
 2010                 /* this packet already seen ? */
 2011                 if ((replay->bitmap)[fr] & (1 << (diff % 8)))
 2012                         return 1;
 2013 
 2014                 /* mark as seen */
 2015                 (replay->bitmap)[fr] |= (1 << (diff % 8));
 2016 
 2017                 /* out of order but good */
 2018         }
 2019 
 2020 ok:
 2021         if (replay->count == ~0) {
 2022 
 2023                 /* set overflow flag */
 2024                 replay->overflow++;
 2025 
 2026                 /* don't increment, no more packets accepted */
 2027                 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
 2028                         return 1;
 2029 
 2030                 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
 2031                     replay->overflow, ipsec_logsastr(sav)));
 2032         }
 2033 
 2034         replay->count++;
 2035 
 2036         return 0;
 2037 }
 2038 
 2039 /*
 2040  * shift variable length bunffer to left.
 2041  * IN:  bitmap: pointer to the buffer
 2042  *      nbit:   the number of to shift.
 2043  *      wsize:  buffer size (bytes).
 2044  */
 2045 static void
 2046 vshiftl(bitmap, nbit, wsize)
 2047         unsigned char *bitmap;
 2048         int nbit, wsize;
 2049 {
 2050         int s, j, i;
 2051         unsigned char over;
 2052 
 2053         for (j = 0; j < nbit; j += 8) {
 2054                 s = (nbit - j < 8) ? (nbit - j): 8;
 2055                 bitmap[0] <<= s;
 2056                 for (i = 1; i < wsize; i++) {
 2057                         over = (bitmap[i] >> (8 - s));
 2058                         bitmap[i] <<= s;
 2059                         bitmap[i-1] |= over;
 2060                 }
 2061         }
 2062 
 2063         return;
 2064 }
 2065 
 2066 /* Return a printable string for the IPv4 address. */
 2067 static char *
 2068 inet_ntoa4(struct in_addr ina)
 2069 {
 2070         static char buf[4][4 * sizeof "123" + 4];
 2071         unsigned char *ucp = (unsigned char *) &ina;
 2072         static int i = 3;
 2073 
 2074         i = (i + 1) % 4;
 2075         sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
 2076             ucp[2] & 0xff, ucp[3] & 0xff);
 2077         return (buf[i]);
 2078 }
 2079 
 2080 /* Return a printable string for the address. */
 2081 char *
 2082 ipsec_address(union sockaddr_union* sa)
 2083 {
 2084         switch (sa->sa.sa_family) {
 2085 #if INET
 2086         case AF_INET:
 2087                 return inet_ntoa4(sa->sin.sin_addr);
 2088 #endif /* INET */
 2089 
 2090 #if INET6
 2091         case AF_INET6:
 2092                 return ip6_sprintf(&sa->sin6.sin6_addr);
 2093 #endif /* INET6 */
 2094 
 2095         default:
 2096                 return "(unknown address family)";
 2097         }
 2098 }
 2099 
 2100 const char *
 2101 ipsec_logsastr(sav)
 2102         struct secasvar *sav;
 2103 {
 2104         static char buf[256];
 2105         char *p;
 2106         struct secasindex *saidx = &sav->sah->saidx;
 2107 
 2108         IPSEC_ASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
 2109                 ("ipsec_logsastr: address family mismatch"));
 2110 
 2111         p = buf;
 2112         snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
 2113         while (p && *p)
 2114                 p++;
 2115         /* NB: only use ipsec_address on one address at a time */
 2116         snprintf(p, sizeof (buf) - (p - buf), "src=%s ",
 2117                 ipsec_address(&saidx->src));
 2118         while (p && *p)
 2119                 p++;
 2120         snprintf(p, sizeof (buf) - (p - buf), "dst=%s)",
 2121                 ipsec_address(&saidx->dst));
 2122 
 2123         return buf;
 2124 }
 2125 
 2126 void
 2127 ipsec_dumpmbuf(m)
 2128         struct mbuf *m;
 2129 {
 2130         int totlen;
 2131         int i;
 2132         u_char *p;
 2133 
 2134         totlen = 0;
 2135         printf("---\n");
 2136         while (m) {
 2137                 p = mtod(m, u_char *);
 2138                 for (i = 0; i < m->m_len; i++) {
 2139                         printf("%02x ", p[i]);
 2140                         totlen++;
 2141                         if (totlen % 16 == 0)
 2142                                 printf("\n");
 2143                 }
 2144                 m = m->m_next;
 2145         }
 2146         if (totlen % 16 != 0)
 2147                 printf("\n");
 2148         printf("---\n");
 2149 }
 2150 
 2151 /* XXX this stuff doesn't belong here... */
 2152 
 2153 static  struct xformsw* xforms = NULL;
 2154 
 2155 /*
 2156  * Register a transform; typically at system startup.
 2157  */
 2158 void
 2159 xform_register(struct xformsw* xsp)
 2160 {
 2161         xsp->xf_next = xforms;
 2162         xforms = xsp;
 2163 }
 2164 
 2165 /*
 2166  * Initialize transform support in an sav.
 2167  */
 2168 int
 2169 xform_init(struct secasvar *sav, int xftype)
 2170 {
 2171         struct xformsw *xsp;
 2172 
 2173         if (sav->tdb_xform != NULL)     /* previously initialized */
 2174                 return 0;
 2175         for (xsp = xforms; xsp; xsp = xsp->xf_next)
 2176                 if (xsp->xf_type == xftype)
 2177                         return (*xsp->xf_init)(sav, xsp);
 2178 
 2179         DPRINTF(("xform_init: no match for xform type %d\n", xftype));
 2180         return EINVAL;
 2181 }
 2182 
 2183 #ifdef __NetBSD__
 2184 void
 2185 ipsec_attach(void)
 2186 {
 2187         printf("initializing IPsec...");
 2188         ah_attach();
 2189         esp_attach();
 2190         ipcomp_attach();
 2191         ipe4_attach();
 2192         printf(" done\n");
 2193 }
 2194 #endif  /* __NetBSD__ */

Cache object: dbb37094655338d12e564e5e5703815d


[ 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.