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 /*      $FreeBSD: releng/11.0/sys/netipsec/ipsec.c 302054 2016-06-21 13:48:49Z bz $     */
    2 /*      $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane 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 "opt_inet.h"
   38 #include "opt_inet6.h"
   39 #include "opt_ipsec.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/malloc.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/domain.h>
   46 #include <sys/priv.h>
   47 #include <sys/protosw.h>
   48 #include <sys/socket.h>
   49 #include <sys/socketvar.h>
   50 #include <sys/errno.h>
   51 #include <sys/hhook.h>
   52 #include <sys/time.h>
   53 #include <sys/kernel.h>
   54 #include <sys/syslog.h>
   55 #include <sys/sysctl.h>
   56 #include <sys/proc.h>
   57 
   58 #include <net/if.h>
   59 #include <net/if_enc.h>
   60 #include <net/if_var.h>
   61 #include <net/vnet.h>
   62 
   63 #include <netinet/in.h>
   64 #include <netinet/in_systm.h>
   65 #include <netinet/ip.h>
   66 #include <netinet/ip_var.h>
   67 #include <netinet/in_var.h>
   68 #include <netinet/udp.h>
   69 #include <netinet/udp_var.h>
   70 #include <netinet/tcp.h>
   71 #include <netinet/udp.h>
   72 
   73 #include <netinet/ip6.h>
   74 #ifdef INET6
   75 #include <netinet6/ip6_var.h>
   76 #endif
   77 #include <netinet/in_pcb.h>
   78 #ifdef INET6
   79 #include <netinet/icmp6.h>
   80 #endif
   81 
   82 #include <sys/types.h>
   83 #include <netipsec/ipsec.h>
   84 #ifdef INET6
   85 #include <netipsec/ipsec6.h>
   86 #endif
   87 #include <netipsec/ah_var.h>
   88 #include <netipsec/esp_var.h>
   89 #include <netipsec/ipcomp.h>            /*XXX*/
   90 #include <netipsec/ipcomp_var.h>
   91 
   92 #include <netipsec/key.h>
   93 #include <netipsec/keydb.h>
   94 #include <netipsec/key_debug.h>
   95 
   96 #include <netipsec/xform.h>
   97 
   98 #include <machine/in_cksum.h>
   99 
  100 #include <opencrypto/cryptodev.h>
  101 
  102 #ifdef IPSEC_DEBUG
  103 VNET_DEFINE(int, ipsec_debug) = 1;
  104 #else
  105 VNET_DEFINE(int, ipsec_debug) = 0;
  106 #endif
  107 
  108 /* NB: name changed so netstat doesn't use it. */
  109 VNET_PCPUSTAT_DEFINE(struct ipsecstat, ipsec4stat);
  110 VNET_PCPUSTAT_SYSINIT(ipsec4stat);
  111 
  112 #ifdef VIMAGE
  113 VNET_PCPUSTAT_SYSUNINIT(ipsec4stat);
  114 #endif /* VIMAGE */
  115 
  116 VNET_DEFINE(int, ip4_ah_offsetmask) = 0;        /* maybe IP_DF? */
  117 /* DF bit on encap. 0: clear 1: set 2: copy */
  118 VNET_DEFINE(int, ip4_ipsec_dfbit) = 0;
  119 VNET_DEFINE(int, ip4_esp_trans_deflev) = IPSEC_LEVEL_USE;
  120 VNET_DEFINE(int, ip4_esp_net_deflev) = IPSEC_LEVEL_USE;
  121 VNET_DEFINE(int, ip4_ah_trans_deflev) = IPSEC_LEVEL_USE;
  122 VNET_DEFINE(int, ip4_ah_net_deflev) = IPSEC_LEVEL_USE;
  123 /* ECN ignore(-1)/forbidden(0)/allowed(1) */
  124 VNET_DEFINE(int, ip4_ipsec_ecn) = 0;
  125 VNET_DEFINE(int, ip4_esp_randpad) = -1;
  126 
  127 static VNET_DEFINE(struct secpolicy, def_policy);
  128 #define V_def_policy    VNET(def_policy)
  129 /*
  130  * Crypto support requirements:
  131  *
  132  *  1   require hardware support
  133  * -1   require software support
  134  *  0   take anything
  135  */
  136 VNET_DEFINE(int, crypto_support) = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  137 
  138 FEATURE(ipsec, "Internet Protocol Security (IPsec)");
  139 #ifdef IPSEC_NAT_T
  140 FEATURE(ipsec_natt, "UDP Encapsulation of IPsec ESP Packets ('NAT-T')");
  141 #endif
  142 
  143 SYSCTL_DECL(_net_inet_ipsec);
  144 
  145 /* net.inet.ipsec */
  146 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy,
  147         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0,
  148         "IPsec default policy.");
  149 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
  150         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_trans_deflev), 0,
  151         "Default ESP transport mode level");
  152 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
  153         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_net_deflev), 0,
  154         "Default ESP tunnel mode level.");
  155 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
  156         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ah_trans_deflev), 0,
  157         "AH transfer mode default level.");
  158 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
  159         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ah_net_deflev), 0,
  160         "AH tunnel mode default level.");
  161 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS, ah_cleartos,
  162         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ah_cleartos), 0,
  163         "If set clear type-of-service field when doing AH computation.");
  164 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK, ah_offsetmask,
  165         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ah_offsetmask), 0,
  166         "If not set clear offset field mask when doing AH computation.");
  167 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT, dfbit,
  168         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_dfbit), 0,
  169         "Do not fragment bit on encap.");
  170 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, ecn,
  171         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_ecn), 0,
  172         "Explicit Congestion Notification handling.");
  173 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG, debug,
  174         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipsec_debug), 0,
  175         "Enable IPsec debugging output when set.");
  176 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, crypto_support,
  177         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(crypto_support), 0,
  178         "Crypto driver selection.");
  179 SYSCTL_VNET_PCPUSTAT(_net_inet_ipsec, OID_AUTO, ipsecstats, struct ipsecstat,
  180     ipsec4stat, "IPsec IPv4 statistics.");
  181 
  182 #ifdef REGRESSION
  183 /*
  184  * When set to 1, IPsec will send packets with the same sequence number.
  185  * This allows to verify if the other side has proper replay attacks detection.
  186  */
  187 VNET_DEFINE(int, ipsec_replay) = 0;
  188 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay,
  189         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipsec_replay), 0,
  190         "Emulate replay attack");
  191 /*
  192  * When set 1, IPsec will send packets with corrupted HMAC.
  193  * This allows to verify if the other side properly detects modified packets.
  194  */
  195 VNET_DEFINE(int, ipsec_integrity) = 0;
  196 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity,
  197         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipsec_integrity), 0,
  198         "Emulate man-in-the-middle attack");
  199 #endif
  200 
  201 #ifdef INET6 
  202 VNET_PCPUSTAT_DEFINE(struct ipsecstat, ipsec6stat);
  203 VNET_PCPUSTAT_SYSINIT(ipsec6stat);
  204 
  205 #ifdef VIMAGE
  206 VNET_PCPUSTAT_SYSUNINIT(ipsec6stat);
  207 #endif /* VIMAGE */
  208 
  209 VNET_DEFINE(int, ip6_esp_trans_deflev) = IPSEC_LEVEL_USE;
  210 VNET_DEFINE(int, ip6_esp_net_deflev) = IPSEC_LEVEL_USE;
  211 VNET_DEFINE(int, ip6_ah_trans_deflev) = IPSEC_LEVEL_USE;
  212 VNET_DEFINE(int, ip6_ah_net_deflev) = IPSEC_LEVEL_USE;
  213 VNET_DEFINE(int, ip6_ipsec_ecn) = 0;    /* ECN ignore(-1)/forbidden(0)/allowed(1) */
  214 
  215 SYSCTL_DECL(_net_inet6_ipsec6);
  216 
  217 /* net.inet6.ipsec6 */
  218 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy,
  219         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0,
  220         "IPsec default policy.");
  221 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
  222         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_trans_deflev), 0,
  223         "Default ESP transport mode level.");
  224 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
  225         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_net_deflev), 0,
  226         "Default ESP tunnel mode level.");
  227 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
  228         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ah_trans_deflev), 0,
  229         "AH transfer mode default level.");
  230 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
  231         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ah_net_deflev), 0,
  232         "AH tunnel mode default level.");
  233 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN, ecn,
  234         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ipsec_ecn), 0,
  235         "Explicit Congestion Notification handling.");
  236 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG, debug,
  237         CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipsec_debug), 0,
  238         "Enable IPsec debugging output when set.");
  239 SYSCTL_VNET_PCPUSTAT(_net_inet6_ipsec6, IPSECCTL_STATS, ipsecstats,
  240     struct ipsecstat, ipsec6stat, "IPsec IPv6 statistics.");
  241 #endif /* INET6 */
  242 
  243 static int ipsec_in_reject(struct secpolicy *, const struct mbuf *);
  244 static int ipsec_setspidx_inpcb(const struct mbuf *, struct inpcb *);
  245 static int ipsec_setspidx(const struct mbuf *, struct secpolicyindex *, int);
  246 static void ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *, int);
  247 static int ipsec4_setspidx_ipaddr(const struct mbuf *, struct secpolicyindex *);
  248 #ifdef INET6
  249 static void ipsec6_get_ulp(const struct mbuf *m, struct secpolicyindex *, int);
  250 static int ipsec6_setspidx_ipaddr(const struct mbuf *, struct secpolicyindex *);
  251 #endif
  252 static void ipsec_delpcbpolicy(struct inpcbpolicy *);
  253 static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
  254 static void vshiftl(unsigned char *, int, int);
  255 
  256 MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
  257 
  258 /*
  259  * Return a held reference to the default SP.
  260  */
  261 static struct secpolicy *
  262 key_allocsp_default(const char* where, int tag)
  263 {
  264         struct secpolicy *sp;
  265 
  266         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  267                 printf("DP key_allocsp_default from %s:%u\n", where, tag));
  268 
  269         sp = &V_def_policy;
  270         if (sp->policy != IPSEC_POLICY_DISCARD &&
  271             sp->policy != IPSEC_POLICY_NONE) {
  272                 ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
  273                     sp->policy, IPSEC_POLICY_NONE));
  274                 sp->policy = IPSEC_POLICY_NONE;
  275         }
  276         key_addref(sp);
  277 
  278         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  279                 printf("DP key_allocsp_default returns SP:%p (%u)\n",
  280                         sp, sp->refcnt));
  281         return (sp);
  282 }
  283 #define KEY_ALLOCSP_DEFAULT() \
  284         key_allocsp_default(__FILE__, __LINE__)
  285 
  286 /*
  287  * For OUTBOUND packet having a socket. Searching SPD for packet,
  288  * and return a pointer to SP.
  289  * OUT: NULL:   no apropreate SP found, the following value is set to error.
  290  *              0       : bypass
  291  *              EACCES  : discard packet.
  292  *              ENOENT  : ipsec_acquire() in progress, maybe.
  293  *              others  : error occurred.
  294  *      others: a pointer to SP
  295  *
  296  * NOTE: IPv6 mapped adddress concern is implemented here.
  297  */
  298 struct secpolicy *
  299 ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
  300 {
  301         struct secpolicy *sp;
  302 
  303         IPSEC_ASSERT(tdbi != NULL, ("null tdbi"));
  304         IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  305                 ("invalid direction %u", dir));
  306 
  307         sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
  308         if (sp == NULL)                 /*XXX????*/
  309                 sp = KEY_ALLOCSP_DEFAULT();
  310         IPSEC_ASSERT(sp != NULL, ("null SP"));
  311         return (sp);
  312 }
  313 
  314 /*
  315  * For OUTBOUND packet having a socket. Searching SPD for packet,
  316  * and return a pointer to SP.
  317  * OUT: NULL:   no apropreate SP found, the following value is set to error.
  318  *              0       : bypass
  319  *              EACCES  : discard packet.
  320  *              ENOENT  : ipsec_acquire() in progress, maybe.
  321  *              others  : error occurred.
  322  *      others: a pointer to SP
  323  *
  324  * NOTE: IPv6 mapped adddress concern is implemented here.
  325  */
  326 static struct secpolicy *
  327 ipsec_getpolicybysock(const struct mbuf *m, u_int dir, struct inpcb *inp,
  328     int *error)
  329 {
  330         struct inpcbpolicy *pcbsp;
  331         struct secpolicy *currsp = NULL;        /* Policy on socket. */
  332         struct secpolicy *sp;
  333 
  334         IPSEC_ASSERT(m != NULL, ("null mbuf"));
  335         IPSEC_ASSERT(inp != NULL, ("null inpcb"));
  336         IPSEC_ASSERT(error != NULL, ("null error"));
  337         IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  338                 ("invalid direction %u", dir));
  339 
  340         if (!key_havesp(dir)) {
  341                 /* No SP found, use system default. */
  342                 sp = KEY_ALLOCSP_DEFAULT();
  343                 return (sp);
  344         }
  345 
  346         /* Set spidx in pcb. */
  347         *error = ipsec_setspidx_inpcb(m, inp);
  348         if (*error)
  349                 return (NULL);
  350 
  351         pcbsp = inp->inp_sp;
  352         IPSEC_ASSERT(pcbsp != NULL, ("null pcbsp"));
  353         switch (dir) {
  354         case IPSEC_DIR_INBOUND:
  355                 currsp = pcbsp->sp_in;
  356                 break;
  357         case IPSEC_DIR_OUTBOUND:
  358                 currsp = pcbsp->sp_out;
  359                 break;
  360         }
  361         IPSEC_ASSERT(currsp != NULL, ("null currsp"));
  362 
  363         if (pcbsp->priv) {                      /* When privilieged socket. */
  364                 switch (currsp->policy) {
  365                 case IPSEC_POLICY_BYPASS:
  366                 case IPSEC_POLICY_IPSEC:
  367                         key_addref(currsp);
  368                         sp = currsp;
  369                         break;
  370 
  371                 case IPSEC_POLICY_ENTRUST:
  372                         /* Look for a policy in SPD. */
  373                         sp = KEY_ALLOCSP(&currsp->spidx, dir);
  374                         if (sp == NULL)         /* No SP found. */
  375                                 sp = KEY_ALLOCSP_DEFAULT();
  376                         break;
  377 
  378                 default:
  379                         ipseclog((LOG_ERR, "%s: Invalid policy for PCB %d\n",
  380                                 __func__, currsp->policy));
  381                         *error = EINVAL;
  382                         return (NULL);
  383                 }
  384         } else {                                /* Unpriv, SPD has policy. */
  385                 sp = KEY_ALLOCSP(&currsp->spidx, dir);
  386                 if (sp == NULL) {               /* No SP found. */
  387                         switch (currsp->policy) {
  388                         case IPSEC_POLICY_BYPASS:
  389                                 ipseclog((LOG_ERR, "%s: Illegal policy for "
  390                                         "non-priviliged defined %d\n",
  391                                         __func__, currsp->policy));
  392                                 *error = EINVAL;
  393                                 return (NULL);
  394 
  395                         case IPSEC_POLICY_ENTRUST:
  396                                 sp = KEY_ALLOCSP_DEFAULT();
  397                                 break;
  398 
  399                         case IPSEC_POLICY_IPSEC:
  400                                 key_addref(currsp);
  401                                 sp = currsp;
  402                                 break;
  403 
  404                         default:
  405                                 ipseclog((LOG_ERR, "%s: Invalid policy for "
  406                                         "PCB %d\n", __func__, currsp->policy));
  407                                 *error = EINVAL;
  408                                 return (NULL);
  409                         }
  410                 }
  411         }
  412         IPSEC_ASSERT(sp != NULL,
  413                 ("null SP (priv %u policy %u", pcbsp->priv, currsp->policy));
  414         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  415                 printf("DP %s (priv %u policy %u) allocate SP:%p (refcnt %u)\n",
  416                         __func__, pcbsp->priv, currsp->policy, sp, sp->refcnt));
  417         return (sp);
  418 }
  419 
  420 /*
  421  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
  422  * and return a pointer to SP.
  423  * OUT: positive: a pointer to the entry for security policy leaf matched.
  424  *      NULL:   no apropreate SP found, the following value is set to error.
  425  *              0       : bypass
  426  *              EACCES  : discard packet.
  427  *              ENOENT  : ipsec_acquire() in progress, maybe.
  428  *              others  : error occurred.
  429  */
  430 struct secpolicy *
  431 ipsec_getpolicybyaddr(const struct mbuf *m, u_int dir, int *error)
  432 {
  433         struct secpolicyindex spidx;
  434         struct secpolicy *sp;
  435 
  436         IPSEC_ASSERT(m != NULL, ("null mbuf"));
  437         IPSEC_ASSERT(error != NULL, ("null error"));
  438         IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  439                 ("invalid direction %u", dir));
  440 
  441         sp = NULL;
  442         *error = 0;
  443         if (key_havesp(dir)) {
  444                 /* Make an index to look for a policy. */
  445                 *error = ipsec_setspidx(m, &spidx, 0);
  446                 if (*error != 0) {
  447                         DPRINTF(("%s: setpidx failed, dir %u\n",
  448                                 __func__, dir));
  449                         return (NULL);
  450                 }
  451                 spidx.dir = dir;
  452                 sp = KEY_ALLOCSP(&spidx, dir);
  453         }
  454         if (sp == NULL)                 /* No SP found, use system default. */
  455                 sp = KEY_ALLOCSP_DEFAULT();
  456         IPSEC_ASSERT(sp != NULL, ("null SP"));
  457         return (sp);
  458 }
  459 
  460 struct secpolicy *
  461 ipsec4_checkpolicy(const struct mbuf *m, u_int dir, int *error,
  462     struct inpcb *inp)
  463 {
  464         struct secpolicy *sp;
  465 
  466         *error = 0;
  467         if (inp == NULL)
  468                 sp = ipsec_getpolicybyaddr(m, dir, error);
  469         else
  470                 sp = ipsec_getpolicybysock(m, dir, inp, error);
  471         if (sp == NULL) {
  472                 IPSEC_ASSERT(*error != 0, ("getpolicy failed w/o error"));
  473                 IPSECSTAT_INC(ips_out_inval);
  474                 return (NULL);
  475         }
  476         IPSEC_ASSERT(*error == 0, ("sp w/ error set to %u", *error));
  477         switch (sp->policy) {
  478         case IPSEC_POLICY_ENTRUST:
  479         default:
  480                 printf("%s: invalid policy %u\n", __func__, sp->policy);
  481                 /* FALLTHROUGH */
  482         case IPSEC_POLICY_DISCARD:
  483                 IPSECSTAT_INC(ips_out_polvio);
  484                 *error = -EINVAL;       /* Packet is discarded by caller. */
  485                 break;
  486         case IPSEC_POLICY_BYPASS:
  487         case IPSEC_POLICY_NONE:
  488                 KEY_FREESP(&sp);
  489                 sp = NULL;              /* NB: force NULL result. */
  490                 break;
  491         case IPSEC_POLICY_IPSEC:
  492                 if (sp->req == NULL)    /* Acquire a SA. */
  493                         *error = key_spdacquire(sp);
  494                 break;
  495         }
  496         if (*error != 0) {
  497                 KEY_FREESP(&sp);
  498                 sp = NULL;
  499         }
  500         return (sp);
  501 }
  502 
  503 static int
  504 ipsec_setspidx_inpcb(const struct mbuf *m, struct inpcb *inp)
  505 {
  506         int error;
  507 
  508         IPSEC_ASSERT(inp != NULL, ("null inp"));
  509         IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp"));
  510         IPSEC_ASSERT(inp->inp_sp->sp_out != NULL && inp->inp_sp->sp_in != NULL,
  511                 ("null sp_in || sp_out"));
  512 
  513         error = ipsec_setspidx(m, &inp->inp_sp->sp_in->spidx, 1);
  514         if (error == 0) {
  515                 inp->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
  516                 inp->inp_sp->sp_out->spidx = inp->inp_sp->sp_in->spidx;
  517                 inp->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
  518         } else {
  519                 bzero(&inp->inp_sp->sp_in->spidx,
  520                         sizeof (inp->inp_sp->sp_in->spidx));
  521                 bzero(&inp->inp_sp->sp_out->spidx,
  522                         sizeof (inp->inp_sp->sp_in->spidx));
  523         }
  524         return (error);
  525 }
  526 
  527 /*
  528  * Configure security policy index (src/dst/proto/sport/dport)
  529  * by looking at the content of mbuf.
  530  * The caller is responsible for error recovery (like clearing up spidx).
  531  */
  532 static int
  533 ipsec_setspidx(const struct mbuf *m, struct secpolicyindex *spidx,
  534     int needport)
  535 {
  536         struct ip ipbuf;
  537         const struct ip *ip = NULL;
  538         const struct mbuf *n;
  539         u_int v;
  540         int len;
  541         int error;
  542 
  543         IPSEC_ASSERT(m != NULL, ("null mbuf"));
  544 
  545         /*
  546          * Validate m->m_pkthdr.len.  We see incorrect length if we
  547          * mistakenly call this function with inconsistent mbuf chain
  548          * (like 4.4BSD tcp/udp processing).  XXX Should we panic here?
  549          */
  550         len = 0;
  551         for (n = m; n; n = n->m_next)
  552                 len += n->m_len;
  553         if (m->m_pkthdr.len != len) {
  554                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  555                         printf("%s: pkthdr len(%d) mismatch (%d), ignored.\n",
  556                                 __func__, len, m->m_pkthdr.len));
  557                 return (EINVAL);
  558         }
  559 
  560         if (m->m_pkthdr.len < sizeof(struct ip)) {
  561                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  562                         printf("%s: pkthdr len(%d) too small (v4), ignored.\n",
  563                             __func__, m->m_pkthdr.len));
  564                 return (EINVAL);
  565         }
  566 
  567         if (m->m_len >= sizeof(*ip))
  568                 ip = mtod(m, const struct ip *);
  569         else {
  570                 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
  571                 ip = &ipbuf;
  572         }
  573         v = ip->ip_v;
  574         switch (v) {
  575         case 4:
  576                 error = ipsec4_setspidx_ipaddr(m, spidx);
  577                 if (error)
  578                         return (error);
  579                 ipsec4_get_ulp(m, spidx, needport);
  580                 return (0);
  581 #ifdef INET6
  582         case 6:
  583                 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
  584                         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  585                                 printf("%s: pkthdr len(%d) too small (v6), "
  586                                 "ignored\n", __func__, m->m_pkthdr.len));
  587                         return (EINVAL);
  588                 }
  589                 error = ipsec6_setspidx_ipaddr(m, spidx);
  590                 if (error)
  591                         return (error);
  592                 ipsec6_get_ulp(m, spidx, needport);
  593                 return (0);
  594 #endif
  595         default:
  596                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  597                         printf("%s: " "unknown IP version %u, ignored.\n",
  598                                 __func__, v));
  599                 return (EINVAL);
  600         }
  601 }
  602 
  603 static void
  604 ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *spidx,
  605     int needport)
  606 {
  607         u_int8_t nxt;
  608         int off;
  609 
  610         /* Sanity check. */
  611         IPSEC_ASSERT(m != NULL, ("null mbuf"));
  612         IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),("packet too short"));
  613 
  614         if (m->m_len >= sizeof (struct ip)) {
  615                 const struct ip *ip = mtod(m, const struct ip *);
  616                 if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
  617                         goto done;
  618                 off = ip->ip_hl << 2;
  619                 nxt = ip->ip_p;
  620         } else {
  621                 struct ip ih;
  622 
  623                 m_copydata(m, 0, sizeof (struct ip), (caddr_t) &ih);
  624                 if (ih.ip_off & htons(IP_MF | IP_OFFMASK))
  625                         goto done;
  626                 off = ih.ip_hl << 2;
  627                 nxt = ih.ip_p;
  628         }
  629 
  630         while (off < m->m_pkthdr.len) {
  631                 struct ip6_ext ip6e;
  632                 struct tcphdr th;
  633                 struct udphdr uh;
  634 
  635                 switch (nxt) {
  636                 case IPPROTO_TCP:
  637                         spidx->ul_proto = nxt;
  638                         if (!needport)
  639                                 goto done_proto;
  640                         if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
  641                                 goto done;
  642                         m_copydata(m, off, sizeof (th), (caddr_t) &th);
  643                         spidx->src.sin.sin_port = th.th_sport;
  644                         spidx->dst.sin.sin_port = th.th_dport;
  645                         return;
  646                 case IPPROTO_UDP:
  647                         spidx->ul_proto = nxt;
  648                         if (!needport)
  649                                 goto done_proto;
  650                         if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
  651                                 goto done;
  652                         m_copydata(m, off, sizeof (uh), (caddr_t) &uh);
  653                         spidx->src.sin.sin_port = uh.uh_sport;
  654                         spidx->dst.sin.sin_port = uh.uh_dport;
  655                         return;
  656                 case IPPROTO_AH:
  657                         if (off + sizeof(ip6e) > m->m_pkthdr.len)
  658                                 goto done;
  659                         /* XXX Sigh, this works but is totally bogus. */
  660                         m_copydata(m, off, sizeof(ip6e), (caddr_t) &ip6e);
  661                         off += (ip6e.ip6e_len + 2) << 2;
  662                         nxt = ip6e.ip6e_nxt;
  663                         break;
  664                 case IPPROTO_ICMP:
  665                 default:
  666                         /* XXX Intermediate headers??? */
  667                         spidx->ul_proto = nxt;
  668                         goto done_proto;
  669                 }
  670         }
  671 done:
  672         spidx->ul_proto = IPSEC_ULPROTO_ANY;
  673 done_proto:
  674         spidx->src.sin.sin_port = IPSEC_PORT_ANY;
  675         spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
  676 }
  677 
  678 /* Assumes that m is sane. */
  679 static int
  680 ipsec4_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx)
  681 {
  682         static const struct sockaddr_in template = {
  683                 sizeof (struct sockaddr_in),
  684                 AF_INET,
  685                 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
  686         };
  687 
  688         spidx->src.sin = template;
  689         spidx->dst.sin = template;
  690 
  691         if (m->m_len < sizeof (struct ip)) {
  692                 m_copydata(m, offsetof(struct ip, ip_src),
  693                            sizeof (struct  in_addr),
  694                            (caddr_t) &spidx->src.sin.sin_addr);
  695                 m_copydata(m, offsetof(struct ip, ip_dst),
  696                            sizeof (struct  in_addr),
  697                            (caddr_t) &spidx->dst.sin.sin_addr);
  698         } else {
  699                 const struct ip *ip = mtod(m, const struct ip *);
  700                 spidx->src.sin.sin_addr = ip->ip_src;
  701                 spidx->dst.sin.sin_addr = ip->ip_dst;
  702         }
  703 
  704         spidx->prefs = sizeof(struct in_addr) << 3;
  705         spidx->prefd = sizeof(struct in_addr) << 3;
  706 
  707         return (0);
  708 }
  709 
  710 #ifdef INET6
  711 static void
  712 ipsec6_get_ulp(const struct mbuf *m, struct secpolicyindex *spidx,
  713     int needport)
  714 {
  715         int off, nxt;
  716         struct tcphdr th;
  717         struct udphdr uh;
  718         struct icmp6_hdr ih;
  719 
  720         /* Sanity check. */
  721         if (m == NULL)
  722                 panic("%s: NULL pointer was passed.\n", __func__);
  723 
  724         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  725                 printf("%s:\n", __func__); kdebug_mbuf(m));
  726 
  727         /* Set default. */
  728         spidx->ul_proto = IPSEC_ULPROTO_ANY;
  729         ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
  730         ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
  731 
  732         nxt = -1;
  733         off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
  734         if (off < 0 || m->m_pkthdr.len < off)
  735                 return;
  736 
  737         switch (nxt) {
  738         case IPPROTO_TCP:
  739                 spidx->ul_proto = nxt;
  740                 if (!needport)
  741                         break;
  742                 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
  743                         break;
  744                 m_copydata(m, off, sizeof(th), (caddr_t)&th);
  745                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
  746                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
  747                 break;
  748         case IPPROTO_UDP:
  749                 spidx->ul_proto = nxt;
  750                 if (!needport)
  751                         break;
  752                 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
  753                         break;
  754                 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
  755                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
  756                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
  757                 break;
  758         case IPPROTO_ICMPV6:
  759                 spidx->ul_proto = nxt;
  760                 if (off + sizeof(struct icmp6_hdr) > m->m_pkthdr.len)
  761                         break;
  762                 m_copydata(m, off, sizeof(ih), (caddr_t)&ih);
  763                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port =
  764                     htons((uint16_t)ih.icmp6_type);
  765                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
  766                     htons((uint16_t)ih.icmp6_code);
  767                 break;
  768         default:
  769                 /* XXX Intermediate headers??? */
  770                 spidx->ul_proto = nxt;
  771                 break;
  772         }
  773 }
  774 
  775 /* Assumes that m is sane. */
  776 static int
  777 ipsec6_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx)
  778 {
  779         struct ip6_hdr ip6buf;
  780         const struct ip6_hdr *ip6 = NULL;
  781         struct sockaddr_in6 *sin6;
  782 
  783         if (m->m_len >= sizeof(*ip6))
  784                 ip6 = mtod(m, const struct ip6_hdr *);
  785         else {
  786                 m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
  787                 ip6 = &ip6buf;
  788         }
  789 
  790         sin6 = (struct sockaddr_in6 *)&spidx->src;
  791         bzero(sin6, sizeof(*sin6));
  792         sin6->sin6_family = AF_INET6;
  793         sin6->sin6_len = sizeof(struct sockaddr_in6);
  794         bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
  795         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
  796                 sin6->sin6_addr.s6_addr16[1] = 0;
  797                 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
  798         }
  799         spidx->prefs = sizeof(struct in6_addr) << 3;
  800 
  801         sin6 = (struct sockaddr_in6 *)&spidx->dst;
  802         bzero(sin6, sizeof(*sin6));
  803         sin6->sin6_family = AF_INET6;
  804         sin6->sin6_len = sizeof(struct sockaddr_in6);
  805         bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
  806         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
  807                 sin6->sin6_addr.s6_addr16[1] = 0;
  808                 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
  809         }
  810         spidx->prefd = sizeof(struct in6_addr) << 3;
  811 
  812         return (0);
  813 }
  814 #endif
  815 
  816 int
  817 ipsec_run_hhooks(struct ipsec_ctx_data *ctx, int type)
  818 {
  819         int idx;
  820 
  821         switch (ctx->af) {
  822 #ifdef INET
  823         case AF_INET:
  824                 idx = HHOOK_IPSEC_INET;
  825                 break;
  826 #endif
  827 #ifdef INET6
  828         case AF_INET6:
  829                 idx = HHOOK_IPSEC_INET6;
  830                 break;
  831 #endif
  832         default:
  833                 return (EPFNOSUPPORT);
  834         }
  835         if (type == HHOOK_TYPE_IPSEC_IN)
  836                 HHOOKS_RUN_IF(V_ipsec_hhh_in[idx], ctx, NULL);
  837         else
  838                 HHOOKS_RUN_IF(V_ipsec_hhh_out[idx], ctx, NULL);
  839         if (*ctx->mp == NULL)
  840                 return (EACCES);
  841         return (0);
  842 }
  843 
  844 static void
  845 ipsec_delpcbpolicy(struct inpcbpolicy *p)
  846 {
  847 
  848         free(p, M_IPSEC_INPCB);
  849 }
  850 
  851 /* Initialize policy in PCB. */
  852 int
  853 ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp)
  854 {
  855         struct inpcbpolicy *new;
  856 
  857         /* Sanity check. */
  858         if (so == NULL || pcb_sp == NULL)
  859                 panic("%s: NULL pointer was passed.\n", __func__);
  860 
  861         new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
  862                                             M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
  863         if (new == NULL) {
  864                 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
  865                 return (ENOBUFS);
  866         }
  867 
  868         new->priv = IPSEC_IS_PRIVILEGED_SO(so);
  869 
  870         if ((new->sp_in = KEY_NEWSP()) == NULL) {
  871                 ipsec_delpcbpolicy(new);
  872                 return (ENOBUFS);
  873         }
  874         new->sp_in->policy = IPSEC_POLICY_ENTRUST;
  875         if ((new->sp_out = KEY_NEWSP()) == NULL) {
  876                 KEY_FREESP(&new->sp_in);
  877                 ipsec_delpcbpolicy(new);
  878                 return (ENOBUFS);
  879         }
  880         new->sp_out->policy = IPSEC_POLICY_ENTRUST;
  881         *pcb_sp = new;
  882 
  883         return (0);
  884 }
  885 
  886 /* Copy old IPsec policy into new. */
  887 int
  888 ipsec_copy_policy(struct inpcbpolicy *old, struct inpcbpolicy *new)
  889 {
  890         struct secpolicy *sp;
  891 
  892         sp = ipsec_deepcopy_policy(old->sp_in);
  893         if (sp) {
  894                 KEY_FREESP(&new->sp_in);
  895                 new->sp_in = sp;
  896         } else
  897                 return (ENOBUFS);
  898 
  899         sp = ipsec_deepcopy_policy(old->sp_out);
  900         if (sp) {
  901                 KEY_FREESP(&new->sp_out);
  902                 new->sp_out = sp;
  903         } else
  904                 return (ENOBUFS);
  905 
  906         new->priv = old->priv;
  907 
  908         return (0);
  909 }
  910 
  911 struct ipsecrequest *
  912 ipsec_newisr(void)
  913 {
  914         struct ipsecrequest *p;
  915 
  916         p = malloc(sizeof(struct ipsecrequest), M_IPSEC_SR, M_NOWAIT|M_ZERO);
  917         if (p != NULL)
  918                 IPSECREQUEST_LOCK_INIT(p);
  919         return (p);
  920 }
  921 
  922 void
  923 ipsec_delisr(struct ipsecrequest *p)
  924 {
  925 
  926         IPSECREQUEST_LOCK_DESTROY(p);
  927         free(p, M_IPSEC_SR);
  928 }
  929 
  930 /* Deep-copy a policy in PCB. */
  931 static struct secpolicy *
  932 ipsec_deepcopy_policy(struct secpolicy *src)
  933 {
  934         struct ipsecrequest *newchain = NULL;
  935         struct ipsecrequest *p;
  936         struct ipsecrequest **q;
  937         struct ipsecrequest *r;
  938         struct secpolicy *dst;
  939 
  940         if (src == NULL)
  941                 return (NULL);
  942         dst = KEY_NEWSP();
  943         if (dst == NULL)
  944                 return (NULL);
  945 
  946         /*
  947          * Deep-copy IPsec request chain.  This is required since struct
  948          * ipsecrequest is not reference counted.
  949          */
  950         q = &newchain;
  951         for (p = src->req; p; p = p->next) {
  952                 *q = ipsec_newisr();
  953                 if (*q == NULL)
  954                         goto fail;
  955                 (*q)->saidx.proto = p->saidx.proto;
  956                 (*q)->saidx.mode = p->saidx.mode;
  957                 (*q)->level = p->level;
  958                 (*q)->saidx.reqid = p->saidx.reqid;
  959 
  960                 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
  961                 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
  962 
  963                 (*q)->sp = dst;
  964 
  965                 q = &((*q)->next);
  966         }
  967 
  968         dst->req = newchain;
  969         dst->policy = src->policy;
  970         /* Do not touch the refcnt fields. */
  971 
  972         return (dst);
  973 
  974 fail:
  975         for (p = newchain; p; p = r) {
  976                 r = p->next;
  977                 ipsec_delisr(p);
  978                 p = NULL;
  979         }
  980         KEY_FREESP(&dst);
  981         return (NULL);
  982 }
  983 
  984 /* Set policy and IPsec request if present. */
  985 static int
  986 ipsec_set_policy_internal(struct secpolicy **pcb_sp, int optname,
  987     caddr_t request, size_t len, struct ucred *cred)
  988 {
  989         struct sadb_x_policy *xpl;
  990         struct secpolicy *newsp = NULL;
  991         int error;
  992 
  993         /* Sanity check. */
  994         if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
  995                 return (EINVAL);
  996         if (len < sizeof(*xpl))
  997                 return (EINVAL);
  998         xpl = (struct sadb_x_policy *)request;
  999 
 1000         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1001                 printf("%s: passed policy\n", __func__);
 1002                 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
 1003 
 1004         /* Check policy type. */
 1005         /* ipsec_set_policy_internal() accepts IPSEC, ENTRUST and BYPASS. */
 1006         if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
 1007          || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
 1008                 return (EINVAL);
 1009 
 1010         /* Check privileged socket. */
 1011         if (cred != NULL && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS) {
 1012                 error = priv_check_cred(cred, PRIV_NETINET_IPSEC, 0);
 1013                 if (error)
 1014                         return (EACCES);
 1015         }
 1016 
 1017         /* Allocating new SP entry. */
 1018         if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
 1019                 return (error);
 1020 
 1021         /* Clear old SP and set new SP. */
 1022         KEY_FREESP(pcb_sp);
 1023         *pcb_sp = newsp;
 1024         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1025                 printf("%s: new policy\n", __func__);
 1026                 kdebug_secpolicy(newsp));
 1027 
 1028         return (0);
 1029 }
 1030 
 1031 int
 1032 ipsec_set_policy(struct inpcb *inp, int optname, caddr_t request,
 1033     size_t len, struct ucred *cred)
 1034 {
 1035         struct sadb_x_policy *xpl;
 1036         struct secpolicy **pcb_sp;
 1037 
 1038         /* Sanity check. */
 1039         if (inp == NULL || request == NULL)
 1040                 return (EINVAL);
 1041         if (len < sizeof(*xpl))
 1042                 return (EINVAL);
 1043         xpl = (struct sadb_x_policy *)request;
 1044 
 1045         /* Select direction. */
 1046         switch (xpl->sadb_x_policy_dir) {
 1047         case IPSEC_DIR_INBOUND:
 1048                 pcb_sp = &inp->inp_sp->sp_in;
 1049                 break;
 1050         case IPSEC_DIR_OUTBOUND:
 1051                 pcb_sp = &inp->inp_sp->sp_out;
 1052                 break;
 1053         default:
 1054                 ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
 1055                         xpl->sadb_x_policy_dir));
 1056                 return (EINVAL);
 1057         }
 1058 
 1059         return (ipsec_set_policy_internal(pcb_sp, optname, request, len, cred));
 1060 }
 1061 
 1062 int
 1063 ipsec_get_policy(struct inpcb *inp, caddr_t request, size_t len,
 1064     struct mbuf **mp)
 1065 {
 1066         struct sadb_x_policy *xpl;
 1067         struct secpolicy *pcb_sp;
 1068 
 1069         /* Sanity check. */
 1070         if (inp == NULL || request == NULL || mp == NULL)
 1071                 return (EINVAL);
 1072         IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp"));
 1073         if (len < sizeof(*xpl))
 1074                 return (EINVAL);
 1075         xpl = (struct sadb_x_policy *)request;
 1076 
 1077         /* Select direction. */
 1078         switch (xpl->sadb_x_policy_dir) {
 1079         case IPSEC_DIR_INBOUND:
 1080                 pcb_sp = inp->inp_sp->sp_in;
 1081                 break;
 1082         case IPSEC_DIR_OUTBOUND:
 1083                 pcb_sp = inp->inp_sp->sp_out;
 1084                 break;
 1085         default:
 1086                 ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
 1087                         xpl->sadb_x_policy_dir));
 1088                 return (EINVAL);
 1089         }
 1090 
 1091         /* Sanity check. Should be an IPSEC_ASSERT. */
 1092         if (pcb_sp == NULL)
 1093                 return (EINVAL);
 1094 
 1095         *mp = key_sp2msg(pcb_sp);
 1096         if (!*mp) {
 1097                 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
 1098                 return (ENOBUFS);
 1099         }
 1100 
 1101         (*mp)->m_type = MT_DATA;
 1102         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1103                 printf("%s:\n", __func__); kdebug_mbuf(*mp));
 1104 
 1105         return (0);
 1106 }
 1107 
 1108 /* Delete policy in PCB. */
 1109 int
 1110 ipsec_delete_pcbpolicy(struct inpcb *inp)
 1111 {
 1112         IPSEC_ASSERT(inp != NULL, ("null inp"));
 1113 
 1114         if (inp->inp_sp == NULL)
 1115                 return (0);
 1116 
 1117         if (inp->inp_sp->sp_in != NULL)
 1118                 KEY_FREESP(&inp->inp_sp->sp_in);
 1119 
 1120         if (inp->inp_sp->sp_out != NULL)
 1121                 KEY_FREESP(&inp->inp_sp->sp_out);
 1122 
 1123         ipsec_delpcbpolicy(inp->inp_sp);
 1124         inp->inp_sp = NULL;
 1125 
 1126         return (0);
 1127 }
 1128 
 1129 /*
 1130  * Return current level.
 1131  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
 1132  */
 1133 u_int
 1134 ipsec_get_reqlevel(struct ipsecrequest *isr)
 1135 {
 1136         u_int level = 0;
 1137         u_int esp_trans_deflev, esp_net_deflev;
 1138         u_int ah_trans_deflev, ah_net_deflev;
 1139 
 1140         IPSEC_ASSERT(isr != NULL && isr->sp != NULL, ("null argument"));
 1141         IPSEC_ASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
 1142                 ("af family mismatch, src %u, dst %u",
 1143                  isr->sp->spidx.src.sa.sa_family,
 1144                  isr->sp->spidx.dst.sa.sa_family));
 1145 
 1146 /* XXX Note that we have ipseclog() expanded here - code sync issue. */
 1147 #define IPSEC_CHECK_DEFAULT(lev) \
 1148         (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE            \
 1149                         && (lev) != IPSEC_LEVEL_UNIQUE)                       \
 1150                 ? (V_ipsec_debug                                                      \
 1151                         ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
 1152                                 (lev), IPSEC_LEVEL_REQUIRE)                   \
 1153                         : 0),                                                 \
 1154                         (lev) = IPSEC_LEVEL_REQUIRE,                          \
 1155                         (lev)                                                 \
 1156                 : (lev))
 1157 
 1158         /* Set default level. */
 1159         switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
 1160 #ifdef INET
 1161         case AF_INET:
 1162                 esp_trans_deflev = IPSEC_CHECK_DEFAULT(V_ip4_esp_trans_deflev);
 1163                 esp_net_deflev = IPSEC_CHECK_DEFAULT(V_ip4_esp_net_deflev);
 1164                 ah_trans_deflev = IPSEC_CHECK_DEFAULT(V_ip4_ah_trans_deflev);
 1165                 ah_net_deflev = IPSEC_CHECK_DEFAULT(V_ip4_ah_net_deflev);
 1166                 break;
 1167 #endif
 1168 #ifdef INET6
 1169         case AF_INET6:
 1170                 esp_trans_deflev = IPSEC_CHECK_DEFAULT(V_ip6_esp_trans_deflev);
 1171                 esp_net_deflev = IPSEC_CHECK_DEFAULT(V_ip6_esp_net_deflev);
 1172                 ah_trans_deflev = IPSEC_CHECK_DEFAULT(V_ip6_ah_trans_deflev);
 1173                 ah_net_deflev = IPSEC_CHECK_DEFAULT(V_ip6_ah_net_deflev);
 1174                 break;
 1175 #endif /* INET6 */
 1176         default:
 1177                 panic("%s: unknown af %u",
 1178                         __func__, isr->sp->spidx.src.sa.sa_family);
 1179         }
 1180 
 1181 #undef IPSEC_CHECK_DEFAULT
 1182 
 1183         /* Set level. */
 1184         switch (isr->level) {
 1185         case IPSEC_LEVEL_DEFAULT:
 1186                 switch (isr->saidx.proto) {
 1187                 case IPPROTO_ESP:
 1188                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1189                                 level = esp_net_deflev;
 1190                         else
 1191                                 level = esp_trans_deflev;
 1192                         break;
 1193                 case IPPROTO_AH:
 1194                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1195                                 level = ah_net_deflev;
 1196                         else
 1197                                 level = ah_trans_deflev;
 1198                         break;
 1199                 case IPPROTO_IPCOMP:
 1200                         /*
 1201                          * We don't really care, as IPcomp document says that
 1202                          * we shouldn't compress small packets.
 1203                          */
 1204                         level = IPSEC_LEVEL_USE;
 1205                         break;
 1206                 default:
 1207                         panic("%s: Illegal protocol defined %u\n", __func__,
 1208                                 isr->saidx.proto);
 1209                 }
 1210                 break;
 1211 
 1212         case IPSEC_LEVEL_USE:
 1213         case IPSEC_LEVEL_REQUIRE:
 1214                 level = isr->level;
 1215                 break;
 1216         case IPSEC_LEVEL_UNIQUE:
 1217                 level = IPSEC_LEVEL_REQUIRE;
 1218                 break;
 1219 
 1220         default:
 1221                 panic("%s: Illegal IPsec level %u\n", __func__, isr->level);
 1222         }
 1223 
 1224         return (level);
 1225 }
 1226 
 1227 /*
 1228  * Check security policy requirements against the actual
 1229  * packet contents.  Return one if the packet should be
 1230  * reject as "invalid"; otherwiser return zero to have the
 1231  * packet treated as "valid".
 1232  *
 1233  * OUT:
 1234  *      0: valid
 1235  *      1: invalid
 1236  */
 1237 static int
 1238 ipsec_in_reject(struct secpolicy *sp, const struct mbuf *m)
 1239 {
 1240         struct ipsecrequest *isr;
 1241         int need_auth;
 1242 
 1243         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1244                 printf("%s: using SP\n", __func__); kdebug_secpolicy(sp));
 1245 
 1246         /* Check policy. */
 1247         switch (sp->policy) {
 1248         case IPSEC_POLICY_DISCARD:
 1249                 return (1);
 1250         case IPSEC_POLICY_BYPASS:
 1251         case IPSEC_POLICY_NONE:
 1252                 return (0);
 1253         }
 1254 
 1255         IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
 1256                 ("invalid policy %u", sp->policy));
 1257 
 1258         /* XXX Should compare policy against IPsec header history. */
 1259 
 1260         need_auth = 0;
 1261         for (isr = sp->req; isr != NULL; isr = isr->next) {
 1262                 if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
 1263                         continue;
 1264                 switch (isr->saidx.proto) {
 1265                 case IPPROTO_ESP:
 1266                         if ((m->m_flags & M_DECRYPTED) == 0) {
 1267                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1268                                     printf("%s: ESP m_flags:%x\n", __func__,
 1269                                             m->m_flags));
 1270                                 return (1);
 1271                         }
 1272 
 1273                         if (!need_auth &&
 1274                             isr->sav != NULL &&
 1275                             isr->sav->tdb_authalgxform != NULL &&
 1276                             (m->m_flags & M_AUTHIPDGM) == 0) {
 1277                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1278                                     printf("%s: ESP/AH m_flags:%x\n", __func__,
 1279                                             m->m_flags));
 1280                                 return (1);
 1281                         }
 1282                         break;
 1283                 case IPPROTO_AH:
 1284                         need_auth = 1;
 1285                         if ((m->m_flags & M_AUTHIPHDR) == 0) {
 1286                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1287                                     printf("%s: AH m_flags:%x\n", __func__,
 1288                                             m->m_flags));
 1289                                 return (1);
 1290                         }
 1291                         break;
 1292                 case IPPROTO_IPCOMP:
 1293                         /*
 1294                          * We don't really care, as IPcomp document
 1295                          * says that we shouldn't compress small
 1296                          * packets.  IPComp policy should always be
 1297                          * treated as being in "use" level.
 1298                          */
 1299                         break;
 1300                 }
 1301         }
 1302         return (0);             /* Valid. */
 1303 }
 1304 
 1305 /*
 1306  * Non zero return value means security policy DISCARD or policy violation.
 1307  */
 1308 static int
 1309 ipsec46_in_reject(const struct mbuf *m, struct inpcb *inp)
 1310 {
 1311         struct secpolicy *sp;
 1312         int error;
 1313         int result;
 1314 
 1315         if (!key_havesp(IPSEC_DIR_INBOUND))
 1316                 return 0;
 1317 
 1318         IPSEC_ASSERT(m != NULL, ("null mbuf"));
 1319 
 1320         /* Get SP for this packet. */
 1321         if (inp == NULL)
 1322                 sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, &error);
 1323         else
 1324                 sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
 1325 
 1326         if (sp != NULL) {
 1327                 result = ipsec_in_reject(sp, m);
 1328                 KEY_FREESP(&sp);
 1329         } else {
 1330                 result = 1;     /* treat errors as policy violation */
 1331         }
 1332         return (result);
 1333 }
 1334 
 1335 /*
 1336  * Check AH/ESP integrity.
 1337  * This function is called from tcp_input(), udp_input(),
 1338  * and {ah,esp}4_input for tunnel mode.
 1339  */
 1340 int
 1341 ipsec4_in_reject(const struct mbuf *m, struct inpcb *inp)
 1342 {
 1343         int result;
 1344 
 1345         result = ipsec46_in_reject(m, inp);
 1346         if (result)
 1347                 IPSECSTAT_INC(ips_in_polvio);
 1348 
 1349         return (result);
 1350 }
 1351 
 1352 #ifdef INET6
 1353 /*
 1354  * Check AH/ESP integrity.
 1355  * This function is called from tcp6_input(), udp6_input(),
 1356  * and {ah,esp}6_input for tunnel mode.
 1357  */
 1358 int
 1359 ipsec6_in_reject(const struct mbuf *m, struct inpcb *inp)
 1360 {
 1361         int result;
 1362 
 1363         result = ipsec46_in_reject(m, inp);
 1364         if (result)
 1365                 IPSEC6STAT_INC(ips_in_polvio);
 1366 
 1367         return (result);
 1368 }
 1369 #endif
 1370 
 1371 /*
 1372  * Compute the byte size to be occupied by IPsec header.
 1373  * In case it is tunnelled, it includes the size of outer IP header.
 1374  * NOTE: SP passed is freed in this function.
 1375  */
 1376 static size_t
 1377 ipsec_hdrsiz_internal(struct secpolicy *sp)
 1378 {
 1379         struct ipsecrequest *isr;
 1380         size_t size;
 1381 
 1382         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1383                 printf("%s: using SP\n", __func__); kdebug_secpolicy(sp));
 1384 
 1385         switch (sp->policy) {
 1386         case IPSEC_POLICY_DISCARD:
 1387         case IPSEC_POLICY_BYPASS:
 1388         case IPSEC_POLICY_NONE:
 1389                 return (0);
 1390         }
 1391 
 1392         IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
 1393                 ("invalid policy %u", sp->policy));
 1394 
 1395         size = 0;
 1396         for (isr = sp->req; isr != NULL; isr = isr->next) {
 1397                 size_t clen = 0;
 1398 
 1399                 switch (isr->saidx.proto) {
 1400                 case IPPROTO_ESP:
 1401                         clen = esp_hdrsiz(isr->sav);
 1402                         break;
 1403                 case IPPROTO_AH:
 1404                         clen = ah_hdrsiz(isr->sav);
 1405                         break;
 1406                 case IPPROTO_IPCOMP:
 1407                         clen = sizeof(struct ipcomp);
 1408                         break;
 1409                 }
 1410 
 1411                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 1412                         switch (isr->saidx.dst.sa.sa_family) {
 1413                         case AF_INET:
 1414                                 clen += sizeof(struct ip);
 1415                                 break;
 1416 #ifdef INET6
 1417                         case AF_INET6:
 1418                                 clen += sizeof(struct ip6_hdr);
 1419                                 break;
 1420 #endif
 1421                         default:
 1422                                 ipseclog((LOG_ERR, "%s: unknown AF %d in "
 1423                                     "IPsec tunnel SA\n", __func__,
 1424                                     ((struct sockaddr *)&isr->saidx.dst)->sa_family));
 1425                                 break;
 1426                         }
 1427                 }
 1428                 size += clen;
 1429         }
 1430 
 1431         return (size);
 1432 }
 1433 
 1434 /* 
 1435  * This function is called from ipsec_hdrsiz_tcp(), ip_ipsec_mtu(),
 1436  * disabled ip6_ipsec_mtu() and ip6_forward().
 1437  */
 1438 size_t
 1439 ipsec_hdrsiz(const struct mbuf *m, u_int dir, struct inpcb *inp)
 1440 {
 1441         struct secpolicy *sp;
 1442         int error;
 1443         size_t size;
 1444 
 1445         if (!key_havesp(dir))
 1446                 return 0;
 1447 
 1448         IPSEC_ASSERT(m != NULL, ("null mbuf"));
 1449 
 1450         /* Get SP for this packet. */
 1451         if (inp == NULL)
 1452                 sp = ipsec_getpolicybyaddr(m, dir, &error);
 1453         else
 1454                 sp = ipsec_getpolicybysock(m, dir, inp, &error);
 1455 
 1456         if (sp != NULL) {
 1457                 size = ipsec_hdrsiz_internal(sp);
 1458                 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1459                         printf("%s: size:%lu.\n", __func__,
 1460                                 (unsigned long)size));
 1461 
 1462                 KEY_FREESP(&sp);
 1463         } else {
 1464                 size = 0;       /* XXX Should be panic?
 1465                                  * -> No, we are called w/o knowing if
 1466                                  *    IPsec processing is needed. */
 1467         }
 1468         return (size);
 1469 }
 1470 
 1471 /*
 1472  * Check the variable replay window.
 1473  * ipsec_chkreplay() performs replay check before ICV verification.
 1474  * ipsec_updatereplay() updates replay bitmap.  This must be called after
 1475  * ICV verification (it also performs replay check, which is usually done
 1476  * beforehand).
 1477  * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
 1478  *
 1479  * Based on RFC 2401.
 1480  */
 1481 int
 1482 ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
 1483 {
 1484         const struct secreplay *replay;
 1485         u_int32_t diff;
 1486         int fr;
 1487         u_int32_t wsizeb;       /* Constant: bits of window size. */
 1488         int frlast;             /* Constant: last frame. */
 1489 
 1490         IPSEC_ASSERT(sav != NULL, ("Null SA"));
 1491         IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
 1492 
 1493         replay = sav->replay;
 1494 
 1495         if (replay->wsize == 0)
 1496                 return (1);     /* No need to check replay. */
 1497 
 1498         /* Constant. */
 1499         frlast = replay->wsize - 1;
 1500         wsizeb = replay->wsize << 3;
 1501 
 1502         /* Sequence number of 0 is invalid. */
 1503         if (seq == 0)
 1504                 return (0);
 1505 
 1506         /* First time is always okay. */
 1507         if (replay->count == 0)
 1508                 return (1);
 1509 
 1510         if (seq > replay->lastseq) {
 1511                 /* Larger sequences are okay. */
 1512                 return (1);
 1513         } else {
 1514                 /* seq is equal or less than lastseq. */
 1515                 diff = replay->lastseq - seq;
 1516 
 1517                 /* Over range to check, i.e. too old or wrapped. */
 1518                 if (diff >= wsizeb)
 1519                         return (0);
 1520 
 1521                 fr = frlast - diff / 8;
 1522 
 1523                 /* This packet already seen? */
 1524                 if ((replay->bitmap)[fr] & (1 << (diff % 8)))
 1525                         return (0);
 1526 
 1527                 /* Out of order but good. */
 1528                 return (1);
 1529         }
 1530 }
 1531 
 1532 /*
 1533  * Check replay counter whether to update or not.
 1534  * OUT: 0:      OK
 1535  *      1:      NG
 1536  */
 1537 int
 1538 ipsec_updatereplay(u_int32_t seq, struct secasvar *sav)
 1539 {
 1540         char buf[128];
 1541         struct secreplay *replay;
 1542         u_int32_t diff;
 1543         int fr;
 1544         u_int32_t wsizeb;       /* Constant: bits of window size. */
 1545         int frlast;             /* Constant: last frame. */
 1546 
 1547         IPSEC_ASSERT(sav != NULL, ("Null SA"));
 1548         IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
 1549 
 1550         replay = sav->replay;
 1551 
 1552         if (replay->wsize == 0)
 1553                 goto ok;        /* No need to check replay. */
 1554 
 1555         /* Constant. */
 1556         frlast = replay->wsize - 1;
 1557         wsizeb = replay->wsize << 3;
 1558 
 1559         /* Sequence number of 0 is invalid. */
 1560         if (seq == 0)
 1561                 return (1);
 1562 
 1563         /* First time. */
 1564         if (replay->count == 0) {
 1565                 replay->lastseq = seq;
 1566                 bzero(replay->bitmap, replay->wsize);
 1567                 (replay->bitmap)[frlast] = 1;
 1568                 goto ok;
 1569         }
 1570 
 1571         if (seq > replay->lastseq) {
 1572                 /* seq is larger than lastseq. */
 1573                 diff = seq - replay->lastseq;
 1574 
 1575                 /* New larger sequence number. */
 1576                 if (diff < wsizeb) {
 1577                         /* In window. */
 1578                         /* Set bit for this packet. */
 1579                         vshiftl(replay->bitmap, diff, replay->wsize);
 1580                         (replay->bitmap)[frlast] |= 1;
 1581                 } else {
 1582                         /* This packet has a "way larger". */
 1583                         bzero(replay->bitmap, replay->wsize);
 1584                         (replay->bitmap)[frlast] = 1;
 1585                 }
 1586                 replay->lastseq = seq;
 1587 
 1588                 /* Larger is good. */
 1589         } else {
 1590                 /* seq is equal or less than lastseq. */
 1591                 diff = replay->lastseq - seq;
 1592 
 1593                 /* Over range to check, i.e. too old or wrapped. */
 1594                 if (diff >= wsizeb)
 1595                         return (1);
 1596 
 1597                 fr = frlast - diff / 8;
 1598 
 1599                 /* This packet already seen? */
 1600                 if ((replay->bitmap)[fr] & (1 << (diff % 8)))
 1601                         return (1);
 1602 
 1603                 /* Mark as seen. */
 1604                 (replay->bitmap)[fr] |= (1 << (diff % 8));
 1605 
 1606                 /* Out of order but good. */
 1607         }
 1608 
 1609 ok:
 1610         if (replay->count == ~0) {
 1611 
 1612                 /* Set overflow flag. */
 1613                 replay->overflow++;
 1614 
 1615                 /* Don't increment, no more packets accepted. */
 1616                 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
 1617                         return (1);
 1618 
 1619                 ipseclog((LOG_WARNING, "%s: replay counter made %d cycle. %s\n",
 1620                     __func__, replay->overflow,
 1621                     ipsec_logsastr(sav, buf, sizeof(buf))));
 1622         }
 1623 
 1624         replay->count++;
 1625 
 1626         return (0);
 1627 }
 1628 
 1629 /*
 1630  * Shift variable length buffer to left.
 1631  * IN:  bitmap: pointer to the buffer
 1632  *      nbit:   the number of to shift.
 1633  *      wsize:  buffer size (bytes).
 1634  */
 1635 static void
 1636 vshiftl(unsigned char *bitmap, int nbit, int wsize)
 1637 {
 1638         int s, j, i;
 1639         unsigned char over;
 1640 
 1641         for (j = 0; j < nbit; j += 8) {
 1642                 s = (nbit - j < 8) ? (nbit - j): 8;
 1643                 bitmap[0] <<= s;
 1644                 for (i = 1; i < wsize; i++) {
 1645                         over = (bitmap[i] >> (8 - s));
 1646                         bitmap[i] <<= s;
 1647                         bitmap[i-1] |= over;
 1648                 }
 1649         }
 1650 }
 1651 
 1652 /* Return a printable string for the address. */
 1653 char*
 1654 ipsec_address(union sockaddr_union* sa, char *buf, socklen_t size)
 1655 {
 1656 
 1657         switch (sa->sa.sa_family) {
 1658 #ifdef INET
 1659         case AF_INET:
 1660                 return (inet_ntop(AF_INET, &sa->sin.sin_addr, buf, size));
 1661 #endif /* INET */
 1662 #ifdef INET6
 1663         case AF_INET6:
 1664                 return (inet_ntop(AF_INET6, &sa->sin6.sin6_addr, buf, size));
 1665 #endif /* INET6 */
 1666         default:
 1667                 return ("(unknown address family)");
 1668         }
 1669 }
 1670 
 1671 char *
 1672 ipsec_logsastr(struct secasvar *sav, char *buf, size_t size)
 1673 {
 1674         char sbuf[INET6_ADDRSTRLEN], dbuf[INET6_ADDRSTRLEN];
 1675 
 1676         IPSEC_ASSERT(sav->sah->saidx.src.sa.sa_family ==
 1677             sav->sah->saidx.dst.sa.sa_family, ("address family mismatch"));
 1678 
 1679         snprintf(buf, size, "SA(SPI=%08lx src=%s dst=%s)",
 1680             (u_long)ntohl(sav->spi),
 1681             ipsec_address(&sav->sah->saidx.src, sbuf, sizeof(sbuf)),
 1682             ipsec_address(&sav->sah->saidx.dst, dbuf, sizeof(dbuf)));
 1683         return (buf);
 1684 }
 1685 
 1686 void
 1687 ipsec_dumpmbuf(const struct mbuf *m)
 1688 {
 1689         const u_char *p;
 1690         int totlen;
 1691         int i;
 1692 
 1693         totlen = 0;
 1694         printf("---\n");
 1695         while (m) {
 1696                 p = mtod(m, const u_char *);
 1697                 for (i = 0; i < m->m_len; i++) {
 1698                         printf("%02x ", p[i]);
 1699                         totlen++;
 1700                         if (totlen % 16 == 0)
 1701                                 printf("\n");
 1702                 }
 1703                 m = m->m_next;
 1704         }
 1705         if (totlen % 16 != 0)
 1706                 printf("\n");
 1707         printf("---\n");
 1708 }
 1709 
 1710 static void
 1711 def_policy_init(const void *unused __unused)
 1712 {
 1713 
 1714         bzero(&V_def_policy, sizeof(struct secpolicy));
 1715         V_def_policy.policy = IPSEC_POLICY_NONE;
 1716         V_def_policy.refcnt = 1;
 1717 }
 1718 VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST,
 1719     def_policy_init, NULL);
 1720 
 1721 
 1722 /* XXX This stuff doesn't belong here... */
 1723 
 1724 static  struct xformsw* xforms = NULL;
 1725 
 1726 /*
 1727  * Register a transform; typically at system startup.
 1728  */
 1729 void
 1730 xform_register(struct xformsw* xsp)
 1731 {
 1732 
 1733         xsp->xf_next = xforms;
 1734         xforms = xsp;
 1735 }
 1736 
 1737 /*
 1738  * Initialize transform support in an sav.
 1739  */
 1740 int
 1741 xform_init(struct secasvar *sav, int xftype)
 1742 {
 1743         struct xformsw *xsp;
 1744 
 1745         if (sav->tdb_xform != NULL)     /* Previously initialized. */
 1746                 return (0);
 1747         for (xsp = xforms; xsp; xsp = xsp->xf_next)
 1748                 if (xsp->xf_type == xftype)
 1749                         return ((*xsp->xf_init)(sav, xsp));
 1750         return (EINVAL);
 1751 }

Cache object: 1830626ee04072b2cdbb9cf9928f6f32


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