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