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