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