2  * Copyright (c) 2008-2020 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29 /*      $FreeBSD: src/sys/netinet6/ipsec.c,v 1.3.2.7 2001/07/19 06:37:23 kris Exp $     */ 
  30 /*      $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */ 
  33  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 
  34  * All rights reserved. 
  36  * Redistribution and use in source and binary forms, with or without 
  37  * modification, are permitted provided that the following conditions 
  39  * 1. Redistributions of source code must retain the above copyright 
  40  *    notice, this list of conditions and the following disclaimer. 
  41  * 2. Redistributions in binary form must reproduce the above copyright 
  42  *    notice, this list of conditions and the following disclaimer in the 
  43  *    documentation and/or other materials provided with the distribution. 
  44  * 3. Neither the name of the project nor the names of its contributors 
  45  *    may be used to endorse or promote products derived from this software 
  46  *    without specific prior written permission. 
  48  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 
  49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 
  52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  62  * IPsec controller part. 
  65 #include <sys/param.h> 
  66 #include <sys/systm.h> 
  67 #include <sys/malloc.h> 
  69 #include <sys/mcache.h> 
  70 #include <sys/domain.h> 
  71 #include <sys/protosw.h> 
  72 #include <sys/socket.h> 
  73 #include <sys/socketvar.h> 
  74 #include <sys/errno.h> 
  76 #include <sys/kernel.h> 
  77 #include <sys/syslog.h> 
  78 #include <sys/sysctl.h> 
  80 #include <kern/locks.h> 
  81 #include <sys/kauth.h> 
  82 #include <sys/bitstring.h> 
  84 #include <libkern/OSAtomic.h> 
  85 #include <libkern/sysctl.h> 
  88 #include <net/route.h> 
  89 #include <net/if_ipsec.h> 
  90 #include <net/if_ports_used.h> 
  92 #include <netinet/in.h> 
  93 #include <netinet/in_systm.h> 
  94 #include <netinet/ip.h> 
  95 #include <netinet/ip_var.h> 
  96 #include <netinet/in_var.h> 
  97 #include <netinet/udp.h> 
  98 #include <netinet/udp_var.h> 
  99 #include <netinet/ip_ecn.h> 
 100 #include <netinet6/ip6_ecn.h> 
 101 #include <netinet/tcp.h> 
 102 #include <netinet/udp.h> 
 104 #include <netinet/ip6.h> 
 105 #include <netinet6/ip6_var.h> 
 106 #include <netinet/in_pcb.h> 
 107 #include <netinet/icmp6.h> 
 109 #include <netinet6/ipsec.h> 
 110 #include <netinet6/ipsec6.h> 
 111 #include <netinet6/ah.h> 
 112 #include <netinet6/ah6.h> 
 114 #include <netinet6/esp.h> 
 115 #include <netinet6/esp6.h> 
 117 #include <netkey/key.h> 
 118 #include <netkey/keydb.h> 
 119 #include <netkey/key_debug.h> 
 121 #include <net/net_osdep.h> 
 123 #include <IOKit/pwr_mgt/IOPM.h> 
 125 #include <os/log_private.h> 
 133 #include <sys/kdebug.h> 
 134 #define DBG_LAYER_BEG                   NETDBG_CODE(DBG_NETIPSEC, 1) 
 135 #define DBG_LAYER_END                   NETDBG_CODE(DBG_NETIPSEC, 3) 
 136 #define DBG_FNC_GETPOL_SOCK             NETDBG_CODE(DBG_NETIPSEC, (1 << 8)) 
 137 #define DBG_FNC_GETPOL_ADDR             NETDBG_CODE(DBG_NETIPSEC, (2 << 8)) 
 138 #define DBG_FNC_IPSEC_OUT               NETDBG_CODE(DBG_NETIPSEC, (3 << 8)) 
 140 extern lck_mtx_t 
*sadb_mutex
; 
 142 struct ipsecstat ipsecstat
; 
 143 int ip4_ah_cleartos 
= 1; 
 144 int ip4_ah_offsetmask 
= 0;      /* maybe IP_DF? */ 
 145 int ip4_ipsec_dfbit 
= 0;        /* DF bit on encap. 0: clear 1: set 2: copy */ 
 146 int ip4_esp_trans_deflev 
= IPSEC_LEVEL_USE
; 
 147 int ip4_esp_net_deflev 
= IPSEC_LEVEL_USE
; 
 148 int ip4_ah_trans_deflev 
= IPSEC_LEVEL_USE
; 
 149 int ip4_ah_net_deflev 
= IPSEC_LEVEL_USE
; 
 150 struct secpolicy ip4_def_policy
; 
 151 int ip4_ipsec_ecn 
= ECN_COMPATIBILITY
;          /* ECN ignore(-1)/compatibility(0)/normal(1) */ 
 152 int ip4_esp_randpad 
= -1; 
 153 int     esp_udp_encap_port 
= 0; 
 154 static int sysctl_def_policy SYSCTL_HANDLER_ARGS
; 
 155 extern int natt_keepalive_interval
; 
 156 extern u_int64_t natt_now
; 
 160 void *sleep_wake_handle 
= NULL
; 
 161 bool ipsec_save_wake_pkt 
= false; 
 163 SYSCTL_DECL(_net_inet_ipsec
); 
 164 SYSCTL_DECL(_net_inet6_ipsec6
); 
 166 SYSCTL_STRUCT(_net_inet_ipsec
, IPSECCTL_STATS
, 
 167     stats
, CTLFLAG_RD 
| CTLFLAG_LOCKED
, &ipsecstat
, ipsecstat
, ""); 
 168 SYSCTL_PROC(_net_inet_ipsec
, IPSECCTL_DEF_POLICY
, def_policy
, CTLTYPE_INT 
| CTLFLAG_RW 
| CTLFLAG_LOCKED
, 
 169     &ip4_def_policy
.policy
, 0, &sysctl_def_policy
, "I", ""); 
 170 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
, 
 171     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_esp_trans_deflev
, 0, ""); 
 172 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
, 
 173     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_esp_net_deflev
, 0, ""); 
 174 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
, 
 175     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_ah_trans_deflev
, 0, ""); 
 176 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
, 
 177     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_ah_net_deflev
, 0, ""); 
 178 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_CLEARTOS
, 
 179     ah_cleartos
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_ah_cleartos
, 0, ""); 
 180 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_OFFSETMASK
, 
 181     ah_offsetmask
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_ah_offsetmask
, 0, ""); 
 182 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DFBIT
, 
 183     dfbit
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_ipsec_dfbit
, 0, ""); 
 184 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ECN
, 
 185     ecn
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_ipsec_ecn
, 0, ""); 
 186 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEBUG
, 
 187     debug
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, ""); 
 188 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ESP_RANDPAD
, 
 189     esp_randpad
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip4_esp_randpad
, 0, ""); 
 191 /* for performance, we bypass ipsec until a security policy is set */ 
 192 int ipsec_bypass 
= 1; 
 193 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, bypass
, CTLFLAG_RD 
| CTLFLAG_LOCKED
, &ipsec_bypass
, 0, ""); 
 196  * NAT Traversal requires a UDP port for encapsulation, 
 197  * esp_udp_encap_port controls which port is used. Racoon 
 198  * must set this port to the port racoon is using locally 
 201 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, esp_port
, 
 202     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &esp_udp_encap_port
, 0, ""); 
 204 struct ipsecstat ipsec6stat
; 
 205 int ip6_esp_trans_deflev 
= IPSEC_LEVEL_USE
; 
 206 int ip6_esp_net_deflev 
= IPSEC_LEVEL_USE
; 
 207 int ip6_ah_trans_deflev 
= IPSEC_LEVEL_USE
; 
 208 int ip6_ah_net_deflev 
= IPSEC_LEVEL_USE
; 
 209 struct secpolicy ip6_def_policy
; 
 210 int ip6_ipsec_ecn 
= ECN_COMPATIBILITY
;          /* ECN ignore(-1)/compatibility(0)/normal(1) */ 
 211 int ip6_esp_randpad 
= -1; 
 213 /* net.inet6.ipsec6 */ 
 214 SYSCTL_STRUCT(_net_inet6_ipsec6
, IPSECCTL_STATS
, 
 215     stats
, CTLFLAG_RD 
| CTLFLAG_LOCKED
, &ipsec6stat
, ipsecstat
, ""); 
 216 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_POLICY
, 
 217     def_policy
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_def_policy
.policy
, 0, ""); 
 218 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
, 
 219     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_esp_trans_deflev
, 0, ""); 
 220 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
, 
 221     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_esp_net_deflev
, 0, ""); 
 222 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
, 
 223     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_ah_trans_deflev
, 0, ""); 
 224 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
, 
 225     CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_ah_net_deflev
, 0, ""); 
 226 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ECN
, 
 227     ecn
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_ipsec_ecn
, 0, ""); 
 228 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEBUG
, 
 229     debug
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, ""); 
 230 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ESP_RANDPAD
, 
 231     esp_randpad
, CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_esp_randpad
, 0, ""); 
 233 SYSCTL_DECL(_net_link_generic_system
); 
 235 struct ipsec_wake_pkt_info ipsec_wake_pkt
; 
 237 static int ipsec_setspidx_interface(struct secpolicyindex 
*, u_int8_t
, struct mbuf 
*, 
 239 static int ipsec_setspidx_mbuf(struct secpolicyindex 
*, u_int8_t
, u_int
, 
 241 static int ipsec4_setspidx_inpcb(struct mbuf 
*, struct inpcb 
*pcb
); 
 242 static int ipsec6_setspidx_in6pcb(struct mbuf 
*, struct in6pcb 
*pcb
); 
 243 static int ipsec_setspidx(struct mbuf 
*, struct secpolicyindex 
*, int, int); 
 244 static void ipsec4_get_ulp(struct mbuf 
*m
, struct secpolicyindex 
*, int); 
 245 static int ipsec4_setspidx_ipaddr(struct mbuf 
*, struct secpolicyindex 
*); 
 246 static void ipsec6_get_ulp(struct mbuf 
*m
, struct secpolicyindex 
*, int); 
 247 static int ipsec6_setspidx_ipaddr(struct mbuf 
*, struct secpolicyindex 
*); 
 248 static struct inpcbpolicy 
*ipsec_newpcbpolicy(void); 
 249 static void ipsec_delpcbpolicy(struct inpcbpolicy 
*); 
 250 static struct secpolicy 
*ipsec_deepcopy_policy(struct secpolicy 
*src
); 
 251 static int ipsec_set_policy(struct secpolicy 
**pcb_sp
, 
 252     int optname
, caddr_t request
, size_t len
, int priv
); 
 253 static void vshiftl(unsigned char *, int, size_t); 
 254 static int ipsec_in_reject(struct secpolicy 
*, struct mbuf 
*); 
 255 static int ipsec64_encapsulate(struct mbuf 
*, struct secasvar 
*); 
 256 static int ipsec6_update_routecache_and_output(struct ipsec_output_state 
*state
, struct secasvar 
*sav
); 
 257 static int ipsec46_encapsulate(struct ipsec_output_state 
*state
, struct secasvar 
*sav
); 
 258 static struct ipsec_tag 
*ipsec_addaux(struct mbuf 
*); 
 259 static struct ipsec_tag 
*ipsec_findaux(struct mbuf 
*); 
 260 static void ipsec_optaux(struct mbuf 
*, struct ipsec_tag 
*); 
 261 int ipsec_send_natt_keepalive(struct secasvar 
*sav
); 
 262 bool ipsec_fill_offload_frame(ifnet_t ifp
, struct secasvar 
*sav
, struct ifnet_keepalive_offload_frame 
*frame
, size_t frame_data_offset
); 
 264 extern bool IOPMCopySleepWakeUUIDKey(char *, size_t); 
 266 typedef IOReturn (*IOServiceInterestHandler
)( void * target
, void * refCon
, 
 267     UInt32 messageType
, void * provider
, 
 268     void * messageArgument
, vm_size_t argSize 
); 
 269 extern void *registerSleepWakeInterest(IOServiceInterestHandler
, void *, void *); 
 272 sysctl_def_policy SYSCTL_HANDLER_ARGS
 
 274         int new_policy 
= ip4_def_policy
.policy
; 
 275         int error 
= sysctl_handle_int(oidp
, &new_policy
, 0, req
); 
 277 #pragma unused(arg1, arg2) 
 279                 if (new_policy 
!= IPSEC_POLICY_NONE 
&& 
 280                     new_policy 
!= IPSEC_POLICY_DISCARD
) { 
 283                 ip4_def_policy
.policy 
= new_policy
; 
 285                 /* Turn off the bypass if the default security policy changes */ 
 286                 if (ipsec_bypass 
!= 0 && ip4_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 295  * For OUTBOUND packet having a socket. Searching SPD for packet, 
 296  * and return a pointer to SP. 
 297  * OUT: NULL:   no apropreate SP found, the following value is set to error. 
 299  *              EACCES  : discard packet. 
 300  *              ENOENT  : ipsec_acquire() in progress, maybe. 
 301  *              others  : error occurred. 
 302  *      others: a pointer to SP 
 304  * NOTE: IPv6 mapped adddress concern is implemented here. 
 307 ipsec4_getpolicybysock(struct mbuf 
*m
, 
 312         struct inpcbpolicy 
*pcbsp 
= NULL
; 
 313         struct secpolicy 
*currsp 
= NULL
;        /* policy on socket */ 
 314         struct secpolicy 
*kernsp 
= NULL
;        /* policy on kernel */ 
 316         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
 318         if (m 
== NULL 
|| so 
== NULL 
|| error 
== NULL
) { 
 319                 panic("ipsec4_getpolicybysock: NULL pointer was passed.\n"); 
 322         if (so
->so_pcb 
== NULL
) { 
 323                 printf("ipsec4_getpolicybysock: so->so_pcb == NULL\n"); 
 324                 return ipsec4_getpolicybyaddr(m
, dir
, 0, error
); 
 327         switch (SOCK_DOM(so
)) { 
 329                 pcbsp 
= sotoinpcb(so
)->inp_sp
; 
 332                 pcbsp 
= sotoin6pcb(so
)->in6p_sp
; 
 337                 /* Socket has not specified an IPSEC policy */ 
 338                 return ipsec4_getpolicybyaddr(m
, dir
, 0, error
); 
 341         KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_START
, 0, 0, 0, 0, 0); 
 343         switch (SOCK_DOM(so
)) { 
 345                 /* set spidx in pcb */ 
 346                 *error 
= ipsec4_setspidx_inpcb(m
, sotoinpcb(so
)); 
 349                 /* set spidx in pcb */ 
 350                 *error 
= ipsec6_setspidx_in6pcb(m
, sotoin6pcb(so
)); 
 353                 panic("ipsec4_getpolicybysock: unsupported address family\n"); 
 356                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 1, *error
, 0, 0, 0); 
 362                 panic("ipsec4_getpolicybysock: pcbsp is NULL.\n"); 
 366         case IPSEC_DIR_INBOUND
: 
 367                 currsp 
= pcbsp
->sp_in
; 
 369         case IPSEC_DIR_OUTBOUND
: 
 370                 currsp 
= pcbsp
->sp_out
; 
 373                 panic("ipsec4_getpolicybysock: illegal direction.\n"); 
 377         if (currsp 
== NULL
) { 
 378                 panic("ipsec4_getpolicybysock: currsp is NULL.\n"); 
 381         /* when privilieged socket */ 
 383                 switch (currsp
->policy
) { 
 384                 case IPSEC_POLICY_BYPASS
: 
 385                         lck_mtx_lock(sadb_mutex
); 
 387                         lck_mtx_unlock(sadb_mutex
); 
 389                         KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 2, *error
, 0, 0, 0); 
 392                 case IPSEC_POLICY_ENTRUST
: 
 393                         /* look for a policy in SPD */ 
 394                         kernsp 
= key_allocsp(&currsp
->spidx
, dir
); 
 397                         if (kernsp 
!= NULL
) { 
 398                                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
 399                                     printf("DP ipsec4_getpolicybysock called " 
 400                                     "to allocate SP:0x%llx\n", 
 401                                     (uint64_t)VM_KERNEL_ADDRPERM(kernsp
))); 
 403                                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 3, *error
, 0, 0, 0); 
 408                         lck_mtx_lock(sadb_mutex
); 
 409                         if (ip4_def_policy
.policy 
!= IPSEC_POLICY_DISCARD
 
 410                             && ip4_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 412                                     "fixed system default policy: %d->%d\n", 
 413                                     ip4_def_policy
.policy
, IPSEC_POLICY_NONE
)); 
 414                                 ip4_def_policy
.policy 
= IPSEC_POLICY_NONE
; 
 416                         ip4_def_policy
.refcnt
++; 
 417                         lck_mtx_unlock(sadb_mutex
); 
 419                         KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 4, *error
, 0, 0, 0); 
 420                         return &ip4_def_policy
; 
 422                 case IPSEC_POLICY_IPSEC
: 
 423                         lck_mtx_lock(sadb_mutex
); 
 425                         lck_mtx_unlock(sadb_mutex
); 
 427                         KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 5, *error
, 0, 0, 0); 
 431                         ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: " 
 432                             "Invalid policy for PCB %d\n", currsp
->policy
)); 
 434                         KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 6, *error
, 0, 0, 0); 
 440         /* when non-privilieged socket */ 
 441         /* look for a policy in SPD */ 
 442         kernsp 
= key_allocsp(&currsp
->spidx
, dir
); 
 445         if (kernsp 
!= NULL
) { 
 446                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
 447                     printf("DP ipsec4_getpolicybysock called " 
 448                     "to allocate SP:0x%llx\n", 
 449                     (uint64_t)VM_KERNEL_ADDRPERM(kernsp
))); 
 451                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 7, *error
, 0, 0, 0); 
 456         switch (currsp
->policy
) { 
 457         case IPSEC_POLICY_BYPASS
: 
 458                 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: " 
 459                     "Illegal policy for non-priviliged defined %d\n", 
 462                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 8, *error
, 0, 0, 0); 
 465         case IPSEC_POLICY_ENTRUST
: 
 466                 lck_mtx_lock(sadb_mutex
); 
 467                 if (ip4_def_policy
.policy 
!= IPSEC_POLICY_DISCARD
 
 468                     && ip4_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 470                             "fixed system default policy: %d->%d\n", 
 471                             ip4_def_policy
.policy
, IPSEC_POLICY_NONE
)); 
 472                         ip4_def_policy
.policy 
= IPSEC_POLICY_NONE
; 
 474                 ip4_def_policy
.refcnt
++; 
 475                 lck_mtx_unlock(sadb_mutex
); 
 477                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 9, *error
, 0, 0, 0); 
 478                 return &ip4_def_policy
; 
 480         case IPSEC_POLICY_IPSEC
: 
 481                 lck_mtx_lock(sadb_mutex
); 
 483                 lck_mtx_unlock(sadb_mutex
); 
 485                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 10, *error
, 0, 0, 0); 
 489                 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: " 
 490                     "Invalid policy for PCB %d\n", currsp
->policy
)); 
 492                 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK 
| DBG_FUNC_END
, 11, *error
, 0, 0, 0); 
 499  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet, 
 500  * and return a pointer to SP. 
 501  * OUT: positive: a pointer to the entry for security policy leaf matched. 
 502  *      NULL:   no apropreate SP found, the following value is set to error. 
 504  *              EACCES  : discard packet. 
 505  *              ENOENT  : ipsec_acquire() in progress, maybe. 
 506  *              others  : error occurred. 
 509 ipsec4_getpolicybyaddr(struct mbuf 
*m
, 
 514         struct secpolicy 
*sp 
= NULL
; 
 516         if (ipsec_bypass 
!= 0) { 
 520         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
 523         if (m 
== NULL 
|| error 
== NULL
) { 
 524                 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.\n"); 
 527                 struct secpolicyindex spidx
; 
 529                 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_START
, 0, 0, 0, 0, 0); 
 530                 bzero(&spidx
, sizeof(spidx
)); 
 532                 /* make a index to look for a policy */ 
 533                 *error 
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET
, m
, 
 534                     (flag 
& IP_FORWARDING
) ? 0 : 1); 
 537                         KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 1, *error
, 0, 0, 0); 
 541                 sp 
= key_allocsp(&spidx
, dir
); 
 546                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
 547                     printf("DP ipsec4_getpolicybyaddr called " 
 548                     "to allocate SP:0x%llx\n", 
 549                     (uint64_t)VM_KERNEL_ADDRPERM(sp
))); 
 551                 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 2, *error
, 0, 0, 0); 
 556         lck_mtx_lock(sadb_mutex
); 
 557         if (ip4_def_policy
.policy 
!= IPSEC_POLICY_DISCARD
 
 558             && ip4_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 559                 ipseclog((LOG_INFO
, "fixed system default policy:%d->%d\n", 
 560                     ip4_def_policy
.policy
, 
 562                 ip4_def_policy
.policy 
= IPSEC_POLICY_NONE
; 
 564         ip4_def_policy
.refcnt
++; 
 565         lck_mtx_unlock(sadb_mutex
); 
 567         KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 3, *error
, 0, 0, 0); 
 568         return &ip4_def_policy
; 
 571 /* Match with bound interface rather than src addr. 
 572  * Unlike getpolicybyaddr, do not set the default policy. 
 573  * Return 0 if should continue processing, or -1 if packet 
 577 ipsec4_getpolicybyinterface(struct mbuf 
*m
, 
 580     struct ip_out_args 
*ipoa
, 
 581     struct secpolicy 
**sp
) 
 583         struct secpolicyindex spidx
; 
 586         if (ipsec_bypass 
!= 0) { 
 591         if (m 
== NULL 
|| ipoa 
== NULL 
|| sp 
== NULL
) { 
 592                 panic("ipsec4_getpolicybyinterface: NULL pointer was passed.\n"); 
 595         if (ipoa
->ipoa_boundif 
== IFSCOPE_NONE
) { 
 599         KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_START
, 0, 0, 0, 0, 0); 
 600         bzero(&spidx
, sizeof(spidx
)); 
 602         /* make a index to look for a policy */ 
 603         error 
= ipsec_setspidx_interface(&spidx
, dir
, m
, (*flags 
& IP_FORWARDING
) ? 0 : 1, 
 604             ipoa
->ipoa_boundif
, 4); 
 607                 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 1, error
, 0, 0, 0); 
 611         *sp 
= key_allocsp(&spidx
, dir
); 
 613         /* Return SP, whether NULL or not */ 
 614         if (*sp 
!= NULL 
&& (*sp
)->policy 
== IPSEC_POLICY_IPSEC
) { 
 615                 if ((*sp
)->ipsec_if 
== NULL
) { 
 616                         /* Invalid to capture on an interface without redirect */ 
 617                         key_freesp(*sp
, KEY_SADB_UNLOCKED
); 
 620                 } else if ((*sp
)->disabled
) { 
 621                         /* Disabled policies go in the clear */ 
 622                         key_freesp(*sp
, KEY_SADB_UNLOCKED
); 
 624                         *flags 
|= IP_NOIPSEC
; /* Avoid later IPsec check */ 
 626                         /* If policy is enabled, redirect to ipsec interface */ 
 627                         ipoa
->ipoa_boundif 
= (*sp
)->ipsec_if
->if_index
; 
 631         KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 2, error
, 0, 0, 0); 
 638  * For OUTBOUND packet having a socket. Searching SPD for packet, 
 639  * and return a pointer to SP. 
 640  * OUT: NULL:   no apropreate SP found, the following value is set to error. 
 642  *              EACCES  : discard packet. 
 643  *              ENOENT  : ipsec_acquire() in progress, maybe. 
 644  *              others  : error occurred. 
 645  *      others: a pointer to SP 
 648 ipsec6_getpolicybysock(struct mbuf 
*m
, 
 653         struct inpcbpolicy 
*pcbsp 
= NULL
; 
 654         struct secpolicy 
*currsp 
= NULL
;        /* policy on socket */ 
 655         struct secpolicy 
*kernsp 
= NULL
;        /* policy on kernel */ 
 657         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
 660         if (m 
== NULL 
|| so 
== NULL 
|| error 
== NULL
) { 
 661                 panic("ipsec6_getpolicybysock: NULL pointer was passed.\n"); 
 665         if (SOCK_DOM(so
) != PF_INET6
) { 
 666                 panic("ipsec6_getpolicybysock: socket domain != inet6\n"); 
 670         pcbsp 
= sotoin6pcb(so
)->in6p_sp
; 
 673                 return ipsec6_getpolicybyaddr(m
, dir
, 0, error
); 
 676         /* set spidx in pcb */ 
 677         ipsec6_setspidx_in6pcb(m
, sotoin6pcb(so
)); 
 681                 panic("ipsec6_getpolicybysock: pcbsp is NULL.\n"); 
 685         case IPSEC_DIR_INBOUND
: 
 686                 currsp 
= pcbsp
->sp_in
; 
 688         case IPSEC_DIR_OUTBOUND
: 
 689                 currsp 
= pcbsp
->sp_out
; 
 692                 panic("ipsec6_getpolicybysock: illegal direction.\n"); 
 696         if (currsp 
== NULL
) { 
 697                 panic("ipsec6_getpolicybysock: currsp is NULL.\n"); 
 700         /* when privilieged socket */ 
 702                 switch (currsp
->policy
) { 
 703                 case IPSEC_POLICY_BYPASS
: 
 704                         lck_mtx_lock(sadb_mutex
); 
 706                         lck_mtx_unlock(sadb_mutex
); 
 710                 case IPSEC_POLICY_ENTRUST
: 
 711                         /* look for a policy in SPD */ 
 712                         kernsp 
= key_allocsp(&currsp
->spidx
, dir
); 
 715                         if (kernsp 
!= NULL
) { 
 716                                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
 717                                     printf("DP ipsec6_getpolicybysock called " 
 718                                     "to allocate SP:0x%llx\n", 
 719                                     (uint64_t)VM_KERNEL_ADDRPERM(kernsp
))); 
 725                         lck_mtx_lock(sadb_mutex
); 
 726                         if (ip6_def_policy
.policy 
!= IPSEC_POLICY_DISCARD
 
 727                             && ip6_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 729                                     "fixed system default policy: %d->%d\n", 
 730                                     ip6_def_policy
.policy
, IPSEC_POLICY_NONE
)); 
 731                                 ip6_def_policy
.policy 
= IPSEC_POLICY_NONE
; 
 733                         ip6_def_policy
.refcnt
++; 
 734                         lck_mtx_unlock(sadb_mutex
); 
 736                         return &ip6_def_policy
; 
 738                 case IPSEC_POLICY_IPSEC
: 
 739                         lck_mtx_lock(sadb_mutex
); 
 741                         lck_mtx_unlock(sadb_mutex
); 
 746                         ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: " 
 747                             "Invalid policy for PCB %d\n", currsp
->policy
)); 
 754         /* when non-privilieged socket */ 
 755         /* look for a policy in SPD */ 
 756         kernsp 
= key_allocsp(&currsp
->spidx
, dir
); 
 759         if (kernsp 
!= NULL
) { 
 760                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
 761                     printf("DP ipsec6_getpolicybysock called " 
 762                     "to allocate SP:0x%llx\n", 
 763                     (uint64_t)VM_KERNEL_ADDRPERM(kernsp
))); 
 769         switch (currsp
->policy
) { 
 770         case IPSEC_POLICY_BYPASS
: 
 771                 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: " 
 772                     "Illegal policy for non-priviliged defined %d\n", 
 777         case IPSEC_POLICY_ENTRUST
: 
 778                 lck_mtx_lock(sadb_mutex
); 
 779                 if (ip6_def_policy
.policy 
!= IPSEC_POLICY_DISCARD
 
 780                     && ip6_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 782                             "fixed system default policy: %d->%d\n", 
 783                             ip6_def_policy
.policy
, IPSEC_POLICY_NONE
)); 
 784                         ip6_def_policy
.policy 
= IPSEC_POLICY_NONE
; 
 786                 ip6_def_policy
.refcnt
++; 
 787                 lck_mtx_unlock(sadb_mutex
); 
 789                 return &ip6_def_policy
; 
 791         case IPSEC_POLICY_IPSEC
: 
 792                 lck_mtx_lock(sadb_mutex
); 
 794                 lck_mtx_unlock(sadb_mutex
); 
 800                     "ipsec6_policybysock: Invalid policy for PCB %d\n", 
 809  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet, 
 810  * and return a pointer to SP. 
 811  * `flag' means that packet is to be forwarded whether or not. 
 813  * OUT: positive: a pointer to the entry for security policy leaf matched. 
 814  *      NULL:   no apropreate SP found, the following value is set to error. 
 816  *              EACCES  : discard packet. 
 817  *              ENOENT  : ipsec_acquire() in progress, maybe. 
 818  *              others  : error occurred. 
 820 #ifndef IP_FORWARDING 
 821 #define IP_FORWARDING 1 
 825 ipsec6_getpolicybyaddr(struct mbuf 
*m
, 
 830         struct secpolicy 
*sp 
= NULL
; 
 832         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
 835         if (m 
== NULL 
|| error 
== NULL
) { 
 836                 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.\n"); 
 840                 struct secpolicyindex spidx
; 
 842                 bzero(&spidx
, sizeof(spidx
)); 
 844                 /* make a index to look for a policy */ 
 845                 *error 
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET6
, m
, 
 846                     (flag 
& IP_FORWARDING
) ? 0 : 1); 
 852                 sp 
= key_allocsp(&spidx
, dir
); 
 857                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
 858                     printf("DP ipsec6_getpolicybyaddr called " 
 859                     "to allocate SP:0x%llx\n", 
 860                     (uint64_t)VM_KERNEL_ADDRPERM(sp
))); 
 866         lck_mtx_lock(sadb_mutex
); 
 867         if (ip6_def_policy
.policy 
!= IPSEC_POLICY_DISCARD
 
 868             && ip6_def_policy
.policy 
!= IPSEC_POLICY_NONE
) { 
 869                 ipseclog((LOG_INFO
, "fixed system default policy: %d->%d\n", 
 870                     ip6_def_policy
.policy
, IPSEC_POLICY_NONE
)); 
 871                 ip6_def_policy
.policy 
= IPSEC_POLICY_NONE
; 
 873         ip6_def_policy
.refcnt
++; 
 874         lck_mtx_unlock(sadb_mutex
); 
 876         return &ip6_def_policy
; 
 879 /* Match with bound interface rather than src addr. 
 880  * Unlike getpolicybyaddr, do not set the default policy. 
 881  * Return 0 if should continue processing, or -1 if packet 
 885 ipsec6_getpolicybyinterface(struct mbuf 
*m
, 
 888     struct ip6_out_args 
*ip6oap
, 
 890     struct secpolicy 
**sp
) 
 892         struct secpolicyindex spidx
; 
 895         if (ipsec_bypass 
!= 0) { 
 900         if (m 
== NULL 
|| sp 
== NULL 
|| noipsec 
== NULL 
|| ip6oap 
== NULL
) { 
 901                 panic("ipsec6_getpolicybyinterface: NULL pointer was passed.\n"); 
 906         if (ip6oap
->ip6oa_boundif 
== IFSCOPE_NONE
) { 
 910         KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_START
, 0, 0, 0, 0, 0); 
 911         bzero(&spidx
, sizeof(spidx
)); 
 913         /* make a index to look for a policy */ 
 914         error 
= ipsec_setspidx_interface(&spidx
, dir
, m
, (flag 
& IP_FORWARDING
) ? 0 : 1, 
 915             ip6oap
->ip6oa_boundif
, 6); 
 918                 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 1, error
, 0, 0, 0); 
 922         *sp 
= key_allocsp(&spidx
, dir
); 
 924         /* Return SP, whether NULL or not */ 
 925         if (*sp 
!= NULL 
&& (*sp
)->policy 
== IPSEC_POLICY_IPSEC
) { 
 926                 if ((*sp
)->ipsec_if 
== NULL
) { 
 927                         /* Invalid to capture on an interface without redirect */ 
 928                         key_freesp(*sp
, KEY_SADB_UNLOCKED
); 
 931                 } else if ((*sp
)->disabled
) { 
 932                         /* Disabled policies go in the clear */ 
 933                         key_freesp(*sp
, KEY_SADB_UNLOCKED
); 
 935                         *noipsec 
= 1; /* Avoid later IPsec check */ 
 937                         /* If policy is enabled, redirect to ipsec interface */ 
 938                         ip6oap
->ip6oa_boundif 
= (*sp
)->ipsec_if
->if_index
; 
 942         KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR 
| DBG_FUNC_END
, 2, *error
, 0, 0, 0); 
 948  * set IP address into spidx from mbuf. 
 949  * When Forwarding packet and ICMP echo reply, this function is used. 
 951  * IN:  get the followings from mbuf. 
 952  *      protocol family, src, dst, next protocol 
 955  *      other:  failure, and set errno. 
 959         struct secpolicyindex 
*spidx
, 
 961         __unused u_int family
, 
 968         if (spidx 
== NULL 
|| m 
== NULL
) { 
 969                 panic("ipsec_setspidx_mbuf: NULL pointer was passed.\n"); 
 972         bzero(spidx
, sizeof(*spidx
)); 
 974         error 
= ipsec_setspidx(m
, spidx
, needport
, 0); 
 984         bzero(spidx
, sizeof(*spidx
)); 
 989 ipsec_setspidx_interface( 
 990         struct secpolicyindex 
*spidx
, 
1000         if (spidx 
== NULL 
|| m 
== NULL
) { 
1001                 panic("ipsec_setspidx_interface: NULL pointer was passed.\n"); 
1004         bzero(spidx
, sizeof(*spidx
)); 
1006         error 
= ipsec_setspidx(m
, spidx
, needport
, ip_version
); 
1013                 ifnet_head_lock_shared(); 
1014                 spidx
->internal_if 
= ifindex2ifnet
[ifindex
]; 
1017                 spidx
->internal_if 
= NULL
; 
1027 ipsec4_setspidx_inpcb(struct mbuf 
*m
, struct inpcb 
*pcb
) 
1029         struct secpolicyindex 
*spidx
; 
1032         if (ipsec_bypass 
!= 0) { 
1038                 panic("ipsec4_setspidx_inpcb: no PCB found.\n"); 
1040         if (pcb
->inp_sp 
== NULL
) { 
1041                 panic("ipsec4_setspidx_inpcb: no inp_sp found.\n"); 
1043         if (pcb
->inp_sp
->sp_out 
== NULL 
|| pcb
->inp_sp
->sp_in 
== NULL
) { 
1044                 panic("ipsec4_setspidx_inpcb: no sp_in/out found.\n"); 
1047         bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
)); 
1048         bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
)); 
1050         spidx 
= &pcb
->inp_sp
->sp_in
->spidx
; 
1051         error 
= ipsec_setspidx(m
, spidx
, 1, 0); 
1055         spidx
->dir 
= IPSEC_DIR_INBOUND
; 
1057         spidx 
= &pcb
->inp_sp
->sp_out
->spidx
; 
1058         error 
= ipsec_setspidx(m
, spidx
, 1, 0); 
1062         spidx
->dir 
= IPSEC_DIR_OUTBOUND
; 
1067         bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
)); 
1068         bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
)); 
1073 ipsec6_setspidx_in6pcb(struct mbuf 
*m
, struct in6pcb 
*pcb
) 
1075         struct secpolicyindex 
*spidx
; 
1080                 panic("ipsec6_setspidx_in6pcb: no PCB found.\n"); 
1082         if (pcb
->in6p_sp 
== NULL
) { 
1083                 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.\n"); 
1085         if (pcb
->in6p_sp
->sp_out 
== NULL 
|| pcb
->in6p_sp
->sp_in 
== NULL
) { 
1086                 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.\n"); 
1089         bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
)); 
1090         bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
)); 
1092         spidx 
= &pcb
->in6p_sp
->sp_in
->spidx
; 
1093         error 
= ipsec_setspidx(m
, spidx
, 1, 0); 
1097         spidx
->dir 
= IPSEC_DIR_INBOUND
; 
1099         spidx 
= &pcb
->in6p_sp
->sp_out
->spidx
; 
1100         error 
= ipsec_setspidx(m
, spidx
, 1, 0); 
1104         spidx
->dir 
= IPSEC_DIR_OUTBOUND
; 
1109         bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
)); 
1110         bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
)); 
1115  * configure security policy index (src/dst/proto/sport/dport) 
1116  * by looking at the content of mbuf. 
1117  * the caller is responsible for error recovery (like clearing up spidx). 
1120 ipsec_setspidx(struct mbuf 
*m
, 
1121     struct secpolicyindex 
*spidx
, 
1123     int force_ip_version
) 
1125         struct ip 
*ip 
= NULL
; 
1133                 panic("ipsec_setspidx: m == 0 passed.\n"); 
1137          * validate m->m_pkthdr.len.  we see incorrect length if we 
1138          * mistakenly call this function with inconsistent mbuf chain 
1139          * (like 4.4BSD tcp/udp processing).  XXX should we panic here? 
1142         for (n 
= m
; n
; n 
= n
->m_next
) { 
1145         if (m
->m_pkthdr
.len 
!= len
) { 
1146                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1147                     printf("ipsec_setspidx: " 
1148                     "total of m_len(%d) != pkthdr.len(%d), " 
1150                     len
, m
->m_pkthdr
.len
)); 
1154         if (m
->m_pkthdr
.len 
< sizeof(struct ip
)) { 
1155                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1156                     printf("ipsec_setspidx: " 
1157                     "pkthdr.len(%d) < sizeof(struct ip), ignored.\n", 
1162         if (m
->m_len 
>= sizeof(*ip
)) { 
1163                 ip 
= mtod(m
, struct ip 
*); 
1165                 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
); 
1169         if (force_ip_version
) { 
1170                 v 
= force_ip_version
; 
1173                 v 
= _IP_VHL_V(ip
->ip_vhl
); 
1180                 error 
= ipsec4_setspidx_ipaddr(m
, spidx
); 
1184                 ipsec4_get_ulp(m
, spidx
, needport
); 
1187                 if (m
->m_pkthdr
.len 
< sizeof(struct ip6_hdr
)) { 
1188                         KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1189                             printf("ipsec_setspidx: " 
1190                             "pkthdr.len(%d) < sizeof(struct ip6_hdr), " 
1191                             "ignored.\n", m
->m_pkthdr
.len
)); 
1194                 error 
= ipsec6_setspidx_ipaddr(m
, spidx
); 
1198                 ipsec6_get_ulp(m
, spidx
, needport
); 
1201                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1202                     printf("ipsec_setspidx: " 
1203                     "unknown IP version %u, ignored.\n", v
)); 
1209 ipsec4_get_ulp(struct mbuf 
*m
, struct secpolicyindex 
*spidx
, int needport
) 
1212         struct ip6_ext ip6e
; 
1220                 panic("ipsec4_get_ulp: NULL pointer was passed.\n"); 
1222         if (m
->m_pkthdr
.len 
< sizeof(ip
)) { 
1223                 panic("ipsec4_get_ulp: too short\n"); 
1227         spidx
->ul_proto 
= IPSEC_ULPROTO_ANY
; 
1228         ((struct sockaddr_in 
*)&spidx
->src
)->sin_port 
= IPSEC_PORT_ANY
; 
1229         ((struct sockaddr_in 
*)&spidx
->dst
)->sin_port 
= IPSEC_PORT_ANY
; 
1231         m_copydata(m
, 0, sizeof(ip
), (caddr_t
)&ip
); 
1232         /* ip_input() flips it into host endian XXX need more checking */ 
1233         if (ip
.ip_off 
& (IP_MF 
| IP_OFFMASK
)) { 
1239         off 
= _IP_VHL_HL(ip
->ip_vhl
) << 2; 
1241         off 
= ip
.ip_hl 
<< 2; 
1243         while (off 
< m
->m_pkthdr
.len
) { 
1246                         spidx
->ul_proto 
= nxt
; 
1250                         if (off 
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
) { 
1253                         m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
); 
1254                         ((struct sockaddr_in 
*)&spidx
->src
)->sin_port 
= 
1256                         ((struct sockaddr_in 
*)&spidx
->dst
)->sin_port 
= 
1260                         spidx
->ul_proto 
= nxt
; 
1264                         if (off 
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
) { 
1267                         m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
); 
1268                         ((struct sockaddr_in 
*)&spidx
->src
)->sin_port 
= 
1270                         ((struct sockaddr_in 
*)&spidx
->dst
)->sin_port 
= 
1274                         if (off 
+ sizeof(ip6e
) > m
->m_pkthdr
.len
) { 
1277                         m_copydata(m
, off
, sizeof(ip6e
), (caddr_t
)&ip6e
); 
1278                         off 
+= (ip6e
.ip6e_len 
+ 2) << 2; 
1279                         nxt 
= ip6e
.ip6e_nxt
; 
1283                         /* XXX intermediate headers??? */ 
1284                         spidx
->ul_proto 
= nxt
; 
1290 /* assumes that m is sane */ 
1292 ipsec4_setspidx_ipaddr(struct mbuf 
*m
, struct secpolicyindex 
*spidx
) 
1294         struct ip 
*ip 
= NULL
; 
1296         struct sockaddr_in 
*sin
; 
1298         if (m
->m_len 
>= sizeof(*ip
)) { 
1299                 ip 
= mtod(m
, struct ip 
*); 
1301                 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
); 
1305         sin 
= (struct sockaddr_in 
*)&spidx
->src
; 
1306         bzero(sin
, sizeof(*sin
)); 
1307         sin
->sin_family 
= AF_INET
; 
1308         sin
->sin_len 
= sizeof(struct sockaddr_in
); 
1309         bcopy(&ip
->ip_src
, &sin
->sin_addr
, sizeof(ip
->ip_src
)); 
1310         spidx
->prefs 
= sizeof(struct in_addr
) << 3; 
1312         sin 
= (struct sockaddr_in 
*)&spidx
->dst
; 
1313         bzero(sin
, sizeof(*sin
)); 
1314         sin
->sin_family 
= AF_INET
; 
1315         sin
->sin_len 
= sizeof(struct sockaddr_in
); 
1316         bcopy(&ip
->ip_dst
, &sin
->sin_addr
, sizeof(ip
->ip_dst
)); 
1317         spidx
->prefd 
= sizeof(struct in_addr
) << 3; 
1323 ipsec6_get_ulp(struct mbuf 
*m
, 
1324     struct secpolicyindex 
*spidx
, 
1333                 panic("ipsec6_get_ulp: NULL pointer was passed.\n"); 
1336         KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1337             printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m
)); 
1340         spidx
->ul_proto 
= IPSEC_ULPROTO_ANY
; 
1341         ((struct sockaddr_in6 
*)&spidx
->src
)->sin6_port 
= IPSEC_PORT_ANY
; 
1342         ((struct sockaddr_in6 
*)&spidx
->dst
)->sin6_port 
= IPSEC_PORT_ANY
; 
1345         off 
= ip6_lasthdr(m
, 0, IPPROTO_IPV6
, &nxt
); 
1346         if (off 
< 0 || m
->m_pkthdr
.len 
< off
) { 
1350         VERIFY(nxt 
<= UINT8_MAX
); 
1353                 spidx
->ul_proto 
= (u_int8_t
)nxt
; 
1357                 if (off 
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
) { 
1360                 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
); 
1361                 ((struct sockaddr_in6 
*)&spidx
->src
)->sin6_port 
= th
.th_sport
; 
1362                 ((struct sockaddr_in6 
*)&spidx
->dst
)->sin6_port 
= th
.th_dport
; 
1365                 spidx
->ul_proto 
= (u_int8_t
)nxt
; 
1369                 if (off 
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
) { 
1372                 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
); 
1373                 ((struct sockaddr_in6 
*)&spidx
->src
)->sin6_port 
= uh
.uh_sport
; 
1374                 ((struct sockaddr_in6 
*)&spidx
->dst
)->sin6_port 
= uh
.uh_dport
; 
1376         case IPPROTO_ICMPV6
: 
1378                 /* XXX intermediate headers??? */ 
1379                 spidx
->ul_proto 
= (u_int8_t
)nxt
; 
1384 /* assumes that m is sane */ 
1386 ipsec6_setspidx_ipaddr(struct mbuf 
*m
, 
1387     struct secpolicyindex 
*spidx
) 
1389         struct ip6_hdr 
*ip6 
= NULL
; 
1390         struct ip6_hdr ip6buf
; 
1391         struct sockaddr_in6 
*sin6
; 
1393         if (m
->m_len 
>= sizeof(*ip6
)) { 
1394                 ip6 
= mtod(m
, struct ip6_hdr 
*); 
1396                 m_copydata(m
, 0, sizeof(ip6buf
), (caddr_t
)&ip6buf
); 
1400         sin6 
= (struct sockaddr_in6 
*)&spidx
->src
; 
1401         bzero(sin6
, sizeof(*sin6
)); 
1402         sin6
->sin6_family 
= AF_INET6
; 
1403         sin6
->sin6_len 
= sizeof(struct sockaddr_in6
); 
1404         bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_src
)); 
1405         if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) { 
1406                 sin6
->sin6_addr
.s6_addr16
[1] = 0; 
1407                 sin6
->sin6_scope_id 
= ntohs(ip6
->ip6_src
.s6_addr16
[1]); 
1409         spidx
->prefs 
= sizeof(struct in6_addr
) << 3; 
1411         sin6 
= (struct sockaddr_in6 
*)&spidx
->dst
; 
1412         bzero(sin6
, sizeof(*sin6
)); 
1413         sin6
->sin6_family 
= AF_INET6
; 
1414         sin6
->sin6_len 
= sizeof(struct sockaddr_in6
); 
1415         bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_dst
)); 
1416         if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) { 
1417                 sin6
->sin6_addr
.s6_addr16
[1] = 0; 
1418                 sin6
->sin6_scope_id 
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]); 
1420         spidx
->prefd 
= sizeof(struct in6_addr
) << 3; 
1425 static struct inpcbpolicy 
* 
1426 ipsec_newpcbpolicy(void) 
1428         struct inpcbpolicy 
*p
; 
1430         p 
= (struct inpcbpolicy 
*)_MALLOC(sizeof(*p
), M_SECA
, M_WAITOK
); 
1435 ipsec_delpcbpolicy(struct inpcbpolicy 
*p
) 
1440 /* initialize policy in PCB */ 
1442 ipsec_init_policy(struct socket 
*so
, 
1443     struct inpcbpolicy 
**pcb_sp
) 
1445         struct inpcbpolicy 
*new; 
1448         if (so 
== NULL 
|| pcb_sp 
== NULL
) { 
1449                 panic("ipsec_init_policy: NULL pointer was passed.\n"); 
1452         new = ipsec_newpcbpolicy(); 
1454                 ipseclog((LOG_DEBUG
, "ipsec_init_policy: No more memory.\n")); 
1457         bzero(new, sizeof(*new)); 
1460         if (kauth_cred_issuser(so
->so_cred
)) 
1462         if (so
->so_cred 
!= 0 && !suser(so
->so_cred
->pc_ucred
, NULL
)) 
1464         { new->priv 
= 1;} else { 
1468         if ((new->sp_in 
= key_newsp()) == NULL
) { 
1469                 ipsec_delpcbpolicy(new); 
1472         new->sp_in
->state 
= IPSEC_SPSTATE_ALIVE
; 
1473         new->sp_in
->policy 
= IPSEC_POLICY_ENTRUST
; 
1475         if ((new->sp_out 
= key_newsp()) == NULL
) { 
1476                 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
); 
1477                 ipsec_delpcbpolicy(new); 
1480         new->sp_out
->state 
= IPSEC_SPSTATE_ALIVE
; 
1481         new->sp_out
->policy 
= IPSEC_POLICY_ENTRUST
; 
1488 /* copy old ipsec policy into new */ 
1490 ipsec_copy_policy(struct inpcbpolicy 
*old
, 
1491     struct inpcbpolicy 
*new) 
1493         struct secpolicy 
*sp
; 
1495         if (ipsec_bypass 
!= 0) { 
1499         sp 
= ipsec_deepcopy_policy(old
->sp_in
); 
1501                 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
); 
1507         sp 
= ipsec_deepcopy_policy(old
->sp_out
); 
1509                 key_freesp(new->sp_out
, KEY_SADB_UNLOCKED
); 
1515         new->priv 
= old
->priv
; 
1520 /* deep-copy a policy in PCB */ 
1521 static struct secpolicy 
* 
1522 ipsec_deepcopy_policy(struct secpolicy 
*src
) 
1524         struct ipsecrequest 
*newchain 
= NULL
; 
1525         struct ipsecrequest 
*p
; 
1526         struct ipsecrequest 
**q
; 
1527         struct ipsecrequest 
*r
; 
1528         struct secpolicy 
*dst
; 
1539          * deep-copy IPsec request chain.  This is required since struct 
1540          * ipsecrequest is not reference counted. 
1543         for (p 
= src
->req
; p
; p 
= p
->next
) { 
1544                 *q 
= (struct ipsecrequest 
*)_MALLOC(sizeof(struct ipsecrequest
), 
1545                     M_SECA
, M_WAITOK 
| M_ZERO
); 
1551                 (*q
)->saidx
.proto 
= p
->saidx
.proto
; 
1552                 (*q
)->saidx
.mode 
= p
->saidx
.mode
; 
1553                 (*q
)->level 
= p
->level
; 
1554                 (*q
)->saidx
.reqid 
= p
->saidx
.reqid
; 
1556                 bcopy(&p
->saidx
.src
, &(*q
)->saidx
.src
, sizeof((*q
)->saidx
.src
)); 
1557                 bcopy(&p
->saidx
.dst
, &(*q
)->saidx
.dst
, sizeof((*q
)->saidx
.dst
)); 
1564         dst
->req 
= newchain
; 
1565         dst
->state 
= src
->state
; 
1566         dst
->policy 
= src
->policy
; 
1567         /* do not touch the refcnt fields */ 
1572         for (p 
= newchain
; p
; p 
= r
) { 
1577         key_freesp(dst
, KEY_SADB_UNLOCKED
); 
1581 /* set policy and ipsec request if present. */ 
1583 ipsec_set_policy(struct secpolicy 
**pcb_sp
, 
1584     __unused 
int optname
, 
1589         struct sadb_x_policy 
*xpl
; 
1590         struct secpolicy 
*newsp 
= NULL
; 
1594         if (pcb_sp 
== NULL 
|| *pcb_sp 
== NULL 
|| request 
== NULL
) { 
1597         if (len 
< sizeof(*xpl
)) { 
1600         xpl 
= (struct sadb_x_policy 
*)(void *)request
; 
1602         KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1603             printf("ipsec_set_policy: passed policy\n"); 
1604             kdebug_sadb_x_policy((struct sadb_ext 
*)xpl
)); 
1606         /* check policy type */ 
1607         /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */ 
1608         if (xpl
->sadb_x_policy_type 
== IPSEC_POLICY_DISCARD
 
1609             || xpl
->sadb_x_policy_type 
== IPSEC_POLICY_NONE
) { 
1613         /* check privileged socket */ 
1614         if (priv 
== 0 && xpl
->sadb_x_policy_type 
== IPSEC_POLICY_BYPASS
) { 
1618         /* allocation new SP entry */ 
1619         if ((newsp 
= key_msg2sp(xpl
, len
, &error
)) == NULL
) { 
1623         newsp
->state 
= IPSEC_SPSTATE_ALIVE
; 
1625         /* clear old SP and set new SP */ 
1626         key_freesp(*pcb_sp
, KEY_SADB_UNLOCKED
); 
1628         KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1629             printf("ipsec_set_policy: new policy\n"); 
1630             kdebug_secpolicy(newsp
)); 
1636 ipsec4_set_policy(struct inpcb 
*inp
, 
1642         struct sadb_x_policy 
*xpl
; 
1643         struct secpolicy 
**pcb_sp
; 
1645         struct sadb_x_policy xpl_aligned_buf
; 
1646         u_int8_t             
*xpl_unaligned
; 
1649         if (inp 
== NULL 
|| request 
== NULL
) { 
1652         if (len 
< sizeof(*xpl
)) { 
1655         xpl 
= (struct sadb_x_policy 
*)(void *)request
; 
1657         /* This is a new mbuf allocated by soopt_getm() */ 
1658         if (IPSEC_IS_P2ALIGNED(xpl
)) { 
1659                 xpl_unaligned 
= NULL
; 
1661                 xpl_unaligned 
= (__typeof__(xpl_unaligned
))xpl
; 
1662                 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
)); 
1663                 xpl 
= (__typeof__(xpl
)) & xpl_aligned_buf
; 
1666         if (inp
->inp_sp 
== NULL
) { 
1667                 error 
= ipsec_init_policy(inp
->inp_socket
, &inp
->inp_sp
); 
1673         /* select direction */ 
1674         switch (xpl
->sadb_x_policy_dir
) { 
1675         case IPSEC_DIR_INBOUND
: 
1676                 pcb_sp 
= &inp
->inp_sp
->sp_in
; 
1678         case IPSEC_DIR_OUTBOUND
: 
1679                 pcb_sp 
= &inp
->inp_sp
->sp_out
; 
1682                 ipseclog((LOG_ERR
, "ipsec4_set_policy: invalid direction=%u\n", 
1683                     xpl
->sadb_x_policy_dir
)); 
1687         /* turn bypass off */ 
1688         if (ipsec_bypass 
!= 0) { 
1692         return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
); 
1695 /* delete policy in PCB */ 
1697 ipsec4_delete_pcbpolicy(struct inpcb 
*inp
) 
1701                 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n"); 
1704         if (inp
->inp_sp 
== NULL
) { 
1708         if (inp
->inp_sp
->sp_in 
!= NULL
) { 
1709                 key_freesp(inp
->inp_sp
->sp_in
, KEY_SADB_UNLOCKED
); 
1710                 inp
->inp_sp
->sp_in 
= NULL
; 
1713         if (inp
->inp_sp
->sp_out 
!= NULL
) { 
1714                 key_freesp(inp
->inp_sp
->sp_out
, KEY_SADB_UNLOCKED
); 
1715                 inp
->inp_sp
->sp_out 
= NULL
; 
1718         ipsec_delpcbpolicy(inp
->inp_sp
); 
1725 ipsec6_set_policy(struct in6pcb 
*in6p
, 
1731         struct sadb_x_policy 
*xpl
; 
1732         struct secpolicy 
**pcb_sp
; 
1734         struct sadb_x_policy xpl_aligned_buf
; 
1735         u_int8_t 
*xpl_unaligned
; 
1738         if (in6p 
== NULL 
|| request 
== NULL
) { 
1741         if (len 
< sizeof(*xpl
)) { 
1744         xpl 
= (struct sadb_x_policy 
*)(void *)request
; 
1746         /* This is a new mbuf allocated by soopt_getm() */ 
1747         if (IPSEC_IS_P2ALIGNED(xpl
)) { 
1748                 xpl_unaligned 
= NULL
; 
1750                 xpl_unaligned 
= (__typeof__(xpl_unaligned
))xpl
; 
1751                 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
)); 
1752                 xpl 
= (__typeof__(xpl
)) & xpl_aligned_buf
; 
1755         if (in6p
->in6p_sp 
== NULL
) { 
1756                 error 
= ipsec_init_policy(in6p
->inp_socket
, &in6p
->in6p_sp
); 
1762         /* select direction */ 
1763         switch (xpl
->sadb_x_policy_dir
) { 
1764         case IPSEC_DIR_INBOUND
: 
1765                 pcb_sp 
= &in6p
->in6p_sp
->sp_in
; 
1767         case IPSEC_DIR_OUTBOUND
: 
1768                 pcb_sp 
= &in6p
->in6p_sp
->sp_out
; 
1771                 ipseclog((LOG_ERR
, "ipsec6_set_policy: invalid direction=%u\n", 
1772                     xpl
->sadb_x_policy_dir
)); 
1776         return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
); 
1780 ipsec6_delete_pcbpolicy(struct in6pcb 
*in6p
) 
1784                 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n"); 
1787         if (in6p
->in6p_sp 
== NULL
) { 
1791         if (in6p
->in6p_sp
->sp_in 
!= NULL
) { 
1792                 key_freesp(in6p
->in6p_sp
->sp_in
, KEY_SADB_UNLOCKED
); 
1793                 in6p
->in6p_sp
->sp_in 
= NULL
; 
1796         if (in6p
->in6p_sp
->sp_out 
!= NULL
) { 
1797                 key_freesp(in6p
->in6p_sp
->sp_out
, KEY_SADB_UNLOCKED
); 
1798                 in6p
->in6p_sp
->sp_out 
= NULL
; 
1801         ipsec_delpcbpolicy(in6p
->in6p_sp
); 
1802         in6p
->in6p_sp 
= NULL
; 
1808  * return current level. 
1809  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned. 
1812 ipsec_get_reqlevel(struct ipsecrequest 
*isr
) 
1815         u_int esp_trans_deflev 
= 0, esp_net_deflev 
= 0, ah_trans_deflev 
= 0, ah_net_deflev 
= 0; 
1818         if (isr 
== NULL 
|| isr
->sp 
== NULL
) { 
1819                 panic("ipsec_get_reqlevel: NULL pointer is passed.\n"); 
1821         if (((struct sockaddr 
*)&isr
->sp
->spidx
.src
)->sa_family
 
1822             != ((struct sockaddr 
*)&isr
->sp
->spidx
.dst
)->sa_family
) { 
1823                 panic("ipsec_get_reqlevel: family mismatched.\n"); 
1826 /* XXX note that we have ipseclog() expanded here - code sync issue */ 
1827 #define IPSEC_CHECK_DEFAULT(lev) \ 
1828         (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE            \ 
1829                         && (lev) != IPSEC_LEVEL_UNIQUE)                       \ 
1831                         ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\ 
1832                                 (lev), IPSEC_LEVEL_REQUIRE)                   \ 
1834                         (lev) = IPSEC_LEVEL_REQUIRE,                          \ 
1838         /* set default level */ 
1839         switch (((struct sockaddr 
*)&isr
->sp
->spidx
.src
)->sa_family
) { 
1841                 esp_trans_deflev 
= IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev
); 
1842                 esp_net_deflev 
= IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev
); 
1843                 ah_trans_deflev 
= IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev
); 
1844                 ah_net_deflev 
= IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev
); 
1847                 esp_trans_deflev 
= IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev
); 
1848                 esp_net_deflev 
= IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev
); 
1849                 ah_trans_deflev 
= IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev
); 
1850                 ah_net_deflev 
= IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev
); 
1853                 panic("key_get_reqlevel: Unknown family. %d\n", 
1854                     ((struct sockaddr 
*)&isr
->sp
->spidx
.src
)->sa_family
); 
1857 #undef IPSEC_CHECK_DEFAULT 
1860         switch (isr
->level
) { 
1861         case IPSEC_LEVEL_DEFAULT
: 
1862                 switch (isr
->saidx
.proto
) { 
1864                         if (isr
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
1865                                 level 
= esp_net_deflev
; 
1867                                 level 
= esp_trans_deflev
; 
1871                         if (isr
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
1872                                 level 
= ah_net_deflev
; 
1874                                 level 
= ah_trans_deflev
; 
1877                 case IPPROTO_IPCOMP
: 
1878                         ipseclog((LOG_ERR
, "ipsec_get_reqlevel: " 
1879                             "still got IPCOMP - exiting\n")); 
1882                         panic("ipsec_get_reqlevel: " 
1883                             "Illegal protocol defined %u\n", 
1888         case IPSEC_LEVEL_USE
: 
1889         case IPSEC_LEVEL_REQUIRE
: 
1892         case IPSEC_LEVEL_UNIQUE
: 
1893                 level 
= IPSEC_LEVEL_REQUIRE
; 
1897                 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n", 
1905  * Check AH/ESP integrity. 
1911 ipsec_in_reject(struct secpolicy 
*sp
, struct mbuf 
*m
) 
1913         struct ipsecrequest 
*isr
; 
1915         int need_auth
, need_conf
, need_icv
; 
1917         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
1918             printf("ipsec_in_reject: using SP\n"); 
1919             kdebug_secpolicy(sp
)); 
1922         switch (sp
->policy
) { 
1923         case IPSEC_POLICY_DISCARD
: 
1924         case IPSEC_POLICY_GENERATE
: 
1926         case IPSEC_POLICY_BYPASS
: 
1927         case IPSEC_POLICY_NONE
: 
1930         case IPSEC_POLICY_IPSEC
: 
1933         case IPSEC_POLICY_ENTRUST
: 
1935                 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
); 
1942         /* XXX should compare policy against ipsec header history */ 
1944         for (isr 
= sp
->req
; isr 
!= NULL
; isr 
= isr
->next
) { 
1945                 /* get current level */ 
1946                 level 
= ipsec_get_reqlevel(isr
); 
1948                 switch (isr
->saidx
.proto
) { 
1950                         if (level 
== IPSEC_LEVEL_REQUIRE
) { 
1954                                 /* this won't work with multiple input threads - isr->sav would change 
1955                                  * with every packet and is not necessarily related to the current packet 
1956                                  * being processed.  If ESP processing is required - the esp code should 
1957                                  * make sure that the integrity check is present and correct.  I don't see 
1958                                  * why it would be necessary to check for the presence of the integrity 
1959                                  * check value here.  I think this is just wrong. 
1960                                  * isr->sav has been removed. 
1961                                  * %%%%%% this needs to be re-worked at some point but I think the code below can 
1962                                  * be ignored for now. 
1964                                 if (isr
->sav 
!= NULL
 
1965                                     && isr
->sav
->flags 
== SADB_X_EXT_NONE
 
1966                                     && isr
->sav
->alg_auth 
!= SADB_AALG_NONE
) { 
1973                         if (level 
== IPSEC_LEVEL_REQUIRE
) { 
1978                 case IPPROTO_IPCOMP
: 
1980                          * we don't really care, as IPcomp document says that 
1981                          * we shouldn't compress small packets, IPComp policy 
1982                          * should always be treated as being in "use" level. 
1988         KEYDEBUG(KEYDEBUG_IPSEC_DUMP
, 
1989             printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n", 
1990             need_auth
, need_conf
, need_icv
, m
->m_flags
)); 
1992         if ((need_conf 
&& !(m
->m_flags 
& M_DECRYPTED
)) 
1993             || (!need_auth 
&& need_icv 
&& !(m
->m_flags 
& M_AUTHIPDGM
)) 
1994             || (need_auth 
&& !(m
->m_flags 
& M_AUTHIPHDR
))) { 
2002  * Check AH/ESP integrity. 
2003  * This function is called from tcp_input(), udp_input(), 
2004  * and {ah,esp}4_input for tunnel mode 
2007 ipsec4_in_reject_so(struct mbuf 
*m
, struct socket 
*so
) 
2009         struct secpolicy 
*sp 
= NULL
; 
2013         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2016                 return 0;       /* XXX should be panic ? */ 
2018         /* get SP for this packet. 
2019          * When we are called from ip_forward(), we call 
2020          * ipsec4_getpolicybyaddr() with IP_FORWARDING flag. 
2023                 sp 
= ipsec4_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
); 
2025                 sp 
= ipsec4_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, 0, &error
); 
2029                 return 0;       /* XXX should be panic ? 
2030                                  * -> No, there may be error. */ 
2032         result 
= ipsec_in_reject(sp
, m
); 
2033         KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
2034             printf("DP ipsec4_in_reject_so call free SP:0x%llx\n", 
2035             (uint64_t)VM_KERNEL_ADDRPERM(sp
))); 
2036         key_freesp(sp
, KEY_SADB_UNLOCKED
); 
2042 ipsec4_in_reject(struct mbuf 
*m
, struct inpcb 
*inp
) 
2044         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2046                 return ipsec4_in_reject_so(m
, NULL
); 
2048         if (inp
->inp_socket
) { 
2049                 return ipsec4_in_reject_so(m
, inp
->inp_socket
); 
2051                 panic("ipsec4_in_reject: invalid inpcb/socket"); 
2059  * Check AH/ESP integrity. 
2060  * This function is called from tcp6_input(), udp6_input(), 
2061  * and {ah,esp}6_input for tunnel mode 
2064 ipsec6_in_reject_so(struct mbuf 
*m
, struct socket 
*so
) 
2066         struct secpolicy 
*sp 
= NULL
; 
2070         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2073                 return 0;       /* XXX should be panic ? */ 
2075         /* get SP for this packet. 
2076          * When we are called from ip_forward(), we call 
2077          * ipsec6_getpolicybyaddr() with IP_FORWARDING flag. 
2080                 sp 
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
); 
2082                 sp 
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, 0, &error
); 
2086                 return 0;       /* XXX should be panic ? */ 
2088         result 
= ipsec_in_reject(sp
, m
); 
2089         KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
2090             printf("DP ipsec6_in_reject_so call free SP:0x%llx\n", 
2091             (uint64_t)VM_KERNEL_ADDRPERM(sp
))); 
2092         key_freesp(sp
, KEY_SADB_UNLOCKED
); 
2098 ipsec6_in_reject(struct mbuf 
*m
, struct in6pcb 
*in6p
) 
2100         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2102                 return ipsec6_in_reject_so(m
, NULL
); 
2104         if (in6p
->in6p_socket
) { 
2105                 return ipsec6_in_reject_so(m
, in6p
->in6p_socket
); 
2107                 panic("ipsec6_in_reject: invalid in6p/socket"); 
2115  * compute the byte size to be occupied by IPsec header. 
2116  * in case it is tunneled, it includes the size of outer IP header. 
2117  * NOTE: SP passed is free in this function. 
2120 ipsec_hdrsiz(struct secpolicy 
*sp
) 
2122         struct ipsecrequest 
*isr
; 
2125         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2126         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
2127             printf("ipsec_hdrsiz: using SP\n"); 
2128             kdebug_secpolicy(sp
)); 
2131         switch (sp
->policy
) { 
2132         case IPSEC_POLICY_DISCARD
: 
2133         case IPSEC_POLICY_GENERATE
: 
2134         case IPSEC_POLICY_BYPASS
: 
2135         case IPSEC_POLICY_NONE
: 
2138         case IPSEC_POLICY_IPSEC
: 
2141         case IPSEC_POLICY_ENTRUST
: 
2143                 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
); 
2148         for (isr 
= sp
->req
; isr 
!= NULL
; isr 
= isr
->next
) { 
2151                 switch (isr
->saidx
.proto
) { 
2154                         clen 
= esp_hdrsiz(isr
); 
2160                         clen 
= ah_hdrsiz(isr
); 
2163                         ipseclog((LOG_ERR
, "ipsec_hdrsiz: " 
2164                             "unknown protocol %u\n", 
2169                 if (isr
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
2170                         switch (((struct sockaddr 
*)&isr
->saidx
.dst
)->sa_family
) { 
2172                                 clen 
+= sizeof(struct ip
); 
2175                                 clen 
+= sizeof(struct ip6_hdr
); 
2178                                 ipseclog((LOG_ERR
, "ipsec_hdrsiz: " 
2179                                     "unknown AF %d in IPsec tunnel SA\n", 
2180                                     ((struct sockaddr 
*)&isr
->saidx
.dst
)->sa_family
)); 
2190 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */ 
2192 ipsec4_hdrsiz(struct mbuf 
*m
, u_int8_t dir
, struct inpcb 
*inp
) 
2194         struct secpolicy 
*sp 
= NULL
; 
2198         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2201                 return 0;       /* XXX should be panic ? */ 
2203         if (inp 
!= NULL 
&& inp
->inp_socket 
== NULL
) { 
2204                 panic("ipsec4_hdrsize: why is socket NULL but there is PCB."); 
2207         /* get SP for this packet. 
2208          * When we are called from ip_forward(), we call 
2209          * ipsec4_getpolicybyaddr() with IP_FORWARDING flag. 
2212                 sp 
= ipsec4_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
); 
2214                 sp 
= ipsec4_getpolicybyaddr(m
, dir
, 0, &error
); 
2218                 return 0;       /* XXX should be panic ? */ 
2220         size 
= ipsec_hdrsiz(sp
); 
2221         KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
2222             printf("DP ipsec4_hdrsiz call free SP:0x%llx\n", 
2223             (uint64_t)VM_KERNEL_ADDRPERM(sp
))); 
2224         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
2225             printf("ipsec4_hdrsiz: size:%lu.\n", (u_int32_t
)size
)); 
2226         key_freesp(sp
, KEY_SADB_UNLOCKED
); 
2231 /* This function is called from ipsec6_hdrsize_tcp(), 
2232  * and maybe from ip6_forward.() 
2235 ipsec6_hdrsiz(struct mbuf 
*m
, u_int8_t dir
, struct in6pcb 
*in6p
) 
2237         struct secpolicy 
*sp 
= NULL
; 
2241         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
2244                 return 0;       /* XXX shoud be panic ? */ 
2246         if (in6p 
!= NULL 
&& in6p
->in6p_socket 
== NULL
) { 
2247                 panic("ipsec6_hdrsize: why is socket NULL but there is PCB."); 
2250         /* get SP for this packet */ 
2251         /* XXX Is it right to call with IP_FORWARDING. */ 
2253                 sp 
= ipsec6_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
); 
2255                 sp 
= ipsec6_getpolicybyaddr(m
, dir
, 0, &error
); 
2261         size 
= ipsec_hdrsiz(sp
); 
2262         KEYDEBUG(KEYDEBUG_IPSEC_STAMP
, 
2263             printf("DP ipsec6_hdrsiz call free SP:0x%llx\n", 
2264             (uint64_t)VM_KERNEL_ADDRPERM(sp
))); 
2265         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
2266             printf("ipsec6_hdrsiz: size:%lu.\n", (u_int32_t
)size
)); 
2267         key_freesp(sp
, KEY_SADB_UNLOCKED
); 
2273  * encapsulate for ipsec tunnel. 
2274  * ip->ip_src must be fixed later on. 
2277 ipsec4_encapsulate(struct mbuf 
*m
, struct secasvar 
*sav
) 
2284         /* can't tunnel between different AFs */ 
2285         if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family
 
2286             != ((struct sockaddr 
*)&sav
->sah
->saidx
.dst
)->sa_family
 
2287             || ((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
!= AF_INET
) { 
2292         if (m
->m_len 
< sizeof(*ip
)) { 
2293                 panic("ipsec4_encapsulate: assumption failed (first mbuf length)"); 
2296         ip 
= mtod(m
, struct ip 
*); 
2298         hlen 
= _IP_VHL_HL(ip
->ip_vhl
) << 2; 
2300         hlen 
= ip
->ip_hl 
<< 2; 
2303         if (m
->m_len 
!= hlen
) { 
2304                 panic("ipsec4_encapsulate: assumption failed (first mbuf length)"); 
2307         /* generate header checksum */ 
2310         ip
->ip_sum 
= in_cksum(m
, hlen
); 
2312         ip
->ip_sum 
= in_cksum(m
, hlen
); 
2315         plen 
= m
->m_pkthdr
.len
; 
2318          * grow the mbuf to accomodate the new IPv4 header. 
2319          * NOTE: IPv4 options will never be copied. 
2321         if (M_LEADINGSPACE(m
->m_next
) < hlen
) { 
2323                 MGET(n
, M_DONTWAIT
, MT_DATA
); 
2329                 n
->m_next 
= m
->m_next
; 
2331                 m
->m_pkthdr
.len 
+= hlen
; 
2332                 oip 
= mtod(n
, struct ip 
*); 
2334                 m
->m_next
->m_len 
+= hlen
; 
2335                 m
->m_next
->m_data 
-= hlen
; 
2336                 m
->m_pkthdr
.len 
+= hlen
; 
2337                 oip 
= mtod(m
->m_next
, struct ip 
*); 
2339         ip 
= mtod(m
, struct ip 
*); 
2340         ovbcopy((caddr_t
)ip
, (caddr_t
)oip
, hlen
); 
2341         m
->m_len 
= sizeof(struct ip
); 
2342         m
->m_pkthdr
.len 
-= (hlen 
- sizeof(struct ip
)); 
2344         /* construct new IPv4 header. see RFC 2401 5.1.2.1 */ 
2345         /* ECN consideration. */ 
2346         ip_ecn_ingress(ip4_ipsec_ecn
, &ip
->ip_tos
, &oip
->ip_tos
); 
2348         ip
->ip_vhl 
= IP_MAKE_VHL(IPVERSION
, sizeof(struct ip
) >> 2); 
2350         ip
->ip_hl 
= sizeof(struct ip
) >> 2; 
2352         ip
->ip_off 
&= htons(~IP_OFFMASK
); 
2353         ip
->ip_off 
&= htons(~IP_MF
); 
2354         switch (ip4_ipsec_dfbit
) { 
2355         case 0: /* clear DF bit */ 
2356                 ip
->ip_off 
&= htons(~IP_DF
); 
2358         case 1: /* set DF bit */ 
2359                 ip
->ip_off 
|= htons(IP_DF
); 
2361         default:        /* copy DF bit */ 
2364         ip
->ip_p 
= IPPROTO_IPIP
; 
2365         if (plen 
+ sizeof(struct ip
) < IP_MAXPACKET
) { 
2366                 ip
->ip_len 
= htons((u_int16_t
)(plen 
+ sizeof(struct ip
))); 
2368                 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: " 
2369                     "leave ip_len as is (invalid packet)\n")); 
2371         if (rfc6864 
&& IP_OFF_IS_ATOMIC(ntohs(ip
->ip_off
))) { 
2374                 ip
->ip_id 
= ip_randomid(); 
2376         bcopy(&((struct sockaddr_in 
*)&sav
->sah
->saidx
.src
)->sin_addr
, 
2377             &ip
->ip_src
, sizeof(ip
->ip_src
)); 
2378         bcopy(&((struct sockaddr_in 
*)&sav
->sah
->saidx
.dst
)->sin_addr
, 
2379             &ip
->ip_dst
, sizeof(ip
->ip_dst
)); 
2380         ip
->ip_ttl 
= IPDEFTTL
; 
2382         /* XXX Should ip_src be updated later ? */ 
2389 ipsec6_encapsulate(struct mbuf 
*m
, struct secasvar 
*sav
) 
2391         struct ip6_hdr 
*oip6
; 
2392         struct ip6_hdr 
*ip6
; 
2395         /* can't tunnel between different AFs */ 
2396         if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family
 
2397             != ((struct sockaddr 
*)&sav
->sah
->saidx
.dst
)->sa_family
 
2398             || ((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
!= AF_INET6
) { 
2403         plen 
= m
->m_pkthdr
.len
; 
2406          * grow the mbuf to accomodate the new IPv6 header. 
2408         if (m
->m_len 
!= sizeof(struct ip6_hdr
)) { 
2409                 panic("ipsec6_encapsulate: assumption failed (first mbuf length)"); 
2411         if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) { 
2413                 MGET(n
, M_DONTWAIT
, MT_DATA
); 
2418                 n
->m_len 
= sizeof(struct ip6_hdr
); 
2419                 n
->m_next 
= m
->m_next
; 
2421                 m
->m_pkthdr
.len 
+= sizeof(struct ip6_hdr
); 
2422                 oip6 
= mtod(n
, struct ip6_hdr 
*); 
2424                 m
->m_next
->m_len 
+= sizeof(struct ip6_hdr
); 
2425                 m
->m_next
->m_data 
-= sizeof(struct ip6_hdr
); 
2426                 m
->m_pkthdr
.len 
+= sizeof(struct ip6_hdr
); 
2427                 oip6 
= mtod(m
->m_next
, struct ip6_hdr 
*); 
2429         ip6 
= mtod(m
, struct ip6_hdr 
*); 
2430         ovbcopy((caddr_t
)ip6
, (caddr_t
)oip6
, sizeof(struct ip6_hdr
)); 
2432         /* Fake link-local scope-class addresses */ 
2433         if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_src
)) { 
2434                 oip6
->ip6_src
.s6_addr16
[1] = 0; 
2436         if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_dst
)) { 
2437                 oip6
->ip6_dst
.s6_addr16
[1] = 0; 
2440         /* construct new IPv6 header. see RFC 2401 5.1.2.2 */ 
2441         /* ECN consideration. */ 
2442         ip6_ecn_ingress(ip6_ipsec_ecn
, &ip6
->ip6_flow
, &oip6
->ip6_flow
); 
2443         if (plen 
< IPV6_MAXPACKET 
- sizeof(struct ip6_hdr
)) { 
2444                 ip6
->ip6_plen 
= htons((u_int16_t
)plen
); 
2446                 /* ip6->ip6_plen will be updated in ip6_output() */ 
2448         ip6
->ip6_nxt 
= IPPROTO_IPV6
; 
2449         bcopy(&((struct sockaddr_in6 
*)&sav
->sah
->saidx
.src
)->sin6_addr
, 
2450             &ip6
->ip6_src
, sizeof(ip6
->ip6_src
)); 
2451         bcopy(&((struct sockaddr_in6 
*)&sav
->sah
->saidx
.dst
)->sin6_addr
, 
2452             &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
)); 
2453         ip6
->ip6_hlim 
= IPV6_DEFHLIM
; 
2455         /* XXX Should ip6_src be updated later ? */ 
2461 ipsec64_encapsulate(struct mbuf 
*m
, struct secasvar 
*sav
) 
2463         struct ip6_hdr 
*ip6
, *ip6i
; 
2468         /* tunneling over IPv4 */ 
2469         if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family
 
2470             != ((struct sockaddr 
*)&sav
->sah
->saidx
.dst
)->sa_family
 
2471             || ((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
!= AF_INET
) { 
2476         plen 
= m
->m_pkthdr
.len
; 
2477         ip6 
= mtod(m
, struct ip6_hdr 
*); 
2478         hlim 
= ip6
->ip6_hlim
; 
2480          * grow the mbuf to accomodate the new IPv4 header. 
2482         if (m
->m_len 
!= sizeof(struct ip6_hdr
)) { 
2483                 panic("ipsec6_encapsulate: assumption failed (first mbuf length)"); 
2485         if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) { 
2487                 MGET(n
, M_DONTWAIT
, MT_DATA
); 
2492                 n
->m_len 
= sizeof(struct ip6_hdr
); 
2493                 n
->m_next 
= m
->m_next
; 
2495                 m
->m_pkthdr
.len 
+= sizeof(struct ip
); 
2496                 ip6i 
= mtod(n
, struct ip6_hdr 
*); 
2498                 m
->m_next
->m_len 
+= sizeof(struct ip6_hdr
); 
2499                 m
->m_next
->m_data 
-= sizeof(struct ip6_hdr
); 
2500                 m
->m_pkthdr
.len 
+= sizeof(struct ip
); 
2501                 ip6i 
= mtod(m
->m_next
, struct ip6_hdr 
*); 
2504         bcopy(ip6
, ip6i
, sizeof(struct ip6_hdr
)); 
2505         ip 
= mtod(m
, struct ip 
*); 
2506         m
->m_len 
= sizeof(struct ip
); 
2508          * Fill in some of the IPv4 fields - we don't need all of them 
2509          * because the rest will be filled in by ip_output 
2511         ip
->ip_v 
= IPVERSION
; 
2512         ip
->ip_hl 
= sizeof(struct ip
) >> 2; 
2518         ip
->ip_p 
= IPPROTO_IPV6
; 
2520         /* construct new IPv4 header. see RFC 2401 5.1.2.1 */ 
2521         /* ECN consideration. */ 
2522         ip64_ecn_ingress(ip4_ipsec_ecn
, &ip
->ip_tos
, &ip6
->ip6_flow
); 
2524         if (plen 
+ sizeof(struct ip
) < IP_MAXPACKET
) { 
2525                 ip
->ip_len 
= htons((u_int16_t
)(plen 
+ sizeof(struct ip
))); 
2527                 ip
->ip_len 
= htons((u_int16_t
)plen
); 
2528                 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: " 
2529                     "leave ip_len as is (invalid packet)\n")); 
2531         bcopy(&((struct sockaddr_in 
*)&sav
->sah
->saidx
.src
)->sin_addr
, 
2532             &ip
->ip_src
, sizeof(ip
->ip_src
)); 
2533         bcopy(&((struct sockaddr_in 
*)&sav
->sah
->saidx
.dst
)->sin_addr
, 
2534             &ip
->ip_dst
, sizeof(ip
->ip_dst
)); 
2540 ipsec6_update_routecache_and_output( 
2541         struct ipsec_output_state 
*state
, 
2542         struct secasvar 
*sav
) 
2544         struct sockaddr_in6
* dst6
; 
2545         struct route_in6 
*ro6
; 
2546         struct ip6_hdr 
*ip6
; 
2550         struct ip6_out_args ip6oa
; 
2551         struct route_in6 ro6_new
; 
2552         struct flowadv 
*adv 
= NULL
; 
2557         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
2559         // grab sadb_mutex, before updating sah's route cache 
2560         lck_mtx_lock(sadb_mutex
); 
2561         ro6 
= &sav
->sah
->sa_route
; 
2562         dst6 
= (struct sockaddr_in6 
*)(void *)&ro6
->ro_dst
; 
2564                 RT_LOCK(ro6
->ro_rt
); 
2566         if (ROUTE_UNUSABLE(ro6
) || 
2567             !IN6_ARE_ADDR_EQUAL(&dst6
->sin6_addr
, &ip6
->ip6_dst
)) { 
2568                 if (ro6
->ro_rt 
!= NULL
) { 
2569                         RT_UNLOCK(ro6
->ro_rt
); 
2573         if (ro6
->ro_rt 
== 0) { 
2574                 bzero(dst6
, sizeof(*dst6
)); 
2575                 dst6
->sin6_family 
= AF_INET6
; 
2576                 dst6
->sin6_len 
= sizeof(*dst6
); 
2577                 dst6
->sin6_addr 
= ip6
->ip6_dst
; 
2578                 rtalloc_scoped((struct route 
*)ro6
, sav
->sah
->outgoing_if
); 
2580                         RT_LOCK(ro6
->ro_rt
); 
2583         if (ro6
->ro_rt 
== 0) { 
2584                 ip6stat
.ip6s_noroute
++; 
2585                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_noroute
); 
2586                 error 
= EHOSTUNREACH
; 
2587                 // release sadb_mutex, after updating sah's route cache 
2588                 lck_mtx_unlock(sadb_mutex
); 
2593          * adjust state->dst if tunnel endpoint is offlink 
2595          * XXX: caching rt_gateway value in the state is 
2596          * not really good, since it may point elsewhere 
2597          * when the gateway gets modified to a larger 
2598          * sockaddr via rt_setgate().  This is currently 
2599          * addressed by SA_SIZE roundup in that routine. 
2601         if (ro6
->ro_rt
->rt_flags 
& RTF_GATEWAY
) { 
2602                 dst6 
= (struct sockaddr_in6 
*)(void *)ro6
->ro_rt
->rt_gateway
; 
2604         RT_UNLOCK(ro6
->ro_rt
); 
2605         ROUTE_RELEASE(&state
->ro
); 
2606         route_copyout((struct route 
*)&state
->ro
, (struct route 
*)ro6
, sizeof(struct route_in6
)); 
2607         state
->dst 
= (struct sockaddr 
*)dst6
; 
2608         state
->tunneled 
= 6; 
2609         // release sadb_mutex, after updating sah's route cache 
2610         lck_mtx_unlock(sadb_mutex
); 
2612         state
->m 
= ipsec6_splithdr(state
->m
); 
2614                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
); 
2619         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
2620         switch (sav
->sah
->saidx
.proto
) { 
2623                 error 
= esp6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
); 
2630                 error 
= ah6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
); 
2633                 ipseclog((LOG_ERR
, "%s: unknown ipsec protocol %d\n", __FUNCTION__
, sav
->sah
->saidx
.proto
)); 
2635                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
2640                 // If error, packet already freed by above output routines 
2645         plen 
= state
->m
->m_pkthdr
.len 
- sizeof(struct ip6_hdr
); 
2646         if (plen 
> IPV6_MAXPACKET
) { 
2647                 ipseclog((LOG_ERR
, "%s: IPsec with IPv6 jumbogram is not supported\n", __FUNCTION__
)); 
2648                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
2649                 error 
= EINVAL
;/*XXX*/ 
2652         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
2653         ip6
->ip6_plen 
= htons((u_int16_t
)plen
); 
2655         ipsec_set_pkthdr_for_interface(sav
->sah
->ipsec_if
, state
->m
, AF_INET6
); 
2656         ipsec_set_ip6oa_for_interface(sav
->sah
->ipsec_if
, &ip6oa
); 
2658         /* Increment statistics */ 
2659         ifnet_stat_increment_out(sav
->sah
->ipsec_if
, 1, (u_int32_t
)mbuf_pkthdr_len(state
->m
), 0); 
2661         /* Send to ip6_output */ 
2662         bzero(&ro6_new
, sizeof(ro6_new
)); 
2663         bzero(&ip6oa
, sizeof(ip6oa
)); 
2664         ip6oa
.ip6oa_flowadv
.code 
= 0; 
2665         ip6oa
.ip6oa_flags 
= IP6OAF_SELECT_SRCIF 
| IP6OAF_BOUND_SRCADDR
; 
2666         if (state
->outgoing_if
) { 
2667                 ip6oa
.ip6oa_boundif 
= state
->outgoing_if
; 
2668                 ip6oa
.ip6oa_flags 
|= IP6OAF_BOUND_IF
; 
2671         adv 
= &ip6oa
.ip6oa_flowadv
; 
2672         (void) ip6_output(state
->m
, NULL
, &ro6_new
, IPV6_OUTARGS
, NULL
, NULL
, &ip6oa
); 
2675         if (adv
->code 
== FADV_FLOW_CONTROLLED 
|| adv
->code 
== FADV_SUSPENDED
) { 
2677                 ifnet_disable_output(sav
->sah
->ipsec_if
); 
2685 ipsec46_encapsulate(struct ipsec_output_state 
*state
, struct secasvar 
*sav
) 
2688         struct ip6_hdr 
*ip6
; 
2699         /* can't tunnel between different AFs */ 
2700         if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family
 
2701             != ((struct sockaddr 
*)&sav
->sah
->saidx
.dst
)->sa_family
 
2702             || ((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
!= AF_INET6
) { 
2707         if (m
->m_len 
< sizeof(*ip
)) { 
2708                 panic("ipsec46_encapsulate: assumption failed (first mbuf length)"); 
2712         ip 
= mtod(m
, struct ip 
*); 
2714         hlen 
= _IP_VHL_HL(ip
->ip_vhl
) << 2; 
2716         hlen 
= ip
->ip_hl 
<< 2; 
2719         if (m
->m_len 
!= hlen
) { 
2720                 panic("ipsec46_encapsulate: assumption failed (first mbuf length)"); 
2724         /* generate header checksum */ 
2727         ip
->ip_sum 
= in_cksum(m
, hlen
); 
2729         ip
->ip_sum 
= in_cksum(m
, hlen
); 
2732         plen 
= m
->m_pkthdr
.len
; // save original IPv4 packet len, this will be ipv6 payload len 
2735          * First move the IPv4 header to the second mbuf in the chain 
2737         if (M_LEADINGSPACE(m
->m_next
) < hlen
) { 
2739                 MGET(n
, M_DONTWAIT
, MT_DATA
); 
2745                 n
->m_next 
= m
->m_next
; 
2747                 m
->m_pkthdr
.len 
+= sizeof(struct ip6_hdr
); 
2748                 oip 
= mtod(n
, struct ip 
*); 
2750                 m
->m_next
->m_len 
+= hlen
; 
2751                 m
->m_next
->m_data 
-= hlen
; 
2752                 m
->m_pkthdr
.len 
+= sizeof(struct ip6_hdr
); 
2753                 oip 
= mtod(m
->m_next
, struct ip 
*); 
2755         ip 
= mtod(m
, struct ip 
*); 
2756         ovbcopy((caddr_t
)ip
, (caddr_t
)oip
, hlen
); 
2759          * Grow the first mbuf to accomodate the new IPv6 header. 
2761         if (M_LEADINGSPACE(m
) < sizeof(struct ip6_hdr
) - hlen
) { 
2763                 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); 
2768                 M_COPY_PKTHDR(n
, m
); 
2769                 MH_ALIGN(n
, sizeof(struct ip6_hdr
)); 
2770                 n
->m_len 
= sizeof(struct ip6_hdr
); 
2771                 n
->m_next 
= m
->m_next
; 
2777                 m
->m_len 
+= (sizeof(struct ip6_hdr
) - hlen
); 
2778                 m
->m_data 
-= (sizeof(struct ip6_hdr
) - hlen
); 
2780         ip6 
= mtod(m
, struct ip6_hdr 
*); 
2782         ip6
->ip6_vfc 
&= ~IPV6_VERSION_MASK
; 
2783         ip6
->ip6_vfc 
|= IPV6_VERSION
; 
2785         /* construct new IPv6 header. see RFC 2401 5.1.2.2 */ 
2786         /* ECN consideration. */ 
2787         ip46_ecn_ingress(ip6_ipsec_ecn
, &ip6
->ip6_flow
, &ip
->ip_tos
); 
2788         if (plen 
< IPV6_MAXPACKET 
- sizeof(struct ip6_hdr
)) { 
2789                 ip6
->ip6_plen 
= htons((u_int16_t
)plen
); 
2791                 /* ip6->ip6_plen will be updated in ip6_output() */ 
2794         ip6
->ip6_nxt 
= IPPROTO_IPV4
; 
2795         ip6
->ip6_hlim 
= IPV6_DEFHLIM
; 
2797         bcopy(&((struct sockaddr_in6 
*)&sav
->sah
->saidx
.src
)->sin6_addr
, 
2798             &ip6
->ip6_src
, sizeof(ip6
->ip6_src
)); 
2799         bcopy(&((struct sockaddr_in6 
*)&sav
->sah
->saidx
.dst
)->sin6_addr
, 
2800             &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
)); 
2806  * Check the variable replay window. 
2807  * ipsec_chkreplay() performs replay check before ICV verification. 
2808  * ipsec_updatereplay() updates replay bitmap.  This must be called after 
2809  * ICV verification (it also performs replay check, which is usually done 
2811  * 0 (zero) is returned if packet disallowed, 1 if packet permitted. 
2813  * based on RFC 2401. 
2816 ipsec_chkreplay(u_int32_t seq
, struct secasvar 
*sav
, u_int8_t replay_index
) 
2818         const struct secreplay 
*replay
; 
2821         size_t wsizeb
;       /* constant: bits of window size */ 
2822         size_t frlast
;       /* constant: last frame */ 
2827                 panic("ipsec_chkreplay: NULL pointer was passed.\n"); 
2830         lck_mtx_lock(sadb_mutex
); 
2831         replay 
= sav
->replay
[replay_index
]; 
2833         if (replay
->wsize 
== 0) { 
2834                 lck_mtx_unlock(sadb_mutex
); 
2835                 return 1;       /* no need to check replay. */ 
2839         frlast 
= replay
->wsize 
- 1; 
2840         wsizeb 
= replay
->wsize 
<< 3; 
2842         /* sequence number of 0 is invalid */ 
2844                 lck_mtx_unlock(sadb_mutex
); 
2848         /* first time is always okay */ 
2849         if (replay
->count 
== 0) { 
2850                 lck_mtx_unlock(sadb_mutex
); 
2854         if (seq 
> replay
->lastseq
) { 
2855                 /* larger sequences are okay */ 
2856                 lck_mtx_unlock(sadb_mutex
); 
2859                 /* seq is equal or less than lastseq. */ 
2860                 diff 
= replay
->lastseq 
- seq
; 
2862                 /* over range to check, i.e. too old or wrapped */ 
2863                 if (diff 
>= wsizeb
) { 
2864                         lck_mtx_unlock(sadb_mutex
); 
2868                 fr 
= frlast 
- diff 
/ 8; 
2870                 /* this packet already seen ? */ 
2871                 if ((replay
->bitmap
)[fr
] & (1 << (diff 
% 8))) { 
2872                         lck_mtx_unlock(sadb_mutex
); 
2876                 /* out of order but good */ 
2877                 lck_mtx_unlock(sadb_mutex
); 
2883  * check replay counter whether to update or not. 
2888 ipsec_updatereplay(u_int32_t seq
, struct secasvar 
*sav
, u_int8_t replay_index
) 
2890         struct secreplay 
*replay
; 
2893         size_t wsizeb
;       /* constant: bits of window size */ 
2894         size_t frlast
;             /* constant: last frame */ 
2898                 panic("ipsec_chkreplay: NULL pointer was passed.\n"); 
2901         lck_mtx_lock(sadb_mutex
); 
2902         replay 
= sav
->replay
[replay_index
]; 
2904         if (replay
->wsize 
== 0) { 
2905                 goto ok
;        /* no need to check replay. */ 
2908         frlast 
= replay
->wsize 
- 1; 
2909         wsizeb 
= replay
->wsize 
<< 3; 
2911         /* sequence number of 0 is invalid */ 
2913                 lck_mtx_unlock(sadb_mutex
); 
2918         if (replay
->count 
== 0) { 
2919                 replay
->lastseq 
= seq
; 
2920                 bzero(replay
->bitmap
, replay
->wsize
); 
2921                 (replay
->bitmap
)[frlast
] = 1; 
2925         if (seq 
> replay
->lastseq
) { 
2926                 /* seq is larger than lastseq. */ 
2927                 diff 
= seq 
- replay
->lastseq
; 
2929                 /* new larger sequence number */ 
2930                 if (diff 
< wsizeb
) { 
2932                         /* set bit for this packet */ 
2933                         vshiftl((unsigned char *) replay
->bitmap
, diff
, replay
->wsize
); 
2934                         (replay
->bitmap
)[frlast
] |= 1; 
2936                         /* this packet has a "way larger" */ 
2937                         bzero(replay
->bitmap
, replay
->wsize
); 
2938                         (replay
->bitmap
)[frlast
] = 1; 
2940                 replay
->lastseq 
= seq
; 
2942                 /* larger is good */ 
2944                 /* seq is equal or less than lastseq. */ 
2945                 diff 
= replay
->lastseq 
- seq
; 
2947                 /* over range to check, i.e. too old or wrapped */ 
2948                 if (diff 
>= wsizeb
) { 
2949                         lck_mtx_unlock(sadb_mutex
); 
2953                 fr 
= frlast 
- diff 
/ 8; 
2955                 /* this packet already seen ? */ 
2956                 if ((replay
->bitmap
)[fr
] & (1 << (diff 
% 8))) { 
2957                         lck_mtx_unlock(sadb_mutex
); 
2962                 (replay
->bitmap
)[fr
] |= (1 << (diff 
% 8)); 
2964                 /* out of order but good */ 
2968         if (replay
->count 
== ~0) { 
2969                 /* set overflow flag */ 
2972                 /* don't increment, no more packets accepted */ 
2973                 if ((sav
->flags 
& SADB_X_EXT_CYCSEQ
) == 0) { 
2974                         lck_mtx_unlock(sadb_mutex
); 
2978                 ipseclog((LOG_WARNING
, "replay counter made %d cycle. %s\n", 
2979                     replay
->overflow
, ipsec_logsastr(sav
))); 
2984         lck_mtx_unlock(sadb_mutex
); 
2989  * shift variable length buffer to left. 
2990  * IN:  bitmap: pointer to the buffer 
2991  *      nbit:   the number of to shift. 
2992  *      wsize:  buffer size (bytes). 
2995 vshiftl(unsigned char *bitmap
, int nbit
, size_t wsize
) 
3001         for (j 
= 0; j 
< nbit
; j 
+= 8) { 
3002                 s 
= (nbit 
- j 
< 8) ? (nbit 
- j
): 8; 
3004                 for (i 
= 1; i 
< wsize
; i
++) { 
3005                         over 
= (bitmap
[i
] >> (8 - s
)); 
3007                         bitmap
[i 
- 1] |= over
; 
3015 ipsec4_logpacketstr(struct ip 
*ip
, u_int32_t spi
) 
3017         static char buf
[256] __attribute__((aligned(4))); 
3021         s 
= (u_int8_t 
*)(&ip
->ip_src
); 
3022         d 
= (u_int8_t 
*)(&ip
->ip_dst
); 
3025         snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
)); 
3029         snprintf(p
, sizeof(buf
) - (p 
- buf
), "src=%u.%u.%u.%u", 
3030             s
[0], s
[1], s
[2], s
[3]); 
3034         snprintf(p
, sizeof(buf
) - (p 
- buf
), " dst=%u.%u.%u.%u", 
3035             d
[0], d
[1], d
[2], d
[3]); 
3039         snprintf(p
, sizeof(buf
) - (p 
- buf
), ")"); 
3045 ipsec6_logpacketstr(struct ip6_hdr 
*ip6
, u_int32_t spi
) 
3047         static char buf
[256] __attribute__((aligned(4))); 
3051         snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
)); 
3055         snprintf(p
, sizeof(buf
) - (p 
- buf
), "src=%s", 
3056             ip6_sprintf(&ip6
->ip6_src
)); 
3060         snprintf(p
, sizeof(buf
) - (p 
- buf
), " dst=%s", 
3061             ip6_sprintf(&ip6
->ip6_dst
)); 
3065         snprintf(p
, sizeof(buf
) - (p 
- buf
), ")"); 
3071 ipsec_logsastr(struct secasvar 
*sav
) 
3073         static char buf
[256] __attribute__((aligned(4))); 
3075         struct secasindex 
*saidx 
= &sav
->sah
->saidx
; 
3077         /* validity check */ 
3078         if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family
 
3079             != ((struct sockaddr 
*)&sav
->sah
->saidx
.dst
)->sa_family
) { 
3080                 panic("ipsec_logsastr: family mismatched.\n"); 
3084         snprintf(buf
, sizeof(buf
), "SA(SPI=%u ", (u_int32_t
)ntohl(sav
->spi
)); 
3088         if (((struct sockaddr 
*)&saidx
->src
)->sa_family 
== AF_INET
) { 
3090                 s 
= (u_int8_t 
*)&((struct sockaddr_in 
*)&saidx
->src
)->sin_addr
; 
3091                 d 
= (u_int8_t 
*)&((struct sockaddr_in 
*)&saidx
->dst
)->sin_addr
; 
3092                 snprintf(p
, sizeof(buf
) - (p 
- buf
), 
3093                     "src=%d.%d.%d.%d dst=%d.%d.%d.%d", 
3094                     s
[0], s
[1], s
[2], s
[3], d
[0], d
[1], d
[2], d
[3]); 
3095         } else if (((struct sockaddr 
*)&saidx
->src
)->sa_family 
== AF_INET6
) { 
3096                 snprintf(p
, sizeof(buf
) - (p 
- buf
), 
3098                     ip6_sprintf(&((struct sockaddr_in6 
*)&saidx
->src
)->sin6_addr
)); 
3102                 snprintf(p
, sizeof(buf
) - (p 
- buf
), 
3104                     ip6_sprintf(&((struct sockaddr_in6 
*)&saidx
->dst
)->sin6_addr
)); 
3109         snprintf(p
, sizeof(buf
) - (p 
- buf
), ")"); 
3115 ipsec_dumpmbuf(struct mbuf 
*m
) 
3124                 p 
= mtod(m
, u_char 
*); 
3125                 for (i 
= 0; i 
< m
->m_len
; i
++) { 
3126                         printf("%02x ", p
[i
]); 
3128                         if (totlen 
% 16 == 0) { 
3134         if (totlen 
% 16 != 0) { 
3142  * IPsec output logic for IPv4. 
3145 ipsec4_output_internal(struct ipsec_output_state 
*state
, struct secasvar 
*sav
) 
3147         struct ip 
*ip 
= NULL
; 
3149         struct sockaddr_in 
*dst4
; 
3152         /* validity check */ 
3153         if (sav 
== NULL 
|| sav
->sah 
== NULL
) { 
3159          * If there is no valid SA, we give up to process any 
3160          * more.  In such a case, the SA's status is changed 
3161          * from DYING to DEAD after allocating.  If a packet 
3162          * send to the receiver by dead SA, the receiver can 
3163          * not decode a packet because SA has been dead. 
3165         if (sav
->state 
!= SADB_SASTATE_MATURE
 
3166             && sav
->state 
!= SADB_SASTATE_DYING
) { 
3167                 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
); 
3172         state
->outgoing_if 
= sav
->sah
->outgoing_if
; 
3175          * There may be the case that SA status will be changed when 
3176          * we are refering to one. So calling splsoftnet(). 
3179         if (sav
->sah
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
3181                  * build IPsec tunnel. 
3183                 state
->m 
= ipsec4_splithdr(state
->m
); 
3189                 if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
== AF_INET6
) { 
3190                         error 
= ipsec46_encapsulate(state
, sav
); 
3192                                 // packet already freed by encapsulation error handling 
3197                         error 
= ipsec6_update_routecache_and_output(state
, sav
); 
3199                 } else if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
== AF_INET
) { 
3200                         error 
= ipsec4_encapsulate(state
->m
, sav
); 
3205                         ip 
= mtod(state
->m
, struct ip 
*); 
3207                         // grab sadb_mutex, before updating sah's route cache 
3208                         lck_mtx_lock(sadb_mutex
); 
3209                         ro4 
= (struct route 
*)&sav
->sah
->sa_route
; 
3210                         dst4 
= (struct sockaddr_in 
*)(void *)&ro4
->ro_dst
; 
3211                         if (ro4
->ro_rt 
!= NULL
) { 
3212                                 RT_LOCK(ro4
->ro_rt
); 
3214                         if (ROUTE_UNUSABLE(ro4
) || 
3215                             dst4
->sin_addr
.s_addr 
!= ip
->ip_dst
.s_addr
) { 
3216                                 if (ro4
->ro_rt 
!= NULL
) { 
3217                                         RT_UNLOCK(ro4
->ro_rt
); 
3221                         if (ro4
->ro_rt 
== 0) { 
3222                                 dst4
->sin_family 
= AF_INET
; 
3223                                 dst4
->sin_len 
= sizeof(*dst4
); 
3224                                 dst4
->sin_addr 
= ip
->ip_dst
; 
3225                                 rtalloc_scoped(ro4
, sav
->sah
->outgoing_if
); 
3226                                 if (ro4
->ro_rt 
== 0) { 
3227                                         OSAddAtomic(1, &ipstat
.ips_noroute
); 
3228                                         error 
= EHOSTUNREACH
; 
3229                                         // release sadb_mutex, after updating sah's route cache 
3230                                         lck_mtx_unlock(sadb_mutex
); 
3233                                 RT_LOCK(ro4
->ro_rt
); 
3237                          * adjust state->dst if tunnel endpoint is offlink 
3239                          * XXX: caching rt_gateway value in the state is 
3240                          * not really good, since it may point elsewhere 
3241                          * when the gateway gets modified to a larger 
3242                          * sockaddr via rt_setgate().  This is currently 
3243                          * addressed by SA_SIZE roundup in that routine. 
3245                         if (ro4
->ro_rt
->rt_flags 
& RTF_GATEWAY
) { 
3246                                 dst4 
= (struct sockaddr_in 
*)(void *)ro4
->ro_rt
->rt_gateway
; 
3248                         RT_UNLOCK(ro4
->ro_rt
); 
3249                         ROUTE_RELEASE(&state
->ro
); 
3250                         route_copyout((struct route 
*)&state
->ro
, ro4
, sizeof(struct route
)); 
3251                         state
->dst 
= (struct sockaddr 
*)dst4
; 
3252                         state
->tunneled 
= 4; 
3253                         // release sadb_mutex, after updating sah's route cache 
3254                         lck_mtx_unlock(sadb_mutex
); 
3256                         ipseclog((LOG_ERR
, "%s: family mismatched between inner and outer spi=%u\n", 
3257                             __FUNCTION__
, (u_int32_t
)ntohl(sav
->spi
))); 
3258                         error 
= EAFNOSUPPORT
; 
3263         state
->m 
= ipsec4_splithdr(state
->m
); 
3268         switch (sav
->sah
->saidx
.proto
) { 
3271                 if ((error 
= esp4_output(state
->m
, sav
)) != 0) { 
3283                 if ((error 
= ah4_output(state
->m
, sav
)) != 0) { 
3290                     "ipsec4_output: unknown ipsec protocol %d\n", 
3291                     sav
->sah
->saidx
.proto
)); 
3294                 error 
= EPROTONOSUPPORT
; 
3298         if (state
->m 
== 0) { 
3310 ipsec4_interface_output(struct ipsec_output_state 
*state
, ifnet_t interface
) 
3313         struct secasvar 
*sav 
= NULL
; 
3315         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
3317         if (state 
== NULL
) { 
3318                 panic("state == NULL in ipsec4_output"); 
3320         if (state
->m 
== NULL
) { 
3321                 panic("state->m == NULL in ipsec4_output"); 
3323         if (state
->dst 
== NULL
) { 
3324                 panic("state->dst == NULL in ipsec4_output"); 
3327         struct ip 
*ip 
= mtod(state
->m
, struct ip 
*); 
3329         struct sockaddr_in src 
= {}; 
3330         src
.sin_family 
= AF_INET
; 
3331         src
.sin_len 
= sizeof(src
); 
3332         memcpy(&src
.sin_addr
, &ip
->ip_src
, sizeof(src
.sin_addr
)); 
3334         struct sockaddr_in dst 
= {}; 
3335         dst
.sin_family 
= AF_INET
; 
3336         dst
.sin_len 
= sizeof(dst
); 
3337         memcpy(&dst
.sin_addr
, &ip
->ip_dst
, sizeof(dst
.sin_addr
)); 
3339         sav 
= key_alloc_outbound_sav_for_interface(interface
, AF_INET
, 
3340             (struct sockaddr 
*)&src
, 
3341             (struct sockaddr 
*)&dst
); 
3346         if ((error 
= ipsec4_output_internal(state
, sav
)) != 0) { 
3350         KERNEL_DEBUG(DBG_FNC_IPSEC_OUT 
| DBG_FUNC_END
, 0, 0, 0, 0, 0); 
3352                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
3358                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
3362         KERNEL_DEBUG(DBG_FNC_IPSEC_OUT 
| DBG_FUNC_END
, error
, 0, 0, 0, 0); 
3367 ipsec4_output(struct ipsec_output_state 
*state
, struct secpolicy 
*sp
, __unused 
int flags
) 
3369         struct ip 
*ip 
= NULL
; 
3370         struct ipsecrequest 
*isr 
= NULL
; 
3371         struct secasindex saidx
; 
3372         struct secasvar 
*sav 
= NULL
; 
3374         struct sockaddr_in 
*sin
; 
3376         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
3379                 panic("state == NULL in ipsec4_output"); 
3382                 panic("state->m == NULL in ipsec4_output"); 
3385                 panic("state->dst == NULL in ipsec4_output"); 
3388         KERNEL_DEBUG(DBG_FNC_IPSEC_OUT 
| DBG_FUNC_START
, 0, 0, 0, 0, 0); 
3390         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
3391             printf("ipsec4_output: applied SP\n"); 
3392             kdebug_secpolicy(sp
)); 
3394         for (isr 
= sp
->req
; isr 
!= NULL
; isr 
= isr
->next
) { 
3395                 /* make SA index for search proper SA */ 
3396                 ip 
= mtod(state
->m
, struct ip 
*); 
3397                 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
)); 
3398                 saidx
.mode 
= isr
->saidx
.mode
; 
3399                 saidx
.reqid 
= isr
->saidx
.reqid
; 
3400                 sin 
= (struct sockaddr_in 
*)&saidx
.src
; 
3401                 if (sin
->sin_len 
== 0) { 
3402                         sin
->sin_len 
= sizeof(*sin
); 
3403                         sin
->sin_family 
= AF_INET
; 
3404                         sin
->sin_port 
= IPSEC_PORT_ANY
; 
3405                         bcopy(&ip
->ip_src
, &sin
->sin_addr
, 
3406                             sizeof(sin
->sin_addr
)); 
3408                 sin 
= (struct sockaddr_in 
*)&saidx
.dst
; 
3409                 if (sin
->sin_len 
== 0) { 
3410                         sin
->sin_len 
= sizeof(*sin
); 
3411                         sin
->sin_family 
= AF_INET
; 
3412                         sin
->sin_port 
= IPSEC_PORT_ANY
; 
3414                          * Get port from packet if upper layer is UDP and nat traversal 
3415                          * is enabled and transport mode. 
3418                         if ((esp_udp_encap_port 
& 0xFFFF) != 0 && 
3419                             isr
->saidx
.mode 
== IPSEC_MODE_TRANSPORT
) { 
3420                                 if (ip
->ip_p 
== IPPROTO_UDP
) { 
3424                                         hlen 
= IP_VHL_HL(ip
->ip_vhl
) << 2; 
3426                                         hlen 
= ip
->ip_hl 
<< 2; 
3428                                         if (state
->m
->m_len 
< hlen 
+ sizeof(struct udphdr
)) { 
3429                                                 state
->m 
= m_pullup(state
->m
, hlen 
+ sizeof(struct udphdr
)); 
3431                                                         ipseclog((LOG_DEBUG
, "IPv4 output: can't pullup UDP header\n")); 
3432                                                         IPSEC_STAT_INCREMENT(ipsecstat
.in_inval
); 
3435                                                 ip 
= mtod(state
->m
, struct ip 
*); 
3437                                         udp 
= (struct udphdr 
*)(void *)(((u_int8_t 
*)ip
) + hlen
); 
3438                                         sin
->sin_port 
= udp
->uh_dport
; 
3442                         bcopy(&ip
->ip_dst
, &sin
->sin_addr
, 
3443                             sizeof(sin
->sin_addr
)); 
3446                 if ((error 
= key_checkrequest(isr
, &saidx
, &sav
)) != 0) { 
3448                          * IPsec processing is required, but no SA found. 
3449                          * I assume that key_acquire() had been called 
3450                          * to get/establish the SA. Here I discard 
3451                          * this packet because it is responsibility for 
3452                          * upper layer to retransmit the packet. 
3454                         IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
); 
3458                 /* validity check */ 
3460                         switch (ipsec_get_reqlevel(isr
)) { 
3461                         case IPSEC_LEVEL_USE
: 
3463                         case IPSEC_LEVEL_REQUIRE
: 
3464                                 /* must be not reached here. */ 
3465                                 panic("ipsec4_output: no SA found, but required."); 
3469                 if ((error 
= ipsec4_output_internal(state
, sav
)) != 0) { 
3474         KERNEL_DEBUG(DBG_FNC_IPSEC_OUT 
| DBG_FUNC_END
, 0, 0, 0, 0, 0); 
3476                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
3482                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
3486         KERNEL_DEBUG(DBG_FNC_IPSEC_OUT 
| DBG_FUNC_END
, error
, 0, 0, 0, 0); 
3493  * IPsec output logic for IPv6, transport mode. 
3496 ipsec6_output_trans_internal( 
3497         struct ipsec_output_state 
*state
, 
3498         struct secasvar 
*sav
, 
3502         struct ip6_hdr 
*ip6
; 
3506         /* validity check */ 
3507         if (sav 
== NULL 
|| sav
->sah 
== NULL
) { 
3513          * If there is no valid SA, we give up to process. 
3514          * see same place at ipsec4_output(). 
3516         if (sav
->state 
!= SADB_SASTATE_MATURE
 
3517             && sav
->state 
!= SADB_SASTATE_DYING
) { 
3518                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
); 
3523         state
->outgoing_if 
= sav
->sah
->outgoing_if
; 
3525         switch (sav
->sah
->saidx
.proto
) { 
3528                 error 
= esp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
); 
3535                 error 
= ah6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
); 
3538                 ipseclog((LOG_ERR
, "ipsec6_output_trans: " 
3539                     "unknown ipsec protocol %d\n", sav
->sah
->saidx
.proto
)); 
3541                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
3542                 error 
= EPROTONOSUPPORT
; 
3549         plen 
= state
->m
->m_pkthdr
.len 
- sizeof(struct ip6_hdr
); 
3550         if (plen 
> IPV6_MAXPACKET
) { 
3551                 ipseclog((LOG_ERR
, "ipsec6_output_trans: " 
3552                     "IPsec with IPv6 jumbogram is not supported\n")); 
3553                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
3554                 error 
= EINVAL
; /*XXX*/ 
3557         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
3558         ip6
->ip6_plen 
= htons((u_int16_t
)plen
); 
3566 ipsec6_output_trans( 
3567         struct ipsec_output_state 
*state
, 
3570         struct secpolicy 
*sp
, 
3574         struct ip6_hdr 
*ip6
; 
3575         struct ipsecrequest 
*isr 
= NULL
; 
3576         struct secasindex saidx
; 
3578         struct sockaddr_in6 
*sin6
; 
3579         struct secasvar 
*sav 
= NULL
; 
3581         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
3584                 panic("state == NULL in ipsec6_output_trans"); 
3587                 panic("state->m == NULL in ipsec6_output_trans"); 
3590                 panic("nexthdrp == NULL in ipsec6_output_trans"); 
3593                 panic("mprev == NULL in ipsec6_output_trans"); 
3596                 panic("sp == NULL in ipsec6_output_trans"); 
3599                 panic("tun == NULL in ipsec6_output_trans"); 
3602         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
3603             printf("ipsec6_output_trans: applyed SP\n"); 
3604             kdebug_secpolicy(sp
)); 
3607         for (isr 
= sp
->req
; isr
; isr 
= isr
->next
) { 
3608                 if (isr
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
3609                         /* the rest will be handled by ipsec6_output_tunnel() */ 
3613                 /* make SA index for search proper SA */ 
3614                 ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
3615                 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
)); 
3616                 saidx
.mode 
= isr
->saidx
.mode
; 
3617                 saidx
.reqid 
= isr
->saidx
.reqid
; 
3618                 sin6 
= (struct sockaddr_in6 
*)&saidx
.src
; 
3619                 if (sin6
->sin6_len 
== 0) { 
3620                         sin6
->sin6_len 
= sizeof(*sin6
); 
3621                         sin6
->sin6_family 
= AF_INET6
; 
3622                         sin6
->sin6_port 
= IPSEC_PORT_ANY
; 
3623                         bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
, 
3624                             sizeof(ip6
->ip6_src
)); 
3625                         if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) { 
3626                                 /* fix scope id for comparing SPD */ 
3627                                 sin6
->sin6_addr
.s6_addr16
[1] = 0; 
3628                                 sin6
->sin6_scope_id 
= ntohs(ip6
->ip6_src
.s6_addr16
[1]); 
3631                 sin6 
= (struct sockaddr_in6 
*)&saidx
.dst
; 
3632                 if (sin6
->sin6_len 
== 0) { 
3633                         sin6
->sin6_len 
= sizeof(*sin6
); 
3634                         sin6
->sin6_family 
= AF_INET6
; 
3635                         sin6
->sin6_port 
= IPSEC_PORT_ANY
; 
3636                         bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
, 
3637                             sizeof(ip6
->ip6_dst
)); 
3638                         if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) { 
3639                                 /* fix scope id for comparing SPD */ 
3640                                 sin6
->sin6_addr
.s6_addr16
[1] = 0; 
3641                                 sin6
->sin6_scope_id 
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]); 
3645                 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) { 
3647                          * IPsec processing is required, but no SA found. 
3648                          * I assume that key_acquire() had been called 
3649                          * to get/establish the SA. Here I discard 
3650                          * this packet because it is responsibility for 
3651                          * upper layer to retransmit the packet. 
3653                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
); 
3657                          * Notify the fact that the packet is discarded 
3658                          * to ourselves. I believe this is better than 
3659                          * just silently discarding. (jinmei@kame.net) 
3660                          * XXX: should we restrict the error to TCP packets? 
3661                          * XXX: should we directly notify sockets via 
3664                         icmp6_error(state
->m
, ICMP6_DST_UNREACH
, 
3665                             ICMP6_DST_UNREACH_ADMIN
, 0); 
3666                         state
->m 
= NULL
; /* icmp6_error freed the mbuf */ 
3670                 /* validity check */ 
3672                         switch (ipsec_get_reqlevel(isr
)) { 
3673                         case IPSEC_LEVEL_USE
: 
3675                         case IPSEC_LEVEL_REQUIRE
: 
3676                                 /* must be not reached here. */ 
3677                                 panic("ipsec6_output_trans: no SA found, but required."); 
3681                 if ((error 
= ipsec6_output_trans_internal(state
, sav
, nexthdrp
, mprev
)) != 0) { 
3686         /* if we have more to go, we need a tunnel mode processing */ 
3692                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
3698                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
3706  * IPsec output logic for IPv6, tunnel mode. 
3709 ipsec6_output_tunnel_internal(struct ipsec_output_state 
*state
, struct secasvar 
*sav
, int *must_be_last
) 
3711         struct ip6_hdr 
*ip6
; 
3712         struct sockaddr_in6
* dst6
; 
3713         struct route_in6 
*ro6
; 
3717         /* validity check */ 
3718         if (sav 
== NULL 
|| sav
->sah 
== NULL 
|| sav
->sah
->saidx
.mode 
!= IPSEC_MODE_TUNNEL
) { 
3724          * If there is no valid SA, we give up to process. 
3725          * see same place at ipsec4_output(). 
3727         if (sav
->state 
!= SADB_SASTATE_MATURE
 
3728             && sav
->state 
!= SADB_SASTATE_DYING
) { 
3729                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
); 
3734         state
->outgoing_if 
= sav
->sah
->outgoing_if
; 
3736         if (sav
->sah
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
3738                  * build IPsec tunnel. 
3740                 state
->m 
= ipsec6_splithdr(state
->m
); 
3742                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
); 
3747                 if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
== AF_INET6
) { 
3748                         error 
= ipsec6_encapsulate(state
->m
, sav
); 
3753                         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
3754                 } else if (((struct sockaddr 
*)&sav
->sah
->saidx
.src
)->sa_family 
== AF_INET
) { 
3756                         struct sockaddr_in
* dst4
; 
3757                         struct route 
*ro4 
= NULL
; 
3758                         struct route  ro4_copy
; 
3759                         struct ip_out_args ipoa
; 
3761                         bzero(&ipoa
, sizeof(ipoa
)); 
3762                         ipoa
.ipoa_boundif 
= IFSCOPE_NONE
; 
3763                         ipoa
.ipoa_flags 
= IPOAF_SELECT_SRCIF
; 
3764                         ipoa
.ipoa_sotc 
= SO_TC_UNSPEC
; 
3765                         ipoa
.ipoa_netsvctype 
= _NET_SERVICE_TYPE_UNSPEC
; 
3771                         state
->tunneled 
= 4; /* must not process any further in ip6_output */ 
3772                         error 
= ipsec64_encapsulate(state
->m
, sav
); 
3777                         /* Now we have an IPv4 packet */ 
3778                         ip 
= mtod(state
->m
, struct ip 
*); 
3780                         // grab sadb_mutex, to update sah's route cache and get a local copy of it 
3781                         lck_mtx_lock(sadb_mutex
); 
3782                         ro4 
= (struct route 
*)&sav
->sah
->sa_route
; 
3783                         dst4 
= (struct sockaddr_in 
*)(void *)&ro4
->ro_dst
; 
3785                                 RT_LOCK(ro4
->ro_rt
); 
3787                         if (ROUTE_UNUSABLE(ro4
) || 
3788                             dst4
->sin_addr
.s_addr 
!= ip
->ip_dst
.s_addr
) { 
3789                                 if (ro4
->ro_rt 
!= NULL
) { 
3790                                         RT_UNLOCK(ro4
->ro_rt
); 
3794                         if (ro4
->ro_rt 
== NULL
) { 
3795                                 dst4
->sin_family 
= AF_INET
; 
3796                                 dst4
->sin_len 
= sizeof(*dst4
); 
3797                                 dst4
->sin_addr 
= ip
->ip_dst
; 
3799                                 RT_UNLOCK(ro4
->ro_rt
); 
3801                         route_copyout(&ro4_copy
, ro4
, sizeof(struct route
)); 
3802                         // release sadb_mutex, after updating sah's route cache and getting a local copy 
3803                         lck_mtx_unlock(sadb_mutex
); 
3804                         state
->m 
= ipsec4_splithdr(state
->m
); 
3807                                 ROUTE_RELEASE(&ro4_copy
); 
3810                         switch (sav
->sah
->saidx
.proto
) { 
3813                                 if ((error 
= esp4_output(state
->m
, sav
)) != 0) { 
3815                                         ROUTE_RELEASE(&ro4_copy
); 
3824                                 ROUTE_RELEASE(&ro4_copy
); 
3828                                 if ((error 
= ah4_output(state
->m
, sav
)) != 0) { 
3830                                         ROUTE_RELEASE(&ro4_copy
); 
3836                                     "ipsec4_output: unknown ipsec protocol %d\n", 
3837                                     sav
->sah
->saidx
.proto
)); 
3840                                 error 
= EPROTONOSUPPORT
; 
3841                                 ROUTE_RELEASE(&ro4_copy
); 
3845                         if (state
->m 
== 0) { 
3847                                 ROUTE_RELEASE(&ro4_copy
); 
3850                         ipsec_set_pkthdr_for_interface(sav
->sah
->ipsec_if
, state
->m
, AF_INET
); 
3851                         ipsec_set_ipoa_for_interface(sav
->sah
->ipsec_if
, &ipoa
); 
3853                         ip 
= mtod(state
->m
, struct ip 
*); 
3854                         ip
->ip_len 
= ntohs(ip
->ip_len
);  /* flip len field before calling ip_output */ 
3855                         error 
= ip_output(state
->m
, NULL
, &ro4_copy
, IP_OUTARGS
, NULL
, &ipoa
); 
3857                         // grab sadb_mutex, to synchronize the sah's route cache with the local copy 
3858                         lck_mtx_lock(sadb_mutex
); 
3859                         route_copyin(&ro4_copy
, ro4
, sizeof(struct route
)); 
3860                         lck_mtx_unlock(sadb_mutex
); 
3866                         ipseclog((LOG_ERR
, "ipsec6_output_tunnel: " 
3867                             "unsupported inner family, spi=%u\n", 
3868                             (u_int32_t
)ntohl(sav
->spi
))); 
3869                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
3870                         error 
= EAFNOSUPPORT
; 
3874                 // grab sadb_mutex, before updating sah's route cache 
3875                 lck_mtx_lock(sadb_mutex
); 
3876                 ro6 
= &sav
->sah
->sa_route
; 
3877                 dst6 
= (struct sockaddr_in6 
*)(void *)&ro6
->ro_dst
; 
3879                         RT_LOCK(ro6
->ro_rt
); 
3881                 if (ROUTE_UNUSABLE(ro6
) || 
3882                     !IN6_ARE_ADDR_EQUAL(&dst6
->sin6_addr
, &ip6
->ip6_dst
)) { 
3883                         if (ro6
->ro_rt 
!= NULL
) { 
3884                                 RT_UNLOCK(ro6
->ro_rt
); 
3888                 if (ro6
->ro_rt 
== 0) { 
3889                         bzero(dst6
, sizeof(*dst6
)); 
3890                         dst6
->sin6_family 
= AF_INET6
; 
3891                         dst6
->sin6_len 
= sizeof(*dst6
); 
3892                         dst6
->sin6_addr 
= ip6
->ip6_dst
; 
3893                         rtalloc_scoped((struct route 
*)ro6
, sav
->sah
->outgoing_if
); 
3895                                 RT_LOCK(ro6
->ro_rt
); 
3898                 if (ro6
->ro_rt 
== 0) { 
3899                         ip6stat
.ip6s_noroute
++; 
3900                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_noroute
); 
3901                         error 
= EHOSTUNREACH
; 
3902                         // release sadb_mutex, after updating sah's route cache 
3903                         lck_mtx_unlock(sadb_mutex
); 
3908                  * adjust state->dst if tunnel endpoint is offlink 
3910                  * XXX: caching rt_gateway value in the state is 
3911                  * not really good, since it may point elsewhere 
3912                  * when the gateway gets modified to a larger 
3913                  * sockaddr via rt_setgate().  This is currently 
3914                  * addressed by SA_SIZE roundup in that routine. 
3916                 if (ro6
->ro_rt
->rt_flags 
& RTF_GATEWAY
) { 
3917                         dst6 
= (struct sockaddr_in6 
*)(void *)ro6
->ro_rt
->rt_gateway
; 
3919                 RT_UNLOCK(ro6
->ro_rt
); 
3920                 ROUTE_RELEASE(&state
->ro
); 
3921                 route_copyout((struct route 
*)&state
->ro
, (struct route 
*)ro6
, sizeof(struct route_in6
)); 
3922                 state
->dst 
= (struct sockaddr 
*)dst6
; 
3923                 state
->tunneled 
= 6; 
3924                 // release sadb_mutex, after updating sah's route cache 
3925                 lck_mtx_unlock(sadb_mutex
); 
3928         state
->m 
= ipsec6_splithdr(state
->m
); 
3930                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
); 
3934         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
3935         switch (sav
->sah
->saidx
.proto
) { 
3938                 error 
= esp6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
); 
3945                 error 
= ah6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
); 
3948                 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: " 
3949                     "unknown ipsec protocol %d\n", sav
->sah
->saidx
.proto
)); 
3951                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
3959         plen 
= state
->m
->m_pkthdr
.len 
- sizeof(struct ip6_hdr
); 
3960         if (plen 
> IPV6_MAXPACKET
) { 
3961                 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: " 
3962                     "IPsec with IPv6 jumbogram is not supported\n")); 
3963                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
3964                 error 
= EINVAL
; /*XXX*/ 
3967         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
3968         ip6
->ip6_plen 
= htons((u_int16_t
)plen
); 
3977 ipsec6_output_tunnel( 
3978         struct ipsec_output_state 
*state
, 
3979         struct secpolicy 
*sp
, 
3982         struct ip6_hdr 
*ip6
; 
3983         struct ipsecrequest 
*isr 
= NULL
; 
3984         struct secasindex saidx
; 
3985         struct secasvar 
*sav 
= NULL
; 
3988         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
3991                 panic("state == NULL in ipsec6_output_tunnel"); 
3994                 panic("state->m == NULL in ipsec6_output_tunnel"); 
3997                 panic("sp == NULL in ipsec6_output_tunnel"); 
4000         KEYDEBUG(KEYDEBUG_IPSEC_DATA
, 
4001             printf("ipsec6_output_tunnel: applyed SP\n"); 
4002             kdebug_secpolicy(sp
)); 
4005          * transport mode ipsec (before the 1st tunnel mode) is already 
4006          * processed by ipsec6_output_trans(). 
4008         for (isr 
= sp
->req
; isr
; isr 
= isr
->next
) { 
4009                 if (isr
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
4014         for (/* already initialized */; isr
; isr 
= isr
->next
) { 
4015                 if (isr
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
4016                         /* When tunnel mode, SA peers must be specified. */ 
4017                         bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
)); 
4019                         /* make SA index to look for a proper SA */ 
4020                         struct sockaddr_in6 
*sin6
; 
4022                         bzero(&saidx
, sizeof(saidx
)); 
4023                         saidx
.proto 
= isr
->saidx
.proto
; 
4024                         saidx
.mode 
= isr
->saidx
.mode
; 
4025                         saidx
.reqid 
= isr
->saidx
.reqid
; 
4027                         ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
4028                         sin6 
= (struct sockaddr_in6 
*)&saidx
.src
; 
4029                         if (sin6
->sin6_len 
== 0) { 
4030                                 sin6
->sin6_len 
= sizeof(*sin6
); 
4031                                 sin6
->sin6_family 
= AF_INET6
; 
4032                                 sin6
->sin6_port 
= IPSEC_PORT_ANY
; 
4033                                 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
, 
4034                                     sizeof(ip6
->ip6_src
)); 
4035                                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) { 
4036                                         /* fix scope id for comparing SPD */ 
4037                                         sin6
->sin6_addr
.s6_addr16
[1] = 0; 
4038                                         sin6
->sin6_scope_id 
= ntohs(ip6
->ip6_src
.s6_addr16
[1]); 
4041                         sin6 
= (struct sockaddr_in6 
*)&saidx
.dst
; 
4042                         if (sin6
->sin6_len 
== 0) { 
4043                                 sin6
->sin6_len 
= sizeof(*sin6
); 
4044                                 sin6
->sin6_family 
= AF_INET6
; 
4045                                 sin6
->sin6_port 
= IPSEC_PORT_ANY
; 
4046                                 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
, 
4047                                     sizeof(ip6
->ip6_dst
)); 
4048                                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) { 
4049                                         /* fix scope id for comparing SPD */ 
4050                                         sin6
->sin6_addr
.s6_addr16
[1] = 0; 
4051                                         sin6
->sin6_scope_id 
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]); 
4056                 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) { 
4058                          * IPsec processing is required, but no SA found. 
4059                          * I assume that key_acquire() had been called 
4060                          * to get/establish the SA. Here I discard 
4061                          * this packet because it is responsibility for 
4062                          * upper layer to retransmit the packet. 
4064                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
); 
4069                 /* validity check */ 
4071                         switch (ipsec_get_reqlevel(isr
)) { 
4072                         case IPSEC_LEVEL_USE
: 
4074                         case IPSEC_LEVEL_REQUIRE
: 
4075                                 /* must be not reached here. */ 
4076                                 panic("ipsec6_output_tunnel: no SA found, but required."); 
4081                  * If there is no valid SA, we give up to process. 
4082                  * see same place at ipsec4_output(). 
4084                 if (sav
->state 
!= SADB_SASTATE_MATURE
 
4085                     && sav
->state 
!= SADB_SASTATE_DYING
) { 
4086                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
); 
4091                 int must_be_last 
= 0; 
4093                 if ((error 
= ipsec6_output_tunnel_internal(state
, sav
, &must_be_last
)) != 0) { 
4097                 if (must_be_last 
&& isr
->next
) { 
4098                         ipseclog((LOG_ERR
, "ipsec6_output_tunnel: " 
4099                             "IPv4 must be outer layer, spi=%u\n", 
4100                             (u_int32_t
)ntohl(sav
->spi
))); 
4107                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
4113                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
4123 ipsec6_interface_output(struct ipsec_output_state 
*state
, ifnet_t interface
, u_char 
*nexthdrp
, struct mbuf 
*mprev
) 
4126         struct secasvar 
*sav 
= NULL
; 
4128         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
4130         if (state 
== NULL
) { 
4131                 panic("state == NULL in ipsec6_output"); 
4133         if (state
->m 
== NULL
) { 
4134                 panic("state->m == NULL in ipsec6_output"); 
4136         if (nexthdrp 
== NULL
) { 
4137                 panic("nexthdrp == NULL in ipsec6_output"); 
4139         if (mprev 
== NULL
) { 
4140                 panic("mprev == NULL in ipsec6_output"); 
4143         struct ip6_hdr 
*ip6 
= mtod(state
->m
, struct ip6_hdr 
*); 
4145         struct sockaddr_in6 src 
= {}; 
4146         src
.sin6_family 
= AF_INET6
; 
4147         src
.sin6_len 
= sizeof(src
); 
4148         memcpy(&src
.sin6_addr
, &ip6
->ip6_src
, sizeof(src
.sin6_addr
)); 
4150         struct sockaddr_in6 dst 
= {}; 
4151         dst
.sin6_family 
= AF_INET6
; 
4152         dst
.sin6_len 
= sizeof(dst
); 
4153         memcpy(&dst
.sin6_addr
, &ip6
->ip6_dst
, sizeof(dst
.sin6_addr
)); 
4155         sav 
= key_alloc_outbound_sav_for_interface(interface
, AF_INET6
, 
4156             (struct sockaddr 
*)&src
, 
4157             (struct sockaddr 
*)&dst
); 
4162         if (sav
->sah 
&& sav
->sah
->saidx
.mode 
== IPSEC_MODE_TUNNEL
) { 
4163                 if ((error 
= ipsec6_output_tunnel_internal(state
, sav
, NULL
)) != 0) { 
4167                 if ((error 
= ipsec6_output_trans_internal(state
, sav
, nexthdrp
, mprev
)) != 0) { 
4173                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
4179                 key_freesav(sav
, KEY_SADB_UNLOCKED
); 
4188  * Chop IP header and option off from the payload. 
4191 ipsec4_splithdr(struct mbuf 
*m
) 
4197         if (m
->m_len 
< sizeof(struct ip
)) { 
4198                 panic("ipsec4_splithdr: first mbuf too short, m_len %d, pkt_len %d, m_flag %x", m
->m_len
, m
->m_pkthdr
.len
, m
->m_flags
); 
4200         ip 
= mtod(m
, struct ip 
*); 
4202         hlen 
= _IP_VHL_HL(ip
->ip_vhl
) << 2; 
4204         hlen 
= ip
->ip_hl 
<< 2; 
4206         if (m
->m_len 
> hlen
) { 
4207                 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
);     /* MAC-OK */ 
4212                 M_COPY_PKTHDR(mh
, m
); 
4214                 m
->m_flags 
&= ~M_PKTHDR
; 
4215                 m_mchtype(m
, MT_DATA
); 
4221                 bcopy((caddr_t
)ip
, mtod(m
, caddr_t
), hlen
); 
4222         } else if (m
->m_len 
< hlen
) { 
4223                 m 
= m_pullup(m
, hlen
); 
4233 ipsec6_splithdr(struct mbuf 
*m
) 
4236         struct ip6_hdr 
*ip6
; 
4239         if (m
->m_len 
< sizeof(struct ip6_hdr
)) { 
4240                 panic("ipsec6_splithdr: first mbuf too short"); 
4242         ip6 
= mtod(m
, struct ip6_hdr 
*); 
4243         hlen 
= sizeof(struct ip6_hdr
); 
4244         if (m
->m_len 
> hlen
) { 
4245                 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
);     /* MAC-OK */ 
4250                 M_COPY_PKTHDR(mh
, m
); 
4252                 m
->m_flags 
&= ~M_PKTHDR
; 
4253                 m_mchtype(m
, MT_DATA
); 
4259                 bcopy((caddr_t
)ip6
, mtod(m
, caddr_t
), hlen
); 
4260         } else if (m
->m_len 
< hlen
) { 
4261                 m 
= m_pullup(m
, hlen
); 
4269 /* validate inbound IPsec tunnel packet. */ 
4271 ipsec4_tunnel_validate( 
4272         struct mbuf 
*m
,         /* no pullup permitted, m->m_len >= ip */ 
4275         struct secasvar 
*sav
, 
4276         sa_family_t 
*ifamily
) 
4278         u_int8_t nxt 
= nxt0 
& 0xff; 
4279         struct sockaddr_in 
*sin
; 
4280         struct sockaddr_in osrc
, odst
, i4src
, i4dst
; 
4281         struct sockaddr_in6 i6src
, i6dst
; 
4283         struct secpolicy 
*sp
; 
4286         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
4289         if (m
->m_len 
< sizeof(struct ip
)) { 
4290                 panic("too short mbuf on ipsec4_tunnel_validate"); 
4293         if (nxt 
!= IPPROTO_IPV4 
&& nxt 
!= IPPROTO_IPV6
) { 
4296         if (m
->m_pkthdr
.len 
< off 
+ sizeof(struct ip
)) { 
4299         /* do not decapsulate if the SA is for transport mode only */ 
4300         if (sav
->sah
->saidx
.mode 
== IPSEC_MODE_TRANSPORT
) { 
4304         oip 
= mtod(m
, struct ip 
*); 
4306         hlen 
= _IP_VHL_HL(oip
->ip_vhl
) << 2; 
4308         hlen 
= oip
->ip_hl 
<< 2; 
4310         if (hlen 
!= sizeof(struct ip
)) { 
4314         sin 
= (struct sockaddr_in 
*)&sav
->sah
->saidx
.dst
; 
4315         if (sin
->sin_family 
!= AF_INET
) { 
4318         if (bcmp(&oip
->ip_dst
, &sin
->sin_addr
, sizeof(oip
->ip_dst
)) != 0) { 
4322         if (sav
->sah
->ipsec_if 
!= NULL
) { 
4323                 // the ipsec interface SAs don't have a policies. 
4324                 if (nxt 
== IPPROTO_IPV4
) { 
4326                 } else if (nxt 
== IPPROTO_IPV6
) { 
4327                         *ifamily 
= AF_INET6
; 
4335         bzero(&osrc
, sizeof(osrc
)); 
4336         bzero(&odst
, sizeof(odst
)); 
4337         osrc
.sin_family 
= odst
.sin_family 
= AF_INET
; 
4338         osrc
.sin_len 
= odst
.sin_len 
= sizeof(struct sockaddr_in
); 
4339         osrc
.sin_addr 
= oip
->ip_src
; 
4340         odst
.sin_addr 
= oip
->ip_dst
; 
4342          * RFC2401 5.2.1 (b): (assume that we are using tunnel mode) 
4343          * - if the inner destination is multicast address, there can be 
4344          *   multiple permissible inner source address.  implementation 
4345          *   may want to skip verification of inner source address against 
4347          * - if the inner protocol is ICMP, the packet may be an error report 
4348          *   from routers on the other side of the VPN cloud (R in the 
4349          *   following diagram).  in this case, we cannot verify inner source 
4350          *   address against SPD selector. 
4351          *      me -- gw === gw -- R -- you 
4353          * we consider the first bullet to be users responsibility on SPD entry 
4354          * configuration (if you need to encrypt multicast traffic, set 
4355          * the source range of SPD selector to 0.0.0.0/0, or have explicit 
4356          * address ranges for possible senders). 
4357          * the second bullet is not taken care of (yet). 
4359          * therefore, we do not do anything special about inner source. 
4361         if (nxt 
== IPPROTO_IPV4
) { 
4362                 bzero(&i4src
, sizeof(struct sockaddr_in
)); 
4363                 bzero(&i4dst
, sizeof(struct sockaddr_in
)); 
4364                 i4src
.sin_family 
= i4dst
.sin_family 
= *ifamily 
= AF_INET
; 
4365                 i4src
.sin_len 
= i4dst
.sin_len 
= sizeof(struct sockaddr_in
); 
4366                 m_copydata(m
, off 
+ offsetof(struct ip
, ip_src
), sizeof(i4src
.sin_addr
), 
4367                     (caddr_t
)&i4src
.sin_addr
); 
4368                 m_copydata(m
, off 
+ offsetof(struct ip
, ip_dst
), sizeof(i4dst
.sin_addr
), 
4369                     (caddr_t
)&i4dst
.sin_addr
); 
4370                 sp 
= key_gettunnel((struct sockaddr 
*)&osrc
, (struct sockaddr 
*)&odst
, 
4371                     (struct sockaddr 
*)&i4src
, (struct sockaddr 
*)&i4dst
); 
4372         } else if (nxt 
== IPPROTO_IPV6
) { 
4373                 bzero(&i6src
, sizeof(struct sockaddr_in6
)); 
4374                 bzero(&i6dst
, sizeof(struct sockaddr_in6
)); 
4375                 i6src
.sin6_family 
= i6dst
.sin6_family 
= *ifamily 
= AF_INET6
; 
4376                 i6src
.sin6_len 
= i6dst
.sin6_len 
= sizeof(struct sockaddr_in6
); 
4377                 m_copydata(m
, off 
+ offsetof(struct ip6_hdr
, ip6_src
), sizeof(i6src
.sin6_addr
), 
4378                     (caddr_t
)&i6src
.sin6_addr
); 
4379                 m_copydata(m
, off 
+ offsetof(struct ip6_hdr
, ip6_dst
), sizeof(i6dst
.sin6_addr
), 
4380                     (caddr_t
)&i6dst
.sin6_addr
); 
4381                 sp 
= key_gettunnel((struct sockaddr 
*)&osrc
, (struct sockaddr 
*)&odst
, 
4382                     (struct sockaddr 
*)&i6src
, (struct sockaddr 
*)&i6dst
); 
4384                 return 0;       /* unsupported family */ 
4390         key_freesp(sp
, KEY_SADB_UNLOCKED
); 
4395 /* validate inbound IPsec tunnel packet. */ 
4397 ipsec6_tunnel_validate( 
4398         struct mbuf 
*m
,         /* no pullup permitted, m->m_len >= ip */ 
4401         struct secasvar 
*sav
, 
4402         sa_family_t 
*ifamily
) 
4404         u_int8_t nxt 
= nxt0 
& 0xff; 
4405         struct sockaddr_in6 
*sin6
; 
4406         struct sockaddr_in i4src
, i4dst
; 
4407         struct sockaddr_in6 osrc
, odst
, i6src
, i6dst
; 
4408         struct secpolicy 
*sp
; 
4409         struct ip6_hdr 
*oip6
; 
4411         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
4414         if (m
->m_len 
< sizeof(struct ip6_hdr
)) { 
4415                 panic("too short mbuf on ipsec6_tunnel_validate"); 
4418         if (nxt 
== IPPROTO_IPV4
) { 
4419                 if (m
->m_pkthdr
.len 
< off 
+ sizeof(struct ip
)) { 
4420                         ipseclog((LOG_NOTICE
, "ipsec6_tunnel_validate pkthdr %d off %d ip6hdr %zu", m
->m_pkthdr
.len
, off
, sizeof(struct ip6_hdr
))); 
4423         } else if (nxt 
== IPPROTO_IPV6
) { 
4424                 if (m
->m_pkthdr
.len 
< off 
+ sizeof(struct ip6_hdr
)) { 
4425                         ipseclog((LOG_NOTICE
, "ipsec6_tunnel_validate pkthdr %d off %d ip6hdr %zu", m
->m_pkthdr
.len
, off
, sizeof(struct ip6_hdr
))); 
4429                 ipseclog((LOG_NOTICE
, "ipsec6_tunnel_validate invalid nxt(%u) protocol", nxt
)); 
4433         /* do not decapsulate if the SA is for transport mode only */ 
4434         if (sav
->sah
->saidx
.mode 
== IPSEC_MODE_TRANSPORT
) { 
4438         oip6 
= mtod(m
, struct ip6_hdr 
*); 
4439         /* AF_INET should be supported, but at this moment we don't. */ 
4440         sin6 
= (struct sockaddr_in6 
*)&sav
->sah
->saidx
.dst
; 
4441         if (sin6
->sin6_family 
!= AF_INET6
) { 
4444         if (!IN6_ARE_ADDR_EQUAL(&oip6
->ip6_dst
, &sin6
->sin6_addr
)) { 
4448         if (sav
->sah
->ipsec_if 
!= NULL
) { 
4449                 // the ipsec interface SAs don't have a policies. 
4450                 if (nxt 
== IPPROTO_IPV4
) { 
4452                 } else if (nxt 
== IPPROTO_IPV6
) { 
4453                         *ifamily 
= AF_INET6
; 
4461         bzero(&osrc
, sizeof(osrc
)); 
4462         bzero(&odst
, sizeof(odst
)); 
4463         osrc
.sin6_family 
= odst
.sin6_family 
= AF_INET6
; 
4464         osrc
.sin6_len 
= odst
.sin6_len 
= sizeof(struct sockaddr_in6
); 
4465         osrc
.sin6_addr 
= oip6
->ip6_src
; 
4466         odst
.sin6_addr 
= oip6
->ip6_dst
; 
4469          * regarding to inner source address validation, see a long comment 
4470          * in ipsec4_tunnel_validate. 
4473         if (nxt 
== IPPROTO_IPV4
) { 
4474                 bzero(&i4src
, sizeof(struct sockaddr_in
)); 
4475                 bzero(&i4dst
, sizeof(struct sockaddr_in
)); 
4476                 i4src
.sin_family 
= i4dst
.sin_family 
= *ifamily 
= AF_INET
; 
4477                 i4src
.sin_len 
= i4dst
.sin_len 
= sizeof(struct sockaddr_in
); 
4478                 m_copydata(m
, off 
+ offsetof(struct ip
, ip_src
), sizeof(i4src
.sin_addr
), 
4479                     (caddr_t
)&i4src
.sin_addr
); 
4480                 m_copydata(m
, off 
+ offsetof(struct ip
, ip_dst
), sizeof(i4dst
.sin_addr
), 
4481                     (caddr_t
)&i4dst
.sin_addr
); 
4482                 sp 
= key_gettunnel((struct sockaddr 
*)&osrc
, (struct sockaddr 
*)&odst
, 
4483                     (struct sockaddr 
*)&i4src
, (struct sockaddr 
*)&i4dst
); 
4484         } else if (nxt 
== IPPROTO_IPV6
) { 
4485                 bzero(&i6src
, sizeof(struct sockaddr_in6
)); 
4486                 bzero(&i6dst
, sizeof(struct sockaddr_in6
)); 
4487                 i6src
.sin6_family 
= i6dst
.sin6_family 
= *ifamily 
= AF_INET6
; 
4488                 i6src
.sin6_len 
= i6dst
.sin6_len 
= sizeof(struct sockaddr_in6
); 
4489                 m_copydata(m
, off 
+ offsetof(struct ip6_hdr
, ip6_src
), sizeof(i6src
.sin6_addr
), 
4490                     (caddr_t
)&i6src
.sin6_addr
); 
4491                 m_copydata(m
, off 
+ offsetof(struct ip6_hdr
, ip6_dst
), sizeof(i6dst
.sin6_addr
), 
4492                     (caddr_t
)&i6dst
.sin6_addr
); 
4493                 sp 
= key_gettunnel((struct sockaddr 
*)&osrc
, (struct sockaddr 
*)&odst
, 
4494                     (struct sockaddr 
*)&i6src
, (struct sockaddr 
*)&i6dst
); 
4496                 return 0;       /* unsupported family */ 
4499          * when there is no suitable inbound policy for the packet of the ipsec 
4500          * tunnel mode, the kernel never decapsulate the tunneled packet 
4501          * as the ipsec tunnel mode even when the system wide policy is "none". 
4502          * then the kernel leaves the generic tunnel module to process this 
4503          * packet.  if there is no rule of the generic tunnel, the packet 
4504          * is rejected and the statistics will be counted up. 
4509         key_freesp(sp
, KEY_SADB_UNLOCKED
); 
4515  * Make a mbuf chain for encryption. 
4516  * If the original mbuf chain contains a mbuf with a cluster, 
4517  * allocate a new cluster and copy the data to the new cluster. 
4518  * XXX: this hack is inefficient, but is necessary to handle cases 
4519  * of TCP retransmission... 
4522 ipsec_copypkt(struct mbuf 
*m
) 
4524         struct mbuf 
*n
, **mpp
, *mnew
; 
4526         for (n 
= m
, mpp 
= &m
; n
; n 
= n
->m_next
) { 
4527                 if (n
->m_flags 
& M_EXT
) { 
4529                          * Make a copy only if there are more than one references 
4531                          * XXX: is this approach effective? 
4534                                 m_get_ext_free(n
) != NULL 
|| 
4535                                 m_mclhasreference(n
) 
4540                                 if (n
->m_flags 
& M_PKTHDR
) { 
4541                                         MGETHDR(mnew
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */ 
4545                                         M_COPY_PKTHDR(mnew
, n
); 
4547                                         MGET(mnew
, M_DONTWAIT
, MT_DATA
); 
4556                                  * Copy data. If we don't have enough space to 
4557                                  * store the whole data, allocate a cluster 
4558                                  * or additional mbufs. 
4559                                  * XXX: we don't use m_copyback(), since the 
4560                                  * function does not use clusters and thus is 
4569                                         if (remain 
<= (mm
->m_flags 
& M_PKTHDR 
? MHLEN 
: MLEN
)) { 
4571                                         } else { /* allocate a cluster */ 
4572                                                 MCLGET(mm
, M_DONTWAIT
); 
4573                                                 if (!(mm
->m_flags 
& M_EXT
)) { 
4577                                                 len 
= remain 
< MCLBYTES 
? 
4581                                         bcopy(n
->m_data 
+ copied
, mm
->m_data
, 
4588                                         if (remain 
<= 0) { /* completed? */ 
4592                                         /* need another mbuf */ 
4593                                         MGETHDR(mn
, M_DONTWAIT
, MT_HEADER
);     /* XXXMAC: tags copied next time in loop? */ 
4597                                         mn
->m_pkthdr
.rcvif 
= NULL
; 
4603                                 mm
->m_next 
= m_free(n
); 
4622  * Tags are allocated as mbufs for now, since our minimum size is MLEN, we 
4623  * should make use of up to that much space. 
4625 #define IPSEC_TAG_HEADER \ 
4628         struct socket                   
*socket
; 
4629         u_int32_t                               history_count
; 
4630         struct ipsec_history    history
[]; 
4631 #if __arm__ && (__BIGGEST_ALIGNMENT__ > 4) 
4632 /* For the newer ARMv7k ABI where 64-bit types are 64-bit aligned, but pointers 
4634  * Aligning to 64-bit since we case to m_tag which is 64-bit aligned. 
4636 } __attribute__ ((aligned(8))); 
4641 #define IPSEC_TAG_SIZE          (MLEN - sizeof(struct m_tag)) 
4642 #define IPSEC_TAG_HDR_SIZE      (offsetof(struct ipsec_tag, history[0])) 
4643 #define IPSEC_HISTORY_MAX       ((IPSEC_TAG_SIZE - IPSEC_TAG_HDR_SIZE) / \ 
4644                                                          sizeof(struct ipsec_history)) 
4646 static struct ipsec_tag 
* 
4652         /* Check if the tag already exists */ 
4653         tag 
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
); 
4656                 struct ipsec_tag        
*itag
; 
4658                 /* Allocate a tag */ 
4659                 tag 
= m_tag_create(KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, 
4660                     IPSEC_TAG_SIZE
, M_DONTWAIT
, m
); 
4663                         itag 
= (struct ipsec_tag
*)(tag 
+ 1); 
4665                         itag
->history_count 
= 0; 
4667                         m_tag_prepend(m
, tag
); 
4671         return tag 
? (struct ipsec_tag
*)(tag 
+ 1) : NULL
; 
4674 static struct ipsec_tag 
* 
4680         tag 
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
); 
4682         return tag 
? (struct ipsec_tag
*)(tag 
+ 1) : NULL
; 
4691         tag 
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
); 
4694                 m_tag_delete(m
, tag
); 
4698 /* if the aux buffer is unnecessary, nuke it. */ 
4702         struct ipsec_tag        
*itag
) 
4704         if (itag 
&& itag
->socket 
== NULL 
&& itag
->history_count 
== 0) { 
4705                 m_tag_delete(m
, ((struct m_tag
*)itag
) - 1); 
4710 ipsec_setsocket(struct mbuf 
*m
, struct socket 
*so
) 
4712         struct ipsec_tag        
*tag
; 
4714         /* if so == NULL, don't insist on getting the aux mbuf */ 
4716                 tag 
= ipsec_addaux(m
); 
4721                 tag 
= ipsec_findaux(m
); 
4725                 ipsec_optaux(m
, tag
); 
4731 ipsec_getsocket(struct mbuf 
*m
) 
4733         struct ipsec_tag        
*itag
; 
4735         itag 
= ipsec_findaux(m
); 
4737                 return itag
->socket
; 
4749         struct ipsec_tag                
*itag
; 
4750         struct ipsec_history    
*p
; 
4751         itag 
= ipsec_addaux(m
); 
4755         if (itag
->history_count 
== IPSEC_HISTORY_MAX
) { 
4756                 return ENOSPC
;  /* XXX */ 
4758         p 
= &itag
->history
[itag
->history_count
]; 
4759         itag
->history_count
++; 
4761         bzero(p
, sizeof(*p
)); 
4762         p
->ih_proto 
= proto
; 
4768 struct ipsec_history 
* 
4773         struct ipsec_tag        
*itag
; 
4775         itag 
= ipsec_findaux(m
); 
4779         if (itag
->history_count 
== 0) { 
4783                 *lenp 
= (int)(itag
->history_count 
* sizeof(struct ipsec_history
)); 
4785         return itag
->history
; 
4792         struct ipsec_tag        
*itag
; 
4794         itag 
= ipsec_findaux(m
); 
4796                 itag
->history_count 
= 0; 
4798         ipsec_optaux(m
, itag
); 
4801 __private_extern__ boolean_t
 
4802 ipsec_send_natt_keepalive( 
4803         struct secasvar 
*sav
) 
4805         struct mbuf 
*m 
= NULL
; 
4807         int keepalive_interval 
= natt_keepalive_interval
; 
4809         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
4810         lck_mtx_lock(sadb_mutex
); 
4812         if (((esp_udp_encap_port 
& 0xFFFF) == 0 && sav
->natt_encapsulated_src_port 
== 0) || sav
->remote_ike_port 
== 0) { 
4813                 lck_mtx_unlock(sadb_mutex
); 
4817         if (sav
->natt_interval 
!= 0) { 
4818                 keepalive_interval 
= (int)sav
->natt_interval
; 
4821         // natt timestamp may have changed... reverify 
4822         if ((natt_now 
- sav
->natt_last_activity
) < keepalive_interval
) { 
4823                 lck_mtx_unlock(sadb_mutex
); 
4827         if (sav
->flags 
& SADB_X_EXT_ESP_KEEPALIVE
) { 
4828                 lck_mtx_unlock(sadb_mutex
); 
4829                 return FALSE
; // don't send these from the kernel 
4832         lck_mtx_unlock(sadb_mutex
); 
4834         m 
= m_gethdr(M_NOWAIT
, MT_DATA
); 
4839         lck_mtx_lock(sadb_mutex
); 
4840         if (sav
->sah
->saidx
.dst
.ss_family 
== AF_INET
) { 
4841                 struct ip_out_args ipoa 
= {}; 
4842                 struct route ro 
= {}; 
4844                 ipoa
.ipoa_boundif 
= IFSCOPE_NONE
; 
4845                 ipoa
.ipoa_flags 
= IPOAF_SELECT_SRCIF
; 
4846                 ipoa
.ipoa_sotc 
= SO_TC_UNSPEC
; 
4847                 ipoa
.ipoa_netsvctype 
= _NET_SERVICE_TYPE_UNSPEC
; 
4849                 struct ip 
*ip 
= (__typeof__(ip
))m_mtod(m
); 
4852                  * Type 2: a UDP packet complete with IP header. 
4853                  * We must do this because UDP output requires 
4854                  * an inpcb which we don't have. UDP packet 
4855                  * contains one byte payload. The byte is set 
4858                 struct udphdr 
*uh 
= (__typeof__(uh
))(void *)((char *)m_mtod(m
) + sizeof(*ip
)); 
4859                 m
->m_len 
= sizeof(struct udpiphdr
) + 1; 
4860                 bzero(m_mtod(m
), m
->m_len
); 
4861                 m
->m_pkthdr
.len 
= m
->m_len
; 
4863                 ip
->ip_len 
= (u_short
)m
->m_len
; 
4864                 ip
->ip_ttl 
= (u_char
)ip_defttl
; 
4865                 ip
->ip_p 
= IPPROTO_UDP
; 
4866                 if (sav
->sah
->dir 
!= IPSEC_DIR_INBOUND
) { 
4867                         ip
->ip_src 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
; 
4868                         ip
->ip_dst 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
; 
4870                         ip
->ip_src 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
; 
4871                         ip
->ip_dst 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
; 
4873                 if (sav
->natt_encapsulated_src_port 
!= 0) { 
4874                         uh
->uh_sport 
= (u_short
)sav
->natt_encapsulated_src_port
; 
4876                         uh
->uh_sport 
= htons((u_short
)esp_udp_encap_port
); 
4878                 uh
->uh_sport 
= htons((u_short
)esp_udp_encap_port
); 
4879                 uh
->uh_dport 
= htons(sav
->remote_ike_port
); 
4880                 uh
->uh_ulen 
= htons(1 + sizeof(*uh
)); 
4882                 *(u_int8_t
*)((char*)m_mtod(m
) + sizeof(*ip
) + sizeof(*uh
)) = 0xFF; 
4884                 if (ROUTE_UNUSABLE(&sav
->sah
->sa_route
) || 
4885                     rt_key(sav
->sah
->sa_route
.ro_rt
)->sa_family 
!= AF_INET
) { 
4886                         ROUTE_RELEASE(&sav
->sah
->sa_route
); 
4889                 route_copyout(&ro
, (struct route 
*)&sav
->sah
->sa_route
, sizeof(struct route
)); 
4890                 lck_mtx_unlock(sadb_mutex
); 
4892                 necp_mark_packet_as_keepalive(m
, TRUE
); 
4893                 error 
= ip_output(m
, NULL
, &ro
, IP_OUTARGS 
| IP_NOIPSEC
, NULL
, &ipoa
); 
4895                 lck_mtx_lock(sadb_mutex
); 
4896                 route_copyin(&ro
, (struct route 
*)&sav
->sah
->sa_route
, sizeof(struct route
)); 
4897         } else if (sav
->sah
->saidx
.dst
.ss_family 
== AF_INET6
) { 
4898                 struct ip6_out_args ip6oa 
= {}; 
4899                 struct route_in6 ro6 
= {}; 
4901                 ip6oa
.ip6oa_flowadv
.code 
= 0; 
4902                 ip6oa
.ip6oa_flags 
= IP6OAF_SELECT_SRCIF 
| IP6OAF_BOUND_SRCADDR
; 
4903                 if (sav
->sah
->outgoing_if
) { 
4904                         ip6oa
.ip6oa_boundif 
= sav
->sah
->outgoing_if
; 
4905                         ip6oa
.ip6oa_flags 
|= IP6OAF_BOUND_IF
; 
4908                 struct ip6_hdr 
*ip6 
= (__typeof__(ip6
))m_mtod(m
); 
4911                  * Type 2: a UDP packet complete with IPv6 header. 
4912                  * We must do this because UDP output requires 
4913                  * an inpcb which we don't have. UDP packet 
4914                  * contains one byte payload. The byte is set 
4917                 struct udphdr 
*uh 
= (__typeof__(uh
))(void *)((char *)m_mtod(m
) + sizeof(*ip6
)); 
4918                 m
->m_len 
= sizeof(struct udphdr
) + sizeof(struct ip6_hdr
) + 1; 
4919                 bzero(m_mtod(m
), m
->m_len
); 
4920                 m
->m_pkthdr
.len 
= m
->m_len
; 
4923                 ip6
->ip6_vfc 
&= ~IPV6_VERSION_MASK
; 
4924                 ip6
->ip6_vfc 
|= IPV6_VERSION
; 
4925                 ip6
->ip6_nxt 
= IPPROTO_UDP
; 
4926                 ip6
->ip6_hlim 
= (u_int8_t
)ip6_defhlim
; 
4927                 ip6
->ip6_plen 
= htons(sizeof(struct udphdr
) + 1); 
4928                 if (sav
->sah
->dir 
!= IPSEC_DIR_INBOUND
) { 
4929                         ip6
->ip6_src 
= ((struct sockaddr_in6 
*)&sav
->sah
->saidx
.src
)->sin6_addr
; 
4930                         ip6
->ip6_dst 
= ((struct sockaddr_in6 
*)&sav
->sah
->saidx
.dst
)->sin6_addr
; 
4932                         ip6
->ip6_src 
= ((struct sockaddr_in6 
*)&sav
->sah
->saidx
.dst
)->sin6_addr
; 
4933                         ip6
->ip6_dst 
= ((struct sockaddr_in6 
*)&sav
->sah
->saidx
.src
)->sin6_addr
; 
4936                 if (IN6_IS_SCOPE_EMBED(&ip6
->ip6_src
)) { 
4937                         ip6
->ip6_src
.s6_addr16
[1] = 0; 
4939                 if (IN6_IS_SCOPE_EMBED(&ip6
->ip6_dst
)) { 
4940                         ip6
->ip6_dst
.s6_addr16
[1] = 0; 
4943                 if (sav
->natt_encapsulated_src_port 
!= 0) { 
4944                         uh
->uh_sport 
= (u_short
)sav
->natt_encapsulated_src_port
; 
4946                         uh
->uh_sport 
= htons((u_short
)esp_udp_encap_port
); 
4948                 uh
->uh_dport 
= htons(sav
->remote_ike_port
); 
4949                 uh
->uh_ulen 
= htons(1 + sizeof(*uh
)); 
4950                 *(u_int8_t
*)((char*)m_mtod(m
) + sizeof(*ip6
) + sizeof(*uh
)) = 0xFF; 
4951                 uh
->uh_sum 
= in6_pseudo(&ip6
->ip6_src
, &ip6
->ip6_dst
, htonl(ntohs(uh
->uh_ulen
) + IPPROTO_UDP
)); 
4952                 m
->m_pkthdr
.csum_flags 
= (CSUM_UDPIPV6 
| CSUM_ZERO_INVERT
); 
4953                 m
->m_pkthdr
.csum_data 
= offsetof(struct udphdr
, uh_sum
); 
4955                 if (ROUTE_UNUSABLE(&sav
->sah
->sa_route
) || 
4956                     rt_key(sav
->sah
->sa_route
.ro_rt
)->sa_family 
!= AF_INET6
) { 
4957                         ROUTE_RELEASE(&sav
->sah
->sa_route
); 
4960                 route_copyout((struct route 
*)&ro6
, (struct route 
*)&sav
->sah
->sa_route
, sizeof(struct route_in6
)); 
4961                 lck_mtx_unlock(sadb_mutex
); 
4963                 necp_mark_packet_as_keepalive(m
, TRUE
); 
4964                 error 
= ip6_output(m
, NULL
, &ro6
, IPV6_OUTARGS
, NULL
, NULL
, &ip6oa
); 
4966                 lck_mtx_lock(sadb_mutex
); 
4967                 route_copyin((struct route 
*)&ro6
, (struct route 
*)&sav
->sah
->sa_route
, sizeof(struct route_in6
)); 
4969                 ipseclog((LOG_ERR
, "nat keepalive: invalid address family %u\n", sav
->sah
->saidx
.dst
.ss_family
)); 
4970                 lck_mtx_unlock(sadb_mutex
); 
4976                 sav
->natt_last_activity 
= natt_now
; 
4977                 lck_mtx_unlock(sadb_mutex
); 
4981         lck_mtx_unlock(sadb_mutex
); 
4985 __private_extern__ 
bool 
4986 ipsec_fill_offload_frame(ifnet_t ifp
, 
4987     struct secasvar 
*sav
, 
4988     struct ifnet_keepalive_offload_frame 
*frame
, 
4989     size_t frame_data_offset
) 
4991         u_int8_t 
*data 
= NULL
; 
4992         struct ip 
*ip 
= NULL
; 
4993         struct udphdr 
*uh 
= NULL
; 
4995         if (sav 
== NULL 
|| sav
->sah 
== NULL 
|| frame 
== NULL 
|| 
4996             (ifp 
!= NULL 
&& ifp
->if_index 
!= sav
->sah
->outgoing_if
) || 
4997             sav
->sah
->saidx
.dst
.ss_family 
!= AF_INET 
|| 
4998             !(sav
->flags 
& SADB_X_EXT_NATT
) || 
4999             !(sav
->flags 
& SADB_X_EXT_NATT_KEEPALIVE
) || 
5000             !(sav
->flags 
& SADB_X_EXT_NATT_KEEPALIVE_OFFLOAD
) || 
5001             sav
->flags 
& SADB_X_EXT_ESP_KEEPALIVE 
|| 
5002             ((esp_udp_encap_port 
& 0xFFFF) == 0 && sav
->natt_encapsulated_src_port 
== 0) || 
5003             sav
->remote_ike_port 
== 0 || 
5004             (natt_keepalive_interval 
== 0 && sav
->natt_interval 
== 0 && sav
->natt_offload_interval 
== 0)) { 
5005                 /* SA is not eligible for keepalive offload on this interface */ 
5009         if (frame_data_offset 
+ sizeof(struct udpiphdr
) + 1 > 
5010             IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE
) { 
5011                 /* Not enough room in this data frame */ 
5016         ip 
= (__typeof__(ip
))(void *)(data 
+ frame_data_offset
); 
5017         uh 
= (__typeof__(uh
))(void *)(data 
+ frame_data_offset 
+ sizeof(*ip
)); 
5019         frame
->length 
= (u_int8_t
)(frame_data_offset 
+ sizeof(struct udpiphdr
) + 1); 
5020         frame
->type 
= IFNET_KEEPALIVE_OFFLOAD_FRAME_IPSEC
; 
5021         frame
->ether_type 
= IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV4
; 
5023         bzero(data
, IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE
); 
5025         ip
->ip_v 
= IPVERSION
; 
5026         ip
->ip_hl 
= sizeof(struct ip
) >> 2; 
5027         ip
->ip_off 
&= htons(~IP_OFFMASK
); 
5028         ip
->ip_off 
&= htons(~IP_MF
); 
5029         switch (ip4_ipsec_dfbit
) { 
5030         case 0:         /* clear DF bit */ 
5031                 ip
->ip_off 
&= htons(~IP_DF
); 
5033         case 1:         /* set DF bit */ 
5034                 ip
->ip_off 
|= htons(IP_DF
); 
5036         default:                /* copy DF bit */ 
5039         ip
->ip_len 
= htons(sizeof(struct udpiphdr
) + 1); 
5040         if (rfc6864 
&& IP_OFF_IS_ATOMIC(htons(ip
->ip_off
))) { 
5043                 ip
->ip_id 
= ip_randomid(); 
5045         ip
->ip_ttl 
= (u_char
)ip_defttl
; 
5046         ip
->ip_p 
= IPPROTO_UDP
; 
5048         if (sav
->sah
->dir 
!= IPSEC_DIR_INBOUND
) { 
5049                 ip
->ip_src 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
; 
5050                 ip
->ip_dst 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
; 
5052                 ip
->ip_src 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
; 
5053                 ip
->ip_dst 
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
; 
5055         ip
->ip_sum 
= in_cksum_hdr_opt(ip
); 
5056         /* Fill out the UDP header */ 
5057         if (sav
->natt_encapsulated_src_port 
!= 0) { 
5058                 uh
->uh_sport 
= (u_short
)sav
->natt_encapsulated_src_port
; 
5060                 uh
->uh_sport 
= htons((u_short
)esp_udp_encap_port
); 
5062         uh
->uh_dport 
= htons(sav
->remote_ike_port
); 
5063         uh
->uh_ulen 
= htons(1 + sizeof(*uh
)); 
5065         *(u_int8_t
*)(data 
+ frame_data_offset 
+ sizeof(*ip
) + sizeof(*uh
)) = 0xFF; 
5067         if (sav
->natt_offload_interval 
!= 0) { 
5068                 frame
->interval 
= sav
->natt_offload_interval
; 
5069         } else if (sav
->natt_interval 
!= 0) { 
5070                 frame
->interval 
= sav
->natt_interval
; 
5072                 frame
->interval 
= (u_int16_t
)natt_keepalive_interval
; 
5078 sysctl_ipsec_wake_packet SYSCTL_HANDLER_ARGS
 
5080  #pragma unused(oidp, arg1, arg2) 
5081         if (req
->newptr 
!= USER_ADDR_NULL
) { 
5082                 ipseclog((LOG_ERR
, "ipsec: invalid parameters")); 
5086         struct proc 
*p 
= current_proc(); 
5088                 uid_t uid 
= kauth_cred_getuid(proc_ucred(p
)); 
5089                 if (uid 
!= 0 && priv_check_cred(kauth_cred_get(), PRIV_NET_PRIVILEGED_IPSEC_WAKE_PACKET
, 0) != 0) { 
5090                         ipseclog((LOG_ERR
, "process does not hold necessary entitlement to get ipsec wake packet")); 
5094                 int result 
= sysctl_io_opaque(req
, &ipsec_wake_pkt
, sizeof(ipsec_wake_pkt
), NULL
); 
5096                 ipseclog((LOG_NOTICE
, "%s: uuid %s spi %u seq %u len %u result %d", 
5098                     ipsec_wake_pkt
.wake_uuid
, 
5099                     ipsec_wake_pkt
.wake_pkt_spi
, 
5100                     ipsec_wake_pkt
.wake_pkt_seq
, 
5101                     ipsec_wake_pkt
.wake_pkt_len
, 
5110 SYSCTL_PROC(_net_link_generic_system
, OID_AUTO
, ipsec_wake_pkt
, CTLTYPE_STRUCT 
| CTLFLAG_RD 
| 
5111     CTLFLAG_LOCKED
, 0, 0, &sysctl_ipsec_wake_packet
, "S,ipsec wake packet", ""); 
5114 ipsec_save_wake_packet(struct mbuf 
*wake_mbuf
, u_int32_t spi
, u_int32_t seq
) 
5116         if (wake_mbuf 
== NULL
) { 
5117                 ipseclog((LOG_ERR
, "ipsec: bad wake packet")); 
5121         lck_mtx_lock(sadb_mutex
); 
5122         if (__probable(!ipsec_save_wake_pkt
)) { 
5126         u_int16_t max_len 
= (wake_mbuf
->m_pkthdr
.len 
> IPSEC_MAX_WAKE_PKT_LEN
) ? IPSEC_MAX_WAKE_PKT_LEN 
: (u_int16_t
)wake_mbuf
->m_pkthdr
.len
; 
5127         m_copydata(wake_mbuf
, 0, max_len
, (void *)ipsec_wake_pkt
.wake_pkt
); 
5128         ipsec_wake_pkt
.wake_pkt_len 
= max_len
; 
5130         ipsec_wake_pkt
.wake_pkt_spi 
= spi
; 
5131         ipsec_wake_pkt
.wake_pkt_seq 
= seq
; 
5133         ipseclog((LOG_NOTICE
, "%s: uuid %s spi %u seq %u len %u", 
5135             ipsec_wake_pkt
.wake_uuid
, 
5136             ipsec_wake_pkt
.wake_pkt_spi
, 
5137             ipsec_wake_pkt
.wake_pkt_seq
, 
5138             ipsec_wake_pkt
.wake_pkt_len
)); 
5140         struct kev_msg ev_msg
; 
5141         bzero(&ev_msg
, sizeof(ev_msg
)); 
5143         ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
5144         ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
5145         ev_msg
.kev_subclass     
= KEV_IPSEC_SUBCLASS
; 
5146         ev_msg
.event_code       
= KEV_IPSEC_WAKE_PACKET
; 
5148         struct ipsec_wake_pkt_event_data event_data
; 
5149         strlcpy(event_data
.wake_uuid
, ipsec_wake_pkt
.wake_uuid
, sizeof(event_data
.wake_uuid
)); 
5150         ev_msg
.dv
[0].data_ptr           
= &event_data
; 
5151         ev_msg
.dv
[0].data_length        
= sizeof(event_data
); 
5153         int result 
= kev_post_msg(&ev_msg
); 
5155                 os_log_error(OS_LOG_DEFAULT
, "%s: kev_post_msg() failed with error %d for wake uuid %s", 
5156                     __func__
, result
, ipsec_wake_pkt
.wake_uuid
); 
5159         ipsec_save_wake_pkt 
= false; 
5161         lck_mtx_unlock(sadb_mutex
); 
5166 ipsec_get_local_ports(void) 
5171         static uint8_t port_bitmap
[bitstr_size(IP_PORTRANGE_SIZE
)]; 
5173         error 
= ifnet_list_get_all(IFNET_FAMILY_IPSEC
, &ifp_list
, &count
); 
5175                 os_log_error(OS_LOG_DEFAULT
, "%s: ifnet_list_get_all() failed %d", 
5179         for (i 
= 0; i 
< count
; i
++) { 
5180                 ifnet_t ifp 
= ifp_list
[i
]; 
5183                  * Get all the TCP and UDP ports for IPv4 and IPv6 
5185                 error 
= ifnet_get_local_ports_extended(ifp
, PF_UNSPEC
, 
5186                     IFNET_GET_LOCAL_PORTS_WILDCARDOK 
| 
5187                     IFNET_GET_LOCAL_PORTS_NOWAKEUPOK 
| 
5188                     IFNET_GET_LOCAL_PORTS_ANYTCPSTATEOK
, 
5191                         os_log_error(OS_LOG_DEFAULT
, "%s: ifnet_get_local_ports_extended(%s) failed %d", 
5192                             __func__
, if_name(ifp
), error
); 
5195         ifnet_list_free(ifp_list
); 
5199 ipsec_sleep_wake_handler(void *target
, void *refCon
, UInt32 messageType
, 
5200     void *provider
, void *messageArgument
, vm_size_t argSize
) 
5202 #pragma unused(target, refCon, provider, messageArgument, argSize) 
5203         switch (messageType
) { 
5204         case kIOMessageSystemWillSleep
: 
5206                 ipsec_get_local_ports(); 
5207                 ipsec_save_wake_pkt 
= false; 
5208                 memset(&ipsec_wake_pkt
, 0, sizeof(ipsec_wake_pkt
)); 
5209                 IOPMCopySleepWakeUUIDKey(ipsec_wake_pkt
.wake_uuid
, 
5210                     sizeof(ipsec_wake_pkt
.wake_uuid
)); 
5211                 ipseclog((LOG_NOTICE
, 
5212                     "ipsec: system will sleep, uuid: %s", ipsec_wake_pkt
.wake_uuid
)); 
5215         case kIOMessageSystemHasPoweredOn
: 
5217                 char wake_reason
[128] = {0}; 
5218                 size_t size 
= sizeof(wake_reason
); 
5219                 if (kernel_sysctlbyname("kern.wakereason", wake_reason
, &size
, NULL
, 0) == 0) { 
5220                         if (strnstr(wake_reason
, "wlan", size
) == 0 || 
5221                             strnstr(wake_reason
, "WL.OutboxNotEmpty", size
) == 0 || 
5222                             strnstr(wake_reason
, "baseband", size
) == 0 || 
5223                             strnstr(wake_reason
, "bluetooth", size
) == 0 || 
5224                             strnstr(wake_reason
, "BT.OutboxNotEmpty", size
) == 0) { 
5225                                 ipsec_save_wake_pkt 
= true; 
5226                                 ipseclog((LOG_NOTICE
, 
5227                                     "ipsec: system has powered on, uuid: %s reason %s", ipsec_wake_pkt
.wake_uuid
, wake_reason
)); 
5236         return IOPMAckImplied
; 
5240 ipsec_monitor_sleep_wake(void) 
5242         LCK_MTX_ASSERT(sadb_mutex
, LCK_MTX_ASSERT_OWNED
); 
5244         if (sleep_wake_handle 
== NULL
) { 
5245                 sleep_wake_handle 
= registerSleepWakeInterest(ipsec_sleep_wake_handler
, 
5247                 if (sleep_wake_handle 
!= NULL
) { 
5249                             "ipsec: monitoring sleep wake"));