Annotation of src/sys/netipsec/ipsec.c, Revision 1.39
1.39 ! degroote 1: /* $NetBSD: ipsec.c,v 1.38 2008/06/27 05:18:58 mlelstv Exp $ */
1.1 jonathan 2: /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $ */
3: /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
4:
5: /*
6: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
1.26 degroote 13: * notice, this list of conditions and the following disclaimer.
1.1 jonathan 14: * 2. Redistributions in binary form must reproduce the above copyright
1.26 degroote 15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
1.1 jonathan 17: * 3. Neither the name of the project nor the names of its contributors
1.26 degroote 18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
1.1 jonathan 20: *
21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include <sys/cdefs.h>
1.39 ! degroote 35: __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.38 2008/06/27 05:18:58 mlelstv Exp $");
1.1 jonathan 36:
37: /*
38: * IPsec controller part.
39: */
40:
41: #include "opt_inet.h"
1.2 jonathan 42: #ifdef __FreeBSD__
1.1 jonathan 43: #include "opt_inet6.h"
1.2 jonathan 44: #endif
1.1 jonathan 45: #include "opt_ipsec.h"
46:
47: #include <sys/param.h>
48: #include <sys/systm.h>
49: #include <sys/malloc.h>
50: #include <sys/mbuf.h>
51: #include <sys/domain.h>
52: #include <sys/protosw.h>
53: #include <sys/socket.h>
54: #include <sys/socketvar.h>
55: #include <sys/errno.h>
56: #include <sys/time.h>
57: #include <sys/kernel.h>
58: #include <sys/syslog.h>
59: #include <sys/sysctl.h>
60: #include <sys/proc.h>
61:
62: #include <net/if.h>
63: #include <net/route.h>
64:
65: #include <netinet/in.h>
66: #include <netinet/in_systm.h>
67: #include <netinet/ip.h>
68: #include <netinet/ip_var.h>
69: #include <netinet/in_var.h>
70: #include <netinet/udp.h>
71: #include <netinet/udp_var.h>
72: #include <netinet/tcp.h>
73: #include <netinet/udp.h>
1.38 mlelstv 74: #include <netinet/ip_icmp.h>
1.1 jonathan 75:
76: #include <netinet/ip6.h>
77: #ifdef INET6
78: #include <netinet6/ip6_var.h>
79: #endif
80: #include <netinet/in_pcb.h>
81: #ifdef INET6
1.5 jonathan 82: #include <netinet6/in6_pcb.h>
1.1 jonathan 83: #include <netinet/icmp6.h>
84: #endif
85:
86: #include <netipsec/ipsec.h>
1.13 jonathan 87: #include <netipsec/ipsec_var.h>
1.37 thorpej 88: #include <netipsec/ipsec_private.h>
1.1 jonathan 89: #ifdef INET6
90: #include <netipsec/ipsec6.h>
91: #endif
92: #include <netipsec/ah_var.h>
93: #include <netipsec/esp_var.h>
94: #include <netipsec/ipcomp.h> /*XXX*/
95: #include <netipsec/ipcomp_var.h>
96:
1.4 tls 97: #include <netipsec/key.h>
98: #include <netipsec/keydb.h>
99: #include <netipsec/key_debug.h>
1.1 jonathan 100:
101: #include <netipsec/xform.h>
102:
103: #include <netipsec/ipsec_osdep.h>
104:
105: #include <net/net_osdep.h>
106:
107: #ifdef IPSEC_DEBUG
108: int ipsec_debug = 1;
1.21 rpaulo 109:
1.26 degroote 110: /*
1.21 rpaulo 111: * When set to 1, IPsec will send packets with the same sequence number.
112: * This allows to verify if the other side has proper replay attacks detection.
113: */
114: int ipsec_replay = 0;
115:
116: /*
117: * When set 1, IPsec will send packets with corrupted HMAC.
118: * This allows to verify if the other side properly detects modified packets.
119: */
120: int ipsec_integrity = 0;
1.1 jonathan 121: #else
122: int ipsec_debug = 0;
123: #endif
124:
1.37 thorpej 125: percpu_t *ipsecstat_percpu;
1.1 jonathan 126: int ip4_ah_offsetmask = 0; /* maybe IP_DF? */
1.18 christos 127: int ip4_ipsec_dfbit = 2; /* DF bit on encap. 0: clear 1: set 2: copy */
1.1 jonathan 128: int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
129: int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
130: int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
131: int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
132: struct secpolicy ip4_def_policy;
133: int ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
134: int ip4_esp_randpad = -1;
1.9 thorpej 135:
136: #ifdef __NetBSD__
137: u_int ipsec_spdgen = 1; /* SPD generation # */
138:
1.33 degroote 139: static struct secpolicy *ipsec_checkpcbcache (struct mbuf *,
140: struct inpcbpolicy *, int);
141: static int ipsec_fillpcbcache (struct inpcbpolicy *, struct mbuf *,
142: struct secpolicy *, int);
143: static int ipsec_invalpcbcache (struct inpcbpolicy *, int);
1.9 thorpej 144: #endif /* __NetBSD__ */
145:
1.1 jonathan 146: /*
147: * Crypto support requirements:
148: *
149: * 1 require hardware support
150: * -1 require software support
151: * 0 take anything
152: */
153: int crypto_support = 0;
154:
1.5 jonathan 155: static struct secpolicy *ipsec_getpolicybysock(struct mbuf *, u_int,
156: PCB_T *, int *);
157:
1.1 jonathan 158: #ifdef __FreeBSD__
159: SYSCTL_DECL(_net_inet_ipsec);
160:
161: /* net.inet.ipsec */
162: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
163: def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
164: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
165: CTLFLAG_RW, &ip4_esp_trans_deflev, 0, "");
166: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
167: CTLFLAG_RW, &ip4_esp_net_deflev, 0, "");
168: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
169: CTLFLAG_RW, &ip4_ah_trans_deflev, 0, "");
170: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
171: CTLFLAG_RW, &ip4_ah_net_deflev, 0, "");
172: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
1.30 degroote 173: ah_cleartos, CTLFLAG_RW, &ip4_ah_cleartos, 0, "");
1.1 jonathan 174: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
175: ah_offsetmask, CTLFLAG_RW, &ip4_ah_offsetmask, 0, "");
176: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
177: dfbit, CTLFLAG_RW, &ip4_ipsec_dfbit, 0, "");
178: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
179: ecn, CTLFLAG_RW, &ip4_ipsec_ecn, 0, "");
180: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
181: debug, CTLFLAG_RW, &ipsec_debug, 0, "");
182: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
183: esp_randpad, CTLFLAG_RW, &ip4_esp_randpad, 0, "");
184: SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
185: crypto_support, CTLFLAG_RW, &crypto_support,0, "");
186: SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
187: ipsecstats, CTLFLAG_RD, &newipsecstat, newipsecstat, "");
1.21 rpaulo 188: SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay, CTLFLAG_RW, &ipsec_replay, 0,
1.26 degroote 189: "Emulate replay attack");
1.21 rpaulo 190: SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity, CTLFLAG_RW,
1.26 degroote 191: &ipsec_integrity, 0, "Emulate man-in-the-middle attack");
1.4 tls 192: #endif /* __FreeBSD__ */
1.1 jonathan 193:
194: #ifdef INET6
195: int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
196: int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
197: int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
198: int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
1.5 jonathan 199: struct secpolicy ip6_def_policy;
1.1 jonathan 200: int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
201: int ip6_esp_randpad = -1;
202:
1.5 jonathan 203:
204: #ifdef __FreeBSD__
1.1 jonathan 205: SYSCTL_DECL(_net_inet6_ipsec6);
206:
207: /* net.inet6.ipsec6 */
208: #ifdef COMPAT_KAME
209: SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
210: 0,0, compat_ipsecstats_sysctl, "S", "");
211: #endif /* COMPAT_KAME */
212: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
213: def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
214: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
215: CTLFLAG_RW, &ip6_esp_trans_deflev, 0, "");
216: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
217: CTLFLAG_RW, &ip6_esp_net_deflev, 0, "");
218: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
219: CTLFLAG_RW, &ip6_ah_trans_deflev, 0, "");
220: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
221: CTLFLAG_RW, &ip6_ah_net_deflev, 0, "");
222: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
223: ecn, CTLFLAG_RW, &ip6_ipsec_ecn, 0, "");
224: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
225: debug, CTLFLAG_RW, &ipsec_debug, 0, "");
226: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
227: esp_randpad, CTLFLAG_RW, &ip6_esp_randpad, 0, "");
228: #endif /* INET6 */
1.6 jonathan 229: #endif /* __FreeBSD__ */
1.1 jonathan 230:
1.33 degroote 231: static int ipsec4_setspidx_inpcb (struct mbuf *, struct inpcb *);
1.1 jonathan 232: #ifdef INET6
1.33 degroote 233: static int ipsec6_setspidx_in6pcb (struct mbuf *, struct in6pcb *);
1.1 jonathan 234: #endif
1.33 degroote 235: static int ipsec_setspidx (struct mbuf *, struct secpolicyindex *, int);
236: static void ipsec4_get_ulp (struct mbuf *m, struct secpolicyindex *, int);
237: static int ipsec4_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
1.1 jonathan 238: #ifdef INET6
1.33 degroote 239: static void ipsec6_get_ulp (struct mbuf *m, struct secpolicyindex *, int);
240: static int ipsec6_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
1.1 jonathan 241: #endif
1.33 degroote 242: static void ipsec_delpcbpolicy (struct inpcbpolicy *);
243: static struct secpolicy *ipsec_deepcopy_policy (struct secpolicy *);
244: static int ipsec_set_policy (struct secpolicy **,int , void *, size_t , int );
245: static int ipsec_get_policy (struct secpolicy *, struct mbuf **);
246: static void vshiftl (unsigned char *, int, int);
247: static size_t ipsec_hdrsiz (struct secpolicy *);
1.1 jonathan 248:
1.9 thorpej 249: #ifdef __NetBSD__
250: /*
251: * Try to validate and use cached policy on a PCB.
252: */
253: static struct secpolicy *
254: ipsec_checkpcbcache(struct mbuf *m, struct inpcbpolicy *pcbsp, int dir)
255: {
256: struct secpolicyindex spidx;
257:
258: switch (dir) {
259: case IPSEC_DIR_INBOUND:
260: case IPSEC_DIR_OUTBOUND:
261: case IPSEC_DIR_ANY:
262: break;
263: default:
264: return NULL;
265: }
266: #ifdef DIAGNOSTIC
1.13 jonathan 267: if (pcbsp == NULL) {
268: printf("ipsec_checkpcbcache: NULL pcbsp\n");
269: /* XXX panic? */
270: return NULL;
271: }
272: #endif
273:
274: #ifdef DIAGNOSTIC
1.9 thorpej 275: if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
276: panic("dir too big in ipsec_checkpcbcache");
277: #endif
278: /* SPD table change invalidate all the caches. */
279: if (ipsec_spdgen != pcbsp->sp_cache[dir].cachegen) {
280: ipsec_invalpcbcache(pcbsp, dir);
281: return NULL;
282: }
283: if (!pcbsp->sp_cache[dir].cachesp)
284: return NULL;
285: if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) {
286: ipsec_invalpcbcache(pcbsp, dir);
287: return NULL;
288: }
289: if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) {
290: if (!pcbsp->sp_cache[dir].cachesp)
291: return NULL;
292: if (ipsec_setspidx(m, &spidx, 1) != 0)
293: return NULL;
1.29 degroote 294:
295: /*
296: * We have to make an exact match here since the cached rule
297: * might have lower priority than a rule that would otherwise
298: * have matched the packet.
299: */
300:
301: if (bcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx, sizeof(spidx)))
302: return NULL;
303:
1.9 thorpej 304: } else {
305: /*
306: * The pcb is connected, and the L4 code is sure that:
307: * - outgoing side uses inp_[lf]addr
308: * - incoming side looks up policy after inpcb lookup
309: * and address pair is know to be stable. We do not need
310: * to generate spidx again, nor check the address match again.
311: *
312: * For IPv4/v6 SOCK_STREAM sockets, this assumptions holds
313: * and there are calls to ipsec_pcbconn() from in_pcbconnect().
314: */
315: }
316:
1.23 kardel 317: pcbsp->sp_cache[dir].cachesp->lastused = time_second;
1.9 thorpej 318: pcbsp->sp_cache[dir].cachesp->refcnt++;
319: KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
320: printf("DP ipsec_checkpcbcache cause refcnt++:%d SP:%p\n",
321: pcbsp->sp_cache[dir].cachesp->refcnt,
322: pcbsp->sp_cache[dir].cachesp));
323: return pcbsp->sp_cache[dir].cachesp;
324: }
325:
326: static int
327: ipsec_fillpcbcache(struct inpcbpolicy *pcbsp, struct mbuf *m,
1.26 degroote 328: struct secpolicy *sp, int dir)
1.9 thorpej 329: {
330:
331: switch (dir) {
332: case IPSEC_DIR_INBOUND:
333: case IPSEC_DIR_OUTBOUND:
334: break;
335: default:
336: return EINVAL;
337: }
338: #ifdef DIAGNOSTIC
339: if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
340: panic("dir too big in ipsec_fillpcbcache");
341: #endif
342:
343: if (pcbsp->sp_cache[dir].cachesp)
344: KEY_FREESP(&pcbsp->sp_cache[dir].cachesp);
345: pcbsp->sp_cache[dir].cachesp = NULL;
346: pcbsp->sp_cache[dir].cachehint = IPSEC_PCBHINT_MAYBE;
347: if (ipsec_setspidx(m, &pcbsp->sp_cache[dir].cacheidx, 1) != 0) {
348: return EINVAL;
349: }
350: pcbsp->sp_cache[dir].cachesp = sp;
351: if (pcbsp->sp_cache[dir].cachesp) {
352: pcbsp->sp_cache[dir].cachesp->refcnt++;
353: KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
354: printf("DP ipsec_fillpcbcache cause refcnt++:%d SP:%p\n",
355: pcbsp->sp_cache[dir].cachesp->refcnt,
356: pcbsp->sp_cache[dir].cachesp));
357:
358: /*
359: * If the PCB is connected, we can remember a hint to
360: * possibly short-circuit IPsec processing in other places.
361: */
362: if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) {
363: switch (pcbsp->sp_cache[dir].cachesp->policy) {
364: case IPSEC_POLICY_NONE:
365: case IPSEC_POLICY_BYPASS:
366: pcbsp->sp_cache[dir].cachehint =
1.26 degroote 367: IPSEC_PCBHINT_NO;
1.9 thorpej 368: break;
369: default:
370: pcbsp->sp_cache[dir].cachehint =
1.26 degroote 371: IPSEC_PCBHINT_YES;
1.9 thorpej 372: }
373: }
374: }
375: pcbsp->sp_cache[dir].cachegen = ipsec_spdgen;
376:
377: return 0;
378: }
379:
380: static int
381: ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir)
382: {
383: int i;
384:
385: for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) {
386: if (dir != IPSEC_DIR_ANY && i != dir)
387: continue;
388: if (pcbsp->sp_cache[i].cachesp)
389: KEY_FREESP(&pcbsp->sp_cache[i].cachesp);
390: pcbsp->sp_cache[i].cachesp = NULL;
391: pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_MAYBE;
392: pcbsp->sp_cache[i].cachegen = 0;
393: bzero(&pcbsp->sp_cache[i].cacheidx,
1.26 degroote 394: sizeof(pcbsp->sp_cache[i].cacheidx));
1.9 thorpej 395: }
396: return 0;
397: }
398:
399: void
400: ipsec_pcbconn(struct inpcbpolicy *pcbsp)
401: {
402:
403: pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED;
404: ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
405: }
406:
407: void
408: ipsec_pcbdisconn(struct inpcbpolicy *pcbsp)
409: {
410:
411: pcbsp->sp_cacheflags &= ~IPSEC_PCBSP_CONNECTED;
412: ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
413: }
414:
415: void
416: ipsec_invalpcbcacheall(void)
417: {
418:
419: if (ipsec_spdgen == UINT_MAX)
420: ipsec_spdgen = 1;
421: else
422: ipsec_spdgen++;
423: }
424: #endif /* __NetBSD__ */
425:
1.1 jonathan 426: /*
427: * Return a held reference to the default SP.
428: */
429: static struct secpolicy *
1.31 degroote 430: key_allocsp_default(int af, const char* where, int tag)
1.1 jonathan 431: {
432: struct secpolicy *sp;
433:
434: KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
435: printf("DP key_allocsp_default from %s:%u\n", where, tag));
436:
1.31 degroote 437: switch(af) {
438: case AF_INET:
439: sp = &ip4_def_policy;
440: break;
441: #ifdef INET6
442: case AF_INET6:
443: sp = &ip6_def_policy;
444: break;
445: #endif
446: default:
447: KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1.32 degroote 448: printf("key_allocsp_default : unexpected protocol family %u\n",
1.31 degroote 449: af));
450: return NULL;
451: }
452:
1.1 jonathan 453: if (sp->policy != IPSEC_POLICY_DISCARD &&
1.26 degroote 454: sp->policy != IPSEC_POLICY_NONE) {
1.1 jonathan 455: ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
1.26 degroote 456: sp->policy, IPSEC_POLICY_NONE));
1.1 jonathan 457: sp->policy = IPSEC_POLICY_NONE;
458: }
459: sp->refcnt++;
460:
461: KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
462: printf("DP key_allocsp_default returns SP:%p (%u)\n",
463: sp, sp->refcnt));
464: return sp;
465: }
1.31 degroote 466: #define KEY_ALLOCSP_DEFAULT(af) \
467: key_allocsp_default((af),__FILE__, __LINE__)
1.1 jonathan 468:
469: /*
470: * For OUTBOUND packet having a socket. Searching SPD for packet,
471: * and return a pointer to SP.
472: * OUT: NULL: no apropreate SP found, the following value is set to error.
473: * 0 : bypass
474: * EACCES : discard packet.
475: * ENOENT : ipsec_acquire() in progress, maybe.
1.7 wiz 476: * others : error occurred.
1.1 jonathan 477: * others: a pointer to SP
478: *
1.20 wiz 479: * NOTE: IPv6 mapped address concern is implemented here.
1.1 jonathan 480: */
481: struct secpolicy *
482: ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
483: {
484: struct secpolicy *sp;
485:
486: IPSEC_ASSERT(tdbi != NULL, ("ipsec_getpolicy: null tdbi"));
487: IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
488: ("ipsec_getpolicy: invalid direction %u", dir));
489:
490: sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
491: if (sp == NULL) /*XXX????*/
1.31 degroote 492: sp = KEY_ALLOCSP_DEFAULT(tdbi->dst.sa.sa_family);
1.1 jonathan 493: IPSEC_ASSERT(sp != NULL, ("ipsec_getpolicy: null SP"));
494: return sp;
495: }
496:
497: /*
498: * For OUTBOUND packet having a socket. Searching SPD for packet,
499: * and return a pointer to SP.
500: * OUT: NULL: no apropreate SP found, the following value is set to error.
501: * 0 : bypass
502: * EACCES : discard packet.
503: * ENOENT : ipsec_acquire() in progress, maybe.
1.7 wiz 504: * others : error occurred.
1.1 jonathan 505: * others: a pointer to SP
506: *
1.20 wiz 507: * NOTE: IPv6 mapped address concern is implemented here.
1.1 jonathan 508: */
1.5 jonathan 509: static struct secpolicy *
1.33 degroote 510: ipsec_getpolicybysock(struct mbuf *m, u_int dir, PCB_T *inp, int *error)
1.1 jonathan 511: {
512: struct inpcbpolicy *pcbsp = NULL;
513: struct secpolicy *currsp = NULL; /* policy on socket */
514: struct secpolicy *sp;
515: int af;
516:
517: IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
518: IPSEC_ASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
519: IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
520: IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
521: ("ipsec_getpolicybysock: invalid direction %u", dir));
522:
1.9 thorpej 523: IPSEC_ASSERT(PCB_SOCKET(inp) != NULL,
1.26 degroote 524: ("ipsec_getppolicybysock: null socket\n"));
1.5 jonathan 525:
526: /* XXX FIXME inpcb/in6pcb vs socket*/
527: af = PCB_FAMILY(inp);
1.1 jonathan 528: IPSEC_ASSERT(af == AF_INET || af == AF_INET6,
529: ("ipsec_getpolicybysock: unexpected protocol family %u", af));
530:
1.9 thorpej 531: #ifdef __NetBSD__
1.13 jonathan 532: IPSEC_ASSERT(inp->inph_sp != NULL, ("null PCB policy cache"));
1.9 thorpej 533: /* If we have a cached entry, and if it is still valid, use it. */
1.37 thorpej 534: IPSEC_STATINC(IPSEC_STAT_SPDCACHELOOKUP);
1.9 thorpej 535: currsp = ipsec_checkpcbcache(m, /*inpcb_hdr*/inp->inph_sp, dir);
536: if (currsp) {
537: *error = 0;
538: return currsp;
539: }
1.37 thorpej 540: IPSEC_STATINC(IPSEC_STAT_SPDCACHEMISS);
1.9 thorpej 541: #endif /* __NetBSD__ */
542:
1.1 jonathan 543: switch (af) {
1.5 jonathan 544: case AF_INET: {
545: struct inpcb *in4p = PCB_TO_IN4PCB(inp);
1.1 jonathan 546: /* set spidx in pcb */
1.5 jonathan 547: *error = ipsec4_setspidx_inpcb(m, in4p);
548: pcbsp = in4p->inp_sp;
1.1 jonathan 549: break;
1.5 jonathan 550: }
551:
552: #if defined(INET6)
553: case AF_INET6: {
554: struct in6pcb *in6p = PCB_TO_IN6PCB(inp);
1.1 jonathan 555: /* set spidx in pcb */
1.5 jonathan 556: *error = ipsec6_setspidx_in6pcb(m, in6p);
557: pcbsp = in6p->in6p_sp;
1.1 jonathan 558: break;
1.5 jonathan 559: }
1.1 jonathan 560: #endif
561: default:
562: *error = EPFNOSUPPORT;
563: break;
564: }
565: if (*error)
566: return NULL;
567:
568: IPSEC_ASSERT(pcbsp != NULL, ("ipsec_getpolicybysock: null pcbsp"));
569: switch (dir) {
570: case IPSEC_DIR_INBOUND:
571: currsp = pcbsp->sp_in;
572: break;
573: case IPSEC_DIR_OUTBOUND:
574: currsp = pcbsp->sp_out;
575: break;
576: }
577: IPSEC_ASSERT(currsp != NULL, ("ipsec_getpolicybysock: null currsp"));
578:
579: if (pcbsp->priv) { /* when privilieged socket */
580: switch (currsp->policy) {
581: case IPSEC_POLICY_BYPASS:
582: case IPSEC_POLICY_IPSEC:
583: currsp->refcnt++;
584: sp = currsp;
585: break;
586:
587: case IPSEC_POLICY_ENTRUST:
588: /* look for a policy in SPD */
589: sp = KEY_ALLOCSP(&currsp->spidx, dir);
590: if (sp == NULL) /* no SP found */
1.31 degroote 591: sp = KEY_ALLOCSP_DEFAULT(af);
1.1 jonathan 592: break;
593:
594: default:
595: ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
1.26 degroote 596: "Invalid policy for PCB %d\n", currsp->policy));
1.1 jonathan 597: *error = EINVAL;
598: return NULL;
599: }
600: } else { /* unpriv, SPD has policy */
601: sp = KEY_ALLOCSP(&currsp->spidx, dir);
602: if (sp == NULL) { /* no SP found */
603: switch (currsp->policy) {
604: case IPSEC_POLICY_BYPASS:
605: ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
1.26 degroote 606: "Illegal policy for non-priviliged defined %d\n",
1.1 jonathan 607: currsp->policy));
608: *error = EINVAL;
609: return NULL;
610:
611: case IPSEC_POLICY_ENTRUST:
1.31 degroote 612: sp = KEY_ALLOCSP_DEFAULT(af);
1.1 jonathan 613: break;
614:
615: case IPSEC_POLICY_IPSEC:
616: currsp->refcnt++;
617: sp = currsp;
618: break;
619:
620: default:
621: ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
622: "Invalid policy for PCB %d\n", currsp->policy));
623: *error = EINVAL;
624: return NULL;
625: }
626: }
627: }
628: IPSEC_ASSERT(sp != NULL,
629: ("ipsec_getpolicybysock: null SP (priv %u policy %u",
630: pcbsp->priv, currsp->policy));
631: KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
632: printf("DP ipsec_getpolicybysock (priv %u policy %u) allocates "
1.26 degroote 633: "SP:%p (refcnt %u)\n", pcbsp->priv, currsp->policy,
634: sp, sp->refcnt));
1.9 thorpej 635: #ifdef __NetBSD__
636: ipsec_fillpcbcache(pcbsp, m, sp, dir);
637: #endif /* __NetBSD__ */
1.1 jonathan 638: return sp;
639: }
640:
641: /*
642: * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
643: * and return a pointer to SP.
644: * OUT: positive: a pointer to the entry for security policy leaf matched.
645: * NULL: no apropreate SP found, the following value is set to error.
646: * 0 : bypass
647: * EACCES : discard packet.
648: * ENOENT : ipsec_acquire() in progress, maybe.
1.7 wiz 649: * others : error occurred.
1.1 jonathan 650: */
651: struct secpolicy *
1.33 degroote 652: ipsec_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
1.1 jonathan 653: {
654: struct secpolicyindex spidx;
655: struct secpolicy *sp;
656:
657: IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybyaddr: null mbuf"));
658: IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybyaddr: null error"));
659: IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
660: ("ipsec4_getpolicybaddr: invalid direction %u", dir));
661:
662: sp = NULL;
1.32 degroote 663:
664: /* Make an index to look for a policy. */
665: *error = ipsec_setspidx(m, &spidx, (flag & IP_FORWARDING) ? 0 : 1);
666: if (*error != 0) {
667: DPRINTF(("ipsec_getpolicybyaddr: setpidx failed,"
668: " dir %u flag %u\n", dir, flag));
669: bzero(&spidx, sizeof (spidx));
670: return NULL;
671: }
672:
673: spidx.dir = dir;
674:
1.1 jonathan 675: if (key_havesp(dir)) {
676: sp = KEY_ALLOCSP(&spidx, dir);
677: }
1.32 degroote 678:
1.1 jonathan 679: if (sp == NULL) /* no SP found, use system default */
1.31 degroote 680: sp = KEY_ALLOCSP_DEFAULT(spidx.dst.sa.sa_family);
1.1 jonathan 681: IPSEC_ASSERT(sp != NULL, ("ipsec_getpolicybyaddr: null SP"));
682: return sp;
683: }
684:
685: struct secpolicy *
1.33 degroote 686: ipsec4_checkpolicy(struct mbuf *m, u_int dir, u_int flag, int *error,
687: struct inpcb *inp)
1.1 jonathan 688: {
689: struct secpolicy *sp;
690:
691: *error = 0;
1.5 jonathan 692:
693:
694: /* XXX KAME IPv6 calls us with non-null inp but bogus inp_socket? */
695: if (inp == NULL || inp->inp_socket == NULL) {
1.1 jonathan 696: sp = ipsec_getpolicybyaddr(m, dir, flag, error);
1.5 jonathan 697: } else
698: sp = ipsec_getpolicybysock(m, dir, IN4PCB_TO_PCB(inp), error);
1.1 jonathan 699: if (sp == NULL) {
700: IPSEC_ASSERT(*error != 0,
701: ("ipsec4_checkpolicy: getpolicy failed w/o error"));
1.37 thorpej 702: IPSEC_STATINC(IPSEC_STAT_OUT_INVAL);
1.1 jonathan 703: return NULL;
704: }
705: IPSEC_ASSERT(*error == 0,
706: ("ipsec4_checkpolicy: sp w/ error set to %u", *error));
707: switch (sp->policy) {
708: case IPSEC_POLICY_ENTRUST:
709: default:
710: printf("ipsec4_checkpolicy: invalid policy %u\n", sp->policy);
711: /* fall thru... */
712: case IPSEC_POLICY_DISCARD:
1.37 thorpej 713: IPSEC_STATINC(IPSEC_STAT_OUT_POLVIO);
1.1 jonathan 714: *error = -EINVAL; /* packet is discarded by caller */
715: break;
716: case IPSEC_POLICY_BYPASS:
717: case IPSEC_POLICY_NONE:
718: KEY_FREESP(&sp);
719: sp = NULL; /* NB: force NULL result */
720: break;
721: case IPSEC_POLICY_IPSEC:
722: if (sp->req == NULL) /* acquire an SA */
723: *error = key_spdacquire(sp);
724: break;
725: }
726: if (*error != 0) {
727: KEY_FREESP(&sp);
728: sp = NULL;
729: }
1.5 jonathan 730: DPRINTF(("ipsecpol: done, sp %p error %d, \n", sp, *error));
1.1 jonathan 731: return sp;
732: }
733:
1.26 degroote 734: #ifdef INET6
735: struct secpolicy *
1.33 degroote 736: ipsec6_checkpolicy(struct mbuf *m, u_int dir, u_int flag, int *error,
737: struct in6pcb *in6p)
1.26 degroote 738: {
739: struct secpolicy *sp;
740:
741: *error = 0;
742:
743:
744: /* XXX KAME IPv6 calls us with non-null inp but bogus inp_socket? */
745: if (in6p == NULL || in6p->in6p_socket == NULL) {
746: sp = ipsec_getpolicybyaddr(m, dir, flag, error);
747: } else
748: sp = ipsec_getpolicybysock(m, dir, IN6PCB_TO_PCB(in6p), error);
749: if (sp == NULL) {
750: IPSEC_ASSERT(*error != 0,
751: ("ipsec6_checkpolicy: getpolicy failed w/o error"));
1.37 thorpej 752: IPSEC_STATINC(IPSEC_STAT_OUT_INVAL);
1.26 degroote 753: return NULL;
754: }
755: IPSEC_ASSERT(*error == 0,
756: ("ipsec6_checkpolicy: sp w/ error set to %u", *error));
757: switch (sp->policy) {
758: case IPSEC_POLICY_ENTRUST:
759: default:
760: printf("ipsec6_checkpolicy: invalid policy %u\n", sp->policy);
761: /* fall thru... */
762: case IPSEC_POLICY_DISCARD:
1.37 thorpej 763: IPSEC_STATINC(IPSEC_STAT_OUT_POLVIO);
1.26 degroote 764: *error = -EINVAL; /* packet is discarded by caller */
765: break;
766: case IPSEC_POLICY_BYPASS:
767: case IPSEC_POLICY_NONE:
768: KEY_FREESP(&sp);
769: sp = NULL; /* NB: force NULL result */
770: break;
771: case IPSEC_POLICY_IPSEC:
772: if (sp->req == NULL) /* acquire an SA */
773: *error = key_spdacquire(sp);
774: break;
775: }
776: if (*error != 0) {
777: KEY_FREESP(&sp);
778: sp = NULL;
779: }
780: DPRINTF(("ipsecpol: done, sp %p error %d, \n", sp, *error));
781: return sp;
782: }
783: #endif /* INET6 */
784:
1.1 jonathan 785: static int
1.33 degroote 786: ipsec4_setspidx_inpcb(struct mbuf *m ,struct inpcb *pcb)
1.1 jonathan 787: {
788: int error;
789:
790: IPSEC_ASSERT(pcb != NULL, ("ipsec4_setspidx_inpcb: null pcb"));
791: IPSEC_ASSERT(pcb->inp_sp != NULL, ("ipsec4_setspidx_inpcb: null inp_sp"));
792: IPSEC_ASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
793: ("ipsec4_setspidx_inpcb: null sp_in || sp_out"));
794:
795: error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
796: if (error == 0) {
797: pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
798: pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
799: pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
800: } else {
801: bzero(&pcb->inp_sp->sp_in->spidx,
802: sizeof (pcb->inp_sp->sp_in->spidx));
803: bzero(&pcb->inp_sp->sp_out->spidx,
804: sizeof (pcb->inp_sp->sp_in->spidx));
805: }
806: return error;
807: }
808:
809: #ifdef INET6
810: static int
1.33 degroote 811: ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb)
1.1 jonathan 812: {
813: struct secpolicyindex *spidx;
814: int error;
815:
816: IPSEC_ASSERT(pcb != NULL, ("ipsec6_setspidx_in6pcb: null pcb"));
817: IPSEC_ASSERT(pcb->in6p_sp != NULL, ("ipsec6_setspidx_in6pcb: null inp_sp"));
818: IPSEC_ASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
819: ("ipsec6_setspidx_in6pcb: null sp_in || sp_out"));
820:
821: bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
822: bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
823:
824: spidx = &pcb->in6p_sp->sp_in->spidx;
825: error = ipsec_setspidx(m, spidx, 1);
826: if (error)
827: goto bad;
828: spidx->dir = IPSEC_DIR_INBOUND;
829:
830: spidx = &pcb->in6p_sp->sp_out->spidx;
831: error = ipsec_setspidx(m, spidx, 1);
832: if (error)
833: goto bad;
834: spidx->dir = IPSEC_DIR_OUTBOUND;
835:
836: return 0;
837:
838: bad:
839: bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
840: bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
841: return error;
842: }
843: #endif
844:
845: /*
846: * configure security policy index (src/dst/proto/sport/dport)
847: * by looking at the content of mbuf.
848: * the caller is responsible for error recovery (like clearing up spidx).
849: */
850: static int
1.33 degroote 851: ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport)
1.1 jonathan 852: {
853: struct ip *ip = NULL;
854: struct ip ipbuf;
855: u_int v;
856: struct mbuf *n;
857: int len;
858: int error;
859:
860: IPSEC_ASSERT(m != NULL, ("ipsec_setspidx: null mbuf"));
861:
862: /*
863: * validate m->m_pkthdr.len. we see incorrect length if we
864: * mistakenly call this function with inconsistent mbuf chain
865: * (like 4.4BSD tcp/udp processing). XXX should we panic here?
866: */
867: len = 0;
868: for (n = m; n; n = n->m_next)
869: len += n->m_len;
870: if (m->m_pkthdr.len != len) {
871: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
872: printf("ipsec_setspidx: "
1.26 degroote 873: "total of m_len(%d) != pkthdr.len(%d), "
874: "ignored.\n",
1.1 jonathan 875: len, m->m_pkthdr.len));
876: return EINVAL;
877: }
878:
879: if (m->m_pkthdr.len < sizeof(struct ip)) {
880: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
881: printf("ipsec_setspidx: "
1.26 degroote 882: "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
883: m->m_pkthdr.len));
1.1 jonathan 884: return EINVAL;
885: }
886:
887: if (m->m_len >= sizeof(*ip))
888: ip = mtod(m, struct ip *);
889: else {
1.28 degroote 890: m_copydata(m, 0, sizeof(ipbuf), &ipbuf);
1.1 jonathan 891: ip = &ipbuf;
892: }
893: v = ip->ip_v;
894: switch (v) {
895: case 4:
896: error = ipsec4_setspidx_ipaddr(m, spidx);
897: if (error)
898: return error;
899: ipsec4_get_ulp(m, spidx, needport);
900: return 0;
901: #ifdef INET6
902: case 6:
903: if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
904: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
905: printf("ipsec_setspidx: "
1.26 degroote 906: "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
907: "ignored.\n", m->m_pkthdr.len));
1.1 jonathan 908: return EINVAL;
909: }
910: error = ipsec6_setspidx_ipaddr(m, spidx);
911: if (error)
912: return error;
913: ipsec6_get_ulp(m, spidx, needport);
914: return 0;
915: #endif
916: default:
917: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
918: printf("ipsec_setspidx: "
1.26 degroote 919: "unknown IP version %u, ignored.\n", v));
1.1 jonathan 920: return EINVAL;
921: }
922: }
923:
924: static void
925: ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
926: {
927: u_int8_t nxt;
928: int off;
929:
930: /* sanity check */
931: IPSEC_ASSERT(m != NULL, ("ipsec4_get_ulp: null mbuf"));
932: IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),
933: ("ipsec4_get_ulp: packet too short"));
934:
935: /* NB: ip_input() flips it into host endian XXX need more checking */
1.8 thorpej 936: if (m->m_len >= sizeof(struct ip)) {
1.1 jonathan 937: struct ip *ip = mtod(m, struct ip *);
1.34 adrianp 938: if (ip->ip_off & IP_OFF_CONVERT(IP_MF | IP_OFFMASK))
1.1 jonathan 939: goto done;
940: off = ip->ip_hl << 2;
941: nxt = ip->ip_p;
942: } else {
943: struct ip ih;
944:
1.28 degroote 945: m_copydata(m, 0, sizeof (struct ip), &ih);
1.34 adrianp 946: if (ih.ip_off & IP_OFF_CONVERT(IP_MF | IP_OFFMASK))
1.1 jonathan 947: goto done;
948: off = ih.ip_hl << 2;
949: nxt = ih.ip_p;
950: }
951:
952: while (off < m->m_pkthdr.len) {
953: struct ip6_ext ip6e;
954: struct tcphdr th;
955: struct udphdr uh;
1.38 mlelstv 956: struct icmp icmph;
1.1 jonathan 957:
958: switch (nxt) {
959: case IPPROTO_TCP:
960: spidx->ul_proto = nxt;
961: if (!needport)
962: goto done_proto;
963: if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
964: goto done;
1.28 degroote 965: m_copydata(m, off, sizeof (th), &th);
1.1 jonathan 966: spidx->src.sin.sin_port = th.th_sport;
967: spidx->dst.sin.sin_port = th.th_dport;
968: return;
969: case IPPROTO_UDP:
970: spidx->ul_proto = nxt;
971: if (!needport)
972: goto done_proto;
973: if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
974: goto done;
1.28 degroote 975: m_copydata(m, off, sizeof (uh), &uh);
1.1 jonathan 976: spidx->src.sin.sin_port = uh.uh_sport;
977: spidx->dst.sin.sin_port = uh.uh_dport;
978: return;
979: case IPPROTO_AH:
980: if (m->m_pkthdr.len > off + sizeof(ip6e))
981: goto done;
982: /* XXX sigh, this works but is totally bogus */
1.28 degroote 983: m_copydata(m, off, sizeof(ip6e), &ip6e);
1.1 jonathan 984: off += (ip6e.ip6e_len + 2) << 2;
985: nxt = ip6e.ip6e_nxt;
986: break;
987: case IPPROTO_ICMP:
1.38 mlelstv 988: spidx->ul_proto = nxt;
989: if (off + sizeof(struct icmp) > m->m_pkthdr.len)
990: return;
1.39 ! degroote 991: m_copydata(m, off, sizeof(icmph), &icmph);
1.38 mlelstv 992: ((struct sockaddr_in *)&spidx->src)->sin_port =
993: htons((uint16_t)icmph.icmp_type);
994: ((struct sockaddr_in *)&spidx->dst)->sin_port =
995: htons((uint16_t)icmph.icmp_code);
996: return;
1.1 jonathan 997: default:
998: /* XXX intermediate headers??? */
999: spidx->ul_proto = nxt;
1000: goto done_proto;
1001: }
1002: }
1003: done:
1004: spidx->ul_proto = IPSEC_ULPROTO_ANY;
1005: done_proto:
1006: spidx->src.sin.sin_port = IPSEC_PORT_ANY;
1007: spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
1008: }
1009:
1010: /* assumes that m is sane */
1011: static int
1012: ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1013: {
1014: static const struct sockaddr_in template = {
1015: sizeof (struct sockaddr_in),
1016: AF_INET,
1017: 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
1018: };
1019:
1020: spidx->src.sin = template;
1021: spidx->dst.sin = template;
1022:
1023: if (m->m_len < sizeof (struct ip)) {
1024: m_copydata(m, offsetof(struct ip, ip_src),
1025: sizeof (struct in_addr),
1.28 degroote 1026: &spidx->src.sin.sin_addr);
1.1 jonathan 1027: m_copydata(m, offsetof(struct ip, ip_dst),
1028: sizeof (struct in_addr),
1.28 degroote 1029: &spidx->dst.sin.sin_addr);
1.1 jonathan 1030: } else {
1031: struct ip *ip = mtod(m, struct ip *);
1032: spidx->src.sin.sin_addr = ip->ip_src;
1033: spidx->dst.sin.sin_addr = ip->ip_dst;
1034: }
1035:
1036: spidx->prefs = sizeof(struct in_addr) << 3;
1037: spidx->prefd = sizeof(struct in_addr) << 3;
1038:
1039: return 0;
1040: }
1041:
1042: #ifdef INET6
1043: static void
1.33 degroote 1044: ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *spidx,
1045: int needport)
1.1 jonathan 1046: {
1047: int off, nxt;
1048: struct tcphdr th;
1049: struct udphdr uh;
1.38 mlelstv 1050: struct icmp6_hdr icmph;
1.1 jonathan 1051:
1052: /* sanity check */
1053: if (m == NULL)
1.16 christos 1054: panic("ipsec6_get_ulp: NULL pointer was passed");
1.1 jonathan 1055:
1056: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1057: printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
1058:
1059: /* set default */
1060: spidx->ul_proto = IPSEC_ULPROTO_ANY;
1061: ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
1062: ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
1063:
1064: nxt = -1;
1065: off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
1066: if (off < 0 || m->m_pkthdr.len < off)
1067: return;
1068:
1069: switch (nxt) {
1070: case IPPROTO_TCP:
1071: spidx->ul_proto = nxt;
1072: if (!needport)
1073: break;
1074: if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1075: break;
1.28 degroote 1076: m_copydata(m, off, sizeof(th), &th);
1.1 jonathan 1077: ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
1078: ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
1079: break;
1080: case IPPROTO_UDP:
1081: spidx->ul_proto = nxt;
1082: if (!needport)
1083: break;
1084: if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1085: break;
1.28 degroote 1086: m_copydata(m, off, sizeof(uh), &uh);
1.1 jonathan 1087: ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
1088: ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
1089: break;
1090: case IPPROTO_ICMPV6:
1.38 mlelstv 1091: spidx->ul_proto = nxt;
1092: if (off + sizeof(struct icmp6_hdr) > m->m_pkthdr.len)
1093: break;
1.39 ! degroote 1094: m_copydata(m, off, sizeof(icmph), &icmph);
1.38 mlelstv 1095: ((struct sockaddr_in6 *)&spidx->src)->sin6_port =
1096: htons((uint16_t)icmph.icmp6_type);
1097: ((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
1098: htons((uint16_t)icmph.icmp6_code);
1099: break;
1.1 jonathan 1100: default:
1101: /* XXX intermediate headers??? */
1102: spidx->ul_proto = nxt;
1103: break;
1104: }
1105: }
1106:
1107: /* assumes that m is sane */
1108: static int
1.33 degroote 1109: ipsec6_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1.1 jonathan 1110: {
1111: struct ip6_hdr *ip6 = NULL;
1112: struct ip6_hdr ip6buf;
1113: struct sockaddr_in6 *sin6;
1114:
1115: if (m->m_len >= sizeof(*ip6))
1116: ip6 = mtod(m, struct ip6_hdr *);
1117: else {
1.28 degroote 1118: m_copydata(m, 0, sizeof(ip6buf), &ip6buf);
1.1 jonathan 1119: ip6 = &ip6buf;
1120: }
1121:
1122: sin6 = (struct sockaddr_in6 *)&spidx->src;
1123: bzero(sin6, sizeof(*sin6));
1124: sin6->sin6_family = AF_INET6;
1125: sin6->sin6_len = sizeof(struct sockaddr_in6);
1126: bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
1127: if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
1128: sin6->sin6_addr.s6_addr16[1] = 0;
1129: sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
1130: }
1131: spidx->prefs = sizeof(struct in6_addr) << 3;
1132:
1133: sin6 = (struct sockaddr_in6 *)&spidx->dst;
1134: bzero(sin6, sizeof(*sin6));
1135: sin6->sin6_family = AF_INET6;
1136: sin6->sin6_len = sizeof(struct sockaddr_in6);
1137: bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
1138: if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
1139: sin6->sin6_addr.s6_addr16[1] = 0;
1140: sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
1141: }
1142: spidx->prefd = sizeof(struct in6_addr) << 3;
1143:
1144: return 0;
1145: }
1146: #endif
1147:
1148: static void
1.33 degroote 1149: ipsec_delpcbpolicy(struct inpcbpolicy *p)
1.1 jonathan 1150: {
1151: free(p, M_SECA);
1152: }
1153:
1154: /* initialize policy in PCB */
1155: int
1.33 degroote 1156: ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp)
1.1 jonathan 1157: {
1158: struct inpcbpolicy *new;
1159:
1160: /* sanity check. */
1161: if (so == NULL || pcb_sp == NULL)
1.16 christos 1162: panic("ipsec_init_policy: NULL pointer was passed");
1.1 jonathan 1163:
1164: new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
1.26 degroote 1165: M_SECA, M_NOWAIT|M_ZERO);
1.1 jonathan 1166: if (new == NULL) {
1167: ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
1168: return ENOBUFS;
1169: }
1170:
1171: if (IPSEC_PRIVILEGED_SO(so))
1172: new->priv = 1;
1173: else
1174: new->priv = 0;
1175:
1176: if ((new->sp_in = KEY_NEWSP()) == NULL) {
1177: ipsec_delpcbpolicy(new);
1178: return ENOBUFS;
1179: }
1180: new->sp_in->state = IPSEC_SPSTATE_ALIVE;
1181: new->sp_in->policy = IPSEC_POLICY_ENTRUST;
1182:
1183: if ((new->sp_out = KEY_NEWSP()) == NULL) {
1184: KEY_FREESP(&new->sp_in);
1185: ipsec_delpcbpolicy(new);
1186: return ENOBUFS;
1187: }
1188: new->sp_out->state = IPSEC_SPSTATE_ALIVE;
1189: new->sp_out->policy = IPSEC_POLICY_ENTRUST;
1190:
1191: *pcb_sp = new;
1192:
1193: return 0;
1194: }
1195:
1196: /* copy old ipsec policy into new */
1197: int
1.33 degroote 1198: ipsec_copy_policy(struct inpcbpolicy *old, struct inpcbpolicy *new)
1.1 jonathan 1199: {
1200: struct secpolicy *sp;
1201:
1202: sp = ipsec_deepcopy_policy(old->sp_in);
1203: if (sp) {
1204: KEY_FREESP(&new->sp_in);
1205: new->sp_in = sp;
1206: } else
1207: return ENOBUFS;
1208:
1209: sp = ipsec_deepcopy_policy(old->sp_out);
1210: if (sp) {
1211: KEY_FREESP(&new->sp_out);
1212: new->sp_out = sp;
1213: } else
1214: return ENOBUFS;
1215:
1216: new->priv = old->priv;
1217:
1218: return 0;
1219: }
1220:
1221: /* deep-copy a policy in PCB */
1222: static struct secpolicy *
1.33 degroote 1223: ipsec_deepcopy_policy(struct secpolicy *src)
1.1 jonathan 1224: {
1225: struct ipsecrequest *newchain = NULL;
1226: struct ipsecrequest *p;
1227: struct ipsecrequest **q;
1228: struct ipsecrequest *r;
1229: struct secpolicy *dst;
1230:
1231: if (src == NULL)
1232: return NULL;
1233: dst = KEY_NEWSP();
1234: if (dst == NULL)
1235: return NULL;
1236:
1237: /*
1238: * deep-copy IPsec request chain. This is required since struct
1239: * ipsecrequest is not reference counted.
1240: */
1241: q = &newchain;
1242: for (p = src->req; p; p = p->next) {
1243: *q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
1244: M_SECA, M_NOWAIT);
1245: if (*q == NULL)
1246: goto fail;
1247: bzero(*q, sizeof(**q));
1248: (*q)->next = NULL;
1249:
1250: (*q)->saidx.proto = p->saidx.proto;
1251: (*q)->saidx.mode = p->saidx.mode;
1252: (*q)->level = p->level;
1253: (*q)->saidx.reqid = p->saidx.reqid;
1254:
1255: bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
1256: bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
1257:
1258: (*q)->sav = NULL;
1259: (*q)->sp = dst;
1260:
1261: q = &((*q)->next);
1262: }
1263:
1264: dst->req = newchain;
1265: dst->state = src->state;
1266: dst->policy = src->policy;
1267: /* do not touch the refcnt fields */
1268:
1269: return dst;
1270:
1271: fail:
1272: for (p = newchain; p; p = r) {
1273: r = p->next;
1274: free(p, M_SECA);
1275: p = NULL;
1276: }
1277: return NULL;
1278: }
1279:
1280: /* set policy and ipsec request if present. */
1281: static int
1.24 christos 1282: ipsec_set_policy(
1.26 degroote 1283: struct secpolicy **pcb_sp,
1284: int optname,
1.27 christos 1285: void *request,
1.26 degroote 1286: size_t len,
1287: int priv
1.24 christos 1288: )
1.1 jonathan 1289: {
1290: struct sadb_x_policy *xpl;
1291: struct secpolicy *newsp = NULL;
1292: int error;
1293:
1294: /* sanity check. */
1295: if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
1296: return EINVAL;
1297: if (len < sizeof(*xpl))
1298: return EINVAL;
1299: xpl = (struct sadb_x_policy *)request;
1300:
1301: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1302: printf("ipsec_set_policy: passed policy\n");
1303: kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1304:
1305: /* check policy type */
1306: /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1307: if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
1308: || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1309: return EINVAL;
1310:
1311: /* check privileged socket */
1312: if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
1313: return EACCES;
1314:
1315: /* allocation new SP entry */
1316: if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1317: return error;
1318:
1319: newsp->state = IPSEC_SPSTATE_ALIVE;
1320:
1321: /* clear old SP and set new SP */
1322: KEY_FREESP(pcb_sp);
1323: *pcb_sp = newsp;
1324: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1325: printf("ipsec_set_policy: new policy\n");
1326: kdebug_secpolicy(newsp));
1327:
1328: return 0;
1329: }
1330:
1331: static int
1.33 degroote 1332: ipsec_get_policy(struct secpolicy *pcb_sp, struct mbuf **mp)
1.1 jonathan 1333: {
1334:
1335: /* sanity check. */
1336: if (pcb_sp == NULL || mp == NULL)
1337: return EINVAL;
1338:
1339: *mp = key_sp2msg(pcb_sp);
1340: if (!*mp) {
1341: ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
1342: return ENOBUFS;
1343: }
1344:
1345: (*mp)->m_type = MT_DATA;
1346: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1347: printf("ipsec_get_policy:\n");
1348: kdebug_mbuf(*mp));
1349:
1350: return 0;
1351: }
1352:
1353: int
1.33 degroote 1354: ipsec4_set_policy(struct inpcb *inp, int optname ,void *request,
1355: size_t len, int priv)
1.1 jonathan 1356: {
1357: struct sadb_x_policy *xpl;
1358: struct secpolicy **pcb_sp;
1359:
1360: /* sanity check. */
1361: if (inp == NULL || request == NULL)
1362: return EINVAL;
1363: if (len < sizeof(*xpl))
1364: return EINVAL;
1365: xpl = (struct sadb_x_policy *)request;
1366:
1367: IPSEC_ASSERT(inp->inp_sp != NULL,
1.26 degroote 1368: ("ipsec4_set_policy(): null inp->in_sp"));
1.1 jonathan 1369:
1370: /* select direction */
1371: switch (xpl->sadb_x_policy_dir) {
1372: case IPSEC_DIR_INBOUND:
1373: pcb_sp = &inp->inp_sp->sp_in;
1374: break;
1375: case IPSEC_DIR_OUTBOUND:
1376: pcb_sp = &inp->inp_sp->sp_out;
1377: break;
1378: default:
1379: ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1380: xpl->sadb_x_policy_dir));
1381: return EINVAL;
1382: }
1383:
1384: return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1385: }
1386:
1387: int
1.33 degroote 1388: ipsec4_get_policy(struct inpcb *inp, void *request, size_t len,
1389: struct mbuf **mp)
1.1 jonathan 1390: {
1391: struct sadb_x_policy *xpl;
1392: struct secpolicy *pcb_sp;
1393:
1394: /* sanity check. */
1395: if (inp == NULL || request == NULL || mp == NULL)
1396: return EINVAL;
1397: IPSEC_ASSERT(inp->inp_sp != NULL, ("ipsec4_get_policy: null inp_sp"));
1398: if (len < sizeof(*xpl))
1399: return EINVAL;
1400: xpl = (struct sadb_x_policy *)request;
1401:
1402: /* select direction */
1403: switch (xpl->sadb_x_policy_dir) {
1404: case IPSEC_DIR_INBOUND:
1405: pcb_sp = inp->inp_sp->sp_in;
1406: break;
1407: case IPSEC_DIR_OUTBOUND:
1408: pcb_sp = inp->inp_sp->sp_out;
1409: break;
1410: default:
1411: ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1412: xpl->sadb_x_policy_dir));
1413: return EINVAL;
1414: }
1415:
1416: return ipsec_get_policy(pcb_sp, mp);
1417: }
1418:
1419: /* delete policy in PCB */
1420: int
1.33 degroote 1421: ipsec4_delete_pcbpolicy(struct inpcb *inp)
1.1 jonathan 1422: {
1423: IPSEC_ASSERT(inp != NULL, ("ipsec4_delete_pcbpolicy: null inp"));
1424:
1425: if (inp->inp_sp == NULL)
1426: return 0;
1427:
1428: if (inp->inp_sp->sp_in != NULL)
1429: KEY_FREESP(&inp->inp_sp->sp_in);
1430:
1431: if (inp->inp_sp->sp_out != NULL)
1432: KEY_FREESP(&inp->inp_sp->sp_out);
1433:
1434: ipsec_delpcbpolicy(inp->inp_sp);
1435: inp->inp_sp = NULL;
1436:
1437: return 0;
1438: }
1439:
1440: #ifdef INET6
1441: int
1.33 degroote 1442: ipsec6_set_policy(struct in6pcb *in6p, int optname, void *request,
1443: size_t len, int priv)
1.1 jonathan 1444: {
1445: struct sadb_x_policy *xpl;
1446: struct secpolicy **pcb_sp;
1447:
1448: /* sanity check. */
1449: if (in6p == NULL || request == NULL)
1450: return EINVAL;
1451: if (len < sizeof(*xpl))
1452: return EINVAL;
1453: xpl = (struct sadb_x_policy *)request;
1454:
1455: /* select direction */
1456: switch (xpl->sadb_x_policy_dir) {
1457: case IPSEC_DIR_INBOUND:
1458: pcb_sp = &in6p->in6p_sp->sp_in;
1459: break;
1460: case IPSEC_DIR_OUTBOUND:
1461: pcb_sp = &in6p->in6p_sp->sp_out;
1462: break;
1463: default:
1464: ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1465: xpl->sadb_x_policy_dir));
1466: return EINVAL;
1467: }
1468:
1469: return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1470: }
1471:
1472: int
1.33 degroote 1473: ipsec6_get_policy(struct in6pcb *in6p, void *request, size_t len,
1474: struct mbuf **mp)
1.1 jonathan 1475: {
1476: struct sadb_x_policy *xpl;
1477: struct secpolicy *pcb_sp;
1478:
1479: /* sanity check. */
1480: if (in6p == NULL || request == NULL || mp == NULL)
1481: return EINVAL;
1482: IPSEC_ASSERT(in6p->in6p_sp != NULL, ("ipsec6_get_policy: null in6p_sp"));
1483: if (len < sizeof(*xpl))
1484: return EINVAL;
1485: xpl = (struct sadb_x_policy *)request;
1486:
1487: /* select direction */
1488: switch (xpl->sadb_x_policy_dir) {
1489: case IPSEC_DIR_INBOUND:
1490: pcb_sp = in6p->in6p_sp->sp_in;
1491: break;
1492: case IPSEC_DIR_OUTBOUND:
1493: pcb_sp = in6p->in6p_sp->sp_out;
1494: break;
1495: default:
1496: ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1497: xpl->sadb_x_policy_dir));
1498: return EINVAL;
1499: }
1500:
1501: return ipsec_get_policy(pcb_sp, mp);
1502: }
1503:
1504: int
1.33 degroote 1505: ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
1.1 jonathan 1506: {
1507: IPSEC_ASSERT(in6p != NULL, ("ipsec6_delete_pcbpolicy: null in6p"));
1508:
1509: if (in6p->in6p_sp == NULL)
1510: return 0;
1511:
1512: if (in6p->in6p_sp->sp_in != NULL)
1513: KEY_FREESP(&in6p->in6p_sp->sp_in);
1514:
1515: if (in6p->in6p_sp->sp_out != NULL)
1516: KEY_FREESP(&in6p->in6p_sp->sp_out);
1517:
1518: ipsec_delpcbpolicy(in6p->in6p_sp);
1519: in6p->in6p_sp = NULL;
1520:
1521: return 0;
1522: }
1523: #endif
1524:
1525: /*
1526: * return current level.
1527: * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1528: */
1529: u_int
1.33 degroote 1530: ipsec_get_reqlevel(struct ipsecrequest *isr)
1.1 jonathan 1531: {
1532: u_int level = 0;
1533: u_int esp_trans_deflev, esp_net_deflev;
1534: u_int ah_trans_deflev, ah_net_deflev;
1535:
1536: IPSEC_ASSERT(isr != NULL && isr->sp != NULL,
1537: ("ipsec_get_reqlevel: null argument"));
1538: IPSEC_ASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
1539: ("ipsec_get_reqlevel: af family mismatch, src %u, dst %u",
1540: isr->sp->spidx.src.sa.sa_family,
1541: isr->sp->spidx.dst.sa.sa_family));
1542:
1543: /* XXX note that we have ipseclog() expanded here - code sync issue */
1544: #define IPSEC_CHECK_DEFAULT(lev) \
1.26 degroote 1545: (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1546: && (lev) != IPSEC_LEVEL_UNIQUE) \
1547: ? (ipsec_debug \
1.1 jonathan 1548: ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1.26 degroote 1549: (lev), IPSEC_LEVEL_REQUIRE) \
1550: : 0), \
1551: (lev) = IPSEC_LEVEL_REQUIRE, \
1552: (lev) \
1.1 jonathan 1553: : (lev))
1554:
1555: /* set default level */
1556: switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
1557: #ifdef INET
1558: case AF_INET:
1559: esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1560: esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1561: ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1562: ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1563: break;
1564: #endif
1565: #ifdef INET6
1566: case AF_INET6:
1567: esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1568: esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1569: ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1570: ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1571: break;
1572: #endif /* INET6 */
1573: default:
1574: panic("key_get_reqlevel: unknown af %u",
1.26 degroote 1575: isr->sp->spidx.src.sa.sa_family);
1.1 jonathan 1576: }
1577:
1578: #undef IPSEC_CHECK_DEFAULT
1579:
1580: /* set level */
1581: switch (isr->level) {
1582: case IPSEC_LEVEL_DEFAULT:
1583: switch (isr->saidx.proto) {
1584: case IPPROTO_ESP:
1585: if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1586: level = esp_net_deflev;
1587: else
1588: level = esp_trans_deflev;
1589: break;
1590: case IPPROTO_AH:
1591: if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1592: level = ah_net_deflev;
1593: else
1594: level = ah_trans_deflev;
1.14 jonathan 1595: break;
1.1 jonathan 1596: case IPPROTO_IPCOMP:
1597: /*
1598: * we don't really care, as IPcomp document says that
1599: * we shouldn't compress small packets
1600: */
1601: level = IPSEC_LEVEL_USE;
1602: break;
1603: default:
1.16 christos 1604: panic("ipsec_get_reqlevel: Illegal protocol defined %u",
1.26 degroote 1605: isr->saidx.proto);
1.1 jonathan 1606: }
1607: break;
1608:
1609: case IPSEC_LEVEL_USE:
1610: case IPSEC_LEVEL_REQUIRE:
1611: level = isr->level;
1612: break;
1613: case IPSEC_LEVEL_UNIQUE:
1614: level = IPSEC_LEVEL_REQUIRE;
1615: break;
1616:
1617: default:
1.16 christos 1618: panic("ipsec_get_reqlevel: Illegal IPsec level %u",
1.1 jonathan 1619: isr->level);
1620: }
1621:
1622: return level;
1623: }
1624:
1625: /*
1626: * Check security policy requirements against the actual
1627: * packet contents. Return one if the packet should be
1628: * reject as "invalid"; otherwiser return zero to have the
1629: * packet treated as "valid".
1630: *
1631: * OUT:
1632: * 0: valid
1633: * 1: invalid
1634: */
1635: int
1636: ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
1637: {
1638: struct ipsecrequest *isr;
1639: int need_auth;
1640:
1641: KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1642: printf("ipsec_in_reject: using SP\n");
1643: kdebug_secpolicy(sp));
1644:
1645: /* check policy */
1646: switch (sp->policy) {
1647: case IPSEC_POLICY_DISCARD:
1648: return 1;
1649: case IPSEC_POLICY_BYPASS:
1650: case IPSEC_POLICY_NONE:
1651: return 0;
1652: }
1653:
1654: IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
1655: ("ipsec_in_reject: invalid policy %u", sp->policy));
1656:
1657: /* XXX should compare policy against ipsec header history */
1658:
1659: need_auth = 0;
1660: for (isr = sp->req; isr != NULL; isr = isr->next) {
1661: if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
1662: continue;
1663: switch (isr->saidx.proto) {
1664: case IPPROTO_ESP:
1665: if ((m->m_flags & M_DECRYPTED) == 0) {
1666: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1.26 degroote 1667: printf("ipsec_in_reject: ESP m_flags:%x\n",
1668: m->m_flags));
1.1 jonathan 1669: return 1;
1670: }
1671:
1672: if (!need_auth &&
1.26 degroote 1673: isr->sav != NULL &&
1674: isr->sav->tdb_authalgxform != NULL &&
1675: (m->m_flags & M_AUTHIPDGM) == 0) {
1.1 jonathan 1676: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1.26 degroote 1677: printf("ipsec_in_reject: ESP/AH m_flags:%x\n",
1678: m->m_flags));
1.1 jonathan 1679: return 1;
1680: }
1681: break;
1682: case IPPROTO_AH:
1683: need_auth = 1;
1684: if ((m->m_flags & M_AUTHIPHDR) == 0) {
1685: KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1.26 degroote 1686: printf("ipsec_in_reject: AH m_flags:%x\n",
1687: m->m_flags));
1.1 jonathan 1688: return 1;
1689: }
1690: break;
1691: case IPPROTO_IPCOMP:
1692: /*
1693: * we don't really care, as IPcomp document
1694: * says that we shouldn't compress small
1695: * packets, IPComp policy should always be
1696: * treated as being in "use" level.
1697: */
1698: break;
1699: }
1700: }
1701: return 0; /* valid */
1702: }
1703:
1704: /*
1705: * Check AH/ESP integrity.
1706: * This function is called from tcp_input(), udp_input(),
1707: * and {ah,esp}4_input for tunnel mode
1708: */
1709: int
1.33 degroote 1710: ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
1.1 jonathan 1711: {
1712: struct secpolicy *sp;
1713: int error;
1714: int result;
1715:
1716: IPSEC_ASSERT(m != NULL, ("ipsec4_in_reject_so: null mbuf"));
1717:
1718: /* get SP for this packet.
1719: * When we are called from ip_forward(), we call
1720: * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1721: */
1722: if (inp == NULL)
1723: sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1724: else
1.5 jonathan 1725: sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
1726: IN4PCB_TO_PCB(inp), &error);
1.1 jonathan 1727:
1728: if (sp != NULL) {
1729: result = ipsec_in_reject(sp, m);
1730: if (result)
1.37 thorpej 1731: IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
1.1 jonathan 1732: KEY_FREESP(&sp);
1733: } else {
1734: result = 0; /* XXX should be panic ?
1735: * -> No, there may be error. */
1736: }
1737: return result;
1738: }
1739:
1740:
1741: #ifdef INET6
1742: /*
1743: * Check AH/ESP integrity.
1744: * This function is called from tcp6_input(), udp6_input(),
1745: * and {ah,esp}6_input for tunnel mode
1746: */
1747: int
1.33 degroote 1748: ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
1.1 jonathan 1749: {
1750: struct secpolicy *sp = NULL;
1751: int error;
1752: int result;
1753:
1754: /* sanity check */
1755: if (m == NULL)
1756: return 0; /* XXX should be panic ? */
1757:
1758: /* get SP for this packet.
1759: * When we are called from ip_forward(), we call
1760: * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1761: */
1.5 jonathan 1762: if (in6p == NULL)
1.1 jonathan 1763: sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1764: else
1.5 jonathan 1765: sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
1766: IN6PCB_TO_PCB(in6p),
1767: &error);
1.1 jonathan 1768:
1769: if (sp != NULL) {
1770: result = ipsec_in_reject(sp, m);
1771: if (result)
1.37 thorpej 1772: IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
1.1 jonathan 1773: KEY_FREESP(&sp);
1774: } else {
1775: result = 0;
1776: }
1777: return result;
1778: }
1779: #endif
1780:
1781: /*
1782: * compute the byte size to be occupied by IPsec header.
1783: * in case it is tunneled, it includes the size of outer IP header.
1784: * NOTE: SP passed is free in this function.
1785: */
1786: static size_t
1787: ipsec_hdrsiz(struct secpolicy *sp)
1788: {
1789: struct ipsecrequest *isr;
1790: size_t siz;
1791:
1792: KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1793: printf("ipsec_hdrsiz: using SP\n");
1794: kdebug_secpolicy(sp));
1795:
1796: switch (sp->policy) {
1797: case IPSEC_POLICY_DISCARD:
1798: case IPSEC_POLICY_BYPASS:
1799: case IPSEC_POLICY_NONE:
1800: return 0;
1801: }
1802:
1803: IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
1804: ("ipsec_hdrsiz: invalid policy %u", sp->policy));
1805:
1806: siz = 0;
1807: for (isr = sp->req; isr != NULL; isr = isr->next) {
1808: size_t clen = 0;
1809:
1810: switch (isr->saidx.proto) {
1811: case IPPROTO_ESP:
1812: clen = esp_hdrsiz(isr->sav);
1813: break;
1814: case IPPROTO_AH:
1815: clen = ah_hdrsiz(isr->sav);
1816: break;
1817: case IPPROTO_IPCOMP:
1818: clen = sizeof(struct ipcomp);
1819: break;
1820: }
1821:
1822: if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1823: switch (isr->saidx.dst.sa.sa_family) {
1824: case AF_INET:
1825: clen += sizeof(struct ip);
1826: break;
1827: #ifdef INET6
1828: case AF_INET6:
1829: clen += sizeof(struct ip6_hdr);
1830: break;
1831: #endif
1832: default:
1833: ipseclog((LOG_ERR, "ipsec_hdrsiz: "
1.26 degroote 1834: "unknown AF %d in IPsec tunnel SA\n",
1835: ((struct sockaddr *)&isr->saidx.dst)->sa_family));
1.1 jonathan 1836: break;
1837: }
1838: }
1839: siz += clen;
1840: }
1841:
1842: return siz;
1843: }
1844:
1845: /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
1846: size_t
1.33 degroote 1847: ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
1.1 jonathan 1848: {
1849: struct secpolicy *sp;
1850: int error;
1851: size_t size;
1852:
1853: IPSEC_ASSERT(m != NULL, ("ipsec4_hdrsiz: null mbuf"));
1854: IPSEC_ASSERT(inp == NULL || inp->inp_socket != NULL,
1855: ("ipsec4_hdrsize: socket w/o inpcb"));
1856:
1857: /* get SP for this packet.
1858: * When we are called from ip_forward(), we call
1859: * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1860: */
1861: if (inp == NULL)
1862: sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1863: else
1.5 jonathan 1864: sp = ipsec_getpolicybysock(m, dir,
1865: IN4PCB_TO_PCB(inp), &error);
1.1 jonathan 1866:
1867: if (sp != NULL) {
1868: size = ipsec_hdrsiz(sp);
1869: KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1870: printf("ipsec4_hdrsiz: size:%lu.\n",
1871: (unsigned long)size));
1872:
1873: KEY_FREESP(&sp);
1874: } else {
1875: size = 0; /* XXX should be panic ? */
1876: }
1877: return size;
1878: }
1879:
1880: #ifdef INET6
1881: /* This function is called from ipsec6_hdrsize_tcp(),
1882: * and maybe from ip6_forward.()
1883: */
1884: size_t
1.33 degroote 1885: ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
1.1 jonathan 1886: {
1887: struct secpolicy *sp;
1888: int error;
1889: size_t size;
1890:
1891: IPSEC_ASSERT(m != NULL, ("ipsec6_hdrsiz: null mbuf"));
1892: IPSEC_ASSERT(in6p == NULL || in6p->in6p_socket != NULL,
1893: ("ipsec6_hdrsize: socket w/o inpcb"));
1894:
1895: /* get SP for this packet */
1896: /* XXX Is it right to call with IP_FORWARDING. */
1897: if (in6p == NULL)
1898: sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1899: else
1.15 perry 1900: sp = ipsec_getpolicybysock(m, dir,
1.5 jonathan 1901: IN6PCB_TO_PCB(in6p),
1902: &error);
1.1 jonathan 1903:
1904: if (sp == NULL)
1905: return 0;
1906: size = ipsec_hdrsiz(sp);
1907: KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1908: printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
1909: KEY_FREESP(&sp);
1910:
1911: return size;
1912: }
1913: #endif /*INET6*/
1914:
1915: /*
1916: * Check the variable replay window.
1917: * ipsec_chkreplay() performs replay check before ICV verification.
1918: * ipsec_updatereplay() updates replay bitmap. This must be called after
1919: * ICV verification (it also performs replay check, which is usually done
1920: * beforehand).
1921: * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
1922: *
1923: * based on RFC 2401.
1924: */
1925: int
1.33 degroote 1926: ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
1.1 jonathan 1927: {
1928: const struct secreplay *replay;
1929: u_int32_t diff;
1930: int fr;
1931: u_int32_t wsizeb; /* constant: bits of window size */
1932: int frlast; /* constant: last frame */
1933:
1934: IPSEC_SPLASSERT_SOFTNET("ipsec_chkreplay");
1935:
1936: IPSEC_ASSERT(sav != NULL, ("ipsec_chkreplay: Null SA"));
1937: IPSEC_ASSERT(sav->replay != NULL, ("ipsec_chkreplay: Null replay state"));
1938:
1939: replay = sav->replay;
1940:
1941: if (replay->wsize == 0)
1942: return 1; /* no need to check replay. */
1943:
1944: /* constant */
1945: frlast = replay->wsize - 1;
1946: wsizeb = replay->wsize << 3;
1947:
1948: /* sequence number of 0 is invalid */
1949: if (seq == 0)
1950: return 0;
1951:
1952: /* first time is always okay */
1953: if (replay->count == 0)
1954: return 1;
1955:
1956: if (seq > replay->lastseq) {
1957: /* larger sequences are okay */
1958: return 1;
1959: } else {
1960: /* seq is equal or less than lastseq. */
1961: diff = replay->lastseq - seq;
1962:
1963: /* over range to check, i.e. too old or wrapped */
1964: if (diff >= wsizeb)
1965: return 0;
1966:
1967: fr = frlast - diff / 8;
1968:
1969: /* this packet already seen ? */
1970: if ((replay->bitmap)[fr] & (1 << (diff % 8)))
1971: return 0;
1972:
1973: /* out of order but good */
1974: return 1;
1975: }
1976: }
1977:
1978: /*
1979: * check replay counter whether to update or not.
1980: * OUT: 0: OK
1981: * 1: NG
1982: */
1983: int
1.33 degroote 1984: ipsec_updatereplay(u_int32_t seq, struct secasvar *sav)
1.1 jonathan 1985: {
1986: struct secreplay *replay;
1987: u_int32_t diff;
1988: int fr;
1989: u_int32_t wsizeb; /* constant: bits of window size */
1990: int frlast; /* constant: last frame */
1991:
1992: IPSEC_SPLASSERT_SOFTNET("ipsec_updatereplay");
1993:
1994: IPSEC_ASSERT(sav != NULL, ("ipsec_updatereplay: Null SA"));
1995: IPSEC_ASSERT(sav->replay != NULL, ("ipsec_updatereplay: Null replay state"));
1996:
1997: replay = sav->replay;
1998:
1999: if (replay->wsize == 0)
2000: goto ok; /* no need to check replay. */
2001:
2002: /* constant */
2003: frlast = replay->wsize - 1;
2004: wsizeb = replay->wsize << 3;
2005:
2006: /* sequence number of 0 is invalid */
2007: if (seq == 0)
2008: return 1;
2009:
2010: /* first time */
2011: if (replay->count == 0) {
2012: replay->lastseq = seq;
2013: bzero(replay->bitmap, replay->wsize);
2014: (replay->bitmap)[frlast] = 1;
2015: goto ok;
2016: }
2017:
2018: if (seq > replay->lastseq) {
2019: /* seq is larger than lastseq. */
2020: diff = seq - replay->lastseq;
2021:
2022: /* new larger sequence number */
2023: if (diff < wsizeb) {
2024: /* In window */
2025: /* set bit for this packet */
2026: vshiftl(replay->bitmap, diff, replay->wsize);
2027: (replay->bitmap)[frlast] |= 1;
2028: } else {
2029: /* this packet has a "way larger" */
2030: bzero(replay->bitmap, replay->wsize);
2031: (replay->bitmap)[frlast] = 1;
2032: }
2033: replay->lastseq = seq;
2034:
2035: /* larger is good */
2036: } else {
2037: /* seq is equal or less than lastseq. */
2038: diff = replay->lastseq - seq;
2039:
2040: /* over range to check, i.e. too old or wrapped */
2041: if (diff >= wsizeb)
2042: return 1;
2043:
2044: fr = frlast - diff / 8;
2045:
2046: /* this packet already seen ? */
2047: if ((replay->bitmap)[fr] & (1 << (diff % 8)))
2048: return 1;
2049:
2050: /* mark as seen */
2051: (replay->bitmap)[fr] |= (1 << (diff % 8));
2052:
2053: /* out of order but good */
2054: }
2055:
2056: ok:
2057: if (replay->count == ~0) {
2058:
2059: /* set overflow flag */
2060: replay->overflow++;
2061:
2062: /* don't increment, no more packets accepted */
2063: if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
2064: return 1;
2065:
2066: ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
1.26 degroote 2067: replay->overflow, ipsec_logsastr(sav)));
1.1 jonathan 2068: }
2069:
2070: replay->count++;
2071:
2072: return 0;
2073: }
2074:
2075: /*
2076: * shift variable length bunffer to left.
2077: * IN: bitmap: pointer to the buffer
2078: * nbit: the number of to shift.
2079: * wsize: buffer size (bytes).
2080: */
2081: static void
1.33 degroote 2082: vshiftl(unsigned char *bitmap, int nbit, int wsize)
1.1 jonathan 2083: {
2084: int s, j, i;
2085: unsigned char over;
2086:
2087: for (j = 0; j < nbit; j += 8) {
2088: s = (nbit - j < 8) ? (nbit - j): 8;
2089: bitmap[0] <<= s;
2090: for (i = 1; i < wsize; i++) {
2091: over = (bitmap[i] >> (8 - s));
2092: bitmap[i] <<= s;
2093: bitmap[i-1] |= over;
2094: }
2095: }
2096:
2097: return;
2098: }
2099:
2100: /* Return a printable string for the IPv4 address. */
2101: static char *
2102: inet_ntoa4(struct in_addr ina)
2103: {
2104: static char buf[4][4 * sizeof "123" + 4];
2105: unsigned char *ucp = (unsigned char *) &ina;
2106: static int i = 3;
2107:
2108: i = (i + 1) % 4;
1.11 itojun 2109: snprintf(buf[i], sizeof(buf[i]), "%d.%d.%d.%d",
1.26 degroote 2110: ucp[0] & 0xff, ucp[1] & 0xff, ucp[2] & 0xff, ucp[3] & 0xff);
1.1 jonathan 2111: return (buf[i]);
2112: }
2113:
2114: /* Return a printable string for the address. */
1.17 christos 2115: const char *
1.1 jonathan 2116: ipsec_address(union sockaddr_union* sa)
2117: {
2118: switch (sa->sa.sa_family) {
2119: #if INET
2120: case AF_INET:
2121: return inet_ntoa4(sa->sin.sin_addr);
2122: #endif /* INET */
2123:
2124: #if INET6
2125: case AF_INET6:
2126: return ip6_sprintf(&sa->sin6.sin6_addr);
2127: #endif /* INET6 */
2128:
2129: default:
2130: return "(unknown address family)";
2131: }
2132: }
2133:
2134: const char *
1.33 degroote 2135: ipsec_logsastr(struct secasvar *sav)
1.1 jonathan 2136: {
2137: static char buf[256];
2138: char *p;
2139: struct secasindex *saidx = &sav->sah->saidx;
2140:
2141: IPSEC_ASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
2142: ("ipsec_logsastr: address family mismatch"));
2143:
2144: p = buf;
2145: snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
2146: while (p && *p)
2147: p++;
2148: /* NB: only use ipsec_address on one address at a time */
2149: snprintf(p, sizeof (buf) - (p - buf), "src=%s ",
2150: ipsec_address(&saidx->src));
2151: while (p && *p)
2152: p++;
2153: snprintf(p, sizeof (buf) - (p - buf), "dst=%s)",
2154: ipsec_address(&saidx->dst));
2155:
2156: return buf;
2157: }
2158:
2159: void
1.33 degroote 2160: ipsec_dumpmbuf(struct mbuf *m)
1.1 jonathan 2161: {
2162: int totlen;
2163: int i;
2164: u_char *p;
2165:
2166: totlen = 0;
2167: printf("---\n");
2168: while (m) {
2169: p = mtod(m, u_char *);
2170: for (i = 0; i < m->m_len; i++) {
2171: printf("%02x ", p[i]);
2172: totlen++;
2173: if (totlen % 16 == 0)
2174: printf("\n");
2175: }
2176: m = m->m_next;
2177: }
2178: if (totlen % 16 != 0)
2179: printf("\n");
2180: printf("---\n");
2181: }
2182:
1.26 degroote 2183: #ifdef INET6
2184: struct secpolicy *
1.33 degroote 2185: ipsec6_check_policy(struct mbuf * m, const struct socket * so,
2186: int flags, int * needipsecp, int * errorp)
1.26 degroote 2187: {
2188: struct in6pcb *in6p = NULL;
2189: struct secpolicy *sp = NULL;
2190: int s;
2191: int error = 0;
2192: int needipsec = 0;
2193:
2194: if (so != NULL && so->so_proto->pr_domain->dom_family == AF_INET6)
2195: in6p = sotoin6pcb(so);
2196:
1.36 degroote 2197: if (!ipsec_outdone(m)) {
2198: s = splsoftnet();
1.26 degroote 2199: if (in6p != NULL &&
1.36 degroote 2200: IPSEC_PCB_SKIP_IPSEC(in6p->in6p_sp, IPSEC_DIR_OUTBOUND))
1.26 degroote 2201: goto skippolicycheck;
2202: sp = ipsec6_checkpolicy(m, IPSEC_DIR_OUTBOUND, flags, &error,in6p);
2203:
1.36 degroote 2204: /*
2205: * There are four return cases:
2206: * sp != NULL apply IPsec policy
2207: * sp == NULL, error == 0 no IPsec handling needed
2208: * sp == NULL, error == -EINVAL discard packet w/o error
2209: * sp == NULL, error != 0 discard packet, report error
2210: */
2211:
1.26 degroote 2212: splx(s);
1.36 degroote 2213: if (sp == NULL) {
2214: /*
2215: * Caller must check the error return to see if it needs to discard
2216: * the packet.
2217: */
1.26 degroote 2218: needipsec = 0;
2219: } else {
1.36 degroote 2220: needipsec = 1;
1.26 degroote 2221: }
2222: }
2223: skippolicycheck:;
2224:
2225: *errorp = error;
2226: *needipsecp = needipsec;
2227: return sp;
2228: }
2229: #endif
2230:
2231:
2232:
1.1 jonathan 2233: /* XXX this stuff doesn't belong here... */
2234:
2235: static struct xformsw* xforms = NULL;
2236:
2237: /*
2238: * Register a transform; typically at system startup.
2239: */
2240: void
2241: xform_register(struct xformsw* xsp)
2242: {
2243: xsp->xf_next = xforms;
2244: xforms = xsp;
2245: }
2246:
2247: /*
2248: * Initialize transform support in an sav.
2249: */
2250: int
2251: xform_init(struct secasvar *sav, int xftype)
2252: {
2253: struct xformsw *xsp;
2254:
2255: if (sav->tdb_xform != NULL) /* previously initialized */
2256: return 0;
2257: for (xsp = xforms; xsp; xsp = xsp->xf_next)
2258: if (xsp->xf_type == xftype)
2259: return (*xsp->xf_init)(sav, xsp);
2260:
2261: DPRINTF(("xform_init: no match for xform type %d\n", xftype));
2262: return EINVAL;
2263: }
2264:
2265: #ifdef __NetBSD__
1.37 thorpej 2266: /*
2267: * XXXJRT This should be done as a protosw init call.
2268: */
1.1 jonathan 2269: void
2270: ipsec_attach(void)
2271: {
1.37 thorpej 2272:
2273: ipsecstat_percpu = percpu_alloc(sizeof(uint64_t) * IPSEC_NSTATS);
2274:
1.1 jonathan 2275: printf("initializing IPsec...");
2276: ah_attach();
2277: esp_attach();
2278: ipcomp_attach();
2279: ipe4_attach();
1.12 jonathan 2280: #ifdef TCP_SIGNATURE
2281: tcpsignature_attach();
2282: #endif
1.1 jonathan 2283: printf(" done\n");
2284: }
2285: #endif /* __NetBSD__ */
CVSweb <webmaster@jp.NetBSD.org>