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