]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet6/ipsec.c
xnu-2050.7.9.tar.gz
[apple/xnu.git] / bsd / netinet6 / ipsec.c
CommitLineData
b0d623f7 1/*
316670eb 2 * Copyright (c) 2008-2012 Apple Inc. All rights reserved.
b0d623f7
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
9bccf70c
A
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 $ */
1c79356b
A
31
32/*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
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.
47 *
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
58 * SUCH DAMAGE.
59 */
60
61/*
62 * IPsec controller part.
63 */
1c79356b
A
64
65#include <sys/param.h>
66#include <sys/systm.h>
67#include <sys/malloc.h>
68#include <sys/mbuf.h>
316670eb 69#include <sys/mcache.h>
1c79356b
A
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>
75#include <sys/time.h>
76#include <sys/kernel.h>
77#include <sys/syslog.h>
1c79356b 78#include <sys/sysctl.h>
91447636
A
79#include <kern/locks.h>
80#include <sys/kauth.h>
2d21ac55 81#include <libkern/OSAtomic.h>
1c79356b
A
82
83#include <net/if.h>
84#include <net/route.h>
85
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>
1c79356b 94#if INET6
9bccf70c
A
95#include <netinet6/ip6_ecn.h>
96#endif
97#include <netinet/tcp.h>
98#include <netinet/udp.h>
99
1c79356b 100#include <netinet/ip6.h>
9bccf70c 101#if INET6
1c79356b
A
102#include <netinet6/ip6_var.h>
103#endif
104#include <netinet/in_pcb.h>
105#if INET6
1c79356b
A
106#include <netinet/icmp6.h>
107#endif
108
109#include <netinet6/ipsec.h>
9bccf70c
A
110#if INET6
111#include <netinet6/ipsec6.h>
112#endif
1c79356b 113#include <netinet6/ah.h>
9bccf70c
A
114#if INET6
115#include <netinet6/ah6.h>
116#endif
1c79356b
A
117#if IPSEC_ESP
118#include <netinet6/esp.h>
9bccf70c
A
119#if INET6
120#include <netinet6/esp6.h>
121#endif
1c79356b
A
122#endif
123#include <netinet6/ipcomp.h>
9bccf70c
A
124#if INET6
125#include <netinet6/ipcomp6.h>
126#endif
1c79356b
A
127#include <netkey/key.h>
128#include <netkey/keydb.h>
129#include <netkey/key_debug.h>
130
131#include <net/net_osdep.h>
132
9bccf70c 133#if IPSEC_DEBUG
1c79356b
A
134int ipsec_debug = 1;
135#else
136int ipsec_debug = 0;
137#endif
138
55e303ae
A
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))
145
91447636 146extern lck_mtx_t *sadb_mutex;
55e303ae 147
1c79356b 148struct ipsecstat ipsecstat;
1c79356b
A
149int ip4_ah_cleartos = 1;
150int ip4_ah_offsetmask = 0; /* maybe IP_DF? */
151int ip4_ipsec_dfbit = 0; /* DF bit on encap. 0: clear 1: set 2: copy */
152int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
153int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
154int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
155int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
156struct secpolicy ip4_def_policy;
157int ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
9bccf70c 158int ip4_esp_randpad = -1;
55e303ae 159int esp_udp_encap_port = 0;
9bccf70c 160static int sysctl_def_policy SYSCTL_HANDLER_ARGS;
b0d623f7 161extern int natt_keepalive_interval;
55e303ae 162extern u_int32_t natt_now;
1c79356b 163
2d21ac55
A
164struct ipsec_tag;
165
1c79356b 166SYSCTL_DECL(_net_inet_ipsec);
9bccf70c
A
167#if INET6
168SYSCTL_DECL(_net_inet6_ipsec6);
169#endif
1c79356b
A
170/* net.inet.ipsec */
171SYSCTL_STRUCT(_net_inet_ipsec, IPSECCTL_STATS,
6d2010ae
A
172 stats, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsecstat, ipsecstat, "");
173SYSCTL_PROC(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, CTLTYPE_INT|CTLFLAG_RW | CTLFLAG_LOCKED,
9bccf70c 174 &ip4_def_policy.policy, 0, &sysctl_def_policy, "I", "");
1c79356b 175SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
6d2010ae 176 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_esp_trans_deflev, 0, "");
1c79356b 177SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
6d2010ae 178 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_esp_net_deflev, 0, "");
1c79356b 179SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
6d2010ae 180 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_trans_deflev, 0, "");
1c79356b 181SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
6d2010ae 182 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_net_deflev, 0, "");
1c79356b 183SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
6d2010ae 184 ah_cleartos, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_cleartos, 0, "");
1c79356b 185SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
6d2010ae 186 ah_offsetmask, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_offsetmask, 0, "");
1c79356b 187SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
6d2010ae 188 dfbit, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ipsec_dfbit, 0, "");
1c79356b 189SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
6d2010ae 190 ecn, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ipsec_ecn, 0, "");
1c79356b 191SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
6d2010ae 192 debug, CTLFLAG_RW | CTLFLAG_LOCKED, &ipsec_debug, 0, "");
9bccf70c 193SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
6d2010ae 194 esp_randpad, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_esp_randpad, 0, "");
9bccf70c
A
195
196/* for performance, we bypass ipsec until a security policy is set */
197int ipsec_bypass = 1;
6d2010ae 198SYSCTL_INT(_net_inet_ipsec, OID_AUTO, bypass, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsec_bypass,0, "");
1c79356b 199
55e303ae
A
200/*
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
204 * for nat traversal.
205 */
206SYSCTL_INT(_net_inet_ipsec, OID_AUTO, esp_port,
6d2010ae 207 CTLFLAG_RW | CTLFLAG_LOCKED, &esp_udp_encap_port, 0, "");
55e303ae 208
1c79356b
A
209#if INET6
210struct ipsecstat ipsec6stat;
1c79356b
A
211int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
212int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
213int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
214int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
215struct secpolicy ip6_def_policy;
216int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
9bccf70c 217int ip6_esp_randpad = -1;
1c79356b 218
1c79356b
A
219/* net.inet6.ipsec6 */
220SYSCTL_STRUCT(_net_inet6_ipsec6, IPSECCTL_STATS,
6d2010ae 221 stats, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsec6stat, ipsecstat, "");
1c79356b 222SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
6d2010ae 223 def_policy, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_def_policy.policy, 0, "");
1c79356b 224SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
6d2010ae 225 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_trans_deflev, 0, "");
1c79356b 226SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
6d2010ae 227 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_net_deflev, 0, "");
1c79356b 228SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
6d2010ae 229 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_ah_trans_deflev, 0, "");
1c79356b 230SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
6d2010ae 231 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_ah_net_deflev, 0, "");
1c79356b 232SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
6d2010ae 233 ecn, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_ipsec_ecn, 0, "");
1c79356b 234SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
6d2010ae 235 debug, CTLFLAG_RW | CTLFLAG_LOCKED, &ipsec_debug, 0, "");
9bccf70c 236SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
6d2010ae 237 esp_randpad, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_randpad, 0, "");
1c79356b
A
238#endif /* INET6 */
239
91447636
A
240static int ipsec_setspidx_mbuf(struct secpolicyindex *, u_int, u_int,
241 struct mbuf *, int);
242static int ipsec4_setspidx_inpcb(struct mbuf *, struct inpcb *pcb);
9bccf70c 243#if INET6
91447636 244static int ipsec6_setspidx_in6pcb(struct mbuf *, struct in6pcb *pcb);
9bccf70c 245#endif
91447636
A
246static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int);
247static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
248static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
1c79356b 249#if INET6
91447636
A
250static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
251static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
1c79356b 252#endif
91447636
A
253static struct inpcbpolicy *ipsec_newpcbpolicy(void);
254static void ipsec_delpcbpolicy(struct inpcbpolicy *);
255static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
256static int ipsec_set_policy(struct secpolicy **pcb_sp,
257 int optname, caddr_t request, size_t len, int priv);
258static int ipsec_get_policy(struct secpolicy *pcb_sp, struct mbuf **mp);
259static void vshiftl(unsigned char *, int, int);
260static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
1c79356b 261#if INET6
2d21ac55 262static int ipsec64_encapsulate(struct mbuf *, struct secasvar *);
1c79356b 263#endif
2d21ac55
A
264static struct ipsec_tag *ipsec_addaux(struct mbuf *);
265static struct ipsec_tag *ipsec_findaux(struct mbuf *);
266static void ipsec_optaux(struct mbuf *, struct ipsec_tag *);
b0d623f7 267int ipsec_send_natt_keepalive(struct secasvar *sav);
9bccf70c
A
268
269static int
270sysctl_def_policy SYSCTL_HANDLER_ARGS
271{
272 int old_policy = ip4_def_policy.policy;
273 int error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
274
b0d623f7
A
275#pragma unused(arg1, arg2)
276
9bccf70c
A
277 if (ip4_def_policy.policy != IPSEC_POLICY_NONE &&
278 ip4_def_policy.policy != IPSEC_POLICY_DISCARD) {
279 ip4_def_policy.policy = old_policy;
280 return EINVAL;
281 }
282
283 /* Turn off the bypass if the default security policy changes */
284 if (ipsec_bypass != 0 && ip4_def_policy.policy != IPSEC_POLICY_NONE)
285 ipsec_bypass = 0;
286
287 return error;
288}
1c79356b
A
289
290/*
291 * For OUTBOUND packet having a socket. Searching SPD for packet,
292 * and return a pointer to SP.
293 * OUT: NULL: no apropreate SP found, the following value is set to error.
294 * 0 : bypass
295 * EACCES : discard packet.
296 * ENOENT : ipsec_acquire() in progress, maybe.
91447636 297 * others : error occurred.
1c79356b
A
298 * others: a pointer to SP
299 *
300 * NOTE: IPv6 mapped adddress concern is implemented here.
301 */
302struct secpolicy *
303ipsec4_getpolicybysock(m, dir, so, error)
304 struct mbuf *m;
305 u_int dir;
306 struct socket *so;
307 int *error;
308{
309 struct inpcbpolicy *pcbsp = NULL;
310 struct secpolicy *currsp = NULL; /* policy on socket */
311 struct secpolicy *kernsp = NULL; /* policy on kernel */
312
2d21ac55 313 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
314 /* sanity check */
315 if (m == NULL || so == NULL || error == NULL)
316 panic("ipsec4_getpolicybysock: NULL pointer was passed.\n");
91447636 317
e5568f75 318 if (so->so_pcb == NULL) {
91447636 319 printf("ipsec4_getpolicybysock: so->so_pcb == NULL\n");
e5568f75
A
320 return ipsec4_getpolicybyaddr(m, dir, 0, error);
321 }
9bccf70c
A
322
323 switch (so->so_proto->pr_domain->dom_family) {
324 case AF_INET:
325 pcbsp = sotoinpcb(so)->inp_sp;
326 break;
327#if INET6
328 case AF_INET6:
329 pcbsp = sotoin6pcb(so)->in6p_sp;
330 break;
331#endif
332 }
333
334 if (!pcbsp){
335 /* Socket has not specified an IPSEC policy */
336 return ipsec4_getpolicybyaddr(m, dir, 0, error);
337 }
1c79356b 338
55e303ae
A
339 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_START, 0,0,0,0,0);
340
1c79356b
A
341 switch (so->so_proto->pr_domain->dom_family) {
342 case AF_INET:
343 /* set spidx in pcb */
9bccf70c 344 *error = ipsec4_setspidx_inpcb(m, sotoinpcb(so));
1c79356b
A
345 break;
346#if INET6
347 case AF_INET6:
348 /* set spidx in pcb */
9bccf70c 349 *error = ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
1c79356b
A
350 break;
351#endif
352 default:
353 panic("ipsec4_getpolicybysock: unsupported address family\n");
354 }
55e303ae
A
355 if (*error) {
356 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 1,*error,0,0,0);
9bccf70c 357 return NULL;
55e303ae 358 }
1c79356b
A
359
360 /* sanity check */
361 if (pcbsp == NULL)
362 panic("ipsec4_getpolicybysock: pcbsp is NULL.\n");
363
1c79356b
A
364 switch (dir) {
365 case IPSEC_DIR_INBOUND:
366 currsp = pcbsp->sp_in;
367 break;
368 case IPSEC_DIR_OUTBOUND:
369 currsp = pcbsp->sp_out;
370 break;
371 default:
372 panic("ipsec4_getpolicybysock: illegal direction.\n");
373 }
374
375 /* sanity check */
376 if (currsp == NULL)
377 panic("ipsec4_getpolicybysock: currsp is NULL.\n");
378
379 /* when privilieged socket */
380 if (pcbsp->priv) {
381 switch (currsp->policy) {
382 case IPSEC_POLICY_BYPASS:
2d21ac55 383 lck_mtx_lock(sadb_mutex);
1c79356b 384 currsp->refcnt++;
2d21ac55 385 lck_mtx_unlock(sadb_mutex);
1c79356b 386 *error = 0;
55e303ae 387 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 2,*error,0,0,0);
1c79356b
A
388 return currsp;
389
390 case IPSEC_POLICY_ENTRUST:
391 /* look for a policy in SPD */
392 kernsp = key_allocsp(&currsp->spidx, dir);
393
394 /* SP found */
395 if (kernsp != NULL) {
396 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
397 printf("DP ipsec4_getpolicybysock called "
398 "to allocate SP:%p\n", kernsp));
399 *error = 0;
55e303ae 400 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 3,*error,0,0,0);
1c79356b
A
401 return kernsp;
402 }
403
404 /* no SP found */
2d21ac55 405 lck_mtx_lock(sadb_mutex);
1c79356b
A
406 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
407 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
408 ipseclog((LOG_INFO,
409 "fixed system default policy: %d->%d\n",
410 ip4_def_policy.policy, IPSEC_POLICY_NONE));
411 ip4_def_policy.policy = IPSEC_POLICY_NONE;
412 }
413 ip4_def_policy.refcnt++;
2d21ac55 414 lck_mtx_unlock(sadb_mutex);
1c79356b 415 *error = 0;
55e303ae 416 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 4,*error,0,0,0);
1c79356b
A
417 return &ip4_def_policy;
418
419 case IPSEC_POLICY_IPSEC:
2d21ac55 420 lck_mtx_lock(sadb_mutex);
1c79356b 421 currsp->refcnt++;
2d21ac55 422 lck_mtx_unlock(sadb_mutex);
1c79356b 423 *error = 0;
55e303ae 424 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 5,*error,0,0,0);
1c79356b
A
425 return currsp;
426
427 default:
428 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
429 "Invalid policy for PCB %d\n", currsp->policy));
430 *error = EINVAL;
55e303ae 431 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 6,*error,0,0,0);
1c79356b
A
432 return NULL;
433 }
434 /* NOTREACHED */
435 }
436
437 /* when non-privilieged socket */
438 /* look for a policy in SPD */
439 kernsp = key_allocsp(&currsp->spidx, dir);
440
441 /* SP found */
442 if (kernsp != NULL) {
443 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
444 printf("DP ipsec4_getpolicybysock called "
445 "to allocate SP:%p\n", kernsp));
446 *error = 0;
55e303ae 447 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 7,*error,0,0,0);
1c79356b
A
448 return kernsp;
449 }
450
451 /* no SP found */
452 switch (currsp->policy) {
453 case IPSEC_POLICY_BYPASS:
454 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
455 "Illegal policy for non-priviliged defined %d\n",
456 currsp->policy));
457 *error = EINVAL;
55e303ae 458 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 8,*error,0,0,0);
1c79356b
A
459 return NULL;
460
461 case IPSEC_POLICY_ENTRUST:
2d21ac55 462 lck_mtx_lock(sadb_mutex);
1c79356b
A
463 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
464 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
465 ipseclog((LOG_INFO,
466 "fixed system default policy: %d->%d\n",
467 ip4_def_policy.policy, IPSEC_POLICY_NONE));
468 ip4_def_policy.policy = IPSEC_POLICY_NONE;
469 }
470 ip4_def_policy.refcnt++;
2d21ac55 471 lck_mtx_unlock(sadb_mutex);
1c79356b 472 *error = 0;
55e303ae 473 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 9,*error,0,0,0);
1c79356b
A
474 return &ip4_def_policy;
475
476 case IPSEC_POLICY_IPSEC:
2d21ac55 477 lck_mtx_lock(sadb_mutex);
1c79356b 478 currsp->refcnt++;
2d21ac55 479 lck_mtx_unlock(sadb_mutex);
1c79356b 480 *error = 0;
55e303ae 481 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 10,*error,0,0,0);
1c79356b
A
482 return currsp;
483
484 default:
485 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
486 "Invalid policy for PCB %d\n", currsp->policy));
487 *error = EINVAL;
55e303ae 488 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 11,*error,0,0,0);
1c79356b
A
489 return NULL;
490 }
491 /* NOTREACHED */
492}
493
494/*
495 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
496 * and return a pointer to SP.
497 * OUT: positive: a pointer to the entry for security policy leaf matched.
498 * NULL: no apropreate SP found, the following value is set to error.
499 * 0 : bypass
500 * EACCES : discard packet.
501 * ENOENT : ipsec_acquire() in progress, maybe.
91447636 502 * others : error occurred.
1c79356b
A
503 */
504struct secpolicy *
505ipsec4_getpolicybyaddr(m, dir, flag, error)
506 struct mbuf *m;
507 u_int dir;
508 int flag;
509 int *error;
510{
511 struct secpolicy *sp = NULL;
512
9bccf70c
A
513 if (ipsec_bypass != 0)
514 return 0;
515
2d21ac55
A
516 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
517
1c79356b
A
518 /* sanity check */
519 if (m == NULL || error == NULL)
520 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.\n");
521
522 {
523 struct secpolicyindex spidx;
524
55e303ae 525 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_START, 0,0,0,0,0);
1c79356b
A
526 bzero(&spidx, sizeof(spidx));
527
528 /* make a index to look for a policy */
9bccf70c
A
529 *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET, m,
530 (flag & IP_FORWARDING) ? 0 : 1);
1c79356b 531
55e303ae
A
532 if (*error != 0) {
533 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 1,*error,0,0,0);
1c79356b 534 return NULL;
55e303ae 535 }
1c79356b
A
536
537 sp = key_allocsp(&spidx, dir);
538 }
539
540 /* SP found */
541 if (sp != NULL) {
542 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
543 printf("DP ipsec4_getpolicybyaddr called "
544 "to allocate SP:%p\n", sp));
545 *error = 0;
55e303ae 546 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 2,*error,0,0,0);
1c79356b
A
547 return sp;
548 }
549
550 /* no SP found */
2d21ac55 551 lck_mtx_lock(sadb_mutex);
1c79356b
A
552 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
553 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
554 ipseclog((LOG_INFO, "fixed system default policy:%d->%d\n",
555 ip4_def_policy.policy,
556 IPSEC_POLICY_NONE));
557 ip4_def_policy.policy = IPSEC_POLICY_NONE;
558 }
559 ip4_def_policy.refcnt++;
2d21ac55 560 lck_mtx_unlock(sadb_mutex);
1c79356b 561 *error = 0;
55e303ae 562 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 3,*error,0,0,0);
1c79356b
A
563 return &ip4_def_policy;
564}
565
566#if INET6
567/*
568 * For OUTBOUND packet having a socket. Searching SPD for packet,
569 * and return a pointer to SP.
570 * OUT: NULL: no apropreate SP found, the following value is set to error.
571 * 0 : bypass
572 * EACCES : discard packet.
573 * ENOENT : ipsec_acquire() in progress, maybe.
91447636 574 * others : error occurred.
1c79356b
A
575 * others: a pointer to SP
576 */
577struct secpolicy *
578ipsec6_getpolicybysock(m, dir, so, error)
579 struct mbuf *m;
580 u_int dir;
581 struct socket *so;
582 int *error;
583{
584 struct inpcbpolicy *pcbsp = NULL;
585 struct secpolicy *currsp = NULL; /* policy on socket */
586 struct secpolicy *kernsp = NULL; /* policy on kernel */
587
2d21ac55
A
588 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
589
1c79356b
A
590 /* sanity check */
591 if (m == NULL || so == NULL || error == NULL)
592 panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
593
9bccf70c
A
594#if DIAGNOSTIC
595 if (so->so_proto->pr_domain->dom_family != AF_INET6)
596 panic("ipsec6_getpolicybysock: socket domain != inet6\n");
597#endif
1c79356b
A
598
599 pcbsp = sotoin6pcb(so)->in6p_sp;
9bccf70c
A
600
601 if (!pcbsp){
602 return ipsec6_getpolicybyaddr(m, dir, 0, error);
603 }
604
605 /* set spidx in pcb */
606 ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
1c79356b
A
607
608 /* sanity check */
609 if (pcbsp == NULL)
610 panic("ipsec6_getpolicybysock: pcbsp is NULL.\n");
611
612 switch (dir) {
613 case IPSEC_DIR_INBOUND:
614 currsp = pcbsp->sp_in;
615 break;
616 case IPSEC_DIR_OUTBOUND:
617 currsp = pcbsp->sp_out;
618 break;
619 default:
620 panic("ipsec6_getpolicybysock: illegal direction.\n");
621 }
622
623 /* sanity check */
624 if (currsp == NULL)
625 panic("ipsec6_getpolicybysock: currsp is NULL.\n");
626
627 /* when privilieged socket */
628 if (pcbsp->priv) {
629 switch (currsp->policy) {
630 case IPSEC_POLICY_BYPASS:
2d21ac55 631 lck_mtx_lock(sadb_mutex);
1c79356b 632 currsp->refcnt++;
2d21ac55 633 lck_mtx_unlock(sadb_mutex);
1c79356b
A
634 *error = 0;
635 return currsp;
636
637 case IPSEC_POLICY_ENTRUST:
638 /* look for a policy in SPD */
639 kernsp = key_allocsp(&currsp->spidx, dir);
640
641 /* SP found */
642 if (kernsp != NULL) {
643 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
644 printf("DP ipsec6_getpolicybysock called "
645 "to allocate SP:%p\n", kernsp));
646 *error = 0;
647 return kernsp;
648 }
649
650 /* no SP found */
2d21ac55 651 lck_mtx_lock(sadb_mutex);
1c79356b
A
652 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
653 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
654 ipseclog((LOG_INFO,
655 "fixed system default policy: %d->%d\n",
656 ip6_def_policy.policy, IPSEC_POLICY_NONE));
657 ip6_def_policy.policy = IPSEC_POLICY_NONE;
658 }
659 ip6_def_policy.refcnt++;
2d21ac55 660 lck_mtx_unlock(sadb_mutex);
1c79356b
A
661 *error = 0;
662 return &ip6_def_policy;
663
664 case IPSEC_POLICY_IPSEC:
2d21ac55 665 lck_mtx_lock(sadb_mutex);
1c79356b 666 currsp->refcnt++;
2d21ac55 667 lck_mtx_unlock(sadb_mutex);
1c79356b
A
668 *error = 0;
669 return currsp;
670
671 default:
672 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
673 "Invalid policy for PCB %d\n", currsp->policy));
674 *error = EINVAL;
675 return NULL;
676 }
677 /* NOTREACHED */
678 }
679
680 /* when non-privilieged socket */
681 /* look for a policy in SPD */
682 kernsp = key_allocsp(&currsp->spidx, dir);
683
684 /* SP found */
685 if (kernsp != NULL) {
686 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
687 printf("DP ipsec6_getpolicybysock called "
688 "to allocate SP:%p\n", kernsp));
689 *error = 0;
690 return kernsp;
691 }
692
693 /* no SP found */
694 switch (currsp->policy) {
695 case IPSEC_POLICY_BYPASS:
696 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
697 "Illegal policy for non-priviliged defined %d\n",
698 currsp->policy));
699 *error = EINVAL;
700 return NULL;
701
702 case IPSEC_POLICY_ENTRUST:
2d21ac55 703 lck_mtx_lock(sadb_mutex);
1c79356b
A
704 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
705 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
706 ipseclog((LOG_INFO,
707 "fixed system default policy: %d->%d\n",
708 ip6_def_policy.policy, IPSEC_POLICY_NONE));
709 ip6_def_policy.policy = IPSEC_POLICY_NONE;
710 }
711 ip6_def_policy.refcnt++;
2d21ac55 712 lck_mtx_unlock(sadb_mutex);
1c79356b
A
713 *error = 0;
714 return &ip6_def_policy;
715
716 case IPSEC_POLICY_IPSEC:
2d21ac55 717 lck_mtx_lock(sadb_mutex);
1c79356b 718 currsp->refcnt++;
2d21ac55 719 lck_mtx_unlock(sadb_mutex);
1c79356b
A
720 *error = 0;
721 return currsp;
722
723 default:
724 ipseclog((LOG_ERR,
725 "ipsec6_policybysock: Invalid policy for PCB %d\n",
726 currsp->policy));
727 *error = EINVAL;
728 return NULL;
729 }
730 /* NOTREACHED */
731}
732
733/*
734 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
735 * and return a pointer to SP.
736 * `flag' means that packet is to be forwarded whether or not.
737 * flag = 1: forwad
738 * OUT: positive: a pointer to the entry for security policy leaf matched.
739 * NULL: no apropreate SP found, the following value is set to error.
740 * 0 : bypass
741 * EACCES : discard packet.
742 * ENOENT : ipsec_acquire() in progress, maybe.
91447636 743 * others : error occurred.
1c79356b
A
744 */
745#ifndef IP_FORWARDING
746#define IP_FORWARDING 1
747#endif
748
749struct secpolicy *
750ipsec6_getpolicybyaddr(m, dir, flag, error)
751 struct mbuf *m;
752 u_int dir;
753 int flag;
754 int *error;
755{
756 struct secpolicy *sp = NULL;
757
2d21ac55
A
758 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
759
1c79356b
A
760 /* sanity check */
761 if (m == NULL || error == NULL)
762 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.\n");
763
764 {
765 struct secpolicyindex spidx;
766
767 bzero(&spidx, sizeof(spidx));
768
769 /* make a index to look for a policy */
9bccf70c
A
770 *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET6, m,
771 (flag & IP_FORWARDING) ? 0 : 1);
1c79356b
A
772
773 if (*error != 0)
774 return NULL;
775
776 sp = key_allocsp(&spidx, dir);
777 }
778
779 /* SP found */
780 if (sp != NULL) {
781 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
782 printf("DP ipsec6_getpolicybyaddr called "
783 "to allocate SP:%p\n", sp));
784 *error = 0;
785 return sp;
786 }
787
788 /* no SP found */
2d21ac55 789 lck_mtx_lock(sadb_mutex);
1c79356b
A
790 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
791 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
792 ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
793 ip6_def_policy.policy, IPSEC_POLICY_NONE));
794 ip6_def_policy.policy = IPSEC_POLICY_NONE;
795 }
796 ip6_def_policy.refcnt++;
2d21ac55 797 lck_mtx_unlock(sadb_mutex);
1c79356b
A
798 *error = 0;
799 return &ip6_def_policy;
800}
801#endif /* INET6 */
802
803/*
804 * set IP address into spidx from mbuf.
805 * When Forwarding packet and ICMP echo reply, this function is used.
806 *
807 * IN: get the followings from mbuf.
808 * protocol family, src, dst, next protocol
809 * OUT:
810 * 0: success.
811 * other: failure, and set errno.
812 */
813int
2d21ac55
A
814ipsec_setspidx_mbuf(
815 struct secpolicyindex *spidx,
816 u_int dir,
817 __unused u_int family,
818 struct mbuf *m,
819 int needport)
1c79356b 820{
9bccf70c 821 int error;
1c79356b
A
822
823 /* sanity check */
824 if (spidx == NULL || m == NULL)
825 panic("ipsec_setspidx_mbuf: NULL pointer was passed.\n");
826
1c79356b
A
827 bzero(spidx, sizeof(*spidx));
828
9bccf70c
A
829 error = ipsec_setspidx(m, spidx, needport);
830 if (error)
831 goto bad;
1c79356b 832 spidx->dir = dir;
1c79356b 833
9bccf70c 834 return 0;
1c79356b 835
9bccf70c
A
836 bad:
837 /* XXX initialize */
838 bzero(spidx, sizeof(*spidx));
839 return EINVAL;
840}
1c79356b 841
9bccf70c
A
842static int
843ipsec4_setspidx_inpcb(m, pcb)
844 struct mbuf *m;
845 struct inpcb *pcb;
846{
847 struct secpolicyindex *spidx;
848 int error;
1c79356b 849
9bccf70c
A
850 if (ipsec_bypass != 0)
851 return 0;
1c79356b 852
9bccf70c
A
853 /* sanity check */
854 if (pcb == NULL)
855 panic("ipsec4_setspidx_inpcb: no PCB found.\n");
856 if (pcb->inp_sp == NULL)
857 panic("ipsec4_setspidx_inpcb: no inp_sp found.\n");
858 if (pcb->inp_sp->sp_out == NULL || pcb->inp_sp->sp_in == NULL)
859 panic("ipsec4_setspidx_inpcb: no sp_in/out found.\n");
1c79356b 860
9bccf70c
A
861 bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
862 bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
1c79356b 863
9bccf70c
A
864 spidx = &pcb->inp_sp->sp_in->spidx;
865 error = ipsec_setspidx(m, spidx, 1);
866 if (error)
867 goto bad;
868 spidx->dir = IPSEC_DIR_INBOUND;
1c79356b 869
9bccf70c
A
870 spidx = &pcb->inp_sp->sp_out->spidx;
871 error = ipsec_setspidx(m, spidx, 1);
872 if (error)
873 goto bad;
874 spidx->dir = IPSEC_DIR_OUTBOUND;
1c79356b 875
9bccf70c 876 return 0;
1c79356b 877
9bccf70c
A
878bad:
879 bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
880 bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
881 return error;
882}
1c79356b 883
9bccf70c
A
884#if INET6
885static int
886ipsec6_setspidx_in6pcb(m, pcb)
887 struct mbuf *m;
888 struct in6pcb *pcb;
889{
890 struct secpolicyindex *spidx;
891 int error;
1c79356b 892
9bccf70c
A
893 /* sanity check */
894 if (pcb == NULL)
895 panic("ipsec6_setspidx_in6pcb: no PCB found.\n");
896 if (pcb->in6p_sp == NULL)
897 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.\n");
898 if (pcb->in6p_sp->sp_out == NULL || pcb->in6p_sp->sp_in == NULL)
899 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.\n");
1c79356b 900
9bccf70c
A
901 bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
902 bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
903
904 spidx = &pcb->in6p_sp->sp_in->spidx;
905 error = ipsec_setspidx(m, spidx, 1);
906 if (error)
907 goto bad;
908 spidx->dir = IPSEC_DIR_INBOUND;
1c79356b 909
55e303ae
A
910 spidx = &pcb->in6p_sp->sp_out->spidx;
911 error = ipsec_setspidx(m, spidx, 1);
912 if (error)
913 goto bad;
914 spidx->dir = IPSEC_DIR_OUTBOUND;
1c79356b
A
915
916 return 0;
917
9bccf70c
A
918bad:
919 bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
920 bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
921 return error;
1c79356b 922}
9bccf70c 923#endif
1c79356b 924
1c79356b 925/*
9bccf70c
A
926 * configure security policy index (src/dst/proto/sport/dport)
927 * by looking at the content of mbuf.
928 * the caller is responsible for error recovery (like clearing up spidx).
1c79356b 929 */
9bccf70c
A
930static int
931ipsec_setspidx(m, spidx, needport)
1c79356b
A
932 struct mbuf *m;
933 struct secpolicyindex *spidx;
9bccf70c 934 int needport;
1c79356b 935{
9bccf70c
A
936 struct ip *ip = NULL;
937 struct ip ipbuf;
938 u_int v;
939 struct mbuf *n;
940 int len;
941 int error;
1c79356b 942
1c79356b 943 if (m == NULL)
9bccf70c 944 panic("ipsec_setspidx: m == 0 passed.\n");
1c79356b 945
9bccf70c
A
946 /*
947 * validate m->m_pkthdr.len. we see incorrect length if we
948 * mistakenly call this function with inconsistent mbuf chain
949 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
950 */
951 len = 0;
952 for (n = m; n; n = n->m_next)
953 len += n->m_len;
954 if (m->m_pkthdr.len != len) {
955 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
956 printf("ipsec_setspidx: "
957 "total of m_len(%d) != pkthdr.len(%d), "
958 "ignored.\n",
959 len, m->m_pkthdr.len));
960 return EINVAL;
961 }
1c79356b 962
9bccf70c
A
963 if (m->m_pkthdr.len < sizeof(struct ip)) {
964 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
965 printf("ipsec_setspidx: "
966 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
967 m->m_pkthdr.len));
968 return EINVAL;
969 }
1c79356b 970
9bccf70c
A
971 if (m->m_len >= sizeof(*ip))
972 ip = mtod(m, struct ip *);
973 else {
974 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
975 ip = &ipbuf;
976 }
977#ifdef _IP_VHL
978 v = _IP_VHL_V(ip->ip_vhl);
979#else
980 v = ip->ip_v;
981#endif
982 switch (v) {
983 case 4:
984 error = ipsec4_setspidx_ipaddr(m, spidx);
985 if (error)
986 return error;
987 ipsec4_get_ulp(m, spidx, needport);
988 return 0;
2d21ac55 989#if INET6
9bccf70c
A
990 case 6:
991 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
992 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
993 printf("ipsec_setspidx: "
994 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
995 "ignored.\n", m->m_pkthdr.len));
996 return EINVAL;
1c79356b 997 }
9bccf70c
A
998 error = ipsec6_setspidx_ipaddr(m, spidx);
999 if (error)
1000 return error;
1001 ipsec6_get_ulp(m, spidx, needport);
1002 return 0;
1003#endif
1c79356b 1004 default:
9bccf70c
A
1005 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1006 printf("ipsec_setspidx: "
1007 "unknown IP version %u, ignored.\n", v));
1008 return EINVAL;
1c79356b
A
1009 }
1010}
1c79356b
A
1011
1012static void
9bccf70c 1013ipsec4_get_ulp(m, spidx, needport)
1c79356b 1014 struct mbuf *m;
1c79356b 1015 struct secpolicyindex *spidx;
9bccf70c
A
1016 int needport;
1017{
1018 struct ip ip;
1019 struct ip6_ext ip6e;
1020 u_int8_t nxt;
1021 int off;
1022 struct tcphdr th;
1023 struct udphdr uh;
1c79356b
A
1024
1025 /* sanity check */
9bccf70c
A
1026 if (m == NULL)
1027 panic("ipsec4_get_ulp: NULL pointer was passed.\n");
1028 if (m->m_pkthdr.len < sizeof(ip))
1029 panic("ipsec4_get_ulp: too short\n");
1c79356b 1030
9bccf70c
A
1031 /* set default */
1032 spidx->ul_proto = IPSEC_ULPROTO_ANY;
1033 ((struct sockaddr_in *)&spidx->src)->sin_port = IPSEC_PORT_ANY;
1034 ((struct sockaddr_in *)&spidx->dst)->sin_port = IPSEC_PORT_ANY;
1c79356b 1035
9bccf70c
A
1036 m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
1037 /* ip_input() flips it into host endian XXX need more checking */
1038 if (ip.ip_off & (IP_MF | IP_OFFMASK))
1039 return;
1c79356b 1040
9bccf70c
A
1041 nxt = ip.ip_p;
1042#ifdef _IP_VHL
1043 off = _IP_VHL_HL(ip->ip_vhl) << 2;
1044#else
1045 off = ip.ip_hl << 2;
1046#endif
1047 while (off < m->m_pkthdr.len) {
1048 switch (nxt) {
1049 case IPPROTO_TCP:
1050 spidx->ul_proto = nxt;
1051 if (!needport)
1052 return;
1053 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1054 return;
1055 m_copydata(m, off, sizeof(th), (caddr_t)&th);
1056 ((struct sockaddr_in *)&spidx->src)->sin_port =
1057 th.th_sport;
1058 ((struct sockaddr_in *)&spidx->dst)->sin_port =
1059 th.th_dport;
1060 return;
1061 case IPPROTO_UDP:
1062 spidx->ul_proto = nxt;
1063 if (!needport)
1064 return;
1065 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1066 return;
1067 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1068 ((struct sockaddr_in *)&spidx->src)->sin_port =
1069 uh.uh_sport;
1070 ((struct sockaddr_in *)&spidx->dst)->sin_port =
1071 uh.uh_dport;
1072 return;
1073 case IPPROTO_AH:
91447636 1074 if (off + sizeof(ip6e) > m->m_pkthdr.len)
9bccf70c
A
1075 return;
1076 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1077 off += (ip6e.ip6e_len + 2) << 2;
1078 nxt = ip6e.ip6e_nxt;
1079 break;
1080 case IPPROTO_ICMP:
1081 default:
1082 /* XXX intermediate headers??? */
1083 spidx->ul_proto = nxt;
1084 return;
1085 }
1086 }
1c79356b
A
1087}
1088
9bccf70c
A
1089/* assumes that m is sane */
1090static int
1c79356b
A
1091ipsec4_setspidx_ipaddr(m, spidx)
1092 struct mbuf *m;
1093 struct secpolicyindex *spidx;
1094{
1095 struct ip *ip = NULL;
1096 struct ip ipbuf;
9bccf70c 1097 struct sockaddr_in *sin;
1c79356b 1098
9bccf70c 1099 if (m->m_len >= sizeof(*ip))
1c79356b
A
1100 ip = mtod(m, struct ip *);
1101 else {
1102 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
1103 ip = &ipbuf;
1104 }
1105
9bccf70c
A
1106 sin = (struct sockaddr_in *)&spidx->src;
1107 bzero(sin, sizeof(*sin));
1108 sin->sin_family = AF_INET;
1109 sin->sin_len = sizeof(struct sockaddr_in);
1110 bcopy(&ip->ip_src, &sin->sin_addr, sizeof(ip->ip_src));
1111 spidx->prefs = sizeof(struct in_addr) << 3;
1c79356b 1112
9bccf70c
A
1113 sin = (struct sockaddr_in *)&spidx->dst;
1114 bzero(sin, sizeof(*sin));
1115 sin->sin_family = AF_INET;
1116 sin->sin_len = sizeof(struct sockaddr_in);
1117 bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst));
1118 spidx->prefd = sizeof(struct in_addr) << 3;
1119 return 0;
1c79356b
A
1120}
1121
1122#if INET6
1123static void
9bccf70c 1124ipsec6_get_ulp(m, spidx, needport)
1c79356b 1125 struct mbuf *m;
1c79356b 1126 struct secpolicyindex *spidx;
9bccf70c
A
1127 int needport;
1128{
1129 int off, nxt;
1130 struct tcphdr th;
1131 struct udphdr uh;
1c79356b
A
1132
1133 /* sanity check */
9bccf70c
A
1134 if (m == NULL)
1135 panic("ipsec6_get_ulp: NULL pointer was passed.\n");
1c79356b 1136
9bccf70c
A
1137 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1138 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
1c79356b 1139
9bccf70c
A
1140 /* set default */
1141 spidx->ul_proto = IPSEC_ULPROTO_ANY;
1142 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
1143 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
1c79356b 1144
9bccf70c
A
1145 nxt = -1;
1146 off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
1147 if (off < 0 || m->m_pkthdr.len < off)
1148 return;
1149
1150 switch (nxt) {
1151 case IPPROTO_TCP:
1152 spidx->ul_proto = nxt;
1153 if (!needport)
1154 break;
1155 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1156 break;
1157 m_copydata(m, off, sizeof(th), (caddr_t)&th);
1158 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
1159 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
1160 break;
1161 case IPPROTO_UDP:
1162 spidx->ul_proto = nxt;
1163 if (!needport)
1164 break;
1165 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1166 break;
1167 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1168 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
1169 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
1170 break;
1171 case IPPROTO_ICMPV6:
1172 default:
1173 /* XXX intermediate headers??? */
1174 spidx->ul_proto = nxt;
1175 break;
1176 }
1c79356b
A
1177}
1178
9bccf70c
A
1179/* assumes that m is sane */
1180static int
1c79356b
A
1181ipsec6_setspidx_ipaddr(m, spidx)
1182 struct mbuf *m;
1183 struct secpolicyindex *spidx;
1184{
1185 struct ip6_hdr *ip6 = NULL;
1186 struct ip6_hdr ip6buf;
9bccf70c 1187 struct sockaddr_in6 *sin6;
1c79356b
A
1188
1189 if (m->m_len >= sizeof(*ip6))
1190 ip6 = mtod(m, struct ip6_hdr *);
1191 else {
1192 m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
1193 ip6 = &ip6buf;
1194 }
1195
9bccf70c
A
1196 sin6 = (struct sockaddr_in6 *)&spidx->src;
1197 bzero(sin6, sizeof(*sin6));
1198 sin6->sin6_family = AF_INET6;
1199 sin6->sin6_len = sizeof(struct sockaddr_in6);
1200 bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
1201 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
1202 sin6->sin6_addr.s6_addr16[1] = 0;
1203 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
1c79356b 1204 }
9bccf70c 1205 spidx->prefs = sizeof(struct in6_addr) << 3;
1c79356b 1206
9bccf70c
A
1207 sin6 = (struct sockaddr_in6 *)&spidx->dst;
1208 bzero(sin6, sizeof(*sin6));
1209 sin6->sin6_family = AF_INET6;
1210 sin6->sin6_len = sizeof(struct sockaddr_in6);
1211 bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
1212 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
1213 sin6->sin6_addr.s6_addr16[1] = 0;
1214 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
1215 }
1216 spidx->prefd = sizeof(struct in6_addr) << 3;
1c79356b 1217
9bccf70c 1218 return 0;
1c79356b
A
1219}
1220#endif
1221
1222static struct inpcbpolicy *
1223ipsec_newpcbpolicy()
1224{
1225 struct inpcbpolicy *p;
1226
0b4e3aa0 1227 p = (struct inpcbpolicy *)_MALLOC(sizeof(*p), M_SECA, M_WAITOK);
1c79356b
A
1228 return p;
1229}
1230
1231static void
1232ipsec_delpcbpolicy(p)
1233 struct inpcbpolicy *p;
1234{
9bccf70c 1235 FREE(p, M_SECA);
1c79356b
A
1236}
1237
1238/* initialize policy in PCB */
1239int
1240ipsec_init_policy(so, pcb_sp)
1241 struct socket *so;
1242 struct inpcbpolicy **pcb_sp;
1243{
1244 struct inpcbpolicy *new;
1245
1246 /* sanity check. */
1247 if (so == NULL || pcb_sp == NULL)
1248 panic("ipsec_init_policy: NULL pointer was passed.\n");
1249
1250 new = ipsec_newpcbpolicy();
1251 if (new == NULL) {
1252 ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
1253 return ENOBUFS;
1254 }
9bccf70c
A
1255 bzero(new, sizeof(*new));
1256
1257#ifdef __APPLE__
316670eb 1258 if (kauth_cred_issuser(so->so_cred))
9bccf70c 1259#else
91447636 1260 if (so->so_cred != 0 && !suser(so->so_cred->pc_ucred, NULL))
9bccf70c 1261#endif
1c79356b
A
1262 new->priv = 1;
1263 else
1264 new->priv = 0;
1265
1c79356b
A
1266 if ((new->sp_in = key_newsp()) == NULL) {
1267 ipsec_delpcbpolicy(new);
1268 return ENOBUFS;
1269 }
1270 new->sp_in->state = IPSEC_SPSTATE_ALIVE;
1271 new->sp_in->policy = IPSEC_POLICY_ENTRUST;
1272
1273 if ((new->sp_out = key_newsp()) == NULL) {
2d21ac55 1274 key_freesp(new->sp_in, KEY_SADB_UNLOCKED);
1c79356b
A
1275 ipsec_delpcbpolicy(new);
1276 return ENOBUFS;
1277 }
1278 new->sp_out->state = IPSEC_SPSTATE_ALIVE;
1279 new->sp_out->policy = IPSEC_POLICY_ENTRUST;
1280
1281 *pcb_sp = new;
1282
1283 return 0;
1284}
1285
1286/* copy old ipsec policy into new */
1287int
1288ipsec_copy_policy(old, new)
1289 struct inpcbpolicy *old, *new;
1290{
1291 struct secpolicy *sp;
1292
9bccf70c
A
1293 if (ipsec_bypass != 0)
1294 return 0;
1295
1c79356b
A
1296 sp = ipsec_deepcopy_policy(old->sp_in);
1297 if (sp) {
2d21ac55 1298 key_freesp(new->sp_in, KEY_SADB_UNLOCKED);
1c79356b
A
1299 new->sp_in = sp;
1300 } else
1301 return ENOBUFS;
1302
1303 sp = ipsec_deepcopy_policy(old->sp_out);
1304 if (sp) {
2d21ac55 1305 key_freesp(new->sp_out, KEY_SADB_UNLOCKED);
1c79356b
A
1306 new->sp_out = sp;
1307 } else
1308 return ENOBUFS;
1309
1310 new->priv = old->priv;
1311
1312 return 0;
1313}
1314
1315/* deep-copy a policy in PCB */
1316static struct secpolicy *
1317ipsec_deepcopy_policy(src)
1318 struct secpolicy *src;
1319{
1320 struct ipsecrequest *newchain = NULL;
1321 struct ipsecrequest *p;
1322 struct ipsecrequest **q;
1323 struct ipsecrequest *r;
1324 struct secpolicy *dst;
1325
2d21ac55
A
1326 if (src == NULL)
1327 return NULL;
1c79356b 1328 dst = key_newsp();
2d21ac55 1329 if (dst == NULL)
1c79356b
A
1330 return NULL;
1331
1332 /*
1333 * deep-copy IPsec request chain. This is required since struct
1334 * ipsecrequest is not reference counted.
1335 */
1336 q = &newchain;
1337 for (p = src->req; p; p = p->next) {
1338 *q = (struct ipsecrequest *)_MALLOC(sizeof(struct ipsecrequest),
0b4e3aa0 1339 M_SECA, M_WAITOK);
1c79356b
A
1340 if (*q == NULL)
1341 goto fail;
1342 bzero(*q, sizeof(**q));
1343 (*q)->next = NULL;
1344
1345 (*q)->saidx.proto = p->saidx.proto;
1346 (*q)->saidx.mode = p->saidx.mode;
1347 (*q)->level = p->level;
1348 (*q)->saidx.reqid = p->saidx.reqid;
1349
1350 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
1351 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
1352
1c79356b
A
1353 (*q)->sp = dst;
1354
1355 q = &((*q)->next);
1356 }
1357
1358 dst->req = newchain;
1359 dst->state = src->state;
1360 dst->policy = src->policy;
1361 /* do not touch the refcnt fields */
1362
1363 return dst;
1364
1365fail:
1366 for (p = newchain; p; p = r) {
1367 r = p->next;
9bccf70c 1368 FREE(p, M_SECA);
1c79356b
A
1369 p = NULL;
1370 }
2d21ac55 1371 key_freesp(dst, KEY_SADB_UNLOCKED);
1c79356b
A
1372 return NULL;
1373}
1374
1375/* set policy and ipsec request if present. */
1376static int
2d21ac55
A
1377ipsec_set_policy(
1378 struct secpolicy **pcb_sp,
1379 __unused int optname,
1380 caddr_t request,
1381 size_t len,
1382 int priv)
1c79356b
A
1383{
1384 struct sadb_x_policy *xpl;
1385 struct secpolicy *newsp = NULL;
1386 int error;
1387
1388 /* sanity check. */
1389 if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
1390 return EINVAL;
1391 if (len < sizeof(*xpl))
1392 return EINVAL;
316670eb 1393 xpl = (struct sadb_x_policy *)(void *)request;
1c79356b
A
1394
1395 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1396 printf("ipsec_set_policy: passed policy\n");
1397 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1398
1399 /* check policy type */
1400 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1401 if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
1402 || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1403 return EINVAL;
1404
1405 /* check privileged socket */
1406 if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
1407 return EACCES;
1408
1409 /* allocation new SP entry */
1410 if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1411 return error;
1412
1413 newsp->state = IPSEC_SPSTATE_ALIVE;
1414
1415 /* clear old SP and set new SP */
2d21ac55 1416 key_freesp(*pcb_sp, KEY_SADB_UNLOCKED);
1c79356b
A
1417 *pcb_sp = newsp;
1418 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1419 printf("ipsec_set_policy: new policy\n");
1420 kdebug_secpolicy(newsp));
1421
1422 return 0;
1423}
1424
1425static int
1426ipsec_get_policy(pcb_sp, mp)
1427 struct secpolicy *pcb_sp;
1428 struct mbuf **mp;
1429{
1430
91447636 1431
1c79356b
A
1432 /* sanity check. */
1433 if (pcb_sp == NULL || mp == NULL)
1434 return EINVAL;
1435
1436 *mp = key_sp2msg(pcb_sp);
1437 if (!*mp) {
1438 ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
1439 return ENOBUFS;
1440 }
1441
2d21ac55 1442 m_mchtype(*mp, MT_DATA);
1c79356b
A
1443 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1444 printf("ipsec_get_policy:\n");
1445 kdebug_mbuf(*mp));
1446
1447 return 0;
1448}
1449
1450int
1451ipsec4_set_policy(inp, optname, request, len, priv)
1452 struct inpcb *inp;
1453 int optname;
1454 caddr_t request;
1455 size_t len;
1456 int priv;
1457{
1458 struct sadb_x_policy *xpl;
1459 struct secpolicy **pcb_sp;
9bccf70c 1460 int error = 0;
316670eb
A
1461 struct sadb_x_policy xpl_aligned_buf;
1462 u_int8_t *xpl_unaligned;
1c79356b
A
1463
1464 /* sanity check. */
1465 if (inp == NULL || request == NULL)
1466 return EINVAL;
1467 if (len < sizeof(*xpl))
1468 return EINVAL;
316670eb
A
1469 xpl = (struct sadb_x_policy *)(void *)request;
1470
1471 /* This is a new mbuf allocated by soopt_getm() */
1472 if (IPSEC_IS_P2ALIGNED(xpl)) {
1473 xpl_unaligned = NULL;
1474 } else {
1475 xpl_unaligned = (__typeof__(xpl_unaligned))xpl;
1476 memcpy(&xpl_aligned_buf, xpl, sizeof(xpl_aligned_buf));
1477 xpl = (__typeof__(xpl))&xpl_aligned_buf;
1478 }
1c79356b 1479
9bccf70c
A
1480 if (inp->inp_sp == NULL) {
1481 error = ipsec_init_policy(inp->inp_socket, &inp->inp_sp);
1482 if (error)
1483 return error;
1484 }
1485
1c79356b
A
1486 /* select direction */
1487 switch (xpl->sadb_x_policy_dir) {
1488 case IPSEC_DIR_INBOUND:
1489 pcb_sp = &inp->inp_sp->sp_in;
1490 break;
1491 case IPSEC_DIR_OUTBOUND:
1492 pcb_sp = &inp->inp_sp->sp_out;
1493 break;
1494 default:
1495 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1496 xpl->sadb_x_policy_dir));
1497 return EINVAL;
1498 }
1499
9bccf70c
A
1500 /* turn bypass off */
1501 if (ipsec_bypass != 0)
1502 ipsec_bypass = 0;
1503
1c79356b
A
1504 return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1505}
1506
1507int
1508ipsec4_get_policy(inp, request, len, mp)
1509 struct inpcb *inp;
1510 caddr_t request;
1511 size_t len;
1512 struct mbuf **mp;
1513{
1514 struct sadb_x_policy *xpl;
1515 struct secpolicy *pcb_sp;
9bccf70c 1516 int error = 0;
316670eb
A
1517 struct sadb_x_policy xpl_aligned_buf;
1518 u_int8_t *xpl_unaligned;
1c79356b 1519
2d21ac55 1520 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
91447636 1521
1c79356b
A
1522 /* sanity check. */
1523 if (inp == NULL || request == NULL || mp == NULL)
1524 return EINVAL;
1c79356b
A
1525 if (len < sizeof(*xpl))
1526 return EINVAL;
316670eb
A
1527 xpl = (struct sadb_x_policy *)(void *)request;
1528
1529 /* This is a new mbuf allocated by soopt_getm() */
1530 if (IPSEC_IS_P2ALIGNED(xpl)) {
1531 xpl_unaligned = NULL;
1532 } else {
1533 xpl_unaligned = (__typeof__(xpl_unaligned))xpl;
1534 memcpy(&xpl_aligned_buf, xpl, sizeof(xpl_aligned_buf));
1535 xpl = (__typeof__(xpl))&xpl_aligned_buf;
1536 }
1537
9bccf70c
A
1538 if (inp->inp_sp == NULL) {
1539 error = ipsec_init_policy(inp->inp_socket, &inp->inp_sp);
1540 if (error)
1541 return error;
1542 }
1c79356b
A
1543
1544 /* select direction */
1545 switch (xpl->sadb_x_policy_dir) {
1546 case IPSEC_DIR_INBOUND:
1547 pcb_sp = inp->inp_sp->sp_in;
1548 break;
1549 case IPSEC_DIR_OUTBOUND:
1550 pcb_sp = inp->inp_sp->sp_out;
1551 break;
1552 default:
1553 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1554 xpl->sadb_x_policy_dir));
1555 return EINVAL;
1556 }
1557
1558 return ipsec_get_policy(pcb_sp, mp);
1559}
1560
1561/* delete policy in PCB */
1562int
1563ipsec4_delete_pcbpolicy(inp)
1564 struct inpcb *inp;
1565{
91447636 1566
1c79356b
A
1567 /* sanity check. */
1568 if (inp == NULL)
1569 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n");
1570
1571 if (inp->inp_sp == NULL)
1572 return 0;
1573
1574 if (inp->inp_sp->sp_in != NULL) {
2d21ac55 1575 key_freesp(inp->inp_sp->sp_in, KEY_SADB_UNLOCKED);
1c79356b
A
1576 inp->inp_sp->sp_in = NULL;
1577 }
1578
1579 if (inp->inp_sp->sp_out != NULL) {
2d21ac55 1580 key_freesp(inp->inp_sp->sp_out, KEY_SADB_UNLOCKED);
1c79356b
A
1581 inp->inp_sp->sp_out = NULL;
1582 }
1583
1584 ipsec_delpcbpolicy(inp->inp_sp);
1585 inp->inp_sp = NULL;
1586
1587 return 0;
1588}
1589
1590#if INET6
1591int
1592ipsec6_set_policy(in6p, optname, request, len, priv)
1593 struct in6pcb *in6p;
1594 int optname;
1595 caddr_t request;
1596 size_t len;
1597 int priv;
1598{
1599 struct sadb_x_policy *xpl;
1600 struct secpolicy **pcb_sp;
9bccf70c 1601 int error = 0;
316670eb
A
1602 struct sadb_x_policy xpl_aligned_buf;
1603 u_int8_t *xpl_unaligned;
1c79356b
A
1604
1605 /* sanity check. */
1606 if (in6p == NULL || request == NULL)
1607 return EINVAL;
1608 if (len < sizeof(*xpl))
1609 return EINVAL;
316670eb
A
1610 xpl = (struct sadb_x_policy *)(void *)request;
1611
1612 /* This is a new mbuf allocated by soopt_getm() */
1613 if (IPSEC_IS_P2ALIGNED(xpl)) {
1614 xpl_unaligned = NULL;
1615 } else {
1616 xpl_unaligned = (__typeof__(xpl_unaligned))xpl;
1617 memcpy(&xpl_aligned_buf, xpl, sizeof(xpl_aligned_buf));
1618 xpl = (__typeof__(xpl))&xpl_aligned_buf;
1619 }
1620
9bccf70c
A
1621 if (in6p->in6p_sp == NULL) {
1622 error = ipsec_init_policy(in6p->inp_socket, &in6p->in6p_sp);
1623 if (error)
1624 return error;
1625 }
1c79356b
A
1626
1627 /* select direction */
1628 switch (xpl->sadb_x_policy_dir) {
1629 case IPSEC_DIR_INBOUND:
1630 pcb_sp = &in6p->in6p_sp->sp_in;
1631 break;
1632 case IPSEC_DIR_OUTBOUND:
1633 pcb_sp = &in6p->in6p_sp->sp_out;
1634 break;
1635 default:
1636 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1637 xpl->sadb_x_policy_dir));
1638 return EINVAL;
1639 }
1640
9bccf70c
A
1641 /* turn bypass off */
1642 if (ipsec_bypass != 0)
1643 ipsec_bypass = 0;
1644
1c79356b
A
1645 return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1646}
1647
1648int
1649ipsec6_get_policy(in6p, request, len, mp)
1650 struct in6pcb *in6p;
1651 caddr_t request;
1652 size_t len;
1653 struct mbuf **mp;
1654{
1655 struct sadb_x_policy *xpl;
1656 struct secpolicy *pcb_sp;
9bccf70c 1657 int error = 0;
316670eb
A
1658 struct sadb_x_policy xpl_aligned_buf;
1659 u_int8_t *xpl_unaligned;
1c79356b
A
1660
1661 /* sanity check. */
1662 if (in6p == NULL || request == NULL || mp == NULL)
1663 return EINVAL;
1c79356b
A
1664 if (len < sizeof(*xpl))
1665 return EINVAL;
316670eb
A
1666 xpl = (struct sadb_x_policy *)(void *)request;
1667
1668 /* This is a new mbuf allocated by soopt_getm() */
1669 if (IPSEC_IS_P2ALIGNED(xpl)) {
1670 xpl_unaligned = NULL;
1671 } else {
1672 xpl_unaligned = (__typeof__(xpl_unaligned))xpl;
1673 memcpy(&xpl_aligned_buf, xpl, sizeof(xpl_aligned_buf));
1674 xpl = (__typeof__(xpl))&xpl_aligned_buf;
1675 }
1676
9bccf70c
A
1677 if (in6p->in6p_sp == NULL) {
1678 error = ipsec_init_policy(in6p->inp_socket, &in6p->in6p_sp);
1679 if (error)
1680 return error;
1681 }
1c79356b
A
1682
1683 /* select direction */
1684 switch (xpl->sadb_x_policy_dir) {
1685 case IPSEC_DIR_INBOUND:
1686 pcb_sp = in6p->in6p_sp->sp_in;
1687 break;
1688 case IPSEC_DIR_OUTBOUND:
1689 pcb_sp = in6p->in6p_sp->sp_out;
1690 break;
1691 default:
1692 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1693 xpl->sadb_x_policy_dir));
1694 return EINVAL;
1695 }
1696
1697 return ipsec_get_policy(pcb_sp, mp);
1698}
1699
1700int
1701ipsec6_delete_pcbpolicy(in6p)
1702 struct in6pcb *in6p;
1703{
91447636 1704
1c79356b
A
1705 /* sanity check. */
1706 if (in6p == NULL)
1707 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n");
1708
1709 if (in6p->in6p_sp == NULL)
1710 return 0;
1711
1712 if (in6p->in6p_sp->sp_in != NULL) {
2d21ac55 1713 key_freesp(in6p->in6p_sp->sp_in, KEY_SADB_UNLOCKED);
1c79356b
A
1714 in6p->in6p_sp->sp_in = NULL;
1715 }
1716
1717 if (in6p->in6p_sp->sp_out != NULL) {
2d21ac55 1718 key_freesp(in6p->in6p_sp->sp_out, KEY_SADB_UNLOCKED);
1c79356b
A
1719 in6p->in6p_sp->sp_out = NULL;
1720 }
1721
1722 ipsec_delpcbpolicy(in6p->in6p_sp);
1723 in6p->in6p_sp = NULL;
1724
1725 return 0;
1726}
1727#endif
1728
1729/*
1730 * return current level.
1731 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1732 */
1733u_int
1734ipsec_get_reqlevel(isr)
1735 struct ipsecrequest *isr;
1736{
1737 u_int level = 0;
2d21ac55 1738 u_int esp_trans_deflev = 0, esp_net_deflev = 0, ah_trans_deflev = 0, ah_net_deflev = 0;
91447636 1739
1c79356b
A
1740 /* sanity check */
1741 if (isr == NULL || isr->sp == NULL)
1742 panic("ipsec_get_reqlevel: NULL pointer is passed.\n");
1743 if (((struct sockaddr *)&isr->sp->spidx.src)->sa_family
1744 != ((struct sockaddr *)&isr->sp->spidx.dst)->sa_family)
1745 panic("ipsec_get_reqlevel: family mismatched.\n");
1746
1747/* XXX note that we have ipseclog() expanded here - code sync issue */
1748#define IPSEC_CHECK_DEFAULT(lev) \
1749 (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1750 && (lev) != IPSEC_LEVEL_UNIQUE) \
1751 ? (ipsec_debug \
1752 ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1753 (lev), IPSEC_LEVEL_REQUIRE) \
6d2010ae 1754 : (void)0), \
1c79356b
A
1755 (lev) = IPSEC_LEVEL_REQUIRE, \
1756 (lev) \
1757 : (lev))
1758
1759 /* set default level */
1760 switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
1761#if INET
1762 case AF_INET:
1763 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1764 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1765 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1766 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1767 break;
1768#endif
1769#if INET6
1770 case AF_INET6:
1771 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1772 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1773 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1774 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1775 break;
1776#endif /* INET6 */
1777 default:
1778 panic("key_get_reqlevel: Unknown family. %d\n",
1779 ((struct sockaddr *)&isr->sp->spidx.src)->sa_family);
1780 }
1781
9bccf70c 1782#undef IPSEC_CHECK_DEFAULT
1c79356b
A
1783
1784 /* set level */
1785 switch (isr->level) {
1786 case IPSEC_LEVEL_DEFAULT:
1787 switch (isr->saidx.proto) {
1788 case IPPROTO_ESP:
1789 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1790 level = esp_net_deflev;
1791 else
1792 level = esp_trans_deflev;
1793 break;
1794 case IPPROTO_AH:
1795 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1796 level = ah_net_deflev;
1797 else
1798 level = ah_trans_deflev;
91447636 1799 break;
1c79356b
A
1800 case IPPROTO_IPCOMP:
1801 /*
1802 * we don't really care, as IPcomp document says that
1803 * we shouldn't compress small packets
1804 */
1805 level = IPSEC_LEVEL_USE;
1806 break;
1807 default:
1808 panic("ipsec_get_reqlevel: "
1809 "Illegal protocol defined %u\n",
1810 isr->saidx.proto);
1811 }
1812 break;
1813
1814 case IPSEC_LEVEL_USE:
1815 case IPSEC_LEVEL_REQUIRE:
1816 level = isr->level;
1817 break;
1818 case IPSEC_LEVEL_UNIQUE:
1819 level = IPSEC_LEVEL_REQUIRE;
1820 break;
1821
1822 default:
1823 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
1824 isr->level);
1825 }
1826
1827 return level;
1828}
1829
1830/*
1831 * Check AH/ESP integrity.
1832 * OUT:
1833 * 0: valid
1834 * 1: invalid
1835 */
1836static int
1837ipsec_in_reject(sp, m)
1838 struct secpolicy *sp;
1839 struct mbuf *m;
1840{
1841 struct ipsecrequest *isr;
1842 u_int level;
1843 int need_auth, need_conf, need_icv;
1844
1845 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1846 printf("ipsec_in_reject: using SP\n");
1847 kdebug_secpolicy(sp));
1848
1849 /* check policy */
1850 switch (sp->policy) {
1851 case IPSEC_POLICY_DISCARD:
2d21ac55 1852 case IPSEC_POLICY_GENERATE:
1c79356b
A
1853 return 1;
1854 case IPSEC_POLICY_BYPASS:
1855 case IPSEC_POLICY_NONE:
1856 return 0;
1857
1858 case IPSEC_POLICY_IPSEC:
1859 break;
1860
1861 case IPSEC_POLICY_ENTRUST:
1862 default:
1863 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp->policy);
1864 }
1865
1866 need_auth = 0;
1867 need_conf = 0;
1868 need_icv = 0;
1869
9bccf70c
A
1870 /* XXX should compare policy against ipsec header history */
1871
1c79356b
A
1872 for (isr = sp->req; isr != NULL; isr = isr->next) {
1873
1874 /* get current level */
1875 level = ipsec_get_reqlevel(isr);
1876
1877 switch (isr->saidx.proto) {
1878 case IPPROTO_ESP:
1879 if (level == IPSEC_LEVEL_REQUIRE) {
1880 need_conf++;
1881
2d21ac55
A
1882#if 0
1883 /* this won't work with multiple input threads - isr->sav would change
1884 * with every packet and is not necessarily related to the current packet
1885 * being processed. If ESP processing is required - the esp code should
1886 * make sure that the integrity check is present and correct. I don't see
1887 * why it would be necessary to check for the presence of the integrity
1888 * check value here. I think this is just wrong.
1889 * isr->sav has been removed.
1890 * %%%%%% this needs to be re-worked at some point but I think the code below can
1891 * be ignored for now.
1892 */
1c79356b
A
1893 if (isr->sav != NULL
1894 && isr->sav->flags == SADB_X_EXT_NONE
1895 && isr->sav->alg_auth != SADB_AALG_NONE)
1896 need_icv++;
2d21ac55 1897#endif
1c79356b
A
1898 }
1899 break;
1900 case IPPROTO_AH:
1901 if (level == IPSEC_LEVEL_REQUIRE) {
1902 need_auth++;
1903 need_icv++;
1904 }
1905 break;
1906 case IPPROTO_IPCOMP:
1907 /*
1908 * we don't really care, as IPcomp document says that
9bccf70c
A
1909 * we shouldn't compress small packets, IPComp policy
1910 * should always be treated as being in "use" level.
1c79356b
A
1911 */
1912 break;
1913 }
1914 }
1915
1916 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1917 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1918 need_auth, need_conf, need_icv, m->m_flags));
1919
1920 if ((need_conf && !(m->m_flags & M_DECRYPTED))
1921 || (!need_auth && need_icv && !(m->m_flags & M_AUTHIPDGM))
1922 || (need_auth && !(m->m_flags & M_AUTHIPHDR)))
1923 return 1;
1924
1925 return 0;
1926}
1927
1928/*
1929 * Check AH/ESP integrity.
1930 * This function is called from tcp_input(), udp_input(),
1931 * and {ah,esp}4_input for tunnel mode
1932 */
1933int
1934ipsec4_in_reject_so(m, so)
1935 struct mbuf *m;
1936 struct socket *so;
1937{
1938 struct secpolicy *sp = NULL;
1939 int error;
1940 int result;
1941
2d21ac55 1942 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
1943 /* sanity check */
1944 if (m == NULL)
1945 return 0; /* XXX should be panic ? */
1946
1947 /* get SP for this packet.
1948 * When we are called from ip_forward(), we call
1949 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1950 */
1951 if (so == NULL)
1952 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1953 else
1954 sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1955
1956 if (sp == NULL)
1957 return 0; /* XXX should be panic ?
1958 * -> No, there may be error. */
1959
1960 result = ipsec_in_reject(sp, m);
1961 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1962 printf("DP ipsec4_in_reject_so call free SP:%p\n", sp));
2d21ac55 1963 key_freesp(sp, KEY_SADB_UNLOCKED);
1c79356b
A
1964
1965 return result;
1966}
1967
1968int
1969ipsec4_in_reject(m, inp)
1970 struct mbuf *m;
1971 struct inpcb *inp;
1972{
2d21ac55
A
1973
1974 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
1975 if (inp == NULL)
1976 return ipsec4_in_reject_so(m, NULL);
9bccf70c
A
1977 if (inp->inp_socket)
1978 return ipsec4_in_reject_so(m, inp->inp_socket);
1979 else
1980 panic("ipsec4_in_reject: invalid inpcb/socket");
91447636
A
1981
1982 /* NOTREACHED */
1983 return 0;
1c79356b
A
1984}
1985
1986#if INET6
1987/*
1988 * Check AH/ESP integrity.
1989 * This function is called from tcp6_input(), udp6_input(),
1990 * and {ah,esp}6_input for tunnel mode
1991 */
1992int
1993ipsec6_in_reject_so(m, so)
1994 struct mbuf *m;
1995 struct socket *so;
1996{
1997 struct secpolicy *sp = NULL;
1998 int error;
1999 int result;
2000
2d21ac55 2001 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
2002 /* sanity check */
2003 if (m == NULL)
2004 return 0; /* XXX should be panic ? */
2005
2006 /* get SP for this packet.
2007 * When we are called from ip_forward(), we call
2008 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
2009 */
2010 if (so == NULL)
2011 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
2012 else
2013 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
2014
2015 if (sp == NULL)
2016 return 0; /* XXX should be panic ? */
2017
2018 result = ipsec_in_reject(sp, m);
2019 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2020 printf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
2d21ac55 2021 key_freesp(sp, KEY_SADB_UNLOCKED);
1c79356b
A
2022
2023 return result;
2024}
2025
2026int
2027ipsec6_in_reject(m, in6p)
2028 struct mbuf *m;
2029 struct in6pcb *in6p;
2030{
91447636 2031
2d21ac55 2032 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
2033 if (in6p == NULL)
2034 return ipsec6_in_reject_so(m, NULL);
9bccf70c
A
2035 if (in6p->in6p_socket)
2036 return ipsec6_in_reject_so(m, in6p->in6p_socket);
2037 else
2038 panic("ipsec6_in_reject: invalid in6p/socket");
91447636
A
2039
2040 /* NOTREACHED */
2041 return 0;
1c79356b
A
2042}
2043#endif
2044
2045/*
2046 * compute the byte size to be occupied by IPsec header.
2047 * in case it is tunneled, it includes the size of outer IP header.
2048 * NOTE: SP passed is free in this function.
2049 */
2d21ac55 2050size_t
1c79356b
A
2051ipsec_hdrsiz(sp)
2052 struct secpolicy *sp;
2053{
2054 struct ipsecrequest *isr;
2055 size_t siz, clen;
2056
2d21ac55 2057 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b 2058 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
55e303ae 2059 printf("ipsec_hdrsiz: using SP\n");
1c79356b
A
2060 kdebug_secpolicy(sp));
2061
2062 /* check policy */
2063 switch (sp->policy) {
2064 case IPSEC_POLICY_DISCARD:
2d21ac55 2065 case IPSEC_POLICY_GENERATE:
1c79356b
A
2066 case IPSEC_POLICY_BYPASS:
2067 case IPSEC_POLICY_NONE:
2068 return 0;
2069
2070 case IPSEC_POLICY_IPSEC:
2071 break;
2072
2073 case IPSEC_POLICY_ENTRUST:
2074 default:
2075 panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp->policy);
2076 }
2077
2078 siz = 0;
2079
2080 for (isr = sp->req; isr != NULL; isr = isr->next) {
2081
2082 clen = 0;
2083
2084 switch (isr->saidx.proto) {
2085 case IPPROTO_ESP:
2086#if IPSEC_ESP
2087 clen = esp_hdrsiz(isr);
2088#else
2089 clen = 0; /*XXX*/
2090#endif
2091 break;
2092 case IPPROTO_AH:
2093 clen = ah_hdrsiz(isr);
2094 break;
2095 case IPPROTO_IPCOMP:
2096 clen = sizeof(struct ipcomp);
2097 break;
2098 }
2099
2100 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2101 switch (((struct sockaddr *)&isr->saidx.dst)->sa_family) {
2102 case AF_INET:
2103 clen += sizeof(struct ip);
2104 break;
2105#if INET6
2106 case AF_INET6:
2107 clen += sizeof(struct ip6_hdr);
2108 break;
2109#endif
2110 default:
2111 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
2112 "unknown AF %d in IPsec tunnel SA\n",
2113 ((struct sockaddr *)&isr->saidx.dst)->sa_family));
2114 break;
2115 }
2116 }
2117 siz += clen;
2118 }
2119
2120 return siz;
2121}
2122
2123/* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
2124size_t
2125ipsec4_hdrsiz(m, dir, inp)
2126 struct mbuf *m;
2127 u_int dir;
2128 struct inpcb *inp;
2129{
2130 struct secpolicy *sp = NULL;
2131 int error;
2132 size_t size;
2133
2d21ac55 2134 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
2135 /* sanity check */
2136 if (m == NULL)
2137 return 0; /* XXX should be panic ? */
2138 if (inp != NULL && inp->inp_socket == NULL)
2139 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
2140
2141 /* get SP for this packet.
2142 * When we are called from ip_forward(), we call
2143 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2144 */
2145 if (inp == NULL)
2146 sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2147 else
2148 sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
2149
2150 if (sp == NULL)
2151 return 0; /* XXX should be panic ? */
2152
2153 size = ipsec_hdrsiz(sp);
2154 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2155 printf("DP ipsec4_hdrsiz call free SP:%p\n", sp));
2156 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
b0d623f7 2157 printf("ipsec4_hdrsiz: size:%lu.\n", (u_int32_t)size));
2d21ac55 2158 key_freesp(sp, KEY_SADB_UNLOCKED);
1c79356b
A
2159
2160 return size;
2161}
2162
2163#if INET6
2164/* This function is called from ipsec6_hdrsize_tcp(),
2165 * and maybe from ip6_forward.()
2166 */
2167size_t
2168ipsec6_hdrsiz(m, dir, in6p)
2169 struct mbuf *m;
2170 u_int dir;
2171 struct in6pcb *in6p;
2172{
2173 struct secpolicy *sp = NULL;
2174 int error;
2175 size_t size;
2176
2d21ac55 2177 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
1c79356b
A
2178 /* sanity check */
2179 if (m == NULL)
2180 return 0; /* XXX shoud be panic ? */
2181 if (in6p != NULL && in6p->in6p_socket == NULL)
2182 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2183
2184 /* get SP for this packet */
2185 /* XXX Is it right to call with IP_FORWARDING. */
2186 if (in6p == NULL)
2187 sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2188 else
2189 sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
2190
2191 if (sp == NULL)
2192 return 0;
2193 size = ipsec_hdrsiz(sp);
2194 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2195 printf("DP ipsec6_hdrsiz call free SP:%p\n", sp));
2196 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
b0d623f7 2197 printf("ipsec6_hdrsiz: size:%lu.\n", (u_int32_t)size));
2d21ac55 2198 key_freesp(sp, KEY_SADB_UNLOCKED);
1c79356b
A
2199
2200 return size;
2201}
2202#endif /*INET6*/
2203
2204#if INET
2205/*
2206 * encapsulate for ipsec tunnel.
2207 * ip->ip_src must be fixed later on.
2208 */
316670eb 2209int
1c79356b
A
2210ipsec4_encapsulate(m, sav)
2211 struct mbuf *m;
2212 struct secasvar *sav;
2213{
2214 struct ip *oip;
2215 struct ip *ip;
2216 size_t hlen;
2217 size_t plen;
2218
2219 /* can't tunnel between different AFs */
2220 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2221 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2222 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
2223 m_freem(m);
2224 return EINVAL;
2225 }
2226#if 0
2227 /* XXX if the dst is myself, perform nothing. */
9bccf70c 2228 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
1c79356b
A
2229 m_freem(m);
2230 return EINVAL;
2231 }
2232#endif
2233
2234 if (m->m_len < sizeof(*ip))
2235 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2236
2237 ip = mtod(m, struct ip *);
2238#ifdef _IP_VHL
9bccf70c 2239 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
1c79356b
A
2240#else
2241 hlen = ip->ip_hl << 2;
2242#endif
2243
2244 if (m->m_len != hlen)
2245 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2246
2247 /* generate header checksum */
2248 ip->ip_sum = 0;
2249#ifdef _IP_VHL
2250 ip->ip_sum = in_cksum(m, hlen);
2251#else
2252 ip->ip_sum = in_cksum(m, hlen);
2253#endif
2254
2255 plen = m->m_pkthdr.len;
2256
2257 /*
2258 * grow the mbuf to accomodate the new IPv4 header.
2259 * NOTE: IPv4 options will never be copied.
2260 */
2261 if (M_LEADINGSPACE(m->m_next) < hlen) {
2262 struct mbuf *n;
2263 MGET(n, M_DONTWAIT, MT_DATA);
2264 if (!n) {
2265 m_freem(m);
2266 return ENOBUFS;
2267 }
2268 n->m_len = hlen;
2269 n->m_next = m->m_next;
2270 m->m_next = n;
2271 m->m_pkthdr.len += hlen;
2272 oip = mtod(n, struct ip *);
2273 } else {
2274 m->m_next->m_len += hlen;
2275 m->m_next->m_data -= hlen;
2276 m->m_pkthdr.len += hlen;
2277 oip = mtod(m->m_next, struct ip *);
2278 }
2279 ip = mtod(m, struct ip *);
2280 ovbcopy((caddr_t)ip, (caddr_t)oip, hlen);
2281 m->m_len = sizeof(struct ip);
2282 m->m_pkthdr.len -= (hlen - sizeof(struct ip));
2283
2284 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2285 /* ECN consideration. */
2286 ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2287#ifdef _IP_VHL
2288 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2);
2289#else
2290 ip->ip_hl = sizeof(struct ip) >> 2;
2291#endif
2292 ip->ip_off &= htons(~IP_OFFMASK);
2293 ip->ip_off &= htons(~IP_MF);
2294 switch (ip4_ipsec_dfbit) {
55e303ae 2295 case 0: /* clear DF bit */
1c79356b
A
2296 ip->ip_off &= htons(~IP_DF);
2297 break;
55e303ae 2298 case 1: /* set DF bit */
1c79356b
A
2299 ip->ip_off |= htons(IP_DF);
2300 break;
55e303ae 2301 default: /* copy DF bit */
1c79356b
A
2302 break;
2303 }
2304 ip->ip_p = IPPROTO_IPIP;
2305 if (plen + sizeof(struct ip) < IP_MAXPACKET)
2306 ip->ip_len = htons(plen + sizeof(struct ip));
2307 else {
2308 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2309 "leave ip_len as is (invalid packet)\n"));
2310 }
9bccf70c
A
2311#ifdef RANDOM_IP_ID
2312 ip->ip_id = ip_randomid();
2313#else
1c79356b 2314 ip->ip_id = htons(ip_id++);
9bccf70c 2315#endif
1c79356b
A
2316 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
2317 &ip->ip_src, sizeof(ip->ip_src));
2318 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
2319 &ip->ip_dst, sizeof(ip->ip_dst));
9bccf70c 2320 ip->ip_ttl = IPDEFTTL;
1c79356b
A
2321
2322 /* XXX Should ip_src be updated later ? */
2323
2324 return 0;
2325}
316670eb
A
2326
2327/*
2328 * encapsulate for ipsec tunnel.
2329 * ip->ip_src must be fixed later on.
2330 */
2331int
2332ipsec4_encapsulate_utun_esp_keepalive(m_ptr, sav)
2333 struct mbuf **m_ptr;
2334 struct secasvar *sav;
2335{
2336 struct ip *ip;
2337 size_t plen;
2338 struct mbuf *m = *m_ptr;
2339
2340 /* can't tunnel between different AFs */
2341 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2342 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2343 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
2344 m_freem(m);
2345 *m_ptr = NULL;
2346 return EINVAL;
2347 }
2348
2349 plen = m->m_pkthdr.len;
2350
2351 /*
2352 * grow the mbuf to accomodate the new IPv4 header.
2353 * NOTE: IPv4 options will never be copied.
2354 */
2355 {
2356 struct mbuf *n;
2357 MGETHDR(n, M_DONTWAIT, MT_HEADER); /* MAC-OK */
2358 if (!n) {
2359 m_freem(m);
2360 *m_ptr = NULL;
2361 return ENOBUFS;
2362 }
2363 if (m->m_flags & M_PKTHDR) {
2364 M_COPY_PKTHDR(n, m);
2365 m->m_flags &= ~M_PKTHDR;
2366 }
2367 MH_ALIGN(n, sizeof(*ip));
2368 n->m_len = sizeof(*ip);
2369 n->m_next = m;
2370 n->m_pkthdr.len = (plen + n->m_len);
2371 m_fixhdr(m);
2372 m = n;
2373 *m_ptr = m;
2374 plen = m->m_pkthdr.len;
2375 }
2376 ip = mtod(m, __typeof__(ip));
2377
2378 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2379 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2380#ifdef _IP_VHL
2381 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(*ip) >> 2);
2382#else
2383 ip->ip_hl = sizeof(*ip) >> 2;
2384#endif
2385 ip->ip_off &= htons(~IP_OFFMASK);
2386 ip->ip_off &= htons(~IP_MF);
2387 switch (ip4_ipsec_dfbit) {
2388 case 0: /* clear DF bit */
2389 ip->ip_off &= htons(~IP_DF);
2390 break;
2391 case 1: /* set DF bit */
2392 ip->ip_off |= htons(IP_DF);
2393 break;
2394 default: /* copy DF bit */
2395 break;
2396 }
2397 ip->ip_p = IPPROTO_IPIP;
2398 if (plen < IP_MAXPACKET)
2399 ip->ip_len = htons(plen);
2400 else {
2401 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2402 "leave ip_len as is (invalid packet)\n"));
2403 }
2404#ifdef RANDOM_IP_ID
2405 ip->ip_id = ip_randomid();
2406#else
2407 ip->ip_id = htons(ip_id++);
2408#endif
2409 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
2410 &ip->ip_src, sizeof(ip->ip_src));
2411 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
2412 &ip->ip_dst, sizeof(ip->ip_dst));
2413 ip->ip_ttl = IPDEFTTL;
2414
2415 /* XXX Should ip_src be updated later ? */
2416
2417 return 0;
2418}
1c79356b
A
2419#endif /*INET*/
2420
2421#if INET6
316670eb 2422int
1c79356b
A
2423ipsec6_encapsulate(m, sav)
2424 struct mbuf *m;
2425 struct secasvar *sav;
2426{
2427 struct ip6_hdr *oip6;
2428 struct ip6_hdr *ip6;
2429 size_t plen;
2430
2431 /* can't tunnel between different AFs */
2432 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2433 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2434 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET6) {
2435 m_freem(m);
2436 return EINVAL;
2437 }
2438#if 0
2439 /* XXX if the dst is myself, perform nothing. */
9bccf70c 2440 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
1c79356b
A
2441 m_freem(m);
2442 return EINVAL;
2443 }
2444#endif
2445
2446 plen = m->m_pkthdr.len;
2447
2448 /*
2449 * grow the mbuf to accomodate the new IPv6 header.
2450 */
2451 if (m->m_len != sizeof(struct ip6_hdr))
2452 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2453 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2454 struct mbuf *n;
2455 MGET(n, M_DONTWAIT, MT_DATA);
2456 if (!n) {
2457 m_freem(m);
2458 return ENOBUFS;
2459 }
2460 n->m_len = sizeof(struct ip6_hdr);
2461 n->m_next = m->m_next;
2462 m->m_next = n;
2463 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2464 oip6 = mtod(n, struct ip6_hdr *);
2465 } else {
2466 m->m_next->m_len += sizeof(struct ip6_hdr);
2467 m->m_next->m_data -= sizeof(struct ip6_hdr);
2468 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2469 oip6 = mtod(m->m_next, struct ip6_hdr *);
2470 }
2471 ip6 = mtod(m, struct ip6_hdr *);
2472 ovbcopy((caddr_t)ip6, (caddr_t)oip6, sizeof(struct ip6_hdr));
2473
2474 /* Fake link-local scope-class addresses */
2475 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src))
2476 oip6->ip6_src.s6_addr16[1] = 0;
2477 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst))
2478 oip6->ip6_dst.s6_addr16[1] = 0;
2479
2480 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2481 /* ECN consideration. */
2482 ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
2483 if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr))
2484 ip6->ip6_plen = htons(plen);
2485 else {
2486 /* ip6->ip6_plen will be updated in ip6_output() */
2487 }
2488 ip6->ip6_nxt = IPPROTO_IPV6;
2489 bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.src)->sin6_addr,
2490 &ip6->ip6_src, sizeof(ip6->ip6_src));
2491 bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.dst)->sin6_addr,
2492 &ip6->ip6_dst, sizeof(ip6->ip6_dst));
9bccf70c 2493 ip6->ip6_hlim = IPV6_DEFHLIM;
1c79356b
A
2494
2495 /* XXX Should ip6_src be updated later ? */
2496
2497 return 0;
2498}
2d21ac55
A
2499
2500static int
2501ipsec64_encapsulate(m, sav)
2502 struct mbuf *m;
2503 struct secasvar *sav;
2504{
2505 struct ip6_hdr *ip6, *ip6i;
2506 struct ip *ip;
2507 size_t plen;
2508 u_int8_t hlim;
2509
2510 /* tunneling over IPv4 */
2511 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2512 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2513 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
2514 m_freem(m);
2515 return EINVAL;
2516 }
2517#if 0
2518 /* XXX if the dst is myself, perform nothing. */
2519 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
2520 m_freem(m);
2521 return EINVAL;
2522 }
2523#endif
2524
2525 plen = m->m_pkthdr.len;
2526 ip6 = mtod(m, struct ip6_hdr *);
2527 hlim = ip6->ip6_hlim;
2528 /*
2529 * grow the mbuf to accomodate the new IPv4 header.
2530 */
2531 if (m->m_len != sizeof(struct ip6_hdr))
2532 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2533 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2534 struct mbuf *n;
2535 MGET(n, M_DONTWAIT, MT_DATA);
2536 if (!n) {
2537 m_freem(m);
2538 return ENOBUFS;
2539 }
2540 n->m_len = sizeof(struct ip6_hdr);
2541 n->m_next = m->m_next;
2542 m->m_next = n;
2543 m->m_pkthdr.len += sizeof(struct ip);
2544 ip6i = mtod(n, struct ip6_hdr *);
2545 } else {
2546 m->m_next->m_len += sizeof(struct ip6_hdr);
2547 m->m_next->m_data -= sizeof(struct ip6_hdr);
2548 m->m_pkthdr.len += sizeof(struct ip);
2549 ip6i = mtod(m->m_next, struct ip6_hdr *);
2550 }
2551 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2552 /* ECN consideration. */
2553 /* XXX To be fixed later if needed */
2554 // ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2555
2556 bcopy(ip6, ip6i, sizeof(struct ip6_hdr));
2557 ip = mtod(m, struct ip *);
2558 m->m_len = sizeof(struct ip);
2559 /*
2560 * Fill in some of the IPv4 fields - we don't need all of them
2561 * because the rest will be filled in by ip_output
2562 */
2563 ip->ip_v = IPVERSION;
2564 ip->ip_hl = sizeof(struct ip) >> 2;
2565 ip->ip_id = 0;
2566 ip->ip_sum = 0;
2567 ip->ip_tos = 0;
2568 ip->ip_off = 0;
2569 ip->ip_ttl = hlim;
2570 ip->ip_p = IPPROTO_IPV6;
2571 if (plen + sizeof(struct ip) < IP_MAXPACKET)
2572 ip->ip_len = htons(plen + sizeof(struct ip));
2573 else {
2574 ip->ip_len = htons(plen);
2575 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2576 "leave ip_len as is (invalid packet)\n"));
2577 }
2578 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
2579 &ip->ip_src, sizeof(ip->ip_src));
2580 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
2581 &ip->ip_dst, sizeof(ip->ip_dst));
2582
2583 return 0;
2584}
316670eb
A
2585
2586int
2587ipsec6_encapsulate_utun_esp_keepalive(m_ptr, sav)
2588 struct mbuf **m_ptr;
2589 struct secasvar *sav;
2590{
2591 struct ip6_hdr *ip6;
2592 size_t plen;
2593 struct mbuf *m = *m_ptr;
2594
2595 /* can't tunnel between different AFs */
2596 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2597 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2598 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET6) {
2599 m_freem(m);
2600 *m_ptr = NULL;
2601 return EINVAL;
2602 }
2603
2604 plen = m->m_pkthdr.len;
2605
2606 /*
2607 * grow the mbuf to accomodate the new IPv6 header.
2608 */
2609 {
2610 struct mbuf *n;
2611 MGETHDR(n, M_DONTWAIT, MT_HEADER); /* MAC-OK */
2612 if (!n) {
2613 m_freem(m);
2614 *m_ptr = NULL;
2615 return ENOBUFS;
2616 }
2617 if (m->m_flags & M_PKTHDR) {
2618 M_COPY_PKTHDR(n, m);
2619 m->m_flags &= ~M_PKTHDR;
2620 }
2621 MH_ALIGN(n, sizeof(*ip6));
2622 n->m_len = sizeof(*ip6);
2623 n->m_next = m;
2624 n->m_pkthdr.len = (plen + n->m_len);
2625 m_fixhdr(m);
2626 m = n;
2627 *m_ptr = m;
2628 plen = m->m_pkthdr.len;
2629 }
2630 ip6 = mtod(m, __typeof__(ip6));
2631
2632 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2633 if (plen < IPV6_MAXPACKET)
2634 ip6->ip6_plen = htons(plen);
2635 else {
2636 /* ip6->ip6_plen will be updated in ip6_output() */
2637 }
2638 ip6->ip6_nxt = IPPROTO_IPV6;
2639 bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.src)->sin6_addr,
2640 &ip6->ip6_src, sizeof(ip6->ip6_src));
2641 bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.dst)->sin6_addr,
2642 &ip6->ip6_dst, sizeof(ip6->ip6_dst));
2643 ip6->ip6_hlim = IPV6_DEFHLIM;
2644
2645 /* XXX Should ip6_src be updated later ? */
2646
2647 return 0;
2648}
1c79356b
A
2649#endif /*INET6*/
2650
2651/*
2652 * Check the variable replay window.
2653 * ipsec_chkreplay() performs replay check before ICV verification.
2654 * ipsec_updatereplay() updates replay bitmap. This must be called after
2655 * ICV verification (it also performs replay check, which is usually done
2656 * beforehand).
2657 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2658 *
2659 * based on RFC 2401.
2660 */
2661int
2662ipsec_chkreplay(seq, sav)
2663 u_int32_t seq;
2664 struct secasvar *sav;
2665{
2666 const struct secreplay *replay;
2667 u_int32_t diff;
2668 int fr;
2669 u_int32_t wsizeb; /* constant: bits of window size */
2670 int frlast; /* constant: last frame */
2671
2d21ac55 2672
1c79356b
A
2673 /* sanity check */
2674 if (sav == NULL)
2675 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2676
2d21ac55 2677 lck_mtx_lock(sadb_mutex);
1c79356b
A
2678 replay = sav->replay;
2679
2d21ac55
A
2680 if (replay->wsize == 0) {
2681 lck_mtx_unlock(sadb_mutex);
1c79356b 2682 return 1; /* no need to check replay. */
2d21ac55 2683 }
1c79356b
A
2684
2685 /* constant */
2686 frlast = replay->wsize - 1;
2687 wsizeb = replay->wsize << 3;
2688
2689 /* sequence number of 0 is invalid */
2d21ac55
A
2690 if (seq == 0) {
2691 lck_mtx_unlock(sadb_mutex);
1c79356b 2692 return 0;
2d21ac55 2693 }
1c79356b
A
2694
2695 /* first time is always okay */
2d21ac55
A
2696 if (replay->count == 0) {
2697 lck_mtx_unlock(sadb_mutex);
1c79356b 2698 return 1;
2d21ac55 2699 }
1c79356b
A
2700
2701 if (seq > replay->lastseq) {
2702 /* larger sequences are okay */
2d21ac55 2703 lck_mtx_unlock(sadb_mutex);
1c79356b
A
2704 return 1;
2705 } else {
2706 /* seq is equal or less than lastseq. */
2707 diff = replay->lastseq - seq;
2708
2709 /* over range to check, i.e. too old or wrapped */
2d21ac55
A
2710 if (diff >= wsizeb) {
2711 lck_mtx_unlock(sadb_mutex);
1c79356b 2712 return 0;
2d21ac55 2713 }
1c79356b
A
2714
2715 fr = frlast - diff / 8;
2716
2717 /* this packet already seen ? */
2d21ac55
A
2718 if ((replay->bitmap)[fr] & (1 << (diff % 8))) {
2719 lck_mtx_unlock(sadb_mutex);
1c79356b 2720 return 0;
2d21ac55 2721 }
1c79356b
A
2722
2723 /* out of order but good */
2d21ac55 2724 lck_mtx_unlock(sadb_mutex);
1c79356b
A
2725 return 1;
2726 }
2727}
2728
2729/*
2730 * check replay counter whether to update or not.
2731 * OUT: 0: OK
2732 * 1: NG
2733 */
2734int
2735ipsec_updatereplay(seq, sav)
2736 u_int32_t seq;
2737 struct secasvar *sav;
2738{
2739 struct secreplay *replay;
2740 u_int32_t diff;
2741 int fr;
2742 u_int32_t wsizeb; /* constant: bits of window size */
2743 int frlast; /* constant: last frame */
2d21ac55 2744
1c79356b
A
2745 /* sanity check */
2746 if (sav == NULL)
2747 panic("ipsec_chkreplay: NULL pointer was passed.\n");
2748
2d21ac55 2749 lck_mtx_lock(sadb_mutex);
1c79356b
A
2750 replay = sav->replay;
2751
2752 if (replay->wsize == 0)
2753 goto ok; /* no need to check replay. */
2754
2755 /* constant */
2756 frlast = replay->wsize - 1;
2757 wsizeb = replay->wsize << 3;
2758
2759 /* sequence number of 0 is invalid */
2760 if (seq == 0)
2761 return 1;
2762
2763 /* first time */
2764 if (replay->count == 0) {
2765 replay->lastseq = seq;
2766 bzero(replay->bitmap, replay->wsize);
2767 (replay->bitmap)[frlast] = 1;
2768 goto ok;
2769 }
2770
2771 if (seq > replay->lastseq) {
2772 /* seq is larger than lastseq. */
2773 diff = seq - replay->lastseq;
2774
2775 /* new larger sequence number */
2776 if (diff < wsizeb) {
2777 /* In window */
2778 /* set bit for this packet */
2d21ac55 2779 vshiftl((unsigned char *) replay->bitmap, diff, replay->wsize);
1c79356b
A
2780 (replay->bitmap)[frlast] |= 1;
2781 } else {
2782 /* this packet has a "way larger" */
2783 bzero(replay->bitmap, replay->wsize);
2784 (replay->bitmap)[frlast] = 1;
2785 }
2786 replay->lastseq = seq;
2787
2788 /* larger is good */
2789 } else {
2790 /* seq is equal or less than lastseq. */
2791 diff = replay->lastseq - seq;
2792
2793 /* over range to check, i.e. too old or wrapped */
2d21ac55
A
2794 if (diff >= wsizeb) {
2795 lck_mtx_unlock(sadb_mutex);
1c79356b 2796 return 1;
2d21ac55 2797 }
1c79356b
A
2798
2799 fr = frlast - diff / 8;
2800
2801 /* this packet already seen ? */
2d21ac55
A
2802 if ((replay->bitmap)[fr] & (1 << (diff % 8))) {
2803 lck_mtx_unlock(sadb_mutex);
1c79356b 2804 return 1;
2d21ac55 2805 }
1c79356b
A
2806
2807 /* mark as seen */
2808 (replay->bitmap)[fr] |= (1 << (diff % 8));
2809
2810 /* out of order but good */
2811 }
2812
2813ok:
2814 if (replay->count == ~0) {
2815
2816 /* set overflow flag */
2817 replay->overflow++;
2818
2819 /* don't increment, no more packets accepted */
2d21ac55
A
2820 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
2821 lck_mtx_unlock(sadb_mutex);
1c79356b 2822 return 1;
2d21ac55 2823 }
1c79356b
A
2824
2825 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
2826 replay->overflow, ipsec_logsastr(sav)));
2827 }
2828
2829 replay->count++;
2d21ac55
A
2830
2831 lck_mtx_unlock(sadb_mutex);
1c79356b
A
2832 return 0;
2833}
2834
2835/*
55e303ae 2836 * shift variable length buffer to left.
1c79356b
A
2837 * IN: bitmap: pointer to the buffer
2838 * nbit: the number of to shift.
2839 * wsize: buffer size (bytes).
2840 */
2841static void
2842vshiftl(bitmap, nbit, wsize)
2843 unsigned char *bitmap;
2844 int nbit, wsize;
2845{
2846 int s, j, i;
2847 unsigned char over;
2848
2849 for (j = 0; j < nbit; j += 8) {
2850 s = (nbit - j < 8) ? (nbit - j): 8;
2851 bitmap[0] <<= s;
2852 for (i = 1; i < wsize; i++) {
2853 over = (bitmap[i] >> (8 - s));
2854 bitmap[i] <<= s;
2855 bitmap[i-1] |= over;
2856 }
2857 }
2858
2859 return;
2860}
2861
2862const char *
2863ipsec4_logpacketstr(ip, spi)
2864 struct ip *ip;
2865 u_int32_t spi;
2866{
316670eb 2867 static char buf[256] __attribute__((aligned(4)));
1c79356b
A
2868 char *p;
2869 u_int8_t *s, *d;
2870
2871 s = (u_int8_t *)(&ip->ip_src);
2872 d = (u_int8_t *)(&ip->ip_dst);
2873
2874 p = buf;
2875 snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2876 while (p && *p)
2877 p++;
9bccf70c 2878 snprintf(p, sizeof(buf) - (p - buf), "src=%u.%u.%u.%u",
1c79356b
A
2879 s[0], s[1], s[2], s[3]);
2880 while (p && *p)
2881 p++;
9bccf70c 2882 snprintf(p, sizeof(buf) - (p - buf), " dst=%u.%u.%u.%u",
1c79356b
A
2883 d[0], d[1], d[2], d[3]);
2884 while (p && *p)
2885 p++;
2886 snprintf(p, sizeof(buf) - (p - buf), ")");
2887
2888 return buf;
2889}
2890
2891#if INET6
2892const char *
2893ipsec6_logpacketstr(ip6, spi)
2894 struct ip6_hdr *ip6;
2895 u_int32_t spi;
2896{
316670eb 2897 static char buf[256] __attribute__((aligned(4)));
1c79356b
A
2898 char *p;
2899
2900 p = buf;
2901 snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2902 while (p && *p)
2903 p++;
2904 snprintf(p, sizeof(buf) - (p - buf), "src=%s",
2905 ip6_sprintf(&ip6->ip6_src));
2906 while (p && *p)
2907 p++;
2908 snprintf(p, sizeof(buf) - (p - buf), " dst=%s",
2909 ip6_sprintf(&ip6->ip6_dst));
2910 while (p && *p)
2911 p++;
2912 snprintf(p, sizeof(buf) - (p - buf), ")");
2913
2914 return buf;
2915}
2916#endif /*INET6*/
2917
2918const char *
2919ipsec_logsastr(sav)
2920 struct secasvar *sav;
2921{
316670eb 2922 static char buf[256] __attribute__((aligned(4)));
1c79356b
A
2923 char *p;
2924 struct secasindex *saidx = &sav->sah->saidx;
2925
2926 /* validity check */
2927 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2928 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family)
2929 panic("ipsec_logsastr: family mismatched.\n");
2930
2931 p = buf;
2932 snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
2933 while (p && *p)
2934 p++;
2935 if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET) {
2936 u_int8_t *s, *d;
2937 s = (u_int8_t *)&((struct sockaddr_in *)&saidx->src)->sin_addr;
2938 d = (u_int8_t *)&((struct sockaddr_in *)&saidx->dst)->sin_addr;
2939 snprintf(p, sizeof(buf) - (p - buf),
2940 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
2941 s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
2942 }
2943#if INET6
2944 else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
2945 snprintf(p, sizeof(buf) - (p - buf),
2946 "src=%s",
2947 ip6_sprintf(&((struct sockaddr_in6 *)&saidx->src)->sin6_addr));
2948 while (p && *p)
2949 p++;
2950 snprintf(p, sizeof(buf) - (p - buf),
2951 " dst=%s",
2952 ip6_sprintf(&((struct sockaddr_in6 *)&saidx->dst)->sin6_addr));
2953 }
2954#endif
2955 while (p && *p)
2956 p++;
2957 snprintf(p, sizeof(buf) - (p - buf), ")");
2958
2959 return buf;
2960}
2961
2962void
2963ipsec_dumpmbuf(m)
2964 struct mbuf *m;
2965{
2966 int totlen;
2967 int i;
2968 u_char *p;
2969
2970 totlen = 0;
2971 printf("---\n");
2972 while (m) {
2973 p = mtod(m, u_char *);
2974 for (i = 0; i < m->m_len; i++) {
2975 printf("%02x ", p[i]);
2976 totlen++;
2977 if (totlen % 16 == 0)
2978 printf("\n");
2979 }
2980 m = m->m_next;
2981 }
2982 if (totlen % 16 != 0)
2983 printf("\n");
2984 printf("---\n");
2985}
2986
9bccf70c 2987#if INET
1c79356b
A
2988/*
2989 * IPsec output logic for IPv4.
2990 */
2991int
2d21ac55
A
2992ipsec4_output(
2993 struct ipsec_output_state *state,
2994 struct secpolicy *sp,
2995 __unused int flags)
1c79356b
A
2996{
2997 struct ip *ip = NULL;
2998 struct ipsecrequest *isr = NULL;
2999 struct secasindex saidx;
2d21ac55
A
3000 struct secasvar *sav = NULL;
3001 int error = 0;
1c79356b 3002 struct sockaddr_in *dst4;
9bccf70c 3003 struct sockaddr_in *sin;
ebb1b9f4 3004 struct route *ro4;
1c79356b 3005
2d21ac55
A
3006 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3007
1c79356b
A
3008 if (!state)
3009 panic("state == NULL in ipsec4_output");
3010 if (!state->m)
3011 panic("state->m == NULL in ipsec4_output");
1c79356b
A
3012 if (!state->dst)
3013 panic("state->dst == NULL in ipsec4_output");
3014
55e303ae
A
3015 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_START, 0,0,0,0,0);
3016
1c79356b
A
3017 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
3018 printf("ipsec4_output: applyed SP\n");
3019 kdebug_secpolicy(sp));
3020
3021 for (isr = sp->req; isr != NULL; isr = isr->next) {
3022
3023#if 0 /* give up to check restriction of transport mode */
3024 /* XXX but should be checked somewhere */
3025 /*
3026 * some of the IPsec operation must be performed only in
3027 * originating case.
3028 */
3029 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT
3030 && (flags & IP_FORWARDING))
3031 continue;
3032#endif
3033
3034 /* make SA index for search proper SA */
3035 ip = mtod(state->m, struct ip *);
3036 bcopy(&isr->saidx, &saidx, sizeof(saidx));
9bccf70c
A
3037 saidx.mode = isr->saidx.mode;
3038 saidx.reqid = isr->saidx.reqid;
3039 sin = (struct sockaddr_in *)&saidx.src;
3040 if (sin->sin_len == 0) {
3041 sin->sin_len = sizeof(*sin);
3042 sin->sin_family = AF_INET;
3043 sin->sin_port = IPSEC_PORT_ANY;
3044 bcopy(&ip->ip_src, &sin->sin_addr,
3045 sizeof(sin->sin_addr));
1c79356b 3046 }
9bccf70c
A
3047 sin = (struct sockaddr_in *)&saidx.dst;
3048 if (sin->sin_len == 0) {
3049 sin->sin_len = sizeof(*sin);
3050 sin->sin_family = AF_INET;
3051 sin->sin_port = IPSEC_PORT_ANY;
2d21ac55
A
3052 /*
3053 * Get port from packet if upper layer is UDP and nat traversal
3054 * is enabled and transport mode.
3055 */
3056
3057 if ((esp_udp_encap_port & 0xFFFF) != 0 &&
3058 isr->saidx.mode == IPSEC_MODE_TRANSPORT) {
3059
3060 if (ip->ip_p == IPPROTO_UDP) {
3061 struct udphdr *udp;
3062 size_t hlen;
3063#ifdef _IP_VHL
3064 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
3065#else
3066 hlen = ip->ip_hl << 2;
3067#endif
3068 if (state->m->m_len < hlen + sizeof(struct udphdr)) {
3069 state->m = m_pullup(state->m, hlen + sizeof(struct udphdr));
3070 if (!state->m) {
3071 ipseclog((LOG_DEBUG,
3072 "IPv4 output: can't pullup UDP header\n"));
3073 IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
3074 goto bad;
3075 }
3076 ip = mtod(state->m, struct ip *);
3077 }
316670eb 3078 udp = (struct udphdr *)(void *)(((u_int8_t *)ip) + hlen);
2d21ac55
A
3079 sin->sin_port = udp->uh_dport;
3080 }
3081 }
3082
9bccf70c
A
3083 bcopy(&ip->ip_dst, &sin->sin_addr,
3084 sizeof(sin->sin_addr));
1c79356b
A
3085 }
3086
2d21ac55 3087 if ((error = key_checkrequest(isr, &saidx, &sav)) != 0) {
1c79356b
A
3088 /*
3089 * IPsec processing is required, but no SA found.
3090 * I assume that key_acquire() had been called
3091 * to get/establish the SA. Here I discard
3092 * this packet because it is responsibility for
3093 * upper layer to retransmit the packet.
3094 */
2d21ac55 3095 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
1c79356b
A
3096 goto bad;
3097 }
3098
3099 /* validity check */
2d21ac55 3100 if (sav == NULL) {
1c79356b
A
3101 switch (ipsec_get_reqlevel(isr)) {
3102 case IPSEC_LEVEL_USE:
3103 continue;
3104 case IPSEC_LEVEL_REQUIRE:
3105 /* must be not reached here. */
3106 panic("ipsec4_output: no SA found, but required.");
3107 }
3108 }
3109
3110 /*
3111 * If there is no valid SA, we give up to process any
3112 * more. In such a case, the SA's status is changed
3113 * from DYING to DEAD after allocating. If a packet
3114 * send to the receiver by dead SA, the receiver can
3115 * not decode a packet because SA has been dead.
3116 */
2d21ac55
A
3117 if (sav->state != SADB_SASTATE_MATURE
3118 && sav->state != SADB_SASTATE_DYING) {
3119 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
1c79356b
A
3120 error = EINVAL;
3121 goto bad;
3122 }
3123
3124 /*
3125 * There may be the case that SA status will be changed when
3126 * we are refering to one. So calling splsoftnet().
3127 */
1c79356b
A
3128
3129 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3130 /*
3131 * build IPsec tunnel.
3132 */
3133 /* XXX should be processed with other familiy */
2d21ac55 3134 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
1c79356b
A
3135 ipseclog((LOG_ERR, "ipsec4_output: "
3136 "family mismatched between inner and outer spi=%u\n",
2d21ac55 3137 (u_int32_t)ntohl(sav->spi)));
1c79356b
A
3138 error = EAFNOSUPPORT;
3139 goto bad;
3140 }
3141
1c79356b
A
3142 state->m = ipsec4_splithdr(state->m);
3143 if (!state->m) {
1c79356b
A
3144 error = ENOMEM;
3145 goto bad;
3146 }
2d21ac55 3147 error = ipsec4_encapsulate(state->m, sav);
1c79356b
A
3148 if (error) {
3149 state->m = NULL;
3150 goto bad;
3151 }
3152 ip = mtod(state->m, struct ip *);
3153
6d2010ae
A
3154 // grab sadb_mutex, before updating sah's route cache
3155 lck_mtx_lock(sadb_mutex);
ebb1b9f4 3156 ro4= &sav->sah->sa_route;
316670eb 3157 dst4 = (struct sockaddr_in *)(void *)&ro4->ro_dst;
ebb1b9f4
A
3158 if (ro4->ro_rt != NULL) {
3159 RT_LOCK(ro4->ro_rt);
6d2010ae 3160 }
ebb1b9f4
A
3161 if (ro4->ro_rt != NULL &&
3162 (ro4->ro_rt->generation_id != route_generation ||
3163 !(ro4->ro_rt->rt_flags & RTF_UP) ||
b0d623f7 3164 dst4->sin_addr.s_addr != ip->ip_dst.s_addr)) {
ebb1b9f4
A
3165 RT_UNLOCK(ro4->ro_rt);
3166 rtfree(ro4->ro_rt);
3167 ro4->ro_rt = NULL;
1c79356b 3168 }
ebb1b9f4 3169 if (ro4->ro_rt == 0) {
1c79356b
A
3170 dst4->sin_family = AF_INET;
3171 dst4->sin_len = sizeof(*dst4);
3172 dst4->sin_addr = ip->ip_dst;
ebb1b9f4
A
3173 rtalloc(ro4);
3174 if (ro4->ro_rt == 0) {
6d2010ae
A
3175 OSAddAtomic(1, &ipstat.ips_noroute);
3176 error = EHOSTUNREACH;
3177 // release sadb_mutex, after updating sah's route cache
3178 lck_mtx_unlock(sadb_mutex);
3179 goto bad;
3180 }
ebb1b9f4 3181 RT_LOCK(ro4->ro_rt);
1c79356b
A
3182 }
3183
b0d623f7
A
3184 /*
3185 * adjust state->dst if tunnel endpoint is offlink
3186 *
3187 * XXX: caching rt_gateway value in the state is
3188 * not really good, since it may point elsewhere
3189 * when the gateway gets modified to a larger
3190 * sockaddr via rt_setgate(). This is currently
3191 * addressed by SA_SIZE roundup in that routine.
3192 */
ebb1b9f4 3193 if (ro4->ro_rt->rt_flags & RTF_GATEWAY)
316670eb 3194 dst4 = (struct sockaddr_in *)(void *)ro4->ro_rt->rt_gateway;
ebb1b9f4
A
3195 RT_UNLOCK(ro4->ro_rt);
3196 if (state->ro.ro_rt != NULL) {
3197 rtfree(state->ro.ro_rt);
3198 state->ro.ro_rt = NULL;
1c79356b 3199 }
ebb1b9f4
A
3200 route_copyout(&state->ro, ro4, sizeof(state->ro));
3201 state->dst = (struct sockaddr *)dst4;
3202 state->tunneled = 4;
6d2010ae
A
3203 // release sadb_mutex, after updating sah's route cache
3204 lck_mtx_unlock(sadb_mutex);
91447636 3205 }
1c79356b
A
3206
3207 state->m = ipsec4_splithdr(state->m);
3208 if (!state->m) {
3209 error = ENOMEM;
3210 goto bad;
3211 }
3212 switch (isr->saidx.proto) {
3213 case IPPROTO_ESP:
3214#if IPSEC_ESP
2d21ac55 3215 if ((error = esp4_output(state->m, sav)) != 0) {
1c79356b
A
3216 state->m = NULL;
3217 goto bad;
3218 }
3219 break;
3220#else
3221 m_freem(state->m);
3222 state->m = NULL;
3223 error = EINVAL;
3224 goto bad;
3225#endif
3226 case IPPROTO_AH:
2d21ac55 3227 if ((error = ah4_output(state->m, sav)) != 0) {
1c79356b
A
3228 state->m = NULL;
3229 goto bad;
3230 }
3231 break;
3232 case IPPROTO_IPCOMP:
2d21ac55 3233 if ((error = ipcomp4_output(state->m, sav)) != 0) {
1c79356b
A
3234 state->m = NULL;
3235 goto bad;
3236 }
3237 break;
3238 default:
3239 ipseclog((LOG_ERR,
3240 "ipsec4_output: unknown ipsec protocol %d\n",
3241 isr->saidx.proto));
3242 m_freem(state->m);
3243 state->m = NULL;
3244 error = EINVAL;
3245 goto bad;
3246 }
3247
3248 if (state->m == 0) {
3249 error = ENOMEM;
3250 goto bad;
3251 }
3252 ip = mtod(state->m, struct ip *);
3253 }
3254
55e303ae 3255 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, 0,0,0,0,0);
2d21ac55
A
3256 if (sav)
3257 key_freesav(sav, KEY_SADB_UNLOCKED);
1c79356b
A
3258 return 0;
3259
3260bad:
2d21ac55
A
3261 if (sav)
3262 key_freesav(sav, KEY_SADB_UNLOCKED);
1c79356b
A
3263 m_freem(state->m);
3264 state->m = NULL;
55e303ae 3265 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, error,0,0,0,0);
1c79356b
A
3266 return error;
3267}
9bccf70c 3268#endif
1c79356b
A
3269
3270#if INET6
3271/*
3272 * IPsec output logic for IPv6, transport mode.
3273 */
3274int
2d21ac55
A
3275ipsec6_output_trans(
3276 struct ipsec_output_state *state,
3277 u_char *nexthdrp,
3278 struct mbuf *mprev,
3279 struct secpolicy *sp,
3280 __unused int flags,
3281 int *tun)
1c79356b
A
3282{
3283 struct ip6_hdr *ip6;
3284 struct ipsecrequest *isr = NULL;
3285 struct secasindex saidx;
3286 int error = 0;
3287 int plen;
9bccf70c 3288 struct sockaddr_in6 *sin6;
2d21ac55 3289 struct secasvar *sav = NULL;
1c79356b 3290
2d21ac55
A
3291 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3292
1c79356b 3293 if (!state)
55e303ae 3294 panic("state == NULL in ipsec6_output_trans");
1c79356b 3295 if (!state->m)
55e303ae 3296 panic("state->m == NULL in ipsec6_output_trans");
1c79356b 3297 if (!nexthdrp)
55e303ae 3298 panic("nexthdrp == NULL in ipsec6_output_trans");
1c79356b 3299 if (!mprev)
55e303ae 3300 panic("mprev == NULL in ipsec6_output_trans");
1c79356b 3301 if (!sp)
55e303ae 3302 panic("sp == NULL in ipsec6_output_trans");
1c79356b 3303 if (!tun)
55e303ae 3304 panic("tun == NULL in ipsec6_output_trans");
1c79356b
A
3305
3306 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
3307 printf("ipsec6_output_trans: applyed SP\n");
3308 kdebug_secpolicy(sp));
91447636 3309
1c79356b
A
3310 *tun = 0;
3311 for (isr = sp->req; isr; isr = isr->next) {
3312 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3313 /* the rest will be handled by ipsec6_output_tunnel() */
3314 break;
3315 }
3316
3317 /* make SA index for search proper SA */
3318 ip6 = mtod(state->m, struct ip6_hdr *);
3319 bcopy(&isr->saidx, &saidx, sizeof(saidx));
9bccf70c
A
3320 saidx.mode = isr->saidx.mode;
3321 saidx.reqid = isr->saidx.reqid;
3322 sin6 = (struct sockaddr_in6 *)&saidx.src;
3323 if (sin6->sin6_len == 0) {
3324 sin6->sin6_len = sizeof(*sin6);
3325 sin6->sin6_family = AF_INET6;
3326 sin6->sin6_port = IPSEC_PORT_ANY;
3327 bcopy(&ip6->ip6_src, &sin6->sin6_addr,
3328 sizeof(ip6->ip6_src));
3329 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
3330 /* fix scope id for comparing SPD */
3331 sin6->sin6_addr.s6_addr16[1] = 0;
3332 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
3333 }
1c79356b 3334 }
9bccf70c
A
3335 sin6 = (struct sockaddr_in6 *)&saidx.dst;
3336 if (sin6->sin6_len == 0) {
3337 sin6->sin6_len = sizeof(*sin6);
3338 sin6->sin6_family = AF_INET6;
3339 sin6->sin6_port = IPSEC_PORT_ANY;
3340 bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
3341 sizeof(ip6->ip6_dst));
3342 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
3343 /* fix scope id for comparing SPD */
3344 sin6->sin6_addr.s6_addr16[1] = 0;
3345 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
3346 }
1c79356b
A
3347 }
3348
2d21ac55 3349 if (key_checkrequest(isr, &saidx, &sav) == ENOENT) {
1c79356b
A
3350 /*
3351 * IPsec processing is required, but no SA found.
3352 * I assume that key_acquire() had been called
3353 * to get/establish the SA. Here I discard
3354 * this packet because it is responsibility for
3355 * upper layer to retransmit the packet.
3356 */
2d21ac55 3357 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
1c79356b 3358 error = ENOENT;
9bccf70c
A
3359
3360 /*
3361 * Notify the fact that the packet is discarded
3362 * to ourselves. I believe this is better than
3363 * just silently discarding. (jinmei@kame.net)
3364 * XXX: should we restrict the error to TCP packets?
3365 * XXX: should we directly notify sockets via
3366 * pfctlinputs?
3367 */
3368 icmp6_error(state->m, ICMP6_DST_UNREACH,
3369 ICMP6_DST_UNREACH_ADMIN, 0);
3370 state->m = NULL; /* icmp6_error freed the mbuf */
1c79356b
A
3371 goto bad;
3372 }
3373
3374 /* validity check */
2d21ac55 3375 if (sav == NULL) {
1c79356b
A
3376 switch (ipsec_get_reqlevel(isr)) {
3377 case IPSEC_LEVEL_USE:
3378 continue;
3379 case IPSEC_LEVEL_REQUIRE:
3380 /* must be not reached here. */
3381 panic("ipsec6_output_trans: no SA found, but required.");
3382 }
3383 }
3384
3385 /*
3386 * If there is no valid SA, we give up to process.
3387 * see same place at ipsec4_output().
3388 */
2d21ac55
A
3389 if (sav->state != SADB_SASTATE_MATURE
3390 && sav->state != SADB_SASTATE_DYING) {
3391 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
1c79356b
A
3392 error = EINVAL;
3393 goto bad;
3394 }
3395
3396 switch (isr->saidx.proto) {
3397 case IPPROTO_ESP:
3398#if IPSEC_ESP
2d21ac55 3399 error = esp6_output(state->m, nexthdrp, mprev->m_next, sav);
1c79356b
A
3400#else
3401 m_freem(state->m);
3402 error = EINVAL;
3403#endif
3404 break;
3405 case IPPROTO_AH:
2d21ac55 3406 error = ah6_output(state->m, nexthdrp, mprev->m_next, sav);
1c79356b
A
3407 break;
3408 case IPPROTO_IPCOMP:
2d21ac55 3409 error = ipcomp6_output(state->m, nexthdrp, mprev->m_next, sav);
1c79356b
A
3410 break;
3411 default:
3412 ipseclog((LOG_ERR, "ipsec6_output_trans: "
3413 "unknown ipsec protocol %d\n", isr->saidx.proto));
3414 m_freem(state->m);
2d21ac55 3415 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
1c79356b
A
3416 error = EINVAL;
3417 break;
3418 }
3419 if (error) {
3420 state->m = NULL;
3421 goto bad;
3422 }
3423 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3424 if (plen > IPV6_MAXPACKET) {
3425 ipseclog((LOG_ERR, "ipsec6_output_trans: "
3426 "IPsec with IPv6 jumbogram is not supported\n"));
2d21ac55 3427 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
1c79356b
A
3428 error = EINVAL; /*XXX*/
3429 goto bad;
3430 }
3431 ip6 = mtod(state->m, struct ip6_hdr *);
3432 ip6->ip6_plen = htons(plen);
3433 }
3434
3435 /* if we have more to go, we need a tunnel mode processing */
3436 if (isr != NULL)
3437 *tun = 1;
3438
2d21ac55
A
3439 if (sav)
3440 key_freesav(sav, KEY_SADB_UNLOCKED);
1c79356b
A
3441 return 0;
3442
3443bad:
2d21ac55
A
3444 if (sav)
3445 key_freesav(sav, KEY_SADB_UNLOCKED);
1c79356b
A
3446 m_freem(state->m);
3447 state->m = NULL;
3448 return error;
3449}
3450
3451/*
3452 * IPsec output logic for IPv6, tunnel mode.
3453 */
3454int
2d21ac55
A
3455ipsec6_output_tunnel(
3456 struct ipsec_output_state *state,
3457 struct secpolicy *sp,
ebb1b9f4 3458 __unused int flags)
1c79356b
A
3459{
3460 struct ip6_hdr *ip6;
3461 struct ipsecrequest *isr = NULL;
3462 struct secasindex saidx;
2d21ac55 3463 struct secasvar *sav = NULL;
1c79356b
A
3464 int error = 0;
3465 int plen;
1c79356b 3466 struct sockaddr_in6* dst6;
ebb1b9f4 3467 struct route *ro6;
1c79356b 3468
2d21ac55
A
3469 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3470
1c79356b 3471 if (!state)
55e303ae 3472 panic("state == NULL in ipsec6_output_tunnel");
1c79356b 3473 if (!state->m)
55e303ae 3474 panic("state->m == NULL in ipsec6_output_tunnel");
1c79356b 3475 if (!sp)
55e303ae 3476 panic("sp == NULL in ipsec6_output_tunnel");
1c79356b
A
3477
3478 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
3479 printf("ipsec6_output_tunnel: applyed SP\n");
3480 kdebug_secpolicy(sp));
3481
3482 /*
3483 * transport mode ipsec (before the 1st tunnel mode) is already
3484 * processed by ipsec6_output_trans().
3485 */
3486 for (isr = sp->req; isr; isr = isr->next) {
3487 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
3488 break;
3489 }
3490
55e303ae
A
3491 for (/* already initialized */; isr; isr = isr->next) {
3492 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3493 /* When tunnel mode, SA peers must be specified. */
3494 bcopy(&isr->saidx, &saidx, sizeof(saidx));
3495 } else {
3496 /* make SA index to look for a proper SA */
3497 struct sockaddr_in6 *sin6;
3498
3499 bzero(&saidx, sizeof(saidx));
3500 saidx.proto = isr->saidx.proto;
3501 saidx.mode = isr->saidx.mode;
3502 saidx.reqid = isr->saidx.reqid;
3503
3504 ip6 = mtod(state->m, struct ip6_hdr *);
3505 sin6 = (struct sockaddr_in6 *)&saidx.src;
3506 if (sin6->sin6_len == 0) {
3507 sin6->sin6_len = sizeof(*sin6);
3508 sin6->sin6_family = AF_INET6;
3509 sin6->sin6_port = IPSEC_PORT_ANY;
3510 bcopy(&ip6->ip6_src, &sin6->sin6_addr,
3511 sizeof(ip6->ip6_src));
3512 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
3513 /* fix scope id for comparing SPD */
3514 sin6->sin6_addr.s6_addr16[1] = 0;
3515 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
3516 }
3517 }
3518 sin6 = (struct sockaddr_in6 *)&saidx.dst;
3519 if (sin6->sin6_len == 0) {
3520 sin6->sin6_len = sizeof(*sin6);
3521 sin6->sin6_family = AF_INET6;
3522 sin6->sin6_port = IPSEC_PORT_ANY;
3523 bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
3524 sizeof(ip6->ip6_dst));
3525 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
3526 /* fix scope id for comparing SPD */
3527 sin6->sin6_addr.s6_addr16[1] = 0;
3528 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
3529 }
3530 }
3531 }
3532
2d21ac55 3533 if (key_checkrequest(isr, &saidx, &sav) == ENOENT) {
1c79356b
A
3534 /*
3535 * IPsec processing is required, but no SA found.
3536 * I assume that key_acquire() had been called
3537 * to get/establish the SA. Here I discard
3538 * this packet because it is responsibility for
3539 * upper layer to retransmit the packet.
3540 */
2d21ac55 3541 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
1c79356b
A
3542 error = ENOENT;
3543 goto bad;
3544 }
3545
3546 /* validity check */
2d21ac55 3547 if (sav == NULL) {
1c79356b
A
3548 switch (ipsec_get_reqlevel(isr)) {
3549 case IPSEC_LEVEL_USE:
3550 continue;
3551 case IPSEC_LEVEL_REQUIRE:
3552 /* must be not reached here. */
3553 panic("ipsec6_output_tunnel: no SA found, but required.");
3554 }
3555 }
3556
3557 /*
3558 * If there is no valid SA, we give up to process.
3559 * see same place at ipsec4_output().
3560 */
2d21ac55
A
3561 if (sav->state != SADB_SASTATE_MATURE
3562 && sav->state != SADB_SASTATE_DYING) {
3563 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
1c79356b
A
3564 error = EINVAL;
3565 goto bad;
3566 }
3567
1c79356b
A
3568 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3569 /*
3570 * build IPsec tunnel.
3571 */
1c79356b
A
3572 state->m = ipsec6_splithdr(state->m);
3573 if (!state->m) {
2d21ac55 3574 IPSEC_STAT_INCREMENT(ipsec6stat.out_nomem);
1c79356b
A
3575 error = ENOMEM;
3576 goto bad;
3577 }
2d21ac55
A
3578
3579 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family == AF_INET6) {
3580 error = ipsec6_encapsulate(state->m, sav);
3581 if (error) {
3582 state->m = 0;
3583 goto bad;
3584 }
3585 ip6 = mtod(state->m, struct ip6_hdr *);
3586 } else if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family == AF_INET) {
3587
3588 struct ip *ip;
3589 struct sockaddr_in* dst4;
3590 struct route *ro4 = NULL;
6d2010ae 3591 struct route ro4_copy;
316670eb
A
3592 struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 },
3593 IPOAF_SELECT_SRCIF };
2d21ac55
A
3594
3595 /*
3596 * must be last isr because encapsulated IPv6 packet
3597 * will be sent by calling ip_output
3598 */
3599 if (isr->next) {
3600 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3601 "IPv4 must be outer layer, spi=%u\n",
3602 (u_int32_t)ntohl(sav->spi)));
3603 error = EINVAL;
3604 goto bad;
3605 }
ebb1b9f4 3606 state->tunneled = 4; /* must not process any further in ip6_output */
2d21ac55
A
3607 error = ipsec64_encapsulate(state->m, sav);
3608 if (error) {
3609 state->m = 0;
3610 goto bad;
3611 }
3612 /* Now we have an IPv4 packet */
3613 ip = mtod(state->m, struct ip *);
3614
6d2010ae
A
3615 // grab sadb_mutex, to update sah's route cache and get a local copy of it
3616 lck_mtx_lock(sadb_mutex);
2d21ac55 3617 ro4 = &sav->sah->sa_route;
316670eb 3618 dst4 = (struct sockaddr_in *)(void *)&ro4->ro_dst;
6d2010ae
A
3619 if (ro4->ro_rt) {
3620 RT_LOCK(ro4->ro_rt);
3621 }
b0d623f7
A
3622 if (ro4->ro_rt != NULL &&
3623 (ro4->ro_rt->generation_id != route_generation ||
3624 !(ro4->ro_rt->rt_flags & RTF_UP) ||
3625 dst4->sin_addr.s_addr != ip->ip_dst.s_addr)) {
6d2010ae 3626 RT_UNLOCK(ro4->ro_rt);
2d21ac55
A
3627 rtfree(ro4->ro_rt);
3628 ro4->ro_rt = NULL;
3629 }
3630 if (ro4->ro_rt == NULL) {
3631 dst4->sin_family = AF_INET;
3632 dst4->sin_len = sizeof(*dst4);
3633 dst4->sin_addr = ip->ip_dst;
6d2010ae
A
3634 } else {
3635 RT_UNLOCK(ro4->ro_rt);
2d21ac55 3636 }
6d2010ae
A
3637 route_copyout(&ro4_copy, ro4, sizeof(ro4_copy));
3638 // release sadb_mutex, after updating sah's route cache and getting a local copy
3639 lck_mtx_unlock(sadb_mutex);
2d21ac55
A
3640 state->m = ipsec4_splithdr(state->m);
3641 if (!state->m) {
3642 error = ENOMEM;
6d2010ae
A
3643 if (ro4_copy.ro_rt != NULL) {
3644 rtfree(ro4_copy.ro_rt);
3645 }
2d21ac55
A
3646 goto bad;
3647 }
3648 switch (isr->saidx.proto) {
3649 case IPPROTO_ESP:
3650#if IPSEC_ESP
3651 if ((error = esp4_output(state->m, sav)) != 0) {
3652 state->m = NULL;
6d2010ae
A
3653 if (ro4_copy.ro_rt != NULL) {
3654 rtfree(ro4_copy.ro_rt);
3655 }
2d21ac55
A
3656 goto bad;
3657 }
3658 break;
3659
3660#else
3661 m_freem(state->m);
3662 state->m = NULL;
3663 error = EINVAL;
6d2010ae
A
3664 if (ro4_copy.ro_rt != NULL) {
3665 rtfree(ro4_copy.ro_rt);
3666 }
2d21ac55
A
3667 goto bad;
3668#endif
3669 case IPPROTO_AH:
3670 if ((error = ah4_output(state->m, sav)) != 0) {
3671 state->m = NULL;
6d2010ae
A
3672 if (ro4_copy.ro_rt != NULL) {
3673 rtfree(ro4_copy.ro_rt);
3674 }
2d21ac55
A
3675 goto bad;
3676 }
3677 break;
3678 case IPPROTO_IPCOMP:
3679 if ((error = ipcomp4_output(state->m, sav)) != 0) {
3680 state->m = NULL;
6d2010ae
A
3681 if (ro4_copy.ro_rt != NULL) {
3682 rtfree(ro4_copy.ro_rt);
3683 }
2d21ac55
A
3684 goto bad;
3685 }
3686 break;
3687 default:
3688 ipseclog((LOG_ERR,
3689 "ipsec4_output: unknown ipsec protocol %d\n",
3690 isr->saidx.proto));
3691 m_freem(state->m);
3692 state->m = NULL;
3693 error = EINVAL;
6d2010ae
A
3694 if (ro4_copy.ro_rt != NULL) {
3695 rtfree(ro4_copy.ro_rt);
3696 }
2d21ac55
A
3697 goto bad;
3698 }
3699
3700 if (state->m == 0) {
3701 error = ENOMEM;
6d2010ae
A
3702 if (ro4_copy.ro_rt != NULL) {
3703 rtfree(ro4_copy.ro_rt);
3704 }
2d21ac55
A
3705 goto bad;
3706 }
3707 ip = mtod(state->m, struct ip *);
3708 ip->ip_len = ntohs(ip->ip_len); /* flip len field before calling ip_output */
6d2010ae 3709 error = ip_output(state->m, NULL, &ro4_copy, IP_OUTARGS, NULL, &ipoa);
2d21ac55 3710 state->m = NULL;
6d2010ae
A
3711 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
3712 lck_mtx_lock(sadb_mutex);
3713 route_copyin(&ro4_copy, ro4, sizeof(ro4_copy));
3714 lck_mtx_unlock(sadb_mutex);
b7266188
A
3715 if (error != 0)
3716 goto bad;
2d21ac55
A
3717 goto done;
3718 } else {
3719 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3720 "unsupported inner family, spi=%u\n",
3721 (u_int32_t)ntohl(sav->spi)));
3722 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
3723 error = EAFNOSUPPORT;
1c79356b
A
3724 goto bad;
3725 }
6d2010ae
A
3726
3727 // grab sadb_mutex, before updating sah's route cache
3728 lck_mtx_lock(sadb_mutex);
ebb1b9f4 3729 ro6 = &sav->sah->sa_route;
316670eb 3730 dst6 = (struct sockaddr_in6 *)(void *)&ro6->ro_dst;
ebb1b9f4
A
3731 if (ro6->ro_rt) {
3732 RT_LOCK(ro6->ro_rt);
6d2010ae 3733 }
ebb1b9f4
A
3734 if (ro6->ro_rt != NULL &&
3735 (ro6->ro_rt->generation_id != route_generation ||
3736 !(ro6->ro_rt->rt_flags & RTF_UP) ||
b0d623f7 3737 !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))) {
ebb1b9f4
A
3738 RT_UNLOCK(ro6->ro_rt);
3739 rtfree(ro6->ro_rt);
3740 ro6->ro_rt = NULL;
1c79356b 3741 }
ebb1b9f4 3742 if (ro6->ro_rt == 0) {
1c79356b
A
3743 bzero(dst6, sizeof(*dst6));
3744 dst6->sin6_family = AF_INET6;
3745 dst6->sin6_len = sizeof(*dst6);
3746 dst6->sin6_addr = ip6->ip6_dst;
ebb1b9f4
A
3747 rtalloc(ro6);
3748 if (ro6->ro_rt) {
3749 RT_LOCK(ro6->ro_rt);
6d2010ae 3750 }
1c79356b 3751 }
ebb1b9f4 3752 if (ro6->ro_rt == 0) {
1c79356b 3753 ip6stat.ip6s_noroute++;
2d21ac55 3754 IPSEC_STAT_INCREMENT(ipsec6stat.out_noroute);
1c79356b 3755 error = EHOSTUNREACH;
6d2010ae
A
3756 // release sadb_mutex, after updating sah's route cache
3757 lck_mtx_unlock(sadb_mutex);
1c79356b
A
3758 goto bad;
3759 }
9bccf70c 3760
b0d623f7
A
3761 /*
3762 * adjust state->dst if tunnel endpoint is offlink
3763 *
3764 * XXX: caching rt_gateway value in the state is
3765 * not really good, since it may point elsewhere
3766 * when the gateway gets modified to a larger
3767 * sockaddr via rt_setgate(). This is currently
3768 * addressed by SA_SIZE roundup in that routine.
3769 */
ebb1b9f4 3770 if (ro6->ro_rt->rt_flags & RTF_GATEWAY)
316670eb 3771 dst6 = (struct sockaddr_in6 *)(void *)ro6->ro_rt->rt_gateway;
ebb1b9f4
A
3772 RT_UNLOCK(ro6->ro_rt);
3773 if (state->ro.ro_rt != NULL) {
3774 rtfree(state->ro.ro_rt);
3775 state->ro.ro_rt = NULL;
1c79356b 3776 }
ebb1b9f4
A
3777 route_copyout(&state->ro, ro6, sizeof(state->ro));
3778 state->dst = (struct sockaddr *)dst6;
3779 state->tunneled = 6;
6d2010ae
A
3780 // release sadb_mutex, after updating sah's route cache
3781 lck_mtx_unlock(sadb_mutex);
91447636 3782 }
1c79356b
A
3783
3784 state->m = ipsec6_splithdr(state->m);
3785 if (!state->m) {
2d21ac55 3786 IPSEC_STAT_INCREMENT(ipsec6stat.out_nomem);
1c79356b
A
3787 error = ENOMEM;
3788 goto bad;
3789 }
3790 ip6 = mtod(state->m, struct ip6_hdr *);
3791 switch (isr->saidx.proto) {
3792 case IPPROTO_ESP:
3793#if IPSEC_ESP
2d21ac55 3794 error = esp6_output(state->m, &ip6->ip6_nxt, state->m->m_next, sav);
1c79356b
A
3795#else
3796 m_freem(state->m);
3797 error = EINVAL;
3798#endif
3799 break;
3800 case IPPROTO_AH:
2d21ac55 3801 error = ah6_output(state->m, &ip6->ip6_nxt, state->m->m_next, sav);
1c79356b
A
3802 break;
3803 case IPPROTO_IPCOMP:
3804 /* XXX code should be here */
3805 /*FALLTHROUGH*/
3806 default:
3807 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3808 "unknown ipsec protocol %d\n", isr->saidx.proto));
3809 m_freem(state->m);
2d21ac55 3810 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
1c79356b
A
3811 error = EINVAL;
3812 break;
3813 }
3814 if (error) {
3815 state->m = NULL;
3816 goto bad;
3817 }
3818 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3819 if (plen > IPV6_MAXPACKET) {
3820 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3821 "IPsec with IPv6 jumbogram is not supported\n"));
2d21ac55 3822 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
1c79356b
A
3823 error = EINVAL; /*XXX*/
3824 goto bad;
3825 }
3826 ip6 = mtod(state->m, struct ip6_hdr *);
3827 ip6->ip6_plen = htons(plen);
3828 }
2d21ac55
A
3829done:
3830 if (sav)
3831 key_freesav(sav, KEY_SADB_UNLOCKED);
1c79356b
A
3832 return 0;
3833
3834bad:
2d21ac55
A
3835 if (sav)
3836 key_freesav(sav, KEY_SADB_UNLOCKED);
3837 if (state->m)
3838 m_freem(state->m);
1c79356b
A
3839 state->m = NULL;
3840 return error;
3841}
3842#endif /*INET6*/
3843
9bccf70c 3844#if INET
1c79356b
A
3845/*
3846 * Chop IP header and option off from the payload.
3847 */
316670eb 3848struct mbuf *
1c79356b
A
3849ipsec4_splithdr(m)
3850 struct mbuf *m;
3851{
3852 struct mbuf *mh;
3853 struct ip *ip;
3854 int hlen;
3855
3856 if (m->m_len < sizeof(struct ip))
316670eb 3857 panic("ipsec4_splithdr: first mbuf too short, m_len %d, pkt_len %d, m_flag %x", m->m_len, m->m_pkthdr.len, m->m_flags);
1c79356b
A
3858 ip = mtod(m, struct ip *);
3859#ifdef _IP_VHL
9bccf70c 3860 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
1c79356b
A
3861#else
3862 hlen = ip->ip_hl << 2;
3863#endif
3864 if (m->m_len > hlen) {
2d21ac55 3865 MGETHDR(mh, M_DONTWAIT, MT_HEADER); /* MAC-OK */
1c79356b
A
3866 if (!mh) {
3867 m_freem(m);
3868 return NULL;
3869 }
3870 M_COPY_PKTHDR(mh, m);
3871 MH_ALIGN(mh, hlen);
3872 m->m_flags &= ~M_PKTHDR;
2d21ac55 3873 m_mchtype(m, MT_DATA);
1c79356b
A
3874 m->m_len -= hlen;
3875 m->m_data += hlen;
3876 mh->m_next = m;
3877 m = mh;
3878 m->m_len = hlen;
3879 bcopy((caddr_t)ip, mtod(m, caddr_t), hlen);
3880 } else if (m->m_len < hlen) {
3881 m = m_pullup(m, hlen);
3882 if (!m)
3883 return NULL;
3884 }
3885 return m;
3886}
9bccf70c 3887#endif
1c79356b
A
3888
3889#if INET6
316670eb 3890struct mbuf *
1c79356b
A
3891ipsec6_splithdr(m)
3892 struct mbuf *m;
3893{
3894 struct mbuf *mh;
3895 struct ip6_hdr *ip6;
3896 int hlen;
3897
3898 if (m->m_len < sizeof(struct ip6_hdr))
3899 panic("ipsec6_splithdr: first mbuf too short");
3900 ip6 = mtod(m, struct ip6_hdr *);
3901 hlen = sizeof(struct ip6_hdr);
3902 if (m->m_len > hlen) {
2d21ac55 3903 MGETHDR(mh, M_DONTWAIT, MT_HEADER); /* MAC-OK */
1c79356b
A
3904 if (!mh) {
3905 m_freem(m);
3906 return NULL;
3907 }
3908 M_COPY_PKTHDR(mh, m);
3909 MH_ALIGN(mh, hlen);
3910 m->m_flags &= ~M_PKTHDR;
2d21ac55 3911 m_mchtype(m, MT_DATA);
1c79356b
A
3912 m->m_len -= hlen;
3913 m->m_data += hlen;
3914 mh->m_next = m;
3915 m = mh;
3916 m->m_len = hlen;
3917 bcopy((caddr_t)ip6, mtod(m, caddr_t), hlen);
3918 } else if (m->m_len < hlen) {
3919 m = m_pullup(m, hlen);
3920 if (!m)
3921 return NULL;
3922 }
3923 return m;
3924}
3925#endif
3926
3927/* validate inbound IPsec tunnel packet. */
3928int
2d21ac55 3929ipsec4_tunnel_validate(m, off, nxt0, sav, ifamily)
9bccf70c
A
3930 struct mbuf *m; /* no pullup permitted, m->m_len >= ip */
3931 int off;
1c79356b
A
3932 u_int nxt0;
3933 struct secasvar *sav;
2d21ac55 3934 sa_family_t *ifamily;
1c79356b
A
3935{
3936 u_int8_t nxt = nxt0 & 0xff;
3937 struct sockaddr_in *sin;
2d21ac55
A
3938 struct sockaddr_in osrc, odst, i4src, i4dst;
3939 struct sockaddr_in6 i6src, i6dst;
1c79356b 3940 int hlen;
9bccf70c
A
3941 struct secpolicy *sp;
3942 struct ip *oip;
1c79356b 3943
2d21ac55 3944 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
91447636 3945
9bccf70c
A
3946#if DIAGNOSTIC
3947 if (m->m_len < sizeof(struct ip))
3948 panic("too short mbuf on ipsec4_tunnel_validate");
3949#endif
2d21ac55 3950 if (nxt != IPPROTO_IPV4 && nxt != IPPROTO_IPV6)
1c79356b 3951 return 0;
9bccf70c
A
3952 if (m->m_pkthdr.len < off + sizeof(struct ip))
3953 return 0;
3954 /* do not decapsulate if the SA is for transport mode only */
3955 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3956 return 0;
3957
3958 oip = mtod(m, struct ip *);
1c79356b 3959#ifdef _IP_VHL
9bccf70c 3960 hlen = _IP_VHL_HL(oip->ip_vhl) << 2;
1c79356b 3961#else
9bccf70c 3962 hlen = oip->ip_hl << 2;
1c79356b
A
3963#endif
3964 if (hlen != sizeof(struct ip))
3965 return 0;
9bccf70c 3966
9bccf70c
A
3967 sin = (struct sockaddr_in *)&sav->sah->saidx.dst;
3968 if (sin->sin_family != AF_INET)
1c79356b 3969 return 0;
9bccf70c
A
3970 if (bcmp(&oip->ip_dst, &sin->sin_addr, sizeof(oip->ip_dst)) != 0)
3971 return 0;
3972
316670eb
A
3973 if (sav->utun_in_fn) {
3974 // the utun SAs don't have a policy (yet).
3975 if (nxt == IPPROTO_IPV4) {
3976 *ifamily = AF_INET;
3977 } else if (nxt == IPPROTO_IPV6) {
3978 *ifamily = AF_INET6;
3979 } else {
3980 return 0;
3981 }
3982 return 1;
3983 }
3984
9bccf70c
A
3985 /* XXX slow */
3986 bzero(&osrc, sizeof(osrc));
3987 bzero(&odst, sizeof(odst));
2d21ac55
A
3988 osrc.sin_family = odst.sin_family = AF_INET;
3989 osrc.sin_len = odst.sin_len = sizeof(struct sockaddr_in);
9bccf70c
A
3990 osrc.sin_addr = oip->ip_src;
3991 odst.sin_addr = oip->ip_dst;
9bccf70c
A
3992 /*
3993 * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
3994 * - if the inner destination is multicast address, there can be
3995 * multiple permissible inner source address. implementation
3996 * may want to skip verification of inner source address against
3997 * SPD selector.
3998 * - if the inner protocol is ICMP, the packet may be an error report
3999 * from routers on the other side of the VPN cloud (R in the
4000 * following diagram). in this case, we cannot verify inner source
4001 * address against SPD selector.
4002 * me -- gw === gw -- R -- you
4003 *
4004 * we consider the first bullet to be users responsibility on SPD entry
4005 * configuration (if you need to encrypt multicast traffic, set
4006 * the source range of SPD selector to 0.0.0.0/0, or have explicit
4007 * address ranges for possible senders).
4008 * the second bullet is not taken care of (yet).
4009 *
4010 * therefore, we do not do anything special about inner source.
4011 */
2d21ac55
A
4012 if (nxt == IPPROTO_IPV4) {
4013 bzero(&i4src, sizeof(struct sockaddr_in));
4014 bzero(&i4dst, sizeof(struct sockaddr_in));
4015 i4src.sin_family = i4dst.sin_family = *ifamily = AF_INET;
4016 i4src.sin_len = i4dst.sin_len = sizeof(struct sockaddr_in);
4017 m_copydata(m, off + offsetof(struct ip, ip_src), sizeof(i4src.sin_addr),
4018 (caddr_t)&i4src.sin_addr);
4019 m_copydata(m, off + offsetof(struct ip, ip_dst), sizeof(i4dst.sin_addr),
4020 (caddr_t)&i4dst.sin_addr);
4021 sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
4022 (struct sockaddr *)&i4src, (struct sockaddr *)&i4dst);
4023 } else if (nxt == IPPROTO_IPV6) {
4024 bzero(&i6src, sizeof(struct sockaddr_in6));
4025 bzero(&i6dst, sizeof(struct sockaddr_in6));
4026 i6src.sin6_family = i6dst.sin6_family = *ifamily = AF_INET6;
4027 i6src.sin6_len = i6dst.sin6_len = sizeof(struct sockaddr_in6);
4028 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_src), sizeof(i6src.sin6_addr),
4029 (caddr_t)&i6src.sin6_addr);
4030 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst), sizeof(i6dst.sin6_addr),
4031 (caddr_t)&i6dst.sin6_addr);
4032 sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
4033 (struct sockaddr *)&i6src, (struct sockaddr *)&i6dst);
4034 } else
4035 return 0; /* unsupported family */
4036
4037 if (!sp)
9bccf70c 4038 return 0;
2d21ac55
A
4039
4040 key_freesp(sp, KEY_SADB_UNLOCKED);
1c79356b
A
4041
4042 return 1;
4043}
4044
4045#if INET6
4046/* validate inbound IPsec tunnel packet. */
4047int
9bccf70c
A
4048ipsec6_tunnel_validate(m, off, nxt0, sav)
4049 struct mbuf *m; /* no pullup permitted, m->m_len >= ip */
4050 int off;
1c79356b
A
4051 u_int nxt0;
4052 struct secasvar *sav;
4053{
4054 u_int8_t nxt = nxt0 & 0xff;
4055 struct sockaddr_in6 *sin6;
9bccf70c
A
4056 struct sockaddr_in6 osrc, odst, isrc, idst;
4057 struct secpolicy *sp;
4058 struct ip6_hdr *oip6;
1c79356b 4059
2d21ac55
A
4060 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
4061
9bccf70c
A
4062#if DIAGNOSTIC
4063 if (m->m_len < sizeof(struct ip6_hdr))
4064 panic("too short mbuf on ipsec6_tunnel_validate");
4065#endif
1c79356b
A
4066 if (nxt != IPPROTO_IPV6)
4067 return 0;
9bccf70c
A
4068 if (m->m_pkthdr.len < off + sizeof(struct ip6_hdr))
4069 return 0;
4070 /* do not decapsulate if the SA is for transport mode only */
4071 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
4072 return 0;
4073
4074 oip6 = mtod(m, struct ip6_hdr *);
4075 /* AF_INET should be supported, but at this moment we don't. */
4076 sin6 = (struct sockaddr_in6 *)&sav->sah->saidx.dst;
4077 if (sin6->sin6_family != AF_INET6)
4078 return 0;
4079 if (!IN6_ARE_ADDR_EQUAL(&oip6->ip6_dst, &sin6->sin6_addr))
1c79356b 4080 return 0;
9bccf70c 4081
316670eb
A
4082 if (sav->utun_in_fn) {
4083 // the utun SAs don't have a policy (yet).
4084 return 1;
4085 }
4086
9bccf70c
A
4087 /* XXX slow */
4088 bzero(&osrc, sizeof(osrc));
4089 bzero(&odst, sizeof(odst));
4090 bzero(&isrc, sizeof(isrc));
4091 bzero(&idst, sizeof(idst));
4092 osrc.sin6_family = odst.sin6_family = isrc.sin6_family =
4093 idst.sin6_family = AF_INET6;
4094 osrc.sin6_len = odst.sin6_len = isrc.sin6_len = idst.sin6_len =
4095 sizeof(struct sockaddr_in6);
4096 osrc.sin6_addr = oip6->ip6_src;
4097 odst.sin6_addr = oip6->ip6_dst;
4098 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_src),
4099 sizeof(isrc.sin6_addr), (caddr_t)&isrc.sin6_addr);
4100 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
4101 sizeof(idst.sin6_addr), (caddr_t)&idst.sin6_addr);
4102
4103 /*
4104 * regarding to inner source address validation, see a long comment
4105 * in ipsec4_tunnel_validate.
4106 */
4107
4108 sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
4109 (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
55e303ae
A
4110 /*
4111 * when there is no suitable inbound policy for the packet of the ipsec
4112 * tunnel mode, the kernel never decapsulate the tunneled packet
4113 * as the ipsec tunnel mode even when the system wide policy is "none".
4114 * then the kernel leaves the generic tunnel module to process this
4115 * packet. if there is no rule of the generic tunnel, the packet
4116 * is rejected and the statistics will be counted up.
4117 */
9bccf70c
A
4118 if (!sp)
4119 return 0;
2d21ac55 4120 key_freesp(sp, KEY_SADB_UNLOCKED);
1c79356b
A
4121
4122 return 1;
4123}
4124#endif
4125
4126/*
4127 * Make a mbuf chain for encryption.
4128 * If the original mbuf chain contains a mbuf with a cluster,
4129 * allocate a new cluster and copy the data to the new cluster.
4130 * XXX: this hack is inefficient, but is necessary to handle cases
4131 * of TCP retransmission...
4132 */
4133struct mbuf *
4134ipsec_copypkt(m)
4135 struct mbuf *m;
4136{
4137 struct mbuf *n, **mpp, *mnew;
4138
4139 for (n = m, mpp = &m; n; n = n->m_next) {
4140 if (n->m_flags & M_EXT) {
4141 /*
4142 * Make a copy only if there are more than one references
4143 * to the cluster.
4144 * XXX: is this approach effective?
4145 */
4146 if (
1c79356b 4147 n->m_ext.ext_free ||
d12e1678 4148 m_mclhasreference(n)
1c79356b
A
4149 )
4150 {
4151 int remain, copied;
4152 struct mbuf *mm;
4153
4154 if (n->m_flags & M_PKTHDR) {
2d21ac55 4155 MGETHDR(mnew, M_DONTWAIT, MT_HEADER); /* MAC-OK */
1c79356b
A
4156 if (mnew == NULL)
4157 goto fail;
1c79356b 4158 M_COPY_PKTHDR(mnew, n);
1c79356b
A
4159 }
4160 else {
4161 MGET(mnew, M_DONTWAIT, MT_DATA);
4162 if (mnew == NULL)
4163 goto fail;
4164 }
4165 mnew->m_len = 0;
4166 mm = mnew;
4167
4168 /*
4169 * Copy data. If we don't have enough space to
4170 * store the whole data, allocate a cluster
4171 * or additional mbufs.
4172 * XXX: we don't use m_copyback(), since the
4173 * function does not use clusters and thus is
4174 * inefficient.
4175 */
4176 remain = n->m_len;
4177 copied = 0;
9bccf70c 4178 while (1) {
1c79356b
A
4179 int len;
4180 struct mbuf *mn;
4181
4182 if (remain <= (mm->m_flags & M_PKTHDR ? MHLEN : MLEN))
4183 len = remain;
4184 else { /* allocate a cluster */
4185 MCLGET(mm, M_DONTWAIT);
4186 if (!(mm->m_flags & M_EXT)) {
4187 m_free(mm);
4188 goto fail;
4189 }
4190 len = remain < MCLBYTES ?
4191 remain : MCLBYTES;
4192 }
4193
4194 bcopy(n->m_data + copied, mm->m_data,
4195 len);
4196
4197 copied += len;
4198 remain -= len;
4199 mm->m_len = len;
4200
4201 if (remain <= 0) /* completed? */
4202 break;
4203
4204 /* need another mbuf */
2d21ac55 4205 MGETHDR(mn, M_DONTWAIT, MT_HEADER); /* XXXMAC: tags copied next time in loop? */
1c79356b
A
4206 if (mn == NULL)
4207 goto fail;
9bccf70c 4208 mn->m_pkthdr.rcvif = NULL;
1c79356b
A
4209 mm->m_next = mn;
4210 mm = mn;
4211 }
4212
4213 /* adjust chain */
4214 mm->m_next = m_free(n);
4215 n = mm;
4216 *mpp = mnew;
4217 mpp = &n->m_next;
4218
4219 continue;
4220 }
4221 }
4222 *mpp = n;
4223 mpp = &n->m_next;
4224 }
4225
4226 return(m);
4227 fail:
4228 m_freem(m);
4229 return(NULL);
4230}
4231
2d21ac55
A
4232/*
4233 * Tags are allocated as mbufs for now, since our minimum size is MLEN, we
4234 * should make use of up to that much space.
4235 */
4236#define IPSEC_TAG_HEADER \
4237
4238struct ipsec_tag {
4239 struct socket *socket;
4240 u_int32_t history_count;
4241 struct ipsec_history history[];
4242};
4243
4244#define IPSEC_TAG_SIZE (MLEN - sizeof(struct m_tag))
4245#define IPSEC_TAG_HDR_SIZE (offsetof(struct ipsec_tag, history[0]))
4246#define IPSEC_HISTORY_MAX ((IPSEC_TAG_SIZE - IPSEC_TAG_HDR_SIZE) / \
4247 sizeof(struct ipsec_history))
4248
4249static struct ipsec_tag *
4250ipsec_addaux(
4251 struct mbuf *m)
1c79356b 4252{
2d21ac55
A
4253 struct m_tag *tag;
4254
4255 /* Check if the tag already exists */
4256 tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC, NULL);
4257
4258 if (tag == NULL) {
4259 struct ipsec_tag *itag;
4260
4261 /* Allocate a tag */
6d2010ae
A
4262 tag = m_tag_create(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC,
4263 IPSEC_TAG_SIZE, M_DONTWAIT, m);
2d21ac55
A
4264
4265 if (tag) {
4266 itag = (struct ipsec_tag*)(tag + 1);
4267 itag->socket = 0;
4268 itag->history_count = 0;
4269
4270 m_tag_prepend(m, tag);
4271 }
4272 }
4273
4274 return tag ? (struct ipsec_tag*)(tag + 1) : NULL;
1c79356b
A
4275}
4276
2d21ac55
A
4277static struct ipsec_tag *
4278ipsec_findaux(
4279 struct mbuf *m)
1c79356b 4280{
2d21ac55
A
4281 struct m_tag *tag;
4282
4283 tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC, NULL);
4284
4285 return tag ? (struct ipsec_tag*)(tag + 1) : NULL;
1c79356b
A
4286}
4287
9bccf70c 4288void
2d21ac55
A
4289ipsec_delaux(
4290 struct mbuf *m)
1c79356b 4291{
2d21ac55
A
4292 struct m_tag *tag;
4293
4294 tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC, NULL);
4295
4296 if (tag) {
4297 m_tag_delete(m, tag);
4298 }
1c79356b
A
4299}
4300
9bccf70c
A
4301/* if the aux buffer is unnecessary, nuke it. */
4302static void
2d21ac55
A
4303ipsec_optaux(
4304 struct mbuf *m,
4305 struct ipsec_tag *itag)
9bccf70c 4306{
2d21ac55
A
4307 if (itag && itag->socket == NULL && itag->history_count == 0) {
4308 m_tag_delete(m, ((struct m_tag*)itag) - 1);
4309 }
9bccf70c 4310}
1c79356b
A
4311
4312int
2d21ac55
A
4313ipsec_setsocket(
4314 struct mbuf *m,
4315 struct socket *so)
1c79356b 4316{
2d21ac55 4317 struct ipsec_tag *tag;
1c79356b 4318
9bccf70c
A
4319 /* if so == NULL, don't insist on getting the aux mbuf */
4320 if (so) {
2d21ac55
A
4321 tag = ipsec_addaux(m);
4322 if (!tag)
9bccf70c
A
4323 return ENOBUFS;
4324 } else
2d21ac55
A
4325 tag = ipsec_findaux(m);
4326 if (tag) {
4327 tag->socket = so;
4328 ipsec_optaux(m, tag);
4329 }
9bccf70c
A
4330 return 0;
4331}
1c79356b 4332
9bccf70c 4333struct socket *
2d21ac55
A
4334ipsec_getsocket(
4335 struct mbuf *m)
9bccf70c 4336{
2d21ac55
A
4337 struct ipsec_tag *itag;
4338
4339 itag = ipsec_findaux(m);
4340 if (itag)
4341 return itag->socket;
9bccf70c
A
4342 else
4343 return NULL;
4344}
1c79356b
A
4345
4346int
2d21ac55
A
4347ipsec_addhist(
4348 struct mbuf *m,
4349 int proto,
4350 u_int32_t spi)
1c79356b 4351{
2d21ac55
A
4352 struct ipsec_tag *itag;
4353 struct ipsec_history *p;
4354 itag = ipsec_addaux(m);
4355 if (!itag)
9bccf70c 4356 return ENOBUFS;
2d21ac55 4357 if (itag->history_count == IPSEC_HISTORY_MAX)
55e303ae 4358 return ENOSPC; /* XXX */
2d21ac55
A
4359
4360 p = &itag->history[itag->history_count];
4361 itag->history_count++;
4362
9bccf70c
A
4363 bzero(p, sizeof(*p));
4364 p->ih_proto = proto;
4365 p->ih_spi = spi;
2d21ac55 4366
9bccf70c 4367 return 0;
1c79356b
A
4368}
4369
9bccf70c 4370struct ipsec_history *
2d21ac55
A
4371ipsec_gethist(
4372 struct mbuf *m,
4373 int *lenp)
9bccf70c 4374{
2d21ac55
A
4375 struct ipsec_tag *itag;
4376
4377 itag = ipsec_findaux(m);
4378 if (!itag)
9bccf70c 4379 return NULL;
2d21ac55 4380 if (itag->history_count == 0)
9bccf70c 4381 return NULL;
9bccf70c 4382 if (lenp)
2d21ac55
A
4383 *lenp = (int)(itag->history_count * sizeof(struct ipsec_history));
4384 return itag->history;
9bccf70c 4385}
1c79356b 4386
9bccf70c 4387void
2d21ac55
A
4388ipsec_clearhist(
4389 struct mbuf *m)
1c79356b 4390{
2d21ac55
A
4391 struct ipsec_tag *itag;
4392
4393 itag = ipsec_findaux(m);
4394 if (itag) {
4395 itag->history_count = 0;
4396 }
4397 ipsec_optaux(m, itag);
1c79356b 4398}
55e303ae 4399
b0d623f7 4400__private_extern__ int
55e303ae
A
4401ipsec_send_natt_keepalive(
4402 struct secasvar *sav)
4403{
316670eb
A
4404 struct mbuf *m;
4405 struct ip *ip;
4406 int error;
4407 struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF };
4408 struct route ro;
91447636 4409
2d21ac55 4410 lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
316670eb 4411
b0d623f7
A
4412 if ((esp_udp_encap_port & 0xFFFF) == 0 || sav->remote_ike_port == 0) return FALSE;
4413
4414 // natt timestamp may have changed... reverify
4415 if ((natt_now - sav->natt_last_activity) < natt_keepalive_interval) return FALSE;
4416
316670eb
A
4417 if (sav->flags & SADB_X_EXT_ESP_KEEPALIVE) return FALSE; // don't send these from the kernel
4418
55e303ae 4419 m = m_gethdr(M_NOWAIT, MT_DATA);
b0d623f7 4420 if (m == NULL) return FALSE;
316670eb
A
4421
4422 ip = (__typeof__(ip))m_mtod(m);
4423
4424 // this sends one type of NATT keepalives (Type 1, ESP keepalives, aren't sent by kernel)
4425 if ((sav->flags & SADB_X_EXT_ESP_KEEPALIVE) == 0) {
4426 struct udphdr *uh;
4427
4428 /*
4429 * Type 2: a UDP packet complete with IP header.
4430 * We must do this because UDP output requires
4431 * an inpcb which we don't have. UDP packet
4432 * contains one byte payload. The byte is set
4433 * to 0xFF.
4434 */
4435 uh = (__typeof__(uh))(void *)((char *)m_mtod(m) + sizeof(*ip));
4436 m->m_len = sizeof(struct udpiphdr) + 1;
4437 bzero(m_mtod(m), m->m_len);
4438 m->m_pkthdr.len = m->m_len;
4439
4440 ip->ip_len = m->m_len;
4441 ip->ip_ttl = ip_defttl;
4442 ip->ip_p = IPPROTO_UDP;
4443 if (sav->sah->dir != IPSEC_DIR_INBOUND) {
4444 ip->ip_src = ((struct sockaddr_in*)&sav->sah->saidx.src)->sin_addr;
4445 ip->ip_dst = ((struct sockaddr_in*)&sav->sah->saidx.dst)->sin_addr;
4446 } else {
4447 ip->ip_src = ((struct sockaddr_in*)&sav->sah->saidx.dst)->sin_addr;
4448 ip->ip_dst = ((struct sockaddr_in*)&sav->sah->saidx.src)->sin_addr;
4449 }
4450 uh->uh_sport = htons((u_short)esp_udp_encap_port);
4451 uh->uh_dport = htons(sav->remote_ike_port);
4452 uh->uh_ulen = htons(1 + sizeof(*uh));
4453 uh->uh_sum = 0;
4454 *(u_int8_t*)((char*)m_mtod(m) + sizeof(*ip) + sizeof(*uh)) = 0xFF;
b0d623f7 4455 }
6d2010ae
A
4456
4457 // grab sadb_mutex, to get a local copy of sah's route cache
4458 lck_mtx_lock(sadb_mutex);
4459 if (sav->sah->sa_route.ro_rt != NULL &&
4460 rt_key(sav->sah->sa_route.ro_rt)->sa_family != AF_INET) {
4461 rtfree(sav->sah->sa_route.ro_rt);
4462 sav->sah->sa_route.ro_rt = NULL;
4463 }
4464 route_copyout(&ro, &sav->sah->sa_route, sizeof(ro));
4465 lck_mtx_unlock(sadb_mutex);
4466
4467 error = ip_output(m, NULL, &ro, IP_OUTARGS | IP_NOIPSEC, NULL, &ipoa);
4468
4469 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
4470 lck_mtx_lock(sadb_mutex);
4471 route_copyin(&ro, &sav->sah->sa_route, sizeof(ro));
4472 lck_mtx_unlock(sadb_mutex);
b0d623f7 4473 if (error == 0) {
55e303ae 4474 sav->natt_last_activity = natt_now;
b0d623f7
A
4475 return TRUE;
4476 }
4477 return FALSE;
55e303ae 4478}