xref: /openbsd-src/sys/net/pfkeyv2_convert.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: pfkeyv2_convert.c,v 1.57 2015/12/09 21:41:50 naddy 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 <sys/timeout.h>
103 #include <net/route.h>
104 #include <net/if.h>
105 
106 #include <netinet/in.h>
107 #include <netinet/ip_ipsp.h>
108 #include <net/pfkeyv2.h>
109 #include <crypto/cryptodev.h>
110 #include <crypto/xform.h>
111 
112 #if NPF > 0
113 #include <net/pfvar.h>
114 #endif
115 
116 /*
117  * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
118  * of the TDB will be initialized by other import routines, and tdb_init().
119  */
120 void
121 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
122 {
123 	if (!sadb_sa)
124 		return;
125 
126 	if (ii) {
127 		ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
128 		ii->ii_authalg = sadb_sa->sadb_sa_auth;
129 		ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
130 
131 		tdb->tdb_spi = sadb_sa->sadb_sa_spi;
132 		tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
133 
134 		if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
135 			tdb->tdb_flags |= TDBF_PFS;
136 
137 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
138 			tdb->tdb_flags |= TDBF_TUNNELING;
139 
140 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
141 			tdb->tdb_flags |= TDBF_UDPENCAP;
142 
143 		if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_ESN)
144 			tdb->tdb_flags |= TDBF_ESN;
145 	}
146 
147 	if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
148 		tdb->tdb_flags |= TDBF_INVALID;
149 }
150 
151 /*
152  * Export some of the information on a TDB.
153  */
154 void
155 export_sa(void **p, struct tdb *tdb)
156 {
157 	struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
158 
159 	sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
160 
161 	sadb_sa->sadb_sa_spi = tdb->tdb_spi;
162 	sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
163 
164 	if (tdb->tdb_flags & TDBF_INVALID)
165 		sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
166 	else
167 		sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE;
168 
169 	if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
170 	    tdb->tdb_compalgxform != NULL) {
171 		switch (tdb->tdb_compalgxform->type) {
172 		case CRYPTO_DEFLATE_COMP:
173 			sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
174 			break;
175 		case CRYPTO_LZS_COMP:
176 			sadb_sa->sadb_sa_encrypt = SADB_X_CALG_LZS;
177 			break;
178 		}
179 	}
180 
181 	if (tdb->tdb_authalgxform) {
182 		switch (tdb->tdb_authalgxform->type) {
183 		case CRYPTO_MD5_HMAC:
184 			sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
185 			break;
186 
187 		case CRYPTO_SHA1_HMAC:
188 			sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
189 			break;
190 
191 		case CRYPTO_RIPEMD160_HMAC:
192 			sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
193 			break;
194 
195 		case CRYPTO_SHA2_256_HMAC:
196 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
197 			break;
198 
199 		case CRYPTO_SHA2_384_HMAC:
200 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
201 			break;
202 
203 		case CRYPTO_SHA2_512_HMAC:
204 			sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
205 			break;
206 
207 		case CRYPTO_AES_128_GMAC:
208 			sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC;
209 			break;
210 
211 		case CRYPTO_AES_192_GMAC:
212 			sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC;
213 			break;
214 
215 		case CRYPTO_AES_256_GMAC:
216 			sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC;
217 			break;
218 
219 		case CRYPTO_CHACHA20_POLY1305_MAC:
220 			sadb_sa->sadb_sa_auth = SADB_X_AALG_CHACHA20POLY1305;
221 			break;
222 		}
223 	}
224 
225 	if (tdb->tdb_encalgxform) {
226 		switch (tdb->tdb_encalgxform->type) {
227 		case CRYPTO_NULL:
228 			sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL;
229 			break;
230 
231 		case CRYPTO_3DES_CBC:
232 			sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
233 			break;
234 
235 		case CRYPTO_AES_CBC:
236 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
237 			break;
238 
239 		case CRYPTO_AES_CTR:
240 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
241 			break;
242 
243 		case CRYPTO_AES_GCM_16:
244 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
245 			break;
246 
247 		case CRYPTO_AES_GMAC:
248 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC;
249 			break;
250 
251 		case CRYPTO_CAST_CBC:
252 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
253 			break;
254 
255 		case CRYPTO_BLF_CBC:
256 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
257 			break;
258 
259 		case CRYPTO_CHACHA20_POLY1305:
260 			sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CHACHA20POLY1305;
261 			break;
262 		}
263 	}
264 
265 	if (tdb->tdb_flags & TDBF_PFS)
266 		sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
267 
268 	if (tdb->tdb_flags & TDBF_TUNNELING)
269 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
270 
271 	if (tdb->tdb_flags & TDBF_UDPENCAP)
272 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP;
273 
274 	if (tdb->tdb_flags & TDBF_ESN)
275 		sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_ESN;
276 
277 	*p += sizeof(struct sadb_sa);
278 }
279 
280 /*
281  * Initialize expirations and counters based on lifetime payload.
282  */
283 void
284 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
285 {
286 	if (!sadb_lifetime)
287 		return;
288 
289 	switch (type) {
290 	case PFKEYV2_LIFETIME_HARD:
291 		if ((tdb->tdb_exp_allocations =
292 		    sadb_lifetime->sadb_lifetime_allocations) != 0)
293 			tdb->tdb_flags |= TDBF_ALLOCATIONS;
294 		else
295 			tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
296 
297 		if ((tdb->tdb_exp_bytes =
298 		    sadb_lifetime->sadb_lifetime_bytes) != 0)
299 			tdb->tdb_flags |= TDBF_BYTES;
300 		else
301 			tdb->tdb_flags &= ~TDBF_BYTES;
302 
303 		if ((tdb->tdb_exp_timeout =
304 		    sadb_lifetime->sadb_lifetime_addtime) != 0) {
305 			tdb->tdb_flags |= TDBF_TIMER;
306 			timeout_add_sec(&tdb->tdb_timer_tmo,
307 			    tdb->tdb_exp_timeout);
308 		} else
309 			tdb->tdb_flags &= ~TDBF_TIMER;
310 
311 		if ((tdb->tdb_exp_first_use =
312 		    sadb_lifetime->sadb_lifetime_usetime) != 0)
313 			tdb->tdb_flags |= TDBF_FIRSTUSE;
314 		else
315 			tdb->tdb_flags &= ~TDBF_FIRSTUSE;
316 		break;
317 
318 	case PFKEYV2_LIFETIME_SOFT:
319 		if ((tdb->tdb_soft_allocations =
320 		    sadb_lifetime->sadb_lifetime_allocations) != 0)
321 			tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
322 		else
323 			tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
324 
325 		if ((tdb->tdb_soft_bytes =
326 		    sadb_lifetime->sadb_lifetime_bytes) != 0)
327 			tdb->tdb_flags |= TDBF_SOFT_BYTES;
328 		else
329 			tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
330 
331 		if ((tdb->tdb_soft_timeout =
332 		    sadb_lifetime->sadb_lifetime_addtime) != 0) {
333 			tdb->tdb_flags |= TDBF_SOFT_TIMER;
334 			timeout_add_sec(&tdb->tdb_stimer_tmo,
335 			    tdb->tdb_soft_timeout);
336 		} else
337 			tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
338 
339 		if ((tdb->tdb_soft_first_use =
340 		    sadb_lifetime->sadb_lifetime_usetime) != 0)
341 			tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
342 		else
343 			tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
344 		break;
345 
346 	case PFKEYV2_LIFETIME_CURRENT:  /* Nothing fancy here. */
347 		tdb->tdb_cur_allocations =
348 		    sadb_lifetime->sadb_lifetime_allocations;
349 		tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
350 		tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
351 		tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
352 	}
353 }
354 
355 /*
356  * Export TDB expiration information.
357  */
358 void
359 export_lifetime(void **p, struct tdb *tdb, int type)
360 {
361 	struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
362 
363 	sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
364 	    sizeof(uint64_t);
365 
366 	switch (type) {
367 	case PFKEYV2_LIFETIME_HARD:
368 		if (tdb->tdb_flags & TDBF_ALLOCATIONS)
369 			sadb_lifetime->sadb_lifetime_allocations =
370 			    tdb->tdb_exp_allocations;
371 
372 		if (tdb->tdb_flags & TDBF_BYTES)
373 			sadb_lifetime->sadb_lifetime_bytes =
374 			    tdb->tdb_exp_bytes;
375 
376 		if (tdb->tdb_flags & TDBF_TIMER)
377 			sadb_lifetime->sadb_lifetime_addtime =
378 			    tdb->tdb_exp_timeout;
379 
380 		if (tdb->tdb_flags & TDBF_FIRSTUSE)
381 			sadb_lifetime->sadb_lifetime_usetime =
382 			    tdb->tdb_exp_first_use;
383 		break;
384 
385 	case PFKEYV2_LIFETIME_SOFT:
386 		if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
387 			sadb_lifetime->sadb_lifetime_allocations =
388 			    tdb->tdb_soft_allocations;
389 
390 		if (tdb->tdb_flags & TDBF_SOFT_BYTES)
391 			sadb_lifetime->sadb_lifetime_bytes =
392 			    tdb->tdb_soft_bytes;
393 
394 		if (tdb->tdb_flags & TDBF_SOFT_TIMER)
395 			sadb_lifetime->sadb_lifetime_addtime =
396 			    tdb->tdb_soft_timeout;
397 
398 		if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
399 			sadb_lifetime->sadb_lifetime_usetime =
400 			    tdb->tdb_soft_first_use;
401 		break;
402 
403 	case PFKEYV2_LIFETIME_CURRENT:
404 		sadb_lifetime->sadb_lifetime_allocations =
405 		    tdb->tdb_cur_allocations;
406 		sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
407 		sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
408 		sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
409 		break;
410 
411 	case PFKEYV2_LIFETIME_LASTUSE:
412 		sadb_lifetime->sadb_lifetime_allocations = 0;
413 		sadb_lifetime->sadb_lifetime_bytes = 0;
414 		sadb_lifetime->sadb_lifetime_addtime = 0;
415 		sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used;
416 		break;
417 	}
418 
419 	*p += sizeof(struct sadb_lifetime);
420 }
421 
422 /*
423  * Import flow information to two struct sockaddr_encap's. Either
424  * all or none of the address arguments are NULL.
425  */
426 void
427 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
428     struct sadb_address *ssrc, struct sadb_address *ssrcmask,
429     struct sadb_address *ddst, struct sadb_address *ddstmask,
430     struct sadb_protocol *sab, struct sadb_protocol *ftype)
431 {
432 	u_int8_t transproto = 0;
433 	union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1);
434 	union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1);
435 	union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1);
436 	union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1);
437 
438 	if (ssrc == NULL)
439 		return; /* There wasn't any information to begin with. */
440 
441 	bzero(flow, sizeof(*flow));
442 	bzero(flowmask, sizeof(*flowmask));
443 
444 	if (sab != NULL)
445 		transproto = sab->sadb_protocol_proto;
446 
447 	/*
448 	 * Check that all the address families match. We know they are
449 	 * valid and supported because pfkeyv2_parsemessage() checked that.
450 	 */
451 	if ((src->sa.sa_family != dst->sa.sa_family) ||
452 	    (src->sa.sa_family != srcmask->sa.sa_family) ||
453 	    (src->sa.sa_family != dstmask->sa.sa_family))
454 		return;
455 
456 	/*
457 	 * We set these as an indication that tdb_filter/tdb_filtermask are
458 	 * in fact initialized.
459 	 */
460 	flow->sen_family = flowmask->sen_family = PF_KEY;
461 	flow->sen_len = flowmask->sen_len = SENT_LEN;
462 
463 	switch (src->sa.sa_family) {
464 	case AF_INET:
465 		/* netmask handling */
466 		rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
467 		rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
468 
469 		flow->sen_type = SENT_IP4;
470 		flow->sen_direction = ftype->sadb_protocol_direction;
471 		flow->sen_ip_src = src->sin.sin_addr;
472 		flow->sen_ip_dst = dst->sin.sin_addr;
473 		flow->sen_proto = transproto;
474 		flow->sen_sport = src->sin.sin_port;
475 		flow->sen_dport = dst->sin.sin_port;
476 
477 		flowmask->sen_type = SENT_IP4;
478 		flowmask->sen_direction = 0xff;
479 		flowmask->sen_ip_src = srcmask->sin.sin_addr;
480 		flowmask->sen_ip_dst = dstmask->sin.sin_addr;
481 		flowmask->sen_sport = srcmask->sin.sin_port;
482 		flowmask->sen_dport = dstmask->sin.sin_port;
483 		if (transproto)
484 			flowmask->sen_proto = 0xff;
485 		break;
486 
487 #ifdef INET6
488 	case AF_INET6:
489 		in6_embedscope(&src->sin6.sin6_addr, &src->sin6,
490 		    NULL);
491 		in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6,
492 		    NULL);
493 
494 		/* netmask handling */
495 		rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
496 		rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
497 
498 		flow->sen_type = SENT_IP6;
499 		flow->sen_ip6_direction = ftype->sadb_protocol_direction;
500 		flow->sen_ip6_src = src->sin6.sin6_addr;
501 		flow->sen_ip6_dst = dst->sin6.sin6_addr;
502 		flow->sen_ip6_proto = transproto;
503 		flow->sen_ip6_sport = src->sin6.sin6_port;
504 		flow->sen_ip6_dport = dst->sin6.sin6_port;
505 
506 		flowmask->sen_type = SENT_IP6;
507 		flowmask->sen_ip6_direction = 0xff;
508 		flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
509 		flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
510 		flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
511 		flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
512 		if (transproto)
513 			flowmask->sen_ip6_proto = 0xff;
514 		break;
515 #endif /* INET6 */
516 	}
517 }
518 
519 /*
520  * Helper to export addresses from an struct sockaddr_encap.
521  */
522 static void
523 export_encap(void **p, struct sockaddr_encap *encap, int type)
524 {
525 	struct sadb_address *saddr = (struct sadb_address *)*p;
526 	union sockaddr_union *sunion;
527 
528 	*p += sizeof(struct sadb_address);
529 	sunion = (union sockaddr_union *)*p;
530 
531 	switch (encap->sen_type) {
532 	case SENT_IP4:
533 		saddr->sadb_address_len = (sizeof(struct sadb_address) +
534 		    PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
535 		sunion->sa.sa_len = sizeof(struct sockaddr_in);
536 		sunion->sa.sa_family = AF_INET;
537 		if (type == SADB_X_EXT_SRC_FLOW ||
538 		    type == SADB_X_EXT_SRC_MASK) {
539 			sunion->sin.sin_addr = encap->sen_ip_src;
540 			sunion->sin.sin_port = encap->sen_sport;
541 		} else {
542 			sunion->sin.sin_addr = encap->sen_ip_dst;
543 			sunion->sin.sin_port = encap->sen_dport;
544 		}
545 		*p += PADUP(sizeof(struct sockaddr_in));
546 		break;
547         case SENT_IP6:
548 		saddr->sadb_address_len = (sizeof(struct sadb_address)
549 		    + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
550 		sunion->sa.sa_len = sizeof(struct sockaddr_in6);
551 		sunion->sa.sa_family = AF_INET6;
552 		if (type == SADB_X_EXT_SRC_FLOW ||
553 		    type == SADB_X_EXT_SRC_MASK) {
554 			sunion->sin6.sin6_addr = encap->sen_ip6_src;
555 			sunion->sin6.sin6_port = encap->sen_ip6_sport;
556 		} else {
557 			sunion->sin6.sin6_addr = encap->sen_ip6_dst;
558 			sunion->sin6.sin6_port = encap->sen_ip6_dport;
559 		}
560 		*p += PADUP(sizeof(struct sockaddr_in6));
561 		break;
562 	}
563 }
564 
565 /*
566  * Export flow information from two struct sockaddr_encap's.
567  */
568 void
569 export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
570     struct sockaddr_encap *flowmask, void **headers)
571 {
572 	struct sadb_protocol *sab;
573 
574 	headers[SADB_X_EXT_FLOW_TYPE] = *p;
575 	sab = (struct sadb_protocol *)*p;
576 	sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
577 	    sizeof(uint64_t);
578 
579 	switch (ftype) {
580 	case IPSP_IPSEC_USE:
581 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
582 		break;
583 	case IPSP_IPSEC_ACQUIRE:
584 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
585 		break;
586 	case IPSP_IPSEC_REQUIRE:
587 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
588 		break;
589 	case IPSP_DENY:
590 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
591 		break;
592 	case IPSP_PERMIT:
593 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
594 		break;
595 	case IPSP_IPSEC_DONTACQ:
596 		sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
597 		break;
598 	default:
599 		sab->sadb_protocol_proto = 0;
600 		break;
601 	}
602 
603 	switch (flow->sen_type) {
604 	case SENT_IP4:
605 		sab->sadb_protocol_direction = flow->sen_direction;
606 		break;
607 #ifdef INET6
608 	case SENT_IP6:
609 		sab->sadb_protocol_direction = flow->sen_ip6_direction;
610 		break;
611 #endif /* INET6 */
612 	}
613 	*p += sizeof(struct sadb_protocol);
614 
615 	headers[SADB_X_EXT_PROTOCOL] = *p;
616 	sab = (struct sadb_protocol *)*p;
617 	sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
618 	    sizeof(uint64_t);
619 	switch (flow->sen_type) {
620 	case SENT_IP4:
621 		sab->sadb_protocol_proto = flow->sen_proto;
622 		break;
623 #ifdef INET6
624 	case SENT_IP6:
625 		sab->sadb_protocol_proto = flow->sen_ip6_proto;
626 		break;
627 #endif /* INET6 */
628 	}
629 	*p += sizeof(struct sadb_protocol);
630 
631 	headers[SADB_X_EXT_SRC_FLOW] = *p;
632 	export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
633 
634 	headers[SADB_X_EXT_SRC_MASK] = *p;
635 	export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
636 
637 	headers[SADB_X_EXT_DST_FLOW] = *p;
638 	export_encap(p, flow, SADB_X_EXT_DST_FLOW);
639 
640 	headers[SADB_X_EXT_DST_MASK] = *p;
641 	export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
642 }
643 
644 /*
645  * Copy an SADB_ADDRESS payload to a struct sockaddr.
646  */
647 void
648 import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
649 {
650 	int salen;
651 	struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
652 	    sizeof(struct sadb_address));
653 
654 	if (!sadb_address)
655 		return;
656 
657 	if (ssa->sa_len)
658 		salen = ssa->sa_len;
659 	else
660 		switch (ssa->sa_family) {
661 		case AF_INET:
662 			salen = sizeof(struct sockaddr_in);
663 			break;
664 
665 #ifdef INET6
666 		case AF_INET6:
667 			salen = sizeof(struct sockaddr_in6);
668 			break;
669 #endif /* INET6 */
670 
671 		default:
672 			return;
673 		}
674 
675 	bcopy(ssa, sa, salen);
676 	sa->sa_len = salen;
677 }
678 
679 /*
680  * Export a struct sockaddr as an SADB_ADDRESS payload.
681  */
682 void
683 export_address(void **p, struct sockaddr *sa)
684 {
685 	struct sadb_address *sadb_address = (struct sadb_address *) *p;
686 
687 	sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
688 	    PADUP(SA_LEN(sa))) / sizeof(uint64_t);
689 
690 	*p += sizeof(struct sadb_address);
691 	bcopy(sa, *p, SA_LEN(sa));
692 	((struct sockaddr *) *p)->sa_family = sa->sa_family;
693 	*p += PADUP(SA_LEN(sa));
694 }
695 
696 /*
697  * Import an identity payload into the TDB.
698  */
699 static void
700 import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident)
701 {
702 	if (!sadb_ident) {
703 		*id = NULL;
704 		return;
705 	}
706 
707 	*id = malloc(EXTLEN(sadb_ident) - sizeof(struct sadb_ident) +
708 	    sizeof(struct ipsec_id), M_CREDENTIALS, M_WAITOK);
709 	(*id)->len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
710 
711 	switch (sadb_ident->sadb_ident_type) {
712 	case SADB_IDENTTYPE_PREFIX:
713 		(*id)->type = IPSP_IDENTITY_PREFIX;
714 		break;
715 	case SADB_IDENTTYPE_FQDN:
716 		(*id)->type = IPSP_IDENTITY_FQDN;
717 		break;
718 	case SADB_IDENTTYPE_USERFQDN:
719 		(*id)->type = IPSP_IDENTITY_USERFQDN;
720 		break;
721 	default:
722 		free(*id, M_CREDENTIALS, 0);
723 		*id = NULL;
724 		return;
725 	}
726 	bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1,
727 	    (*id)->len);
728 }
729 
730 void
731 import_identities(struct ipsec_ids **ids, int swapped,
732     struct sadb_ident *srcid, struct sadb_ident *dstid)
733 {
734 	struct ipsec_ids *tmp;
735 
736 	*ids = NULL;
737 	tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS, M_WAITOK);
738 	import_identity(&tmp->id_local, swapped ? dstid: srcid);
739 	import_identity(&tmp->id_remote, swapped ? srcid: dstid);
740 	if (tmp->id_local != NULL && tmp->id_remote != NULL) {
741 		*ids = ipsp_ids_insert(tmp);
742 		if (*ids == tmp)
743 			return;
744 	}
745 	free(tmp->id_local, M_CREDENTIALS, 0);
746 	free(tmp->id_remote, M_CREDENTIALS, 0);
747 	free(tmp, M_CREDENTIALS, 0);
748 }
749 
750 static void
751 export_identity(void **p, struct ipsec_id *id)
752 {
753 	struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
754 
755 	sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
756 	    PADUP(id->len)) / sizeof(uint64_t);
757 
758 	switch (id->type) {
759 	case IPSP_IDENTITY_PREFIX:
760 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
761 		break;
762 	case IPSP_IDENTITY_FQDN:
763 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
764 		break;
765 	case IPSP_IDENTITY_USERFQDN:
766 		sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
767 		break;
768 	}
769 	*p += sizeof(struct sadb_ident);
770 	bcopy(id + 1, *p, id->len);
771 	*p += PADUP(id->len);
772 }
773 
774 void
775 export_identities(void **p, struct ipsec_ids *ids, int swapped,
776     void **headers)
777 {
778 	headers[SADB_EXT_IDENTITY_SRC] = *p;
779 	export_identity(p, swapped ? ids->id_remote : ids->id_local);
780 	headers[SADB_EXT_IDENTITY_DST] = *p;
781 	export_identity(p, swapped ? ids->id_local : ids->id_remote);
782 }
783 
784 /* ... */
785 void
786 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
787 {
788 	if (!sadb_key)
789 		return;
790 
791 	if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
792 		ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
793 		ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
794 	} else {
795 		ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
796 		ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
797 	}
798 }
799 
800 void
801 export_key(void **p, struct tdb *tdb, int type)
802 {
803 	struct sadb_key *sadb_key = (struct sadb_key *) *p;
804 
805 	if (type == PFKEYV2_ENCRYPTION_KEY) {
806 		sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
807 		    PADUP(tdb->tdb_emxkeylen)) /
808 		    sizeof(uint64_t);
809 		sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
810 		*p += sizeof(struct sadb_key);
811 		bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
812 		*p += PADUP(tdb->tdb_emxkeylen);
813 	} else {
814 		sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
815 		    PADUP(tdb->tdb_amxkeylen)) /
816 		    sizeof(uint64_t);
817 		sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
818 		*p += sizeof(struct sadb_key);
819 		bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
820 		*p += PADUP(tdb->tdb_amxkeylen);
821 	}
822 }
823 
824 /* Import/Export remote port for UDP Encapsulation */
825 void
826 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
827 {
828 	if (sadb_udpencap)
829 		tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
830 }
831 
832 void
833 export_udpencap(void **p, struct tdb *tdb)
834 {
835 	struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
836 
837 	sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
838 	sadb_udpencap->sadb_x_udpencap_reserved = 0;
839 	sadb_udpencap->sadb_x_udpencap_len =
840 	    sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
841 	*p += sizeof(struct sadb_x_udpencap);
842 }
843 
844 #if NPF > 0
845 /* Import PF tag information for SA */
846 void
847 import_tag(struct tdb *tdb, struct sadb_x_tag *stag)
848 {
849 	char *s;
850 
851 	if (stag) {
852 		s = (char *)(stag + 1);
853 		tdb->tdb_tag = pf_tagname2tag(s, 1);
854 	}
855 }
856 
857 /* Export PF tag information for SA */
858 void
859 export_tag(void **p, struct tdb *tdb)
860 {
861 	struct sadb_x_tag *stag = (struct sadb_x_tag *)*p;
862 	char *s = (char *)(stag + 1);
863 
864 	pf_tag2tagname(tdb->tdb_tag, s);
865 
866 	stag->sadb_x_tag_taglen = strlen(s) + 1;
867 	stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) +
868 	    PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
869 	*p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen);
870 }
871 
872 /* Import enc(4) tap device information for SA */
873 void
874 import_tap(struct tdb *tdb, struct sadb_x_tap *stap)
875 {
876 	if (stap)
877 		tdb->tdb_tap = stap->sadb_x_tap_unit;
878 }
879 
880 /* Export enc(4) tap device information for SA */
881 void
882 export_tap(void **p, struct tdb *tdb)
883 {
884 	struct sadb_x_tap *stag = (struct sadb_x_tap *)*p;
885 
886 	stag->sadb_x_tap_unit = tdb->tdb_tap;
887 	stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t);
888 	*p += sizeof(struct sadb_x_tap);
889 }
890 #endif
891