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