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/bsd/netinet6/ipsec.c

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

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

Cache object: 734c2a13e4fb9edc342f52025954bd26


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