2 * Copyright (c) 2008-2012 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>
79 #include <kern/locks.h>
80 #include <sys/kauth.h>
81 #include <libkern/OSAtomic.h>
84 #include <net/route.h>
86 #include <netinet/in.h>
87 #include <netinet/in_systm.h>
88 #include <netinet/ip.h>
89 #include <netinet/ip_var.h>
90 #include <netinet/in_var.h>
91 #include <netinet/udp.h>
92 #include <netinet/udp_var.h>
93 #include <netinet/ip_ecn.h>
95 #include <netinet6/ip6_ecn.h>
97 #include <netinet/tcp.h>
98 #include <netinet/udp.h>
100 #include <netinet/ip6.h>
102 #include <netinet6/ip6_var.h>
104 #include <netinet/in_pcb.h>
106 #include <netinet/icmp6.h>
109 #include <netinet6/ipsec.h>
111 #include <netinet6/ipsec6.h>
113 #include <netinet6/ah.h>
115 #include <netinet6/ah6.h>
118 #include <netinet6/esp.h>
120 #include <netinet6/esp6.h>
123 #include <netinet6/ipcomp.h>
125 #include <netinet6/ipcomp6.h>
127 #include <netkey/key.h>
128 #include <netkey/keydb.h>
129 #include <netkey/key_debug.h>
131 #include <net/net_osdep.h>
139 #include <sys/kdebug.h>
140 #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETIPSEC, 1)
141 #define DBG_LAYER_END NETDBG_CODE(DBG_NETIPSEC, 3)
142 #define DBG_FNC_GETPOL_SOCK NETDBG_CODE(DBG_NETIPSEC, (1 << 8))
143 #define DBG_FNC_GETPOL_ADDR NETDBG_CODE(DBG_NETIPSEC, (2 << 8))
144 #define DBG_FNC_IPSEC_OUT NETDBG_CODE(DBG_NETIPSEC, (3 << 8))
146 extern lck_mtx_t
*sadb_mutex
;
148 struct ipsecstat ipsecstat
;
149 int ip4_ah_cleartos
= 1;
150 int ip4_ah_offsetmask
= 0; /* maybe IP_DF? */
151 int ip4_ipsec_dfbit
= 0; /* DF bit on encap. 0: clear 1: set 2: copy */
152 int ip4_esp_trans_deflev
= IPSEC_LEVEL_USE
;
153 int ip4_esp_net_deflev
= IPSEC_LEVEL_USE
;
154 int ip4_ah_trans_deflev
= IPSEC_LEVEL_USE
;
155 int ip4_ah_net_deflev
= IPSEC_LEVEL_USE
;
156 struct secpolicy ip4_def_policy
;
157 int ip4_ipsec_ecn
= 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
158 int ip4_esp_randpad
= -1;
159 int esp_udp_encap_port
= 0;
160 static int sysctl_def_policy SYSCTL_HANDLER_ARGS
;
161 extern int natt_keepalive_interval
;
162 extern u_int32_t natt_now
;
166 SYSCTL_DECL(_net_inet_ipsec
);
168 SYSCTL_DECL(_net_inet6_ipsec6
);
171 SYSCTL_STRUCT(_net_inet_ipsec
, IPSECCTL_STATS
,
172 stats
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsecstat
, ipsecstat
, "");
173 SYSCTL_PROC(_net_inet_ipsec
, IPSECCTL_DEF_POLICY
, def_policy
, CTLTYPE_INT
|CTLFLAG_RW
| CTLFLAG_LOCKED
,
174 &ip4_def_policy
.policy
, 0, &sysctl_def_policy
, "I", "");
175 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
,
176 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_trans_deflev
, 0, "");
177 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
,
178 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_net_deflev
, 0, "");
179 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
,
180 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_trans_deflev
, 0, "");
181 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
,
182 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_net_deflev
, 0, "");
183 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_CLEARTOS
,
184 ah_cleartos
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_cleartos
, 0, "");
185 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_OFFSETMASK
,
186 ah_offsetmask
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_offsetmask
, 0, "");
187 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DFBIT
,
188 dfbit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ipsec_dfbit
, 0, "");
189 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ECN
,
190 ecn
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ipsec_ecn
, 0, "");
191 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEBUG
,
192 debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, "");
193 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ESP_RANDPAD
,
194 esp_randpad
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_randpad
, 0, "");
196 /* for performance, we bypass ipsec until a security policy is set */
197 int ipsec_bypass
= 1;
198 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, bypass
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsec_bypass
,0, "");
201 * NAT Traversal requires a UDP port for encapsulation,
202 * esp_udp_encap_port controls which port is used. Racoon
203 * must set this port to the port racoon is using locally
206 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, esp_port
,
207 CTLFLAG_RW
| CTLFLAG_LOCKED
, &esp_udp_encap_port
, 0, "");
210 struct ipsecstat ipsec6stat
;
211 int ip6_esp_trans_deflev
= IPSEC_LEVEL_USE
;
212 int ip6_esp_net_deflev
= IPSEC_LEVEL_USE
;
213 int ip6_ah_trans_deflev
= IPSEC_LEVEL_USE
;
214 int ip6_ah_net_deflev
= IPSEC_LEVEL_USE
;
215 struct secpolicy ip6_def_policy
;
216 int ip6_ipsec_ecn
= 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
217 int ip6_esp_randpad
= -1;
219 /* net.inet6.ipsec6 */
220 SYSCTL_STRUCT(_net_inet6_ipsec6
, IPSECCTL_STATS
,
221 stats
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsec6stat
, ipsecstat
, "");
222 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_POLICY
,
223 def_policy
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_def_policy
.policy
, 0, "");
224 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
,
225 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_trans_deflev
, 0, "");
226 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
,
227 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_net_deflev
, 0, "");
228 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
,
229 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ah_trans_deflev
, 0, "");
230 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
,
231 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ah_net_deflev
, 0, "");
232 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ECN
,
233 ecn
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ipsec_ecn
, 0, "");
234 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEBUG
,
235 debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, "");
236 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ESP_RANDPAD
,
237 esp_randpad
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_randpad
, 0, "");
240 static int ipsec_setspidx_mbuf(struct secpolicyindex
*, u_int
, u_int
,
242 static int ipsec4_setspidx_inpcb(struct mbuf
*, struct inpcb
*pcb
);
244 static int ipsec6_setspidx_in6pcb(struct mbuf
*, struct in6pcb
*pcb
);
246 static int ipsec_setspidx(struct mbuf
*, struct secpolicyindex
*, int);
247 static void ipsec4_get_ulp(struct mbuf
*m
, struct secpolicyindex
*, int);
248 static int ipsec4_setspidx_ipaddr(struct mbuf
*, struct secpolicyindex
*);
250 static void ipsec6_get_ulp(struct mbuf
*m
, struct secpolicyindex
*, int);
251 static int ipsec6_setspidx_ipaddr(struct mbuf
*, struct secpolicyindex
*);
253 static struct inpcbpolicy
*ipsec_newpcbpolicy(void);
254 static void ipsec_delpcbpolicy(struct inpcbpolicy
*);
255 static struct secpolicy
*ipsec_deepcopy_policy(struct secpolicy
*src
);
256 static int ipsec_set_policy(struct secpolicy
**pcb_sp
,
257 int optname
, caddr_t request
, size_t len
, int priv
);
258 static int ipsec_get_policy(struct secpolicy
*pcb_sp
, struct mbuf
**mp
);
259 static void vshiftl(unsigned char *, int, int);
260 static int ipsec_in_reject(struct secpolicy
*, struct mbuf
*);
262 static int ipsec64_encapsulate(struct mbuf
*, struct secasvar
*);
264 static struct ipsec_tag
*ipsec_addaux(struct mbuf
*);
265 static struct ipsec_tag
*ipsec_findaux(struct mbuf
*);
266 static void ipsec_optaux(struct mbuf
*, struct ipsec_tag
*);
267 int ipsec_send_natt_keepalive(struct secasvar
*sav
);
270 sysctl_def_policy SYSCTL_HANDLER_ARGS
272 int old_policy
= ip4_def_policy
.policy
;
273 int error
= sysctl_handle_int(oidp
, oidp
->oid_arg1
, oidp
->oid_arg2
, req
);
275 #pragma unused(arg1, arg2)
277 if (ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
&&
278 ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
) {
279 ip4_def_policy
.policy
= old_policy
;
283 /* Turn off the bypass if the default security policy changes */
284 if (ipsec_bypass
!= 0 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
)
291 * For OUTBOUND packet having a socket. Searching SPD for packet,
292 * and return a pointer to SP.
293 * OUT: NULL: no apropreate SP found, the following value is set to error.
295 * EACCES : discard packet.
296 * ENOENT : ipsec_acquire() in progress, maybe.
297 * others : error occurred.
298 * others: a pointer to SP
300 * NOTE: IPv6 mapped adddress concern is implemented here.
303 ipsec4_getpolicybysock(m
, dir
, so
, error
)
309 struct inpcbpolicy
*pcbsp
= NULL
;
310 struct secpolicy
*currsp
= NULL
; /* policy on socket */
311 struct secpolicy
*kernsp
= NULL
; /* policy on kernel */
313 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
315 if (m
== NULL
|| so
== NULL
|| error
== NULL
)
316 panic("ipsec4_getpolicybysock: NULL pointer was passed.\n");
318 if (so
->so_pcb
== NULL
) {
319 printf("ipsec4_getpolicybysock: so->so_pcb == NULL\n");
320 return ipsec4_getpolicybyaddr(m
, dir
, 0, error
);
323 switch (so
->so_proto
->pr_domain
->dom_family
) {
325 pcbsp
= sotoinpcb(so
)->inp_sp
;
329 pcbsp
= sotoin6pcb(so
)->in6p_sp
;
335 /* Socket has not specified an IPSEC policy */
336 return ipsec4_getpolicybyaddr(m
, dir
, 0, error
);
339 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_START
, 0,0,0,0,0);
341 switch (so
->so_proto
->pr_domain
->dom_family
) {
343 /* set spidx in pcb */
344 *error
= ipsec4_setspidx_inpcb(m
, sotoinpcb(so
));
348 /* set spidx in pcb */
349 *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");
365 case IPSEC_DIR_INBOUND
:
366 currsp
= pcbsp
->sp_in
;
368 case IPSEC_DIR_OUTBOUND
:
369 currsp
= pcbsp
->sp_out
;
372 panic("ipsec4_getpolicybysock: illegal direction.\n");
377 panic("ipsec4_getpolicybysock: currsp is NULL.\n");
379 /* when privilieged socket */
381 switch (currsp
->policy
) {
382 case IPSEC_POLICY_BYPASS
:
383 lck_mtx_lock(sadb_mutex
);
385 lck_mtx_unlock(sadb_mutex
);
387 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 2,*error
,0,0,0);
390 case IPSEC_POLICY_ENTRUST
:
391 /* look for a policy in SPD */
392 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
395 if (kernsp
!= NULL
) {
396 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
397 printf("DP ipsec4_getpolicybysock called "
398 "to allocate SP:%p\n", kernsp
));
400 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 3,*error
,0,0,0);
405 lck_mtx_lock(sadb_mutex
);
406 if (ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
407 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
409 "fixed system default policy: %d->%d\n",
410 ip4_def_policy
.policy
, IPSEC_POLICY_NONE
));
411 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
413 ip4_def_policy
.refcnt
++;
414 lck_mtx_unlock(sadb_mutex
);
416 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 4,*error
,0,0,0);
417 return &ip4_def_policy
;
419 case IPSEC_POLICY_IPSEC
:
420 lck_mtx_lock(sadb_mutex
);
422 lck_mtx_unlock(sadb_mutex
);
424 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 5,*error
,0,0,0);
428 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: "
429 "Invalid policy for PCB %d\n", currsp
->policy
));
431 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 6,*error
,0,0,0);
437 /* when non-privilieged socket */
438 /* look for a policy in SPD */
439 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
442 if (kernsp
!= NULL
) {
443 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
444 printf("DP ipsec4_getpolicybysock called "
445 "to allocate SP:%p\n", kernsp
));
447 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 7,*error
,0,0,0);
452 switch (currsp
->policy
) {
453 case IPSEC_POLICY_BYPASS
:
454 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: "
455 "Illegal policy for non-priviliged defined %d\n",
458 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 8,*error
,0,0,0);
461 case IPSEC_POLICY_ENTRUST
:
462 lck_mtx_lock(sadb_mutex
);
463 if (ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
464 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
466 "fixed system default policy: %d->%d\n",
467 ip4_def_policy
.policy
, IPSEC_POLICY_NONE
));
468 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
470 ip4_def_policy
.refcnt
++;
471 lck_mtx_unlock(sadb_mutex
);
473 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 9,*error
,0,0,0);
474 return &ip4_def_policy
;
476 case IPSEC_POLICY_IPSEC
:
477 lck_mtx_lock(sadb_mutex
);
479 lck_mtx_unlock(sadb_mutex
);
481 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 10,*error
,0,0,0);
485 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: "
486 "Invalid policy for PCB %d\n", currsp
->policy
));
488 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 11,*error
,0,0,0);
495 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
496 * and return a pointer to SP.
497 * OUT: positive: a pointer to the entry for security policy leaf matched.
498 * NULL: no apropreate SP found, the following value is set to error.
500 * EACCES : discard packet.
501 * ENOENT : ipsec_acquire() in progress, maybe.
502 * others : error occurred.
505 ipsec4_getpolicybyaddr(m
, dir
, flag
, error
)
511 struct secpolicy
*sp
= NULL
;
513 if (ipsec_bypass
!= 0)
516 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
519 if (m
== NULL
|| error
== NULL
)
520 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.\n");
523 struct secpolicyindex spidx
;
525 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_START
, 0,0,0,0,0);
526 bzero(&spidx
, sizeof(spidx
));
528 /* make a index to look for a policy */
529 *error
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET
, m
,
530 (flag
& IP_FORWARDING
) ? 0 : 1);
533 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 1,*error
,0,0,0);
537 sp
= key_allocsp(&spidx
, dir
);
542 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
543 printf("DP ipsec4_getpolicybyaddr called "
544 "to allocate SP:%p\n", sp
));
546 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 2,*error
,0,0,0);
551 lck_mtx_lock(sadb_mutex
);
552 if (ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
553 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
554 ipseclog((LOG_INFO
, "fixed system default policy:%d->%d\n",
555 ip4_def_policy
.policy
,
557 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
559 ip4_def_policy
.refcnt
++;
560 lck_mtx_unlock(sadb_mutex
);
562 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 3,*error
,0,0,0);
563 return &ip4_def_policy
;
568 * For OUTBOUND packet having a socket. Searching SPD for packet,
569 * and return a pointer to SP.
570 * OUT: NULL: no apropreate SP found, the following value is set to error.
572 * EACCES : discard packet.
573 * ENOENT : ipsec_acquire() in progress, maybe.
574 * others : error occurred.
575 * others: a pointer to SP
578 ipsec6_getpolicybysock(m
, dir
, so
, error
)
584 struct inpcbpolicy
*pcbsp
= NULL
;
585 struct secpolicy
*currsp
= NULL
; /* policy on socket */
586 struct secpolicy
*kernsp
= NULL
; /* policy on kernel */
588 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
591 if (m
== NULL
|| so
== NULL
|| error
== NULL
)
592 panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
595 if (so
->so_proto
->pr_domain
->dom_family
!= AF_INET6
)
596 panic("ipsec6_getpolicybysock: socket domain != inet6\n");
599 pcbsp
= sotoin6pcb(so
)->in6p_sp
;
602 return ipsec6_getpolicybyaddr(m
, dir
, 0, error
);
605 /* set spidx in pcb */
606 ipsec6_setspidx_in6pcb(m
, sotoin6pcb(so
));
610 panic("ipsec6_getpolicybysock: pcbsp is NULL.\n");
613 case IPSEC_DIR_INBOUND
:
614 currsp
= pcbsp
->sp_in
;
616 case IPSEC_DIR_OUTBOUND
:
617 currsp
= pcbsp
->sp_out
;
620 panic("ipsec6_getpolicybysock: illegal direction.\n");
625 panic("ipsec6_getpolicybysock: currsp is NULL.\n");
627 /* when privilieged socket */
629 switch (currsp
->policy
) {
630 case IPSEC_POLICY_BYPASS
:
631 lck_mtx_lock(sadb_mutex
);
633 lck_mtx_unlock(sadb_mutex
);
637 case IPSEC_POLICY_ENTRUST
:
638 /* look for a policy in SPD */
639 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
642 if (kernsp
!= NULL
) {
643 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
644 printf("DP ipsec6_getpolicybysock called "
645 "to allocate SP:%p\n", kernsp
));
651 lck_mtx_lock(sadb_mutex
);
652 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
653 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
655 "fixed system default policy: %d->%d\n",
656 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
657 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
659 ip6_def_policy
.refcnt
++;
660 lck_mtx_unlock(sadb_mutex
);
662 return &ip6_def_policy
;
664 case IPSEC_POLICY_IPSEC
:
665 lck_mtx_lock(sadb_mutex
);
667 lck_mtx_unlock(sadb_mutex
);
672 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: "
673 "Invalid policy for PCB %d\n", currsp
->policy
));
680 /* when non-privilieged socket */
681 /* look for a policy in SPD */
682 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
685 if (kernsp
!= NULL
) {
686 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
687 printf("DP ipsec6_getpolicybysock called "
688 "to allocate SP:%p\n", kernsp
));
694 switch (currsp
->policy
) {
695 case IPSEC_POLICY_BYPASS
:
696 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: "
697 "Illegal policy for non-priviliged defined %d\n",
702 case IPSEC_POLICY_ENTRUST
:
703 lck_mtx_lock(sadb_mutex
);
704 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
705 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
707 "fixed system default policy: %d->%d\n",
708 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
709 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
711 ip6_def_policy
.refcnt
++;
712 lck_mtx_unlock(sadb_mutex
);
714 return &ip6_def_policy
;
716 case IPSEC_POLICY_IPSEC
:
717 lck_mtx_lock(sadb_mutex
);
719 lck_mtx_unlock(sadb_mutex
);
725 "ipsec6_policybysock: Invalid policy for PCB %d\n",
734 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
735 * and return a pointer to SP.
736 * `flag' means that packet is to be forwarded whether or not.
738 * OUT: positive: a pointer to the entry for security policy leaf matched.
739 * NULL: no apropreate SP found, the following value is set to error.
741 * EACCES : discard packet.
742 * ENOENT : ipsec_acquire() in progress, maybe.
743 * others : error occurred.
745 #ifndef IP_FORWARDING
746 #define IP_FORWARDING 1
750 ipsec6_getpolicybyaddr(m
, dir
, flag
, error
)
756 struct secpolicy
*sp
= NULL
;
758 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
761 if (m
== NULL
|| error
== NULL
)
762 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.\n");
765 struct secpolicyindex spidx
;
767 bzero(&spidx
, sizeof(spidx
));
769 /* make a index to look for a policy */
770 *error
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET6
, m
,
771 (flag
& IP_FORWARDING
) ? 0 : 1);
776 sp
= key_allocsp(&spidx
, dir
);
781 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
782 printf("DP ipsec6_getpolicybyaddr called "
783 "to allocate SP:%p\n", sp
));
789 lck_mtx_lock(sadb_mutex
);
790 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
791 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
792 ipseclog((LOG_INFO
, "fixed system default policy: %d->%d\n",
793 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
794 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
796 ip6_def_policy
.refcnt
++;
797 lck_mtx_unlock(sadb_mutex
);
799 return &ip6_def_policy
;
804 * set IP address into spidx from mbuf.
805 * When Forwarding packet and ICMP echo reply, this function is used.
807 * IN: get the followings from mbuf.
808 * protocol family, src, dst, next protocol
811 * other: failure, and set errno.
815 struct secpolicyindex
*spidx
,
817 __unused u_int family
,
824 if (spidx
== NULL
|| m
== NULL
)
825 panic("ipsec_setspidx_mbuf: NULL pointer was passed.\n");
827 bzero(spidx
, sizeof(*spidx
));
829 error
= ipsec_setspidx(m
, spidx
, needport
);
838 bzero(spidx
, sizeof(*spidx
));
843 ipsec4_setspidx_inpcb(m
, pcb
)
847 struct secpolicyindex
*spidx
;
850 if (ipsec_bypass
!= 0)
855 panic("ipsec4_setspidx_inpcb: no PCB found.\n");
856 if (pcb
->inp_sp
== NULL
)
857 panic("ipsec4_setspidx_inpcb: no inp_sp found.\n");
858 if (pcb
->inp_sp
->sp_out
== NULL
|| pcb
->inp_sp
->sp_in
== NULL
)
859 panic("ipsec4_setspidx_inpcb: no sp_in/out found.\n");
861 bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
));
862 bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
));
864 spidx
= &pcb
->inp_sp
->sp_in
->spidx
;
865 error
= ipsec_setspidx(m
, spidx
, 1);
868 spidx
->dir
= IPSEC_DIR_INBOUND
;
870 spidx
= &pcb
->inp_sp
->sp_out
->spidx
;
871 error
= ipsec_setspidx(m
, spidx
, 1);
874 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
879 bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
));
880 bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
));
886 ipsec6_setspidx_in6pcb(m
, pcb
)
890 struct secpolicyindex
*spidx
;
895 panic("ipsec6_setspidx_in6pcb: no PCB found.\n");
896 if (pcb
->in6p_sp
== NULL
)
897 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.\n");
898 if (pcb
->in6p_sp
->sp_out
== NULL
|| pcb
->in6p_sp
->sp_in
== NULL
)
899 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.\n");
901 bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
));
902 bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
));
904 spidx
= &pcb
->in6p_sp
->sp_in
->spidx
;
905 error
= ipsec_setspidx(m
, spidx
, 1);
908 spidx
->dir
= IPSEC_DIR_INBOUND
;
910 spidx
= &pcb
->in6p_sp
->sp_out
->spidx
;
911 error
= ipsec_setspidx(m
, spidx
, 1);
914 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
919 bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
));
920 bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
));
926 * configure security policy index (src/dst/proto/sport/dport)
927 * by looking at the content of mbuf.
928 * the caller is responsible for error recovery (like clearing up spidx).
931 ipsec_setspidx(m
, spidx
, needport
)
933 struct secpolicyindex
*spidx
;
936 struct ip
*ip
= NULL
;
944 panic("ipsec_setspidx: m == 0 passed.\n");
947 * validate m->m_pkthdr.len. we see incorrect length if we
948 * mistakenly call this function with inconsistent mbuf chain
949 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
952 for (n
= m
; n
; n
= n
->m_next
)
954 if (m
->m_pkthdr
.len
!= len
) {
955 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
956 printf("ipsec_setspidx: "
957 "total of m_len(%d) != pkthdr.len(%d), "
959 len
, m
->m_pkthdr
.len
));
963 if (m
->m_pkthdr
.len
< sizeof(struct ip
)) {
964 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
965 printf("ipsec_setspidx: "
966 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
971 if (m
->m_len
>= sizeof(*ip
))
972 ip
= mtod(m
, struct ip
*);
974 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
);
978 v
= _IP_VHL_V(ip
->ip_vhl
);
984 error
= ipsec4_setspidx_ipaddr(m
, spidx
);
987 ipsec4_get_ulp(m
, spidx
, needport
);
991 if (m
->m_pkthdr
.len
< sizeof(struct ip6_hdr
)) {
992 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
993 printf("ipsec_setspidx: "
994 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
995 "ignored.\n", m
->m_pkthdr
.len
));
998 error
= ipsec6_setspidx_ipaddr(m
, spidx
);
1001 ipsec6_get_ulp(m
, spidx
, needport
);
1005 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1006 printf("ipsec_setspidx: "
1007 "unknown IP version %u, ignored.\n", v
));
1013 ipsec4_get_ulp(m
, spidx
, needport
)
1015 struct secpolicyindex
*spidx
;
1019 struct ip6_ext ip6e
;
1027 panic("ipsec4_get_ulp: NULL pointer was passed.\n");
1028 if (m
->m_pkthdr
.len
< sizeof(ip
))
1029 panic("ipsec4_get_ulp: too short\n");
1032 spidx
->ul_proto
= IPSEC_ULPROTO_ANY
;
1033 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
= IPSEC_PORT_ANY
;
1034 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
= IPSEC_PORT_ANY
;
1036 m_copydata(m
, 0, sizeof(ip
), (caddr_t
)&ip
);
1037 /* ip_input() flips it into host endian XXX need more checking */
1038 if (ip
.ip_off
& (IP_MF
| IP_OFFMASK
))
1043 off
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
1045 off
= ip
.ip_hl
<< 2;
1047 while (off
< m
->m_pkthdr
.len
) {
1050 spidx
->ul_proto
= nxt
;
1053 if (off
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
)
1055 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
);
1056 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
=
1058 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
=
1062 spidx
->ul_proto
= nxt
;
1065 if (off
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
)
1067 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
);
1068 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
=
1070 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
=
1074 if (off
+ sizeof(ip6e
) > m
->m_pkthdr
.len
)
1076 m_copydata(m
, off
, sizeof(ip6e
), (caddr_t
)&ip6e
);
1077 off
+= (ip6e
.ip6e_len
+ 2) << 2;
1078 nxt
= ip6e
.ip6e_nxt
;
1082 /* XXX intermediate headers??? */
1083 spidx
->ul_proto
= nxt
;
1089 /* assumes that m is sane */
1091 ipsec4_setspidx_ipaddr(m
, spidx
)
1093 struct secpolicyindex
*spidx
;
1095 struct ip
*ip
= NULL
;
1097 struct sockaddr_in
*sin
;
1099 if (m
->m_len
>= sizeof(*ip
))
1100 ip
= mtod(m
, struct ip
*);
1102 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
);
1106 sin
= (struct sockaddr_in
*)&spidx
->src
;
1107 bzero(sin
, sizeof(*sin
));
1108 sin
->sin_family
= AF_INET
;
1109 sin
->sin_len
= sizeof(struct sockaddr_in
);
1110 bcopy(&ip
->ip_src
, &sin
->sin_addr
, sizeof(ip
->ip_src
));
1111 spidx
->prefs
= sizeof(struct in_addr
) << 3;
1113 sin
= (struct sockaddr_in
*)&spidx
->dst
;
1114 bzero(sin
, sizeof(*sin
));
1115 sin
->sin_family
= AF_INET
;
1116 sin
->sin_len
= sizeof(struct sockaddr_in
);
1117 bcopy(&ip
->ip_dst
, &sin
->sin_addr
, sizeof(ip
->ip_dst
));
1118 spidx
->prefd
= sizeof(struct in_addr
) << 3;
1124 ipsec6_get_ulp(m
, spidx
, needport
)
1126 struct secpolicyindex
*spidx
;
1135 panic("ipsec6_get_ulp: NULL pointer was passed.\n");
1137 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1138 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m
));
1141 spidx
->ul_proto
= IPSEC_ULPROTO_ANY
;
1142 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= IPSEC_PORT_ANY
;
1143 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= IPSEC_PORT_ANY
;
1146 off
= ip6_lasthdr(m
, 0, IPPROTO_IPV6
, &nxt
);
1147 if (off
< 0 || m
->m_pkthdr
.len
< off
)
1152 spidx
->ul_proto
= nxt
;
1155 if (off
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
)
1157 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
);
1158 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= th
.th_sport
;
1159 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= th
.th_dport
;
1162 spidx
->ul_proto
= nxt
;
1165 if (off
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
)
1167 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
);
1168 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= uh
.uh_sport
;
1169 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= uh
.uh_dport
;
1171 case IPPROTO_ICMPV6
:
1173 /* XXX intermediate headers??? */
1174 spidx
->ul_proto
= nxt
;
1179 /* assumes that m is sane */
1181 ipsec6_setspidx_ipaddr(m
, spidx
)
1183 struct secpolicyindex
*spidx
;
1185 struct ip6_hdr
*ip6
= NULL
;
1186 struct ip6_hdr ip6buf
;
1187 struct sockaddr_in6
*sin6
;
1189 if (m
->m_len
>= sizeof(*ip6
))
1190 ip6
= mtod(m
, struct ip6_hdr
*);
1192 m_copydata(m
, 0, sizeof(ip6buf
), (caddr_t
)&ip6buf
);
1196 sin6
= (struct sockaddr_in6
*)&spidx
->src
;
1197 bzero(sin6
, sizeof(*sin6
));
1198 sin6
->sin6_family
= AF_INET6
;
1199 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
1200 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_src
));
1201 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
1202 sin6
->sin6_addr
.s6_addr16
[1] = 0;
1203 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
1205 spidx
->prefs
= sizeof(struct in6_addr
) << 3;
1207 sin6
= (struct sockaddr_in6
*)&spidx
->dst
;
1208 bzero(sin6
, sizeof(*sin6
));
1209 sin6
->sin6_family
= AF_INET6
;
1210 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
1211 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_dst
));
1212 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
1213 sin6
->sin6_addr
.s6_addr16
[1] = 0;
1214 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
1216 spidx
->prefd
= sizeof(struct in6_addr
) << 3;
1222 static struct inpcbpolicy
*
1223 ipsec_newpcbpolicy()
1225 struct inpcbpolicy
*p
;
1227 p
= (struct inpcbpolicy
*)_MALLOC(sizeof(*p
), M_SECA
, M_WAITOK
);
1232 ipsec_delpcbpolicy(p
)
1233 struct inpcbpolicy
*p
;
1238 /* initialize policy in PCB */
1240 ipsec_init_policy(so
, pcb_sp
)
1242 struct inpcbpolicy
**pcb_sp
;
1244 struct inpcbpolicy
*new;
1247 if (so
== NULL
|| pcb_sp
== NULL
)
1248 panic("ipsec_init_policy: NULL pointer was passed.\n");
1250 new = ipsec_newpcbpolicy();
1252 ipseclog((LOG_DEBUG
, "ipsec_init_policy: No more memory.\n"));
1255 bzero(new, sizeof(*new));
1258 if (kauth_cred_issuser(so
->so_cred
))
1260 if (so
->so_cred
!= 0 && !suser(so
->so_cred
->pc_ucred
, NULL
))
1266 if ((new->sp_in
= key_newsp()) == NULL
) {
1267 ipsec_delpcbpolicy(new);
1270 new->sp_in
->state
= IPSEC_SPSTATE_ALIVE
;
1271 new->sp_in
->policy
= IPSEC_POLICY_ENTRUST
;
1273 if ((new->sp_out
= key_newsp()) == NULL
) {
1274 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
);
1275 ipsec_delpcbpolicy(new);
1278 new->sp_out
->state
= IPSEC_SPSTATE_ALIVE
;
1279 new->sp_out
->policy
= IPSEC_POLICY_ENTRUST
;
1286 /* copy old ipsec policy into new */
1288 ipsec_copy_policy(old
, new)
1289 struct inpcbpolicy
*old
, *new;
1291 struct secpolicy
*sp
;
1293 if (ipsec_bypass
!= 0)
1296 sp
= ipsec_deepcopy_policy(old
->sp_in
);
1298 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
);
1303 sp
= ipsec_deepcopy_policy(old
->sp_out
);
1305 key_freesp(new->sp_out
, KEY_SADB_UNLOCKED
);
1310 new->priv
= old
->priv
;
1315 /* deep-copy a policy in PCB */
1316 static struct secpolicy
*
1317 ipsec_deepcopy_policy(src
)
1318 struct secpolicy
*src
;
1320 struct ipsecrequest
*newchain
= NULL
;
1321 struct ipsecrequest
*p
;
1322 struct ipsecrequest
**q
;
1323 struct ipsecrequest
*r
;
1324 struct secpolicy
*dst
;
1333 * deep-copy IPsec request chain. This is required since struct
1334 * ipsecrequest is not reference counted.
1337 for (p
= src
->req
; p
; p
= p
->next
) {
1338 *q
= (struct ipsecrequest
*)_MALLOC(sizeof(struct ipsecrequest
),
1342 bzero(*q
, sizeof(**q
));
1345 (*q
)->saidx
.proto
= p
->saidx
.proto
;
1346 (*q
)->saidx
.mode
= p
->saidx
.mode
;
1347 (*q
)->level
= p
->level
;
1348 (*q
)->saidx
.reqid
= p
->saidx
.reqid
;
1350 bcopy(&p
->saidx
.src
, &(*q
)->saidx
.src
, sizeof((*q
)->saidx
.src
));
1351 bcopy(&p
->saidx
.dst
, &(*q
)->saidx
.dst
, sizeof((*q
)->saidx
.dst
));
1358 dst
->req
= newchain
;
1359 dst
->state
= src
->state
;
1360 dst
->policy
= src
->policy
;
1361 /* do not touch the refcnt fields */
1366 for (p
= newchain
; p
; p
= r
) {
1371 key_freesp(dst
, KEY_SADB_UNLOCKED
);
1375 /* set policy and ipsec request if present. */
1378 struct secpolicy
**pcb_sp
,
1379 __unused
int optname
,
1384 struct sadb_x_policy
*xpl
;
1385 struct secpolicy
*newsp
= NULL
;
1389 if (pcb_sp
== NULL
|| *pcb_sp
== NULL
|| request
== NULL
)
1391 if (len
< sizeof(*xpl
))
1393 xpl
= (struct sadb_x_policy
*)(void *)request
;
1395 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1396 printf("ipsec_set_policy: passed policy\n");
1397 kdebug_sadb_x_policy((struct sadb_ext
*)xpl
));
1399 /* check policy type */
1400 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1401 if (xpl
->sadb_x_policy_type
== IPSEC_POLICY_DISCARD
1402 || xpl
->sadb_x_policy_type
== IPSEC_POLICY_NONE
)
1405 /* check privileged socket */
1406 if (priv
== 0 && xpl
->sadb_x_policy_type
== IPSEC_POLICY_BYPASS
)
1409 /* allocation new SP entry */
1410 if ((newsp
= key_msg2sp(xpl
, len
, &error
)) == NULL
)
1413 newsp
->state
= IPSEC_SPSTATE_ALIVE
;
1415 /* clear old SP and set new SP */
1416 key_freesp(*pcb_sp
, KEY_SADB_UNLOCKED
);
1418 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1419 printf("ipsec_set_policy: new policy\n");
1420 kdebug_secpolicy(newsp
));
1426 ipsec_get_policy(pcb_sp
, mp
)
1427 struct secpolicy
*pcb_sp
;
1433 if (pcb_sp
== NULL
|| mp
== NULL
)
1436 *mp
= key_sp2msg(pcb_sp
);
1438 ipseclog((LOG_DEBUG
, "ipsec_get_policy: No more memory.\n"));
1442 m_mchtype(*mp
, MT_DATA
);
1443 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1444 printf("ipsec_get_policy:\n");
1451 ipsec4_set_policy(inp
, optname
, request
, len
, priv
)
1458 struct sadb_x_policy
*xpl
;
1459 struct secpolicy
**pcb_sp
;
1461 struct sadb_x_policy xpl_aligned_buf
;
1462 u_int8_t
*xpl_unaligned
;
1465 if (inp
== NULL
|| request
== NULL
)
1467 if (len
< sizeof(*xpl
))
1469 xpl
= (struct sadb_x_policy
*)(void *)request
;
1471 /* This is a new mbuf allocated by soopt_getm() */
1472 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1473 xpl_unaligned
= NULL
;
1475 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1476 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1477 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1480 if (inp
->inp_sp
== NULL
) {
1481 error
= ipsec_init_policy(inp
->inp_socket
, &inp
->inp_sp
);
1486 /* select direction */
1487 switch (xpl
->sadb_x_policy_dir
) {
1488 case IPSEC_DIR_INBOUND
:
1489 pcb_sp
= &inp
->inp_sp
->sp_in
;
1491 case IPSEC_DIR_OUTBOUND
:
1492 pcb_sp
= &inp
->inp_sp
->sp_out
;
1495 ipseclog((LOG_ERR
, "ipsec4_set_policy: invalid direction=%u\n",
1496 xpl
->sadb_x_policy_dir
));
1500 /* turn bypass off */
1501 if (ipsec_bypass
!= 0)
1504 return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
);
1508 ipsec4_get_policy(inp
, request
, len
, mp
)
1514 struct sadb_x_policy
*xpl
;
1515 struct secpolicy
*pcb_sp
;
1517 struct sadb_x_policy xpl_aligned_buf
;
1518 u_int8_t
*xpl_unaligned
;
1520 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1523 if (inp
== NULL
|| request
== NULL
|| mp
== NULL
)
1525 if (len
< sizeof(*xpl
))
1527 xpl
= (struct sadb_x_policy
*)(void *)request
;
1529 /* This is a new mbuf allocated by soopt_getm() */
1530 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1531 xpl_unaligned
= NULL
;
1533 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1534 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1535 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1538 if (inp
->inp_sp
== NULL
) {
1539 error
= ipsec_init_policy(inp
->inp_socket
, &inp
->inp_sp
);
1544 /* select direction */
1545 switch (xpl
->sadb_x_policy_dir
) {
1546 case IPSEC_DIR_INBOUND
:
1547 pcb_sp
= inp
->inp_sp
->sp_in
;
1549 case IPSEC_DIR_OUTBOUND
:
1550 pcb_sp
= inp
->inp_sp
->sp_out
;
1553 ipseclog((LOG_ERR
, "ipsec4_set_policy: invalid direction=%u\n",
1554 xpl
->sadb_x_policy_dir
));
1558 return ipsec_get_policy(pcb_sp
, mp
);
1561 /* delete policy in PCB */
1563 ipsec4_delete_pcbpolicy(inp
)
1569 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n");
1571 if (inp
->inp_sp
== NULL
)
1574 if (inp
->inp_sp
->sp_in
!= NULL
) {
1575 key_freesp(inp
->inp_sp
->sp_in
, KEY_SADB_UNLOCKED
);
1576 inp
->inp_sp
->sp_in
= NULL
;
1579 if (inp
->inp_sp
->sp_out
!= NULL
) {
1580 key_freesp(inp
->inp_sp
->sp_out
, KEY_SADB_UNLOCKED
);
1581 inp
->inp_sp
->sp_out
= NULL
;
1584 ipsec_delpcbpolicy(inp
->inp_sp
);
1592 ipsec6_set_policy(in6p
, optname
, request
, len
, priv
)
1593 struct in6pcb
*in6p
;
1599 struct sadb_x_policy
*xpl
;
1600 struct secpolicy
**pcb_sp
;
1602 struct sadb_x_policy xpl_aligned_buf
;
1603 u_int8_t
*xpl_unaligned
;
1606 if (in6p
== NULL
|| request
== NULL
)
1608 if (len
< sizeof(*xpl
))
1610 xpl
= (struct sadb_x_policy
*)(void *)request
;
1612 /* This is a new mbuf allocated by soopt_getm() */
1613 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1614 xpl_unaligned
= NULL
;
1616 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1617 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1618 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1621 if (in6p
->in6p_sp
== NULL
) {
1622 error
= ipsec_init_policy(in6p
->inp_socket
, &in6p
->in6p_sp
);
1627 /* select direction */
1628 switch (xpl
->sadb_x_policy_dir
) {
1629 case IPSEC_DIR_INBOUND
:
1630 pcb_sp
= &in6p
->in6p_sp
->sp_in
;
1632 case IPSEC_DIR_OUTBOUND
:
1633 pcb_sp
= &in6p
->in6p_sp
->sp_out
;
1636 ipseclog((LOG_ERR
, "ipsec6_set_policy: invalid direction=%u\n",
1637 xpl
->sadb_x_policy_dir
));
1641 /* turn bypass off */
1642 if (ipsec_bypass
!= 0)
1645 return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
);
1649 ipsec6_get_policy(in6p
, request
, len
, mp
)
1650 struct in6pcb
*in6p
;
1655 struct sadb_x_policy
*xpl
;
1656 struct secpolicy
*pcb_sp
;
1658 struct sadb_x_policy xpl_aligned_buf
;
1659 u_int8_t
*xpl_unaligned
;
1662 if (in6p
== NULL
|| request
== NULL
|| mp
== NULL
)
1664 if (len
< sizeof(*xpl
))
1666 xpl
= (struct sadb_x_policy
*)(void *)request
;
1668 /* This is a new mbuf allocated by soopt_getm() */
1669 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1670 xpl_unaligned
= NULL
;
1672 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1673 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1674 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1677 if (in6p
->in6p_sp
== NULL
) {
1678 error
= ipsec_init_policy(in6p
->inp_socket
, &in6p
->in6p_sp
);
1683 /* select direction */
1684 switch (xpl
->sadb_x_policy_dir
) {
1685 case IPSEC_DIR_INBOUND
:
1686 pcb_sp
= in6p
->in6p_sp
->sp_in
;
1688 case IPSEC_DIR_OUTBOUND
:
1689 pcb_sp
= in6p
->in6p_sp
->sp_out
;
1692 ipseclog((LOG_ERR
, "ipsec6_set_policy: invalid direction=%u\n",
1693 xpl
->sadb_x_policy_dir
));
1697 return ipsec_get_policy(pcb_sp
, mp
);
1701 ipsec6_delete_pcbpolicy(in6p
)
1702 struct in6pcb
*in6p
;
1707 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n");
1709 if (in6p
->in6p_sp
== NULL
)
1712 if (in6p
->in6p_sp
->sp_in
!= NULL
) {
1713 key_freesp(in6p
->in6p_sp
->sp_in
, KEY_SADB_UNLOCKED
);
1714 in6p
->in6p_sp
->sp_in
= NULL
;
1717 if (in6p
->in6p_sp
->sp_out
!= NULL
) {
1718 key_freesp(in6p
->in6p_sp
->sp_out
, KEY_SADB_UNLOCKED
);
1719 in6p
->in6p_sp
->sp_out
= NULL
;
1722 ipsec_delpcbpolicy(in6p
->in6p_sp
);
1723 in6p
->in6p_sp
= NULL
;
1730 * return current level.
1731 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1734 ipsec_get_reqlevel(isr
)
1735 struct ipsecrequest
*isr
;
1738 u_int esp_trans_deflev
= 0, esp_net_deflev
= 0, ah_trans_deflev
= 0, ah_net_deflev
= 0;
1741 if (isr
== NULL
|| isr
->sp
== NULL
)
1742 panic("ipsec_get_reqlevel: NULL pointer is passed.\n");
1743 if (((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
1744 != ((struct sockaddr
*)&isr
->sp
->spidx
.dst
)->sa_family
)
1745 panic("ipsec_get_reqlevel: family mismatched.\n");
1747 /* XXX note that we have ipseclog() expanded here - code sync issue */
1748 #define IPSEC_CHECK_DEFAULT(lev) \
1749 (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1750 && (lev) != IPSEC_LEVEL_UNIQUE) \
1752 ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1753 (lev), IPSEC_LEVEL_REQUIRE) \
1755 (lev) = IPSEC_LEVEL_REQUIRE, \
1759 /* set default level */
1760 switch (((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
) {
1763 esp_trans_deflev
= IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev
);
1764 esp_net_deflev
= IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev
);
1765 ah_trans_deflev
= IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev
);
1766 ah_net_deflev
= IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev
);
1771 esp_trans_deflev
= IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev
);
1772 esp_net_deflev
= IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev
);
1773 ah_trans_deflev
= IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev
);
1774 ah_net_deflev
= IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev
);
1778 panic("key_get_reqlevel: Unknown family. %d\n",
1779 ((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
);
1782 #undef IPSEC_CHECK_DEFAULT
1785 switch (isr
->level
) {
1786 case IPSEC_LEVEL_DEFAULT
:
1787 switch (isr
->saidx
.proto
) {
1789 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
1790 level
= esp_net_deflev
;
1792 level
= esp_trans_deflev
;
1795 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
1796 level
= ah_net_deflev
;
1798 level
= ah_trans_deflev
;
1800 case IPPROTO_IPCOMP
:
1802 * we don't really care, as IPcomp document says that
1803 * we shouldn't compress small packets
1805 level
= IPSEC_LEVEL_USE
;
1808 panic("ipsec_get_reqlevel: "
1809 "Illegal protocol defined %u\n",
1814 case IPSEC_LEVEL_USE
:
1815 case IPSEC_LEVEL_REQUIRE
:
1818 case IPSEC_LEVEL_UNIQUE
:
1819 level
= IPSEC_LEVEL_REQUIRE
;
1823 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
1831 * Check AH/ESP integrity.
1837 ipsec_in_reject(sp
, m
)
1838 struct secpolicy
*sp
;
1841 struct ipsecrequest
*isr
;
1843 int need_auth
, need_conf
, need_icv
;
1845 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
1846 printf("ipsec_in_reject: using SP\n");
1847 kdebug_secpolicy(sp
));
1850 switch (sp
->policy
) {
1851 case IPSEC_POLICY_DISCARD
:
1852 case IPSEC_POLICY_GENERATE
:
1854 case IPSEC_POLICY_BYPASS
:
1855 case IPSEC_POLICY_NONE
:
1858 case IPSEC_POLICY_IPSEC
:
1861 case IPSEC_POLICY_ENTRUST
:
1863 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
);
1870 /* XXX should compare policy against ipsec header history */
1872 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
1874 /* get current level */
1875 level
= ipsec_get_reqlevel(isr
);
1877 switch (isr
->saidx
.proto
) {
1879 if (level
== IPSEC_LEVEL_REQUIRE
) {
1883 /* this won't work with multiple input threads - isr->sav would change
1884 * with every packet and is not necessarily related to the current packet
1885 * being processed. If ESP processing is required - the esp code should
1886 * make sure that the integrity check is present and correct. I don't see
1887 * why it would be necessary to check for the presence of the integrity
1888 * check value here. I think this is just wrong.
1889 * isr->sav has been removed.
1890 * %%%%%% this needs to be re-worked at some point but I think the code below can
1891 * be ignored for now.
1893 if (isr
->sav
!= NULL
1894 && isr
->sav
->flags
== SADB_X_EXT_NONE
1895 && isr
->sav
->alg_auth
!= SADB_AALG_NONE
)
1901 if (level
== IPSEC_LEVEL_REQUIRE
) {
1906 case IPPROTO_IPCOMP
:
1908 * we don't really care, as IPcomp document says that
1909 * we shouldn't compress small packets, IPComp policy
1910 * should always be treated as being in "use" level.
1916 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1917 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1918 need_auth
, need_conf
, need_icv
, m
->m_flags
));
1920 if ((need_conf
&& !(m
->m_flags
& M_DECRYPTED
))
1921 || (!need_auth
&& need_icv
&& !(m
->m_flags
& M_AUTHIPDGM
))
1922 || (need_auth
&& !(m
->m_flags
& M_AUTHIPHDR
)))
1929 * Check AH/ESP integrity.
1930 * This function is called from tcp_input(), udp_input(),
1931 * and {ah,esp}4_input for tunnel mode
1934 ipsec4_in_reject_so(m
, so
)
1938 struct secpolicy
*sp
= NULL
;
1942 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1945 return 0; /* XXX should be panic ? */
1947 /* get SP for this packet.
1948 * When we are called from ip_forward(), we call
1949 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1952 sp
= ipsec4_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
);
1954 sp
= ipsec4_getpolicybysock(m
, IPSEC_DIR_INBOUND
, so
, &error
);
1957 return 0; /* XXX should be panic ?
1958 * -> No, there may be error. */
1960 result
= ipsec_in_reject(sp
, m
);
1961 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
1962 printf("DP ipsec4_in_reject_so call free SP:%p\n", sp
));
1963 key_freesp(sp
, KEY_SADB_UNLOCKED
);
1969 ipsec4_in_reject(m
, inp
)
1974 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1976 return ipsec4_in_reject_so(m
, NULL
);
1977 if (inp
->inp_socket
)
1978 return ipsec4_in_reject_so(m
, inp
->inp_socket
);
1980 panic("ipsec4_in_reject: invalid inpcb/socket");
1988 * Check AH/ESP integrity.
1989 * This function is called from tcp6_input(), udp6_input(),
1990 * and {ah,esp}6_input for tunnel mode
1993 ipsec6_in_reject_so(m
, so
)
1997 struct secpolicy
*sp
= NULL
;
2001 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2004 return 0; /* XXX should be panic ? */
2006 /* get SP for this packet.
2007 * When we are called from ip_forward(), we call
2008 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
2011 sp
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
);
2013 sp
= ipsec6_getpolicybysock(m
, IPSEC_DIR_INBOUND
, so
, &error
);
2016 return 0; /* XXX should be panic ? */
2018 result
= ipsec_in_reject(sp
, m
);
2019 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2020 printf("DP ipsec6_in_reject_so call free SP:%p\n", sp
));
2021 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2027 ipsec6_in_reject(m
, in6p
)
2029 struct in6pcb
*in6p
;
2032 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2034 return ipsec6_in_reject_so(m
, NULL
);
2035 if (in6p
->in6p_socket
)
2036 return ipsec6_in_reject_so(m
, in6p
->in6p_socket
);
2038 panic("ipsec6_in_reject: invalid in6p/socket");
2046 * compute the byte size to be occupied by IPsec header.
2047 * in case it is tunneled, it includes the size of outer IP header.
2048 * NOTE: SP passed is free in this function.
2052 struct secpolicy
*sp
;
2054 struct ipsecrequest
*isr
;
2057 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2058 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2059 printf("ipsec_hdrsiz: using SP\n");
2060 kdebug_secpolicy(sp
));
2063 switch (sp
->policy
) {
2064 case IPSEC_POLICY_DISCARD
:
2065 case IPSEC_POLICY_GENERATE
:
2066 case IPSEC_POLICY_BYPASS
:
2067 case IPSEC_POLICY_NONE
:
2070 case IPSEC_POLICY_IPSEC
:
2073 case IPSEC_POLICY_ENTRUST
:
2075 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
);
2080 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
2084 switch (isr
->saidx
.proto
) {
2087 clen
= esp_hdrsiz(isr
);
2093 clen
= ah_hdrsiz(isr
);
2095 case IPPROTO_IPCOMP
:
2096 clen
= sizeof(struct ipcomp
);
2100 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
2101 switch (((struct sockaddr
*)&isr
->saidx
.dst
)->sa_family
) {
2103 clen
+= sizeof(struct ip
);
2107 clen
+= sizeof(struct ip6_hdr
);
2111 ipseclog((LOG_ERR
, "ipsec_hdrsiz: "
2112 "unknown AF %d in IPsec tunnel SA\n",
2113 ((struct sockaddr
*)&isr
->saidx
.dst
)->sa_family
));
2123 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
2125 ipsec4_hdrsiz(m
, dir
, inp
)
2130 struct secpolicy
*sp
= NULL
;
2134 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2137 return 0; /* XXX should be panic ? */
2138 if (inp
!= NULL
&& inp
->inp_socket
== NULL
)
2139 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
2141 /* get SP for this packet.
2142 * When we are called from ip_forward(), we call
2143 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2146 sp
= ipsec4_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
);
2148 sp
= ipsec4_getpolicybysock(m
, dir
, inp
->inp_socket
, &error
);
2151 return 0; /* XXX should be panic ? */
2153 size
= ipsec_hdrsiz(sp
);
2154 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2155 printf("DP ipsec4_hdrsiz call free SP:%p\n", sp
));
2156 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2157 printf("ipsec4_hdrsiz: size:%lu.\n", (u_int32_t
)size
));
2158 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2164 /* This function is called from ipsec6_hdrsize_tcp(),
2165 * and maybe from ip6_forward.()
2168 ipsec6_hdrsiz(m
, dir
, in6p
)
2171 struct in6pcb
*in6p
;
2173 struct secpolicy
*sp
= NULL
;
2177 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2180 return 0; /* XXX shoud be panic ? */
2181 if (in6p
!= NULL
&& in6p
->in6p_socket
== NULL
)
2182 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2184 /* get SP for this packet */
2185 /* XXX Is it right to call with IP_FORWARDING. */
2187 sp
= ipsec6_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
);
2189 sp
= ipsec6_getpolicybysock(m
, dir
, in6p
->in6p_socket
, &error
);
2193 size
= ipsec_hdrsiz(sp
);
2194 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2195 printf("DP ipsec6_hdrsiz call free SP:%p\n", sp
));
2196 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2197 printf("ipsec6_hdrsiz: size:%lu.\n", (u_int32_t
)size
));
2198 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2206 * encapsulate for ipsec tunnel.
2207 * ip->ip_src must be fixed later on.
2210 ipsec4_encapsulate(m
, sav
)
2212 struct secasvar
*sav
;
2219 /* can't tunnel between different AFs */
2220 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2221 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2222 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2227 /* XXX if the dst is myself, perform nothing. */
2228 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2234 if (m
->m_len
< sizeof(*ip
))
2235 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2237 ip
= mtod(m
, struct ip
*);
2239 hlen
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
2241 hlen
= ip
->ip_hl
<< 2;
2244 if (m
->m_len
!= hlen
)
2245 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2247 /* generate header checksum */
2250 ip
->ip_sum
= in_cksum(m
, hlen
);
2252 ip
->ip_sum
= in_cksum(m
, hlen
);
2255 plen
= m
->m_pkthdr
.len
;
2258 * grow the mbuf to accomodate the new IPv4 header.
2259 * NOTE: IPv4 options will never be copied.
2261 if (M_LEADINGSPACE(m
->m_next
) < hlen
) {
2263 MGET(n
, M_DONTWAIT
, MT_DATA
);
2269 n
->m_next
= m
->m_next
;
2271 m
->m_pkthdr
.len
+= hlen
;
2272 oip
= mtod(n
, struct ip
*);
2274 m
->m_next
->m_len
+= hlen
;
2275 m
->m_next
->m_data
-= hlen
;
2276 m
->m_pkthdr
.len
+= hlen
;
2277 oip
= mtod(m
->m_next
, struct ip
*);
2279 ip
= mtod(m
, struct ip
*);
2280 ovbcopy((caddr_t
)ip
, (caddr_t
)oip
, hlen
);
2281 m
->m_len
= sizeof(struct ip
);
2282 m
->m_pkthdr
.len
-= (hlen
- sizeof(struct ip
));
2284 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2285 /* ECN consideration. */
2286 ip_ecn_ingress(ip4_ipsec_ecn
, &ip
->ip_tos
, &oip
->ip_tos
);
2288 ip
->ip_vhl
= IP_MAKE_VHL(IPVERSION
, sizeof(struct ip
) >> 2);
2290 ip
->ip_hl
= sizeof(struct ip
) >> 2;
2292 ip
->ip_off
&= htons(~IP_OFFMASK
);
2293 ip
->ip_off
&= htons(~IP_MF
);
2294 switch (ip4_ipsec_dfbit
) {
2295 case 0: /* clear DF bit */
2296 ip
->ip_off
&= htons(~IP_DF
);
2298 case 1: /* set DF bit */
2299 ip
->ip_off
|= htons(IP_DF
);
2301 default: /* copy DF bit */
2304 ip
->ip_p
= IPPROTO_IPIP
;
2305 if (plen
+ sizeof(struct ip
) < IP_MAXPACKET
)
2306 ip
->ip_len
= htons(plen
+ sizeof(struct ip
));
2308 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2309 "leave ip_len as is (invalid packet)\n"));
2312 ip
->ip_id
= ip_randomid();
2314 ip
->ip_id
= htons(ip_id
++);
2316 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2317 &ip
->ip_src
, sizeof(ip
->ip_src
));
2318 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2319 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2320 ip
->ip_ttl
= IPDEFTTL
;
2322 /* XXX Should ip_src be updated later ? */
2328 * encapsulate for ipsec tunnel.
2329 * ip->ip_src must be fixed later on.
2332 ipsec4_encapsulate_utun_esp_keepalive(m_ptr
, sav
)
2333 struct mbuf
**m_ptr
;
2334 struct secasvar
*sav
;
2338 struct mbuf
*m
= *m_ptr
;
2340 /* can't tunnel between different AFs */
2341 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2342 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2343 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2349 plen
= m
->m_pkthdr
.len
;
2352 * grow the mbuf to accomodate the new IPv4 header.
2353 * NOTE: IPv4 options will never be copied.
2357 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
2363 if (m
->m_flags
& M_PKTHDR
) {
2364 M_COPY_PKTHDR(n
, m
);
2365 m
->m_flags
&= ~M_PKTHDR
;
2367 MH_ALIGN(n
, sizeof(*ip
));
2368 n
->m_len
= sizeof(*ip
);
2370 n
->m_pkthdr
.len
= (plen
+ n
->m_len
);
2374 plen
= m
->m_pkthdr
.len
;
2376 ip
= mtod(m
, __typeof__(ip
));
2378 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2379 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2381 ip
->ip_vhl
= IP_MAKE_VHL(IPVERSION
, sizeof(*ip
) >> 2);
2383 ip
->ip_hl
= sizeof(*ip
) >> 2;
2385 ip
->ip_off
&= htons(~IP_OFFMASK
);
2386 ip
->ip_off
&= htons(~IP_MF
);
2387 switch (ip4_ipsec_dfbit
) {
2388 case 0: /* clear DF bit */
2389 ip
->ip_off
&= htons(~IP_DF
);
2391 case 1: /* set DF bit */
2392 ip
->ip_off
|= htons(IP_DF
);
2394 default: /* copy DF bit */
2397 ip
->ip_p
= IPPROTO_IPIP
;
2398 if (plen
< IP_MAXPACKET
)
2399 ip
->ip_len
= htons(plen
);
2401 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2402 "leave ip_len as is (invalid packet)\n"));
2405 ip
->ip_id
= ip_randomid();
2407 ip
->ip_id
= htons(ip_id
++);
2409 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2410 &ip
->ip_src
, sizeof(ip
->ip_src
));
2411 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2412 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2413 ip
->ip_ttl
= IPDEFTTL
;
2415 /* XXX Should ip_src be updated later ? */
2423 ipsec6_encapsulate(m
, sav
)
2425 struct secasvar
*sav
;
2427 struct ip6_hdr
*oip6
;
2428 struct ip6_hdr
*ip6
;
2431 /* can't tunnel between different AFs */
2432 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2433 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2434 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET6
) {
2439 /* XXX if the dst is myself, perform nothing. */
2440 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2446 plen
= m
->m_pkthdr
.len
;
2449 * grow the mbuf to accomodate the new IPv6 header.
2451 if (m
->m_len
!= sizeof(struct ip6_hdr
))
2452 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2453 if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) {
2455 MGET(n
, M_DONTWAIT
, MT_DATA
);
2460 n
->m_len
= sizeof(struct ip6_hdr
);
2461 n
->m_next
= m
->m_next
;
2463 m
->m_pkthdr
.len
+= sizeof(struct ip6_hdr
);
2464 oip6
= mtod(n
, struct ip6_hdr
*);
2466 m
->m_next
->m_len
+= sizeof(struct ip6_hdr
);
2467 m
->m_next
->m_data
-= sizeof(struct ip6_hdr
);
2468 m
->m_pkthdr
.len
+= sizeof(struct ip6_hdr
);
2469 oip6
= mtod(m
->m_next
, struct ip6_hdr
*);
2471 ip6
= mtod(m
, struct ip6_hdr
*);
2472 ovbcopy((caddr_t
)ip6
, (caddr_t
)oip6
, sizeof(struct ip6_hdr
));
2474 /* Fake link-local scope-class addresses */
2475 if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_src
))
2476 oip6
->ip6_src
.s6_addr16
[1] = 0;
2477 if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_dst
))
2478 oip6
->ip6_dst
.s6_addr16
[1] = 0;
2480 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2481 /* ECN consideration. */
2482 ip6_ecn_ingress(ip6_ipsec_ecn
, &ip6
->ip6_flow
, &oip6
->ip6_flow
);
2483 if (plen
< IPV6_MAXPACKET
- sizeof(struct ip6_hdr
))
2484 ip6
->ip6_plen
= htons(plen
);
2486 /* ip6->ip6_plen will be updated in ip6_output() */
2488 ip6
->ip6_nxt
= IPPROTO_IPV6
;
2489 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.src
)->sin6_addr
,
2490 &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
2491 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
)->sin6_addr
,
2492 &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
2493 ip6
->ip6_hlim
= IPV6_DEFHLIM
;
2495 /* XXX Should ip6_src be updated later ? */
2501 ipsec64_encapsulate(m
, sav
)
2503 struct secasvar
*sav
;
2505 struct ip6_hdr
*ip6
, *ip6i
;
2510 /* tunneling over IPv4 */
2511 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2512 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2513 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2518 /* XXX if the dst is myself, perform nothing. */
2519 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2525 plen
= m
->m_pkthdr
.len
;
2526 ip6
= mtod(m
, struct ip6_hdr
*);
2527 hlim
= ip6
->ip6_hlim
;
2529 * grow the mbuf to accomodate the new IPv4 header.
2531 if (m
->m_len
!= sizeof(struct ip6_hdr
))
2532 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2533 if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) {
2535 MGET(n
, M_DONTWAIT
, MT_DATA
);
2540 n
->m_len
= sizeof(struct ip6_hdr
);
2541 n
->m_next
= m
->m_next
;
2543 m
->m_pkthdr
.len
+= sizeof(struct ip
);
2544 ip6i
= mtod(n
, struct ip6_hdr
*);
2546 m
->m_next
->m_len
+= sizeof(struct ip6_hdr
);
2547 m
->m_next
->m_data
-= sizeof(struct ip6_hdr
);
2548 m
->m_pkthdr
.len
+= sizeof(struct ip
);
2549 ip6i
= mtod(m
->m_next
, struct ip6_hdr
*);
2551 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2552 /* ECN consideration. */
2553 /* XXX To be fixed later if needed */
2554 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2556 bcopy(ip6
, ip6i
, sizeof(struct ip6_hdr
));
2557 ip
= mtod(m
, struct ip
*);
2558 m
->m_len
= sizeof(struct ip
);
2560 * Fill in some of the IPv4 fields - we don't need all of them
2561 * because the rest will be filled in by ip_output
2563 ip
->ip_v
= IPVERSION
;
2564 ip
->ip_hl
= sizeof(struct ip
) >> 2;
2570 ip
->ip_p
= IPPROTO_IPV6
;
2571 if (plen
+ sizeof(struct ip
) < IP_MAXPACKET
)
2572 ip
->ip_len
= htons(plen
+ sizeof(struct ip
));
2574 ip
->ip_len
= htons(plen
);
2575 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2576 "leave ip_len as is (invalid packet)\n"));
2578 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2579 &ip
->ip_src
, sizeof(ip
->ip_src
));
2580 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2581 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2587 ipsec6_encapsulate_utun_esp_keepalive(m_ptr
, sav
)
2588 struct mbuf
**m_ptr
;
2589 struct secasvar
*sav
;
2591 struct ip6_hdr
*ip6
;
2593 struct mbuf
*m
= *m_ptr
;
2595 /* can't tunnel between different AFs */
2596 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2597 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2598 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET6
) {
2604 plen
= m
->m_pkthdr
.len
;
2607 * grow the mbuf to accomodate the new IPv6 header.
2611 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
2617 if (m
->m_flags
& M_PKTHDR
) {
2618 M_COPY_PKTHDR(n
, m
);
2619 m
->m_flags
&= ~M_PKTHDR
;
2621 MH_ALIGN(n
, sizeof(*ip6
));
2622 n
->m_len
= sizeof(*ip6
);
2624 n
->m_pkthdr
.len
= (plen
+ n
->m_len
);
2628 plen
= m
->m_pkthdr
.len
;
2630 ip6
= mtod(m
, __typeof__(ip6
));
2632 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2633 if (plen
< IPV6_MAXPACKET
)
2634 ip6
->ip6_plen
= htons(plen
);
2636 /* ip6->ip6_plen will be updated in ip6_output() */
2638 ip6
->ip6_nxt
= IPPROTO_IPV6
;
2639 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.src
)->sin6_addr
,
2640 &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
2641 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
)->sin6_addr
,
2642 &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
2643 ip6
->ip6_hlim
= IPV6_DEFHLIM
;
2645 /* XXX Should ip6_src be updated later ? */
2652 * Check the variable replay window.
2653 * ipsec_chkreplay() performs replay check before ICV verification.
2654 * ipsec_updatereplay() updates replay bitmap. This must be called after
2655 * ICV verification (it also performs replay check, which is usually done
2657 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2659 * based on RFC 2401.
2662 ipsec_chkreplay(seq
, sav
)
2664 struct secasvar
*sav
;
2666 const struct secreplay
*replay
;
2669 u_int32_t wsizeb
; /* constant: bits of window size */
2670 int frlast
; /* constant: last frame */
2675 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2677 lck_mtx_lock(sadb_mutex
);
2678 replay
= sav
->replay
;
2680 if (replay
->wsize
== 0) {
2681 lck_mtx_unlock(sadb_mutex
);
2682 return 1; /* no need to check replay. */
2686 frlast
= replay
->wsize
- 1;
2687 wsizeb
= replay
->wsize
<< 3;
2689 /* sequence number of 0 is invalid */
2691 lck_mtx_unlock(sadb_mutex
);
2695 /* first time is always okay */
2696 if (replay
->count
== 0) {
2697 lck_mtx_unlock(sadb_mutex
);
2701 if (seq
> replay
->lastseq
) {
2702 /* larger sequences are okay */
2703 lck_mtx_unlock(sadb_mutex
);
2706 /* seq is equal or less than lastseq. */
2707 diff
= replay
->lastseq
- seq
;
2709 /* over range to check, i.e. too old or wrapped */
2710 if (diff
>= wsizeb
) {
2711 lck_mtx_unlock(sadb_mutex
);
2715 fr
= frlast
- diff
/ 8;
2717 /* this packet already seen ? */
2718 if ((replay
->bitmap
)[fr
] & (1 << (diff
% 8))) {
2719 lck_mtx_unlock(sadb_mutex
);
2723 /* out of order but good */
2724 lck_mtx_unlock(sadb_mutex
);
2730 * check replay counter whether to update or not.
2735 ipsec_updatereplay(seq
, sav
)
2737 struct secasvar
*sav
;
2739 struct secreplay
*replay
;
2742 u_int32_t wsizeb
; /* constant: bits of window size */
2743 int frlast
; /* constant: last frame */
2747 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2749 lck_mtx_lock(sadb_mutex
);
2750 replay
= sav
->replay
;
2752 if (replay
->wsize
== 0)
2753 goto ok
; /* no need to check replay. */
2756 frlast
= replay
->wsize
- 1;
2757 wsizeb
= replay
->wsize
<< 3;
2759 /* sequence number of 0 is invalid */
2764 if (replay
->count
== 0) {
2765 replay
->lastseq
= seq
;
2766 bzero(replay
->bitmap
, replay
->wsize
);
2767 (replay
->bitmap
)[frlast
] = 1;
2771 if (seq
> replay
->lastseq
) {
2772 /* seq is larger than lastseq. */
2773 diff
= seq
- replay
->lastseq
;
2775 /* new larger sequence number */
2776 if (diff
< wsizeb
) {
2778 /* set bit for this packet */
2779 vshiftl((unsigned char *) replay
->bitmap
, diff
, replay
->wsize
);
2780 (replay
->bitmap
)[frlast
] |= 1;
2782 /* this packet has a "way larger" */
2783 bzero(replay
->bitmap
, replay
->wsize
);
2784 (replay
->bitmap
)[frlast
] = 1;
2786 replay
->lastseq
= seq
;
2788 /* larger is good */
2790 /* seq is equal or less than lastseq. */
2791 diff
= replay
->lastseq
- seq
;
2793 /* over range to check, i.e. too old or wrapped */
2794 if (diff
>= wsizeb
) {
2795 lck_mtx_unlock(sadb_mutex
);
2799 fr
= frlast
- diff
/ 8;
2801 /* this packet already seen ? */
2802 if ((replay
->bitmap
)[fr
] & (1 << (diff
% 8))) {
2803 lck_mtx_unlock(sadb_mutex
);
2808 (replay
->bitmap
)[fr
] |= (1 << (diff
% 8));
2810 /* out of order but good */
2814 if (replay
->count
== ~0) {
2816 /* set overflow flag */
2819 /* don't increment, no more packets accepted */
2820 if ((sav
->flags
& SADB_X_EXT_CYCSEQ
) == 0) {
2821 lck_mtx_unlock(sadb_mutex
);
2825 ipseclog((LOG_WARNING
, "replay counter made %d cycle. %s\n",
2826 replay
->overflow
, ipsec_logsastr(sav
)));
2831 lck_mtx_unlock(sadb_mutex
);
2836 * shift variable length buffer to left.
2837 * IN: bitmap: pointer to the buffer
2838 * nbit: the number of to shift.
2839 * wsize: buffer size (bytes).
2842 vshiftl(bitmap
, nbit
, wsize
)
2843 unsigned char *bitmap
;
2849 for (j
= 0; j
< nbit
; j
+= 8) {
2850 s
= (nbit
- j
< 8) ? (nbit
- j
): 8;
2852 for (i
= 1; i
< wsize
; i
++) {
2853 over
= (bitmap
[i
] >> (8 - s
));
2855 bitmap
[i
-1] |= over
;
2863 ipsec4_logpacketstr(ip
, spi
)
2867 static char buf
[256] __attribute__((aligned(4)));
2871 s
= (u_int8_t
*)(&ip
->ip_src
);
2872 d
= (u_int8_t
*)(&ip
->ip_dst
);
2875 snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
));
2878 snprintf(p
, sizeof(buf
) - (p
- buf
), "src=%u.%u.%u.%u",
2879 s
[0], s
[1], s
[2], s
[3]);
2882 snprintf(p
, sizeof(buf
) - (p
- buf
), " dst=%u.%u.%u.%u",
2883 d
[0], d
[1], d
[2], d
[3]);
2886 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
2893 ipsec6_logpacketstr(ip6
, spi
)
2894 struct ip6_hdr
*ip6
;
2897 static char buf
[256] __attribute__((aligned(4)));
2901 snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
));
2904 snprintf(p
, sizeof(buf
) - (p
- buf
), "src=%s",
2905 ip6_sprintf(&ip6
->ip6_src
));
2908 snprintf(p
, sizeof(buf
) - (p
- buf
), " dst=%s",
2909 ip6_sprintf(&ip6
->ip6_dst
));
2912 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
2920 struct secasvar
*sav
;
2922 static char buf
[256] __attribute__((aligned(4)));
2924 struct secasindex
*saidx
= &sav
->sah
->saidx
;
2926 /* validity check */
2927 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2928 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
)
2929 panic("ipsec_logsastr: family mismatched.\n");
2932 snprintf(buf
, sizeof(buf
), "SA(SPI=%u ", (u_int32_t
)ntohl(sav
->spi
));
2935 if (((struct sockaddr
*)&saidx
->src
)->sa_family
== AF_INET
) {
2937 s
= (u_int8_t
*)&((struct sockaddr_in
*)&saidx
->src
)->sin_addr
;
2938 d
= (u_int8_t
*)&((struct sockaddr_in
*)&saidx
->dst
)->sin_addr
;
2939 snprintf(p
, sizeof(buf
) - (p
- buf
),
2940 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
2941 s
[0], s
[1], s
[2], s
[3], d
[0], d
[1], d
[2], d
[3]);
2944 else if (((struct sockaddr
*)&saidx
->src
)->sa_family
== AF_INET6
) {
2945 snprintf(p
, sizeof(buf
) - (p
- buf
),
2947 ip6_sprintf(&((struct sockaddr_in6
*)&saidx
->src
)->sin6_addr
));
2950 snprintf(p
, sizeof(buf
) - (p
- buf
),
2952 ip6_sprintf(&((struct sockaddr_in6
*)&saidx
->dst
)->sin6_addr
));
2957 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
2973 p
= mtod(m
, u_char
*);
2974 for (i
= 0; i
< m
->m_len
; i
++) {
2975 printf("%02x ", p
[i
]);
2977 if (totlen
% 16 == 0)
2982 if (totlen
% 16 != 0)
2989 * IPsec output logic for IPv4.
2993 struct ipsec_output_state
*state
,
2994 struct secpolicy
*sp
,
2997 struct ip
*ip
= NULL
;
2998 struct ipsecrequest
*isr
= NULL
;
2999 struct secasindex saidx
;
3000 struct secasvar
*sav
= NULL
;
3002 struct sockaddr_in
*dst4
;
3003 struct sockaddr_in
*sin
;
3006 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3009 panic("state == NULL in ipsec4_output");
3011 panic("state->m == NULL in ipsec4_output");
3013 panic("state->dst == NULL in ipsec4_output");
3015 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_START
, 0,0,0,0,0);
3017 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3018 printf("ipsec4_output: applyed SP\n");
3019 kdebug_secpolicy(sp
));
3021 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
3023 #if 0 /* give up to check restriction of transport mode */
3024 /* XXX but should be checked somewhere */
3026 * some of the IPsec operation must be performed only in
3029 if (isr
->saidx
.mode
== IPSEC_MODE_TRANSPORT
3030 && (flags
& IP_FORWARDING
))
3034 /* make SA index for search proper SA */
3035 ip
= mtod(state
->m
, struct ip
*);
3036 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3037 saidx
.mode
= isr
->saidx
.mode
;
3038 saidx
.reqid
= isr
->saidx
.reqid
;
3039 sin
= (struct sockaddr_in
*)&saidx
.src
;
3040 if (sin
->sin_len
== 0) {
3041 sin
->sin_len
= sizeof(*sin
);
3042 sin
->sin_family
= AF_INET
;
3043 sin
->sin_port
= IPSEC_PORT_ANY
;
3044 bcopy(&ip
->ip_src
, &sin
->sin_addr
,
3045 sizeof(sin
->sin_addr
));
3047 sin
= (struct sockaddr_in
*)&saidx
.dst
;
3048 if (sin
->sin_len
== 0) {
3049 sin
->sin_len
= sizeof(*sin
);
3050 sin
->sin_family
= AF_INET
;
3051 sin
->sin_port
= IPSEC_PORT_ANY
;
3053 * Get port from packet if upper layer is UDP and nat traversal
3054 * is enabled and transport mode.
3057 if ((esp_udp_encap_port
& 0xFFFF) != 0 &&
3058 isr
->saidx
.mode
== IPSEC_MODE_TRANSPORT
) {
3060 if (ip
->ip_p
== IPPROTO_UDP
) {
3064 hlen
= IP_VHL_HL(ip
->ip_vhl
) << 2;
3066 hlen
= ip
->ip_hl
<< 2;
3068 if (state
->m
->m_len
< hlen
+ sizeof(struct udphdr
)) {
3069 state
->m
= m_pullup(state
->m
, hlen
+ sizeof(struct udphdr
));
3071 ipseclog((LOG_DEBUG
,
3072 "IPv4 output: can't pullup UDP header\n"));
3073 IPSEC_STAT_INCREMENT(ipsecstat
.in_inval
);
3076 ip
= mtod(state
->m
, struct ip
*);
3078 udp
= (struct udphdr
*)(void *)(((u_int8_t
*)ip
) + hlen
);
3079 sin
->sin_port
= udp
->uh_dport
;
3083 bcopy(&ip
->ip_dst
, &sin
->sin_addr
,
3084 sizeof(sin
->sin_addr
));
3087 if ((error
= key_checkrequest(isr
, &saidx
, &sav
)) != 0) {
3089 * IPsec processing is required, but no SA found.
3090 * I assume that key_acquire() had been called
3091 * to get/establish the SA. Here I discard
3092 * this packet because it is responsibility for
3093 * upper layer to retransmit the packet.
3095 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
);
3099 /* validity check */
3101 switch (ipsec_get_reqlevel(isr
)) {
3102 case IPSEC_LEVEL_USE
:
3104 case IPSEC_LEVEL_REQUIRE
:
3105 /* must be not reached here. */
3106 panic("ipsec4_output: no SA found, but required.");
3111 * If there is no valid SA, we give up to process any
3112 * more. In such a case, the SA's status is changed
3113 * from DYING to DEAD after allocating. If a packet
3114 * send to the receiver by dead SA, the receiver can
3115 * not decode a packet because SA has been dead.
3117 if (sav
->state
!= SADB_SASTATE_MATURE
3118 && sav
->state
!= SADB_SASTATE_DYING
) {
3119 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
);
3125 * There may be the case that SA status will be changed when
3126 * we are refering to one. So calling splsoftnet().
3129 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3131 * build IPsec tunnel.
3133 /* XXX should be processed with other familiy */
3134 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
3135 ipseclog((LOG_ERR
, "ipsec4_output: "
3136 "family mismatched between inner and outer spi=%u\n",
3137 (u_int32_t
)ntohl(sav
->spi
)));
3138 error
= EAFNOSUPPORT
;
3142 state
->m
= ipsec4_splithdr(state
->m
);
3147 error
= ipsec4_encapsulate(state
->m
, sav
);
3152 ip
= mtod(state
->m
, struct ip
*);
3154 // grab sadb_mutex, before updating sah's route cache
3155 lck_mtx_lock(sadb_mutex
);
3156 ro4
= &sav
->sah
->sa_route
;
3157 dst4
= (struct sockaddr_in
*)(void *)&ro4
->ro_dst
;
3158 if (ro4
->ro_rt
!= NULL
) {
3159 RT_LOCK(ro4
->ro_rt
);
3161 if (ro4
->ro_rt
!= NULL
&&
3162 (ro4
->ro_rt
->generation_id
!= route_generation
||
3163 !(ro4
->ro_rt
->rt_flags
& RTF_UP
) ||
3164 dst4
->sin_addr
.s_addr
!= ip
->ip_dst
.s_addr
)) {
3165 RT_UNLOCK(ro4
->ro_rt
);
3169 if (ro4
->ro_rt
== 0) {
3170 dst4
->sin_family
= AF_INET
;
3171 dst4
->sin_len
= sizeof(*dst4
);
3172 dst4
->sin_addr
= ip
->ip_dst
;
3174 if (ro4
->ro_rt
== 0) {
3175 OSAddAtomic(1, &ipstat
.ips_noroute
);
3176 error
= EHOSTUNREACH
;
3177 // release sadb_mutex, after updating sah's route cache
3178 lck_mtx_unlock(sadb_mutex
);
3181 RT_LOCK(ro4
->ro_rt
);
3185 * adjust state->dst if tunnel endpoint is offlink
3187 * XXX: caching rt_gateway value in the state is
3188 * not really good, since it may point elsewhere
3189 * when the gateway gets modified to a larger
3190 * sockaddr via rt_setgate(). This is currently
3191 * addressed by SA_SIZE roundup in that routine.
3193 if (ro4
->ro_rt
->rt_flags
& RTF_GATEWAY
)
3194 dst4
= (struct sockaddr_in
*)(void *)ro4
->ro_rt
->rt_gateway
;
3195 RT_UNLOCK(ro4
->ro_rt
);
3196 if (state
->ro
.ro_rt
!= NULL
) {
3197 rtfree(state
->ro
.ro_rt
);
3198 state
->ro
.ro_rt
= NULL
;
3200 route_copyout(&state
->ro
, ro4
, sizeof(state
->ro
));
3201 state
->dst
= (struct sockaddr
*)dst4
;
3202 state
->tunneled
= 4;
3203 // release sadb_mutex, after updating sah's route cache
3204 lck_mtx_unlock(sadb_mutex
);
3207 state
->m
= ipsec4_splithdr(state
->m
);
3212 switch (isr
->saidx
.proto
) {
3215 if ((error
= esp4_output(state
->m
, sav
)) != 0) {
3227 if ((error
= ah4_output(state
->m
, sav
)) != 0) {
3232 case IPPROTO_IPCOMP
:
3233 if ((error
= ipcomp4_output(state
->m
, sav
)) != 0) {
3240 "ipsec4_output: unknown ipsec protocol %d\n",
3248 if (state
->m
== 0) {
3252 ip
= mtod(state
->m
, struct ip
*);
3255 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, 0,0,0,0,0);
3257 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3262 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3265 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, error
,0,0,0,0);
3272 * IPsec output logic for IPv6, transport mode.
3275 ipsec6_output_trans(
3276 struct ipsec_output_state
*state
,
3279 struct secpolicy
*sp
,
3283 struct ip6_hdr
*ip6
;
3284 struct ipsecrequest
*isr
= NULL
;
3285 struct secasindex saidx
;
3288 struct sockaddr_in6
*sin6
;
3289 struct secasvar
*sav
= NULL
;
3291 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3294 panic("state == NULL in ipsec6_output_trans");
3296 panic("state->m == NULL in ipsec6_output_trans");
3298 panic("nexthdrp == NULL in ipsec6_output_trans");
3300 panic("mprev == NULL in ipsec6_output_trans");
3302 panic("sp == NULL in ipsec6_output_trans");
3304 panic("tun == NULL in ipsec6_output_trans");
3306 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3307 printf("ipsec6_output_trans: applyed SP\n");
3308 kdebug_secpolicy(sp
));
3311 for (isr
= sp
->req
; isr
; isr
= isr
->next
) {
3312 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3313 /* the rest will be handled by ipsec6_output_tunnel() */
3317 /* make SA index for search proper SA */
3318 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3319 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3320 saidx
.mode
= isr
->saidx
.mode
;
3321 saidx
.reqid
= isr
->saidx
.reqid
;
3322 sin6
= (struct sockaddr_in6
*)&saidx
.src
;
3323 if (sin6
->sin6_len
== 0) {
3324 sin6
->sin6_len
= sizeof(*sin6
);
3325 sin6
->sin6_family
= AF_INET6
;
3326 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3327 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
,
3328 sizeof(ip6
->ip6_src
));
3329 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
3330 /* fix scope id for comparing SPD */
3331 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3332 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
3335 sin6
= (struct sockaddr_in6
*)&saidx
.dst
;
3336 if (sin6
->sin6_len
== 0) {
3337 sin6
->sin6_len
= sizeof(*sin6
);
3338 sin6
->sin6_family
= AF_INET6
;
3339 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3340 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
,
3341 sizeof(ip6
->ip6_dst
));
3342 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
3343 /* fix scope id for comparing SPD */
3344 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3345 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
3349 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) {
3351 * IPsec processing is required, but no SA found.
3352 * I assume that key_acquire() had been called
3353 * to get/establish the SA. Here I discard
3354 * this packet because it is responsibility for
3355 * upper layer to retransmit the packet.
3357 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3361 * Notify the fact that the packet is discarded
3362 * to ourselves. I believe this is better than
3363 * just silently discarding. (jinmei@kame.net)
3364 * XXX: should we restrict the error to TCP packets?
3365 * XXX: should we directly notify sockets via
3368 icmp6_error(state
->m
, ICMP6_DST_UNREACH
,
3369 ICMP6_DST_UNREACH_ADMIN
, 0);
3370 state
->m
= NULL
; /* icmp6_error freed the mbuf */
3374 /* validity check */
3376 switch (ipsec_get_reqlevel(isr
)) {
3377 case IPSEC_LEVEL_USE
:
3379 case IPSEC_LEVEL_REQUIRE
:
3380 /* must be not reached here. */
3381 panic("ipsec6_output_trans: no SA found, but required.");
3386 * If there is no valid SA, we give up to process.
3387 * see same place at ipsec4_output().
3389 if (sav
->state
!= SADB_SASTATE_MATURE
3390 && sav
->state
!= SADB_SASTATE_DYING
) {
3391 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3396 switch (isr
->saidx
.proto
) {
3399 error
= esp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3406 error
= ah6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3408 case IPPROTO_IPCOMP
:
3409 error
= ipcomp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3412 ipseclog((LOG_ERR
, "ipsec6_output_trans: "
3413 "unknown ipsec protocol %d\n", isr
->saidx
.proto
));
3415 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3423 plen
= state
->m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
3424 if (plen
> IPV6_MAXPACKET
) {
3425 ipseclog((LOG_ERR
, "ipsec6_output_trans: "
3426 "IPsec with IPv6 jumbogram is not supported\n"));
3427 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3428 error
= EINVAL
; /*XXX*/
3431 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3432 ip6
->ip6_plen
= htons(plen
);
3435 /* if we have more to go, we need a tunnel mode processing */
3440 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3445 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3452 * IPsec output logic for IPv6, tunnel mode.
3455 ipsec6_output_tunnel(
3456 struct ipsec_output_state
*state
,
3457 struct secpolicy
*sp
,
3460 struct ip6_hdr
*ip6
;
3461 struct ipsecrequest
*isr
= NULL
;
3462 struct secasindex saidx
;
3463 struct secasvar
*sav
= NULL
;
3466 struct sockaddr_in6
* dst6
;
3469 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3472 panic("state == NULL in ipsec6_output_tunnel");
3474 panic("state->m == NULL in ipsec6_output_tunnel");
3476 panic("sp == NULL in ipsec6_output_tunnel");
3478 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3479 printf("ipsec6_output_tunnel: applyed SP\n");
3480 kdebug_secpolicy(sp
));
3483 * transport mode ipsec (before the 1st tunnel mode) is already
3484 * processed by ipsec6_output_trans().
3486 for (isr
= sp
->req
; isr
; isr
= isr
->next
) {
3487 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
3491 for (/* already initialized */; isr
; isr
= isr
->next
) {
3492 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3493 /* When tunnel mode, SA peers must be specified. */
3494 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3496 /* make SA index to look for a proper SA */
3497 struct sockaddr_in6
*sin6
;
3499 bzero(&saidx
, sizeof(saidx
));
3500 saidx
.proto
= isr
->saidx
.proto
;
3501 saidx
.mode
= isr
->saidx
.mode
;
3502 saidx
.reqid
= isr
->saidx
.reqid
;
3504 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3505 sin6
= (struct sockaddr_in6
*)&saidx
.src
;
3506 if (sin6
->sin6_len
== 0) {
3507 sin6
->sin6_len
= sizeof(*sin6
);
3508 sin6
->sin6_family
= AF_INET6
;
3509 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3510 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
,
3511 sizeof(ip6
->ip6_src
));
3512 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
3513 /* fix scope id for comparing SPD */
3514 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3515 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
3518 sin6
= (struct sockaddr_in6
*)&saidx
.dst
;
3519 if (sin6
->sin6_len
== 0) {
3520 sin6
->sin6_len
= sizeof(*sin6
);
3521 sin6
->sin6_family
= AF_INET6
;
3522 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3523 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
,
3524 sizeof(ip6
->ip6_dst
));
3525 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
3526 /* fix scope id for comparing SPD */
3527 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3528 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
3533 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) {
3535 * IPsec processing is required, but no SA found.
3536 * I assume that key_acquire() had been called
3537 * to get/establish the SA. Here I discard
3538 * this packet because it is responsibility for
3539 * upper layer to retransmit the packet.
3541 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3546 /* validity check */
3548 switch (ipsec_get_reqlevel(isr
)) {
3549 case IPSEC_LEVEL_USE
:
3551 case IPSEC_LEVEL_REQUIRE
:
3552 /* must be not reached here. */
3553 panic("ipsec6_output_tunnel: no SA found, but required.");
3558 * If there is no valid SA, we give up to process.
3559 * see same place at ipsec4_output().
3561 if (sav
->state
!= SADB_SASTATE_MATURE
3562 && sav
->state
!= SADB_SASTATE_DYING
) {
3563 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3568 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3570 * build IPsec tunnel.
3572 state
->m
= ipsec6_splithdr(state
->m
);
3574 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
);
3579 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
== AF_INET6
) {
3580 error
= ipsec6_encapsulate(state
->m
, sav
);
3585 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3586 } else if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
== AF_INET
) {
3589 struct sockaddr_in
* dst4
;
3590 struct route
*ro4
= NULL
;
3591 struct route ro4_copy
;
3592 struct ip_out_args ipoa
= { IFSCOPE_NONE
, { 0 },
3593 IPOAF_SELECT_SRCIF
};
3596 * must be last isr because encapsulated IPv6 packet
3597 * will be sent by calling ip_output
3600 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3601 "IPv4 must be outer layer, spi=%u\n",
3602 (u_int32_t
)ntohl(sav
->spi
)));
3606 state
->tunneled
= 4; /* must not process any further in ip6_output */
3607 error
= ipsec64_encapsulate(state
->m
, sav
);
3612 /* Now we have an IPv4 packet */
3613 ip
= mtod(state
->m
, struct ip
*);
3615 // grab sadb_mutex, to update sah's route cache and get a local copy of it
3616 lck_mtx_lock(sadb_mutex
);
3617 ro4
= &sav
->sah
->sa_route
;
3618 dst4
= (struct sockaddr_in
*)(void *)&ro4
->ro_dst
;
3620 RT_LOCK(ro4
->ro_rt
);
3622 if (ro4
->ro_rt
!= NULL
&&
3623 (ro4
->ro_rt
->generation_id
!= route_generation
||
3624 !(ro4
->ro_rt
->rt_flags
& RTF_UP
) ||
3625 dst4
->sin_addr
.s_addr
!= ip
->ip_dst
.s_addr
)) {
3626 RT_UNLOCK(ro4
->ro_rt
);
3630 if (ro4
->ro_rt
== NULL
) {
3631 dst4
->sin_family
= AF_INET
;
3632 dst4
->sin_len
= sizeof(*dst4
);
3633 dst4
->sin_addr
= ip
->ip_dst
;
3635 RT_UNLOCK(ro4
->ro_rt
);
3637 route_copyout(&ro4_copy
, ro4
, sizeof(ro4_copy
));
3638 // release sadb_mutex, after updating sah's route cache and getting a local copy
3639 lck_mtx_unlock(sadb_mutex
);
3640 state
->m
= ipsec4_splithdr(state
->m
);
3643 if (ro4_copy
.ro_rt
!= NULL
) {
3644 rtfree(ro4_copy
.ro_rt
);
3648 switch (isr
->saidx
.proto
) {
3651 if ((error
= esp4_output(state
->m
, sav
)) != 0) {
3653 if (ro4_copy
.ro_rt
!= NULL
) {
3654 rtfree(ro4_copy
.ro_rt
);
3664 if (ro4_copy
.ro_rt
!= NULL
) {
3665 rtfree(ro4_copy
.ro_rt
);
3670 if ((error
= ah4_output(state
->m
, sav
)) != 0) {
3672 if (ro4_copy
.ro_rt
!= NULL
) {
3673 rtfree(ro4_copy
.ro_rt
);
3678 case IPPROTO_IPCOMP
:
3679 if ((error
= ipcomp4_output(state
->m
, sav
)) != 0) {
3681 if (ro4_copy
.ro_rt
!= NULL
) {
3682 rtfree(ro4_copy
.ro_rt
);
3689 "ipsec4_output: unknown ipsec protocol %d\n",
3694 if (ro4_copy
.ro_rt
!= NULL
) {
3695 rtfree(ro4_copy
.ro_rt
);
3700 if (state
->m
== 0) {
3702 if (ro4_copy
.ro_rt
!= NULL
) {
3703 rtfree(ro4_copy
.ro_rt
);
3707 ip
= mtod(state
->m
, struct ip
*);
3708 ip
->ip_len
= ntohs(ip
->ip_len
); /* flip len field before calling ip_output */
3709 error
= ip_output(state
->m
, NULL
, &ro4_copy
, IP_OUTARGS
, NULL
, &ipoa
);
3711 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
3712 lck_mtx_lock(sadb_mutex
);
3713 route_copyin(&ro4_copy
, ro4
, sizeof(ro4_copy
));
3714 lck_mtx_unlock(sadb_mutex
);
3719 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3720 "unsupported inner family, spi=%u\n",
3721 (u_int32_t
)ntohl(sav
->spi
)));
3722 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3723 error
= EAFNOSUPPORT
;
3727 // grab sadb_mutex, before updating sah's route cache
3728 lck_mtx_lock(sadb_mutex
);
3729 ro6
= &sav
->sah
->sa_route
;
3730 dst6
= (struct sockaddr_in6
*)(void *)&ro6
->ro_dst
;
3732 RT_LOCK(ro6
->ro_rt
);
3734 if (ro6
->ro_rt
!= NULL
&&
3735 (ro6
->ro_rt
->generation_id
!= route_generation
||
3736 !(ro6
->ro_rt
->rt_flags
& RTF_UP
) ||
3737 !IN6_ARE_ADDR_EQUAL(&dst6
->sin6_addr
, &ip6
->ip6_dst
))) {
3738 RT_UNLOCK(ro6
->ro_rt
);
3742 if (ro6
->ro_rt
== 0) {
3743 bzero(dst6
, sizeof(*dst6
));
3744 dst6
->sin6_family
= AF_INET6
;
3745 dst6
->sin6_len
= sizeof(*dst6
);
3746 dst6
->sin6_addr
= ip6
->ip6_dst
;
3749 RT_LOCK(ro6
->ro_rt
);
3752 if (ro6
->ro_rt
== 0) {
3753 ip6stat
.ip6s_noroute
++;
3754 IPSEC_STAT_INCREMENT(ipsec6stat
.out_noroute
);
3755 error
= EHOSTUNREACH
;
3756 // release sadb_mutex, after updating sah's route cache
3757 lck_mtx_unlock(sadb_mutex
);
3762 * adjust state->dst if tunnel endpoint is offlink
3764 * XXX: caching rt_gateway value in the state is
3765 * not really good, since it may point elsewhere
3766 * when the gateway gets modified to a larger
3767 * sockaddr via rt_setgate(). This is currently
3768 * addressed by SA_SIZE roundup in that routine.
3770 if (ro6
->ro_rt
->rt_flags
& RTF_GATEWAY
)
3771 dst6
= (struct sockaddr_in6
*)(void *)ro6
->ro_rt
->rt_gateway
;
3772 RT_UNLOCK(ro6
->ro_rt
);
3773 if (state
->ro
.ro_rt
!= NULL
) {
3774 rtfree(state
->ro
.ro_rt
);
3775 state
->ro
.ro_rt
= NULL
;
3777 route_copyout(&state
->ro
, ro6
, sizeof(state
->ro
));
3778 state
->dst
= (struct sockaddr
*)dst6
;
3779 state
->tunneled
= 6;
3780 // release sadb_mutex, after updating sah's route cache
3781 lck_mtx_unlock(sadb_mutex
);
3784 state
->m
= ipsec6_splithdr(state
->m
);
3786 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
);
3790 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3791 switch (isr
->saidx
.proto
) {
3794 error
= esp6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
);
3801 error
= ah6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
);
3803 case IPPROTO_IPCOMP
:
3804 /* XXX code should be here */
3807 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3808 "unknown ipsec protocol %d\n", isr
->saidx
.proto
));
3810 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3818 plen
= state
->m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
3819 if (plen
> IPV6_MAXPACKET
) {
3820 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3821 "IPsec with IPv6 jumbogram is not supported\n"));
3822 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3823 error
= EINVAL
; /*XXX*/
3826 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3827 ip6
->ip6_plen
= htons(plen
);
3831 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3836 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3846 * Chop IP header and option off from the payload.
3856 if (m
->m_len
< sizeof(struct ip
))
3857 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
);
3858 ip
= mtod(m
, struct ip
*);
3860 hlen
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
3862 hlen
= ip
->ip_hl
<< 2;
3864 if (m
->m_len
> hlen
) {
3865 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
3870 M_COPY_PKTHDR(mh
, m
);
3872 m
->m_flags
&= ~M_PKTHDR
;
3873 m_mchtype(m
, MT_DATA
);
3879 bcopy((caddr_t
)ip
, mtod(m
, caddr_t
), hlen
);
3880 } else if (m
->m_len
< hlen
) {
3881 m
= m_pullup(m
, hlen
);
3895 struct ip6_hdr
*ip6
;
3898 if (m
->m_len
< sizeof(struct ip6_hdr
))
3899 panic("ipsec6_splithdr: first mbuf too short");
3900 ip6
= mtod(m
, struct ip6_hdr
*);
3901 hlen
= sizeof(struct ip6_hdr
);
3902 if (m
->m_len
> hlen
) {
3903 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
3908 M_COPY_PKTHDR(mh
, m
);
3910 m
->m_flags
&= ~M_PKTHDR
;
3911 m_mchtype(m
, MT_DATA
);
3917 bcopy((caddr_t
)ip6
, mtod(m
, caddr_t
), hlen
);
3918 } else if (m
->m_len
< hlen
) {
3919 m
= m_pullup(m
, hlen
);
3927 /* validate inbound IPsec tunnel packet. */
3929 ipsec4_tunnel_validate(m
, off
, nxt0
, sav
, ifamily
)
3930 struct mbuf
*m
; /* no pullup permitted, m->m_len >= ip */
3933 struct secasvar
*sav
;
3934 sa_family_t
*ifamily
;
3936 u_int8_t nxt
= nxt0
& 0xff;
3937 struct sockaddr_in
*sin
;
3938 struct sockaddr_in osrc
, odst
, i4src
, i4dst
;
3939 struct sockaddr_in6 i6src
, i6dst
;
3941 struct secpolicy
*sp
;
3944 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3947 if (m
->m_len
< sizeof(struct ip
))
3948 panic("too short mbuf on ipsec4_tunnel_validate");
3950 if (nxt
!= IPPROTO_IPV4
&& nxt
!= IPPROTO_IPV6
)
3952 if (m
->m_pkthdr
.len
< off
+ sizeof(struct ip
))
3954 /* do not decapsulate if the SA is for transport mode only */
3955 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
3958 oip
= mtod(m
, struct ip
*);
3960 hlen
= _IP_VHL_HL(oip
->ip_vhl
) << 2;
3962 hlen
= oip
->ip_hl
<< 2;
3964 if (hlen
!= sizeof(struct ip
))
3967 sin
= (struct sockaddr_in
*)&sav
->sah
->saidx
.dst
;
3968 if (sin
->sin_family
!= AF_INET
)
3970 if (bcmp(&oip
->ip_dst
, &sin
->sin_addr
, sizeof(oip
->ip_dst
)) != 0)
3973 if (sav
->utun_in_fn
) {
3974 // the utun SAs don't have a policy (yet).
3975 if (nxt
== IPPROTO_IPV4
) {
3977 } else if (nxt
== IPPROTO_IPV6
) {
3978 *ifamily
= AF_INET6
;
3986 bzero(&osrc
, sizeof(osrc
));
3987 bzero(&odst
, sizeof(odst
));
3988 osrc
.sin_family
= odst
.sin_family
= AF_INET
;
3989 osrc
.sin_len
= odst
.sin_len
= sizeof(struct sockaddr_in
);
3990 osrc
.sin_addr
= oip
->ip_src
;
3991 odst
.sin_addr
= oip
->ip_dst
;
3993 * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
3994 * - if the inner destination is multicast address, there can be
3995 * multiple permissible inner source address. implementation
3996 * may want to skip verification of inner source address against
3998 * - if the inner protocol is ICMP, the packet may be an error report
3999 * from routers on the other side of the VPN cloud (R in the
4000 * following diagram). in this case, we cannot verify inner source
4001 * address against SPD selector.
4002 * me -- gw === gw -- R -- you
4004 * we consider the first bullet to be users responsibility on SPD entry
4005 * configuration (if you need to encrypt multicast traffic, set
4006 * the source range of SPD selector to 0.0.0.0/0, or have explicit
4007 * address ranges for possible senders).
4008 * the second bullet is not taken care of (yet).
4010 * therefore, we do not do anything special about inner source.
4012 if (nxt
== IPPROTO_IPV4
) {
4013 bzero(&i4src
, sizeof(struct sockaddr_in
));
4014 bzero(&i4dst
, sizeof(struct sockaddr_in
));
4015 i4src
.sin_family
= i4dst
.sin_family
= *ifamily
= AF_INET
;
4016 i4src
.sin_len
= i4dst
.sin_len
= sizeof(struct sockaddr_in
);
4017 m_copydata(m
, off
+ offsetof(struct ip
, ip_src
), sizeof(i4src
.sin_addr
),
4018 (caddr_t
)&i4src
.sin_addr
);
4019 m_copydata(m
, off
+ offsetof(struct ip
, ip_dst
), sizeof(i4dst
.sin_addr
),
4020 (caddr_t
)&i4dst
.sin_addr
);
4021 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4022 (struct sockaddr
*)&i4src
, (struct sockaddr
*)&i4dst
);
4023 } else if (nxt
== IPPROTO_IPV6
) {
4024 bzero(&i6src
, sizeof(struct sockaddr_in6
));
4025 bzero(&i6dst
, sizeof(struct sockaddr_in6
));
4026 i6src
.sin6_family
= i6dst
.sin6_family
= *ifamily
= AF_INET6
;
4027 i6src
.sin6_len
= i6dst
.sin6_len
= sizeof(struct sockaddr_in6
);
4028 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_src
), sizeof(i6src
.sin6_addr
),
4029 (caddr_t
)&i6src
.sin6_addr
);
4030 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_dst
), sizeof(i6dst
.sin6_addr
),
4031 (caddr_t
)&i6dst
.sin6_addr
);
4032 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4033 (struct sockaddr
*)&i6src
, (struct sockaddr
*)&i6dst
);
4035 return 0; /* unsupported family */
4040 key_freesp(sp
, KEY_SADB_UNLOCKED
);
4046 /* validate inbound IPsec tunnel packet. */
4048 ipsec6_tunnel_validate(m
, off
, nxt0
, sav
)
4049 struct mbuf
*m
; /* no pullup permitted, m->m_len >= ip */
4052 struct secasvar
*sav
;
4054 u_int8_t nxt
= nxt0
& 0xff;
4055 struct sockaddr_in6
*sin6
;
4056 struct sockaddr_in6 osrc
, odst
, isrc
, idst
;
4057 struct secpolicy
*sp
;
4058 struct ip6_hdr
*oip6
;
4060 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4063 if (m
->m_len
< sizeof(struct ip6_hdr
))
4064 panic("too short mbuf on ipsec6_tunnel_validate");
4066 if (nxt
!= IPPROTO_IPV6
)
4068 if (m
->m_pkthdr
.len
< off
+ sizeof(struct ip6_hdr
))
4070 /* do not decapsulate if the SA is for transport mode only */
4071 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
4074 oip6
= mtod(m
, struct ip6_hdr
*);
4075 /* AF_INET should be supported, but at this moment we don't. */
4076 sin6
= (struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
;
4077 if (sin6
->sin6_family
!= AF_INET6
)
4079 if (!IN6_ARE_ADDR_EQUAL(&oip6
->ip6_dst
, &sin6
->sin6_addr
))
4082 if (sav
->utun_in_fn
) {
4083 // the utun SAs don't have a policy (yet).
4088 bzero(&osrc
, sizeof(osrc
));
4089 bzero(&odst
, sizeof(odst
));
4090 bzero(&isrc
, sizeof(isrc
));
4091 bzero(&idst
, sizeof(idst
));
4092 osrc
.sin6_family
= odst
.sin6_family
= isrc
.sin6_family
=
4093 idst
.sin6_family
= AF_INET6
;
4094 osrc
.sin6_len
= odst
.sin6_len
= isrc
.sin6_len
= idst
.sin6_len
=
4095 sizeof(struct sockaddr_in6
);
4096 osrc
.sin6_addr
= oip6
->ip6_src
;
4097 odst
.sin6_addr
= oip6
->ip6_dst
;
4098 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_src
),
4099 sizeof(isrc
.sin6_addr
), (caddr_t
)&isrc
.sin6_addr
);
4100 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_dst
),
4101 sizeof(idst
.sin6_addr
), (caddr_t
)&idst
.sin6_addr
);
4104 * regarding to inner source address validation, see a long comment
4105 * in ipsec4_tunnel_validate.
4108 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4109 (struct sockaddr
*)&isrc
, (struct sockaddr
*)&idst
);
4111 * when there is no suitable inbound policy for the packet of the ipsec
4112 * tunnel mode, the kernel never decapsulate the tunneled packet
4113 * as the ipsec tunnel mode even when the system wide policy is "none".
4114 * then the kernel leaves the generic tunnel module to process this
4115 * packet. if there is no rule of the generic tunnel, the packet
4116 * is rejected and the statistics will be counted up.
4120 key_freesp(sp
, KEY_SADB_UNLOCKED
);
4127 * Make a mbuf chain for encryption.
4128 * If the original mbuf chain contains a mbuf with a cluster,
4129 * allocate a new cluster and copy the data to the new cluster.
4130 * XXX: this hack is inefficient, but is necessary to handle cases
4131 * of TCP retransmission...
4137 struct mbuf
*n
, **mpp
, *mnew
;
4139 for (n
= m
, mpp
= &m
; n
; n
= n
->m_next
) {
4140 if (n
->m_flags
& M_EXT
) {
4142 * Make a copy only if there are more than one references
4144 * XXX: is this approach effective?
4147 n
->m_ext
.ext_free
||
4148 m_mclhasreference(n
)
4154 if (n
->m_flags
& M_PKTHDR
) {
4155 MGETHDR(mnew
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4158 M_COPY_PKTHDR(mnew
, n
);
4161 MGET(mnew
, M_DONTWAIT
, MT_DATA
);
4169 * Copy data. If we don't have enough space to
4170 * store the whole data, allocate a cluster
4171 * or additional mbufs.
4172 * XXX: we don't use m_copyback(), since the
4173 * function does not use clusters and thus is
4182 if (remain
<= (mm
->m_flags
& M_PKTHDR
? MHLEN
: MLEN
))
4184 else { /* allocate a cluster */
4185 MCLGET(mm
, M_DONTWAIT
);
4186 if (!(mm
->m_flags
& M_EXT
)) {
4190 len
= remain
< MCLBYTES
?
4194 bcopy(n
->m_data
+ copied
, mm
->m_data
,
4201 if (remain
<= 0) /* completed? */
4204 /* need another mbuf */
4205 MGETHDR(mn
, M_DONTWAIT
, MT_HEADER
); /* XXXMAC: tags copied next time in loop? */
4208 mn
->m_pkthdr
.rcvif
= NULL
;
4214 mm
->m_next
= m_free(n
);
4233 * Tags are allocated as mbufs for now, since our minimum size is MLEN, we
4234 * should make use of up to that much space.
4236 #define IPSEC_TAG_HEADER \
4239 struct socket
*socket
;
4240 u_int32_t history_count
;
4241 struct ipsec_history history
[];
4244 #define IPSEC_TAG_SIZE (MLEN - sizeof(struct m_tag))
4245 #define IPSEC_TAG_HDR_SIZE (offsetof(struct ipsec_tag, history[0]))
4246 #define IPSEC_HISTORY_MAX ((IPSEC_TAG_SIZE - IPSEC_TAG_HDR_SIZE) / \
4247 sizeof(struct ipsec_history))
4249 static struct ipsec_tag
*
4255 /* Check if the tag already exists */
4256 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4259 struct ipsec_tag
*itag
;
4261 /* Allocate a tag */
4262 tag
= m_tag_create(KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
,
4263 IPSEC_TAG_SIZE
, M_DONTWAIT
, m
);
4266 itag
= (struct ipsec_tag
*)(tag
+ 1);
4268 itag
->history_count
= 0;
4270 m_tag_prepend(m
, tag
);
4274 return tag
? (struct ipsec_tag
*)(tag
+ 1) : NULL
;
4277 static struct ipsec_tag
*
4283 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4285 return tag
? (struct ipsec_tag
*)(tag
+ 1) : NULL
;
4294 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4297 m_tag_delete(m
, tag
);
4301 /* if the aux buffer is unnecessary, nuke it. */
4305 struct ipsec_tag
*itag
)
4307 if (itag
&& itag
->socket
== NULL
&& itag
->history_count
== 0) {
4308 m_tag_delete(m
, ((struct m_tag
*)itag
) - 1);
4317 struct ipsec_tag
*tag
;
4319 /* if so == NULL, don't insist on getting the aux mbuf */
4321 tag
= ipsec_addaux(m
);
4325 tag
= ipsec_findaux(m
);
4328 ipsec_optaux(m
, tag
);
4337 struct ipsec_tag
*itag
;
4339 itag
= ipsec_findaux(m
);
4341 return itag
->socket
;
4352 struct ipsec_tag
*itag
;
4353 struct ipsec_history
*p
;
4354 itag
= ipsec_addaux(m
);
4357 if (itag
->history_count
== IPSEC_HISTORY_MAX
)
4358 return ENOSPC
; /* XXX */
4360 p
= &itag
->history
[itag
->history_count
];
4361 itag
->history_count
++;
4363 bzero(p
, sizeof(*p
));
4364 p
->ih_proto
= proto
;
4370 struct ipsec_history
*
4375 struct ipsec_tag
*itag
;
4377 itag
= ipsec_findaux(m
);
4380 if (itag
->history_count
== 0)
4383 *lenp
= (int)(itag
->history_count
* sizeof(struct ipsec_history
));
4384 return itag
->history
;
4391 struct ipsec_tag
*itag
;
4393 itag
= ipsec_findaux(m
);
4395 itag
->history_count
= 0;
4397 ipsec_optaux(m
, itag
);
4400 __private_extern__
int
4401 ipsec_send_natt_keepalive(
4402 struct secasvar
*sav
)
4407 struct ip_out_args ipoa
= { IFSCOPE_NONE
, { 0 }, IPOAF_SELECT_SRCIF
};
4410 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4412 if ((esp_udp_encap_port
& 0xFFFF) == 0 || sav
->remote_ike_port
== 0) return FALSE
;
4414 // natt timestamp may have changed... reverify
4415 if ((natt_now
- sav
->natt_last_activity
) < natt_keepalive_interval
) return FALSE
;
4417 if (sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
) return FALSE
; // don't send these from the kernel
4419 m
= m_gethdr(M_NOWAIT
, MT_DATA
);
4420 if (m
== NULL
) return FALSE
;
4422 ip
= (__typeof__(ip
))m_mtod(m
);
4424 // this sends one type of NATT keepalives (Type 1, ESP keepalives, aren't sent by kernel)
4425 if ((sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
) == 0) {
4429 * Type 2: a UDP packet complete with IP header.
4430 * We must do this because UDP output requires
4431 * an inpcb which we don't have. UDP packet
4432 * contains one byte payload. The byte is set
4435 uh
= (__typeof__(uh
))(void *)((char *)m_mtod(m
) + sizeof(*ip
));
4436 m
->m_len
= sizeof(struct udpiphdr
) + 1;
4437 bzero(m_mtod(m
), m
->m_len
);
4438 m
->m_pkthdr
.len
= m
->m_len
;
4440 ip
->ip_len
= m
->m_len
;
4441 ip
->ip_ttl
= ip_defttl
;
4442 ip
->ip_p
= IPPROTO_UDP
;
4443 if (sav
->sah
->dir
!= IPSEC_DIR_INBOUND
) {
4444 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4445 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4447 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4448 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4450 uh
->uh_sport
= htons((u_short
)esp_udp_encap_port
);
4451 uh
->uh_dport
= htons(sav
->remote_ike_port
);
4452 uh
->uh_ulen
= htons(1 + sizeof(*uh
));
4454 *(u_int8_t
*)((char*)m_mtod(m
) + sizeof(*ip
) + sizeof(*uh
)) = 0xFF;
4457 // grab sadb_mutex, to get a local copy of sah's route cache
4458 lck_mtx_lock(sadb_mutex
);
4459 if (sav
->sah
->sa_route
.ro_rt
!= NULL
&&
4460 rt_key(sav
->sah
->sa_route
.ro_rt
)->sa_family
!= AF_INET
) {
4461 rtfree(sav
->sah
->sa_route
.ro_rt
);
4462 sav
->sah
->sa_route
.ro_rt
= NULL
;
4464 route_copyout(&ro
, &sav
->sah
->sa_route
, sizeof(ro
));
4465 lck_mtx_unlock(sadb_mutex
);
4467 error
= ip_output(m
, NULL
, &ro
, IP_OUTARGS
| IP_NOIPSEC
, NULL
, &ipoa
);
4469 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
4470 lck_mtx_lock(sadb_mutex
);
4471 route_copyin(&ro
, &sav
->sah
->sa_route
, sizeof(ro
));
4472 lck_mtx_unlock(sadb_mutex
);
4474 sav
->natt_last_activity
= natt_now
;