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