| 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 | } |