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