2 * Copyright (c) 2008-2014 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>
85 #include <net/if_ipsec.h>
87 #include <netinet/in.h>
88 #include <netinet/in_systm.h>
89 #include <netinet/ip.h>
90 #include <netinet/ip_var.h>
91 #include <netinet/in_var.h>
92 #include <netinet/udp.h>
93 #include <netinet/udp_var.h>
94 #include <netinet/ip_ecn.h>
96 #include <netinet6/ip6_ecn.h>
98 #include <netinet/tcp.h>
99 #include <netinet/udp.h>
101 #include <netinet/ip6.h>
103 #include <netinet6/ip6_var.h>
105 #include <netinet/in_pcb.h>
107 #include <netinet/icmp6.h>
110 #include <netinet6/ipsec.h>
112 #include <netinet6/ipsec6.h>
114 #include <netinet6/ah.h>
116 #include <netinet6/ah6.h>
119 #include <netinet6/esp.h>
121 #include <netinet6/esp6.h>
124 #include <netinet6/ipcomp.h>
126 #include <netinet6/ipcomp6.h>
128 #include <netkey/key.h>
129 #include <netkey/keydb.h>
130 #include <netkey/key_debug.h>
132 #include <net/net_osdep.h>
140 #include <sys/kdebug.h>
141 #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETIPSEC, 1)
142 #define DBG_LAYER_END NETDBG_CODE(DBG_NETIPSEC, 3)
143 #define DBG_FNC_GETPOL_SOCK NETDBG_CODE(DBG_NETIPSEC, (1 << 8))
144 #define DBG_FNC_GETPOL_ADDR NETDBG_CODE(DBG_NETIPSEC, (2 << 8))
145 #define DBG_FNC_IPSEC_OUT NETDBG_CODE(DBG_NETIPSEC, (3 << 8))
147 extern lck_mtx_t
*sadb_mutex
;
149 struct ipsecstat ipsecstat
;
150 int ip4_ah_cleartos
= 1;
151 int ip4_ah_offsetmask
= 0; /* maybe IP_DF? */
152 int ip4_ipsec_dfbit
= 0; /* DF bit on encap. 0: clear 1: set 2: copy */
153 int ip4_esp_trans_deflev
= IPSEC_LEVEL_USE
;
154 int ip4_esp_net_deflev
= IPSEC_LEVEL_USE
;
155 int ip4_ah_trans_deflev
= IPSEC_LEVEL_USE
;
156 int ip4_ah_net_deflev
= IPSEC_LEVEL_USE
;
157 struct secpolicy ip4_def_policy
;
158 int ip4_ipsec_ecn
= 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
159 int ip4_esp_randpad
= -1;
160 int esp_udp_encap_port
= 0;
161 static int sysctl_def_policy SYSCTL_HANDLER_ARGS
;
162 extern int natt_keepalive_interval
;
163 extern u_int32_t natt_now
;
167 SYSCTL_DECL(_net_inet_ipsec
);
169 SYSCTL_DECL(_net_inet6_ipsec6
);
172 SYSCTL_STRUCT(_net_inet_ipsec
, IPSECCTL_STATS
,
173 stats
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsecstat
, ipsecstat
, "");
174 SYSCTL_PROC(_net_inet_ipsec
, IPSECCTL_DEF_POLICY
, def_policy
, CTLTYPE_INT
|CTLFLAG_RW
| CTLFLAG_LOCKED
,
175 &ip4_def_policy
.policy
, 0, &sysctl_def_policy
, "I", "");
176 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
,
177 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_trans_deflev
, 0, "");
178 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
,
179 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_net_deflev
, 0, "");
180 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
,
181 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_trans_deflev
, 0, "");
182 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
,
183 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_net_deflev
, 0, "");
184 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_CLEARTOS
,
185 ah_cleartos
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_cleartos
, 0, "");
186 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_OFFSETMASK
,
187 ah_offsetmask
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_offsetmask
, 0, "");
188 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DFBIT
,
189 dfbit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ipsec_dfbit
, 0, "");
190 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ECN
,
191 ecn
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ipsec_ecn
, 0, "");
192 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEBUG
,
193 debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, "");
194 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ESP_RANDPAD
,
195 esp_randpad
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_randpad
, 0, "");
197 /* for performance, we bypass ipsec until a security policy is set */
198 int ipsec_bypass
= 1;
199 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, bypass
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsec_bypass
,0, "");
202 * NAT Traversal requires a UDP port for encapsulation,
203 * esp_udp_encap_port controls which port is used. Racoon
204 * must set this port to the port racoon is using locally
207 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, esp_port
,
208 CTLFLAG_RW
| CTLFLAG_LOCKED
, &esp_udp_encap_port
, 0, "");
211 struct ipsecstat ipsec6stat
;
212 int ip6_esp_trans_deflev
= IPSEC_LEVEL_USE
;
213 int ip6_esp_net_deflev
= IPSEC_LEVEL_USE
;
214 int ip6_ah_trans_deflev
= IPSEC_LEVEL_USE
;
215 int ip6_ah_net_deflev
= IPSEC_LEVEL_USE
;
216 struct secpolicy ip6_def_policy
;
217 int ip6_ipsec_ecn
= 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
218 int ip6_esp_randpad
= -1;
220 /* net.inet6.ipsec6 */
221 SYSCTL_STRUCT(_net_inet6_ipsec6
, IPSECCTL_STATS
,
222 stats
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsec6stat
, ipsecstat
, "");
223 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_POLICY
,
224 def_policy
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_def_policy
.policy
, 0, "");
225 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
,
226 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_trans_deflev
, 0, "");
227 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
,
228 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_net_deflev
, 0, "");
229 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
,
230 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ah_trans_deflev
, 0, "");
231 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
,
232 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ah_net_deflev
, 0, "");
233 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ECN
,
234 ecn
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ipsec_ecn
, 0, "");
235 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEBUG
,
236 debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, "");
237 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ESP_RANDPAD
,
238 esp_randpad
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_randpad
, 0, "");
241 static int ipsec_setspidx_interface(struct secpolicyindex
*, u_int
, struct mbuf
*,
243 static int ipsec_setspidx_mbuf(struct secpolicyindex
*, u_int
, u_int
,
245 static int ipsec4_setspidx_inpcb(struct mbuf
*, struct inpcb
*pcb
);
247 static int ipsec6_setspidx_in6pcb(struct mbuf
*, struct in6pcb
*pcb
);
249 static int ipsec_setspidx(struct mbuf
*, struct secpolicyindex
*, int, int);
250 static void ipsec4_get_ulp(struct mbuf
*m
, struct secpolicyindex
*, int);
251 static int ipsec4_setspidx_ipaddr(struct mbuf
*, struct secpolicyindex
*);
253 static void ipsec6_get_ulp(struct mbuf
*m
, struct secpolicyindex
*, int);
254 static int ipsec6_setspidx_ipaddr(struct mbuf
*, struct secpolicyindex
*);
256 static struct inpcbpolicy
*ipsec_newpcbpolicy(void);
257 static void ipsec_delpcbpolicy(struct inpcbpolicy
*);
258 static struct secpolicy
*ipsec_deepcopy_policy(struct secpolicy
*src
);
259 static int ipsec_set_policy(struct secpolicy
**pcb_sp
,
260 int optname
, caddr_t request
, size_t len
, int priv
);
261 static void vshiftl(unsigned char *, int, int);
262 static int ipsec_in_reject(struct secpolicy
*, struct mbuf
*);
264 static int ipsec64_encapsulate(struct mbuf
*, struct secasvar
*);
266 static struct ipsec_tag
*ipsec_addaux(struct mbuf
*);
267 static struct ipsec_tag
*ipsec_findaux(struct mbuf
*);
268 static void ipsec_optaux(struct mbuf
*, struct ipsec_tag
*);
269 int ipsec_send_natt_keepalive(struct secasvar
*sav
);
270 bool ipsec_fill_offload_frame(ifnet_t ifp
, struct secasvar
*sav
, struct ipsec_offload_frame
*frame
, size_t frame_data_offset
);
273 sysctl_def_policy SYSCTL_HANDLER_ARGS
275 int old_policy
= ip4_def_policy
.policy
;
276 int error
= sysctl_handle_int(oidp
, oidp
->oid_arg1
, oidp
->oid_arg2
, req
);
278 #pragma unused(arg1, arg2)
280 if (ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
&&
281 ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
) {
282 ip4_def_policy
.policy
= old_policy
;
286 /* Turn off the bypass if the default security policy changes */
287 if (ipsec_bypass
!= 0 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
)
294 * For OUTBOUND packet having a socket. Searching SPD for packet,
295 * and return a pointer to SP.
296 * OUT: NULL: no apropreate SP found, the following value is set to error.
298 * EACCES : discard packet.
299 * ENOENT : ipsec_acquire() in progress, maybe.
300 * others : error occurred.
301 * others: a pointer to SP
303 * NOTE: IPv6 mapped adddress concern is implemented here.
306 ipsec4_getpolicybysock(struct mbuf
*m
,
311 struct inpcbpolicy
*pcbsp
= NULL
;
312 struct secpolicy
*currsp
= NULL
; /* policy on socket */
313 struct secpolicy
*kernsp
= NULL
; /* policy on kernel */
315 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
317 if (m
== NULL
|| so
== NULL
|| error
== NULL
)
318 panic("ipsec4_getpolicybysock: NULL pointer was passed.\n");
320 if (so
->so_pcb
== NULL
) {
321 printf("ipsec4_getpolicybysock: so->so_pcb == NULL\n");
322 return ipsec4_getpolicybyaddr(m
, dir
, 0, error
);
325 switch (SOCK_DOM(so
)) {
327 pcbsp
= sotoinpcb(so
)->inp_sp
;
331 pcbsp
= sotoin6pcb(so
)->in6p_sp
;
337 /* Socket has not specified an IPSEC policy */
338 return ipsec4_getpolicybyaddr(m
, dir
, 0, error
);
341 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_START
, 0,0,0,0,0);
343 switch (SOCK_DOM(so
)) {
345 /* set spidx in pcb */
346 *error
= ipsec4_setspidx_inpcb(m
, sotoinpcb(so
));
350 /* set spidx in pcb */
351 *error
= ipsec6_setspidx_in6pcb(m
, sotoin6pcb(so
));
355 panic("ipsec4_getpolicybysock: unsupported address family\n");
358 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 1,*error
,0,0,0);
364 panic("ipsec4_getpolicybysock: pcbsp is NULL.\n");
367 case IPSEC_DIR_INBOUND
:
368 currsp
= pcbsp
->sp_in
;
370 case IPSEC_DIR_OUTBOUND
:
371 currsp
= pcbsp
->sp_out
;
374 panic("ipsec4_getpolicybysock: illegal direction.\n");
379 panic("ipsec4_getpolicybysock: currsp is NULL.\n");
381 /* when privilieged socket */
383 switch (currsp
->policy
) {
384 case IPSEC_POLICY_BYPASS
:
385 lck_mtx_lock(sadb_mutex
);
387 lck_mtx_unlock(sadb_mutex
);
389 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 2,*error
,0,0,0);
392 case IPSEC_POLICY_ENTRUST
:
393 /* look for a policy in SPD */
394 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
397 if (kernsp
!= NULL
) {
398 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
399 printf("DP ipsec4_getpolicybysock called "
400 "to allocate SP:0x%llx\n",
401 (uint64_t)VM_KERNEL_ADDRPERM(kernsp
)));
403 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 3,*error
,0,0,0);
408 lck_mtx_lock(sadb_mutex
);
409 if (ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
410 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
412 "fixed system default policy: %d->%d\n",
413 ip4_def_policy
.policy
, IPSEC_POLICY_NONE
));
414 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
416 ip4_def_policy
.refcnt
++;
417 lck_mtx_unlock(sadb_mutex
);
419 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 4,*error
,0,0,0);
420 return &ip4_def_policy
;
422 case IPSEC_POLICY_IPSEC
:
423 lck_mtx_lock(sadb_mutex
);
425 lck_mtx_unlock(sadb_mutex
);
427 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 5,*error
,0,0,0);
431 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: "
432 "Invalid policy for PCB %d\n", currsp
->policy
));
434 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 6,*error
,0,0,0);
440 /* when non-privilieged socket */
441 /* look for a policy in SPD */
442 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
445 if (kernsp
!= NULL
) {
446 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
447 printf("DP ipsec4_getpolicybysock called "
448 "to allocate SP:0x%llx\n",
449 (uint64_t)VM_KERNEL_ADDRPERM(kernsp
)));
451 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 7,*error
,0,0,0);
456 switch (currsp
->policy
) {
457 case IPSEC_POLICY_BYPASS
:
458 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: "
459 "Illegal policy for non-priviliged defined %d\n",
462 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 8,*error
,0,0,0);
465 case IPSEC_POLICY_ENTRUST
:
466 lck_mtx_lock(sadb_mutex
);
467 if (ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
468 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
470 "fixed system default policy: %d->%d\n",
471 ip4_def_policy
.policy
, IPSEC_POLICY_NONE
));
472 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
474 ip4_def_policy
.refcnt
++;
475 lck_mtx_unlock(sadb_mutex
);
477 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 9,*error
,0,0,0);
478 return &ip4_def_policy
;
480 case IPSEC_POLICY_IPSEC
:
481 lck_mtx_lock(sadb_mutex
);
483 lck_mtx_unlock(sadb_mutex
);
485 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 10,*error
,0,0,0);
489 ipseclog((LOG_ERR
, "ipsec4_getpolicybysock: "
490 "Invalid policy for PCB %d\n", currsp
->policy
));
492 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK
| DBG_FUNC_END
, 11,*error
,0,0,0);
499 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
500 * and return a pointer to SP.
501 * OUT: positive: a pointer to the entry for security policy leaf matched.
502 * NULL: no apropreate SP found, the following value is set to error.
504 * EACCES : discard packet.
505 * ENOENT : ipsec_acquire() in progress, maybe.
506 * others : error occurred.
509 ipsec4_getpolicybyaddr(struct mbuf
*m
,
514 struct secpolicy
*sp
= NULL
;
516 if (ipsec_bypass
!= 0)
519 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
522 if (m
== NULL
|| error
== NULL
)
523 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.\n");
525 struct secpolicyindex spidx
;
527 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_START
, 0,0,0,0,0);
528 bzero(&spidx
, sizeof(spidx
));
530 /* make a index to look for a policy */
531 *error
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET
, m
,
532 (flag
& IP_FORWARDING
) ? 0 : 1);
535 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 1,*error
,0,0,0);
539 sp
= key_allocsp(&spidx
, dir
);
544 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
545 printf("DP ipsec4_getpolicybyaddr called "
546 "to allocate SP:0x%llx\n",
547 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
549 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 2,*error
,0,0,0);
554 lck_mtx_lock(sadb_mutex
);
555 if (ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
556 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
557 ipseclog((LOG_INFO
, "fixed system default policy:%d->%d\n",
558 ip4_def_policy
.policy
,
560 ip4_def_policy
.policy
= IPSEC_POLICY_NONE
;
562 ip4_def_policy
.refcnt
++;
563 lck_mtx_unlock(sadb_mutex
);
565 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 3,*error
,0,0,0);
566 return &ip4_def_policy
;
569 /* Match with bound interface rather than src addr.
570 * Unlike getpolicybyaddr, do not set the default policy.
571 * Return 0 if should continue processing, or -1 if packet
575 ipsec4_getpolicybyinterface(struct mbuf
*m
,
578 struct ip_out_args
*ipoa
,
579 struct secpolicy
**sp
)
581 struct secpolicyindex spidx
;
584 if (ipsec_bypass
!= 0)
588 if (m
== NULL
|| ipoa
== NULL
|| sp
== NULL
)
589 panic("ipsec4_getpolicybyinterface: NULL pointer was passed.\n");
591 if (ipoa
->ipoa_boundif
== IFSCOPE_NONE
)
594 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_START
, 0,0,0,0,0);
595 bzero(&spidx
, sizeof(spidx
));
597 /* make a index to look for a policy */
598 error
= ipsec_setspidx_interface(&spidx
, dir
, m
, (*flags
& IP_FORWARDING
) ? 0 : 1,
599 ipoa
->ipoa_boundif
, 4);
602 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 1,error
,0,0,0);
606 *sp
= key_allocsp(&spidx
, dir
);
608 /* Return SP, whether NULL or not */
609 if (*sp
!= NULL
&& (*sp
)->policy
== IPSEC_POLICY_IPSEC
) {
610 if ((*sp
)->ipsec_if
== NULL
) {
611 /* Invalid to capture on an interface without redirect */
612 key_freesp(*sp
, KEY_SADB_UNLOCKED
);
615 } else if ((*sp
)->disabled
) {
616 /* Disabled policies go in the clear */
617 key_freesp(*sp
, KEY_SADB_UNLOCKED
);
619 *flags
|= IP_NOIPSEC
; /* Avoid later IPSec check */
621 /* If policy is enabled, redirect to ipsec interface */
622 ipoa
->ipoa_boundif
= (*sp
)->ipsec_if
->if_index
;
626 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 2,error
,0,0,0);
634 * For OUTBOUND packet having a socket. Searching SPD for packet,
635 * and return a pointer to SP.
636 * OUT: NULL: no apropreate SP found, the following value is set to error.
638 * EACCES : discard packet.
639 * ENOENT : ipsec_acquire() in progress, maybe.
640 * others : error occurred.
641 * others: a pointer to SP
644 ipsec6_getpolicybysock(struct mbuf
*m
,
649 struct inpcbpolicy
*pcbsp
= NULL
;
650 struct secpolicy
*currsp
= NULL
; /* policy on socket */
651 struct secpolicy
*kernsp
= NULL
; /* policy on kernel */
653 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
656 if (m
== NULL
|| so
== NULL
|| error
== NULL
)
657 panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
660 if (SOCK_DOM(so
) != PF_INET6
)
661 panic("ipsec6_getpolicybysock: socket domain != inet6\n");
664 pcbsp
= sotoin6pcb(so
)->in6p_sp
;
667 return ipsec6_getpolicybyaddr(m
, dir
, 0, error
);
670 /* set spidx in pcb */
671 ipsec6_setspidx_in6pcb(m
, sotoin6pcb(so
));
675 panic("ipsec6_getpolicybysock: pcbsp is NULL.\n");
678 case IPSEC_DIR_INBOUND
:
679 currsp
= pcbsp
->sp_in
;
681 case IPSEC_DIR_OUTBOUND
:
682 currsp
= pcbsp
->sp_out
;
685 panic("ipsec6_getpolicybysock: illegal direction.\n");
690 panic("ipsec6_getpolicybysock: currsp is NULL.\n");
692 /* when privilieged socket */
694 switch (currsp
->policy
) {
695 case IPSEC_POLICY_BYPASS
:
696 lck_mtx_lock(sadb_mutex
);
698 lck_mtx_unlock(sadb_mutex
);
702 case IPSEC_POLICY_ENTRUST
:
703 /* look for a policy in SPD */
704 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
707 if (kernsp
!= NULL
) {
708 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
709 printf("DP ipsec6_getpolicybysock called "
710 "to allocate SP:0x%llx\n",
711 (uint64_t)VM_KERNEL_ADDRPERM(kernsp
)));
717 lck_mtx_lock(sadb_mutex
);
718 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
719 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
721 "fixed system default policy: %d->%d\n",
722 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
723 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
725 ip6_def_policy
.refcnt
++;
726 lck_mtx_unlock(sadb_mutex
);
728 return &ip6_def_policy
;
730 case IPSEC_POLICY_IPSEC
:
731 lck_mtx_lock(sadb_mutex
);
733 lck_mtx_unlock(sadb_mutex
);
738 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: "
739 "Invalid policy for PCB %d\n", currsp
->policy
));
746 /* when non-privilieged socket */
747 /* look for a policy in SPD */
748 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
751 if (kernsp
!= NULL
) {
752 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
753 printf("DP ipsec6_getpolicybysock called "
754 "to allocate SP:0x%llx\n",
755 (uint64_t)VM_KERNEL_ADDRPERM(kernsp
)));
761 switch (currsp
->policy
) {
762 case IPSEC_POLICY_BYPASS
:
763 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: "
764 "Illegal policy for non-priviliged defined %d\n",
769 case IPSEC_POLICY_ENTRUST
:
770 lck_mtx_lock(sadb_mutex
);
771 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
772 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
774 "fixed system default policy: %d->%d\n",
775 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
776 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
778 ip6_def_policy
.refcnt
++;
779 lck_mtx_unlock(sadb_mutex
);
781 return &ip6_def_policy
;
783 case IPSEC_POLICY_IPSEC
:
784 lck_mtx_lock(sadb_mutex
);
786 lck_mtx_unlock(sadb_mutex
);
792 "ipsec6_policybysock: Invalid policy for PCB %d\n",
801 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
802 * and return a pointer to SP.
803 * `flag' means that packet is to be forwarded whether or not.
805 * OUT: positive: a pointer to the entry for security policy leaf matched.
806 * NULL: no apropreate SP found, the following value is set to error.
808 * EACCES : discard packet.
809 * ENOENT : ipsec_acquire() in progress, maybe.
810 * others : error occurred.
812 #ifndef IP_FORWARDING
813 #define IP_FORWARDING 1
817 ipsec6_getpolicybyaddr(struct mbuf
*m
,
822 struct secpolicy
*sp
= NULL
;
824 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
827 if (m
== NULL
|| error
== NULL
)
828 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.\n");
831 struct secpolicyindex spidx
;
833 bzero(&spidx
, sizeof(spidx
));
835 /* make a index to look for a policy */
836 *error
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET6
, m
,
837 (flag
& IP_FORWARDING
) ? 0 : 1);
842 sp
= key_allocsp(&spidx
, dir
);
847 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
848 printf("DP ipsec6_getpolicybyaddr called "
849 "to allocate SP:0x%llx\n",
850 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
856 lck_mtx_lock(sadb_mutex
);
857 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
858 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
859 ipseclog((LOG_INFO
, "fixed system default policy: %d->%d\n",
860 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
861 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
863 ip6_def_policy
.refcnt
++;
864 lck_mtx_unlock(sadb_mutex
);
866 return &ip6_def_policy
;
869 /* Match with bound interface rather than src addr.
870 * Unlike getpolicybyaddr, do not set the default policy.
871 * Return 0 if should continue processing, or -1 if packet
875 ipsec6_getpolicybyinterface(struct mbuf
*m
,
878 struct ip6_out_args
*ip6oap
,
880 struct secpolicy
**sp
)
882 struct secpolicyindex spidx
;
885 if (ipsec_bypass
!= 0)
889 if (m
== NULL
|| sp
== NULL
|| noipsec
== NULL
|| ip6oap
== NULL
)
890 panic("ipsec6_getpolicybyinterface: NULL pointer was passed.\n");
894 if (ip6oap
->ip6oa_boundif
== IFSCOPE_NONE
)
897 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_START
, 0,0,0,0,0);
898 bzero(&spidx
, sizeof(spidx
));
900 /* make a index to look for a policy */
901 error
= ipsec_setspidx_interface(&spidx
, dir
, m
, (flag
& IP_FORWARDING
) ? 0 : 1,
902 ip6oap
->ip6oa_boundif
, 6);
905 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 1,error
,0,0,0);
909 *sp
= key_allocsp(&spidx
, dir
);
911 /* Return SP, whether NULL or not */
912 if (*sp
!= NULL
&& (*sp
)->policy
== IPSEC_POLICY_IPSEC
) {
913 if ((*sp
)->ipsec_if
== NULL
) {
914 /* Invalid to capture on an interface without redirect */
915 key_freesp(*sp
, KEY_SADB_UNLOCKED
);
918 } else if ((*sp
)->disabled
) {
919 /* Disabled policies go in the clear */
920 key_freesp(*sp
, KEY_SADB_UNLOCKED
);
922 *noipsec
= 1; /* Avoid later IPSec check */
924 /* If policy is enabled, redirect to ipsec interface */
925 ip6oap
->ip6oa_boundif
= (*sp
)->ipsec_if
->if_index
;
929 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 2,*error
,0,0,0);
936 * set IP address into spidx from mbuf.
937 * When Forwarding packet and ICMP echo reply, this function is used.
939 * IN: get the followings from mbuf.
940 * protocol family, src, dst, next protocol
943 * other: failure, and set errno.
947 struct secpolicyindex
*spidx
,
949 __unused u_int family
,
956 if (spidx
== NULL
|| m
== NULL
)
957 panic("ipsec_setspidx_mbuf: NULL pointer was passed.\n");
959 bzero(spidx
, sizeof(*spidx
));
961 error
= ipsec_setspidx(m
, spidx
, needport
, 0);
970 bzero(spidx
, sizeof(*spidx
));
975 ipsec_setspidx_interface(
976 struct secpolicyindex
*spidx
,
986 if (spidx
== NULL
|| m
== NULL
)
987 panic("ipsec_setspidx_interface: NULL pointer was passed.\n");
989 bzero(spidx
, sizeof(*spidx
));
991 error
= ipsec_setspidx(m
, spidx
, needport
, ip_version
);
997 ifnet_head_lock_shared();
998 spidx
->internal_if
= ifindex2ifnet
[ifindex
];
1001 spidx
->internal_if
= NULL
;
1011 ipsec4_setspidx_inpcb(m
, pcb
)
1015 struct secpolicyindex
*spidx
;
1018 if (ipsec_bypass
!= 0)
1023 panic("ipsec4_setspidx_inpcb: no PCB found.\n");
1024 if (pcb
->inp_sp
== NULL
)
1025 panic("ipsec4_setspidx_inpcb: no inp_sp found.\n");
1026 if (pcb
->inp_sp
->sp_out
== NULL
|| pcb
->inp_sp
->sp_in
== NULL
)
1027 panic("ipsec4_setspidx_inpcb: no sp_in/out found.\n");
1029 bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
));
1030 bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
));
1032 spidx
= &pcb
->inp_sp
->sp_in
->spidx
;
1033 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1036 spidx
->dir
= IPSEC_DIR_INBOUND
;
1038 spidx
= &pcb
->inp_sp
->sp_out
->spidx
;
1039 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1042 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
1047 bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
));
1048 bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
));
1054 ipsec6_setspidx_in6pcb(m
, pcb
)
1058 struct secpolicyindex
*spidx
;
1063 panic("ipsec6_setspidx_in6pcb: no PCB found.\n");
1064 if (pcb
->in6p_sp
== NULL
)
1065 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.\n");
1066 if (pcb
->in6p_sp
->sp_out
== NULL
|| pcb
->in6p_sp
->sp_in
== NULL
)
1067 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.\n");
1069 bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
));
1070 bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
));
1072 spidx
= &pcb
->in6p_sp
->sp_in
->spidx
;
1073 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1076 spidx
->dir
= IPSEC_DIR_INBOUND
;
1078 spidx
= &pcb
->in6p_sp
->sp_out
->spidx
;
1079 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1082 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
1087 bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
));
1088 bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
));
1094 * configure security policy index (src/dst/proto/sport/dport)
1095 * by looking at the content of mbuf.
1096 * the caller is responsible for error recovery (like clearing up spidx).
1099 ipsec_setspidx(struct mbuf
*m
,
1100 struct secpolicyindex
*spidx
,
1102 int force_ip_version
)
1104 struct ip
*ip
= NULL
;
1112 panic("ipsec_setspidx: m == 0 passed.\n");
1115 * validate m->m_pkthdr.len. we see incorrect length if we
1116 * mistakenly call this function with inconsistent mbuf chain
1117 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
1120 for (n
= m
; n
; n
= n
->m_next
)
1122 if (m
->m_pkthdr
.len
!= len
) {
1123 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1124 printf("ipsec_setspidx: "
1125 "total of m_len(%d) != pkthdr.len(%d), "
1127 len
, m
->m_pkthdr
.len
));
1131 if (m
->m_pkthdr
.len
< sizeof(struct ip
)) {
1132 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1133 printf("ipsec_setspidx: "
1134 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
1139 if (m
->m_len
>= sizeof(*ip
))
1140 ip
= mtod(m
, struct ip
*);
1142 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
);
1146 if (force_ip_version
) {
1147 v
= force_ip_version
;
1150 v
= _IP_VHL_V(ip
->ip_vhl
);
1157 error
= ipsec4_setspidx_ipaddr(m
, spidx
);
1160 ipsec4_get_ulp(m
, spidx
, needport
);
1164 if (m
->m_pkthdr
.len
< sizeof(struct ip6_hdr
)) {
1165 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1166 printf("ipsec_setspidx: "
1167 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
1168 "ignored.\n", m
->m_pkthdr
.len
));
1171 error
= ipsec6_setspidx_ipaddr(m
, spidx
);
1174 ipsec6_get_ulp(m
, spidx
, needport
);
1178 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1179 printf("ipsec_setspidx: "
1180 "unknown IP version %u, ignored.\n", v
));
1186 ipsec4_get_ulp(m
, spidx
, needport
)
1188 struct secpolicyindex
*spidx
;
1192 struct ip6_ext ip6e
;
1200 panic("ipsec4_get_ulp: NULL pointer was passed.\n");
1201 if (m
->m_pkthdr
.len
< sizeof(ip
))
1202 panic("ipsec4_get_ulp: too short\n");
1205 spidx
->ul_proto
= IPSEC_ULPROTO_ANY
;
1206 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
= IPSEC_PORT_ANY
;
1207 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
= IPSEC_PORT_ANY
;
1209 m_copydata(m
, 0, sizeof(ip
), (caddr_t
)&ip
);
1210 /* ip_input() flips it into host endian XXX need more checking */
1211 if (ip
.ip_off
& (IP_MF
| IP_OFFMASK
))
1216 off
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
1218 off
= ip
.ip_hl
<< 2;
1220 while (off
< m
->m_pkthdr
.len
) {
1223 spidx
->ul_proto
= nxt
;
1226 if (off
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
)
1228 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
);
1229 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
=
1231 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
=
1235 spidx
->ul_proto
= nxt
;
1238 if (off
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
)
1240 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
);
1241 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
=
1243 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
=
1247 if (off
+ sizeof(ip6e
) > m
->m_pkthdr
.len
)
1249 m_copydata(m
, off
, sizeof(ip6e
), (caddr_t
)&ip6e
);
1250 off
+= (ip6e
.ip6e_len
+ 2) << 2;
1251 nxt
= ip6e
.ip6e_nxt
;
1255 /* XXX intermediate headers??? */
1256 spidx
->ul_proto
= nxt
;
1262 /* assumes that m is sane */
1264 ipsec4_setspidx_ipaddr(m
, spidx
)
1266 struct secpolicyindex
*spidx
;
1268 struct ip
*ip
= NULL
;
1270 struct sockaddr_in
*sin
;
1272 if (m
->m_len
>= sizeof(*ip
))
1273 ip
= mtod(m
, struct ip
*);
1275 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
);
1279 sin
= (struct sockaddr_in
*)&spidx
->src
;
1280 bzero(sin
, sizeof(*sin
));
1281 sin
->sin_family
= AF_INET
;
1282 sin
->sin_len
= sizeof(struct sockaddr_in
);
1283 bcopy(&ip
->ip_src
, &sin
->sin_addr
, sizeof(ip
->ip_src
));
1284 spidx
->prefs
= sizeof(struct in_addr
) << 3;
1286 sin
= (struct sockaddr_in
*)&spidx
->dst
;
1287 bzero(sin
, sizeof(*sin
));
1288 sin
->sin_family
= AF_INET
;
1289 sin
->sin_len
= sizeof(struct sockaddr_in
);
1290 bcopy(&ip
->ip_dst
, &sin
->sin_addr
, sizeof(ip
->ip_dst
));
1291 spidx
->prefd
= sizeof(struct in_addr
) << 3;
1298 ipsec6_get_ulp(struct mbuf
*m
,
1299 struct secpolicyindex
*spidx
,
1308 panic("ipsec6_get_ulp: NULL pointer was passed.\n");
1310 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1311 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m
));
1314 spidx
->ul_proto
= IPSEC_ULPROTO_ANY
;
1315 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= IPSEC_PORT_ANY
;
1316 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= IPSEC_PORT_ANY
;
1319 off
= ip6_lasthdr(m
, 0, IPPROTO_IPV6
, &nxt
);
1320 if (off
< 0 || m
->m_pkthdr
.len
< off
)
1325 spidx
->ul_proto
= nxt
;
1328 if (off
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
)
1330 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
);
1331 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= th
.th_sport
;
1332 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= th
.th_dport
;
1335 spidx
->ul_proto
= nxt
;
1338 if (off
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
)
1340 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
);
1341 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= uh
.uh_sport
;
1342 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= uh
.uh_dport
;
1344 case IPPROTO_ICMPV6
:
1346 /* XXX intermediate headers??? */
1347 spidx
->ul_proto
= nxt
;
1352 /* assumes that m is sane */
1354 ipsec6_setspidx_ipaddr(struct mbuf
*m
,
1355 struct secpolicyindex
*spidx
)
1357 struct ip6_hdr
*ip6
= NULL
;
1358 struct ip6_hdr ip6buf
;
1359 struct sockaddr_in6
*sin6
;
1361 if (m
->m_len
>= sizeof(*ip6
))
1362 ip6
= mtod(m
, struct ip6_hdr
*);
1364 m_copydata(m
, 0, sizeof(ip6buf
), (caddr_t
)&ip6buf
);
1368 sin6
= (struct sockaddr_in6
*)&spidx
->src
;
1369 bzero(sin6
, sizeof(*sin6
));
1370 sin6
->sin6_family
= AF_INET6
;
1371 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
1372 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_src
));
1373 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
1374 sin6
->sin6_addr
.s6_addr16
[1] = 0;
1375 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
1377 spidx
->prefs
= sizeof(struct in6_addr
) << 3;
1379 sin6
= (struct sockaddr_in6
*)&spidx
->dst
;
1380 bzero(sin6
, sizeof(*sin6
));
1381 sin6
->sin6_family
= AF_INET6
;
1382 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
1383 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_dst
));
1384 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
1385 sin6
->sin6_addr
.s6_addr16
[1] = 0;
1386 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
1388 spidx
->prefd
= sizeof(struct in6_addr
) << 3;
1394 static struct inpcbpolicy
*
1395 ipsec_newpcbpolicy()
1397 struct inpcbpolicy
*p
;
1399 p
= (struct inpcbpolicy
*)_MALLOC(sizeof(*p
), M_SECA
, M_WAITOK
);
1404 ipsec_delpcbpolicy(struct inpcbpolicy
*p
)
1409 /* initialize policy in PCB */
1411 ipsec_init_policy(struct socket
*so
,
1412 struct inpcbpolicy
**pcb_sp
)
1414 struct inpcbpolicy
*new;
1417 if (so
== NULL
|| pcb_sp
== NULL
)
1418 panic("ipsec_init_policy: NULL pointer was passed.\n");
1420 new = ipsec_newpcbpolicy();
1422 ipseclog((LOG_DEBUG
, "ipsec_init_policy: No more memory.\n"));
1425 bzero(new, sizeof(*new));
1428 if (kauth_cred_issuser(so
->so_cred
))
1430 if (so
->so_cred
!= 0 && !suser(so
->so_cred
->pc_ucred
, NULL
))
1436 if ((new->sp_in
= key_newsp()) == NULL
) {
1437 ipsec_delpcbpolicy(new);
1440 new->sp_in
->state
= IPSEC_SPSTATE_ALIVE
;
1441 new->sp_in
->policy
= IPSEC_POLICY_ENTRUST
;
1443 if ((new->sp_out
= key_newsp()) == NULL
) {
1444 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
);
1445 ipsec_delpcbpolicy(new);
1448 new->sp_out
->state
= IPSEC_SPSTATE_ALIVE
;
1449 new->sp_out
->policy
= IPSEC_POLICY_ENTRUST
;
1456 /* copy old ipsec policy into new */
1458 ipsec_copy_policy(struct inpcbpolicy
*old
,
1459 struct inpcbpolicy
*new)
1461 struct secpolicy
*sp
;
1463 if (ipsec_bypass
!= 0)
1466 sp
= ipsec_deepcopy_policy(old
->sp_in
);
1468 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
);
1473 sp
= ipsec_deepcopy_policy(old
->sp_out
);
1475 key_freesp(new->sp_out
, KEY_SADB_UNLOCKED
);
1480 new->priv
= old
->priv
;
1485 /* deep-copy a policy in PCB */
1486 static struct secpolicy
*
1487 ipsec_deepcopy_policy(struct secpolicy
*src
)
1489 struct ipsecrequest
*newchain
= NULL
;
1490 struct ipsecrequest
*p
;
1491 struct ipsecrequest
**q
;
1492 struct ipsecrequest
*r
;
1493 struct secpolicy
*dst
;
1502 * deep-copy IPsec request chain. This is required since struct
1503 * ipsecrequest is not reference counted.
1506 for (p
= src
->req
; p
; p
= p
->next
) {
1507 *q
= (struct ipsecrequest
*)_MALLOC(sizeof(struct ipsecrequest
),
1511 bzero(*q
, sizeof(**q
));
1514 (*q
)->saidx
.proto
= p
->saidx
.proto
;
1515 (*q
)->saidx
.mode
= p
->saidx
.mode
;
1516 (*q
)->level
= p
->level
;
1517 (*q
)->saidx
.reqid
= p
->saidx
.reqid
;
1519 bcopy(&p
->saidx
.src
, &(*q
)->saidx
.src
, sizeof((*q
)->saidx
.src
));
1520 bcopy(&p
->saidx
.dst
, &(*q
)->saidx
.dst
, sizeof((*q
)->saidx
.dst
));
1527 dst
->req
= newchain
;
1528 dst
->state
= src
->state
;
1529 dst
->policy
= src
->policy
;
1530 /* do not touch the refcnt fields */
1535 for (p
= newchain
; p
; p
= r
) {
1540 key_freesp(dst
, KEY_SADB_UNLOCKED
);
1544 /* set policy and ipsec request if present. */
1546 ipsec_set_policy(struct secpolicy
**pcb_sp
,
1547 __unused
int optname
,
1552 struct sadb_x_policy
*xpl
;
1553 struct secpolicy
*newsp
= NULL
;
1557 if (pcb_sp
== NULL
|| *pcb_sp
== NULL
|| request
== NULL
)
1559 if (len
< sizeof(*xpl
))
1561 xpl
= (struct sadb_x_policy
*)(void *)request
;
1563 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1564 printf("ipsec_set_policy: passed policy\n");
1565 kdebug_sadb_x_policy((struct sadb_ext
*)xpl
));
1567 /* check policy type */
1568 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1569 if (xpl
->sadb_x_policy_type
== IPSEC_POLICY_DISCARD
1570 || xpl
->sadb_x_policy_type
== IPSEC_POLICY_NONE
)
1573 /* check privileged socket */
1574 if (priv
== 0 && xpl
->sadb_x_policy_type
== IPSEC_POLICY_BYPASS
)
1577 /* allocation new SP entry */
1578 if ((newsp
= key_msg2sp(xpl
, len
, &error
)) == NULL
)
1581 newsp
->state
= IPSEC_SPSTATE_ALIVE
;
1583 /* clear old SP and set new SP */
1584 key_freesp(*pcb_sp
, KEY_SADB_UNLOCKED
);
1586 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1587 printf("ipsec_set_policy: new policy\n");
1588 kdebug_secpolicy(newsp
));
1594 ipsec4_set_policy(struct inpcb
*inp
,
1600 struct sadb_x_policy
*xpl
;
1601 struct secpolicy
**pcb_sp
;
1603 struct sadb_x_policy xpl_aligned_buf
;
1604 u_int8_t
*xpl_unaligned
;
1607 if (inp
== NULL
|| request
== NULL
)
1609 if (len
< sizeof(*xpl
))
1611 xpl
= (struct sadb_x_policy
*)(void *)request
;
1613 /* This is a new mbuf allocated by soopt_getm() */
1614 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1615 xpl_unaligned
= NULL
;
1617 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1618 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1619 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1622 if (inp
->inp_sp
== NULL
) {
1623 error
= ipsec_init_policy(inp
->inp_socket
, &inp
->inp_sp
);
1628 /* select direction */
1629 switch (xpl
->sadb_x_policy_dir
) {
1630 case IPSEC_DIR_INBOUND
:
1631 pcb_sp
= &inp
->inp_sp
->sp_in
;
1633 case IPSEC_DIR_OUTBOUND
:
1634 pcb_sp
= &inp
->inp_sp
->sp_out
;
1637 ipseclog((LOG_ERR
, "ipsec4_set_policy: invalid direction=%u\n",
1638 xpl
->sadb_x_policy_dir
));
1642 /* turn bypass off */
1643 if (ipsec_bypass
!= 0)
1646 return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
);
1649 /* delete policy in PCB */
1651 ipsec4_delete_pcbpolicy(struct inpcb
*inp
)
1656 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n");
1658 if (inp
->inp_sp
== NULL
)
1661 if (inp
->inp_sp
->sp_in
!= NULL
) {
1662 key_freesp(inp
->inp_sp
->sp_in
, KEY_SADB_UNLOCKED
);
1663 inp
->inp_sp
->sp_in
= NULL
;
1666 if (inp
->inp_sp
->sp_out
!= NULL
) {
1667 key_freesp(inp
->inp_sp
->sp_out
, KEY_SADB_UNLOCKED
);
1668 inp
->inp_sp
->sp_out
= NULL
;
1671 ipsec_delpcbpolicy(inp
->inp_sp
);
1679 ipsec6_set_policy(struct in6pcb
*in6p
,
1685 struct sadb_x_policy
*xpl
;
1686 struct secpolicy
**pcb_sp
;
1688 struct sadb_x_policy xpl_aligned_buf
;
1689 u_int8_t
*xpl_unaligned
;
1692 if (in6p
== NULL
|| request
== NULL
)
1694 if (len
< sizeof(*xpl
))
1696 xpl
= (struct sadb_x_policy
*)(void *)request
;
1698 /* This is a new mbuf allocated by soopt_getm() */
1699 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1700 xpl_unaligned
= NULL
;
1702 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1703 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1704 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1707 if (in6p
->in6p_sp
== NULL
) {
1708 error
= ipsec_init_policy(in6p
->inp_socket
, &in6p
->in6p_sp
);
1713 /* select direction */
1714 switch (xpl
->sadb_x_policy_dir
) {
1715 case IPSEC_DIR_INBOUND
:
1716 pcb_sp
= &in6p
->in6p_sp
->sp_in
;
1718 case IPSEC_DIR_OUTBOUND
:
1719 pcb_sp
= &in6p
->in6p_sp
->sp_out
;
1722 ipseclog((LOG_ERR
, "ipsec6_set_policy: invalid direction=%u\n",
1723 xpl
->sadb_x_policy_dir
));
1727 return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
);
1731 ipsec6_delete_pcbpolicy(struct in6pcb
*in6p
)
1736 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n");
1738 if (in6p
->in6p_sp
== NULL
)
1741 if (in6p
->in6p_sp
->sp_in
!= NULL
) {
1742 key_freesp(in6p
->in6p_sp
->sp_in
, KEY_SADB_UNLOCKED
);
1743 in6p
->in6p_sp
->sp_in
= NULL
;
1746 if (in6p
->in6p_sp
->sp_out
!= NULL
) {
1747 key_freesp(in6p
->in6p_sp
->sp_out
, KEY_SADB_UNLOCKED
);
1748 in6p
->in6p_sp
->sp_out
= NULL
;
1751 ipsec_delpcbpolicy(in6p
->in6p_sp
);
1752 in6p
->in6p_sp
= NULL
;
1759 * return current level.
1760 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1763 ipsec_get_reqlevel(isr
)
1764 struct ipsecrequest
*isr
;
1767 u_int esp_trans_deflev
= 0, esp_net_deflev
= 0, ah_trans_deflev
= 0, ah_net_deflev
= 0;
1770 if (isr
== NULL
|| isr
->sp
== NULL
)
1771 panic("ipsec_get_reqlevel: NULL pointer is passed.\n");
1772 if (((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
1773 != ((struct sockaddr
*)&isr
->sp
->spidx
.dst
)->sa_family
)
1774 panic("ipsec_get_reqlevel: family mismatched.\n");
1776 /* XXX note that we have ipseclog() expanded here - code sync issue */
1777 #define IPSEC_CHECK_DEFAULT(lev) \
1778 (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1779 && (lev) != IPSEC_LEVEL_UNIQUE) \
1781 ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1782 (lev), IPSEC_LEVEL_REQUIRE) \
1784 (lev) = IPSEC_LEVEL_REQUIRE, \
1788 /* set default level */
1789 switch (((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
) {
1792 esp_trans_deflev
= IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev
);
1793 esp_net_deflev
= IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev
);
1794 ah_trans_deflev
= IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev
);
1795 ah_net_deflev
= IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev
);
1800 esp_trans_deflev
= IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev
);
1801 esp_net_deflev
= IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev
);
1802 ah_trans_deflev
= IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev
);
1803 ah_net_deflev
= IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev
);
1807 panic("key_get_reqlevel: Unknown family. %d\n",
1808 ((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
);
1811 #undef IPSEC_CHECK_DEFAULT
1814 switch (isr
->level
) {
1815 case IPSEC_LEVEL_DEFAULT
:
1816 switch (isr
->saidx
.proto
) {
1818 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
1819 level
= esp_net_deflev
;
1821 level
= esp_trans_deflev
;
1824 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
1825 level
= ah_net_deflev
;
1827 level
= ah_trans_deflev
;
1829 case IPPROTO_IPCOMP
:
1831 * we don't really care, as IPcomp document says that
1832 * we shouldn't compress small packets
1834 level
= IPSEC_LEVEL_USE
;
1837 panic("ipsec_get_reqlevel: "
1838 "Illegal protocol defined %u\n",
1843 case IPSEC_LEVEL_USE
:
1844 case IPSEC_LEVEL_REQUIRE
:
1847 case IPSEC_LEVEL_UNIQUE
:
1848 level
= IPSEC_LEVEL_REQUIRE
;
1852 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
1860 * Check AH/ESP integrity.
1866 ipsec_in_reject(sp
, m
)
1867 struct secpolicy
*sp
;
1870 struct ipsecrequest
*isr
;
1872 int need_auth
, need_conf
, need_icv
;
1874 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
1875 printf("ipsec_in_reject: using SP\n");
1876 kdebug_secpolicy(sp
));
1879 switch (sp
->policy
) {
1880 case IPSEC_POLICY_DISCARD
:
1881 case IPSEC_POLICY_GENERATE
:
1883 case IPSEC_POLICY_BYPASS
:
1884 case IPSEC_POLICY_NONE
:
1887 case IPSEC_POLICY_IPSEC
:
1890 case IPSEC_POLICY_ENTRUST
:
1892 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
);
1899 /* XXX should compare policy against ipsec header history */
1901 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
1903 /* get current level */
1904 level
= ipsec_get_reqlevel(isr
);
1906 switch (isr
->saidx
.proto
) {
1908 if (level
== IPSEC_LEVEL_REQUIRE
) {
1912 /* this won't work with multiple input threads - isr->sav would change
1913 * with every packet and is not necessarily related to the current packet
1914 * being processed. If ESP processing is required - the esp code should
1915 * make sure that the integrity check is present and correct. I don't see
1916 * why it would be necessary to check for the presence of the integrity
1917 * check value here. I think this is just wrong.
1918 * isr->sav has been removed.
1919 * %%%%%% this needs to be re-worked at some point but I think the code below can
1920 * be ignored for now.
1922 if (isr
->sav
!= NULL
1923 && isr
->sav
->flags
== SADB_X_EXT_NONE
1924 && isr
->sav
->alg_auth
!= SADB_AALG_NONE
)
1930 if (level
== IPSEC_LEVEL_REQUIRE
) {
1935 case IPPROTO_IPCOMP
:
1937 * we don't really care, as IPcomp document says that
1938 * we shouldn't compress small packets, IPComp policy
1939 * should always be treated as being in "use" level.
1945 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1946 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1947 need_auth
, need_conf
, need_icv
, m
->m_flags
));
1949 if ((need_conf
&& !(m
->m_flags
& M_DECRYPTED
))
1950 || (!need_auth
&& need_icv
&& !(m
->m_flags
& M_AUTHIPDGM
))
1951 || (need_auth
&& !(m
->m_flags
& M_AUTHIPHDR
)))
1958 * Check AH/ESP integrity.
1959 * This function is called from tcp_input(), udp_input(),
1960 * and {ah,esp}4_input for tunnel mode
1963 ipsec4_in_reject_so(m
, so
)
1967 struct secpolicy
*sp
= NULL
;
1971 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1974 return 0; /* XXX should be panic ? */
1976 /* get SP for this packet.
1977 * When we are called from ip_forward(), we call
1978 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1981 sp
= ipsec4_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
);
1983 sp
= ipsec4_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, 0, &error
);
1986 return 0; /* XXX should be panic ?
1987 * -> No, there may be error. */
1989 result
= ipsec_in_reject(sp
, m
);
1990 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
1991 printf("DP ipsec4_in_reject_so call free SP:0x%llx\n",
1992 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
1993 key_freesp(sp
, KEY_SADB_UNLOCKED
);
1999 ipsec4_in_reject(m
, inp
)
2004 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2006 return ipsec4_in_reject_so(m
, NULL
);
2007 if (inp
->inp_socket
)
2008 return ipsec4_in_reject_so(m
, inp
->inp_socket
);
2010 panic("ipsec4_in_reject: invalid inpcb/socket");
2018 * Check AH/ESP integrity.
2019 * This function is called from tcp6_input(), udp6_input(),
2020 * and {ah,esp}6_input for tunnel mode
2023 ipsec6_in_reject_so(m
, so
)
2027 struct secpolicy
*sp
= NULL
;
2031 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2034 return 0; /* XXX should be panic ? */
2036 /* get SP for this packet.
2037 * When we are called from ip_forward(), we call
2038 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
2041 sp
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
);
2043 sp
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, 0, &error
);
2046 return 0; /* XXX should be panic ? */
2048 result
= ipsec_in_reject(sp
, m
);
2049 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2050 printf("DP ipsec6_in_reject_so call free SP:0x%llx\n",
2051 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2052 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2058 ipsec6_in_reject(m
, in6p
)
2060 struct in6pcb
*in6p
;
2063 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2065 return ipsec6_in_reject_so(m
, NULL
);
2066 if (in6p
->in6p_socket
)
2067 return ipsec6_in_reject_so(m
, in6p
->in6p_socket
);
2069 panic("ipsec6_in_reject: invalid in6p/socket");
2077 * compute the byte size to be occupied by IPsec header.
2078 * in case it is tunneled, it includes the size of outer IP header.
2079 * NOTE: SP passed is free in this function.
2083 struct secpolicy
*sp
;
2085 struct ipsecrequest
*isr
;
2088 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2089 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2090 printf("ipsec_hdrsiz: using SP\n");
2091 kdebug_secpolicy(sp
));
2094 switch (sp
->policy
) {
2095 case IPSEC_POLICY_DISCARD
:
2096 case IPSEC_POLICY_GENERATE
:
2097 case IPSEC_POLICY_BYPASS
:
2098 case IPSEC_POLICY_NONE
:
2101 case IPSEC_POLICY_IPSEC
:
2104 case IPSEC_POLICY_ENTRUST
:
2106 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
);
2111 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
2115 switch (isr
->saidx
.proto
) {
2118 clen
= esp_hdrsiz(isr
);
2124 clen
= ah_hdrsiz(isr
);
2126 case IPPROTO_IPCOMP
:
2127 clen
= sizeof(struct ipcomp
);
2131 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
2132 switch (((struct sockaddr
*)&isr
->saidx
.dst
)->sa_family
) {
2134 clen
+= sizeof(struct ip
);
2138 clen
+= sizeof(struct ip6_hdr
);
2142 ipseclog((LOG_ERR
, "ipsec_hdrsiz: "
2143 "unknown AF %d in IPsec tunnel SA\n",
2144 ((struct sockaddr
*)&isr
->saidx
.dst
)->sa_family
));
2154 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
2156 ipsec4_hdrsiz(m
, dir
, inp
)
2161 struct secpolicy
*sp
= NULL
;
2165 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2168 return 0; /* XXX should be panic ? */
2169 if (inp
!= NULL
&& inp
->inp_socket
== NULL
)
2170 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
2172 /* get SP for this packet.
2173 * When we are called from ip_forward(), we call
2174 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2177 sp
= ipsec4_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
);
2179 sp
= ipsec4_getpolicybyaddr(m
, dir
, 0, &error
);
2182 return 0; /* XXX should be panic ? */
2184 size
= ipsec_hdrsiz(sp
);
2185 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2186 printf("DP ipsec4_hdrsiz call free SP:0x%llx\n",
2187 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2188 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2189 printf("ipsec4_hdrsiz: size:%lu.\n", (u_int32_t
)size
));
2190 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2196 /* This function is called from ipsec6_hdrsize_tcp(),
2197 * and maybe from ip6_forward.()
2200 ipsec6_hdrsiz(m
, dir
, in6p
)
2203 struct in6pcb
*in6p
;
2205 struct secpolicy
*sp
= NULL
;
2209 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2212 return 0; /* XXX shoud be panic ? */
2213 if (in6p
!= NULL
&& in6p
->in6p_socket
== NULL
)
2214 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2216 /* get SP for this packet */
2217 /* XXX Is it right to call with IP_FORWARDING. */
2219 sp
= ipsec6_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
);
2221 sp
= ipsec6_getpolicybyaddr(m
, dir
, 0, &error
);
2225 size
= ipsec_hdrsiz(sp
);
2226 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2227 printf("DP ipsec6_hdrsiz call free SP:0x%llx\n",
2228 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2229 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2230 printf("ipsec6_hdrsiz: size:%lu.\n", (u_int32_t
)size
));
2231 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2239 * encapsulate for ipsec tunnel.
2240 * ip->ip_src must be fixed later on.
2243 ipsec4_encapsulate(m
, sav
)
2245 struct secasvar
*sav
;
2252 /* can't tunnel between different AFs */
2253 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2254 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2255 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2260 /* XXX if the dst is myself, perform nothing. */
2261 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2267 if (m
->m_len
< sizeof(*ip
))
2268 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2270 ip
= mtod(m
, struct ip
*);
2272 hlen
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
2274 hlen
= ip
->ip_hl
<< 2;
2277 if (m
->m_len
!= hlen
)
2278 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2280 /* generate header checksum */
2283 ip
->ip_sum
= in_cksum(m
, hlen
);
2285 ip
->ip_sum
= in_cksum(m
, hlen
);
2288 plen
= m
->m_pkthdr
.len
;
2291 * grow the mbuf to accomodate the new IPv4 header.
2292 * NOTE: IPv4 options will never be copied.
2294 if (M_LEADINGSPACE(m
->m_next
) < hlen
) {
2296 MGET(n
, M_DONTWAIT
, MT_DATA
);
2302 n
->m_next
= m
->m_next
;
2304 m
->m_pkthdr
.len
+= hlen
;
2305 oip
= mtod(n
, struct ip
*);
2307 m
->m_next
->m_len
+= hlen
;
2308 m
->m_next
->m_data
-= hlen
;
2309 m
->m_pkthdr
.len
+= hlen
;
2310 oip
= mtod(m
->m_next
, struct ip
*);
2312 ip
= mtod(m
, struct ip
*);
2313 ovbcopy((caddr_t
)ip
, (caddr_t
)oip
, hlen
);
2314 m
->m_len
= sizeof(struct ip
);
2315 m
->m_pkthdr
.len
-= (hlen
- sizeof(struct ip
));
2317 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2318 /* ECN consideration. */
2319 ip_ecn_ingress(ip4_ipsec_ecn
, &ip
->ip_tos
, &oip
->ip_tos
);
2321 ip
->ip_vhl
= IP_MAKE_VHL(IPVERSION
, sizeof(struct ip
) >> 2);
2323 ip
->ip_hl
= sizeof(struct ip
) >> 2;
2325 ip
->ip_off
&= htons(~IP_OFFMASK
);
2326 ip
->ip_off
&= htons(~IP_MF
);
2327 switch (ip4_ipsec_dfbit
) {
2328 case 0: /* clear DF bit */
2329 ip
->ip_off
&= htons(~IP_DF
);
2331 case 1: /* set DF bit */
2332 ip
->ip_off
|= htons(IP_DF
);
2334 default: /* copy DF bit */
2337 ip
->ip_p
= IPPROTO_IPIP
;
2338 if (plen
+ sizeof(struct ip
) < IP_MAXPACKET
)
2339 ip
->ip_len
= htons(plen
+ sizeof(struct ip
));
2341 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2342 "leave ip_len as is (invalid packet)\n"));
2344 ip
->ip_id
= ip_randomid();
2345 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2346 &ip
->ip_src
, sizeof(ip
->ip_src
));
2347 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2348 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2349 ip
->ip_ttl
= IPDEFTTL
;
2351 /* XXX Should ip_src be updated later ? */
2357 * encapsulate for ipsec tunnel.
2358 * ip->ip_src must be fixed later on.
2361 ipsec4_encapsulate_utun_esp_keepalive(m_ptr
, sav
)
2362 struct mbuf
**m_ptr
;
2363 struct secasvar
*sav
;
2367 struct mbuf
*m
= *m_ptr
;
2369 /* can't tunnel between different AFs */
2370 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2371 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2372 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2378 plen
= m
->m_pkthdr
.len
;
2381 * grow the mbuf to accomodate the new IPv4 header.
2382 * NOTE: IPv4 options will never be copied.
2386 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
2392 if (m
->m_flags
& M_PKTHDR
) {
2393 M_COPY_PKTHDR(n
, m
);
2394 m
->m_flags
&= ~M_PKTHDR
;
2396 MH_ALIGN(n
, sizeof(*ip
));
2397 n
->m_len
= sizeof(*ip
);
2399 n
->m_pkthdr
.len
= (plen
+ n
->m_len
);
2403 plen
= m
->m_pkthdr
.len
;
2405 ip
= mtod(m
, __typeof__(ip
));
2407 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2408 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2410 ip
->ip_vhl
= IP_MAKE_VHL(IPVERSION
, sizeof(*ip
) >> 2);
2412 ip
->ip_hl
= sizeof(*ip
) >> 2;
2414 ip
->ip_off
&= htons(~IP_OFFMASK
);
2415 ip
->ip_off
&= htons(~IP_MF
);
2416 switch (ip4_ipsec_dfbit
) {
2417 case 0: /* clear DF bit */
2418 ip
->ip_off
&= htons(~IP_DF
);
2420 case 1: /* set DF bit */
2421 ip
->ip_off
|= htons(IP_DF
);
2423 default: /* copy DF bit */
2426 ip
->ip_p
= IPPROTO_IPIP
;
2427 if (plen
< IP_MAXPACKET
)
2428 ip
->ip_len
= htons(plen
);
2430 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2431 "leave ip_len as is (invalid packet)\n"));
2433 ip
->ip_id
= ip_randomid();
2434 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2435 &ip
->ip_src
, sizeof(ip
->ip_src
));
2436 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2437 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2438 ip
->ip_ttl
= IPDEFTTL
;
2440 /* XXX Should ip_src be updated later ? */
2448 ipsec6_encapsulate(m
, sav
)
2450 struct secasvar
*sav
;
2452 struct ip6_hdr
*oip6
;
2453 struct ip6_hdr
*ip6
;
2456 /* can't tunnel between different AFs */
2457 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2458 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2459 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET6
) {
2464 /* XXX if the dst is myself, perform nothing. */
2465 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2471 plen
= m
->m_pkthdr
.len
;
2474 * grow the mbuf to accomodate the new IPv6 header.
2476 if (m
->m_len
!= sizeof(struct ip6_hdr
))
2477 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2478 if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) {
2480 MGET(n
, M_DONTWAIT
, MT_DATA
);
2485 n
->m_len
= sizeof(struct ip6_hdr
);
2486 n
->m_next
= m
->m_next
;
2488 m
->m_pkthdr
.len
+= sizeof(struct ip6_hdr
);
2489 oip6
= mtod(n
, struct ip6_hdr
*);
2491 m
->m_next
->m_len
+= sizeof(struct ip6_hdr
);
2492 m
->m_next
->m_data
-= sizeof(struct ip6_hdr
);
2493 m
->m_pkthdr
.len
+= sizeof(struct ip6_hdr
);
2494 oip6
= mtod(m
->m_next
, struct ip6_hdr
*);
2496 ip6
= mtod(m
, struct ip6_hdr
*);
2497 ovbcopy((caddr_t
)ip6
, (caddr_t
)oip6
, sizeof(struct ip6_hdr
));
2499 /* Fake link-local scope-class addresses */
2500 if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_src
))
2501 oip6
->ip6_src
.s6_addr16
[1] = 0;
2502 if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_dst
))
2503 oip6
->ip6_dst
.s6_addr16
[1] = 0;
2505 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2506 /* ECN consideration. */
2507 ip6_ecn_ingress(ip6_ipsec_ecn
, &ip6
->ip6_flow
, &oip6
->ip6_flow
);
2508 if (plen
< IPV6_MAXPACKET
- sizeof(struct ip6_hdr
))
2509 ip6
->ip6_plen
= htons(plen
);
2511 /* ip6->ip6_plen will be updated in ip6_output() */
2513 ip6
->ip6_nxt
= IPPROTO_IPV6
;
2514 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.src
)->sin6_addr
,
2515 &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
2516 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
)->sin6_addr
,
2517 &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
2518 ip6
->ip6_hlim
= IPV6_DEFHLIM
;
2520 /* XXX Should ip6_src be updated later ? */
2526 ipsec64_encapsulate(m
, sav
)
2528 struct secasvar
*sav
;
2530 struct ip6_hdr
*ip6
, *ip6i
;
2535 /* tunneling over IPv4 */
2536 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2537 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2538 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2543 /* XXX if the dst is myself, perform nothing. */
2544 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2550 plen
= m
->m_pkthdr
.len
;
2551 ip6
= mtod(m
, struct ip6_hdr
*);
2552 hlim
= ip6
->ip6_hlim
;
2554 * grow the mbuf to accomodate the new IPv4 header.
2556 if (m
->m_len
!= sizeof(struct ip6_hdr
))
2557 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2558 if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) {
2560 MGET(n
, M_DONTWAIT
, MT_DATA
);
2565 n
->m_len
= sizeof(struct ip6_hdr
);
2566 n
->m_next
= m
->m_next
;
2568 m
->m_pkthdr
.len
+= sizeof(struct ip
);
2569 ip6i
= mtod(n
, struct ip6_hdr
*);
2571 m
->m_next
->m_len
+= sizeof(struct ip6_hdr
);
2572 m
->m_next
->m_data
-= sizeof(struct ip6_hdr
);
2573 m
->m_pkthdr
.len
+= sizeof(struct ip
);
2574 ip6i
= mtod(m
->m_next
, struct ip6_hdr
*);
2576 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2577 /* ECN consideration. */
2578 /* XXX To be fixed later if needed */
2579 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2581 bcopy(ip6
, ip6i
, sizeof(struct ip6_hdr
));
2582 ip
= mtod(m
, struct ip
*);
2583 m
->m_len
= sizeof(struct ip
);
2585 * Fill in some of the IPv4 fields - we don't need all of them
2586 * because the rest will be filled in by ip_output
2588 ip
->ip_v
= IPVERSION
;
2589 ip
->ip_hl
= sizeof(struct ip
) >> 2;
2595 ip
->ip_p
= IPPROTO_IPV6
;
2596 if (plen
+ sizeof(struct ip
) < IP_MAXPACKET
)
2597 ip
->ip_len
= htons(plen
+ sizeof(struct ip
));
2599 ip
->ip_len
= htons(plen
);
2600 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2601 "leave ip_len as is (invalid packet)\n"));
2603 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2604 &ip
->ip_src
, sizeof(ip
->ip_src
));
2605 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2606 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2612 ipsec6_encapsulate_utun_esp_keepalive(m_ptr
, sav
)
2613 struct mbuf
**m_ptr
;
2614 struct secasvar
*sav
;
2616 struct ip6_hdr
*ip6
;
2618 struct mbuf
*m
= *m_ptr
;
2620 /* can't tunnel between different AFs */
2621 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2622 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2623 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET6
) {
2629 plen
= m
->m_pkthdr
.len
;
2632 * grow the mbuf to accomodate the new IPv6 header.
2636 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
2642 if (m
->m_flags
& M_PKTHDR
) {
2643 M_COPY_PKTHDR(n
, m
);
2644 m
->m_flags
&= ~M_PKTHDR
;
2646 MH_ALIGN(n
, sizeof(*ip6
));
2647 n
->m_len
= sizeof(*ip6
);
2649 n
->m_pkthdr
.len
= (plen
+ n
->m_len
);
2653 plen
= m
->m_pkthdr
.len
;
2655 ip6
= mtod(m
, __typeof__(ip6
));
2657 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2658 if (plen
< IPV6_MAXPACKET
)
2659 ip6
->ip6_plen
= htons(plen
);
2661 /* ip6->ip6_plen will be updated in ip6_output() */
2663 ip6
->ip6_nxt
= IPPROTO_IPV6
;
2664 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.src
)->sin6_addr
,
2665 &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
2666 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
)->sin6_addr
,
2667 &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
2668 ip6
->ip6_hlim
= IPV6_DEFHLIM
;
2670 /* XXX Should ip6_src be updated later ? */
2677 * Check the variable replay window.
2678 * ipsec_chkreplay() performs replay check before ICV verification.
2679 * ipsec_updatereplay() updates replay bitmap. This must be called after
2680 * ICV verification (it also performs replay check, which is usually done
2682 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2684 * based on RFC 2401.
2687 ipsec_chkreplay(seq
, sav
)
2689 struct secasvar
*sav
;
2691 const struct secreplay
*replay
;
2694 u_int32_t wsizeb
; /* constant: bits of window size */
2695 int frlast
; /* constant: last frame */
2700 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2702 lck_mtx_lock(sadb_mutex
);
2703 replay
= sav
->replay
;
2705 if (replay
->wsize
== 0) {
2706 lck_mtx_unlock(sadb_mutex
);
2707 return 1; /* no need to check replay. */
2711 frlast
= replay
->wsize
- 1;
2712 wsizeb
= replay
->wsize
<< 3;
2714 /* sequence number of 0 is invalid */
2716 lck_mtx_unlock(sadb_mutex
);
2720 /* first time is always okay */
2721 if (replay
->count
== 0) {
2722 lck_mtx_unlock(sadb_mutex
);
2726 if (seq
> replay
->lastseq
) {
2727 /* larger sequences are okay */
2728 lck_mtx_unlock(sadb_mutex
);
2731 /* seq is equal or less than lastseq. */
2732 diff
= replay
->lastseq
- seq
;
2734 /* over range to check, i.e. too old or wrapped */
2735 if (diff
>= wsizeb
) {
2736 lck_mtx_unlock(sadb_mutex
);
2740 fr
= frlast
- diff
/ 8;
2742 /* this packet already seen ? */
2743 if ((replay
->bitmap
)[fr
] & (1 << (diff
% 8))) {
2744 lck_mtx_unlock(sadb_mutex
);
2748 /* out of order but good */
2749 lck_mtx_unlock(sadb_mutex
);
2755 * check replay counter whether to update or not.
2760 ipsec_updatereplay(seq
, sav
)
2762 struct secasvar
*sav
;
2764 struct secreplay
*replay
;
2767 u_int32_t wsizeb
; /* constant: bits of window size */
2768 int frlast
; /* constant: last frame */
2772 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2774 lck_mtx_lock(sadb_mutex
);
2775 replay
= sav
->replay
;
2777 if (replay
->wsize
== 0)
2778 goto ok
; /* no need to check replay. */
2781 frlast
= replay
->wsize
- 1;
2782 wsizeb
= replay
->wsize
<< 3;
2784 /* sequence number of 0 is invalid */
2789 if (replay
->count
== 0) {
2790 replay
->lastseq
= seq
;
2791 bzero(replay
->bitmap
, replay
->wsize
);
2792 (replay
->bitmap
)[frlast
] = 1;
2796 if (seq
> replay
->lastseq
) {
2797 /* seq is larger than lastseq. */
2798 diff
= seq
- replay
->lastseq
;
2800 /* new larger sequence number */
2801 if (diff
< wsizeb
) {
2803 /* set bit for this packet */
2804 vshiftl((unsigned char *) replay
->bitmap
, diff
, replay
->wsize
);
2805 (replay
->bitmap
)[frlast
] |= 1;
2807 /* this packet has a "way larger" */
2808 bzero(replay
->bitmap
, replay
->wsize
);
2809 (replay
->bitmap
)[frlast
] = 1;
2811 replay
->lastseq
= seq
;
2813 /* larger is good */
2815 /* seq is equal or less than lastseq. */
2816 diff
= replay
->lastseq
- seq
;
2818 /* over range to check, i.e. too old or wrapped */
2819 if (diff
>= wsizeb
) {
2820 lck_mtx_unlock(sadb_mutex
);
2824 fr
= frlast
- diff
/ 8;
2826 /* this packet already seen ? */
2827 if ((replay
->bitmap
)[fr
] & (1 << (diff
% 8))) {
2828 lck_mtx_unlock(sadb_mutex
);
2833 (replay
->bitmap
)[fr
] |= (1 << (diff
% 8));
2835 /* out of order but good */
2839 if (replay
->count
== ~0) {
2841 /* set overflow flag */
2844 /* don't increment, no more packets accepted */
2845 if ((sav
->flags
& SADB_X_EXT_CYCSEQ
) == 0) {
2846 lck_mtx_unlock(sadb_mutex
);
2850 ipseclog((LOG_WARNING
, "replay counter made %d cycle. %s\n",
2851 replay
->overflow
, ipsec_logsastr(sav
)));
2856 lck_mtx_unlock(sadb_mutex
);
2861 * shift variable length buffer to left.
2862 * IN: bitmap: pointer to the buffer
2863 * nbit: the number of to shift.
2864 * wsize: buffer size (bytes).
2867 vshiftl(bitmap
, nbit
, wsize
)
2868 unsigned char *bitmap
;
2874 for (j
= 0; j
< nbit
; j
+= 8) {
2875 s
= (nbit
- j
< 8) ? (nbit
- j
): 8;
2877 for (i
= 1; i
< wsize
; i
++) {
2878 over
= (bitmap
[i
] >> (8 - s
));
2880 bitmap
[i
-1] |= over
;
2888 ipsec4_logpacketstr(ip
, spi
)
2892 static char buf
[256] __attribute__((aligned(4)));
2896 s
= (u_int8_t
*)(&ip
->ip_src
);
2897 d
= (u_int8_t
*)(&ip
->ip_dst
);
2900 snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
));
2903 snprintf(p
, sizeof(buf
) - (p
- buf
), "src=%u.%u.%u.%u",
2904 s
[0], s
[1], s
[2], s
[3]);
2907 snprintf(p
, sizeof(buf
) - (p
- buf
), " dst=%u.%u.%u.%u",
2908 d
[0], d
[1], d
[2], d
[3]);
2911 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
2918 ipsec6_logpacketstr(ip6
, spi
)
2919 struct ip6_hdr
*ip6
;
2922 static char buf
[256] __attribute__((aligned(4)));
2926 snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
));
2929 snprintf(p
, sizeof(buf
) - (p
- buf
), "src=%s",
2930 ip6_sprintf(&ip6
->ip6_src
));
2933 snprintf(p
, sizeof(buf
) - (p
- buf
), " dst=%s",
2934 ip6_sprintf(&ip6
->ip6_dst
));
2937 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
2945 struct secasvar
*sav
;
2947 static char buf
[256] __attribute__((aligned(4)));
2949 struct secasindex
*saidx
= &sav
->sah
->saidx
;
2951 /* validity check */
2952 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2953 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
)
2954 panic("ipsec_logsastr: family mismatched.\n");
2957 snprintf(buf
, sizeof(buf
), "SA(SPI=%u ", (u_int32_t
)ntohl(sav
->spi
));
2960 if (((struct sockaddr
*)&saidx
->src
)->sa_family
== AF_INET
) {
2962 s
= (u_int8_t
*)&((struct sockaddr_in
*)&saidx
->src
)->sin_addr
;
2963 d
= (u_int8_t
*)&((struct sockaddr_in
*)&saidx
->dst
)->sin_addr
;
2964 snprintf(p
, sizeof(buf
) - (p
- buf
),
2965 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
2966 s
[0], s
[1], s
[2], s
[3], d
[0], d
[1], d
[2], d
[3]);
2969 else if (((struct sockaddr
*)&saidx
->src
)->sa_family
== AF_INET6
) {
2970 snprintf(p
, sizeof(buf
) - (p
- buf
),
2972 ip6_sprintf(&((struct sockaddr_in6
*)&saidx
->src
)->sin6_addr
));
2975 snprintf(p
, sizeof(buf
) - (p
- buf
),
2977 ip6_sprintf(&((struct sockaddr_in6
*)&saidx
->dst
)->sin6_addr
));
2982 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
2998 p
= mtod(m
, u_char
*);
2999 for (i
= 0; i
< m
->m_len
; i
++) {
3000 printf("%02x ", p
[i
]);
3002 if (totlen
% 16 == 0)
3007 if (totlen
% 16 != 0)
3014 * IPsec output logic for IPv4.
3017 ipsec4_output_internal(struct ipsec_output_state
*state
, struct secasvar
*sav
)
3019 struct ip
*ip
= NULL
;
3021 struct sockaddr_in
*dst4
;
3024 /* validity check */
3025 if (sav
== NULL
|| sav
->sah
== NULL
) {
3031 * If there is no valid SA, we give up to process any
3032 * more. In such a case, the SA's status is changed
3033 * from DYING to DEAD after allocating. If a packet
3034 * send to the receiver by dead SA, the receiver can
3035 * not decode a packet because SA has been dead.
3037 if (sav
->state
!= SADB_SASTATE_MATURE
3038 && sav
->state
!= SADB_SASTATE_DYING
) {
3039 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
);
3044 state
->outgoing_if
= sav
->sah
->outgoing_if
;
3047 * There may be the case that SA status will be changed when
3048 * we are refering to one. So calling splsoftnet().
3051 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3053 * build IPsec tunnel.
3055 /* XXX should be processed with other familiy */
3056 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
3057 ipseclog((LOG_ERR
, "ipsec4_output: "
3058 "family mismatched between inner and outer spi=%u\n",
3059 (u_int32_t
)ntohl(sav
->spi
)));
3060 error
= EAFNOSUPPORT
;
3064 state
->m
= ipsec4_splithdr(state
->m
);
3069 error
= ipsec4_encapsulate(state
->m
, sav
);
3074 ip
= mtod(state
->m
, struct ip
*);
3076 // grab sadb_mutex, before updating sah's route cache
3077 lck_mtx_lock(sadb_mutex
);
3078 ro4
= &sav
->sah
->sa_route
;
3079 dst4
= (struct sockaddr_in
*)(void *)&ro4
->ro_dst
;
3080 if (ro4
->ro_rt
!= NULL
) {
3081 RT_LOCK(ro4
->ro_rt
);
3083 if (ROUTE_UNUSABLE(ro4
) ||
3084 dst4
->sin_addr
.s_addr
!= ip
->ip_dst
.s_addr
) {
3085 if (ro4
->ro_rt
!= NULL
)
3086 RT_UNLOCK(ro4
->ro_rt
);
3089 if (ro4
->ro_rt
== 0) {
3090 dst4
->sin_family
= AF_INET
;
3091 dst4
->sin_len
= sizeof(*dst4
);
3092 dst4
->sin_addr
= ip
->ip_dst
;
3094 if (ro4
->ro_rt
== 0) {
3095 OSAddAtomic(1, &ipstat
.ips_noroute
);
3096 error
= EHOSTUNREACH
;
3097 // release sadb_mutex, after updating sah's route cache
3098 lck_mtx_unlock(sadb_mutex
);
3101 RT_LOCK(ro4
->ro_rt
);
3105 * adjust state->dst if tunnel endpoint is offlink
3107 * XXX: caching rt_gateway value in the state is
3108 * not really good, since it may point elsewhere
3109 * when the gateway gets modified to a larger
3110 * sockaddr via rt_setgate(). This is currently
3111 * addressed by SA_SIZE roundup in that routine.
3113 if (ro4
->ro_rt
->rt_flags
& RTF_GATEWAY
)
3114 dst4
= (struct sockaddr_in
*)(void *)ro4
->ro_rt
->rt_gateway
;
3115 RT_UNLOCK(ro4
->ro_rt
);
3116 ROUTE_RELEASE(&state
->ro
);
3117 route_copyout(&state
->ro
, ro4
, sizeof(state
->ro
));
3118 state
->dst
= (struct sockaddr
*)dst4
;
3119 state
->tunneled
= 4;
3120 // release sadb_mutex, after updating sah's route cache
3121 lck_mtx_unlock(sadb_mutex
);
3124 state
->m
= ipsec4_splithdr(state
->m
);
3129 switch (sav
->sah
->saidx
.proto
) {
3132 if ((error
= esp4_output(state
->m
, sav
)) != 0) {
3144 if ((error
= ah4_output(state
->m
, sav
)) != 0) {
3149 case IPPROTO_IPCOMP
:
3150 if ((error
= ipcomp4_output(state
->m
, sav
)) != 0) {
3157 "ipsec4_output: unknown ipsec protocol %d\n",
3158 sav
->sah
->saidx
.proto
));
3165 if (state
->m
== 0) {
3177 ipsec4_interface_output(struct ipsec_output_state
*state
, ifnet_t interface
)
3180 struct secasvar
*sav
= NULL
;
3182 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3185 panic("state == NULL in ipsec4_output");
3187 panic("state->m == NULL in ipsec4_output");
3189 panic("state->dst == NULL in ipsec4_output");
3191 sav
= key_alloc_outbound_sav_for_interface(interface
, AF_INET
);
3196 if ((error
= ipsec4_output_internal(state
, sav
)) != 0) {
3200 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, 0,0,0,0,0);
3202 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3207 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3210 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, error
,0,0,0,0);
3215 ipsec4_output(struct ipsec_output_state
*state
, struct secpolicy
*sp
, __unused
int flags
)
3217 struct ip
*ip
= NULL
;
3218 struct ipsecrequest
*isr
= NULL
;
3219 struct secasindex saidx
;
3220 struct secasvar
*sav
= NULL
;
3222 struct sockaddr_in
*sin
;
3224 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3227 panic("state == NULL in ipsec4_output");
3229 panic("state->m == NULL in ipsec4_output");
3231 panic("state->dst == NULL in ipsec4_output");
3233 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_START
, 0,0,0,0,0);
3235 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3236 printf("ipsec4_output: applied SP\n");
3237 kdebug_secpolicy(sp
));
3239 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
3240 /* make SA index for search proper SA */
3241 ip
= mtod(state
->m
, struct ip
*);
3242 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3243 saidx
.mode
= isr
->saidx
.mode
;
3244 saidx
.reqid
= isr
->saidx
.reqid
;
3245 sin
= (struct sockaddr_in
*)&saidx
.src
;
3246 if (sin
->sin_len
== 0) {
3247 sin
->sin_len
= sizeof(*sin
);
3248 sin
->sin_family
= AF_INET
;
3249 sin
->sin_port
= IPSEC_PORT_ANY
;
3250 bcopy(&ip
->ip_src
, &sin
->sin_addr
,
3251 sizeof(sin
->sin_addr
));
3253 sin
= (struct sockaddr_in
*)&saidx
.dst
;
3254 if (sin
->sin_len
== 0) {
3255 sin
->sin_len
= sizeof(*sin
);
3256 sin
->sin_family
= AF_INET
;
3257 sin
->sin_port
= IPSEC_PORT_ANY
;
3259 * Get port from packet if upper layer is UDP and nat traversal
3260 * is enabled and transport mode.
3263 if ((esp_udp_encap_port
& 0xFFFF) != 0 &&
3264 isr
->saidx
.mode
== IPSEC_MODE_TRANSPORT
) {
3266 if (ip
->ip_p
== IPPROTO_UDP
) {
3270 hlen
= IP_VHL_HL(ip
->ip_vhl
) << 2;
3272 hlen
= ip
->ip_hl
<< 2;
3274 if (state
->m
->m_len
< hlen
+ sizeof(struct udphdr
)) {
3275 state
->m
= m_pullup(state
->m
, hlen
+ sizeof(struct udphdr
));
3277 ipseclog((LOG_DEBUG
, "IPv4 output: can't pullup UDP header\n"));
3278 IPSEC_STAT_INCREMENT(ipsecstat
.in_inval
);
3281 ip
= mtod(state
->m
, struct ip
*);
3283 udp
= (struct udphdr
*)(void *)(((u_int8_t
*)ip
) + hlen
);
3284 sin
->sin_port
= udp
->uh_dport
;
3288 bcopy(&ip
->ip_dst
, &sin
->sin_addr
,
3289 sizeof(sin
->sin_addr
));
3292 if ((error
= key_checkrequest(isr
, &saidx
, &sav
)) != 0) {
3294 * IPsec processing is required, but no SA found.
3295 * I assume that key_acquire() had been called
3296 * to get/establish the SA. Here I discard
3297 * this packet because it is responsibility for
3298 * upper layer to retransmit the packet.
3300 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
);
3304 /* validity check */
3306 switch (ipsec_get_reqlevel(isr
)) {
3307 case IPSEC_LEVEL_USE
:
3309 case IPSEC_LEVEL_REQUIRE
:
3310 /* must be not reached here. */
3311 panic("ipsec4_output: no SA found, but required.");
3315 if ((error
= ipsec4_output_internal(state
, sav
)) != 0) {
3320 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, 0,0,0,0,0);
3322 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3327 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3330 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, error
,0,0,0,0);
3338 * IPsec output logic for IPv6, transport mode.
3341 ipsec6_output_trans_internal(
3342 struct ipsec_output_state
*state
,
3343 struct secasvar
*sav
,
3347 struct ip6_hdr
*ip6
;
3351 /* validity check */
3352 if (sav
== NULL
|| sav
->sah
== NULL
) {
3358 * If there is no valid SA, we give up to process.
3359 * see same place at ipsec4_output().
3361 if (sav
->state
!= SADB_SASTATE_MATURE
3362 && sav
->state
!= SADB_SASTATE_DYING
) {
3363 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3368 state
->outgoing_if
= sav
->sah
->outgoing_if
;
3370 switch (sav
->sah
->saidx
.proto
) {
3373 error
= esp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3380 error
= ah6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3382 case IPPROTO_IPCOMP
:
3383 error
= ipcomp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3386 ipseclog((LOG_ERR
, "ipsec6_output_trans: "
3387 "unknown ipsec protocol %d\n", sav
->sah
->saidx
.proto
));
3389 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3397 plen
= state
->m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
3398 if (plen
> IPV6_MAXPACKET
) {
3399 ipseclog((LOG_ERR
, "ipsec6_output_trans: "
3400 "IPsec with IPv6 jumbogram is not supported\n"));
3401 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3402 error
= EINVAL
; /*XXX*/
3405 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3406 ip6
->ip6_plen
= htons(plen
);
3414 ipsec6_output_trans(
3415 struct ipsec_output_state
*state
,
3418 struct secpolicy
*sp
,
3422 struct ip6_hdr
*ip6
;
3423 struct ipsecrequest
*isr
= NULL
;
3424 struct secasindex saidx
;
3426 struct sockaddr_in6
*sin6
;
3427 struct secasvar
*sav
= NULL
;
3429 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3432 panic("state == NULL in ipsec6_output_trans");
3434 panic("state->m == NULL in ipsec6_output_trans");
3436 panic("nexthdrp == NULL in ipsec6_output_trans");
3438 panic("mprev == NULL in ipsec6_output_trans");
3440 panic("sp == NULL in ipsec6_output_trans");
3442 panic("tun == NULL in ipsec6_output_trans");
3444 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3445 printf("ipsec6_output_trans: applyed SP\n");
3446 kdebug_secpolicy(sp
));
3449 for (isr
= sp
->req
; isr
; isr
= isr
->next
) {
3450 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3451 /* the rest will be handled by ipsec6_output_tunnel() */
3455 /* make SA index for search proper SA */
3456 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3457 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3458 saidx
.mode
= isr
->saidx
.mode
;
3459 saidx
.reqid
= isr
->saidx
.reqid
;
3460 sin6
= (struct sockaddr_in6
*)&saidx
.src
;
3461 if (sin6
->sin6_len
== 0) {
3462 sin6
->sin6_len
= sizeof(*sin6
);
3463 sin6
->sin6_family
= AF_INET6
;
3464 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3465 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
,
3466 sizeof(ip6
->ip6_src
));
3467 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
3468 /* fix scope id for comparing SPD */
3469 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3470 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
3473 sin6
= (struct sockaddr_in6
*)&saidx
.dst
;
3474 if (sin6
->sin6_len
== 0) {
3475 sin6
->sin6_len
= sizeof(*sin6
);
3476 sin6
->sin6_family
= AF_INET6
;
3477 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3478 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
,
3479 sizeof(ip6
->ip6_dst
));
3480 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
3481 /* fix scope id for comparing SPD */
3482 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3483 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
3487 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) {
3489 * IPsec processing is required, but no SA found.
3490 * I assume that key_acquire() had been called
3491 * to get/establish the SA. Here I discard
3492 * this packet because it is responsibility for
3493 * upper layer to retransmit the packet.
3495 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3499 * Notify the fact that the packet is discarded
3500 * to ourselves. I believe this is better than
3501 * just silently discarding. (jinmei@kame.net)
3502 * XXX: should we restrict the error to TCP packets?
3503 * XXX: should we directly notify sockets via
3506 icmp6_error(state
->m
, ICMP6_DST_UNREACH
,
3507 ICMP6_DST_UNREACH_ADMIN
, 0);
3508 state
->m
= NULL
; /* icmp6_error freed the mbuf */
3512 /* validity check */
3514 switch (ipsec_get_reqlevel(isr
)) {
3515 case IPSEC_LEVEL_USE
:
3517 case IPSEC_LEVEL_REQUIRE
:
3518 /* must be not reached here. */
3519 panic("ipsec6_output_trans: no SA found, but required.");
3523 if ((error
= ipsec6_output_trans_internal(state
, sav
, nexthdrp
, mprev
)) != 0) {
3528 /* if we have more to go, we need a tunnel mode processing */
3533 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3538 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3545 * IPsec output logic for IPv6, tunnel mode.
3548 ipsec6_output_tunnel_internal(struct ipsec_output_state
*state
, struct secasvar
*sav
, int *must_be_last
)
3550 struct ip6_hdr
*ip6
;
3553 struct sockaddr_in6
* dst6
;
3556 /* validity check */
3557 if (sav
== NULL
|| sav
->sah
== NULL
|| sav
->sah
->saidx
.mode
!= IPSEC_MODE_TUNNEL
) {
3563 * If there is no valid SA, we give up to process.
3564 * see same place at ipsec4_output().
3566 if (sav
->state
!= SADB_SASTATE_MATURE
3567 && sav
->state
!= SADB_SASTATE_DYING
) {
3568 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3573 state
->outgoing_if
= sav
->sah
->outgoing_if
;
3575 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3577 * build IPsec tunnel.
3579 state
->m
= ipsec6_splithdr(state
->m
);
3581 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
);
3586 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
== AF_INET6
) {
3587 error
= ipsec6_encapsulate(state
->m
, sav
);
3592 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3593 } else if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
== AF_INET
) {
3596 struct sockaddr_in
* dst4
;
3597 struct route
*ro4
= NULL
;
3598 struct route ro4_copy
;
3599 struct ip_out_args ipoa
= { IFSCOPE_NONE
, { 0 },
3600 IPOAF_SELECT_SRCIF
, 0 };
3605 state
->tunneled
= 4; /* must not process any further in ip6_output */
3606 error
= ipsec64_encapsulate(state
->m
, sav
);
3611 /* Now we have an IPv4 packet */
3612 ip
= mtod(state
->m
, struct ip
*);
3614 // grab sadb_mutex, to update sah's route cache and get a local copy of it
3615 lck_mtx_lock(sadb_mutex
);
3616 ro4
= &sav
->sah
->sa_route
;
3617 dst4
= (struct sockaddr_in
*)(void *)&ro4
->ro_dst
;
3619 RT_LOCK(ro4
->ro_rt
);
3621 if (ROUTE_UNUSABLE(ro4
) ||
3622 dst4
->sin_addr
.s_addr
!= ip
->ip_dst
.s_addr
) {
3623 if (ro4
->ro_rt
!= NULL
)
3624 RT_UNLOCK(ro4
->ro_rt
);
3627 if (ro4
->ro_rt
== NULL
) {
3628 dst4
->sin_family
= AF_INET
;
3629 dst4
->sin_len
= sizeof(*dst4
);
3630 dst4
->sin_addr
= ip
->ip_dst
;
3632 RT_UNLOCK(ro4
->ro_rt
);
3634 route_copyout(&ro4_copy
, ro4
, sizeof(ro4_copy
));
3635 // release sadb_mutex, after updating sah's route cache and getting a local copy
3636 lck_mtx_unlock(sadb_mutex
);
3637 state
->m
= ipsec4_splithdr(state
->m
);
3640 ROUTE_RELEASE(&ro4_copy
);
3643 switch (sav
->sah
->saidx
.proto
) {
3646 if ((error
= esp4_output(state
->m
, sav
)) != 0) {
3648 ROUTE_RELEASE(&ro4_copy
);
3657 ROUTE_RELEASE(&ro4_copy
);
3661 if ((error
= ah4_output(state
->m
, sav
)) != 0) {
3663 ROUTE_RELEASE(&ro4_copy
);
3667 case IPPROTO_IPCOMP
:
3668 if ((error
= ipcomp4_output(state
->m
, sav
)) != 0) {
3670 ROUTE_RELEASE(&ro4_copy
);
3676 "ipsec4_output: unknown ipsec protocol %d\n",
3677 sav
->sah
->saidx
.proto
));
3681 ROUTE_RELEASE(&ro4_copy
);
3685 if (state
->m
== 0) {
3687 ROUTE_RELEASE(&ro4_copy
);
3690 ipsec_set_pkthdr_for_interface(sav
->sah
->ipsec_if
, state
->m
, AF_INET
);
3691 ip
= mtod(state
->m
, struct ip
*);
3692 ip
->ip_len
= ntohs(ip
->ip_len
); /* flip len field before calling ip_output */
3693 error
= ip_output(state
->m
, NULL
, &ro4_copy
, IP_OUTARGS
, NULL
, &ipoa
);
3695 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
3696 lck_mtx_lock(sadb_mutex
);
3697 route_copyin(&ro4_copy
, ro4
, sizeof(ro4_copy
));
3698 lck_mtx_unlock(sadb_mutex
);
3703 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3704 "unsupported inner family, spi=%u\n",
3705 (u_int32_t
)ntohl(sav
->spi
)));
3706 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3707 error
= EAFNOSUPPORT
;
3711 // grab sadb_mutex, before updating sah's route cache
3712 lck_mtx_lock(sadb_mutex
);
3713 ro6
= &sav
->sah
->sa_route
;
3714 dst6
= (struct sockaddr_in6
*)(void *)&ro6
->ro_dst
;
3716 RT_LOCK(ro6
->ro_rt
);
3718 if (ROUTE_UNUSABLE(ro6
) ||
3719 !IN6_ARE_ADDR_EQUAL(&dst6
->sin6_addr
, &ip6
->ip6_dst
)) {
3720 if (ro6
->ro_rt
!= NULL
)
3721 RT_UNLOCK(ro6
->ro_rt
);
3724 if (ro6
->ro_rt
== 0) {
3725 bzero(dst6
, sizeof(*dst6
));
3726 dst6
->sin6_family
= AF_INET6
;
3727 dst6
->sin6_len
= sizeof(*dst6
);
3728 dst6
->sin6_addr
= ip6
->ip6_dst
;
3731 RT_LOCK(ro6
->ro_rt
);
3734 if (ro6
->ro_rt
== 0) {
3735 ip6stat
.ip6s_noroute
++;
3736 IPSEC_STAT_INCREMENT(ipsec6stat
.out_noroute
);
3737 error
= EHOSTUNREACH
;
3738 // release sadb_mutex, after updating sah's route cache
3739 lck_mtx_unlock(sadb_mutex
);
3744 * adjust state->dst if tunnel endpoint is offlink
3746 * XXX: caching rt_gateway value in the state is
3747 * not really good, since it may point elsewhere
3748 * when the gateway gets modified to a larger
3749 * sockaddr via rt_setgate(). This is currently
3750 * addressed by SA_SIZE roundup in that routine.
3752 if (ro6
->ro_rt
->rt_flags
& RTF_GATEWAY
)
3753 dst6
= (struct sockaddr_in6
*)(void *)ro6
->ro_rt
->rt_gateway
;
3754 RT_UNLOCK(ro6
->ro_rt
);
3755 ROUTE_RELEASE(&state
->ro
);
3756 route_copyout(&state
->ro
, ro6
, sizeof(state
->ro
));
3757 state
->dst
= (struct sockaddr
*)dst6
;
3758 state
->tunneled
= 6;
3759 // release sadb_mutex, after updating sah's route cache
3760 lck_mtx_unlock(sadb_mutex
);
3763 state
->m
= ipsec6_splithdr(state
->m
);
3765 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
);
3769 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3770 switch (sav
->sah
->saidx
.proto
) {
3773 error
= esp6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
);
3780 error
= ah6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
);
3782 case IPPROTO_IPCOMP
:
3783 /* XXX code should be here */
3786 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3787 "unknown ipsec protocol %d\n", sav
->sah
->saidx
.proto
));
3789 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3797 plen
= state
->m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
3798 if (plen
> IPV6_MAXPACKET
) {
3799 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3800 "IPsec with IPv6 jumbogram is not supported\n"));
3801 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3802 error
= EINVAL
; /*XXX*/
3805 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3806 ip6
->ip6_plen
= htons(plen
);
3815 ipsec6_output_tunnel(
3816 struct ipsec_output_state
*state
,
3817 struct secpolicy
*sp
,
3820 struct ip6_hdr
*ip6
;
3821 struct ipsecrequest
*isr
= NULL
;
3822 struct secasindex saidx
;
3823 struct secasvar
*sav
= NULL
;
3826 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3829 panic("state == NULL in ipsec6_output_tunnel");
3831 panic("state->m == NULL in ipsec6_output_tunnel");
3833 panic("sp == NULL in ipsec6_output_tunnel");
3835 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3836 printf("ipsec6_output_tunnel: applyed SP\n");
3837 kdebug_secpolicy(sp
));
3840 * transport mode ipsec (before the 1st tunnel mode) is already
3841 * processed by ipsec6_output_trans().
3843 for (isr
= sp
->req
; isr
; isr
= isr
->next
) {
3844 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
3848 for (/* already initialized */; isr
; isr
= isr
->next
) {
3849 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3850 /* When tunnel mode, SA peers must be specified. */
3851 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3853 /* make SA index to look for a proper SA */
3854 struct sockaddr_in6
*sin6
;
3856 bzero(&saidx
, sizeof(saidx
));
3857 saidx
.proto
= isr
->saidx
.proto
;
3858 saidx
.mode
= isr
->saidx
.mode
;
3859 saidx
.reqid
= isr
->saidx
.reqid
;
3861 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3862 sin6
= (struct sockaddr_in6
*)&saidx
.src
;
3863 if (sin6
->sin6_len
== 0) {
3864 sin6
->sin6_len
= sizeof(*sin6
);
3865 sin6
->sin6_family
= AF_INET6
;
3866 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3867 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
,
3868 sizeof(ip6
->ip6_src
));
3869 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
3870 /* fix scope id for comparing SPD */
3871 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3872 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
3875 sin6
= (struct sockaddr_in6
*)&saidx
.dst
;
3876 if (sin6
->sin6_len
== 0) {
3877 sin6
->sin6_len
= sizeof(*sin6
);
3878 sin6
->sin6_family
= AF_INET6
;
3879 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3880 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
,
3881 sizeof(ip6
->ip6_dst
));
3882 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
3883 /* fix scope id for comparing SPD */
3884 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3885 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
3890 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) {
3892 * IPsec processing is required, but no SA found.
3893 * I assume that key_acquire() had been called
3894 * to get/establish the SA. Here I discard
3895 * this packet because it is responsibility for
3896 * upper layer to retransmit the packet.
3898 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3903 /* validity check */
3905 switch (ipsec_get_reqlevel(isr
)) {
3906 case IPSEC_LEVEL_USE
:
3908 case IPSEC_LEVEL_REQUIRE
:
3909 /* must be not reached here. */
3910 panic("ipsec6_output_tunnel: no SA found, but required.");
3915 * If there is no valid SA, we give up to process.
3916 * see same place at ipsec4_output().
3918 if (sav
->state
!= SADB_SASTATE_MATURE
3919 && sav
->state
!= SADB_SASTATE_DYING
) {
3920 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3925 int must_be_last
= 0;
3927 if ((error
= ipsec6_output_tunnel_internal(state
, sav
, &must_be_last
)) != 0) {
3931 if (must_be_last
&& isr
->next
) {
3932 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3933 "IPv4 must be outer layer, spi=%u\n",
3934 (u_int32_t
)ntohl(sav
->spi
)));
3941 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3946 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3954 ipsec6_interface_output(struct ipsec_output_state
*state
, ifnet_t interface
, u_char
*nexthdrp
, struct mbuf
*mprev
)
3957 struct secasvar
*sav
= NULL
;
3959 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3962 panic("state == NULL in ipsec6_output");
3964 panic("state->m == NULL in ipsec6_output");
3966 panic("nexthdrp == NULL in ipsec6_output");
3968 panic("mprev == NULL in ipsec6_output");
3970 sav
= key_alloc_outbound_sav_for_interface(interface
, AF_INET6
);
3975 if (sav
->sah
&& sav
->sah
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3976 if ((error
= ipsec6_output_tunnel_internal(state
, sav
, NULL
)) != 0) {
3981 if ((error
= ipsec6_output_trans_internal(state
, sav
, nexthdrp
, mprev
)) != 0) {
3987 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3992 key_freesav(sav
, KEY_SADB_UNLOCKED
);
4001 * Chop IP header and option off from the payload.
4011 if (m
->m_len
< sizeof(struct ip
))
4012 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
);
4013 ip
= mtod(m
, struct ip
*);
4015 hlen
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
4017 hlen
= ip
->ip_hl
<< 2;
4019 if (m
->m_len
> hlen
) {
4020 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4025 M_COPY_PKTHDR(mh
, m
);
4027 m
->m_flags
&= ~M_PKTHDR
;
4028 m_mchtype(m
, MT_DATA
);
4034 bcopy((caddr_t
)ip
, mtod(m
, caddr_t
), hlen
);
4035 } else if (m
->m_len
< hlen
) {
4036 m
= m_pullup(m
, hlen
);
4050 struct ip6_hdr
*ip6
;
4053 if (m
->m_len
< sizeof(struct ip6_hdr
))
4054 panic("ipsec6_splithdr: first mbuf too short");
4055 ip6
= mtod(m
, struct ip6_hdr
*);
4056 hlen
= sizeof(struct ip6_hdr
);
4057 if (m
->m_len
> hlen
) {
4058 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4063 M_COPY_PKTHDR(mh
, m
);
4065 m
->m_flags
&= ~M_PKTHDR
;
4066 m_mchtype(m
, MT_DATA
);
4072 bcopy((caddr_t
)ip6
, mtod(m
, caddr_t
), hlen
);
4073 } else if (m
->m_len
< hlen
) {
4074 m
= m_pullup(m
, hlen
);
4082 /* validate inbound IPsec tunnel packet. */
4084 ipsec4_tunnel_validate(m
, off
, nxt0
, sav
, ifamily
)
4085 struct mbuf
*m
; /* no pullup permitted, m->m_len >= ip */
4088 struct secasvar
*sav
;
4089 sa_family_t
*ifamily
;
4091 u_int8_t nxt
= nxt0
& 0xff;
4092 struct sockaddr_in
*sin
;
4093 struct sockaddr_in osrc
, odst
, i4src
, i4dst
;
4094 struct sockaddr_in6 i6src
, i6dst
;
4096 struct secpolicy
*sp
;
4099 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4102 if (m
->m_len
< sizeof(struct ip
))
4103 panic("too short mbuf on ipsec4_tunnel_validate");
4105 if (nxt
!= IPPROTO_IPV4
&& nxt
!= IPPROTO_IPV6
)
4107 if (m
->m_pkthdr
.len
< off
+ sizeof(struct ip
))
4109 /* do not decapsulate if the SA is for transport mode only */
4110 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
4113 oip
= mtod(m
, struct ip
*);
4115 hlen
= _IP_VHL_HL(oip
->ip_vhl
) << 2;
4117 hlen
= oip
->ip_hl
<< 2;
4119 if (hlen
!= sizeof(struct ip
))
4122 sin
= (struct sockaddr_in
*)&sav
->sah
->saidx
.dst
;
4123 if (sin
->sin_family
!= AF_INET
)
4125 if (bcmp(&oip
->ip_dst
, &sin
->sin_addr
, sizeof(oip
->ip_dst
)) != 0)
4128 if (sav
->utun_in_fn
||
4129 sav
->sah
->ipsec_if
!= NULL
) {
4130 // the ipsec/utun interface SAs don't have a policies.
4131 if (nxt
== IPPROTO_IPV4
) {
4133 } else if (nxt
== IPPROTO_IPV6
) {
4134 *ifamily
= AF_INET6
;
4142 bzero(&osrc
, sizeof(osrc
));
4143 bzero(&odst
, sizeof(odst
));
4144 osrc
.sin_family
= odst
.sin_family
= AF_INET
;
4145 osrc
.sin_len
= odst
.sin_len
= sizeof(struct sockaddr_in
);
4146 osrc
.sin_addr
= oip
->ip_src
;
4147 odst
.sin_addr
= oip
->ip_dst
;
4149 * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
4150 * - if the inner destination is multicast address, there can be
4151 * multiple permissible inner source address. implementation
4152 * may want to skip verification of inner source address against
4154 * - if the inner protocol is ICMP, the packet may be an error report
4155 * from routers on the other side of the VPN cloud (R in the
4156 * following diagram). in this case, we cannot verify inner source
4157 * address against SPD selector.
4158 * me -- gw === gw -- R -- you
4160 * we consider the first bullet to be users responsibility on SPD entry
4161 * configuration (if you need to encrypt multicast traffic, set
4162 * the source range of SPD selector to 0.0.0.0/0, or have explicit
4163 * address ranges for possible senders).
4164 * the second bullet is not taken care of (yet).
4166 * therefore, we do not do anything special about inner source.
4168 if (nxt
== IPPROTO_IPV4
) {
4169 bzero(&i4src
, sizeof(struct sockaddr_in
));
4170 bzero(&i4dst
, sizeof(struct sockaddr_in
));
4171 i4src
.sin_family
= i4dst
.sin_family
= *ifamily
= AF_INET
;
4172 i4src
.sin_len
= i4dst
.sin_len
= sizeof(struct sockaddr_in
);
4173 m_copydata(m
, off
+ offsetof(struct ip
, ip_src
), sizeof(i4src
.sin_addr
),
4174 (caddr_t
)&i4src
.sin_addr
);
4175 m_copydata(m
, off
+ offsetof(struct ip
, ip_dst
), sizeof(i4dst
.sin_addr
),
4176 (caddr_t
)&i4dst
.sin_addr
);
4177 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4178 (struct sockaddr
*)&i4src
, (struct sockaddr
*)&i4dst
);
4179 } else if (nxt
== IPPROTO_IPV6
) {
4180 bzero(&i6src
, sizeof(struct sockaddr_in6
));
4181 bzero(&i6dst
, sizeof(struct sockaddr_in6
));
4182 i6src
.sin6_family
= i6dst
.sin6_family
= *ifamily
= AF_INET6
;
4183 i6src
.sin6_len
= i6dst
.sin6_len
= sizeof(struct sockaddr_in6
);
4184 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_src
), sizeof(i6src
.sin6_addr
),
4185 (caddr_t
)&i6src
.sin6_addr
);
4186 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_dst
), sizeof(i6dst
.sin6_addr
),
4187 (caddr_t
)&i6dst
.sin6_addr
);
4188 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4189 (struct sockaddr
*)&i6src
, (struct sockaddr
*)&i6dst
);
4191 return 0; /* unsupported family */
4196 key_freesp(sp
, KEY_SADB_UNLOCKED
);
4202 /* validate inbound IPsec tunnel packet. */
4204 ipsec6_tunnel_validate(m
, off
, nxt0
, sav
)
4205 struct mbuf
*m
; /* no pullup permitted, m->m_len >= ip */
4208 struct secasvar
*sav
;
4210 u_int8_t nxt
= nxt0
& 0xff;
4211 struct sockaddr_in6
*sin6
;
4212 struct sockaddr_in6 osrc
, odst
, isrc
, idst
;
4213 struct secpolicy
*sp
;
4214 struct ip6_hdr
*oip6
;
4216 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4219 if (m
->m_len
< sizeof(struct ip6_hdr
))
4220 panic("too short mbuf on ipsec6_tunnel_validate");
4222 if (nxt
!= IPPROTO_IPV6
)
4224 if (m
->m_pkthdr
.len
< off
+ sizeof(struct ip6_hdr
))
4226 /* do not decapsulate if the SA is for transport mode only */
4227 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
4230 oip6
= mtod(m
, struct ip6_hdr
*);
4231 /* AF_INET should be supported, but at this moment we don't. */
4232 sin6
= (struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
;
4233 if (sin6
->sin6_family
!= AF_INET6
)
4235 if (!IN6_ARE_ADDR_EQUAL(&oip6
->ip6_dst
, &sin6
->sin6_addr
))
4238 if (sav
->utun_in_fn
) {
4239 // the utun SAs don't have a policy (yet).
4244 bzero(&osrc
, sizeof(osrc
));
4245 bzero(&odst
, sizeof(odst
));
4246 bzero(&isrc
, sizeof(isrc
));
4247 bzero(&idst
, sizeof(idst
));
4248 osrc
.sin6_family
= odst
.sin6_family
= isrc
.sin6_family
=
4249 idst
.sin6_family
= AF_INET6
;
4250 osrc
.sin6_len
= odst
.sin6_len
= isrc
.sin6_len
= idst
.sin6_len
=
4251 sizeof(struct sockaddr_in6
);
4252 osrc
.sin6_addr
= oip6
->ip6_src
;
4253 odst
.sin6_addr
= oip6
->ip6_dst
;
4254 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_src
),
4255 sizeof(isrc
.sin6_addr
), (caddr_t
)&isrc
.sin6_addr
);
4256 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_dst
),
4257 sizeof(idst
.sin6_addr
), (caddr_t
)&idst
.sin6_addr
);
4260 * regarding to inner source address validation, see a long comment
4261 * in ipsec4_tunnel_validate.
4264 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4265 (struct sockaddr
*)&isrc
, (struct sockaddr
*)&idst
);
4267 * when there is no suitable inbound policy for the packet of the ipsec
4268 * tunnel mode, the kernel never decapsulate the tunneled packet
4269 * as the ipsec tunnel mode even when the system wide policy is "none".
4270 * then the kernel leaves the generic tunnel module to process this
4271 * packet. if there is no rule of the generic tunnel, the packet
4272 * is rejected and the statistics will be counted up.
4276 key_freesp(sp
, KEY_SADB_UNLOCKED
);
4283 * Make a mbuf chain for encryption.
4284 * If the original mbuf chain contains a mbuf with a cluster,
4285 * allocate a new cluster and copy the data to the new cluster.
4286 * XXX: this hack is inefficient, but is necessary to handle cases
4287 * of TCP retransmission...
4293 struct mbuf
*n
, **mpp
, *mnew
;
4295 for (n
= m
, mpp
= &m
; n
; n
= n
->m_next
) {
4296 if (n
->m_flags
& M_EXT
) {
4298 * Make a copy only if there are more than one references
4300 * XXX: is this approach effective?
4303 n
->m_ext
.ext_free
||
4304 m_mclhasreference(n
)
4310 if (n
->m_flags
& M_PKTHDR
) {
4311 MGETHDR(mnew
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4314 M_COPY_PKTHDR(mnew
, n
);
4317 MGET(mnew
, M_DONTWAIT
, MT_DATA
);
4325 * Copy data. If we don't have enough space to
4326 * store the whole data, allocate a cluster
4327 * or additional mbufs.
4328 * XXX: we don't use m_copyback(), since the
4329 * function does not use clusters and thus is
4338 if (remain
<= (mm
->m_flags
& M_PKTHDR
? MHLEN
: MLEN
))
4340 else { /* allocate a cluster */
4341 MCLGET(mm
, M_DONTWAIT
);
4342 if (!(mm
->m_flags
& M_EXT
)) {
4346 len
= remain
< MCLBYTES
?
4350 bcopy(n
->m_data
+ copied
, mm
->m_data
,
4357 if (remain
<= 0) /* completed? */
4360 /* need another mbuf */
4361 MGETHDR(mn
, M_DONTWAIT
, MT_HEADER
); /* XXXMAC: tags copied next time in loop? */
4364 mn
->m_pkthdr
.rcvif
= NULL
;
4370 mm
->m_next
= m_free(n
);
4389 * Tags are allocated as mbufs for now, since our minimum size is MLEN, we
4390 * should make use of up to that much space.
4392 #define IPSEC_TAG_HEADER \
4395 struct socket
*socket
;
4396 u_int32_t history_count
;
4397 struct ipsec_history history
[];
4400 #define IPSEC_TAG_SIZE (MLEN - sizeof(struct m_tag))
4401 #define IPSEC_TAG_HDR_SIZE (offsetof(struct ipsec_tag, history[0]))
4402 #define IPSEC_HISTORY_MAX ((IPSEC_TAG_SIZE - IPSEC_TAG_HDR_SIZE) / \
4403 sizeof(struct ipsec_history))
4405 static struct ipsec_tag
*
4411 /* Check if the tag already exists */
4412 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4415 struct ipsec_tag
*itag
;
4417 /* Allocate a tag */
4418 tag
= m_tag_create(KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
,
4419 IPSEC_TAG_SIZE
, M_DONTWAIT
, m
);
4422 itag
= (struct ipsec_tag
*)(tag
+ 1);
4424 itag
->history_count
= 0;
4426 m_tag_prepend(m
, tag
);
4430 return tag
? (struct ipsec_tag
*)(tag
+ 1) : NULL
;
4433 static struct ipsec_tag
*
4439 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4441 return tag
? (struct ipsec_tag
*)(tag
+ 1) : NULL
;
4450 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4453 m_tag_delete(m
, tag
);
4457 /* if the aux buffer is unnecessary, nuke it. */
4461 struct ipsec_tag
*itag
)
4463 if (itag
&& itag
->socket
== NULL
&& itag
->history_count
== 0) {
4464 m_tag_delete(m
, ((struct m_tag
*)itag
) - 1);
4469 ipsec_setsocket(struct mbuf
*m
, struct socket
*so
)
4471 struct ipsec_tag
*tag
;
4473 /* if so == NULL, don't insist on getting the aux mbuf */
4475 tag
= ipsec_addaux(m
);
4479 tag
= ipsec_findaux(m
);
4482 ipsec_optaux(m
, tag
);
4488 ipsec_getsocket(struct mbuf
*m
)
4490 struct ipsec_tag
*itag
;
4492 itag
= ipsec_findaux(m
);
4494 return itag
->socket
;
4505 struct ipsec_tag
*itag
;
4506 struct ipsec_history
*p
;
4507 itag
= ipsec_addaux(m
);
4510 if (itag
->history_count
== IPSEC_HISTORY_MAX
)
4511 return ENOSPC
; /* XXX */
4513 p
= &itag
->history
[itag
->history_count
];
4514 itag
->history_count
++;
4516 bzero(p
, sizeof(*p
));
4517 p
->ih_proto
= proto
;
4523 struct ipsec_history
*
4528 struct ipsec_tag
*itag
;
4530 itag
= ipsec_findaux(m
);
4533 if (itag
->history_count
== 0)
4536 *lenp
= (int)(itag
->history_count
* sizeof(struct ipsec_history
));
4537 return itag
->history
;
4544 struct ipsec_tag
*itag
;
4546 itag
= ipsec_findaux(m
);
4548 itag
->history_count
= 0;
4550 ipsec_optaux(m
, itag
);
4553 __private_extern__
int
4554 ipsec_send_natt_keepalive(
4555 struct secasvar
*sav
)
4560 struct ip_out_args ipoa
=
4561 { IFSCOPE_NONE
, { 0 }, IPOAF_SELECT_SRCIF
, 0 };
4563 int keepalive_interval
= natt_keepalive_interval
;
4565 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4567 if ((esp_udp_encap_port
& 0xFFFF) == 0 || sav
->remote_ike_port
== 0) return FALSE
;
4569 if (sav
->natt_interval
!= 0) {
4570 keepalive_interval
= (int)sav
->natt_interval
;
4573 // natt timestamp may have changed... reverify
4574 if ((natt_now
- sav
->natt_last_activity
) < keepalive_interval
) return FALSE
;
4576 if (sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
) return FALSE
; // don't send these from the kernel
4578 m
= m_gethdr(M_NOWAIT
, MT_DATA
);
4579 if (m
== NULL
) return FALSE
;
4581 ip
= (__typeof__(ip
))m_mtod(m
);
4583 // this sends one type of NATT keepalives (Type 1, ESP keepalives, aren't sent by kernel)
4584 if ((sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
) == 0) {
4588 * Type 2: a UDP packet complete with IP header.
4589 * We must do this because UDP output requires
4590 * an inpcb which we don't have. UDP packet
4591 * contains one byte payload. The byte is set
4594 uh
= (__typeof__(uh
))(void *)((char *)m_mtod(m
) + sizeof(*ip
));
4595 m
->m_len
= sizeof(struct udpiphdr
) + 1;
4596 bzero(m_mtod(m
), m
->m_len
);
4597 m
->m_pkthdr
.len
= m
->m_len
;
4599 ip
->ip_len
= m
->m_len
;
4600 ip
->ip_ttl
= ip_defttl
;
4601 ip
->ip_p
= IPPROTO_UDP
;
4602 if (sav
->sah
->dir
!= IPSEC_DIR_INBOUND
) {
4603 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4604 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4606 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4607 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4609 uh
->uh_sport
= htons((u_short
)esp_udp_encap_port
);
4610 uh
->uh_dport
= htons(sav
->remote_ike_port
);
4611 uh
->uh_ulen
= htons(1 + sizeof(*uh
));
4613 *(u_int8_t
*)((char*)m_mtod(m
) + sizeof(*ip
) + sizeof(*uh
)) = 0xFF;
4616 // grab sadb_mutex, to get a local copy of sah's route cache
4617 lck_mtx_lock(sadb_mutex
);
4618 if (ROUTE_UNUSABLE(&sav
->sah
->sa_route
) ||
4619 rt_key(sav
->sah
->sa_route
.ro_rt
)->sa_family
!= AF_INET
)
4620 ROUTE_RELEASE(&sav
->sah
->sa_route
);
4622 route_copyout(&ro
, &sav
->sah
->sa_route
, sizeof(ro
));
4623 lck_mtx_unlock(sadb_mutex
);
4625 necp_mark_packet_as_keepalive(m
, TRUE
);
4627 error
= ip_output(m
, NULL
, &ro
, IP_OUTARGS
| IP_NOIPSEC
, NULL
, &ipoa
);
4629 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
4630 lck_mtx_lock(sadb_mutex
);
4631 route_copyin(&ro
, &sav
->sah
->sa_route
, sizeof(ro
));
4632 lck_mtx_unlock(sadb_mutex
);
4634 sav
->natt_last_activity
= natt_now
;
4640 __private_extern__
bool
4641 ipsec_fill_offload_frame(ifnet_t ifp
,
4642 struct secasvar
*sav
,
4643 struct ipsec_offload_frame
*frame
,
4644 size_t frame_data_offset
)
4646 u_int8_t
*data
= NULL
;
4647 struct ip
*ip
= NULL
;
4648 struct udphdr
*uh
= NULL
;
4650 if (sav
== NULL
|| sav
->sah
== NULL
|| frame
== NULL
||
4651 (ifp
!= NULL
&& ifp
->if_index
!= sav
->sah
->outgoing_if
) ||
4652 sav
->sah
->saidx
.dst
.ss_family
!= AF_INET
||
4653 !(sav
->flags
& SADB_X_EXT_NATT
) ||
4654 !(sav
->flags
& SADB_X_EXT_NATT_KEEPALIVE
) ||
4655 !(sav
->flags
& SADB_X_EXT_NATT_KEEPALIVE_OFFLOAD
) ||
4656 sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
||
4657 (esp_udp_encap_port
& 0xFFFF) == 0 ||
4658 sav
->remote_ike_port
== 0 ||
4659 (natt_keepalive_interval
== 0 && sav
->natt_interval
== 0)) {
4660 /* SA is not eligible for keepalive offload on this interface */
4664 if (frame_data_offset
+ sizeof(struct udpiphdr
) + 1 > IPSEC_OFFLOAD_FRAME_DATA_SIZE
) {
4665 /* Not enough room in this data frame */
4670 ip
= (__typeof__(ip
))(void *)(data
+ frame_data_offset
);
4671 uh
= (__typeof__(uh
))(void *)(data
+ frame_data_offset
+ sizeof(*ip
));
4673 frame
->length
= frame_data_offset
+ sizeof(struct udpiphdr
) + 1;
4674 bzero(data
, IPSEC_OFFLOAD_FRAME_DATA_SIZE
);
4676 ip
->ip_v
= IPVERSION
;
4677 ip
->ip_hl
= sizeof(struct ip
) >> 2;
4678 ip
->ip_off
&= htons(~IP_OFFMASK
);
4679 ip
->ip_off
&= htons(~IP_MF
);
4680 switch (ip4_ipsec_dfbit
) {
4681 case 0: /* clear DF bit */
4682 ip
->ip_off
&= htons(~IP_DF
);
4684 case 1: /* set DF bit */
4685 ip
->ip_off
|= htons(IP_DF
);
4687 default: /* copy DF bit */
4690 ip
->ip_len
= htons(sizeof(struct udpiphdr
) + 1);
4691 ip
->ip_id
= ip_randomid();
4692 ip
->ip_ttl
= ip_defttl
;
4693 ip
->ip_p
= IPPROTO_UDP
;
4695 if (sav
->sah
->dir
!= IPSEC_DIR_INBOUND
) {
4696 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4697 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4699 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4700 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4702 ip
->ip_sum
= in_cksum_hdr_opt(ip
);
4703 uh
->uh_sport
= htons((u_short
)esp_udp_encap_port
);
4704 uh
->uh_dport
= htons(sav
->remote_ike_port
);
4705 uh
->uh_ulen
= htons(1 + sizeof(*uh
));
4707 *(u_int8_t
*)(data
+ frame_data_offset
+ sizeof(*ip
) + sizeof(*uh
)) = 0xFF;
4709 if (sav
->natt_interval
!= 0) {
4710 frame
->interval
= sav
->natt_interval
;
4712 frame
->interval
= natt_keepalive_interval
;