Annotation of sys/net/pfkeyv2_convert.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pfkeyv2_convert.c,v 1.29 2006/11/24 13:52:14 reyk Exp $ */
2: /*
3: * The author of this code is Angelos D. Keromytis (angelos@keromytis.org)
4: *
5: * Part of this code is based on code written by Craig Metz (cmetz@inner.net)
6: * for NRL. Those licenses follow this one.
7: *
8: * Copyright (c) 2001 Angelos D. Keromytis.
9: *
10: * Permission to use, copy, and modify this software with or without fee
11: * is hereby granted, provided that this entire notice is included in
12: * all copies of any software which is or includes a copy or
13: * modification of this software.
14: * You may use this code under the GNU public license if you so wish. Please
15: * contribute changes back to the authors under this freer than GPL license
16: * so that we may further the use of strong encryption without limitations to
17: * all.
18: *
19: * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
20: * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
21: * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
22: * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
23: * PURPOSE.
24: */
25:
26: /*
27: * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
28: *
29: * NRL grants permission for redistribution and use in source and binary
30: * forms, with or without modification, of the software and documentation
31: * created at NRL provided that the following conditions are met:
32: *
33: * 1. Redistributions of source code must retain the above copyright
34: * notice, this list of conditions and the following disclaimer.
35: * 2. Redistributions in binary form must reproduce the above copyright
36: * notice, this list of conditions and the following disclaimer in the
37: * documentation and/or other materials provided with the distribution.
38: * 3. All advertising materials mentioning features or use of this software
39: * must display the following acknowledgements:
40: * This product includes software developed by the University of
41: * California, Berkeley and its contributors.
42: * This product includes software developed at the Information
43: * Technology Division, US Naval Research Laboratory.
44: * 4. Neither the name of the NRL nor the names of its contributors
45: * may be used to endorse or promote products derived from this software
46: * without specific prior written permission.
47: *
48: * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
49: * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
50: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
51: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
52: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59: *
60: * The views and conclusions contained in the software and documentation
61: * are those of the authors and should not be interpreted as representing
62: * official policies, either expressed or implied, of the US Naval
63: * Research Laboratory (NRL).
64: */
65:
66: /*
67: * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
68: *
69: * Redistribution and use in source and binary forms, with or without
70: * modification, are permitted provided that the following conditions
71: * are met:
72: * 1. Redistributions of source code must retain the above copyright
73: * notice, this list of conditions and the following disclaimer.
74: * 2. Redistributions in binary form must reproduce the above copyright
75: * notice, this list of conditions and the following disclaimer in the
76: * documentation and/or other materials provided with the distribution.
77: * 3. Neither the name of the author nor the names of any contributors
78: * may be used to endorse or promote products derived from this software
79: * without specific prior written permission.
80: *
81: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91: * SUCH DAMAGE.
92: */
93:
94: #include "pf.h"
95:
96: #include <sys/types.h>
97: #include <sys/param.h>
98: #include <sys/systm.h>
99: #include <sys/mbuf.h>
100: #include <sys/kernel.h>
101: #include <sys/socket.h>
102: #include <net/route.h>
103: #include <net/if.h>
104:
105: #if NPF > 0
106: #include <net/pfvar.h>
107: #endif
108:
109: #include <netinet/ip_ipsp.h>
110: #ifdef INET6
111: #include <netinet6/in6_var.h>
112: #endif
113: #include <net/pfkeyv2.h>
114: #include <crypto/cryptodev.h>
115: #include <crypto/xform.h>
116:
117: /*
118: * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
119: * of the TDB will be initialized by other import routines, and tdb_init().
120: */
121: void
122: import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
123: {
124: if (!sadb_sa)
125: return;
126:
127: if (ii) {
128: ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
129: ii->ii_authalg = sadb_sa->sadb_sa_auth;
130: ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
131:
132: tdb->tdb_spi = sadb_sa->sadb_sa_spi;
133: tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
134:
135: if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
136: tdb->tdb_flags |= TDBF_PFS;
137:
138: if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV)
139: tdb->tdb_flags |= TDBF_HALFIV;
140:
141: if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
142: tdb->tdb_flags |= TDBF_TUNNELING;
143:
144: if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING)
145: tdb->tdb_flags |= TDBF_RANDOMPADDING;
146:
147: if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY)
148: tdb->tdb_flags |= TDBF_NOREPLAY;
149:
150: if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
151: tdb->tdb_flags |= TDBF_UDPENCAP;
152: }
153:
154: if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
155: tdb->tdb_flags |= TDBF_INVALID;
156: }
157:
158: /*
159: * Export some of the information on a TDB.
160: */
161: void
162: export_sa(void **p, struct tdb *tdb)
163: {
164: struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
165:
166: sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
167:
168: sadb_sa->sadb_sa_spi = tdb->tdb_spi;
169: sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
170:
171: if (tdb->tdb_flags & TDBF_INVALID)
172: sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
173: else
174: sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE;
175:
176: if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
177: tdb->tdb_compalgxform != NULL) {
178: switch (tdb->tdb_compalgxform->type) {
179: case CRYPTO_DEFLATE_COMP:
180: sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
181: break;
182: case CRYPTO_LZS_COMP:
183: sadb_sa->sadb_sa_encrypt = SADB_X_CALG_LZS;
184: break;
185: }
186: }
187:
188: if (tdb->tdb_authalgxform) {
189: switch (tdb->tdb_authalgxform->type) {
190: case CRYPTO_MD5_HMAC:
191: sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
192: break;
193:
194: case CRYPTO_SHA1_HMAC:
195: sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
196: break;
197:
198: case CRYPTO_RIPEMD160_HMAC:
199: sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
200: break;
201:
202: case CRYPTO_SHA2_256_HMAC:
203: sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
204: break;
205:
206: case CRYPTO_SHA2_384_HMAC:
207: sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
208: break;
209:
210: case CRYPTO_SHA2_512_HMAC:
211: sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
212: break;
213:
214: case CRYPTO_MD5_KPDK:
215: sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5;
216: break;
217:
218: case CRYPTO_SHA1_KPDK:
219: sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1;
220: break;
221: }
222: }
223:
224: if (tdb->tdb_encalgxform) {
225: switch (tdb->tdb_encalgxform->type) {
226: case CRYPTO_NULL:
227: sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL;
228: break;
229:
230: case CRYPTO_DES_CBC:
231: sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC;
232: break;
233:
234: case CRYPTO_3DES_CBC:
235: sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
236: break;
237:
238: case CRYPTO_AES_CBC:
239: sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
240: break;
241:
242: case CRYPTO_AES_CTR:
243: sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
244: break;
245:
246: case CRYPTO_CAST_CBC:
247: sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
248: break;
249:
250: case CRYPTO_BLF_CBC:
251: sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
252: break;
253:
254: case CRYPTO_SKIPJACK_CBC:
255: sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK;
256: break;
257: }
258: }
259:
260: if (tdb->tdb_flags & TDBF_PFS)
261: sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
262:
263: /* Only relevant for the "old" IPsec transforms. */
264: if (tdb->tdb_flags & TDBF_HALFIV)
265: sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
266:
267: if (tdb->tdb_flags & TDBF_TUNNELING)
268: sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
269:
270: if (tdb->tdb_flags & TDBF_RANDOMPADDING)
271: sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING;
272:
273: if (tdb->tdb_flags & TDBF_NOREPLAY)
274: sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
275:
276: *p += sizeof(struct sadb_sa);
277: }
278:
279: /*
280: * Initialize expirations and counters based on lifetime payload.
281: */
282: void
283: import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
284: {
285: struct timeval tv;
286:
287: if (!sadb_lifetime)
288: return;
289:
290: getmicrotime(&tv);
291:
292: switch (type) {
293: case PFKEYV2_LIFETIME_HARD:
294: if ((tdb->tdb_exp_allocations =
295: sadb_lifetime->sadb_lifetime_allocations) != 0)
296: tdb->tdb_flags |= TDBF_ALLOCATIONS;
297: else
298: tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
299:
300: if ((tdb->tdb_exp_bytes =
301: sadb_lifetime->sadb_lifetime_bytes) != 0)
302: tdb->tdb_flags |= TDBF_BYTES;
303: else
304: tdb->tdb_flags &= ~TDBF_BYTES;
305:
306: if ((tdb->tdb_exp_timeout =
307: sadb_lifetime->sadb_lifetime_addtime) != 0) {
308: tdb->tdb_flags |= TDBF_TIMER;
309: if (tv.tv_sec + tdb->tdb_exp_timeout < tv.tv_sec)
310: tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
311: else
312: tv.tv_sec += tdb->tdb_exp_timeout;
313: timeout_add(&tdb->tdb_timer_tmo, hzto(&tv));
314: } else
315: tdb->tdb_flags &= ~TDBF_TIMER;
316:
317: if ((tdb->tdb_exp_first_use =
318: sadb_lifetime->sadb_lifetime_usetime) != 0)
319: tdb->tdb_flags |= TDBF_FIRSTUSE;
320: else
321: tdb->tdb_flags &= ~TDBF_FIRSTUSE;
322: break;
323:
324: case PFKEYV2_LIFETIME_SOFT:
325: if ((tdb->tdb_soft_allocations =
326: sadb_lifetime->sadb_lifetime_allocations) != 0)
327: tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
328: else
329: tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
330:
331: if ((tdb->tdb_soft_bytes =
332: sadb_lifetime->sadb_lifetime_bytes) != 0)
333: tdb->tdb_flags |= TDBF_SOFT_BYTES;
334: else
335: tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
336:
337: if ((tdb->tdb_soft_timeout =
338: sadb_lifetime->sadb_lifetime_addtime) != 0) {
339: tdb->tdb_flags |= TDBF_SOFT_TIMER;
340: if (tv.tv_sec + tdb->tdb_soft_timeout < tv.tv_sec)
341: tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
342: else
343: tv.tv_sec += tdb->tdb_soft_timeout;
344: timeout_add(&tdb->tdb_stimer_tmo, hzto(&tv));
345: } else
346: tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
347:
348: if ((tdb->tdb_soft_first_use =
349: sadb_lifetime->sadb_lifetime_usetime) != 0)
350: tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
351: else
352: tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
353: break;
354:
355: case PFKEYV2_LIFETIME_CURRENT: /* Nothing fancy here. */
356: tdb->tdb_cur_allocations =
357: sadb_lifetime->sadb_lifetime_allocations;
358: tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
359: tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
360: tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
361: }
362: }
363:
364: /*
365: * Export TDB expiration information.
366: */
367: void
368: export_lifetime(void **p, struct tdb *tdb, int type)
369: {
370: struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
371:
372: sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
373: sizeof(uint64_t);
374:
375: switch (type) {
376: case PFKEYV2_LIFETIME_HARD:
377: if (tdb->tdb_flags & TDBF_ALLOCATIONS)
378: sadb_lifetime->sadb_lifetime_allocations =
379: tdb->tdb_exp_allocations;
380:
381: if (tdb->tdb_flags & TDBF_BYTES)
382: sadb_lifetime->sadb_lifetime_bytes =
383: tdb->tdb_exp_bytes;
384:
385: if (tdb->tdb_flags & TDBF_TIMER)
386: sadb_lifetime->sadb_lifetime_addtime =
387: tdb->tdb_exp_timeout;
388:
389: if (tdb->tdb_flags & TDBF_FIRSTUSE)
390: sadb_lifetime->sadb_lifetime_usetime =
391: tdb->tdb_exp_first_use;
392: break;
393:
394: case PFKEYV2_LIFETIME_SOFT:
395: if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
396: sadb_lifetime->sadb_lifetime_allocations =
397: tdb->tdb_soft_allocations;
398:
399: if (tdb->tdb_flags & TDBF_SOFT_BYTES)
400: sadb_lifetime->sadb_lifetime_bytes =
401: tdb->tdb_soft_bytes;
402:
403: if (tdb->tdb_flags & TDBF_SOFT_TIMER)
404: sadb_lifetime->sadb_lifetime_addtime =
405: tdb->tdb_soft_timeout;
406:
407: if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
408: sadb_lifetime->sadb_lifetime_usetime =
409: tdb->tdb_soft_first_use;
410: break;
411:
412: case PFKEYV2_LIFETIME_CURRENT:
413: sadb_lifetime->sadb_lifetime_allocations =
414: tdb->tdb_cur_allocations;
415: sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
416: sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
417: sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
418: break;
419:
420: case PFKEYV2_LIFETIME_LASTUSE:
421: sadb_lifetime->sadb_lifetime_allocations = 0;
422: sadb_lifetime->sadb_lifetime_bytes = 0;
423: sadb_lifetime->sadb_lifetime_addtime = 0;
424: sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used;
425: break;
426: }
427:
428: *p += sizeof(struct sadb_lifetime);
429: }
430:
431: /*
432: * Import flow information to two struct sockaddr_encap's. Either
433: * all or none of the address arguments are NULL.
434: */
435: void
436: import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
437: struct sadb_address *ssrc, struct sadb_address *ssrcmask,
438: struct sadb_address *ddst, struct sadb_address *ddstmask,
439: struct sadb_protocol *sab, struct sadb_protocol *ftype)
440: {
441: u_int8_t transproto = 0;
442: union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1);
443: union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1);
444: union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1);
445: union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1);
446:
447: if (ssrc == NULL)
448: return; /* There wasn't any information to begin with. */
449:
450: bzero(flow, sizeof(*flow));
451: bzero(flowmask, sizeof(*flowmask));
452:
453: if (sab != NULL)
454: transproto = sab->sadb_protocol_proto;
455:
456: /*
457: * Check that all the address families match. We know they are
458: * valid and supported because pfkeyv2_parsemessage() checked that.
459: */
460: if ((src->sa.sa_family != dst->sa.sa_family) ||
461: (src->sa.sa_family != srcmask->sa.sa_family) ||
462: (src->sa.sa_family != dstmask->sa.sa_family))
463: return;
464:
465: /*
466: * We set these as an indication that tdb_filter/tdb_filtermask are
467: * in fact initialized.
468: */
469: flow->sen_family = flowmask->sen_family = PF_KEY;
470: flow->sen_len = flowmask->sen_len = SENT_LEN;
471:
472: switch (src->sa.sa_family)
473: {
474: #ifdef INET
475: case AF_INET:
476: /* netmask handling */
477: rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
478: rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
479:
480: flow->sen_type = SENT_IP4;
481: flow->sen_direction = ftype->sadb_protocol_direction;
482: flow->sen_ip_src = src->sin.sin_addr;
483: flow->sen_ip_dst = dst->sin.sin_addr;
484: flow->sen_proto = transproto;
485: flow->sen_sport = src->sin.sin_port;
486: flow->sen_dport = dst->sin.sin_port;
487:
488: flowmask->sen_type = SENT_IP4;
489: flowmask->sen_direction = 0xff;
490: flowmask->sen_ip_src = srcmask->sin.sin_addr;
491: flowmask->sen_ip_dst = dstmask->sin.sin_addr;
492: flowmask->sen_sport = srcmask->sin.sin_port;
493: flowmask->sen_dport = dstmask->sin.sin_port;
494: if (transproto)
495: flowmask->sen_proto = 0xff;
496: break;
497: #endif /* INET */
498:
499: #ifdef INET6
500: case AF_INET6:
501: in6_embedscope(&src->sin6.sin6_addr, &src->sin6,
502: NULL, NULL);
503: in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6,
504: NULL, NULL);
505:
506: /* netmask handling */
507: rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
508: rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
509:
510: flow->sen_type = SENT_IP6;
511: flow->sen_ip6_direction = ftype->sadb_protocol_direction;
512: flow->sen_ip6_src = src->sin6.sin6_addr;
513: flow->sen_ip6_dst = dst->sin6.sin6_addr;
514: flow->sen_ip6_proto = transproto;
515: flow->sen_ip6_sport = src->sin6.sin6_port;
516: flow->sen_ip6_dport = dst->sin6.sin6_port;
517:
518: flowmask->sen_type = SENT_IP6;
519: flowmask->sen_ip6_direction = 0xff;
520: flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
521: flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
522: flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
523: flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
524: if (transproto)
525: flowmask->sen_ip6_proto = 0xff;
526: break;
527: #endif /* INET6 */
528: }
529: }
530:
531: /*
532: * Helper to export addresses from an struct sockaddr_encap.
533: */
534: static void
535: export_encap(void **p, struct sockaddr_encap *encap, int type)
536: {
537: struct sadb_address *saddr = (struct sadb_address *)*p;
538: union sockaddr_union *sunion;
539:
540: *p += sizeof(struct sadb_address);
541: sunion = (union sockaddr_union *)*p;
542:
543: switch (encap->sen_type) {
544: case SENT_IP4:
545: saddr->sadb_address_len = (sizeof(struct sadb_address) +
546: PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
547: sunion->sa.sa_len = sizeof(struct sockaddr_in);
548: sunion->sa.sa_family = AF_INET;
549: if (type == SADB_X_EXT_SRC_FLOW ||
550: type == SADB_X_EXT_SRC_MASK) {
551: sunion->sin.sin_addr = encap->sen_ip_src;
552: sunion->sin.sin_port = encap->sen_sport;
553: } else {
554: sunion->sin.sin_addr = encap->sen_ip_dst;
555: sunion->sin.sin_port = encap->sen_dport;
556: }
557: *p += PADUP(sizeof(struct sockaddr_in));
558: break;
559: case SENT_IP6:
560: saddr->sadb_address_len = (sizeof(struct sadb_address)
561: + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
562: sunion->sa.sa_len = sizeof(struct sockaddr_in6);
563: sunion->sa.sa_family = AF_INET6;
564: if (type == SADB_X_EXT_SRC_FLOW ||
565: type == SADB_X_EXT_SRC_MASK) {
566: sunion->sin6.sin6_addr = encap->sen_ip6_src;
567: sunion->sin6.sin6_port = encap->sen_ip6_sport;
568: } else {
569: sunion->sin6.sin6_addr = encap->sen_ip6_dst;
570: sunion->sin6.sin6_port = encap->sen_ip6_dport;
571: }
572: *p += PADUP(sizeof(struct sockaddr_in6));
573: break;
574: }
575: }
576:
577: /*
578: * Export flow information from two struct sockaddr_encap's.
579: */
580: void
581: export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
582: struct sockaddr_encap *flowmask, void **headers)
583: {
584: struct sadb_protocol *sab;
585:
586: headers[SADB_X_EXT_FLOW_TYPE] = *p;
587: sab = (struct sadb_protocol *)*p;
588: sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
589: sizeof(uint64_t);
590:
591: switch (ftype) {
592: case IPSP_IPSEC_USE:
593: sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
594: break;
595: case IPSP_IPSEC_ACQUIRE:
596: sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
597: break;
598: case IPSP_IPSEC_REQUIRE:
599: sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
600: break;
601: case IPSP_DENY:
602: sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
603: break;
604: case IPSP_PERMIT:
605: sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
606: break;
607: case IPSP_IPSEC_DONTACQ:
608: sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
609: break;
610: default:
611: sab->sadb_protocol_proto = 0;
612: break;
613: }
614:
615: switch (flow->sen_type) {
616: #ifdef INET
617: case SENT_IP4:
618: sab->sadb_protocol_direction = flow->sen_direction;
619: break;
620: #endif /* INET */
621: #ifdef INET6
622: case SENT_IP6:
623: sab->sadb_protocol_direction = flow->sen_ip6_direction;
624: break;
625: #endif /* INET6 */
626: }
627: *p += sizeof(struct sadb_protocol);
628:
629: headers[SADB_X_EXT_PROTOCOL] = *p;
630: sab = (struct sadb_protocol *)*p;
631: sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
632: sizeof(uint64_t);
633: switch (flow->sen_type) {
634: #ifdef INET
635: case SENT_IP4:
636: sab->sadb_protocol_proto = flow->sen_proto;
637: break;
638: #endif /* INET */
639: #ifdef INET6
640: case SENT_IP6:
641: sab->sadb_protocol_proto = flow->sen_ip6_proto;
642: break;
643: #endif /* INET6 */
644: }
645: *p += sizeof(struct sadb_protocol);
646:
647: headers[SADB_X_EXT_SRC_FLOW] = *p;
648: export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
649:
650: headers[SADB_X_EXT_SRC_MASK] = *p;
651: export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
652:
653: headers[SADB_X_EXT_DST_FLOW] = *p;
654: export_encap(p, flow, SADB_X_EXT_DST_FLOW);
655:
656: headers[SADB_X_EXT_DST_MASK] = *p;
657: export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
658: }
659:
660: /*
661: * Copy an SADB_ADDRESS payload to a struct sockaddr.
662: */
663: void
664: import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
665: {
666: int salen;
667: struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
668: sizeof(struct sadb_address));
669:
670: if (!sadb_address)
671: return;
672:
673: if (ssa->sa_len)
674: salen = ssa->sa_len;
675: else
676: switch (ssa->sa_family) {
677: #ifdef INET
678: case AF_INET:
679: salen = sizeof(struct sockaddr_in);
680: break;
681: #endif /* INET */
682:
683: #if INET6
684: case AF_INET6:
685: salen = sizeof(struct sockaddr_in6);
686: break;
687: #endif /* INET6 */
688:
689: default:
690: return;
691: }
692:
693: bcopy(ssa, sa, salen);
694: sa->sa_len = salen;
695: }
696:
697: /*
698: * Export a struct sockaddr as an SADB_ADDRESS payload.
699: */
700: void
701: export_address(void **p, struct sockaddr *sa)
702: {
703: struct sadb_address *sadb_address = (struct sadb_address *) *p;
704:
705: sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
706: PADUP(SA_LEN(sa))) / sizeof(uint64_t);
707:
708: *p += sizeof(struct sadb_address);
709: bcopy(sa, *p, SA_LEN(sa));
710: ((struct sockaddr *) *p)->sa_family = sa->sa_family;
711: *p += PADUP(SA_LEN(sa));
712: }
713:
714: /*
715: * Import authentication information into the TDB.
716: */
717: void
718: import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth)
719: {
720: struct ipsec_ref **ipr;
721:
722: if (!sadb_auth)
723: return;
724:
725: if (dstauth == PFKEYV2_AUTH_REMOTE)
726: ipr = &tdb->tdb_remote_auth;
727: else
728: ipr = &tdb->tdb_local_auth;
729:
730: MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) -
731: sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
732: M_CREDENTIALS, M_WAITOK);
733: (*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred);
734:
735: switch (sadb_auth->sadb_x_cred_type) {
736: case SADB_X_AUTHTYPE_PASSPHRASE:
737: (*ipr)->ref_type = IPSP_AUTH_PASSPHRASE;
738: break;
739: case SADB_X_AUTHTYPE_RSA:
740: (*ipr)->ref_type = IPSP_AUTH_RSA;
741: break;
742: default:
743: FREE(*ipr, M_CREDENTIALS);
744: *ipr = NULL;
745: return;
746: }
747: (*ipr)->ref_count = 1;
748: (*ipr)->ref_malloctype = M_CREDENTIALS;
749: bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred),
750: (*ipr) + 1, (*ipr)->ref_len);
751: }
752:
753: /*
754: * Import a set of credentials into the TDB.
755: */
756: void
757: import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred)
758: {
759: struct ipsec_ref **ipr;
760:
761: if (!sadb_cred)
762: return;
763:
764: if (dstcred == PFKEYV2_CRED_REMOTE)
765: ipr = &tdb->tdb_remote_cred;
766: else
767: ipr = &tdb->tdb_local_cred;
768:
769: MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) -
770: sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
771: M_CREDENTIALS, M_WAITOK);
772: (*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred);
773:
774: switch (sadb_cred->sadb_x_cred_type) {
775: case SADB_X_CREDTYPE_X509:
776: (*ipr)->ref_type = IPSP_CRED_X509;
777: break;
778: case SADB_X_CREDTYPE_KEYNOTE:
779: (*ipr)->ref_type = IPSP_CRED_KEYNOTE;
780: break;
781: default:
782: FREE(*ipr, M_CREDENTIALS);
783: *ipr = NULL;
784: return;
785: }
786: (*ipr)->ref_count = 1;
787: (*ipr)->ref_malloctype = M_CREDENTIALS;
788: bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred),
789: (*ipr) + 1, (*ipr)->ref_len);
790: }
791:
792: /*
793: * Import an identity payload into the TDB.
794: */
795: void
796: import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type)
797: {
798: struct ipsec_ref **ipr;
799:
800: if (!sadb_ident)
801: return;
802:
803: if (type == PFKEYV2_IDENTITY_SRC)
804: ipr = &tdb->tdb_srcid;
805: else
806: ipr = &tdb->tdb_dstid;
807:
808: MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) -
809: sizeof(struct sadb_ident) + sizeof(struct ipsec_ref),
810: M_CREDENTIALS, M_WAITOK);
811: (*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
812:
813: switch (sadb_ident->sadb_ident_type) {
814: case SADB_IDENTTYPE_PREFIX:
815: (*ipr)->ref_type = IPSP_IDENTITY_PREFIX;
816: break;
817: case SADB_IDENTTYPE_FQDN:
818: (*ipr)->ref_type = IPSP_IDENTITY_FQDN;
819: break;
820: case SADB_IDENTTYPE_USERFQDN:
821: (*ipr)->ref_type = IPSP_IDENTITY_USERFQDN;
822: break;
823: case SADB_X_IDENTTYPE_CONNECTION:
824: (*ipr)->ref_type = IPSP_IDENTITY_CONNECTION;
825: break;
826: default:
827: FREE(*ipr, M_CREDENTIALS);
828: *ipr = NULL;
829: return;
830: }
831: (*ipr)->ref_count = 1;
832: (*ipr)->ref_malloctype = M_CREDENTIALS;
833: bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1,
834: (*ipr)->ref_len);
835: }
836:
837: void
838: export_credentials(void **p, struct tdb *tdb, int dstcred)
839: {
840: struct ipsec_ref **ipr;
841: struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p;
842:
843: if (dstcred == PFKEYV2_CRED_REMOTE)
844: ipr = &tdb->tdb_remote_cred;
845: else
846: ipr = &tdb->tdb_local_cred;
847:
848: sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
849: PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
850:
851: switch ((*ipr)->ref_type) {
852: case IPSP_CRED_KEYNOTE:
853: sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
854: break;
855: case IPSP_CRED_X509:
856: sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
857: break;
858: }
859: *p += sizeof(struct sadb_x_cred);
860: bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
861: *p += PADUP((*ipr)->ref_len);
862: }
863:
864: void
865: export_auth(void **p, struct tdb *tdb, int dstauth)
866: {
867: struct ipsec_ref **ipr;
868: struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p;
869:
870: if (dstauth == PFKEYV2_AUTH_REMOTE)
871: ipr = &tdb->tdb_remote_auth;
872: else
873: ipr = &tdb->tdb_local_auth;
874:
875: sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
876: PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
877:
878: switch ((*ipr)->ref_type) {
879: case IPSP_AUTH_PASSPHRASE:
880: sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
881: break;
882: case IPSP_AUTH_RSA:
883: sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
884: break;
885: }
886: *p += sizeof(struct sadb_x_cred);
887: bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
888: *p += PADUP((*ipr)->ref_len);
889: }
890:
891: void
892: export_identity(void **p, struct tdb *tdb, int type)
893: {
894: struct ipsec_ref **ipr;
895: struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
896:
897: if (type == PFKEYV2_IDENTITY_SRC)
898: ipr = &tdb->tdb_srcid;
899: else
900: ipr = &tdb->tdb_dstid;
901:
902: sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
903: PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
904:
905: switch ((*ipr)->ref_type) {
906: case IPSP_IDENTITY_PREFIX:
907: sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
908: break;
909: case IPSP_IDENTITY_FQDN:
910: sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
911: break;
912: case IPSP_IDENTITY_USERFQDN:
913: sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
914: break;
915: case IPSP_IDENTITY_CONNECTION:
916: sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION;
917: break;
918: }
919: *p += sizeof(struct sadb_ident);
920: bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
921: *p += PADUP((*ipr)->ref_len);
922: }
923:
924: /* ... */
925: void
926: import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
927: {
928: if (!sadb_key)
929: return;
930:
931: if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
932: ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
933: ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
934: } else {
935: ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
936: ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
937: }
938: }
939:
940: void
941: export_key(void **p, struct tdb *tdb, int type)
942: {
943: struct sadb_key *sadb_key = (struct sadb_key *) *p;
944:
945: if (type == PFKEYV2_ENCRYPTION_KEY) {
946: sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
947: PADUP(tdb->tdb_emxkeylen)) /
948: sizeof(uint64_t);
949: sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
950: *p += sizeof(struct sadb_key);
951: bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
952: *p += PADUP(tdb->tdb_emxkeylen);
953: } else {
954: sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
955: PADUP(tdb->tdb_amxkeylen)) /
956: sizeof(uint64_t);
957: sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
958: *p += sizeof(struct sadb_key);
959: bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
960: *p += PADUP(tdb->tdb_amxkeylen);
961: }
962: }
963:
964: /* Import/Export remote port for UDP Encapsulation */
965: void
966: import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
967: {
968: if (sadb_udpencap)
969: tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
970: }
971:
972: void
973: export_udpencap(void **p, struct tdb *tdb)
974: {
975: struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
976:
977: sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
978: sadb_udpencap->sadb_x_udpencap_reserved = 0;
979: sadb_udpencap->sadb_x_udpencap_len =
980: sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
981: *p += sizeof(struct sadb_x_udpencap);
982: }
983:
984: #if NPF > 0
985: /* Import PF tag information for SA */
986: void
987: import_tag(struct tdb *tdb, struct sadb_x_tag *stag)
988: {
989: char *s;
990:
991: if (stag) {
992: s = (char *)(stag + 1);
993: tdb->tdb_tag = pf_tagname2tag(s);
994: }
995: }
996:
997: /* Export PF tag information for SA */
998: void
999: export_tag(void **p, struct tdb *tdb)
1000: {
1001: struct sadb_x_tag *stag = (struct sadb_x_tag *)*p;
1002: char *s = (char *)(stag + 1);
1003:
1004: pf_tag2tagname(tdb->tdb_tag, s);
1005: stag->sadb_x_tag_taglen = strlen(s) + 1;
1006: stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) +
1007: PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
1008: *p += PADUP(stag->sadb_x_tag_taglen) + sizeof(struct sadb_x_tag);
1009: }
1010: #endif
CVSweb