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