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