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"));