2 * Copyright (c) 2008-2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $FreeBSD: src/sys/netinet6/ipsec.c,v 1.3.2.7 2001/07/19 06:37:23 kris Exp $ */
30 /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * IPsec controller part.
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/malloc.h>
69 #include <sys/mcache.h>
70 #include <sys/domain.h>
71 #include <sys/protosw.h>
72 #include <sys/socket.h>
73 #include <sys/socketvar.h>
74 #include <sys/errno.h>
76 #include <sys/kernel.h>
77 #include <sys/syslog.h>
78 #include <sys/sysctl.h>
79 #include <kern/locks.h>
80 #include <sys/kauth.h>
81 #include <libkern/OSAtomic.h>
84 #include <net/route.h>
86 #include <netinet/in.h>
87 #include <netinet/in_systm.h>
88 #include <netinet/ip.h>
89 #include <netinet/ip_var.h>
90 #include <netinet/in_var.h>
91 #include <netinet/udp.h>
92 #include <netinet/udp_var.h>
93 #include <netinet/ip_ecn.h>
95 #include <netinet6/ip6_ecn.h>
97 #include <netinet/tcp.h>
98 #include <netinet/udp.h>
100 #include <netinet/ip6.h>
102 #include <netinet6/ip6_var.h>
104 #include <netinet/in_pcb.h>
106 #include <netinet/icmp6.h>
109 #include <netinet6/ipsec.h>
111 #include <netinet6/ipsec6.h>
113 #include <netinet6/ah.h>
115 #include <netinet6/ah6.h>
118 #include <netinet6/esp.h>
120 #include <netinet6/esp6.h>
123 #include <netinet6/ipcomp.h>
125 #include <netinet6/ipcomp6.h>
127 #include <netkey/key.h>
128 #include <netkey/keydb.h>
129 #include <netkey/key_debug.h>
131 #include <net/net_osdep.h>
139 #include <sys/kdebug.h>
140 #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETIPSEC, 1)
141 #define DBG_LAYER_END NETDBG_CODE(DBG_NETIPSEC, 3)
142 #define DBG_FNC_GETPOL_SOCK NETDBG_CODE(DBG_NETIPSEC, (1 << 8))
143 #define DBG_FNC_GETPOL_ADDR NETDBG_CODE(DBG_NETIPSEC, (2 << 8))
144 #define DBG_FNC_IPSEC_OUT NETDBG_CODE(DBG_NETIPSEC, (3 << 8))
146 extern lck_mtx_t
*sadb_mutex
;
148 struct ipsecstat ipsecstat
;
149 int ip4_ah_cleartos
= 1;
150 int ip4_ah_offsetmask
= 0; /* maybe IP_DF? */
151 int ip4_ipsec_dfbit
= 0; /* DF bit on encap. 0: clear 1: set 2: copy */
152 int ip4_esp_trans_deflev
= IPSEC_LEVEL_USE
;
153 int ip4_esp_net_deflev
= IPSEC_LEVEL_USE
;
154 int ip4_ah_trans_deflev
= IPSEC_LEVEL_USE
;
155 int ip4_ah_net_deflev
= IPSEC_LEVEL_USE
;
156 struct secpolicy ip4_def_policy
;
157 int ip4_ipsec_ecn
= 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
158 int ip4_esp_randpad
= -1;
159 int esp_udp_encap_port
= 0;
160 static int sysctl_def_policy SYSCTL_HANDLER_ARGS
;
161 extern int natt_keepalive_interval
;
162 extern u_int32_t natt_now
;
166 SYSCTL_DECL(_net_inet_ipsec
);
168 SYSCTL_DECL(_net_inet6_ipsec6
);
171 SYSCTL_STRUCT(_net_inet_ipsec
, IPSECCTL_STATS
,
172 stats
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsecstat
, ipsecstat
, "");
173 SYSCTL_PROC(_net_inet_ipsec
, IPSECCTL_DEF_POLICY
, def_policy
, CTLTYPE_INT
|CTLFLAG_RW
| CTLFLAG_LOCKED
,
174 &ip4_def_policy
.policy
, 0, &sysctl_def_policy
, "I", "");
175 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
,
176 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_trans_deflev
, 0, "");
177 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
,
178 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_net_deflev
, 0, "");
179 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
,
180 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_trans_deflev
, 0, "");
181 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
,
182 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_net_deflev
, 0, "");
183 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_CLEARTOS
,
184 ah_cleartos
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_cleartos
, 0, "");
185 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_AH_OFFSETMASK
,
186 ah_offsetmask
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ah_offsetmask
, 0, "");
187 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DFBIT
,
188 dfbit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ipsec_dfbit
, 0, "");
189 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ECN
,
190 ecn
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_ipsec_ecn
, 0, "");
191 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_DEBUG
,
192 debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, "");
193 SYSCTL_INT(_net_inet_ipsec
, IPSECCTL_ESP_RANDPAD
,
194 esp_randpad
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip4_esp_randpad
, 0, "");
196 /* for performance, we bypass ipsec until a security policy is set */
197 int ipsec_bypass
= 1;
198 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, bypass
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsec_bypass
,0, "");
201 * NAT Traversal requires a UDP port for encapsulation,
202 * esp_udp_encap_port controls which port is used. Racoon
203 * must set this port to the port racoon is using locally
206 SYSCTL_INT(_net_inet_ipsec
, OID_AUTO
, esp_port
,
207 CTLFLAG_RW
| CTLFLAG_LOCKED
, &esp_udp_encap_port
, 0, "");
210 struct ipsecstat ipsec6stat
;
211 int ip6_esp_trans_deflev
= IPSEC_LEVEL_USE
;
212 int ip6_esp_net_deflev
= IPSEC_LEVEL_USE
;
213 int ip6_ah_trans_deflev
= IPSEC_LEVEL_USE
;
214 int ip6_ah_net_deflev
= IPSEC_LEVEL_USE
;
215 struct secpolicy ip6_def_policy
;
216 int ip6_ipsec_ecn
= 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
217 int ip6_esp_randpad
= -1;
219 /* net.inet6.ipsec6 */
220 SYSCTL_STRUCT(_net_inet6_ipsec6
, IPSECCTL_STATS
,
221 stats
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &ipsec6stat
, ipsecstat
, "");
222 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_POLICY
,
223 def_policy
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_def_policy
.policy
, 0, "");
224 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_TRANSLEV
, esp_trans_deflev
,
225 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_trans_deflev
, 0, "");
226 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_ESP_NETLEV
, esp_net_deflev
,
227 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_net_deflev
, 0, "");
228 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_TRANSLEV
, ah_trans_deflev
,
229 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ah_trans_deflev
, 0, "");
230 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEF_AH_NETLEV
, ah_net_deflev
,
231 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ah_net_deflev
, 0, "");
232 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ECN
,
233 ecn
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_ipsec_ecn
, 0, "");
234 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_DEBUG
,
235 debug
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipsec_debug
, 0, "");
236 SYSCTL_INT(_net_inet6_ipsec6
, IPSECCTL_ESP_RANDPAD
,
237 esp_randpad
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &ip6_esp_randpad
, 0, "");
240 static int ipsec_setspidx_interface(struct secpolicyindex
*, u_int
, struct mbuf
*,
242 static int ipsec_setspidx_mbuf(struct secpolicyindex
*, u_int
, u_int
,
244 static int ipsec4_setspidx_inpcb(struct mbuf
*, struct inpcb
*pcb
);
246 static int ipsec6_setspidx_in6pcb(struct mbuf
*, struct in6pcb
*pcb
);
248 static int ipsec_setspidx(struct mbuf
*, struct secpolicyindex
*, int, int);
249 static void ipsec4_get_ulp(struct mbuf
*m
, struct secpolicyindex
*, int);
250 static int ipsec4_setspidx_ipaddr(struct mbuf
*, struct secpolicyindex
*);
252 static void ipsec6_get_ulp(struct mbuf
*m
, struct secpolicyindex
*, int);
253 static int ipsec6_setspidx_ipaddr(struct mbuf
*, struct secpolicyindex
*);
255 static struct inpcbpolicy
*ipsec_newpcbpolicy(void);
256 static void ipsec_delpcbpolicy(struct inpcbpolicy
*);
257 static struct secpolicy
*ipsec_deepcopy_policy(struct secpolicy
*src
);
258 static int ipsec_set_policy(struct secpolicy
**pcb_sp
,
259 int optname
, caddr_t request
, size_t len
, int priv
);
260 static int ipsec_get_policy(struct secpolicy
*pcb_sp
, struct mbuf
**mp
);
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
);
272 sysctl_def_policy SYSCTL_HANDLER_ARGS
274 int old_policy
= ip4_def_policy
.policy
;
275 int error
= sysctl_handle_int(oidp
, oidp
->oid_arg1
, oidp
->oid_arg2
, req
);
277 #pragma unused(arg1, arg2)
279 if (ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
&&
280 ip4_def_policy
.policy
!= IPSEC_POLICY_DISCARD
) {
281 ip4_def_policy
.policy
= old_policy
;
285 /* Turn off the bypass if the default security policy changes */
286 if (ipsec_bypass
!= 0 && ip4_def_policy
.policy
!= IPSEC_POLICY_NONE
)
293 * For OUTBOUND packet having a socket. Searching SPD for packet,
294 * and return a pointer to SP.
295 * OUT: NULL: no apropreate SP found, the following value is set to error.
297 * EACCES : discard packet.
298 * ENOENT : ipsec_acquire() in progress, maybe.
299 * others : error occurred.
300 * others: a pointer to SP
302 * NOTE: IPv6 mapped adddress concern is implemented here.
305 ipsec4_getpolicybysock(m
, dir
, so
, error
)
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(m
, dir
, so
, error
)
650 struct inpcbpolicy
*pcbsp
= NULL
;
651 struct secpolicy
*currsp
= NULL
; /* policy on socket */
652 struct secpolicy
*kernsp
= NULL
; /* policy on kernel */
654 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
657 if (m
== NULL
|| so
== NULL
|| error
== NULL
)
658 panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
661 if (SOCK_DOM(so
) != PF_INET6
)
662 panic("ipsec6_getpolicybysock: socket domain != inet6\n");
665 pcbsp
= sotoin6pcb(so
)->in6p_sp
;
668 return ipsec6_getpolicybyaddr(m
, dir
, 0, error
);
671 /* set spidx in pcb */
672 ipsec6_setspidx_in6pcb(m
, sotoin6pcb(so
));
676 panic("ipsec6_getpolicybysock: pcbsp is NULL.\n");
679 case IPSEC_DIR_INBOUND
:
680 currsp
= pcbsp
->sp_in
;
682 case IPSEC_DIR_OUTBOUND
:
683 currsp
= pcbsp
->sp_out
;
686 panic("ipsec6_getpolicybysock: illegal direction.\n");
691 panic("ipsec6_getpolicybysock: currsp is NULL.\n");
693 /* when privilieged socket */
695 switch (currsp
->policy
) {
696 case IPSEC_POLICY_BYPASS
:
697 lck_mtx_lock(sadb_mutex
);
699 lck_mtx_unlock(sadb_mutex
);
703 case IPSEC_POLICY_ENTRUST
:
704 /* look for a policy in SPD */
705 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
708 if (kernsp
!= NULL
) {
709 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
710 printf("DP ipsec6_getpolicybysock called "
711 "to allocate SP:0x%llx\n",
712 (uint64_t)VM_KERNEL_ADDRPERM(kernsp
)));
718 lck_mtx_lock(sadb_mutex
);
719 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
720 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
722 "fixed system default policy: %d->%d\n",
723 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
724 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
726 ip6_def_policy
.refcnt
++;
727 lck_mtx_unlock(sadb_mutex
);
729 return &ip6_def_policy
;
731 case IPSEC_POLICY_IPSEC
:
732 lck_mtx_lock(sadb_mutex
);
734 lck_mtx_unlock(sadb_mutex
);
739 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: "
740 "Invalid policy for PCB %d\n", currsp
->policy
));
747 /* when non-privilieged socket */
748 /* look for a policy in SPD */
749 kernsp
= key_allocsp(&currsp
->spidx
, dir
);
752 if (kernsp
!= NULL
) {
753 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
754 printf("DP ipsec6_getpolicybysock called "
755 "to allocate SP:0x%llx\n",
756 (uint64_t)VM_KERNEL_ADDRPERM(kernsp
)));
762 switch (currsp
->policy
) {
763 case IPSEC_POLICY_BYPASS
:
764 ipseclog((LOG_ERR
, "ipsec6_getpolicybysock: "
765 "Illegal policy for non-priviliged defined %d\n",
770 case IPSEC_POLICY_ENTRUST
:
771 lck_mtx_lock(sadb_mutex
);
772 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
773 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
775 "fixed system default policy: %d->%d\n",
776 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
777 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
779 ip6_def_policy
.refcnt
++;
780 lck_mtx_unlock(sadb_mutex
);
782 return &ip6_def_policy
;
784 case IPSEC_POLICY_IPSEC
:
785 lck_mtx_lock(sadb_mutex
);
787 lck_mtx_unlock(sadb_mutex
);
793 "ipsec6_policybysock: Invalid policy for PCB %d\n",
802 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
803 * and return a pointer to SP.
804 * `flag' means that packet is to be forwarded whether or not.
806 * OUT: positive: a pointer to the entry for security policy leaf matched.
807 * NULL: no apropreate SP found, the following value is set to error.
809 * EACCES : discard packet.
810 * ENOENT : ipsec_acquire() in progress, maybe.
811 * others : error occurred.
813 #ifndef IP_FORWARDING
814 #define IP_FORWARDING 1
818 ipsec6_getpolicybyaddr(struct mbuf
*m
,
823 struct secpolicy
*sp
= NULL
;
825 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
828 if (m
== NULL
|| error
== NULL
)
829 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.\n");
832 struct secpolicyindex spidx
;
834 bzero(&spidx
, sizeof(spidx
));
836 /* make a index to look for a policy */
837 *error
= ipsec_setspidx_mbuf(&spidx
, dir
, AF_INET6
, m
,
838 (flag
& IP_FORWARDING
) ? 0 : 1);
843 sp
= key_allocsp(&spidx
, dir
);
848 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
849 printf("DP ipsec6_getpolicybyaddr called "
850 "to allocate SP:0x%llx\n",
851 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
857 lck_mtx_lock(sadb_mutex
);
858 if (ip6_def_policy
.policy
!= IPSEC_POLICY_DISCARD
859 && ip6_def_policy
.policy
!= IPSEC_POLICY_NONE
) {
860 ipseclog((LOG_INFO
, "fixed system default policy: %d->%d\n",
861 ip6_def_policy
.policy
, IPSEC_POLICY_NONE
));
862 ip6_def_policy
.policy
= IPSEC_POLICY_NONE
;
864 ip6_def_policy
.refcnt
++;
865 lck_mtx_unlock(sadb_mutex
);
867 return &ip6_def_policy
;
870 /* Match with bound interface rather than src addr.
871 * Unlike getpolicybyaddr, do not set the default policy.
872 * Return 0 if should continue processing, or -1 if packet
876 ipsec6_getpolicybyinterface(struct mbuf
*m
,
879 struct ip6_out_args
*ip6oap
,
881 struct secpolicy
**sp
)
883 struct secpolicyindex spidx
;
886 if (ipsec_bypass
!= 0)
890 if (m
== NULL
|| sp
== NULL
|| noipsec
== NULL
|| ip6oap
== NULL
)
891 panic("ipsec6_getpolicybyinterface: NULL pointer was passed.\n");
895 if (ip6oap
->ip6oa_boundif
== IFSCOPE_NONE
)
898 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_START
, 0,0,0,0,0);
899 bzero(&spidx
, sizeof(spidx
));
901 /* make a index to look for a policy */
902 error
= ipsec_setspidx_interface(&spidx
, dir
, m
, (flag
& IP_FORWARDING
) ? 0 : 1,
903 ip6oap
->ip6oa_boundif
, 6);
906 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 1,error
,0,0,0);
910 *sp
= key_allocsp(&spidx
, dir
);
912 /* Return SP, whether NULL or not */
913 if (*sp
!= NULL
&& (*sp
)->policy
== IPSEC_POLICY_IPSEC
) {
914 if ((*sp
)->ipsec_if
== NULL
) {
915 /* Invalid to capture on an interface without redirect */
916 key_freesp(*sp
, KEY_SADB_UNLOCKED
);
919 } else if ((*sp
)->disabled
) {
920 /* Disabled policies go in the clear */
921 key_freesp(*sp
, KEY_SADB_UNLOCKED
);
923 *noipsec
= 1; /* Avoid later IPSec check */
925 /* If policy is enabled, redirect to ipsec interface */
926 ip6oap
->ip6oa_boundif
= (*sp
)->ipsec_if
->if_index
;
930 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR
| DBG_FUNC_END
, 2,*error
,0,0,0);
937 * set IP address into spidx from mbuf.
938 * When Forwarding packet and ICMP echo reply, this function is used.
940 * IN: get the followings from mbuf.
941 * protocol family, src, dst, next protocol
944 * other: failure, and set errno.
948 struct secpolicyindex
*spidx
,
950 __unused u_int family
,
957 if (spidx
== NULL
|| m
== NULL
)
958 panic("ipsec_setspidx_mbuf: NULL pointer was passed.\n");
960 bzero(spidx
, sizeof(*spidx
));
962 error
= ipsec_setspidx(m
, spidx
, needport
, 0);
971 bzero(spidx
, sizeof(*spidx
));
976 ipsec_setspidx_interface(
977 struct secpolicyindex
*spidx
,
987 if (spidx
== NULL
|| m
== NULL
)
988 panic("ipsec_setspidx_interface: NULL pointer was passed.\n");
990 bzero(spidx
, sizeof(*spidx
));
992 error
= ipsec_setspidx(m
, spidx
, needport
, ip_version
);
998 ifnet_head_lock_shared();
999 spidx
->internal_if
= ifindex2ifnet
[ifindex
];
1002 spidx
->internal_if
= NULL
;
1012 ipsec4_setspidx_inpcb(m
, pcb
)
1016 struct secpolicyindex
*spidx
;
1019 if (ipsec_bypass
!= 0)
1024 panic("ipsec4_setspidx_inpcb: no PCB found.\n");
1025 if (pcb
->inp_sp
== NULL
)
1026 panic("ipsec4_setspidx_inpcb: no inp_sp found.\n");
1027 if (pcb
->inp_sp
->sp_out
== NULL
|| pcb
->inp_sp
->sp_in
== NULL
)
1028 panic("ipsec4_setspidx_inpcb: no sp_in/out found.\n");
1030 bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
));
1031 bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
));
1033 spidx
= &pcb
->inp_sp
->sp_in
->spidx
;
1034 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1037 spidx
->dir
= IPSEC_DIR_INBOUND
;
1039 spidx
= &pcb
->inp_sp
->sp_out
->spidx
;
1040 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1043 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
1048 bzero(&pcb
->inp_sp
->sp_in
->spidx
, sizeof(*spidx
));
1049 bzero(&pcb
->inp_sp
->sp_out
->spidx
, sizeof(*spidx
));
1055 ipsec6_setspidx_in6pcb(m
, pcb
)
1059 struct secpolicyindex
*spidx
;
1064 panic("ipsec6_setspidx_in6pcb: no PCB found.\n");
1065 if (pcb
->in6p_sp
== NULL
)
1066 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.\n");
1067 if (pcb
->in6p_sp
->sp_out
== NULL
|| pcb
->in6p_sp
->sp_in
== NULL
)
1068 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.\n");
1070 bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
));
1071 bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
));
1073 spidx
= &pcb
->in6p_sp
->sp_in
->spidx
;
1074 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1077 spidx
->dir
= IPSEC_DIR_INBOUND
;
1079 spidx
= &pcb
->in6p_sp
->sp_out
->spidx
;
1080 error
= ipsec_setspidx(m
, spidx
, 1, 0);
1083 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
1088 bzero(&pcb
->in6p_sp
->sp_in
->spidx
, sizeof(*spidx
));
1089 bzero(&pcb
->in6p_sp
->sp_out
->spidx
, sizeof(*spidx
));
1095 * configure security policy index (src/dst/proto/sport/dport)
1096 * by looking at the content of mbuf.
1097 * the caller is responsible for error recovery (like clearing up spidx).
1100 ipsec_setspidx(struct mbuf
*m
,
1101 struct secpolicyindex
*spidx
,
1103 int force_ip_version
)
1105 struct ip
*ip
= NULL
;
1113 panic("ipsec_setspidx: m == 0 passed.\n");
1116 * validate m->m_pkthdr.len. we see incorrect length if we
1117 * mistakenly call this function with inconsistent mbuf chain
1118 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
1121 for (n
= m
; n
; n
= n
->m_next
)
1123 if (m
->m_pkthdr
.len
!= len
) {
1124 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1125 printf("ipsec_setspidx: "
1126 "total of m_len(%d) != pkthdr.len(%d), "
1128 len
, m
->m_pkthdr
.len
));
1132 if (m
->m_pkthdr
.len
< sizeof(struct ip
)) {
1133 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1134 printf("ipsec_setspidx: "
1135 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
1140 if (m
->m_len
>= sizeof(*ip
))
1141 ip
= mtod(m
, struct ip
*);
1143 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
);
1147 if (force_ip_version
) {
1148 v
= force_ip_version
;
1151 v
= _IP_VHL_V(ip
->ip_vhl
);
1158 error
= ipsec4_setspidx_ipaddr(m
, spidx
);
1161 ipsec4_get_ulp(m
, spidx
, needport
);
1165 if (m
->m_pkthdr
.len
< sizeof(struct ip6_hdr
)) {
1166 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1167 printf("ipsec_setspidx: "
1168 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
1169 "ignored.\n", m
->m_pkthdr
.len
));
1172 error
= ipsec6_setspidx_ipaddr(m
, spidx
);
1175 ipsec6_get_ulp(m
, spidx
, needport
);
1179 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1180 printf("ipsec_setspidx: "
1181 "unknown IP version %u, ignored.\n", v
));
1187 ipsec4_get_ulp(m
, spidx
, needport
)
1189 struct secpolicyindex
*spidx
;
1193 struct ip6_ext ip6e
;
1201 panic("ipsec4_get_ulp: NULL pointer was passed.\n");
1202 if (m
->m_pkthdr
.len
< sizeof(ip
))
1203 panic("ipsec4_get_ulp: too short\n");
1206 spidx
->ul_proto
= IPSEC_ULPROTO_ANY
;
1207 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
= IPSEC_PORT_ANY
;
1208 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
= IPSEC_PORT_ANY
;
1210 m_copydata(m
, 0, sizeof(ip
), (caddr_t
)&ip
);
1211 /* ip_input() flips it into host endian XXX need more checking */
1212 if (ip
.ip_off
& (IP_MF
| IP_OFFMASK
))
1217 off
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
1219 off
= ip
.ip_hl
<< 2;
1221 while (off
< m
->m_pkthdr
.len
) {
1224 spidx
->ul_proto
= nxt
;
1227 if (off
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
)
1229 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
);
1230 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
=
1232 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
=
1236 spidx
->ul_proto
= nxt
;
1239 if (off
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
)
1241 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
);
1242 ((struct sockaddr_in
*)&spidx
->src
)->sin_port
=
1244 ((struct sockaddr_in
*)&spidx
->dst
)->sin_port
=
1248 if (off
+ sizeof(ip6e
) > m
->m_pkthdr
.len
)
1250 m_copydata(m
, off
, sizeof(ip6e
), (caddr_t
)&ip6e
);
1251 off
+= (ip6e
.ip6e_len
+ 2) << 2;
1252 nxt
= ip6e
.ip6e_nxt
;
1256 /* XXX intermediate headers??? */
1257 spidx
->ul_proto
= nxt
;
1263 /* assumes that m is sane */
1265 ipsec4_setspidx_ipaddr(m
, spidx
)
1267 struct secpolicyindex
*spidx
;
1269 struct ip
*ip
= NULL
;
1271 struct sockaddr_in
*sin
;
1273 if (m
->m_len
>= sizeof(*ip
))
1274 ip
= mtod(m
, struct ip
*);
1276 m_copydata(m
, 0, sizeof(ipbuf
), (caddr_t
)&ipbuf
);
1280 sin
= (struct sockaddr_in
*)&spidx
->src
;
1281 bzero(sin
, sizeof(*sin
));
1282 sin
->sin_family
= AF_INET
;
1283 sin
->sin_len
= sizeof(struct sockaddr_in
);
1284 bcopy(&ip
->ip_src
, &sin
->sin_addr
, sizeof(ip
->ip_src
));
1285 spidx
->prefs
= sizeof(struct in_addr
) << 3;
1287 sin
= (struct sockaddr_in
*)&spidx
->dst
;
1288 bzero(sin
, sizeof(*sin
));
1289 sin
->sin_family
= AF_INET
;
1290 sin
->sin_len
= sizeof(struct sockaddr_in
);
1291 bcopy(&ip
->ip_dst
, &sin
->sin_addr
, sizeof(ip
->ip_dst
));
1292 spidx
->prefd
= sizeof(struct in_addr
) << 3;
1299 ipsec6_get_ulp(m
, spidx
, needport
)
1301 struct secpolicyindex
*spidx
;
1310 panic("ipsec6_get_ulp: NULL pointer was passed.\n");
1312 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1313 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m
));
1316 spidx
->ul_proto
= IPSEC_ULPROTO_ANY
;
1317 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= IPSEC_PORT_ANY
;
1318 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= IPSEC_PORT_ANY
;
1321 off
= ip6_lasthdr(m
, 0, IPPROTO_IPV6
, &nxt
);
1322 if (off
< 0 || m
->m_pkthdr
.len
< off
)
1327 spidx
->ul_proto
= nxt
;
1330 if (off
+ sizeof(struct tcphdr
) > m
->m_pkthdr
.len
)
1332 m_copydata(m
, off
, sizeof(th
), (caddr_t
)&th
);
1333 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= th
.th_sport
;
1334 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= th
.th_dport
;
1337 spidx
->ul_proto
= nxt
;
1340 if (off
+ sizeof(struct udphdr
) > m
->m_pkthdr
.len
)
1342 m_copydata(m
, off
, sizeof(uh
), (caddr_t
)&uh
);
1343 ((struct sockaddr_in6
*)&spidx
->src
)->sin6_port
= uh
.uh_sport
;
1344 ((struct sockaddr_in6
*)&spidx
->dst
)->sin6_port
= uh
.uh_dport
;
1346 case IPPROTO_ICMPV6
:
1348 /* XXX intermediate headers??? */
1349 spidx
->ul_proto
= nxt
;
1354 /* assumes that m is sane */
1356 ipsec6_setspidx_ipaddr(m
, spidx
)
1358 struct secpolicyindex
*spidx
;
1360 struct ip6_hdr
*ip6
= NULL
;
1361 struct ip6_hdr ip6buf
;
1362 struct sockaddr_in6
*sin6
;
1364 if (m
->m_len
>= sizeof(*ip6
))
1365 ip6
= mtod(m
, struct ip6_hdr
*);
1367 m_copydata(m
, 0, sizeof(ip6buf
), (caddr_t
)&ip6buf
);
1371 sin6
= (struct sockaddr_in6
*)&spidx
->src
;
1372 bzero(sin6
, sizeof(*sin6
));
1373 sin6
->sin6_family
= AF_INET6
;
1374 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
1375 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_src
));
1376 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
1377 sin6
->sin6_addr
.s6_addr16
[1] = 0;
1378 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
1380 spidx
->prefs
= sizeof(struct in6_addr
) << 3;
1382 sin6
= (struct sockaddr_in6
*)&spidx
->dst
;
1383 bzero(sin6
, sizeof(*sin6
));
1384 sin6
->sin6_family
= AF_INET6
;
1385 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
1386 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
, sizeof(ip6
->ip6_dst
));
1387 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
1388 sin6
->sin6_addr
.s6_addr16
[1] = 0;
1389 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
1391 spidx
->prefd
= sizeof(struct in6_addr
) << 3;
1397 static struct inpcbpolicy
*
1398 ipsec_newpcbpolicy()
1400 struct inpcbpolicy
*p
;
1402 p
= (struct inpcbpolicy
*)_MALLOC(sizeof(*p
), M_SECA
, M_WAITOK
);
1407 ipsec_delpcbpolicy(p
)
1408 struct inpcbpolicy
*p
;
1413 /* initialize policy in PCB */
1415 ipsec_init_policy(so
, pcb_sp
)
1417 struct inpcbpolicy
**pcb_sp
;
1419 struct inpcbpolicy
*new;
1422 if (so
== NULL
|| pcb_sp
== NULL
)
1423 panic("ipsec_init_policy: NULL pointer was passed.\n");
1425 new = ipsec_newpcbpolicy();
1427 ipseclog((LOG_DEBUG
, "ipsec_init_policy: No more memory.\n"));
1430 bzero(new, sizeof(*new));
1433 if (kauth_cred_issuser(so
->so_cred
))
1435 if (so
->so_cred
!= 0 && !suser(so
->so_cred
->pc_ucred
, NULL
))
1441 if ((new->sp_in
= key_newsp()) == NULL
) {
1442 ipsec_delpcbpolicy(new);
1445 new->sp_in
->state
= IPSEC_SPSTATE_ALIVE
;
1446 new->sp_in
->policy
= IPSEC_POLICY_ENTRUST
;
1448 if ((new->sp_out
= key_newsp()) == NULL
) {
1449 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
);
1450 ipsec_delpcbpolicy(new);
1453 new->sp_out
->state
= IPSEC_SPSTATE_ALIVE
;
1454 new->sp_out
->policy
= IPSEC_POLICY_ENTRUST
;
1461 /* copy old ipsec policy into new */
1463 ipsec_copy_policy(old
, new)
1464 struct inpcbpolicy
*old
, *new;
1466 struct secpolicy
*sp
;
1468 if (ipsec_bypass
!= 0)
1471 sp
= ipsec_deepcopy_policy(old
->sp_in
);
1473 key_freesp(new->sp_in
, KEY_SADB_UNLOCKED
);
1478 sp
= ipsec_deepcopy_policy(old
->sp_out
);
1480 key_freesp(new->sp_out
, KEY_SADB_UNLOCKED
);
1485 new->priv
= old
->priv
;
1490 /* deep-copy a policy in PCB */
1491 static struct secpolicy
*
1492 ipsec_deepcopy_policy(src
)
1493 struct secpolicy
*src
;
1495 struct ipsecrequest
*newchain
= NULL
;
1496 struct ipsecrequest
*p
;
1497 struct ipsecrequest
**q
;
1498 struct ipsecrequest
*r
;
1499 struct secpolicy
*dst
;
1508 * deep-copy IPsec request chain. This is required since struct
1509 * ipsecrequest is not reference counted.
1512 for (p
= src
->req
; p
; p
= p
->next
) {
1513 *q
= (struct ipsecrequest
*)_MALLOC(sizeof(struct ipsecrequest
),
1517 bzero(*q
, sizeof(**q
));
1520 (*q
)->saidx
.proto
= p
->saidx
.proto
;
1521 (*q
)->saidx
.mode
= p
->saidx
.mode
;
1522 (*q
)->level
= p
->level
;
1523 (*q
)->saidx
.reqid
= p
->saidx
.reqid
;
1525 bcopy(&p
->saidx
.src
, &(*q
)->saidx
.src
, sizeof((*q
)->saidx
.src
));
1526 bcopy(&p
->saidx
.dst
, &(*q
)->saidx
.dst
, sizeof((*q
)->saidx
.dst
));
1533 dst
->req
= newchain
;
1534 dst
->state
= src
->state
;
1535 dst
->policy
= src
->policy
;
1536 /* do not touch the refcnt fields */
1541 for (p
= newchain
; p
; p
= r
) {
1546 key_freesp(dst
, KEY_SADB_UNLOCKED
);
1550 /* set policy and ipsec request if present. */
1553 struct secpolicy
**pcb_sp
,
1554 __unused
int optname
,
1559 struct sadb_x_policy
*xpl
;
1560 struct secpolicy
*newsp
= NULL
;
1564 if (pcb_sp
== NULL
|| *pcb_sp
== NULL
|| request
== NULL
)
1566 if (len
< sizeof(*xpl
))
1568 xpl
= (struct sadb_x_policy
*)(void *)request
;
1570 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1571 printf("ipsec_set_policy: passed policy\n");
1572 kdebug_sadb_x_policy((struct sadb_ext
*)xpl
));
1574 /* check policy type */
1575 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1576 if (xpl
->sadb_x_policy_type
== IPSEC_POLICY_DISCARD
1577 || xpl
->sadb_x_policy_type
== IPSEC_POLICY_NONE
)
1580 /* check privileged socket */
1581 if (priv
== 0 && xpl
->sadb_x_policy_type
== IPSEC_POLICY_BYPASS
)
1584 /* allocation new SP entry */
1585 if ((newsp
= key_msg2sp(xpl
, len
, &error
)) == NULL
)
1588 newsp
->state
= IPSEC_SPSTATE_ALIVE
;
1590 /* clear old SP and set new SP */
1591 key_freesp(*pcb_sp
, KEY_SADB_UNLOCKED
);
1593 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1594 printf("ipsec_set_policy: new policy\n");
1595 kdebug_secpolicy(newsp
));
1601 ipsec_get_policy(pcb_sp
, mp
)
1602 struct secpolicy
*pcb_sp
;
1608 if (pcb_sp
== NULL
|| mp
== NULL
)
1611 *mp
= key_sp2msg(pcb_sp
);
1613 ipseclog((LOG_DEBUG
, "ipsec_get_policy: No more memory.\n"));
1617 m_mchtype(*mp
, MT_DATA
);
1618 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
1619 printf("ipsec_get_policy:\n");
1626 ipsec4_set_policy(inp
, optname
, request
, len
, priv
)
1633 struct sadb_x_policy
*xpl
;
1634 struct secpolicy
**pcb_sp
;
1636 struct sadb_x_policy xpl_aligned_buf
;
1637 u_int8_t
*xpl_unaligned
;
1640 if (inp
== NULL
|| request
== NULL
)
1642 if (len
< sizeof(*xpl
))
1644 xpl
= (struct sadb_x_policy
*)(void *)request
;
1646 /* This is a new mbuf allocated by soopt_getm() */
1647 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1648 xpl_unaligned
= NULL
;
1650 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1651 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1652 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1655 if (inp
->inp_sp
== NULL
) {
1656 error
= ipsec_init_policy(inp
->inp_socket
, &inp
->inp_sp
);
1661 /* select direction */
1662 switch (xpl
->sadb_x_policy_dir
) {
1663 case IPSEC_DIR_INBOUND
:
1664 pcb_sp
= &inp
->inp_sp
->sp_in
;
1666 case IPSEC_DIR_OUTBOUND
:
1667 pcb_sp
= &inp
->inp_sp
->sp_out
;
1670 ipseclog((LOG_ERR
, "ipsec4_set_policy: invalid direction=%u\n",
1671 xpl
->sadb_x_policy_dir
));
1675 /* turn bypass off */
1676 if (ipsec_bypass
!= 0)
1679 return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
);
1683 ipsec4_get_policy(inp
, request
, len
, mp
)
1689 struct sadb_x_policy
*xpl
;
1690 struct secpolicy
*pcb_sp
;
1692 struct sadb_x_policy xpl_aligned_buf
;
1693 u_int8_t
*xpl_unaligned
;
1695 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1698 if (inp
== NULL
|| request
== NULL
|| mp
== NULL
)
1700 if (len
< sizeof(*xpl
))
1702 xpl
= (struct sadb_x_policy
*)(void *)request
;
1704 /* This is a new mbuf allocated by soopt_getm() */
1705 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1706 xpl_unaligned
= NULL
;
1708 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1709 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1710 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1713 if (inp
->inp_sp
== NULL
) {
1714 error
= ipsec_init_policy(inp
->inp_socket
, &inp
->inp_sp
);
1719 /* select direction */
1720 switch (xpl
->sadb_x_policy_dir
) {
1721 case IPSEC_DIR_INBOUND
:
1722 pcb_sp
= inp
->inp_sp
->sp_in
;
1724 case IPSEC_DIR_OUTBOUND
:
1725 pcb_sp
= inp
->inp_sp
->sp_out
;
1728 ipseclog((LOG_ERR
, "ipsec4_set_policy: invalid direction=%u\n",
1729 xpl
->sadb_x_policy_dir
));
1733 return ipsec_get_policy(pcb_sp
, mp
);
1736 /* delete policy in PCB */
1738 ipsec4_delete_pcbpolicy(inp
)
1744 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n");
1746 if (inp
->inp_sp
== NULL
)
1749 if (inp
->inp_sp
->sp_in
!= NULL
) {
1750 key_freesp(inp
->inp_sp
->sp_in
, KEY_SADB_UNLOCKED
);
1751 inp
->inp_sp
->sp_in
= NULL
;
1754 if (inp
->inp_sp
->sp_out
!= NULL
) {
1755 key_freesp(inp
->inp_sp
->sp_out
, KEY_SADB_UNLOCKED
);
1756 inp
->inp_sp
->sp_out
= NULL
;
1759 ipsec_delpcbpolicy(inp
->inp_sp
);
1767 ipsec6_set_policy(in6p
, optname
, request
, len
, priv
)
1768 struct in6pcb
*in6p
;
1774 struct sadb_x_policy
*xpl
;
1775 struct secpolicy
**pcb_sp
;
1777 struct sadb_x_policy xpl_aligned_buf
;
1778 u_int8_t
*xpl_unaligned
;
1781 if (in6p
== NULL
|| request
== NULL
)
1783 if (len
< sizeof(*xpl
))
1785 xpl
= (struct sadb_x_policy
*)(void *)request
;
1787 /* This is a new mbuf allocated by soopt_getm() */
1788 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1789 xpl_unaligned
= NULL
;
1791 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1792 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1793 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1796 if (in6p
->in6p_sp
== NULL
) {
1797 error
= ipsec_init_policy(in6p
->inp_socket
, &in6p
->in6p_sp
);
1802 /* select direction */
1803 switch (xpl
->sadb_x_policy_dir
) {
1804 case IPSEC_DIR_INBOUND
:
1805 pcb_sp
= &in6p
->in6p_sp
->sp_in
;
1807 case IPSEC_DIR_OUTBOUND
:
1808 pcb_sp
= &in6p
->in6p_sp
->sp_out
;
1811 ipseclog((LOG_ERR
, "ipsec6_set_policy: invalid direction=%u\n",
1812 xpl
->sadb_x_policy_dir
));
1816 /* turn bypass off */
1817 if (ipsec_bypass
!= 0)
1820 return ipsec_set_policy(pcb_sp
, optname
, request
, len
, priv
);
1824 ipsec6_get_policy(in6p
, request
, len
, mp
)
1825 struct in6pcb
*in6p
;
1830 struct sadb_x_policy
*xpl
;
1831 struct secpolicy
*pcb_sp
;
1833 struct sadb_x_policy xpl_aligned_buf
;
1834 u_int8_t
*xpl_unaligned
;
1837 if (in6p
== NULL
|| request
== NULL
|| mp
== NULL
)
1839 if (len
< sizeof(*xpl
))
1841 xpl
= (struct sadb_x_policy
*)(void *)request
;
1843 /* This is a new mbuf allocated by soopt_getm() */
1844 if (IPSEC_IS_P2ALIGNED(xpl
)) {
1845 xpl_unaligned
= NULL
;
1847 xpl_unaligned
= (__typeof__(xpl_unaligned
))xpl
;
1848 memcpy(&xpl_aligned_buf
, xpl
, sizeof(xpl_aligned_buf
));
1849 xpl
= (__typeof__(xpl
))&xpl_aligned_buf
;
1852 if (in6p
->in6p_sp
== NULL
) {
1853 error
= ipsec_init_policy(in6p
->inp_socket
, &in6p
->in6p_sp
);
1858 /* select direction */
1859 switch (xpl
->sadb_x_policy_dir
) {
1860 case IPSEC_DIR_INBOUND
:
1861 pcb_sp
= in6p
->in6p_sp
->sp_in
;
1863 case IPSEC_DIR_OUTBOUND
:
1864 pcb_sp
= in6p
->in6p_sp
->sp_out
;
1867 ipseclog((LOG_ERR
, "ipsec6_set_policy: invalid direction=%u\n",
1868 xpl
->sadb_x_policy_dir
));
1872 return ipsec_get_policy(pcb_sp
, mp
);
1876 ipsec6_delete_pcbpolicy(in6p
)
1877 struct in6pcb
*in6p
;
1882 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n");
1884 if (in6p
->in6p_sp
== NULL
)
1887 if (in6p
->in6p_sp
->sp_in
!= NULL
) {
1888 key_freesp(in6p
->in6p_sp
->sp_in
, KEY_SADB_UNLOCKED
);
1889 in6p
->in6p_sp
->sp_in
= NULL
;
1892 if (in6p
->in6p_sp
->sp_out
!= NULL
) {
1893 key_freesp(in6p
->in6p_sp
->sp_out
, KEY_SADB_UNLOCKED
);
1894 in6p
->in6p_sp
->sp_out
= NULL
;
1897 ipsec_delpcbpolicy(in6p
->in6p_sp
);
1898 in6p
->in6p_sp
= NULL
;
1905 * return current level.
1906 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1909 ipsec_get_reqlevel(isr
)
1910 struct ipsecrequest
*isr
;
1913 u_int esp_trans_deflev
= 0, esp_net_deflev
= 0, ah_trans_deflev
= 0, ah_net_deflev
= 0;
1916 if (isr
== NULL
|| isr
->sp
== NULL
)
1917 panic("ipsec_get_reqlevel: NULL pointer is passed.\n");
1918 if (((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
1919 != ((struct sockaddr
*)&isr
->sp
->spidx
.dst
)->sa_family
)
1920 panic("ipsec_get_reqlevel: family mismatched.\n");
1922 /* XXX note that we have ipseclog() expanded here - code sync issue */
1923 #define IPSEC_CHECK_DEFAULT(lev) \
1924 (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1925 && (lev) != IPSEC_LEVEL_UNIQUE) \
1927 ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1928 (lev), IPSEC_LEVEL_REQUIRE) \
1930 (lev) = IPSEC_LEVEL_REQUIRE, \
1934 /* set default level */
1935 switch (((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
) {
1938 esp_trans_deflev
= IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev
);
1939 esp_net_deflev
= IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev
);
1940 ah_trans_deflev
= IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev
);
1941 ah_net_deflev
= IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev
);
1946 esp_trans_deflev
= IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev
);
1947 esp_net_deflev
= IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev
);
1948 ah_trans_deflev
= IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev
);
1949 ah_net_deflev
= IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev
);
1953 panic("key_get_reqlevel: Unknown family. %d\n",
1954 ((struct sockaddr
*)&isr
->sp
->spidx
.src
)->sa_family
);
1957 #undef IPSEC_CHECK_DEFAULT
1960 switch (isr
->level
) {
1961 case IPSEC_LEVEL_DEFAULT
:
1962 switch (isr
->saidx
.proto
) {
1964 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
1965 level
= esp_net_deflev
;
1967 level
= esp_trans_deflev
;
1970 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
1971 level
= ah_net_deflev
;
1973 level
= ah_trans_deflev
;
1975 case IPPROTO_IPCOMP
:
1977 * we don't really care, as IPcomp document says that
1978 * we shouldn't compress small packets
1980 level
= IPSEC_LEVEL_USE
;
1983 panic("ipsec_get_reqlevel: "
1984 "Illegal protocol defined %u\n",
1989 case IPSEC_LEVEL_USE
:
1990 case IPSEC_LEVEL_REQUIRE
:
1993 case IPSEC_LEVEL_UNIQUE
:
1994 level
= IPSEC_LEVEL_REQUIRE
;
1998 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
2006 * Check AH/ESP integrity.
2012 ipsec_in_reject(sp
, m
)
2013 struct secpolicy
*sp
;
2016 struct ipsecrequest
*isr
;
2018 int need_auth
, need_conf
, need_icv
;
2020 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2021 printf("ipsec_in_reject: using SP\n");
2022 kdebug_secpolicy(sp
));
2025 switch (sp
->policy
) {
2026 case IPSEC_POLICY_DISCARD
:
2027 case IPSEC_POLICY_GENERATE
:
2029 case IPSEC_POLICY_BYPASS
:
2030 case IPSEC_POLICY_NONE
:
2033 case IPSEC_POLICY_IPSEC
:
2036 case IPSEC_POLICY_ENTRUST
:
2038 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
);
2045 /* XXX should compare policy against ipsec header history */
2047 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
2049 /* get current level */
2050 level
= ipsec_get_reqlevel(isr
);
2052 switch (isr
->saidx
.proto
) {
2054 if (level
== IPSEC_LEVEL_REQUIRE
) {
2058 /* this won't work with multiple input threads - isr->sav would change
2059 * with every packet and is not necessarily related to the current packet
2060 * being processed. If ESP processing is required - the esp code should
2061 * make sure that the integrity check is present and correct. I don't see
2062 * why it would be necessary to check for the presence of the integrity
2063 * check value here. I think this is just wrong.
2064 * isr->sav has been removed.
2065 * %%%%%% this needs to be re-worked at some point but I think the code below can
2066 * be ignored for now.
2068 if (isr
->sav
!= NULL
2069 && isr
->sav
->flags
== SADB_X_EXT_NONE
2070 && isr
->sav
->alg_auth
!= SADB_AALG_NONE
)
2076 if (level
== IPSEC_LEVEL_REQUIRE
) {
2081 case IPPROTO_IPCOMP
:
2083 * we don't really care, as IPcomp document says that
2084 * we shouldn't compress small packets, IPComp policy
2085 * should always be treated as being in "use" level.
2091 KEYDEBUG(KEYDEBUG_IPSEC_DUMP
,
2092 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
2093 need_auth
, need_conf
, need_icv
, m
->m_flags
));
2095 if ((need_conf
&& !(m
->m_flags
& M_DECRYPTED
))
2096 || (!need_auth
&& need_icv
&& !(m
->m_flags
& M_AUTHIPDGM
))
2097 || (need_auth
&& !(m
->m_flags
& M_AUTHIPHDR
)))
2104 * Check AH/ESP integrity.
2105 * This function is called from tcp_input(), udp_input(),
2106 * and {ah,esp}4_input for tunnel mode
2109 ipsec4_in_reject_so(m
, so
)
2113 struct secpolicy
*sp
= NULL
;
2117 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2120 return 0; /* XXX should be panic ? */
2122 /* get SP for this packet.
2123 * When we are called from ip_forward(), we call
2124 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2127 sp
= ipsec4_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
);
2129 sp
= ipsec4_getpolicybysock(m
, IPSEC_DIR_INBOUND
, so
, &error
);
2132 return 0; /* XXX should be panic ?
2133 * -> No, there may be error. */
2135 result
= ipsec_in_reject(sp
, m
);
2136 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2137 printf("DP ipsec4_in_reject_so call free SP:0x%llx\n",
2138 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2139 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2145 ipsec4_in_reject(m
, inp
)
2150 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2152 return ipsec4_in_reject_so(m
, NULL
);
2153 if (inp
->inp_socket
)
2154 return ipsec4_in_reject_so(m
, inp
->inp_socket
);
2156 panic("ipsec4_in_reject: invalid inpcb/socket");
2164 * Check AH/ESP integrity.
2165 * This function is called from tcp6_input(), udp6_input(),
2166 * and {ah,esp}6_input for tunnel mode
2169 ipsec6_in_reject_so(m
, so
)
2173 struct secpolicy
*sp
= NULL
;
2177 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2180 return 0; /* XXX should be panic ? */
2182 /* get SP for this packet.
2183 * When we are called from ip_forward(), we call
2184 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
2187 sp
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_INBOUND
, IP_FORWARDING
, &error
);
2189 sp
= ipsec6_getpolicybysock(m
, IPSEC_DIR_INBOUND
, so
, &error
);
2192 return 0; /* XXX should be panic ? */
2194 result
= ipsec_in_reject(sp
, m
);
2195 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2196 printf("DP ipsec6_in_reject_so call free SP:0x%llx\n",
2197 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2198 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2204 ipsec6_in_reject(m
, in6p
)
2206 struct in6pcb
*in6p
;
2209 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2211 return ipsec6_in_reject_so(m
, NULL
);
2212 if (in6p
->in6p_socket
)
2213 return ipsec6_in_reject_so(m
, in6p
->in6p_socket
);
2215 panic("ipsec6_in_reject: invalid in6p/socket");
2223 * compute the byte size to be occupied by IPsec header.
2224 * in case it is tunneled, it includes the size of outer IP header.
2225 * NOTE: SP passed is free in this function.
2229 struct secpolicy
*sp
;
2231 struct ipsecrequest
*isr
;
2234 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2235 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2236 printf("ipsec_hdrsiz: using SP\n");
2237 kdebug_secpolicy(sp
));
2240 switch (sp
->policy
) {
2241 case IPSEC_POLICY_DISCARD
:
2242 case IPSEC_POLICY_GENERATE
:
2243 case IPSEC_POLICY_BYPASS
:
2244 case IPSEC_POLICY_NONE
:
2247 case IPSEC_POLICY_IPSEC
:
2250 case IPSEC_POLICY_ENTRUST
:
2252 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp
->policy
);
2257 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
2261 switch (isr
->saidx
.proto
) {
2264 clen
= esp_hdrsiz(isr
);
2270 clen
= ah_hdrsiz(isr
);
2272 case IPPROTO_IPCOMP
:
2273 clen
= sizeof(struct ipcomp
);
2277 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
2278 switch (((struct sockaddr
*)&isr
->saidx
.dst
)->sa_family
) {
2280 clen
+= sizeof(struct ip
);
2284 clen
+= sizeof(struct ip6_hdr
);
2288 ipseclog((LOG_ERR
, "ipsec_hdrsiz: "
2289 "unknown AF %d in IPsec tunnel SA\n",
2290 ((struct sockaddr
*)&isr
->saidx
.dst
)->sa_family
));
2300 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
2302 ipsec4_hdrsiz(m
, dir
, inp
)
2307 struct secpolicy
*sp
= NULL
;
2311 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2314 return 0; /* XXX should be panic ? */
2315 if (inp
!= NULL
&& inp
->inp_socket
== NULL
)
2316 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
2318 /* get SP for this packet.
2319 * When we are called from ip_forward(), we call
2320 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2323 sp
= ipsec4_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
);
2325 sp
= ipsec4_getpolicybysock(m
, dir
, inp
->inp_socket
, &error
);
2328 return 0; /* XXX should be panic ? */
2330 size
= ipsec_hdrsiz(sp
);
2331 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2332 printf("DP ipsec4_hdrsiz call free SP:0x%llx\n",
2333 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2334 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2335 printf("ipsec4_hdrsiz: size:%lu.\n", (u_int32_t
)size
));
2336 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2342 /* This function is called from ipsec6_hdrsize_tcp(),
2343 * and maybe from ip6_forward.()
2346 ipsec6_hdrsiz(m
, dir
, in6p
)
2349 struct in6pcb
*in6p
;
2351 struct secpolicy
*sp
= NULL
;
2355 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
2358 return 0; /* XXX shoud be panic ? */
2359 if (in6p
!= NULL
&& in6p
->in6p_socket
== NULL
)
2360 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2362 /* get SP for this packet */
2363 /* XXX Is it right to call with IP_FORWARDING. */
2365 sp
= ipsec6_getpolicybyaddr(m
, dir
, IP_FORWARDING
, &error
);
2367 sp
= ipsec6_getpolicybysock(m
, dir
, in6p
->in6p_socket
, &error
);
2371 size
= ipsec_hdrsiz(sp
);
2372 KEYDEBUG(KEYDEBUG_IPSEC_STAMP
,
2373 printf("DP ipsec6_hdrsiz call free SP:0x%llx\n",
2374 (uint64_t)VM_KERNEL_ADDRPERM(sp
)));
2375 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
2376 printf("ipsec6_hdrsiz: size:%lu.\n", (u_int32_t
)size
));
2377 key_freesp(sp
, KEY_SADB_UNLOCKED
);
2385 * encapsulate for ipsec tunnel.
2386 * ip->ip_src must be fixed later on.
2389 ipsec4_encapsulate(m
, sav
)
2391 struct secasvar
*sav
;
2398 /* can't tunnel between different AFs */
2399 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2400 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2401 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2406 /* XXX if the dst is myself, perform nothing. */
2407 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2413 if (m
->m_len
< sizeof(*ip
))
2414 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2416 ip
= mtod(m
, struct ip
*);
2418 hlen
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
2420 hlen
= ip
->ip_hl
<< 2;
2423 if (m
->m_len
!= hlen
)
2424 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2426 /* generate header checksum */
2429 ip
->ip_sum
= in_cksum(m
, hlen
);
2431 ip
->ip_sum
= in_cksum(m
, hlen
);
2434 plen
= m
->m_pkthdr
.len
;
2437 * grow the mbuf to accomodate the new IPv4 header.
2438 * NOTE: IPv4 options will never be copied.
2440 if (M_LEADINGSPACE(m
->m_next
) < hlen
) {
2442 MGET(n
, M_DONTWAIT
, MT_DATA
);
2448 n
->m_next
= m
->m_next
;
2450 m
->m_pkthdr
.len
+= hlen
;
2451 oip
= mtod(n
, struct ip
*);
2453 m
->m_next
->m_len
+= hlen
;
2454 m
->m_next
->m_data
-= hlen
;
2455 m
->m_pkthdr
.len
+= hlen
;
2456 oip
= mtod(m
->m_next
, struct ip
*);
2458 ip
= mtod(m
, struct ip
*);
2459 ovbcopy((caddr_t
)ip
, (caddr_t
)oip
, hlen
);
2460 m
->m_len
= sizeof(struct ip
);
2461 m
->m_pkthdr
.len
-= (hlen
- sizeof(struct ip
));
2463 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2464 /* ECN consideration. */
2465 ip_ecn_ingress(ip4_ipsec_ecn
, &ip
->ip_tos
, &oip
->ip_tos
);
2467 ip
->ip_vhl
= IP_MAKE_VHL(IPVERSION
, sizeof(struct ip
) >> 2);
2469 ip
->ip_hl
= sizeof(struct ip
) >> 2;
2471 ip
->ip_off
&= htons(~IP_OFFMASK
);
2472 ip
->ip_off
&= htons(~IP_MF
);
2473 switch (ip4_ipsec_dfbit
) {
2474 case 0: /* clear DF bit */
2475 ip
->ip_off
&= htons(~IP_DF
);
2477 case 1: /* set DF bit */
2478 ip
->ip_off
|= htons(IP_DF
);
2480 default: /* copy DF bit */
2483 ip
->ip_p
= IPPROTO_IPIP
;
2484 if (plen
+ sizeof(struct ip
) < IP_MAXPACKET
)
2485 ip
->ip_len
= htons(plen
+ sizeof(struct ip
));
2487 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2488 "leave ip_len as is (invalid packet)\n"));
2490 ip
->ip_id
= ip_randomid();
2491 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2492 &ip
->ip_src
, sizeof(ip
->ip_src
));
2493 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2494 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2495 ip
->ip_ttl
= IPDEFTTL
;
2497 /* XXX Should ip_src be updated later ? */
2503 * encapsulate for ipsec tunnel.
2504 * ip->ip_src must be fixed later on.
2507 ipsec4_encapsulate_utun_esp_keepalive(m_ptr
, sav
)
2508 struct mbuf
**m_ptr
;
2509 struct secasvar
*sav
;
2513 struct mbuf
*m
= *m_ptr
;
2515 /* can't tunnel between different AFs */
2516 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2517 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2518 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2524 plen
= m
->m_pkthdr
.len
;
2527 * grow the mbuf to accomodate the new IPv4 header.
2528 * NOTE: IPv4 options will never be copied.
2532 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
2538 if (m
->m_flags
& M_PKTHDR
) {
2539 M_COPY_PKTHDR(n
, m
);
2540 m
->m_flags
&= ~M_PKTHDR
;
2542 MH_ALIGN(n
, sizeof(*ip
));
2543 n
->m_len
= sizeof(*ip
);
2545 n
->m_pkthdr
.len
= (plen
+ n
->m_len
);
2549 plen
= m
->m_pkthdr
.len
;
2551 ip
= mtod(m
, __typeof__(ip
));
2553 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2554 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2556 ip
->ip_vhl
= IP_MAKE_VHL(IPVERSION
, sizeof(*ip
) >> 2);
2558 ip
->ip_hl
= sizeof(*ip
) >> 2;
2560 ip
->ip_off
&= htons(~IP_OFFMASK
);
2561 ip
->ip_off
&= htons(~IP_MF
);
2562 switch (ip4_ipsec_dfbit
) {
2563 case 0: /* clear DF bit */
2564 ip
->ip_off
&= htons(~IP_DF
);
2566 case 1: /* set DF bit */
2567 ip
->ip_off
|= htons(IP_DF
);
2569 default: /* copy DF bit */
2572 ip
->ip_p
= IPPROTO_IPIP
;
2573 if (plen
< IP_MAXPACKET
)
2574 ip
->ip_len
= htons(plen
);
2576 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2577 "leave ip_len as is (invalid packet)\n"));
2579 ip
->ip_id
= ip_randomid();
2580 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2581 &ip
->ip_src
, sizeof(ip
->ip_src
));
2582 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2583 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2584 ip
->ip_ttl
= IPDEFTTL
;
2586 /* XXX Should ip_src be updated later ? */
2594 ipsec6_encapsulate(m
, sav
)
2596 struct secasvar
*sav
;
2598 struct ip6_hdr
*oip6
;
2599 struct ip6_hdr
*ip6
;
2602 /* can't tunnel between different AFs */
2603 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2604 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2605 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET6
) {
2610 /* XXX if the dst is myself, perform nothing. */
2611 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2617 plen
= m
->m_pkthdr
.len
;
2620 * grow the mbuf to accomodate the new IPv6 header.
2622 if (m
->m_len
!= sizeof(struct ip6_hdr
))
2623 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2624 if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) {
2626 MGET(n
, M_DONTWAIT
, MT_DATA
);
2631 n
->m_len
= sizeof(struct ip6_hdr
);
2632 n
->m_next
= m
->m_next
;
2634 m
->m_pkthdr
.len
+= sizeof(struct ip6_hdr
);
2635 oip6
= mtod(n
, struct ip6_hdr
*);
2637 m
->m_next
->m_len
+= sizeof(struct ip6_hdr
);
2638 m
->m_next
->m_data
-= sizeof(struct ip6_hdr
);
2639 m
->m_pkthdr
.len
+= sizeof(struct ip6_hdr
);
2640 oip6
= mtod(m
->m_next
, struct ip6_hdr
*);
2642 ip6
= mtod(m
, struct ip6_hdr
*);
2643 ovbcopy((caddr_t
)ip6
, (caddr_t
)oip6
, sizeof(struct ip6_hdr
));
2645 /* Fake link-local scope-class addresses */
2646 if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_src
))
2647 oip6
->ip6_src
.s6_addr16
[1] = 0;
2648 if (IN6_IS_SCOPE_LINKLOCAL(&oip6
->ip6_dst
))
2649 oip6
->ip6_dst
.s6_addr16
[1] = 0;
2651 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2652 /* ECN consideration. */
2653 ip6_ecn_ingress(ip6_ipsec_ecn
, &ip6
->ip6_flow
, &oip6
->ip6_flow
);
2654 if (plen
< IPV6_MAXPACKET
- sizeof(struct ip6_hdr
))
2655 ip6
->ip6_plen
= htons(plen
);
2657 /* ip6->ip6_plen will be updated in ip6_output() */
2659 ip6
->ip6_nxt
= IPPROTO_IPV6
;
2660 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.src
)->sin6_addr
,
2661 &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
2662 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
)->sin6_addr
,
2663 &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
2664 ip6
->ip6_hlim
= IPV6_DEFHLIM
;
2666 /* XXX Should ip6_src be updated later ? */
2672 ipsec64_encapsulate(m
, sav
)
2674 struct secasvar
*sav
;
2676 struct ip6_hdr
*ip6
, *ip6i
;
2681 /* tunneling over IPv4 */
2682 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2683 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2684 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
2689 /* XXX if the dst is myself, perform nothing. */
2690 if (key_ismyaddr((struct sockaddr
*)&sav
->sah
->saidx
.dst
)) {
2696 plen
= m
->m_pkthdr
.len
;
2697 ip6
= mtod(m
, struct ip6_hdr
*);
2698 hlim
= ip6
->ip6_hlim
;
2700 * grow the mbuf to accomodate the new IPv4 header.
2702 if (m
->m_len
!= sizeof(struct ip6_hdr
))
2703 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2704 if (M_LEADINGSPACE(m
->m_next
) < sizeof(struct ip6_hdr
)) {
2706 MGET(n
, M_DONTWAIT
, MT_DATA
);
2711 n
->m_len
= sizeof(struct ip6_hdr
);
2712 n
->m_next
= m
->m_next
;
2714 m
->m_pkthdr
.len
+= sizeof(struct ip
);
2715 ip6i
= mtod(n
, struct ip6_hdr
*);
2717 m
->m_next
->m_len
+= sizeof(struct ip6_hdr
);
2718 m
->m_next
->m_data
-= sizeof(struct ip6_hdr
);
2719 m
->m_pkthdr
.len
+= sizeof(struct ip
);
2720 ip6i
= mtod(m
->m_next
, struct ip6_hdr
*);
2722 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2723 /* ECN consideration. */
2724 /* XXX To be fixed later if needed */
2725 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2727 bcopy(ip6
, ip6i
, sizeof(struct ip6_hdr
));
2728 ip
= mtod(m
, struct ip
*);
2729 m
->m_len
= sizeof(struct ip
);
2731 * Fill in some of the IPv4 fields - we don't need all of them
2732 * because the rest will be filled in by ip_output
2734 ip
->ip_v
= IPVERSION
;
2735 ip
->ip_hl
= sizeof(struct ip
) >> 2;
2741 ip
->ip_p
= IPPROTO_IPV6
;
2742 if (plen
+ sizeof(struct ip
) < IP_MAXPACKET
)
2743 ip
->ip_len
= htons(plen
+ sizeof(struct ip
));
2745 ip
->ip_len
= htons(plen
);
2746 ipseclog((LOG_ERR
, "IPv4 ipsec: size exceeds limit: "
2747 "leave ip_len as is (invalid packet)\n"));
2749 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
,
2750 &ip
->ip_src
, sizeof(ip
->ip_src
));
2751 bcopy(&((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
,
2752 &ip
->ip_dst
, sizeof(ip
->ip_dst
));
2758 ipsec6_encapsulate_utun_esp_keepalive(m_ptr
, sav
)
2759 struct mbuf
**m_ptr
;
2760 struct secasvar
*sav
;
2762 struct ip6_hdr
*ip6
;
2764 struct mbuf
*m
= *m_ptr
;
2766 /* can't tunnel between different AFs */
2767 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
2768 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
2769 || ((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET6
) {
2775 plen
= m
->m_pkthdr
.len
;
2778 * grow the mbuf to accomodate the new IPv6 header.
2782 MGETHDR(n
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
2788 if (m
->m_flags
& M_PKTHDR
) {
2789 M_COPY_PKTHDR(n
, m
);
2790 m
->m_flags
&= ~M_PKTHDR
;
2792 MH_ALIGN(n
, sizeof(*ip6
));
2793 n
->m_len
= sizeof(*ip6
);
2795 n
->m_pkthdr
.len
= (plen
+ n
->m_len
);
2799 plen
= m
->m_pkthdr
.len
;
2801 ip6
= mtod(m
, __typeof__(ip6
));
2803 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2804 if (plen
< IPV6_MAXPACKET
)
2805 ip6
->ip6_plen
= htons(plen
);
2807 /* ip6->ip6_plen will be updated in ip6_output() */
2809 ip6
->ip6_nxt
= IPPROTO_IPV6
;
2810 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.src
)->sin6_addr
,
2811 &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
2812 bcopy(&((struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
)->sin6_addr
,
2813 &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
2814 ip6
->ip6_hlim
= IPV6_DEFHLIM
;
2816 /* XXX Should ip6_src be updated later ? */
2823 * Check the variable replay window.
2824 * ipsec_chkreplay() performs replay check before ICV verification.
2825 * ipsec_updatereplay() updates replay bitmap. This must be called after
2826 * ICV verification (it also performs replay check, which is usually done
2828 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2830 * based on RFC 2401.
2833 ipsec_chkreplay(seq
, sav
)
2835 struct secasvar
*sav
;
2837 const struct secreplay
*replay
;
2840 u_int32_t wsizeb
; /* constant: bits of window size */
2841 int frlast
; /* constant: last frame */
2846 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2848 lck_mtx_lock(sadb_mutex
);
2849 replay
= sav
->replay
;
2851 if (replay
->wsize
== 0) {
2852 lck_mtx_unlock(sadb_mutex
);
2853 return 1; /* no need to check replay. */
2857 frlast
= replay
->wsize
- 1;
2858 wsizeb
= replay
->wsize
<< 3;
2860 /* sequence number of 0 is invalid */
2862 lck_mtx_unlock(sadb_mutex
);
2866 /* first time is always okay */
2867 if (replay
->count
== 0) {
2868 lck_mtx_unlock(sadb_mutex
);
2872 if (seq
> replay
->lastseq
) {
2873 /* larger sequences are okay */
2874 lck_mtx_unlock(sadb_mutex
);
2877 /* seq is equal or less than lastseq. */
2878 diff
= replay
->lastseq
- seq
;
2880 /* over range to check, i.e. too old or wrapped */
2881 if (diff
>= wsizeb
) {
2882 lck_mtx_unlock(sadb_mutex
);
2886 fr
= frlast
- diff
/ 8;
2888 /* this packet already seen ? */
2889 if ((replay
->bitmap
)[fr
] & (1 << (diff
% 8))) {
2890 lck_mtx_unlock(sadb_mutex
);
2894 /* out of order but good */
2895 lck_mtx_unlock(sadb_mutex
);
2901 * check replay counter whether to update or not.
2906 ipsec_updatereplay(seq
, sav
)
2908 struct secasvar
*sav
;
2910 struct secreplay
*replay
;
2913 u_int32_t wsizeb
; /* constant: bits of window size */
2914 int frlast
; /* constant: last frame */
2918 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2920 lck_mtx_lock(sadb_mutex
);
2921 replay
= sav
->replay
;
2923 if (replay
->wsize
== 0)
2924 goto ok
; /* no need to check replay. */
2927 frlast
= replay
->wsize
- 1;
2928 wsizeb
= replay
->wsize
<< 3;
2930 /* sequence number of 0 is invalid */
2935 if (replay
->count
== 0) {
2936 replay
->lastseq
= seq
;
2937 bzero(replay
->bitmap
, replay
->wsize
);
2938 (replay
->bitmap
)[frlast
] = 1;
2942 if (seq
> replay
->lastseq
) {
2943 /* seq is larger than lastseq. */
2944 diff
= seq
- replay
->lastseq
;
2946 /* new larger sequence number */
2947 if (diff
< wsizeb
) {
2949 /* set bit for this packet */
2950 vshiftl((unsigned char *) replay
->bitmap
, diff
, replay
->wsize
);
2951 (replay
->bitmap
)[frlast
] |= 1;
2953 /* this packet has a "way larger" */
2954 bzero(replay
->bitmap
, replay
->wsize
);
2955 (replay
->bitmap
)[frlast
] = 1;
2957 replay
->lastseq
= seq
;
2959 /* larger is good */
2961 /* seq is equal or less than lastseq. */
2962 diff
= replay
->lastseq
- seq
;
2964 /* over range to check, i.e. too old or wrapped */
2965 if (diff
>= wsizeb
) {
2966 lck_mtx_unlock(sadb_mutex
);
2970 fr
= frlast
- diff
/ 8;
2972 /* this packet already seen ? */
2973 if ((replay
->bitmap
)[fr
] & (1 << (diff
% 8))) {
2974 lck_mtx_unlock(sadb_mutex
);
2979 (replay
->bitmap
)[fr
] |= (1 << (diff
% 8));
2981 /* out of order but good */
2985 if (replay
->count
== ~0) {
2987 /* set overflow flag */
2990 /* don't increment, no more packets accepted */
2991 if ((sav
->flags
& SADB_X_EXT_CYCSEQ
) == 0) {
2992 lck_mtx_unlock(sadb_mutex
);
2996 ipseclog((LOG_WARNING
, "replay counter made %d cycle. %s\n",
2997 replay
->overflow
, ipsec_logsastr(sav
)));
3002 lck_mtx_unlock(sadb_mutex
);
3007 * shift variable length buffer to left.
3008 * IN: bitmap: pointer to the buffer
3009 * nbit: the number of to shift.
3010 * wsize: buffer size (bytes).
3013 vshiftl(bitmap
, nbit
, wsize
)
3014 unsigned char *bitmap
;
3020 for (j
= 0; j
< nbit
; j
+= 8) {
3021 s
= (nbit
- j
< 8) ? (nbit
- j
): 8;
3023 for (i
= 1; i
< wsize
; i
++) {
3024 over
= (bitmap
[i
] >> (8 - s
));
3026 bitmap
[i
-1] |= over
;
3034 ipsec4_logpacketstr(ip
, spi
)
3038 static char buf
[256] __attribute__((aligned(4)));
3042 s
= (u_int8_t
*)(&ip
->ip_src
);
3043 d
= (u_int8_t
*)(&ip
->ip_dst
);
3046 snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
));
3049 snprintf(p
, sizeof(buf
) - (p
- buf
), "src=%u.%u.%u.%u",
3050 s
[0], s
[1], s
[2], s
[3]);
3053 snprintf(p
, sizeof(buf
) - (p
- buf
), " dst=%u.%u.%u.%u",
3054 d
[0], d
[1], d
[2], d
[3]);
3057 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
3064 ipsec6_logpacketstr(ip6
, spi
)
3065 struct ip6_hdr
*ip6
;
3068 static char buf
[256] __attribute__((aligned(4)));
3072 snprintf(buf
, sizeof(buf
), "packet(SPI=%u ", (u_int32_t
)ntohl(spi
));
3075 snprintf(p
, sizeof(buf
) - (p
- buf
), "src=%s",
3076 ip6_sprintf(&ip6
->ip6_src
));
3079 snprintf(p
, sizeof(buf
) - (p
- buf
), " dst=%s",
3080 ip6_sprintf(&ip6
->ip6_dst
));
3083 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
3091 struct secasvar
*sav
;
3093 static char buf
[256] __attribute__((aligned(4)));
3095 struct secasindex
*saidx
= &sav
->sah
->saidx
;
3097 /* validity check */
3098 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
3099 != ((struct sockaddr
*)&sav
->sah
->saidx
.dst
)->sa_family
)
3100 panic("ipsec_logsastr: family mismatched.\n");
3103 snprintf(buf
, sizeof(buf
), "SA(SPI=%u ", (u_int32_t
)ntohl(sav
->spi
));
3106 if (((struct sockaddr
*)&saidx
->src
)->sa_family
== AF_INET
) {
3108 s
= (u_int8_t
*)&((struct sockaddr_in
*)&saidx
->src
)->sin_addr
;
3109 d
= (u_int8_t
*)&((struct sockaddr_in
*)&saidx
->dst
)->sin_addr
;
3110 snprintf(p
, sizeof(buf
) - (p
- buf
),
3111 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
3112 s
[0], s
[1], s
[2], s
[3], d
[0], d
[1], d
[2], d
[3]);
3115 else if (((struct sockaddr
*)&saidx
->src
)->sa_family
== AF_INET6
) {
3116 snprintf(p
, sizeof(buf
) - (p
- buf
),
3118 ip6_sprintf(&((struct sockaddr_in6
*)&saidx
->src
)->sin6_addr
));
3121 snprintf(p
, sizeof(buf
) - (p
- buf
),
3123 ip6_sprintf(&((struct sockaddr_in6
*)&saidx
->dst
)->sin6_addr
));
3128 snprintf(p
, sizeof(buf
) - (p
- buf
), ")");
3144 p
= mtod(m
, u_char
*);
3145 for (i
= 0; i
< m
->m_len
; i
++) {
3146 printf("%02x ", p
[i
]);
3148 if (totlen
% 16 == 0)
3153 if (totlen
% 16 != 0)
3160 * IPsec output logic for IPv4.
3164 struct ipsec_output_state
*state
,
3165 struct secpolicy
*sp
,
3168 struct ip
*ip
= NULL
;
3169 struct ipsecrequest
*isr
= NULL
;
3170 struct secasindex saidx
;
3171 struct secasvar
*sav
= NULL
;
3173 struct sockaddr_in
*dst4
;
3174 struct sockaddr_in
*sin
;
3177 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3180 panic("state == NULL in ipsec4_output");
3182 panic("state->m == NULL in ipsec4_output");
3184 panic("state->dst == NULL in ipsec4_output");
3186 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_START
, 0,0,0,0,0);
3188 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3189 printf("ipsec4_output: applyed SP\n");
3190 kdebug_secpolicy(sp
));
3192 for (isr
= sp
->req
; isr
!= NULL
; isr
= isr
->next
) {
3194 #if 0 /* give up to check restriction of transport mode */
3195 /* XXX but should be checked somewhere */
3197 * some of the IPsec operation must be performed only in
3200 if (isr
->saidx
.mode
== IPSEC_MODE_TRANSPORT
3201 && (flags
& IP_FORWARDING
))
3205 /* make SA index for search proper SA */
3206 ip
= mtod(state
->m
, struct ip
*);
3207 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3208 saidx
.mode
= isr
->saidx
.mode
;
3209 saidx
.reqid
= isr
->saidx
.reqid
;
3210 sin
= (struct sockaddr_in
*)&saidx
.src
;
3211 if (sin
->sin_len
== 0) {
3212 sin
->sin_len
= sizeof(*sin
);
3213 sin
->sin_family
= AF_INET
;
3214 sin
->sin_port
= IPSEC_PORT_ANY
;
3215 bcopy(&ip
->ip_src
, &sin
->sin_addr
,
3216 sizeof(sin
->sin_addr
));
3218 sin
= (struct sockaddr_in
*)&saidx
.dst
;
3219 if (sin
->sin_len
== 0) {
3220 sin
->sin_len
= sizeof(*sin
);
3221 sin
->sin_family
= AF_INET
;
3222 sin
->sin_port
= IPSEC_PORT_ANY
;
3224 * Get port from packet if upper layer is UDP and nat traversal
3225 * is enabled and transport mode.
3228 if ((esp_udp_encap_port
& 0xFFFF) != 0 &&
3229 isr
->saidx
.mode
== IPSEC_MODE_TRANSPORT
) {
3231 if (ip
->ip_p
== IPPROTO_UDP
) {
3235 hlen
= IP_VHL_HL(ip
->ip_vhl
) << 2;
3237 hlen
= ip
->ip_hl
<< 2;
3239 if (state
->m
->m_len
< hlen
+ sizeof(struct udphdr
)) {
3240 state
->m
= m_pullup(state
->m
, hlen
+ sizeof(struct udphdr
));
3242 ipseclog((LOG_DEBUG
,
3243 "IPv4 output: can't pullup UDP header\n"));
3244 IPSEC_STAT_INCREMENT(ipsecstat
.in_inval
);
3247 ip
= mtod(state
->m
, struct ip
*);
3249 udp
= (struct udphdr
*)(void *)(((u_int8_t
*)ip
) + hlen
);
3250 sin
->sin_port
= udp
->uh_dport
;
3254 bcopy(&ip
->ip_dst
, &sin
->sin_addr
,
3255 sizeof(sin
->sin_addr
));
3258 if ((error
= key_checkrequest(isr
, &saidx
, &sav
)) != 0) {
3260 * IPsec processing is required, but no SA found.
3261 * I assume that key_acquire() had been called
3262 * to get/establish the SA. Here I discard
3263 * this packet because it is responsibility for
3264 * upper layer to retransmit the packet.
3266 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
);
3270 /* validity check */
3272 switch (ipsec_get_reqlevel(isr
)) {
3273 case IPSEC_LEVEL_USE
:
3275 case IPSEC_LEVEL_REQUIRE
:
3276 /* must be not reached here. */
3277 panic("ipsec4_output: no SA found, but required.");
3282 * If there is no valid SA, we give up to process any
3283 * more. In such a case, the SA's status is changed
3284 * from DYING to DEAD after allocating. If a packet
3285 * send to the receiver by dead SA, the receiver can
3286 * not decode a packet because SA has been dead.
3288 if (sav
->state
!= SADB_SASTATE_MATURE
3289 && sav
->state
!= SADB_SASTATE_DYING
) {
3290 IPSEC_STAT_INCREMENT(ipsecstat
.out_nosa
);
3296 * There may be the case that SA status will be changed when
3297 * we are refering to one. So calling splsoftnet().
3300 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3302 * build IPsec tunnel.
3304 /* XXX should be processed with other familiy */
3305 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
!= AF_INET
) {
3306 ipseclog((LOG_ERR
, "ipsec4_output: "
3307 "family mismatched between inner and outer spi=%u\n",
3308 (u_int32_t
)ntohl(sav
->spi
)));
3309 error
= EAFNOSUPPORT
;
3313 state
->m
= ipsec4_splithdr(state
->m
);
3318 error
= ipsec4_encapsulate(state
->m
, sav
);
3323 ip
= mtod(state
->m
, struct ip
*);
3325 // grab sadb_mutex, before updating sah's route cache
3326 lck_mtx_lock(sadb_mutex
);
3327 ro4
= &sav
->sah
->sa_route
;
3328 dst4
= (struct sockaddr_in
*)(void *)&ro4
->ro_dst
;
3329 if (ro4
->ro_rt
!= NULL
) {
3330 RT_LOCK(ro4
->ro_rt
);
3332 if (ROUTE_UNUSABLE(ro4
) ||
3333 dst4
->sin_addr
.s_addr
!= ip
->ip_dst
.s_addr
) {
3334 if (ro4
->ro_rt
!= NULL
)
3335 RT_UNLOCK(ro4
->ro_rt
);
3338 if (ro4
->ro_rt
== 0) {
3339 dst4
->sin_family
= AF_INET
;
3340 dst4
->sin_len
= sizeof(*dst4
);
3341 dst4
->sin_addr
= ip
->ip_dst
;
3343 if (ro4
->ro_rt
== 0) {
3344 OSAddAtomic(1, &ipstat
.ips_noroute
);
3345 error
= EHOSTUNREACH
;
3346 // release sadb_mutex, after updating sah's route cache
3347 lck_mtx_unlock(sadb_mutex
);
3350 RT_LOCK(ro4
->ro_rt
);
3354 * adjust state->dst if tunnel endpoint is offlink
3356 * XXX: caching rt_gateway value in the state is
3357 * not really good, since it may point elsewhere
3358 * when the gateway gets modified to a larger
3359 * sockaddr via rt_setgate(). This is currently
3360 * addressed by SA_SIZE roundup in that routine.
3362 if (ro4
->ro_rt
->rt_flags
& RTF_GATEWAY
)
3363 dst4
= (struct sockaddr_in
*)(void *)ro4
->ro_rt
->rt_gateway
;
3364 RT_UNLOCK(ro4
->ro_rt
);
3365 ROUTE_RELEASE(&state
->ro
);
3366 route_copyout(&state
->ro
, ro4
, sizeof(state
->ro
));
3367 state
->dst
= (struct sockaddr
*)dst4
;
3368 state
->tunneled
= 4;
3369 // release sadb_mutex, after updating sah's route cache
3370 lck_mtx_unlock(sadb_mutex
);
3373 state
->m
= ipsec4_splithdr(state
->m
);
3378 switch (isr
->saidx
.proto
) {
3381 if ((error
= esp4_output(state
->m
, sav
)) != 0) {
3393 if ((error
= ah4_output(state
->m
, sav
)) != 0) {
3398 case IPPROTO_IPCOMP
:
3399 if ((error
= ipcomp4_output(state
->m
, sav
)) != 0) {
3406 "ipsec4_output: unknown ipsec protocol %d\n",
3414 if (state
->m
== 0) {
3418 ip
= mtod(state
->m
, struct ip
*);
3421 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, 0,0,0,0,0);
3423 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3428 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3431 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT
| DBG_FUNC_END
, error
,0,0,0,0);
3438 * IPsec output logic for IPv6, transport mode.
3441 ipsec6_output_trans(
3442 struct ipsec_output_state
*state
,
3445 struct secpolicy
*sp
,
3449 struct ip6_hdr
*ip6
;
3450 struct ipsecrequest
*isr
= NULL
;
3451 struct secasindex saidx
;
3454 struct sockaddr_in6
*sin6
;
3455 struct secasvar
*sav
= NULL
;
3457 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3460 panic("state == NULL in ipsec6_output_trans");
3462 panic("state->m == NULL in ipsec6_output_trans");
3464 panic("nexthdrp == NULL in ipsec6_output_trans");
3466 panic("mprev == NULL in ipsec6_output_trans");
3468 panic("sp == NULL in ipsec6_output_trans");
3470 panic("tun == NULL in ipsec6_output_trans");
3472 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3473 printf("ipsec6_output_trans: applyed SP\n");
3474 kdebug_secpolicy(sp
));
3477 for (isr
= sp
->req
; isr
; isr
= isr
->next
) {
3478 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3479 /* the rest will be handled by ipsec6_output_tunnel() */
3483 /* make SA index for search proper SA */
3484 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3485 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3486 saidx
.mode
= isr
->saidx
.mode
;
3487 saidx
.reqid
= isr
->saidx
.reqid
;
3488 sin6
= (struct sockaddr_in6
*)&saidx
.src
;
3489 if (sin6
->sin6_len
== 0) {
3490 sin6
->sin6_len
= sizeof(*sin6
);
3491 sin6
->sin6_family
= AF_INET6
;
3492 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3493 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
,
3494 sizeof(ip6
->ip6_src
));
3495 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
3496 /* fix scope id for comparing SPD */
3497 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3498 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
3501 sin6
= (struct sockaddr_in6
*)&saidx
.dst
;
3502 if (sin6
->sin6_len
== 0) {
3503 sin6
->sin6_len
= sizeof(*sin6
);
3504 sin6
->sin6_family
= AF_INET6
;
3505 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3506 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
,
3507 sizeof(ip6
->ip6_dst
));
3508 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
3509 /* fix scope id for comparing SPD */
3510 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3511 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
3515 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) {
3517 * IPsec processing is required, but no SA found.
3518 * I assume that key_acquire() had been called
3519 * to get/establish the SA. Here I discard
3520 * this packet because it is responsibility for
3521 * upper layer to retransmit the packet.
3523 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3527 * Notify the fact that the packet is discarded
3528 * to ourselves. I believe this is better than
3529 * just silently discarding. (jinmei@kame.net)
3530 * XXX: should we restrict the error to TCP packets?
3531 * XXX: should we directly notify sockets via
3534 icmp6_error(state
->m
, ICMP6_DST_UNREACH
,
3535 ICMP6_DST_UNREACH_ADMIN
, 0);
3536 state
->m
= NULL
; /* icmp6_error freed the mbuf */
3540 /* validity check */
3542 switch (ipsec_get_reqlevel(isr
)) {
3543 case IPSEC_LEVEL_USE
:
3545 case IPSEC_LEVEL_REQUIRE
:
3546 /* must be not reached here. */
3547 panic("ipsec6_output_trans: no SA found, but required.");
3552 * If there is no valid SA, we give up to process.
3553 * see same place at ipsec4_output().
3555 if (sav
->state
!= SADB_SASTATE_MATURE
3556 && sav
->state
!= SADB_SASTATE_DYING
) {
3557 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3562 switch (isr
->saidx
.proto
) {
3565 error
= esp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3572 error
= ah6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3574 case IPPROTO_IPCOMP
:
3575 error
= ipcomp6_output(state
->m
, nexthdrp
, mprev
->m_next
, sav
);
3578 ipseclog((LOG_ERR
, "ipsec6_output_trans: "
3579 "unknown ipsec protocol %d\n", isr
->saidx
.proto
));
3581 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3589 plen
= state
->m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
3590 if (plen
> IPV6_MAXPACKET
) {
3591 ipseclog((LOG_ERR
, "ipsec6_output_trans: "
3592 "IPsec with IPv6 jumbogram is not supported\n"));
3593 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3594 error
= EINVAL
; /*XXX*/
3597 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3598 ip6
->ip6_plen
= htons(plen
);
3601 /* if we have more to go, we need a tunnel mode processing */
3606 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3611 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3618 * IPsec output logic for IPv6, tunnel mode.
3621 ipsec6_output_tunnel(
3622 struct ipsec_output_state
*state
,
3623 struct secpolicy
*sp
,
3626 struct ip6_hdr
*ip6
;
3627 struct ipsecrequest
*isr
= NULL
;
3628 struct secasindex saidx
;
3629 struct secasvar
*sav
= NULL
;
3632 struct sockaddr_in6
* dst6
;
3635 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3638 panic("state == NULL in ipsec6_output_tunnel");
3640 panic("state->m == NULL in ipsec6_output_tunnel");
3642 panic("sp == NULL in ipsec6_output_tunnel");
3644 KEYDEBUG(KEYDEBUG_IPSEC_DATA
,
3645 printf("ipsec6_output_tunnel: applyed SP\n");
3646 kdebug_secpolicy(sp
));
3649 * transport mode ipsec (before the 1st tunnel mode) is already
3650 * processed by ipsec6_output_trans().
3652 for (isr
= sp
->req
; isr
; isr
= isr
->next
) {
3653 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
)
3657 for (/* already initialized */; isr
; isr
= isr
->next
) {
3658 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3659 /* When tunnel mode, SA peers must be specified. */
3660 bcopy(&isr
->saidx
, &saidx
, sizeof(saidx
));
3662 /* make SA index to look for a proper SA */
3663 struct sockaddr_in6
*sin6
;
3665 bzero(&saidx
, sizeof(saidx
));
3666 saidx
.proto
= isr
->saidx
.proto
;
3667 saidx
.mode
= isr
->saidx
.mode
;
3668 saidx
.reqid
= isr
->saidx
.reqid
;
3670 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3671 sin6
= (struct sockaddr_in6
*)&saidx
.src
;
3672 if (sin6
->sin6_len
== 0) {
3673 sin6
->sin6_len
= sizeof(*sin6
);
3674 sin6
->sin6_family
= AF_INET6
;
3675 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3676 bcopy(&ip6
->ip6_src
, &sin6
->sin6_addr
,
3677 sizeof(ip6
->ip6_src
));
3678 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
)) {
3679 /* fix scope id for comparing SPD */
3680 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3681 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_src
.s6_addr16
[1]);
3684 sin6
= (struct sockaddr_in6
*)&saidx
.dst
;
3685 if (sin6
->sin6_len
== 0) {
3686 sin6
->sin6_len
= sizeof(*sin6
);
3687 sin6
->sin6_family
= AF_INET6
;
3688 sin6
->sin6_port
= IPSEC_PORT_ANY
;
3689 bcopy(&ip6
->ip6_dst
, &sin6
->sin6_addr
,
3690 sizeof(ip6
->ip6_dst
));
3691 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
)) {
3692 /* fix scope id for comparing SPD */
3693 sin6
->sin6_addr
.s6_addr16
[1] = 0;
3694 sin6
->sin6_scope_id
= ntohs(ip6
->ip6_dst
.s6_addr16
[1]);
3699 if (key_checkrequest(isr
, &saidx
, &sav
) == ENOENT
) {
3701 * IPsec processing is required, but no SA found.
3702 * I assume that key_acquire() had been called
3703 * to get/establish the SA. Here I discard
3704 * this packet because it is responsibility for
3705 * upper layer to retransmit the packet.
3707 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3712 /* validity check */
3714 switch (ipsec_get_reqlevel(isr
)) {
3715 case IPSEC_LEVEL_USE
:
3717 case IPSEC_LEVEL_REQUIRE
:
3718 /* must be not reached here. */
3719 panic("ipsec6_output_tunnel: no SA found, but required.");
3724 * If there is no valid SA, we give up to process.
3725 * see same place at ipsec4_output().
3727 if (sav
->state
!= SADB_SASTATE_MATURE
3728 && sav
->state
!= SADB_SASTATE_DYING
) {
3729 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nosa
);
3734 if (isr
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
3736 * build IPsec tunnel.
3738 state
->m
= ipsec6_splithdr(state
->m
);
3740 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
);
3745 if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
== AF_INET6
) {
3746 error
= ipsec6_encapsulate(state
->m
, sav
);
3751 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3752 } else if (((struct sockaddr
*)&sav
->sah
->saidx
.src
)->sa_family
== AF_INET
) {
3755 struct sockaddr_in
* dst4
;
3756 struct route
*ro4
= NULL
;
3757 struct route ro4_copy
;
3758 struct ip_out_args ipoa
= { IFSCOPE_NONE
, { 0 },
3759 IPOAF_SELECT_SRCIF
, 0 };
3762 * must be last isr because encapsulated IPv6 packet
3763 * will be sent by calling ip_output
3766 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3767 "IPv4 must be outer layer, spi=%u\n",
3768 (u_int32_t
)ntohl(sav
->spi
)));
3772 state
->tunneled
= 4; /* must not process any further in ip6_output */
3773 error
= ipsec64_encapsulate(state
->m
, sav
);
3778 /* Now we have an IPv4 packet */
3779 ip
= mtod(state
->m
, struct ip
*);
3781 // grab sadb_mutex, to update sah's route cache and get a local copy of it
3782 lck_mtx_lock(sadb_mutex
);
3783 ro4
= &sav
->sah
->sa_route
;
3784 dst4
= (struct sockaddr_in
*)(void *)&ro4
->ro_dst
;
3786 RT_LOCK(ro4
->ro_rt
);
3788 if (ROUTE_UNUSABLE(ro4
) ||
3789 dst4
->sin_addr
.s_addr
!= ip
->ip_dst
.s_addr
) {
3790 if (ro4
->ro_rt
!= NULL
)
3791 RT_UNLOCK(ro4
->ro_rt
);
3794 if (ro4
->ro_rt
== NULL
) {
3795 dst4
->sin_family
= AF_INET
;
3796 dst4
->sin_len
= sizeof(*dst4
);
3797 dst4
->sin_addr
= ip
->ip_dst
;
3799 RT_UNLOCK(ro4
->ro_rt
);
3801 route_copyout(&ro4_copy
, ro4
, sizeof(ro4_copy
));
3802 // release sadb_mutex, after updating sah's route cache and getting a local copy
3803 lck_mtx_unlock(sadb_mutex
);
3804 state
->m
= ipsec4_splithdr(state
->m
);
3807 ROUTE_RELEASE(&ro4_copy
);
3810 switch (isr
->saidx
.proto
) {
3813 if ((error
= esp4_output(state
->m
, sav
)) != 0) {
3815 ROUTE_RELEASE(&ro4_copy
);
3824 ROUTE_RELEASE(&ro4_copy
);
3828 if ((error
= ah4_output(state
->m
, sav
)) != 0) {
3830 ROUTE_RELEASE(&ro4_copy
);
3834 case IPPROTO_IPCOMP
:
3835 if ((error
= ipcomp4_output(state
->m
, sav
)) != 0) {
3837 ROUTE_RELEASE(&ro4_copy
);
3843 "ipsec4_output: unknown ipsec protocol %d\n",
3848 ROUTE_RELEASE(&ro4_copy
);
3852 if (state
->m
== 0) {
3854 ROUTE_RELEASE(&ro4_copy
);
3857 ip
= mtod(state
->m
, struct ip
*);
3858 ip
->ip_len
= ntohs(ip
->ip_len
); /* flip len field before calling ip_output */
3859 error
= ip_output(state
->m
, NULL
, &ro4_copy
, IP_OUTARGS
, NULL
, &ipoa
);
3861 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
3862 lck_mtx_lock(sadb_mutex
);
3863 route_copyin(&ro4_copy
, ro4
, sizeof(ro4_copy
));
3864 lck_mtx_unlock(sadb_mutex
);
3869 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3870 "unsupported inner family, spi=%u\n",
3871 (u_int32_t
)ntohl(sav
->spi
)));
3872 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3873 error
= EAFNOSUPPORT
;
3877 // grab sadb_mutex, before updating sah's route cache
3878 lck_mtx_lock(sadb_mutex
);
3879 ro6
= &sav
->sah
->sa_route
;
3880 dst6
= (struct sockaddr_in6
*)(void *)&ro6
->ro_dst
;
3882 RT_LOCK(ro6
->ro_rt
);
3884 if (ROUTE_UNUSABLE(ro6
) ||
3885 !IN6_ARE_ADDR_EQUAL(&dst6
->sin6_addr
, &ip6
->ip6_dst
)) {
3886 if (ro6
->ro_rt
!= NULL
)
3887 RT_UNLOCK(ro6
->ro_rt
);
3890 if (ro6
->ro_rt
== 0) {
3891 bzero(dst6
, sizeof(*dst6
));
3892 dst6
->sin6_family
= AF_INET6
;
3893 dst6
->sin6_len
= sizeof(*dst6
);
3894 dst6
->sin6_addr
= ip6
->ip6_dst
;
3897 RT_LOCK(ro6
->ro_rt
);
3900 if (ro6
->ro_rt
== 0) {
3901 ip6stat
.ip6s_noroute
++;
3902 IPSEC_STAT_INCREMENT(ipsec6stat
.out_noroute
);
3903 error
= EHOSTUNREACH
;
3904 // release sadb_mutex, after updating sah's route cache
3905 lck_mtx_unlock(sadb_mutex
);
3910 * adjust state->dst if tunnel endpoint is offlink
3912 * XXX: caching rt_gateway value in the state is
3913 * not really good, since it may point elsewhere
3914 * when the gateway gets modified to a larger
3915 * sockaddr via rt_setgate(). This is currently
3916 * addressed by SA_SIZE roundup in that routine.
3918 if (ro6
->ro_rt
->rt_flags
& RTF_GATEWAY
)
3919 dst6
= (struct sockaddr_in6
*)(void *)ro6
->ro_rt
->rt_gateway
;
3920 RT_UNLOCK(ro6
->ro_rt
);
3921 ROUTE_RELEASE(&state
->ro
);
3922 route_copyout(&state
->ro
, ro6
, sizeof(state
->ro
));
3923 state
->dst
= (struct sockaddr
*)dst6
;
3924 state
->tunneled
= 6;
3925 // release sadb_mutex, after updating sah's route cache
3926 lck_mtx_unlock(sadb_mutex
);
3929 state
->m
= ipsec6_splithdr(state
->m
);
3931 IPSEC_STAT_INCREMENT(ipsec6stat
.out_nomem
);
3935 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3936 switch (isr
->saidx
.proto
) {
3939 error
= esp6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
);
3946 error
= ah6_output(state
->m
, &ip6
->ip6_nxt
, state
->m
->m_next
, sav
);
3948 case IPPROTO_IPCOMP
:
3949 /* XXX code should be here */
3952 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3953 "unknown ipsec protocol %d\n", isr
->saidx
.proto
));
3955 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3963 plen
= state
->m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
3964 if (plen
> IPV6_MAXPACKET
) {
3965 ipseclog((LOG_ERR
, "ipsec6_output_tunnel: "
3966 "IPsec with IPv6 jumbogram is not supported\n"));
3967 IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
);
3968 error
= EINVAL
; /*XXX*/
3971 ip6
= mtod(state
->m
, struct ip6_hdr
*);
3972 ip6
->ip6_plen
= htons(plen
);
3976 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3981 key_freesav(sav
, KEY_SADB_UNLOCKED
);
3991 * Chop IP header and option off from the payload.
4001 if (m
->m_len
< sizeof(struct ip
))
4002 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
);
4003 ip
= mtod(m
, struct ip
*);
4005 hlen
= _IP_VHL_HL(ip
->ip_vhl
) << 2;
4007 hlen
= ip
->ip_hl
<< 2;
4009 if (m
->m_len
> hlen
) {
4010 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4015 M_COPY_PKTHDR(mh
, m
);
4017 m
->m_flags
&= ~M_PKTHDR
;
4018 m_mchtype(m
, MT_DATA
);
4024 bcopy((caddr_t
)ip
, mtod(m
, caddr_t
), hlen
);
4025 } else if (m
->m_len
< hlen
) {
4026 m
= m_pullup(m
, hlen
);
4040 struct ip6_hdr
*ip6
;
4043 if (m
->m_len
< sizeof(struct ip6_hdr
))
4044 panic("ipsec6_splithdr: first mbuf too short");
4045 ip6
= mtod(m
, struct ip6_hdr
*);
4046 hlen
= sizeof(struct ip6_hdr
);
4047 if (m
->m_len
> hlen
) {
4048 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4053 M_COPY_PKTHDR(mh
, m
);
4055 m
->m_flags
&= ~M_PKTHDR
;
4056 m_mchtype(m
, MT_DATA
);
4062 bcopy((caddr_t
)ip6
, mtod(m
, caddr_t
), hlen
);
4063 } else if (m
->m_len
< hlen
) {
4064 m
= m_pullup(m
, hlen
);
4072 /* validate inbound IPsec tunnel packet. */
4074 ipsec4_tunnel_validate(m
, off
, nxt0
, sav
, ifamily
)
4075 struct mbuf
*m
; /* no pullup permitted, m->m_len >= ip */
4078 struct secasvar
*sav
;
4079 sa_family_t
*ifamily
;
4081 u_int8_t nxt
= nxt0
& 0xff;
4082 struct sockaddr_in
*sin
;
4083 struct sockaddr_in osrc
, odst
, i4src
, i4dst
;
4084 struct sockaddr_in6 i6src
, i6dst
;
4086 struct secpolicy
*sp
;
4089 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4092 if (m
->m_len
< sizeof(struct ip
))
4093 panic("too short mbuf on ipsec4_tunnel_validate");
4095 if (nxt
!= IPPROTO_IPV4
&& nxt
!= IPPROTO_IPV6
)
4097 if (m
->m_pkthdr
.len
< off
+ sizeof(struct ip
))
4099 /* do not decapsulate if the SA is for transport mode only */
4100 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
4103 oip
= mtod(m
, struct ip
*);
4105 hlen
= _IP_VHL_HL(oip
->ip_vhl
) << 2;
4107 hlen
= oip
->ip_hl
<< 2;
4109 if (hlen
!= sizeof(struct ip
))
4112 sin
= (struct sockaddr_in
*)&sav
->sah
->saidx
.dst
;
4113 if (sin
->sin_family
!= AF_INET
)
4115 if (bcmp(&oip
->ip_dst
, &sin
->sin_addr
, sizeof(oip
->ip_dst
)) != 0)
4118 if (sav
->utun_in_fn
) {
4119 // the utun SAs don't have a policy (yet).
4120 if (nxt
== IPPROTO_IPV4
) {
4122 } else if (nxt
== IPPROTO_IPV6
) {
4123 *ifamily
= AF_INET6
;
4131 bzero(&osrc
, sizeof(osrc
));
4132 bzero(&odst
, sizeof(odst
));
4133 osrc
.sin_family
= odst
.sin_family
= AF_INET
;
4134 osrc
.sin_len
= odst
.sin_len
= sizeof(struct sockaddr_in
);
4135 osrc
.sin_addr
= oip
->ip_src
;
4136 odst
.sin_addr
= oip
->ip_dst
;
4138 * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
4139 * - if the inner destination is multicast address, there can be
4140 * multiple permissible inner source address. implementation
4141 * may want to skip verification of inner source address against
4143 * - if the inner protocol is ICMP, the packet may be an error report
4144 * from routers on the other side of the VPN cloud (R in the
4145 * following diagram). in this case, we cannot verify inner source
4146 * address against SPD selector.
4147 * me -- gw === gw -- R -- you
4149 * we consider the first bullet to be users responsibility on SPD entry
4150 * configuration (if you need to encrypt multicast traffic, set
4151 * the source range of SPD selector to 0.0.0.0/0, or have explicit
4152 * address ranges for possible senders).
4153 * the second bullet is not taken care of (yet).
4155 * therefore, we do not do anything special about inner source.
4157 if (nxt
== IPPROTO_IPV4
) {
4158 bzero(&i4src
, sizeof(struct sockaddr_in
));
4159 bzero(&i4dst
, sizeof(struct sockaddr_in
));
4160 i4src
.sin_family
= i4dst
.sin_family
= *ifamily
= AF_INET
;
4161 i4src
.sin_len
= i4dst
.sin_len
= sizeof(struct sockaddr_in
);
4162 m_copydata(m
, off
+ offsetof(struct ip
, ip_src
), sizeof(i4src
.sin_addr
),
4163 (caddr_t
)&i4src
.sin_addr
);
4164 m_copydata(m
, off
+ offsetof(struct ip
, ip_dst
), sizeof(i4dst
.sin_addr
),
4165 (caddr_t
)&i4dst
.sin_addr
);
4166 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4167 (struct sockaddr
*)&i4src
, (struct sockaddr
*)&i4dst
);
4168 } else if (nxt
== IPPROTO_IPV6
) {
4169 bzero(&i6src
, sizeof(struct sockaddr_in6
));
4170 bzero(&i6dst
, sizeof(struct sockaddr_in6
));
4171 i6src
.sin6_family
= i6dst
.sin6_family
= *ifamily
= AF_INET6
;
4172 i6src
.sin6_len
= i6dst
.sin6_len
= sizeof(struct sockaddr_in6
);
4173 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_src
), sizeof(i6src
.sin6_addr
),
4174 (caddr_t
)&i6src
.sin6_addr
);
4175 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_dst
), sizeof(i6dst
.sin6_addr
),
4176 (caddr_t
)&i6dst
.sin6_addr
);
4177 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4178 (struct sockaddr
*)&i6src
, (struct sockaddr
*)&i6dst
);
4180 return 0; /* unsupported family */
4185 key_freesp(sp
, KEY_SADB_UNLOCKED
);
4191 /* validate inbound IPsec tunnel packet. */
4193 ipsec6_tunnel_validate(m
, off
, nxt0
, sav
)
4194 struct mbuf
*m
; /* no pullup permitted, m->m_len >= ip */
4197 struct secasvar
*sav
;
4199 u_int8_t nxt
= nxt0
& 0xff;
4200 struct sockaddr_in6
*sin6
;
4201 struct sockaddr_in6 osrc
, odst
, isrc
, idst
;
4202 struct secpolicy
*sp
;
4203 struct ip6_hdr
*oip6
;
4205 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4208 if (m
->m_len
< sizeof(struct ip6_hdr
))
4209 panic("too short mbuf on ipsec6_tunnel_validate");
4211 if (nxt
!= IPPROTO_IPV6
)
4213 if (m
->m_pkthdr
.len
< off
+ sizeof(struct ip6_hdr
))
4215 /* do not decapsulate if the SA is for transport mode only */
4216 if (sav
->sah
->saidx
.mode
== IPSEC_MODE_TRANSPORT
)
4219 oip6
= mtod(m
, struct ip6_hdr
*);
4220 /* AF_INET should be supported, but at this moment we don't. */
4221 sin6
= (struct sockaddr_in6
*)&sav
->sah
->saidx
.dst
;
4222 if (sin6
->sin6_family
!= AF_INET6
)
4224 if (!IN6_ARE_ADDR_EQUAL(&oip6
->ip6_dst
, &sin6
->sin6_addr
))
4227 if (sav
->utun_in_fn
) {
4228 // the utun SAs don't have a policy (yet).
4233 bzero(&osrc
, sizeof(osrc
));
4234 bzero(&odst
, sizeof(odst
));
4235 bzero(&isrc
, sizeof(isrc
));
4236 bzero(&idst
, sizeof(idst
));
4237 osrc
.sin6_family
= odst
.sin6_family
= isrc
.sin6_family
=
4238 idst
.sin6_family
= AF_INET6
;
4239 osrc
.sin6_len
= odst
.sin6_len
= isrc
.sin6_len
= idst
.sin6_len
=
4240 sizeof(struct sockaddr_in6
);
4241 osrc
.sin6_addr
= oip6
->ip6_src
;
4242 odst
.sin6_addr
= oip6
->ip6_dst
;
4243 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_src
),
4244 sizeof(isrc
.sin6_addr
), (caddr_t
)&isrc
.sin6_addr
);
4245 m_copydata(m
, off
+ offsetof(struct ip6_hdr
, ip6_dst
),
4246 sizeof(idst
.sin6_addr
), (caddr_t
)&idst
.sin6_addr
);
4249 * regarding to inner source address validation, see a long comment
4250 * in ipsec4_tunnel_validate.
4253 sp
= key_gettunnel((struct sockaddr
*)&osrc
, (struct sockaddr
*)&odst
,
4254 (struct sockaddr
*)&isrc
, (struct sockaddr
*)&idst
);
4256 * when there is no suitable inbound policy for the packet of the ipsec
4257 * tunnel mode, the kernel never decapsulate the tunneled packet
4258 * as the ipsec tunnel mode even when the system wide policy is "none".
4259 * then the kernel leaves the generic tunnel module to process this
4260 * packet. if there is no rule of the generic tunnel, the packet
4261 * is rejected and the statistics will be counted up.
4265 key_freesp(sp
, KEY_SADB_UNLOCKED
);
4272 * Make a mbuf chain for encryption.
4273 * If the original mbuf chain contains a mbuf with a cluster,
4274 * allocate a new cluster and copy the data to the new cluster.
4275 * XXX: this hack is inefficient, but is necessary to handle cases
4276 * of TCP retransmission...
4282 struct mbuf
*n
, **mpp
, *mnew
;
4284 for (n
= m
, mpp
= &m
; n
; n
= n
->m_next
) {
4285 if (n
->m_flags
& M_EXT
) {
4287 * Make a copy only if there are more than one references
4289 * XXX: is this approach effective?
4292 n
->m_ext
.ext_free
||
4293 m_mclhasreference(n
)
4299 if (n
->m_flags
& M_PKTHDR
) {
4300 MGETHDR(mnew
, M_DONTWAIT
, MT_HEADER
); /* MAC-OK */
4303 M_COPY_PKTHDR(mnew
, n
);
4306 MGET(mnew
, M_DONTWAIT
, MT_DATA
);
4314 * Copy data. If we don't have enough space to
4315 * store the whole data, allocate a cluster
4316 * or additional mbufs.
4317 * XXX: we don't use m_copyback(), since the
4318 * function does not use clusters and thus is
4327 if (remain
<= (mm
->m_flags
& M_PKTHDR
? MHLEN
: MLEN
))
4329 else { /* allocate a cluster */
4330 MCLGET(mm
, M_DONTWAIT
);
4331 if (!(mm
->m_flags
& M_EXT
)) {
4335 len
= remain
< MCLBYTES
?
4339 bcopy(n
->m_data
+ copied
, mm
->m_data
,
4346 if (remain
<= 0) /* completed? */
4349 /* need another mbuf */
4350 MGETHDR(mn
, M_DONTWAIT
, MT_HEADER
); /* XXXMAC: tags copied next time in loop? */
4353 mn
->m_pkthdr
.rcvif
= NULL
;
4359 mm
->m_next
= m_free(n
);
4378 * Tags are allocated as mbufs for now, since our minimum size is MLEN, we
4379 * should make use of up to that much space.
4381 #define IPSEC_TAG_HEADER \
4384 struct socket
*socket
;
4385 u_int32_t history_count
;
4386 struct ipsec_history history
[];
4389 #define IPSEC_TAG_SIZE (MLEN - sizeof(struct m_tag))
4390 #define IPSEC_TAG_HDR_SIZE (offsetof(struct ipsec_tag, history[0]))
4391 #define IPSEC_HISTORY_MAX ((IPSEC_TAG_SIZE - IPSEC_TAG_HDR_SIZE) / \
4392 sizeof(struct ipsec_history))
4394 static struct ipsec_tag
*
4400 /* Check if the tag already exists */
4401 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4404 struct ipsec_tag
*itag
;
4406 /* Allocate a tag */
4407 tag
= m_tag_create(KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
,
4408 IPSEC_TAG_SIZE
, M_DONTWAIT
, m
);
4411 itag
= (struct ipsec_tag
*)(tag
+ 1);
4413 itag
->history_count
= 0;
4415 m_tag_prepend(m
, tag
);
4419 return tag
? (struct ipsec_tag
*)(tag
+ 1) : NULL
;
4422 static struct ipsec_tag
*
4428 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4430 return tag
? (struct ipsec_tag
*)(tag
+ 1) : NULL
;
4439 tag
= m_tag_locate(m
, KERNEL_MODULE_TAG_ID
, KERNEL_TAG_TYPE_IPSEC
, NULL
);
4442 m_tag_delete(m
, tag
);
4446 /* if the aux buffer is unnecessary, nuke it. */
4450 struct ipsec_tag
*itag
)
4452 if (itag
&& itag
->socket
== NULL
&& itag
->history_count
== 0) {
4453 m_tag_delete(m
, ((struct m_tag
*)itag
) - 1);
4462 struct ipsec_tag
*tag
;
4464 /* if so == NULL, don't insist on getting the aux mbuf */
4466 tag
= ipsec_addaux(m
);
4470 tag
= ipsec_findaux(m
);
4473 ipsec_optaux(m
, tag
);
4482 struct ipsec_tag
*itag
;
4484 itag
= ipsec_findaux(m
);
4486 return itag
->socket
;
4497 struct ipsec_tag
*itag
;
4498 struct ipsec_history
*p
;
4499 itag
= ipsec_addaux(m
);
4502 if (itag
->history_count
== IPSEC_HISTORY_MAX
)
4503 return ENOSPC
; /* XXX */
4505 p
= &itag
->history
[itag
->history_count
];
4506 itag
->history_count
++;
4508 bzero(p
, sizeof(*p
));
4509 p
->ih_proto
= proto
;
4515 struct ipsec_history
*
4520 struct ipsec_tag
*itag
;
4522 itag
= ipsec_findaux(m
);
4525 if (itag
->history_count
== 0)
4528 *lenp
= (int)(itag
->history_count
* sizeof(struct ipsec_history
));
4529 return itag
->history
;
4536 struct ipsec_tag
*itag
;
4538 itag
= ipsec_findaux(m
);
4540 itag
->history_count
= 0;
4542 ipsec_optaux(m
, itag
);
4545 __private_extern__
int
4546 ipsec_send_natt_keepalive(
4547 struct secasvar
*sav
)
4552 struct ip_out_args ipoa
=
4553 { IFSCOPE_NONE
, { 0 }, IPOAF_SELECT_SRCIF
, 0 };
4556 lck_mtx_assert(sadb_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
4558 if ((esp_udp_encap_port
& 0xFFFF) == 0 || sav
->remote_ike_port
== 0) return FALSE
;
4560 // natt timestamp may have changed... reverify
4561 if ((natt_now
- sav
->natt_last_activity
) < natt_keepalive_interval
) return FALSE
;
4563 if (sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
) return FALSE
; // don't send these from the kernel
4565 m
= m_gethdr(M_NOWAIT
, MT_DATA
);
4566 if (m
== NULL
) return FALSE
;
4568 ip
= (__typeof__(ip
))m_mtod(m
);
4570 // this sends one type of NATT keepalives (Type 1, ESP keepalives, aren't sent by kernel)
4571 if ((sav
->flags
& SADB_X_EXT_ESP_KEEPALIVE
) == 0) {
4575 * Type 2: a UDP packet complete with IP header.
4576 * We must do this because UDP output requires
4577 * an inpcb which we don't have. UDP packet
4578 * contains one byte payload. The byte is set
4581 uh
= (__typeof__(uh
))(void *)((char *)m_mtod(m
) + sizeof(*ip
));
4582 m
->m_len
= sizeof(struct udpiphdr
) + 1;
4583 bzero(m_mtod(m
), m
->m_len
);
4584 m
->m_pkthdr
.len
= m
->m_len
;
4586 ip
->ip_len
= m
->m_len
;
4587 ip
->ip_ttl
= ip_defttl
;
4588 ip
->ip_p
= IPPROTO_UDP
;
4589 if (sav
->sah
->dir
!= IPSEC_DIR_INBOUND
) {
4590 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4591 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4593 ip
->ip_src
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.dst
)->sin_addr
;
4594 ip
->ip_dst
= ((struct sockaddr_in
*)&sav
->sah
->saidx
.src
)->sin_addr
;
4596 uh
->uh_sport
= htons((u_short
)esp_udp_encap_port
);
4597 uh
->uh_dport
= htons(sav
->remote_ike_port
);
4598 uh
->uh_ulen
= htons(1 + sizeof(*uh
));
4600 *(u_int8_t
*)((char*)m_mtod(m
) + sizeof(*ip
) + sizeof(*uh
)) = 0xFF;
4603 // grab sadb_mutex, to get a local copy of sah's route cache
4604 lck_mtx_lock(sadb_mutex
);
4605 if (ROUTE_UNUSABLE(&sav
->sah
->sa_route
) ||
4606 rt_key(sav
->sah
->sa_route
.ro_rt
)->sa_family
!= AF_INET
)
4607 ROUTE_RELEASE(&sav
->sah
->sa_route
);
4609 route_copyout(&ro
, &sav
->sah
->sa_route
, sizeof(ro
));
4610 lck_mtx_unlock(sadb_mutex
);
4612 error
= ip_output(m
, NULL
, &ro
, IP_OUTARGS
| IP_NOIPSEC
, NULL
, &ipoa
);
4614 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
4615 lck_mtx_lock(sadb_mutex
);
4616 route_copyin(&ro
, &sav
->sah
->sa_route
, sizeof(ro
));
4617 lck_mtx_unlock(sadb_mutex
);
4619 sav
->natt_last_activity
= natt_now
;