File: | net/pfkeyv2_convert.c |
Warning: | line 752, column 2 3rd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: pfkeyv2_convert.c,v 1.83 2023/11/28 13:23:20 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 NPF1 > 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_PFS0x001) | |||
135 | tdb->tdb_flags |= TDBF_PFS0x00800; | |||
136 | ||||
137 | if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL0x004) | |||
138 | tdb->tdb_flags |= TDBF_TUNNELING0x01000; | |||
139 | ||||
140 | if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP0x200) | |||
141 | tdb->tdb_flags |= TDBF_UDPENCAP0x20000; | |||
142 | ||||
143 | if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_ESN0x400) | |||
144 | tdb->tdb_flags |= TDBF_ESN0x100000; | |||
145 | } | |||
146 | ||||
147 | if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE1) | |||
148 | tdb->tdb_flags |= TDBF_INVALID0x00010; | |||
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_INVALID0x00010) | |||
166 | sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL0; | |||
167 | else | |||
168 | sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE1; | |||
169 | ||||
170 | if (tdb->tdb_sproto == IPPROTO_IPCOMP108 && | |||
171 | tdb->tdb_compalgxform != NULL((void *)0)) { | |||
172 | switch (tdb->tdb_compalgxform->type) { | |||
173 | case CRYPTO_DEFLATE_COMP8: | |||
174 | sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE2; | |||
175 | break; | |||
176 | } | |||
177 | } | |||
178 | ||||
179 | if (tdb->tdb_authalgxform) { | |||
180 | switch (tdb->tdb_authalgxform->type) { | |||
181 | case CRYPTO_MD5_HMAC4: | |||
182 | sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC2; | |||
183 | break; | |||
184 | ||||
185 | case CRYPTO_SHA1_HMAC5: | |||
186 | sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC3; | |||
187 | break; | |||
188 | ||||
189 | case CRYPTO_RIPEMD160_HMAC6: | |||
190 | sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC8; | |||
191 | break; | |||
192 | ||||
193 | case CRYPTO_SHA2_256_HMAC11: | |||
194 | sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_2565; | |||
195 | break; | |||
196 | ||||
197 | case CRYPTO_SHA2_384_HMAC12: | |||
198 | sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_3846; | |||
199 | break; | |||
200 | ||||
201 | case CRYPTO_SHA2_512_HMAC13: | |||
202 | sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_5127; | |||
203 | break; | |||
204 | ||||
205 | case CRYPTO_AES_128_GMAC17: | |||
206 | sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC9; | |||
207 | break; | |||
208 | ||||
209 | case CRYPTO_AES_192_GMAC18: | |||
210 | sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC10; | |||
211 | break; | |||
212 | ||||
213 | case CRYPTO_AES_256_GMAC19: | |||
214 | sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC11; | |||
215 | break; | |||
216 | ||||
217 | case CRYPTO_CHACHA20_POLY1305_MAC22: | |||
218 | sadb_sa->sadb_sa_auth = SADB_X_AALG_CHACHA20POLY130512; | |||
219 | break; | |||
220 | } | |||
221 | } | |||
222 | ||||
223 | if (tdb->tdb_encalgxform) { | |||
224 | switch (tdb->tdb_encalgxform->type) { | |||
225 | case CRYPTO_NULL9: | |||
226 | sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL11; | |||
227 | break; | |||
228 | ||||
229 | case CRYPTO_3DES_CBC1: | |||
230 | sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC3; | |||
231 | break; | |||
232 | ||||
233 | case CRYPTO_AES_CBC7: | |||
234 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES12; | |||
235 | break; | |||
236 | ||||
237 | case CRYPTO_AES_CTR14: | |||
238 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR13; | |||
239 | break; | |||
240 | ||||
241 | case CRYPTO_AES_GCM_1616: | |||
242 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM1620; | |||
243 | break; | |||
244 | ||||
245 | case CRYPTO_AES_GMAC20: | |||
246 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC21; | |||
247 | break; | |||
248 | ||||
249 | case CRYPTO_CAST_CBC3: | |||
250 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST6; | |||
251 | break; | |||
252 | ||||
253 | case CRYPTO_BLF_CBC2: | |||
254 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF7; | |||
255 | break; | |||
256 | ||||
257 | case CRYPTO_CHACHA20_POLY130521: | |||
258 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CHACHA20POLY130522; | |||
259 | break; | |||
260 | } | |||
261 | } | |||
262 | ||||
263 | if (tdb->tdb_flags & TDBF_PFS0x00800) | |||
264 | sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS0x001; | |||
265 | ||||
266 | if (tdb->tdb_flags & TDBF_TUNNELING0x01000) | |||
267 | sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL0x004; | |||
268 | ||||
269 | if (tdb->tdb_flags & TDBF_UDPENCAP0x20000) | |||
270 | sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP0x200; | |||
271 | ||||
272 | if (tdb->tdb_flags & TDBF_ESN0x100000) | |||
273 | sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_ESN0x400; | |||
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_HARD0: | |||
290 | if ((tdb->tdb_exp_allocations = | |||
291 | sadb_lifetime->sadb_lifetime_allocations) != 0) | |||
292 | tdb->tdb_flags |= TDBF_ALLOCATIONS0x00008; | |||
293 | else | |||
294 | tdb->tdb_flags &= ~TDBF_ALLOCATIONS0x00008; | |||
295 | ||||
296 | if ((tdb->tdb_exp_bytes = | |||
297 | sadb_lifetime->sadb_lifetime_bytes) != 0) | |||
298 | tdb->tdb_flags |= TDBF_BYTES0x00004; | |||
299 | else | |||
300 | tdb->tdb_flags &= ~TDBF_BYTES0x00004; | |||
301 | ||||
302 | if ((tdb->tdb_exp_timeout = | |||
303 | sadb_lifetime->sadb_lifetime_addtime) != 0) { | |||
304 | tdb->tdb_flags |= TDBF_TIMER0x00002; | |||
305 | } else | |||
306 | tdb->tdb_flags &= ~TDBF_TIMER0x00002; | |||
307 | ||||
308 | if ((tdb->tdb_exp_first_use = | |||
309 | sadb_lifetime->sadb_lifetime_usetime) != 0) | |||
310 | tdb->tdb_flags |= TDBF_FIRSTUSE0x00020; | |||
311 | else | |||
312 | tdb->tdb_flags &= ~TDBF_FIRSTUSE0x00020; | |||
313 | break; | |||
314 | ||||
315 | case PFKEYV2_LIFETIME_SOFT1: | |||
316 | if ((tdb->tdb_soft_allocations = | |||
317 | sadb_lifetime->sadb_lifetime_allocations) != 0) | |||
318 | tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS0x00200; | |||
319 | else | |||
320 | tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS0x00200; | |||
321 | ||||
322 | if ((tdb->tdb_soft_bytes = | |||
323 | sadb_lifetime->sadb_lifetime_bytes) != 0) | |||
324 | tdb->tdb_flags |= TDBF_SOFT_BYTES0x00100; | |||
325 | else | |||
326 | tdb->tdb_flags &= ~TDBF_SOFT_BYTES0x00100; | |||
327 | ||||
328 | if ((tdb->tdb_soft_timeout = | |||
329 | sadb_lifetime->sadb_lifetime_addtime) != 0) { | |||
330 | tdb->tdb_flags |= TDBF_SOFT_TIMER0x00080; | |||
331 | } else | |||
332 | tdb->tdb_flags &= ~TDBF_SOFT_TIMER0x00080; | |||
333 | ||||
334 | if ((tdb->tdb_soft_first_use = | |||
335 | sadb_lifetime->sadb_lifetime_usetime) != 0) | |||
336 | tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE0x00400; | |||
337 | else | |||
338 | tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE0x00400; | |||
339 | break; | |||
340 | ||||
341 | case PFKEYV2_LIFETIME_CURRENT2: /* Nothing fancy here. */ | |||
342 | tdb->tdb_cur_allocations = | |||
343 | sadb_lifetime->sadb_lifetime_allocations; | |||
344 | tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes; | |||
345 | tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; | |||
346 | tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; | |||
347 | } | |||
348 | mtx_leave(&tdb->tdb_mtx); | |||
349 | } | |||
350 | ||||
351 | /* | |||
352 | * Export TDB expiration information. | |||
353 | */ | |||
354 | void | |||
355 | export_lifetime(void **p, struct tdb *tdb, int type) | |||
356 | { | |||
357 | struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p; | |||
358 | ||||
359 | sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / | |||
360 | sizeof(uint64_t); | |||
361 | ||||
362 | switch (type) { | |||
363 | case PFKEYV2_LIFETIME_HARD0: | |||
364 | if (tdb->tdb_flags & TDBF_ALLOCATIONS0x00008) | |||
365 | sadb_lifetime->sadb_lifetime_allocations = | |||
366 | tdb->tdb_exp_allocations; | |||
367 | ||||
368 | if (tdb->tdb_flags & TDBF_BYTES0x00004) | |||
369 | sadb_lifetime->sadb_lifetime_bytes = | |||
370 | tdb->tdb_exp_bytes; | |||
371 | ||||
372 | if (tdb->tdb_flags & TDBF_TIMER0x00002) | |||
373 | sadb_lifetime->sadb_lifetime_addtime = | |||
374 | tdb->tdb_exp_timeout; | |||
375 | ||||
376 | if (tdb->tdb_flags & TDBF_FIRSTUSE0x00020) | |||
377 | sadb_lifetime->sadb_lifetime_usetime = | |||
378 | tdb->tdb_exp_first_use; | |||
379 | break; | |||
380 | ||||
381 | case PFKEYV2_LIFETIME_SOFT1: | |||
382 | if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS0x00200) | |||
383 | sadb_lifetime->sadb_lifetime_allocations = | |||
384 | tdb->tdb_soft_allocations; | |||
385 | ||||
386 | if (tdb->tdb_flags & TDBF_SOFT_BYTES0x00100) | |||
387 | sadb_lifetime->sadb_lifetime_bytes = | |||
388 | tdb->tdb_soft_bytes; | |||
389 | ||||
390 | if (tdb->tdb_flags & TDBF_SOFT_TIMER0x00080) | |||
391 | sadb_lifetime->sadb_lifetime_addtime = | |||
392 | tdb->tdb_soft_timeout; | |||
393 | ||||
394 | if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE0x00400) | |||
395 | sadb_lifetime->sadb_lifetime_usetime = | |||
396 | tdb->tdb_soft_first_use; | |||
397 | break; | |||
398 | ||||
399 | case PFKEYV2_LIFETIME_CURRENT2: | |||
400 | sadb_lifetime->sadb_lifetime_allocations = | |||
401 | tdb->tdb_cur_allocations; | |||
402 | sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes; | |||
403 | sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established; | |||
404 | sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use; | |||
405 | break; | |||
406 | ||||
407 | case PFKEYV2_LIFETIME_LASTUSE3: | |||
408 | sadb_lifetime->sadb_lifetime_allocations = 0; | |||
409 | sadb_lifetime->sadb_lifetime_bytes = 0; | |||
410 | sadb_lifetime->sadb_lifetime_addtime = 0; | |||
411 | sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used; | |||
412 | break; | |||
413 | } | |||
414 | ||||
415 | *p += sizeof(struct sadb_lifetime); | |||
416 | } | |||
417 | ||||
418 | /* | |||
419 | * Import flow information to two struct sockaddr_encap's. Either | |||
420 | * all or none of the address arguments are NULL. | |||
421 | */ | |||
422 | int | |||
423 | import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask, | |||
424 | struct sadb_address *ssrc, struct sadb_address *ssrcmask, | |||
425 | struct sadb_address *ddst, struct sadb_address *ddstmask, | |||
426 | struct sadb_protocol *sab, struct sadb_protocol *ftype) | |||
427 | { | |||
428 | u_int8_t transproto = 0; | |||
429 | union sockaddr_union *src, *dst, *srcmask, *dstmask; | |||
430 | ||||
431 | if (ssrc == NULL((void *)0)) | |||
432 | return 0; /* There wasn't any information to begin with. */ | |||
433 | ||||
434 | src = (union sockaddr_union *)(ssrc + 1); | |||
435 | dst = (union sockaddr_union *)(ddst + 1); | |||
436 | srcmask = (union sockaddr_union *)(ssrcmask + 1); | |||
437 | dstmask = (union sockaddr_union *)(ddstmask + 1); | |||
438 | ||||
439 | bzero(flow, sizeof(*flow))__builtin_bzero((flow), (sizeof(*flow))); | |||
440 | bzero(flowmask, sizeof(*flowmask))__builtin_bzero((flowmask), (sizeof(*flowmask))); | |||
441 | ||||
442 | if (sab != NULL((void *)0)) | |||
443 | transproto = sab->sadb_protocol_proto; | |||
444 | ||||
445 | /* | |||
446 | * Check that all the address families match. We know they are | |||
447 | * valid and supported because pfkeyv2_parsemessage() checked that. | |||
448 | */ | |||
449 | if ((src->sa.sa_family != dst->sa.sa_family) || | |||
450 | (src->sa.sa_family != srcmask->sa.sa_family) || | |||
451 | (src->sa.sa_family != dstmask->sa.sa_family)) | |||
452 | return EINVAL22; | |||
453 | ||||
454 | /* | |||
455 | * We set these as an indication that tdb_filter/tdb_filtermask are | |||
456 | * in fact initialized. | |||
457 | */ | |||
458 | flow->sen_family = flowmask->sen_family = PF_KEY30; | |||
459 | flow->sen_len = flowmask->sen_len = SENT_LENsizeof(struct sockaddr_encap); | |||
460 | ||||
461 | switch (src->sa.sa_family) { | |||
462 | case AF_INET2: | |||
463 | /* netmask handling */ | |||
464 | rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); | |||
465 | rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); | |||
466 | ||||
467 | flow->sen_type = SENT_IP40x0001; | |||
468 | flow->sen_directionSen.Sip4.Direction = ftype->sadb_protocol_direction; | |||
469 | flow->sen_ip_srcSen.Sip4.Src = src->sin.sin_addr; | |||
470 | flow->sen_ip_dstSen.Sip4.Dst = dst->sin.sin_addr; | |||
471 | flow->sen_protoSen.Sip4.Proto = transproto; | |||
472 | flow->sen_sportSen.Sip4.Sport = src->sin.sin_port; | |||
473 | flow->sen_dportSen.Sip4.Dport = dst->sin.sin_port; | |||
474 | ||||
475 | flowmask->sen_type = SENT_IP40x0001; | |||
476 | flowmask->sen_directionSen.Sip4.Direction = 0xff; | |||
477 | flowmask->sen_ip_srcSen.Sip4.Src = srcmask->sin.sin_addr; | |||
478 | flowmask->sen_ip_dstSen.Sip4.Dst = dstmask->sin.sin_addr; | |||
479 | flowmask->sen_sportSen.Sip4.Sport = srcmask->sin.sin_port; | |||
480 | flowmask->sen_dportSen.Sip4.Dport = dstmask->sin.sin_port; | |||
481 | if (transproto) | |||
482 | flowmask->sen_protoSen.Sip4.Proto = 0xff; | |||
483 | break; | |||
484 | ||||
485 | #ifdef INET61 | |||
486 | case AF_INET624: | |||
487 | in6_embedscope(&src->sin6.sin6_addr, &src->sin6, NULL((void *)0), NULL((void *)0)); | |||
488 | in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6, NULL((void *)0), NULL((void *)0)); | |||
489 | ||||
490 | /* netmask handling */ | |||
491 | rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); | |||
492 | rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); | |||
493 | ||||
494 | flow->sen_type = SENT_IP60x0002; | |||
495 | flow->sen_ip6_directionSen.Sip6.Direction = ftype->sadb_protocol_direction; | |||
496 | flow->sen_ip6_srcSen.Sip6.Src = src->sin6.sin6_addr; | |||
497 | flow->sen_ip6_dstSen.Sip6.Dst = dst->sin6.sin6_addr; | |||
498 | flow->sen_ip6_protoSen.Sip6.Proto = transproto; | |||
499 | flow->sen_ip6_sportSen.Sip6.Sport = src->sin6.sin6_port; | |||
500 | flow->sen_ip6_dportSen.Sip6.Dport = dst->sin6.sin6_port; | |||
501 | ||||
502 | flowmask->sen_type = SENT_IP60x0002; | |||
503 | flowmask->sen_ip6_directionSen.Sip6.Direction = 0xff; | |||
504 | flowmask->sen_ip6_srcSen.Sip6.Src = srcmask->sin6.sin6_addr; | |||
505 | flowmask->sen_ip6_dstSen.Sip6.Dst = dstmask->sin6.sin6_addr; | |||
506 | flowmask->sen_ip6_sportSen.Sip6.Sport = srcmask->sin6.sin6_port; | |||
507 | flowmask->sen_ip6_dportSen.Sip6.Dport = dstmask->sin6.sin6_port; | |||
508 | if (transproto) | |||
509 | flowmask->sen_ip6_protoSen.Sip6.Proto = 0xff; | |||
510 | break; | |||
511 | #endif /* INET6 */ | |||
512 | } | |||
513 | ||||
514 | return 0; | |||
515 | } | |||
516 | ||||
517 | /* | |||
518 | * Helper to export addresses from an struct sockaddr_encap. | |||
519 | */ | |||
520 | static void | |||
521 | export_encap(void **p, struct sockaddr_encap *encap, int type) | |||
522 | { | |||
523 | struct sadb_address *saddr = (struct sadb_address *)*p; | |||
524 | union sockaddr_union *sunion; | |||
525 | ||||
526 | *p += sizeof(struct sadb_address); | |||
527 | sunion = (union sockaddr_union *)*p; | |||
528 | ||||
529 | switch (encap->sen_type) { | |||
530 | case SENT_IP40x0001: | |||
531 | saddr->sadb_address_len = (sizeof(struct sadb_address) + | |||
532 | PADUP(sizeof(struct sockaddr_in))(((sizeof(struct sockaddr_in)) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1))) / sizeof(uint64_t); | |||
533 | sunion->sa.sa_len = sizeof(struct sockaddr_in); | |||
534 | sunion->sa.sa_family = AF_INET2; | |||
535 | if (type == SADB_X_EXT_SRC_FLOW21 || | |||
536 | type == SADB_X_EXT_SRC_MASK17) { | |||
537 | sunion->sin.sin_addr = encap->sen_ip_srcSen.Sip4.Src; | |||
538 | sunion->sin.sin_port = encap->sen_sportSen.Sip4.Sport; | |||
539 | } else { | |||
540 | sunion->sin.sin_addr = encap->sen_ip_dstSen.Sip4.Dst; | |||
541 | sunion->sin.sin_port = encap->sen_dportSen.Sip4.Dport; | |||
542 | } | |||
543 | *p += PADUP(sizeof(struct sockaddr_in))(((sizeof(struct sockaddr_in)) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1)); | |||
544 | break; | |||
545 | case SENT_IP60x0002: | |||
546 | saddr->sadb_address_len = (sizeof(struct sadb_address) | |||
547 | + PADUP(sizeof(struct sockaddr_in6))(((sizeof(struct sockaddr_in6)) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))) / sizeof(uint64_t); | |||
548 | sunion->sa.sa_len = sizeof(struct sockaddr_in6); | |||
549 | sunion->sa.sa_family = AF_INET624; | |||
550 | if (type == SADB_X_EXT_SRC_FLOW21 || | |||
551 | type == SADB_X_EXT_SRC_MASK17) { | |||
552 | sunion->sin6.sin6_addr = encap->sen_ip6_srcSen.Sip6.Src; | |||
553 | sunion->sin6.sin6_port = encap->sen_ip6_sportSen.Sip6.Sport; | |||
554 | } else { | |||
555 | sunion->sin6.sin6_addr = encap->sen_ip6_dstSen.Sip6.Dst; | |||
556 | sunion->sin6.sin6_port = encap->sen_ip6_dportSen.Sip6.Dport; | |||
557 | } | |||
558 | *p += PADUP(sizeof(struct sockaddr_in6))(((sizeof(struct sockaddr_in6)) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)); | |||
559 | break; | |||
560 | } | |||
561 | } | |||
562 | ||||
563 | /* | |||
564 | * Export flow information from two struct sockaddr_encap's. | |||
565 | */ | |||
566 | void | |||
567 | export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow, | |||
568 | struct sockaddr_encap *flowmask, void **headers) | |||
569 | { | |||
570 | struct sadb_protocol *sab; | |||
571 | ||||
572 | headers[SADB_X_EXT_FLOW_TYPE20] = *p; | |||
573 | sab = (struct sadb_protocol *)*p; | |||
574 | sab->sadb_protocol_len = sizeof(struct sadb_protocol) / | |||
575 | sizeof(uint64_t); | |||
576 | ||||
577 | switch (ftype) { | |||
578 | case IPSP_IPSEC_USE0: | |||
579 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE1; | |||
580 | break; | |||
581 | case IPSP_IPSEC_ACQUIRE1: | |||
582 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE2; | |||
583 | break; | |||
584 | case IPSP_IPSEC_REQUIRE2: | |||
585 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE3; | |||
586 | break; | |||
587 | case IPSP_DENY4: | |||
588 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY5; | |||
589 | break; | |||
590 | case IPSP_PERMIT3: | |||
591 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS4; | |||
592 | break; | |||
593 | case IPSP_IPSEC_DONTACQ5: | |||
594 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ6; | |||
595 | break; | |||
596 | default: | |||
597 | sab->sadb_protocol_proto = 0; | |||
598 | break; | |||
599 | } | |||
600 | ||||
601 | switch (flow->sen_type) { | |||
602 | case SENT_IP40x0001: | |||
603 | sab->sadb_protocol_direction = flow->sen_directionSen.Sip4.Direction; | |||
604 | break; | |||
605 | #ifdef INET61 | |||
606 | case SENT_IP60x0002: | |||
607 | sab->sadb_protocol_direction = flow->sen_ip6_directionSen.Sip6.Direction; | |||
608 | break; | |||
609 | #endif /* INET6 */ | |||
610 | } | |||
611 | *p += sizeof(struct sadb_protocol); | |||
612 | ||||
613 | headers[SADB_X_EXT_PROTOCOL19] = *p; | |||
614 | sab = (struct sadb_protocol *)*p; | |||
615 | sab->sadb_protocol_len = sizeof(struct sadb_protocol) / | |||
616 | sizeof(uint64_t); | |||
617 | switch (flow->sen_type) { | |||
618 | case SENT_IP40x0001: | |||
619 | sab->sadb_protocol_proto = flow->sen_protoSen.Sip4.Proto; | |||
620 | break; | |||
621 | #ifdef INET61 | |||
622 | case SENT_IP60x0002: | |||
623 | sab->sadb_protocol_proto = flow->sen_ip6_protoSen.Sip6.Proto; | |||
624 | break; | |||
625 | #endif /* INET6 */ | |||
626 | } | |||
627 | *p += sizeof(struct sadb_protocol); | |||
628 | ||||
629 | headers[SADB_X_EXT_SRC_FLOW21] = *p; | |||
630 | export_encap(p, flow, SADB_X_EXT_SRC_FLOW21); | |||
631 | ||||
632 | headers[SADB_X_EXT_SRC_MASK17] = *p; | |||
633 | export_encap(p, flowmask, SADB_X_EXT_SRC_MASK17); | |||
634 | ||||
635 | headers[SADB_X_EXT_DST_FLOW22] = *p; | |||
636 | export_encap(p, flow, SADB_X_EXT_DST_FLOW22); | |||
637 | ||||
638 | headers[SADB_X_EXT_DST_MASK18] = *p; | |||
639 | export_encap(p, flowmask, SADB_X_EXT_DST_MASK18); | |||
640 | } | |||
641 | ||||
642 | /* | |||
643 | * Copy an SADB_ADDRESS payload to a struct sockaddr. | |||
644 | */ | |||
645 | void | |||
646 | import_address(struct sockaddr *sa, struct sadb_address *sadb_address) | |||
647 | { | |||
648 | int salen; | |||
649 | struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address + | |||
650 | sizeof(struct sadb_address)); | |||
651 | ||||
652 | if (!sadb_address) | |||
653 | return; | |||
654 | ||||
655 | if (ssa->sa_len) | |||
656 | salen = ssa->sa_len; | |||
657 | else | |||
658 | switch (ssa->sa_family) { | |||
659 | case AF_INET2: | |||
660 | salen = sizeof(struct sockaddr_in); | |||
661 | break; | |||
662 | ||||
663 | #ifdef INET61 | |||
664 | case AF_INET624: | |||
665 | salen = sizeof(struct sockaddr_in6); | |||
666 | break; | |||
667 | #endif /* INET6 */ | |||
668 | ||||
669 | default: | |||
670 | return; | |||
671 | } | |||
672 | ||||
673 | bcopy(ssa, sa, salen); | |||
674 | sa->sa_len = salen; | |||
675 | } | |||
676 | ||||
677 | /* | |||
678 | * Export a struct sockaddr as an SADB_ADDRESS payload. | |||
679 | */ | |||
680 | void | |||
681 | export_address(void **p, struct sockaddr *sa) | |||
682 | { | |||
683 | struct sadb_address *sadb_address = (struct sadb_address *) *p; | |||
684 | ||||
685 | sadb_address->sadb_address_len = (sizeof(struct sadb_address) + | |||
686 | PADUP(sa->sa_len)(((sa->sa_len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1))) / sizeof(uint64_t); | |||
687 | ||||
688 | *p += sizeof(struct sadb_address); | |||
689 | bcopy(sa, *p, sa->sa_len); | |||
690 | ((struct sockaddr *) *p)->sa_family = sa->sa_family; | |||
691 | *p += PADUP(sa->sa_len)(((sa->sa_len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1)); | |||
692 | } | |||
693 | ||||
694 | /* | |||
695 | * Import an identity payload into the TDB. | |||
696 | */ | |||
697 | static void | |||
698 | import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident, | |||
699 | size_t *id_sz) | |||
700 | { | |||
701 | size_t id_len; | |||
702 | ||||
703 | if (!sadb_ident) { | |||
704 | *id = NULL((void *)0); | |||
705 | return; | |||
706 | } | |||
707 | ||||
708 | id_len = EXTLEN(sadb_ident)(((struct sadb_ext *)(sadb_ident))->sadb_ext_len * sizeof( uint64_t)) - sizeof(struct sadb_ident); | |||
709 | *id_sz = sizeof(struct ipsec_id) + id_len; | |||
710 | *id = malloc(*id_sz, M_CREDENTIALS110, M_WAITOK0x0001); | |||
711 | (*id)->len = id_len; | |||
712 | ||||
713 | switch (sadb_ident->sadb_ident_type) { | |||
714 | case SADB_IDENTTYPE_PREFIX1: | |||
715 | (*id)->type = IPSP_IDENTITY_PREFIX1; | |||
716 | break; | |||
717 | case SADB_IDENTTYPE_FQDN2: | |||
718 | (*id)->type = IPSP_IDENTITY_FQDN2; | |||
719 | break; | |||
720 | case SADB_IDENTTYPE_USERFQDN3: | |||
721 | (*id)->type = IPSP_IDENTITY_USERFQDN3; | |||
722 | break; | |||
723 | case SADB_IDENTTYPE_ASN1_DN4: | |||
724 | (*id)->type = IPSP_IDENTITY_ASN1_DN4; | |||
725 | break; | |||
726 | default: | |||
727 | free(*id, M_CREDENTIALS110, *id_sz); | |||
728 | *id = NULL((void *)0); | |||
729 | return; | |||
730 | } | |||
731 | bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1, | |||
732 | (*id)->len); | |||
733 | } | |||
734 | ||||
735 | void | |||
736 | import_identities(struct ipsec_ids **ids, int swapped, | |||
737 | struct sadb_ident *srcid, struct sadb_ident *dstid) | |||
738 | { | |||
739 | struct ipsec_ids *tmp; | |||
740 | size_t id_local_sz, id_remote_sz; | |||
| ||||
741 | ||||
742 | *ids = NULL((void *)0); | |||
743 | tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS110, M_WAITOK0x0001); | |||
744 | import_identity(&tmp->id_local, swapped ? dstid: srcid, &id_local_sz); | |||
745 | import_identity(&tmp->id_remote, swapped
| |||
746 | if (tmp->id_local
| |||
747 | *ids = ipsp_ids_insert(tmp); | |||
748 | if (*ids == tmp) | |||
749 | return; | |||
750 | } | |||
751 | free(tmp->id_local, M_CREDENTIALS110, id_local_sz); | |||
752 | free(tmp->id_remote, M_CREDENTIALS110, id_remote_sz); | |||
| ||||
753 | free(tmp, M_CREDENTIALS110, sizeof(*tmp)); | |||
754 | } | |||
755 | ||||
756 | static void | |||
757 | export_identity(void **p, struct ipsec_id *id) | |||
758 | { | |||
759 | struct sadb_ident *sadb_ident = (struct sadb_ident *) *p; | |||
760 | ||||
761 | sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) + | |||
762 | PADUP(id->len)(((id->len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1))) / sizeof(uint64_t); | |||
763 | ||||
764 | switch (id->type) { | |||
765 | case IPSP_IDENTITY_PREFIX1: | |||
766 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX1; | |||
767 | break; | |||
768 | case IPSP_IDENTITY_FQDN2: | |||
769 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN2; | |||
770 | break; | |||
771 | case IPSP_IDENTITY_USERFQDN3: | |||
772 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN3; | |||
773 | break; | |||
774 | case IPSP_IDENTITY_ASN1_DN4: | |||
775 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_ASN1_DN4; | |||
776 | break; | |||
777 | } | |||
778 | *p += sizeof(struct sadb_ident); | |||
779 | bcopy(id + 1, *p, id->len); | |||
780 | *p += PADUP(id->len)(((id->len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1)); | |||
781 | } | |||
782 | ||||
783 | void | |||
784 | export_identities(void **p, struct ipsec_ids *ids, int swapped, | |||
785 | void **headers) | |||
786 | { | |||
787 | headers[SADB_EXT_IDENTITY_SRC10] = *p; | |||
788 | export_identity(p, swapped ? ids->id_remote : ids->id_local); | |||
789 | headers[SADB_EXT_IDENTITY_DST11] = *p; | |||
790 | export_identity(p, swapped ? ids->id_local : ids->id_remote); | |||
791 | } | |||
792 | ||||
793 | /* ... */ | |||
794 | void | |||
795 | import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type) | |||
796 | { | |||
797 | if (!sadb_key) | |||
798 | return; | |||
799 | ||||
800 | if (type == PFKEYV2_ENCRYPTION_KEY0) { /* Encryption key */ | |||
801 | ii->ii_enckeylen = sadb_key->sadb_key_bits / 8; | |||
802 | ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key); | |||
803 | } else { | |||
804 | ii->ii_authkeylen = sadb_key->sadb_key_bits / 8; | |||
805 | ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key); | |||
806 | } | |||
807 | } | |||
808 | ||||
809 | void | |||
810 | export_key(void **p, struct tdb *tdb, int type) | |||
811 | { | |||
812 | struct sadb_key *sadb_key = (struct sadb_key *) *p; | |||
813 | ||||
814 | if (type == PFKEYV2_ENCRYPTION_KEY0) { | |||
815 | sadb_key->sadb_key_len = (sizeof(struct sadb_key) + | |||
816 | PADUP(tdb->tdb_emxkeylen)(((tdb->tdb_emxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1))) / | |||
817 | sizeof(uint64_t); | |||
818 | sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8; | |||
819 | *p += sizeof(struct sadb_key); | |||
820 | bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen); | |||
821 | *p += PADUP(tdb->tdb_emxkeylen)(((tdb->tdb_emxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1)); | |||
822 | } else { | |||
823 | sadb_key->sadb_key_len = (sizeof(struct sadb_key) + | |||
824 | PADUP(tdb->tdb_amxkeylen)(((tdb->tdb_amxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1))) / | |||
825 | sizeof(uint64_t); | |||
826 | sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8; | |||
827 | *p += sizeof(struct sadb_key); | |||
828 | bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen); | |||
829 | *p += PADUP(tdb->tdb_amxkeylen)(((tdb->tdb_amxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1)); | |||
830 | } | |||
831 | } | |||
832 | ||||
833 | /* Import/Export remote port for UDP Encapsulation */ | |||
834 | void | |||
835 | import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap) | |||
836 | { | |||
837 | if (sadb_udpencap) | |||
838 | tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port; | |||
839 | } | |||
840 | ||||
841 | void | |||
842 | export_udpencap(void **p, struct tdb *tdb) | |||
843 | { | |||
844 | struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p; | |||
845 | ||||
846 | sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port; | |||
847 | sadb_udpencap->sadb_x_udpencap_reserved = 0; | |||
848 | sadb_udpencap->sadb_x_udpencap_len = | |||
849 | sizeof(struct sadb_x_udpencap) / sizeof(uint64_t); | |||
850 | *p += sizeof(struct sadb_x_udpencap); | |||
851 | } | |||
852 | ||||
853 | /* Export PF replay for SA */ | |||
854 | void | |||
855 | export_replay(void **p, struct tdb *tdb) | |||
856 | { | |||
857 | struct sadb_x_replay *sreplay = (struct sadb_x_replay *)*p; | |||
858 | ||||
859 | sreplay->sadb_x_replay_count = tdb->tdb_rpl; | |||
860 | sreplay->sadb_x_replay_len = | |||
861 | sizeof(struct sadb_x_replay) / sizeof(uint64_t); | |||
862 | *p += sizeof(struct sadb_x_replay); | |||
863 | } | |||
864 | ||||
865 | /* Export mtu for SA */ | |||
866 | void | |||
867 | export_mtu(void **p, struct tdb *tdb) | |||
868 | { | |||
869 | struct sadb_x_mtu *smtu = (struct sadb_x_mtu *)*p; | |||
870 | ||||
871 | smtu->sadb_x_mtu_mtu = tdb->tdb_mtu; | |||
872 | smtu->sadb_x_mtu_len = | |||
873 | sizeof(struct sadb_x_mtu) / sizeof(uint64_t); | |||
874 | *p += sizeof(struct sadb_x_mtu); | |||
875 | } | |||
876 | ||||
877 | /* Import rdomain switch for SA */ | |||
878 | void | |||
879 | import_rdomain(struct tdb *tdb, struct sadb_x_rdomain *srdomain) | |||
880 | { | |||
881 | if (srdomain) | |||
882 | tdb->tdb_rdomain_post = srdomain->sadb_x_rdomain_dom2; | |||
883 | } | |||
884 | ||||
885 | /* Export rdomain switch for SA */ | |||
886 | void | |||
887 | export_rdomain(void **p, struct tdb *tdb) | |||
888 | { | |||
889 | struct sadb_x_rdomain *srdomain = (struct sadb_x_rdomain *)*p; | |||
890 | ||||
891 | srdomain->sadb_x_rdomain_dom1 = tdb->tdb_rdomain; | |||
892 | srdomain->sadb_x_rdomain_dom2 = tdb->tdb_rdomain_post; | |||
893 | srdomain->sadb_x_rdomain_len = | |||
894 | sizeof(struct sadb_x_rdomain) / sizeof(uint64_t); | |||
895 | *p += sizeof(struct sadb_x_rdomain); | |||
896 | } | |||
897 | ||||
898 | #if NPF1 > 0 | |||
899 | /* Import PF tag information for SA */ | |||
900 | void | |||
901 | import_tag(struct tdb *tdb, struct sadb_x_tag *stag) | |||
902 | { | |||
903 | char *s; | |||
904 | ||||
905 | if (stag) { | |||
906 | s = (char *)(stag + 1); | |||
907 | tdb->tdb_tag = pf_tagname2tag(s, 1); | |||
908 | } | |||
909 | } | |||
910 | ||||
911 | /* Export PF tag information for SA */ | |||
912 | void | |||
913 | export_tag(void **p, struct tdb *tdb) | |||
914 | { | |||
915 | struct sadb_x_tag *stag = (struct sadb_x_tag *)*p; | |||
916 | char *s = (char *)(stag + 1); | |||
917 | ||||
918 | pf_tag2tagname(tdb->tdb_tag, s); | |||
919 | ||||
920 | stag->sadb_x_tag_taglen = strlen(s) + 1; | |||
921 | stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) + | |||
922 | PADUP(stag->sadb_x_tag_taglen)(((stag->sadb_x_tag_taglen) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1))) / sizeof(uint64_t); | |||
923 | *p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen)(((stag->sadb_x_tag_taglen) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1)); | |||
924 | } | |||
925 | ||||
926 | /* Import enc(4) tap device information for SA */ | |||
927 | void | |||
928 | import_tap(struct tdb *tdb, struct sadb_x_tap *stap) | |||
929 | { | |||
930 | if (stap) | |||
931 | tdb->tdb_tap = stap->sadb_x_tap_unit; | |||
932 | } | |||
933 | ||||
934 | /* Export enc(4) tap device information for SA */ | |||
935 | void | |||
936 | export_tap(void **p, struct tdb *tdb) | |||
937 | { | |||
938 | struct sadb_x_tap *stag = (struct sadb_x_tap *)*p; | |||
939 | ||||
940 | stag->sadb_x_tap_unit = tdb->tdb_tap; | |||
941 | stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t); | |||
942 | *p += sizeof(struct sadb_x_tap); | |||
943 | } | |||
944 | #endif | |||
945 | ||||
946 | /* Import interface information for SA */ | |||
947 | void | |||
948 | import_iface(struct tdb *tdb, struct sadb_x_iface *siface) | |||
949 | { | |||
950 | if (siface != NULL((void *)0)) { | |||
951 | SET(tdb->tdb_flags, TDBF_IFACE)((tdb->tdb_flags) |= (0x400000)); | |||
952 | tdb->tdb_iface = siface->sadb_x_iface_unit; | |||
953 | tdb->tdb_iface_dir = siface->sadb_x_iface_direction; | |||
954 | } | |||
955 | } | |||
956 | ||||
957 | /* Export interface information for SA */ | |||
958 | void | |||
959 | export_iface(void **p, struct tdb *tdb) | |||
960 | { | |||
961 | struct sadb_x_iface *siface = (struct sadb_x_iface *)*p; | |||
962 | ||||
963 | siface->sadb_x_iface_len = sizeof(*siface) / sizeof(uint64_t); | |||
964 | siface->sadb_x_iface_unit = tdb->tdb_iface; | |||
965 | siface->sadb_x_iface_direction = tdb->tdb_iface_dir; | |||
966 | ||||
967 | *p += sizeof(*siface); | |||
968 | } | |||
969 | ||||
970 | void | |||
971 | export_satype(void **p, struct tdb *tdb) | |||
972 | { | |||
973 | struct sadb_protocol *sab = *p; | |||
974 | ||||
975 | sab->sadb_protocol_len = sizeof(struct sadb_protocol) / | |||
976 | sizeof(uint64_t); | |||
977 | sab->sadb_protocol_proto = tdb->tdb_satype; | |||
978 | *p += sizeof(struct sadb_protocol); | |||
979 | } | |||
980 | ||||
981 | void | |||
982 | export_counter(void **p, struct tdb *tdb) | |||
983 | { | |||
984 | uint64_t counters[tdb_ncounters]; | |||
985 | struct sadb_x_counter *scnt = (struct sadb_x_counter *)*p; | |||
986 | ||||
987 | counters_read(tdb->tdb_counters, counters, tdb_ncounters, NULL((void *)0)); | |||
988 | ||||
989 | scnt->sadb_x_counter_len = sizeof(struct sadb_x_counter) / | |||
990 | sizeof(uint64_t); | |||
991 | scnt->sadb_x_counter_pad = 0; | |||
992 | scnt->sadb_x_counter_ipackets = counters[tdb_ipackets]; | |||
993 | scnt->sadb_x_counter_opackets = counters[tdb_opackets]; | |||
994 | scnt->sadb_x_counter_ibytes = counters[tdb_ibytes]; | |||
995 | scnt->sadb_x_counter_obytes = counters[tdb_obytes]; | |||
996 | scnt->sadb_x_counter_idrops = counters[tdb_idrops]; | |||
997 | scnt->sadb_x_counter_odrops = counters[tdb_odrops]; | |||
998 | scnt->sadb_x_counter_idecompbytes = counters[tdb_idecompbytes]; | |||
999 | scnt->sadb_x_counter_ouncompbytes = counters[tdb_ouncompbytes]; | |||
1000 | *p += sizeof(struct sadb_x_counter); | |||
1001 | } |