1 /* $OpenBSD: pfkey.c,v 1.51 2010/10/06 22:19:20 mikeb Exp $ */ 2 /* 3 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 4 * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org> 5 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/queue.h> 22 #include <sys/uio.h> 23 #include <sys/socket.h> 24 #include <netinet/in.h> 25 #include <netinet/ip_ipsp.h> 26 #include <net/pfkeyv2.h> 27 28 #include <err.h> 29 #include <errno.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 35 #include "ipsecctl.h" 36 #include "pfkey.h" 37 38 #define ROUNDUP(x) (((x) + (PFKEYV2_CHUNK - 1)) & ~(PFKEYV2_CHUNK - 1)) 39 #define IOV_CNT 20 40 41 static int fd; 42 static u_int32_t sadb_msg_seq = 1; 43 44 static int pfkey_flow(int, u_int8_t, u_int8_t, u_int8_t, u_int8_t, 45 struct ipsec_addr_wrap *, u_int16_t, 46 struct ipsec_addr_wrap *, u_int16_t, 47 struct ipsec_addr_wrap *, struct ipsec_addr_wrap *, 48 struct ipsec_auth *, u_int8_t); 49 static int pfkey_sa(int, u_int8_t, u_int8_t, u_int32_t, 50 struct ipsec_addr_wrap *, struct ipsec_addr_wrap *, 51 struct ipsec_transforms *, struct ipsec_key *, 52 struct ipsec_key *, u_int8_t); 53 static int pfkey_sagroup(int, u_int8_t, u_int8_t, u_int8_t, 54 struct ipsec_addr_wrap *, u_int32_t, 55 struct ipsec_addr_wrap *, u_int32_t); 56 static int pfkey_reply(int, u_int8_t **, ssize_t *); 57 int pfkey_parse(struct sadb_msg *, struct ipsec_rule *); 58 int pfkey_ipsec_flush(void); 59 int pfkey_ipsec_establish(int, struct ipsec_rule *); 60 int pfkey_init(void); 61 62 static int 63 pfkey_flow(int sd, u_int8_t satype, u_int8_t action, u_int8_t direction, 64 u_int8_t proto, struct ipsec_addr_wrap *src, u_int16_t sport, 65 struct ipsec_addr_wrap *dst, u_int16_t dport, 66 struct ipsec_addr_wrap *local, struct ipsec_addr_wrap *peer, 67 struct ipsec_auth *auth, u_int8_t flowtype) 68 { 69 struct sadb_msg smsg; 70 struct sadb_address sa_src, sa_dst, sa_local, sa_peer, sa_smask, 71 sa_dmask; 72 struct sadb_protocol sa_flowtype, sa_protocol; 73 struct sadb_ident *sa_srcid, *sa_dstid; 74 struct sockaddr_storage ssrc, sdst, slocal, speer, smask, dmask; 75 struct iovec iov[IOV_CNT]; 76 ssize_t n; 77 int iov_cnt, len, ret = 0; 78 79 sa_srcid = sa_dstid = NULL; 80 81 bzero(&ssrc, sizeof(ssrc)); 82 bzero(&smask, sizeof(smask)); 83 ssrc.ss_family = smask.ss_family = src->af; 84 switch (src->af) { 85 case AF_INET: 86 ((struct sockaddr_in *)&ssrc)->sin_addr = src->address.v4; 87 ssrc.ss_len = sizeof(struct sockaddr_in); 88 ((struct sockaddr_in *)&smask)->sin_addr = src->mask.v4; 89 if (sport) { 90 ((struct sockaddr_in *)&ssrc)->sin_port = sport; 91 ((struct sockaddr_in *)&smask)->sin_port = 0xffff; 92 } 93 break; 94 case AF_INET6: 95 ((struct sockaddr_in6 *)&ssrc)->sin6_addr = src->address.v6; 96 ssrc.ss_len = sizeof(struct sockaddr_in6); 97 ((struct sockaddr_in6 *)&smask)->sin6_addr = src->mask.v6; 98 if (sport) { 99 ((struct sockaddr_in6 *)&ssrc)->sin6_port = sport; 100 ((struct sockaddr_in6 *)&smask)->sin6_port = 0xffff; 101 } 102 break; 103 default: 104 warnx("unsupported address family %d", src->af); 105 return -1; 106 } 107 smask.ss_len = ssrc.ss_len; 108 109 bzero(&sdst, sizeof(sdst)); 110 bzero(&dmask, sizeof(dmask)); 111 sdst.ss_family = dmask.ss_family = dst->af; 112 switch (dst->af) { 113 case AF_INET: 114 ((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4; 115 sdst.ss_len = sizeof(struct sockaddr_in); 116 ((struct sockaddr_in *)&dmask)->sin_addr = dst->mask.v4; 117 if (dport) { 118 ((struct sockaddr_in *)&sdst)->sin_port = dport; 119 ((struct sockaddr_in *)&dmask)->sin_port = 0xffff; 120 } 121 break; 122 case AF_INET6: 123 ((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6; 124 sdst.ss_len = sizeof(struct sockaddr_in6); 125 ((struct sockaddr_in6 *)&dmask)->sin6_addr = dst->mask.v6; 126 if (dport) { 127 ((struct sockaddr_in6 *)&sdst)->sin6_port = dport; 128 ((struct sockaddr_in6 *)&dmask)->sin6_port = 0xffff; 129 } 130 break; 131 default: 132 warnx("unsupported address family %d", dst->af); 133 return -1; 134 } 135 dmask.ss_len = sdst.ss_len; 136 137 bzero(&slocal, sizeof(slocal)); 138 if (local) { 139 slocal.ss_family = local->af; 140 switch (local->af) { 141 case AF_INET: 142 ((struct sockaddr_in *)&slocal)->sin_addr = 143 local->address.v4; 144 slocal.ss_len = sizeof(struct sockaddr_in); 145 break; 146 case AF_INET6: 147 ((struct sockaddr_in6 *)&slocal)->sin6_addr = 148 local->address.v6; 149 slocal.ss_len = sizeof(struct sockaddr_in6); 150 break; 151 default: 152 warnx("unsupported address family %d", local->af); 153 return -1; 154 } 155 } 156 157 bzero(&speer, sizeof(speer)); 158 if (peer) { 159 speer.ss_family = peer->af; 160 switch (peer->af) { 161 case AF_INET: 162 ((struct sockaddr_in *)&speer)->sin_addr = 163 peer->address.v4; 164 speer.ss_len = sizeof(struct sockaddr_in); 165 break; 166 case AF_INET6: 167 ((struct sockaddr_in6 *)&speer)->sin6_addr = 168 peer->address.v6; 169 speer.ss_len = sizeof(struct sockaddr_in6); 170 break; 171 default: 172 warnx("unsupported address family %d", peer->af); 173 return -1; 174 } 175 } 176 177 bzero(&smsg, sizeof(smsg)); 178 smsg.sadb_msg_version = PF_KEY_V2; 179 smsg.sadb_msg_seq = sadb_msg_seq++; 180 smsg.sadb_msg_pid = getpid(); 181 smsg.sadb_msg_len = sizeof(smsg) / 8; 182 smsg.sadb_msg_type = action; 183 smsg.sadb_msg_satype = satype; 184 185 bzero(&sa_flowtype, sizeof(sa_flowtype)); 186 sa_flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE; 187 sa_flowtype.sadb_protocol_len = sizeof(sa_flowtype) / 8; 188 sa_flowtype.sadb_protocol_direction = direction; 189 190 switch (flowtype) { 191 case TYPE_USE: 192 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE; 193 break; 194 case TYPE_ACQUIRE: 195 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE; 196 break; 197 case TYPE_REQUIRE: 198 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE; 199 break; 200 case TYPE_DENY: 201 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY; 202 break; 203 case TYPE_BYPASS: 204 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS; 205 break; 206 case TYPE_DONTACQ: 207 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ; 208 break; 209 default: 210 warnx("unsupported flowtype %d", flowtype); 211 return -1; 212 } 213 214 bzero(&sa_protocol, sizeof(sa_protocol)); 215 sa_protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; 216 sa_protocol.sadb_protocol_len = sizeof(sa_protocol) / 8; 217 sa_protocol.sadb_protocol_direction = 0; 218 sa_protocol.sadb_protocol_proto = proto; 219 220 bzero(&sa_src, sizeof(sa_src)); 221 sa_src.sadb_address_exttype = SADB_X_EXT_SRC_FLOW; 222 sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8; 223 224 bzero(&sa_smask, sizeof(sa_smask)); 225 sa_smask.sadb_address_exttype = SADB_X_EXT_SRC_MASK; 226 sa_smask.sadb_address_len = 227 (sizeof(sa_smask) + ROUNDUP(smask.ss_len)) / 8; 228 229 bzero(&sa_dst, sizeof(sa_dst)); 230 sa_dst.sadb_address_exttype = SADB_X_EXT_DST_FLOW; 231 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 232 233 bzero(&sa_dmask, sizeof(sa_dmask)); 234 sa_dmask.sadb_address_exttype = SADB_X_EXT_DST_MASK; 235 sa_dmask.sadb_address_len = 236 (sizeof(sa_dmask) + ROUNDUP(dmask.ss_len)) / 8; 237 238 if (local) { 239 bzero(&sa_local, sizeof(sa_local)); 240 sa_local.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 241 sa_local.sadb_address_len = 242 (sizeof(sa_local) + ROUNDUP(slocal.ss_len)) / 8; 243 } 244 if (peer) { 245 bzero(&sa_peer, sizeof(sa_peer)); 246 sa_peer.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 247 sa_peer.sadb_address_len = 248 (sizeof(sa_peer) + ROUNDUP(speer.ss_len)) / 8; 249 } 250 251 if (auth && auth->srcid) { 252 len = ROUNDUP(strlen(auth->srcid) + 1) + sizeof(*sa_srcid); 253 254 sa_srcid = calloc(len, sizeof(u_int8_t)); 255 if (sa_srcid == NULL) 256 err(1, "pfkey_flow: calloc"); 257 258 sa_srcid->sadb_ident_type = auth->srcid_type; 259 sa_srcid->sadb_ident_len = len / 8; 260 sa_srcid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; 261 262 strlcpy((char *)(sa_srcid + 1), auth->srcid, 263 ROUNDUP(strlen(auth->srcid) + 1)); 264 } 265 if (auth && auth->dstid) { 266 len = ROUNDUP(strlen(auth->dstid) + 1) + sizeof(*sa_dstid); 267 268 sa_dstid = calloc(len, sizeof(u_int8_t)); 269 if (sa_dstid == NULL) 270 err(1, "pfkey_flow: calloc"); 271 272 sa_dstid->sadb_ident_type = auth->dstid_type; 273 sa_dstid->sadb_ident_len = len / 8; 274 sa_dstid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST; 275 276 strlcpy((char *)(sa_dstid + 1), auth->dstid, 277 ROUNDUP(strlen(auth->dstid) + 1)); 278 } 279 280 iov_cnt = 0; 281 282 /* header */ 283 iov[iov_cnt].iov_base = &smsg; 284 iov[iov_cnt].iov_len = sizeof(smsg); 285 iov_cnt++; 286 287 /* add flow type */ 288 iov[iov_cnt].iov_base = &sa_flowtype; 289 iov[iov_cnt].iov_len = sizeof(sa_flowtype); 290 smsg.sadb_msg_len += sa_flowtype.sadb_protocol_len; 291 iov_cnt++; 292 293 /* local ip */ 294 if (local) { 295 iov[iov_cnt].iov_base = &sa_local; 296 iov[iov_cnt].iov_len = sizeof(sa_local); 297 iov_cnt++; 298 iov[iov_cnt].iov_base = &slocal; 299 iov[iov_cnt].iov_len = ROUNDUP(slocal.ss_len); 300 smsg.sadb_msg_len += sa_local.sadb_address_len; 301 iov_cnt++; 302 } 303 304 /* remote peer */ 305 if (peer) { 306 iov[iov_cnt].iov_base = &sa_peer; 307 iov[iov_cnt].iov_len = sizeof(sa_peer); 308 iov_cnt++; 309 iov[iov_cnt].iov_base = &speer; 310 iov[iov_cnt].iov_len = ROUNDUP(speer.ss_len); 311 smsg.sadb_msg_len += sa_peer.sadb_address_len; 312 iov_cnt++; 313 } 314 315 /* src addr */ 316 iov[iov_cnt].iov_base = &sa_src; 317 iov[iov_cnt].iov_len = sizeof(sa_src); 318 iov_cnt++; 319 iov[iov_cnt].iov_base = &ssrc; 320 iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len); 321 smsg.sadb_msg_len += sa_src.sadb_address_len; 322 iov_cnt++; 323 324 /* src mask */ 325 iov[iov_cnt].iov_base = &sa_smask; 326 iov[iov_cnt].iov_len = sizeof(sa_smask); 327 iov_cnt++; 328 iov[iov_cnt].iov_base = &smask; 329 iov[iov_cnt].iov_len = ROUNDUP(smask.ss_len); 330 smsg.sadb_msg_len += sa_smask.sadb_address_len; 331 iov_cnt++; 332 333 /* dest addr */ 334 iov[iov_cnt].iov_base = &sa_dst; 335 iov[iov_cnt].iov_len = sizeof(sa_dst); 336 iov_cnt++; 337 iov[iov_cnt].iov_base = &sdst; 338 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 339 smsg.sadb_msg_len += sa_dst.sadb_address_len; 340 iov_cnt++; 341 342 /* dst mask */ 343 iov[iov_cnt].iov_base = &sa_dmask; 344 iov[iov_cnt].iov_len = sizeof(sa_dmask); 345 iov_cnt++; 346 iov[iov_cnt].iov_base = &dmask; 347 iov[iov_cnt].iov_len = ROUNDUP(dmask.ss_len); 348 smsg.sadb_msg_len += sa_dmask.sadb_address_len; 349 iov_cnt++; 350 351 /* add protocol */ 352 iov[iov_cnt].iov_base = &sa_protocol; 353 iov[iov_cnt].iov_len = sizeof(sa_protocol); 354 smsg.sadb_msg_len += sa_protocol.sadb_protocol_len; 355 iov_cnt++; 356 357 if (sa_srcid) { 358 /* src identity */ 359 iov[iov_cnt].iov_base = sa_srcid; 360 iov[iov_cnt].iov_len = sa_srcid->sadb_ident_len * 8; 361 smsg.sadb_msg_len += sa_srcid->sadb_ident_len; 362 iov_cnt++; 363 } 364 if (sa_dstid) { 365 /* dst identity */ 366 iov[iov_cnt].iov_base = sa_dstid; 367 iov[iov_cnt].iov_len = sa_dstid->sadb_ident_len * 8; 368 smsg.sadb_msg_len += sa_dstid->sadb_ident_len; 369 iov_cnt++; 370 } 371 len = smsg.sadb_msg_len * 8; 372 373 do { 374 n = writev(sd, iov, iov_cnt); 375 } while (n == -1 && (errno == EAGAIN || errno == EINTR)); 376 if (n == -1) { 377 warn("writev failed"); 378 ret = -1; 379 } 380 381 if (sa_srcid) 382 free(sa_srcid); 383 if (sa_dstid) 384 free(sa_dstid); 385 386 return ret; 387 } 388 389 static int 390 pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi, 391 struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst, 392 struct ipsec_transforms *xfs, struct ipsec_key *authkey, 393 struct ipsec_key *enckey, u_int8_t tmode) 394 { 395 struct sadb_msg smsg; 396 struct sadb_sa sa; 397 struct sadb_address sa_src, sa_dst; 398 struct sadb_key sa_authkey, sa_enckey; 399 struct sockaddr_storage ssrc, sdst; 400 struct iovec iov[IOV_CNT]; 401 ssize_t n; 402 int iov_cnt, len, ret = 0; 403 404 bzero(&ssrc, sizeof(ssrc)); 405 ssrc.ss_family = src->af; 406 switch (src->af) { 407 case AF_INET: 408 ((struct sockaddr_in *)&ssrc)->sin_addr = src->address.v4; 409 ssrc.ss_len = sizeof(struct sockaddr_in); 410 break; 411 case AF_INET6: 412 ((struct sockaddr_in6 *)&ssrc)->sin6_addr = src->address.v6; 413 ssrc.ss_len = sizeof(struct sockaddr_in6); 414 break; 415 default: 416 warnx("unsupported address family %d", src->af); 417 return -1; 418 } 419 420 bzero(&sdst, sizeof(sdst)); 421 sdst.ss_family = dst->af; 422 switch (dst->af) { 423 case AF_INET: 424 ((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4; 425 sdst.ss_len = sizeof(struct sockaddr_in); 426 break; 427 case AF_INET6: 428 ((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6; 429 sdst.ss_len = sizeof(struct sockaddr_in6); 430 break; 431 default: 432 warnx("unsupported address family %d", dst->af); 433 return -1; 434 } 435 436 bzero(&smsg, sizeof(smsg)); 437 smsg.sadb_msg_version = PF_KEY_V2; 438 smsg.sadb_msg_seq = sadb_msg_seq++; 439 smsg.sadb_msg_pid = getpid(); 440 smsg.sadb_msg_len = sizeof(smsg) / 8; 441 smsg.sadb_msg_type = action; 442 smsg.sadb_msg_satype = satype; 443 444 bzero(&sa, sizeof(sa)); 445 sa.sadb_sa_len = sizeof(sa) / 8; 446 sa.sadb_sa_exttype = SADB_EXT_SA; 447 sa.sadb_sa_spi = htonl(spi); 448 sa.sadb_sa_state = SADB_SASTATE_MATURE; 449 450 if (satype != SADB_X_SATYPE_IPIP && tmode == IPSEC_TUNNEL) 451 sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; 452 453 if (xfs && xfs->authxf) { 454 switch (xfs->authxf->id) { 455 case AUTHXF_NONE: 456 break; 457 case AUTHXF_HMAC_MD5: 458 sa.sadb_sa_auth = SADB_AALG_MD5HMAC; 459 break; 460 case AUTHXF_HMAC_RIPEMD160: 461 sa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC; 462 break; 463 case AUTHXF_HMAC_SHA1: 464 sa.sadb_sa_auth = SADB_AALG_SHA1HMAC; 465 break; 466 case AUTHXF_HMAC_SHA2_256: 467 sa.sadb_sa_auth = SADB_X_AALG_SHA2_256; 468 break; 469 case AUTHXF_HMAC_SHA2_384: 470 sa.sadb_sa_auth = SADB_X_AALG_SHA2_384; 471 break; 472 case AUTHXF_HMAC_SHA2_512: 473 sa.sadb_sa_auth = SADB_X_AALG_SHA2_512; 474 break; 475 default: 476 warnx("unsupported authentication algorithm %d", 477 xfs->authxf->id); 478 } 479 } 480 if (xfs && xfs->encxf) { 481 switch (xfs->encxf->id) { 482 case ENCXF_NONE: 483 break; 484 case ENCXF_3DES_CBC: 485 sa.sadb_sa_encrypt = SADB_EALG_3DESCBC; 486 break; 487 case ENCXF_DES_CBC: 488 sa.sadb_sa_encrypt = SADB_EALG_DESCBC; 489 break; 490 case ENCXF_AES: 491 case ENCXF_AES_128: 492 case ENCXF_AES_192: 493 case ENCXF_AES_256: 494 sa.sadb_sa_encrypt = SADB_X_EALG_AES; 495 break; 496 case ENCXF_AESCTR: 497 sa.sadb_sa_encrypt = SADB_X_EALG_AESCTR; 498 break; 499 case ENCXF_AES_128_GCM: 500 case ENCXF_AES_192_GCM: 501 case ENCXF_AES_256_GCM: 502 sa.sadb_sa_encrypt = SADB_X_EALG_AESGCM16; 503 break; 504 case ENCXF_AES_128_GMAC: 505 case ENCXF_AES_192_GMAC: 506 case ENCXF_AES_256_GMAC: 507 sa.sadb_sa_encrypt = SADB_X_EALG_AESGMAC; 508 break; 509 case ENCXF_BLOWFISH: 510 sa.sadb_sa_encrypt = SADB_X_EALG_BLF; 511 break; 512 case ENCXF_CAST128: 513 sa.sadb_sa_encrypt = SADB_X_EALG_CAST; 514 break; 515 case ENCXF_NULL: 516 sa.sadb_sa_encrypt = SADB_EALG_NULL; 517 break; 518 default: 519 warnx("unsupported encryption algorithm %d", 520 xfs->encxf->id); 521 } 522 } 523 if (xfs && xfs->compxf) { 524 switch (xfs->compxf->id) { 525 case COMPXF_DEFLATE: 526 sa.sadb_sa_encrypt = SADB_X_CALG_DEFLATE; 527 break; 528 case COMPXF_LZS: 529 sa.sadb_sa_encrypt = SADB_X_CALG_LZS; 530 break; 531 default: 532 warnx("unsupported compression algorithm %d", 533 xfs->compxf->id); 534 } 535 } 536 537 bzero(&sa_src, sizeof(sa_src)); 538 sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8; 539 sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 540 541 bzero(&sa_dst, sizeof(sa_dst)); 542 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 543 sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 544 545 if (action == SADB_ADD && !authkey && !enckey && satype != 546 SADB_X_SATYPE_IPCOMP && satype != SADB_X_SATYPE_IPIP) { /* XXX ENCNULL */ 547 warnx("no key specified"); 548 return -1; 549 } 550 if (authkey) { 551 bzero(&sa_authkey, sizeof(sa_authkey)); 552 sa_authkey.sadb_key_len = (sizeof(sa_authkey) + 553 ((authkey->len + 7) / 8) * 8) / 8; 554 sa_authkey.sadb_key_exttype = SADB_EXT_KEY_AUTH; 555 sa_authkey.sadb_key_bits = 8 * authkey->len; 556 } 557 if (enckey) { 558 bzero(&sa_enckey, sizeof(sa_enckey)); 559 sa_enckey.sadb_key_len = (sizeof(sa_enckey) + 560 ((enckey->len + 7) / 8) * 8) / 8; 561 sa_enckey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 562 sa_enckey.sadb_key_bits = 8 * enckey->len; 563 } 564 565 iov_cnt = 0; 566 567 /* header */ 568 iov[iov_cnt].iov_base = &smsg; 569 iov[iov_cnt].iov_len = sizeof(smsg); 570 iov_cnt++; 571 572 /* sa */ 573 iov[iov_cnt].iov_base = &sa; 574 iov[iov_cnt].iov_len = sizeof(sa); 575 smsg.sadb_msg_len += sa.sadb_sa_len; 576 iov_cnt++; 577 578 /* src addr */ 579 iov[iov_cnt].iov_base = &sa_src; 580 iov[iov_cnt].iov_len = sizeof(sa_src); 581 iov_cnt++; 582 iov[iov_cnt].iov_base = &ssrc; 583 iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len); 584 smsg.sadb_msg_len += sa_src.sadb_address_len; 585 iov_cnt++; 586 587 /* dst addr */ 588 iov[iov_cnt].iov_base = &sa_dst; 589 iov[iov_cnt].iov_len = sizeof(sa_dst); 590 iov_cnt++; 591 iov[iov_cnt].iov_base = &sdst; 592 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 593 smsg.sadb_msg_len += sa_dst.sadb_address_len; 594 iov_cnt++; 595 596 if (authkey) { 597 /* authentication key */ 598 iov[iov_cnt].iov_base = &sa_authkey; 599 iov[iov_cnt].iov_len = sizeof(sa_authkey); 600 iov_cnt++; 601 iov[iov_cnt].iov_base = authkey->data; 602 iov[iov_cnt].iov_len = ((authkey->len + 7) / 8) * 8; 603 smsg.sadb_msg_len += sa_authkey.sadb_key_len; 604 iov_cnt++; 605 } 606 if (enckey) { 607 /* encryption key */ 608 iov[iov_cnt].iov_base = &sa_enckey; 609 iov[iov_cnt].iov_len = sizeof(sa_enckey); 610 iov_cnt++; 611 iov[iov_cnt].iov_base = enckey->data; 612 iov[iov_cnt].iov_len = ((enckey->len + 7) / 8) * 8; 613 smsg.sadb_msg_len += sa_enckey.sadb_key_len; 614 iov_cnt++; 615 } 616 617 len = smsg.sadb_msg_len * 8; 618 if ((n = writev(sd, iov, iov_cnt)) == -1) { 619 warn("writev failed"); 620 ret = -1; 621 } else if (n != len) { 622 warnx("short write"); 623 ret = -1; 624 } 625 626 return ret; 627 } 628 629 static int 630 pfkey_sagroup(int sd, u_int8_t satype, u_int8_t satype2, u_int8_t action, 631 struct ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_addr_wrap *dst2, 632 u_int32_t spi2) 633 { 634 struct sadb_msg smsg; 635 struct sadb_sa sa1, sa2; 636 struct sadb_address sa_dst, sa_dst2; 637 struct sockaddr_storage sdst, sdst2; 638 struct sadb_protocol sa_proto; 639 struct iovec iov[IOV_CNT]; 640 ssize_t n; 641 int iov_cnt, len, ret = 0; 642 643 bzero(&sdst, sizeof(sdst)); 644 sdst.ss_family = dst->af; 645 switch (dst->af) { 646 case AF_INET: 647 ((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4; 648 sdst.ss_len = sizeof(struct sockaddr_in); 649 break; 650 case AF_INET6: 651 ((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6; 652 sdst.ss_len = sizeof(struct sockaddr_in6); 653 break; 654 default: 655 warnx("unsupported address family %d", dst->af); 656 return -1; 657 } 658 659 bzero(&sdst2, sizeof(sdst2)); 660 sdst2.ss_family = dst2->af; 661 switch (dst2->af) { 662 case AF_INET: 663 ((struct sockaddr_in *)&sdst2)->sin_addr = dst2->address.v4; 664 sdst2.ss_len = sizeof(struct sockaddr_in); 665 break; 666 case AF_INET6: 667 ((struct sockaddr_in6 *)&sdst2)->sin6_addr = dst2->address.v6; 668 sdst2.ss_len = sizeof(struct sockaddr_in6); 669 break; 670 default: 671 warnx("unsupported address family %d", dst2->af); 672 return -1; 673 } 674 675 bzero(&smsg, sizeof(smsg)); 676 smsg.sadb_msg_version = PF_KEY_V2; 677 smsg.sadb_msg_seq = sadb_msg_seq++; 678 smsg.sadb_msg_pid = getpid(); 679 smsg.sadb_msg_len = sizeof(smsg) / 8; 680 smsg.sadb_msg_type = action; 681 smsg.sadb_msg_satype = satype; 682 683 bzero(&sa1, sizeof(sa1)); 684 sa1.sadb_sa_len = sizeof(sa1) / 8; 685 sa1.sadb_sa_exttype = SADB_EXT_SA; 686 sa1.sadb_sa_spi = htonl(spi); 687 sa1.sadb_sa_state = SADB_SASTATE_MATURE; 688 689 bzero(&sa2, sizeof(sa2)); 690 sa2.sadb_sa_len = sizeof(sa2) / 8; 691 sa2.sadb_sa_exttype = SADB_X_EXT_SA2; 692 sa2.sadb_sa_spi = htonl(spi2); 693 sa2.sadb_sa_state = SADB_SASTATE_MATURE; 694 iov_cnt = 0; 695 696 bzero(&sa_dst, sizeof(sa_dst)); 697 sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 698 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 699 700 bzero(&sa_dst2, sizeof(sa_dst2)); 701 sa_dst2.sadb_address_exttype = SADB_X_EXT_DST2; 702 sa_dst2.sadb_address_len = (sizeof(sa_dst2) + ROUNDUP(sdst2.ss_len)) / 8; 703 704 bzero(&sa_proto, sizeof(sa_proto)); 705 sa_proto.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; 706 sa_proto.sadb_protocol_len = sizeof(sa_proto) / 8; 707 sa_proto.sadb_protocol_direction = 0; 708 sa_proto.sadb_protocol_proto = satype2; 709 710 /* header */ 711 iov[iov_cnt].iov_base = &smsg; 712 iov[iov_cnt].iov_len = sizeof(smsg); 713 iov_cnt++; 714 715 /* sa */ 716 iov[iov_cnt].iov_base = &sa1; 717 iov[iov_cnt].iov_len = sizeof(sa1); 718 smsg.sadb_msg_len += sa1.sadb_sa_len; 719 iov_cnt++; 720 721 /* dst addr */ 722 iov[iov_cnt].iov_base = &sa_dst; 723 iov[iov_cnt].iov_len = sizeof(sa_dst); 724 iov_cnt++; 725 iov[iov_cnt].iov_base = &sdst; 726 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 727 smsg.sadb_msg_len += sa_dst.sadb_address_len; 728 iov_cnt++; 729 730 /* second sa */ 731 iov[iov_cnt].iov_base = &sa2; 732 iov[iov_cnt].iov_len = sizeof(sa2); 733 smsg.sadb_msg_len += sa2.sadb_sa_len; 734 iov_cnt++; 735 736 /* second dst addr */ 737 iov[iov_cnt].iov_base = &sa_dst2; 738 iov[iov_cnt].iov_len = sizeof(sa_dst2); 739 iov_cnt++; 740 iov[iov_cnt].iov_base = &sdst2; 741 iov[iov_cnt].iov_len = ROUNDUP(sdst2.ss_len); 742 smsg.sadb_msg_len += sa_dst2.sadb_address_len; 743 iov_cnt++; 744 745 /* SA type */ 746 iov[iov_cnt].iov_base = &sa_proto; 747 iov[iov_cnt].iov_len = sizeof(sa_proto); 748 smsg.sadb_msg_len += sa_proto.sadb_protocol_len; 749 iov_cnt++; 750 751 len = smsg.sadb_msg_len * 8; 752 if ((n = writev(sd, iov, iov_cnt)) == -1) { 753 warn("writev failed"); 754 ret = -1; 755 } else if (n != len) { 756 warnx("short write"); 757 ret = -1; 758 } 759 760 return (ret); 761 } 762 763 static int 764 pfkey_reply(int sd, u_int8_t **datap, ssize_t *lenp) 765 { 766 struct sadb_msg hdr; 767 ssize_t len; 768 u_int8_t *data; 769 770 if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) { 771 warnx("short read"); 772 return -1; 773 } 774 len = hdr.sadb_msg_len * PFKEYV2_CHUNK; 775 if ((data = malloc(len)) == NULL) 776 err(1, "pfkey_reply: malloc"); 777 if (read(sd, data, len) != len) { 778 warn("PF_KEY short read"); 779 bzero(data, len); 780 free(data); 781 return -1; 782 } 783 if (datap) { 784 *datap = data; 785 if (lenp) 786 *lenp = len; 787 } else { 788 bzero(data, len); 789 free(data); 790 } 791 if (datap == NULL && hdr.sadb_msg_errno != 0) { 792 errno = hdr.sadb_msg_errno; 793 if (errno != EEXIST) { 794 warn("PF_KEY failed"); 795 return -1; 796 } 797 } 798 return 0; 799 } 800 801 int 802 pfkey_parse(struct sadb_msg *msg, struct ipsec_rule *rule) 803 { 804 struct sadb_ext *ext; 805 struct sadb_address *saddr; 806 struct sadb_protocol *sproto; 807 struct sadb_ident *sident; 808 struct sockaddr *sa; 809 struct sockaddr_in *sa_in; 810 struct sockaddr_in6 *sa_in6; 811 int len; 812 813 switch (msg->sadb_msg_satype) { 814 case SADB_SATYPE_ESP: 815 rule->satype = IPSEC_ESP; 816 break; 817 case SADB_SATYPE_AH: 818 rule->satype = IPSEC_AH; 819 break; 820 case SADB_X_SATYPE_IPCOMP: 821 rule->satype = IPSEC_IPCOMP; 822 break; 823 case SADB_X_SATYPE_IPIP: 824 rule->satype = IPSEC_IPIP; 825 break; 826 default: 827 return (1); 828 } 829 830 for (ext = (struct sadb_ext *)(msg + 1); 831 (size_t)((u_int8_t *)ext - (u_int8_t *)msg) < 832 msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0; 833 ext = (struct sadb_ext *)((u_int8_t *)ext + 834 ext->sadb_ext_len * PFKEYV2_CHUNK)) { 835 switch (ext->sadb_ext_type) { 836 case SADB_EXT_ADDRESS_SRC: 837 saddr = (struct sadb_address *)ext; 838 sa = (struct sockaddr *)(saddr + 1); 839 840 rule->local = calloc(1, sizeof(struct ipsec_addr_wrap)); 841 if (rule->local == NULL) 842 err(1, "pfkey_parse: calloc"); 843 844 rule->local->af = sa->sa_family; 845 switch (sa->sa_family) { 846 case AF_INET: 847 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 848 &rule->local->address.v4, 849 sizeof(struct in_addr)); 850 set_ipmask(rule->local, 32); 851 break; 852 case AF_INET6: 853 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 854 &rule->local->address.v6, 855 sizeof(struct in6_addr)); 856 set_ipmask(rule->local, 128); 857 break; 858 default: 859 return (1); 860 } 861 break; 862 863 864 case SADB_EXT_ADDRESS_DST: 865 saddr = (struct sadb_address *)ext; 866 sa = (struct sockaddr *)(saddr + 1); 867 868 rule->peer = calloc(1, sizeof(struct ipsec_addr_wrap)); 869 if (rule->peer == NULL) 870 err(1, "pfkey_parse: calloc"); 871 872 rule->peer->af = sa->sa_family; 873 switch (sa->sa_family) { 874 case AF_INET: 875 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 876 &rule->peer->address.v4, 877 sizeof(struct in_addr)); 878 set_ipmask(rule->peer, 32); 879 break; 880 case AF_INET6: 881 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 882 &rule->peer->address.v6, 883 sizeof(struct in6_addr)); 884 set_ipmask(rule->peer, 128); 885 break; 886 default: 887 return (1); 888 } 889 break; 890 891 case SADB_EXT_IDENTITY_SRC: 892 sident = (struct sadb_ident *)ext; 893 len = (sident->sadb_ident_len * sizeof(uint64_t)) - 894 sizeof(struct sadb_ident); 895 896 if (rule->auth == NULL) { 897 rule->auth = calloc(1, sizeof(struct 898 ipsec_auth)); 899 if (rule->auth == NULL) 900 err(1, "pfkey_parse: calloc"); 901 } 902 903 rule->auth->srcid = calloc(1, len); 904 if (rule->auth->srcid == NULL) 905 err(1, "pfkey_parse: calloc"); 906 907 strlcpy(rule->auth->srcid, (char *)(sident + 1), len); 908 break; 909 910 case SADB_EXT_IDENTITY_DST: 911 sident = (struct sadb_ident *)ext; 912 len = (sident->sadb_ident_len * sizeof(uint64_t)) - 913 sizeof(struct sadb_ident); 914 915 if (rule->auth == NULL) { 916 rule->auth = calloc(1, sizeof(struct 917 ipsec_auth)); 918 if (rule->auth == NULL) 919 err(1, "pfkey_parse: calloc"); 920 } 921 922 rule->auth->dstid = calloc(1, len); 923 if (rule->auth->dstid == NULL) 924 err(1, "pfkey_parse: calloc"); 925 926 strlcpy(rule->auth->dstid, (char *)(sident + 1), len); 927 break; 928 929 case SADB_X_EXT_PROTOCOL: 930 sproto = (struct sadb_protocol *)ext; 931 if (sproto->sadb_protocol_direction == 0) 932 rule->proto = sproto->sadb_protocol_proto; 933 break; 934 935 case SADB_X_EXT_FLOW_TYPE: 936 sproto = (struct sadb_protocol *)ext; 937 938 switch (sproto->sadb_protocol_direction) { 939 case IPSP_DIRECTION_IN: 940 rule->direction = IPSEC_IN; 941 break; 942 case IPSP_DIRECTION_OUT: 943 rule->direction = IPSEC_OUT; 944 break; 945 default: 946 return (1); 947 } 948 switch (sproto->sadb_protocol_proto) { 949 case SADB_X_FLOW_TYPE_USE: 950 rule->flowtype = TYPE_USE; 951 break; 952 case SADB_X_FLOW_TYPE_ACQUIRE: 953 rule->flowtype = TYPE_ACQUIRE; 954 break; 955 case SADB_X_FLOW_TYPE_REQUIRE: 956 rule->flowtype = TYPE_REQUIRE; 957 break; 958 case SADB_X_FLOW_TYPE_DENY: 959 rule->flowtype = TYPE_DENY; 960 break; 961 case SADB_X_FLOW_TYPE_BYPASS: 962 rule->flowtype = TYPE_BYPASS; 963 break; 964 case SADB_X_FLOW_TYPE_DONTACQ: 965 rule->flowtype = TYPE_DONTACQ; 966 break; 967 default: 968 rule->flowtype = TYPE_UNKNOWN; 969 break; 970 } 971 break; 972 973 case SADB_X_EXT_SRC_FLOW: 974 saddr = (struct sadb_address *)ext; 975 sa = (struct sockaddr *)(saddr + 1); 976 977 if (rule->src == NULL) { 978 rule->src = calloc(1, 979 sizeof(struct ipsec_addr_wrap)); 980 if (rule->src == NULL) 981 err(1, "pfkey_parse: calloc"); 982 } 983 984 rule->src->af = sa->sa_family; 985 switch (sa->sa_family) { 986 case AF_INET: 987 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 988 &rule->src->address.v4, 989 sizeof(struct in_addr)); 990 rule->sport = 991 ((struct sockaddr_in *)sa)->sin_port; 992 break; 993 case AF_INET6: 994 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 995 &rule->src->address.v6, 996 sizeof(struct in6_addr)); 997 rule->sport = 998 ((struct sockaddr_in6 *)sa)->sin6_port; 999 break; 1000 default: 1001 return (1); 1002 } 1003 break; 1004 1005 case SADB_X_EXT_DST_FLOW: 1006 saddr = (struct sadb_address *)ext; 1007 sa = (struct sockaddr *)(saddr + 1); 1008 1009 if (rule->dst == NULL) { 1010 rule->dst = calloc(1, 1011 sizeof(struct ipsec_addr_wrap)); 1012 if (rule->dst == NULL) 1013 err(1, "pfkey_parse: calloc"); 1014 } 1015 1016 rule->dst->af = sa->sa_family; 1017 switch (sa->sa_family) { 1018 case AF_INET: 1019 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 1020 &rule->dst->address.v4, 1021 sizeof(struct in_addr)); 1022 rule->dport = 1023 ((struct sockaddr_in *)sa)->sin_port; 1024 break; 1025 case AF_INET6: 1026 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 1027 &rule->dst->address.v6, 1028 sizeof(struct in6_addr)); 1029 rule->dport = 1030 ((struct sockaddr_in6 *)sa)->sin6_port; 1031 break; 1032 default: 1033 return (1); 1034 } 1035 break; 1036 1037 1038 case SADB_X_EXT_SRC_MASK: 1039 saddr = (struct sadb_address *)ext; 1040 sa = (struct sockaddr *)(saddr + 1); 1041 1042 if (rule->src == NULL) { 1043 rule->src = calloc(1, 1044 sizeof(struct ipsec_addr_wrap)); 1045 if (rule->src == NULL) 1046 err(1, "pfkey_parse: calloc"); 1047 } 1048 1049 rule->src->af = sa->sa_family; 1050 switch (sa->sa_family) { 1051 case AF_INET: 1052 sa_in = (struct sockaddr_in *)sa; 1053 bcopy(&sa_in->sin_addr, &rule->src->mask.v4, 1054 sizeof(struct in_addr)); 1055 break; 1056 case AF_INET6: 1057 sa_in6 = (struct sockaddr_in6 *)sa; 1058 bcopy(&sa_in6->sin6_addr, &rule->src->mask.v6, 1059 sizeof(struct in6_addr)); 1060 break; 1061 1062 default: 1063 return (1); 1064 } 1065 break; 1066 1067 case SADB_X_EXT_DST_MASK: 1068 saddr = (struct sadb_address *)ext; 1069 sa = (struct sockaddr *)(saddr + 1); 1070 1071 if (rule->dst == NULL) { 1072 rule->dst = calloc(1, 1073 sizeof(struct ipsec_addr_wrap)); 1074 if (rule->dst == NULL) 1075 err(1, "pfkey_parse: calloc"); 1076 } 1077 1078 rule->dst->af = sa->sa_family; 1079 switch (sa->sa_family) { 1080 case AF_INET: 1081 sa_in = (struct sockaddr_in *)sa; 1082 bcopy(&sa_in->sin_addr, &rule->dst->mask.v4, 1083 sizeof(struct in_addr)); 1084 break; 1085 case AF_INET6: 1086 sa_in6 = (struct sockaddr_in6 *)sa; 1087 bcopy(&sa_in6->sin6_addr, &rule->dst->mask.v6, 1088 sizeof(struct in6_addr)); 1089 break; 1090 default: 1091 return (1); 1092 } 1093 break; 1094 1095 default: 1096 return (1); 1097 } 1098 } 1099 1100 return (0); 1101 } 1102 1103 int 1104 pfkey_ipsec_establish(int action, struct ipsec_rule *r) 1105 { 1106 int ret; 1107 u_int8_t satype, satype2, direction; 1108 1109 if (r->type == RULE_FLOW) { 1110 switch (r->satype) { 1111 case IPSEC_ESP: 1112 satype = SADB_SATYPE_ESP; 1113 break; 1114 case IPSEC_AH: 1115 satype = SADB_SATYPE_AH; 1116 break; 1117 case IPSEC_IPCOMP: 1118 satype = SADB_X_SATYPE_IPCOMP; 1119 break; 1120 case IPSEC_IPIP: 1121 satype = SADB_X_SATYPE_IPIP; 1122 break; 1123 default: 1124 return -1; 1125 } 1126 1127 switch (r->direction) { 1128 case IPSEC_IN: 1129 direction = IPSP_DIRECTION_IN; 1130 break; 1131 case IPSEC_OUT: 1132 direction = IPSP_DIRECTION_OUT; 1133 break; 1134 default: 1135 return -1; 1136 } 1137 1138 switch (action) { 1139 case ACTION_ADD: 1140 ret = pfkey_flow(fd, satype, SADB_X_ADDFLOW, direction, 1141 r->proto, r->src, r->sport, r->dst, r->dport, 1142 r->local, r->peer, r->auth, r->flowtype); 1143 break; 1144 case ACTION_DELETE: 1145 /* No peer for flow deletion. */ 1146 ret = pfkey_flow(fd, satype, SADB_X_DELFLOW, direction, 1147 r->proto, r->src, r->sport, r->dst, r->dport, 1148 NULL, NULL, NULL, r->flowtype); 1149 break; 1150 default: 1151 return -1; 1152 } 1153 } else if (r->type == RULE_SA) { 1154 switch (r->satype) { 1155 case IPSEC_AH: 1156 satype = SADB_SATYPE_AH; 1157 break; 1158 case IPSEC_ESP: 1159 satype = SADB_SATYPE_ESP; 1160 break; 1161 case IPSEC_IPCOMP: 1162 satype = SADB_X_SATYPE_IPCOMP; 1163 break; 1164 case IPSEC_TCPMD5: 1165 satype = SADB_X_SATYPE_TCPSIGNATURE; 1166 break; 1167 case IPSEC_IPIP: 1168 satype = SADB_X_SATYPE_IPIP; 1169 break; 1170 default: 1171 return -1; 1172 } 1173 switch (action) { 1174 case ACTION_ADD: 1175 ret = pfkey_sa(fd, satype, SADB_ADD, r->spi, 1176 r->src, r->dst, r->xfs, r->authkey, r->enckey, 1177 r->tmode); 1178 break; 1179 case ACTION_DELETE: 1180 ret = pfkey_sa(fd, satype, SADB_DELETE, r->spi, 1181 r->src, r->dst, r->xfs, NULL, NULL, r->tmode); 1182 break; 1183 default: 1184 return -1; 1185 } 1186 } else if (r->type == RULE_GROUP) { 1187 switch (r->satype) { 1188 case IPSEC_AH: 1189 satype = SADB_SATYPE_AH; 1190 break; 1191 case IPSEC_ESP: 1192 satype = SADB_SATYPE_ESP; 1193 break; 1194 case IPSEC_IPCOMP: 1195 satype = SADB_X_SATYPE_IPCOMP; 1196 break; 1197 case IPSEC_TCPMD5: 1198 satype = SADB_X_SATYPE_TCPSIGNATURE; 1199 break; 1200 case IPSEC_IPIP: 1201 satype = SADB_X_SATYPE_IPIP; 1202 break; 1203 default: 1204 return -1; 1205 } 1206 switch (r->proto2) { 1207 case IPSEC_AH: 1208 satype2 = SADB_SATYPE_AH; 1209 break; 1210 case IPSEC_ESP: 1211 satype2 = SADB_SATYPE_ESP; 1212 break; 1213 case IPSEC_IPCOMP: 1214 satype2 = SADB_X_SATYPE_IPCOMP; 1215 break; 1216 case IPSEC_TCPMD5: 1217 satype2 = SADB_X_SATYPE_TCPSIGNATURE; 1218 break; 1219 case IPSEC_IPIP: 1220 satype2 = SADB_X_SATYPE_IPIP; 1221 break; 1222 default: 1223 return -1; 1224 } 1225 switch (action) { 1226 case ACTION_ADD: 1227 ret = pfkey_sagroup(fd, satype, satype2, 1228 SADB_X_GRPSPIS, r->dst, r->spi, r->dst2, r->spi2); 1229 break; 1230 case ACTION_DELETE: 1231 return 0; 1232 default: 1233 return -1; 1234 } 1235 } else 1236 return -1; 1237 1238 if (ret < 0) 1239 return -1; 1240 if (pfkey_reply(fd, NULL, NULL) < 0) 1241 return -1; 1242 1243 return 0; 1244 } 1245 1246 int 1247 pfkey_ipsec_flush(void) 1248 { 1249 struct sadb_msg smsg; 1250 struct iovec iov[IOV_CNT]; 1251 ssize_t n; 1252 int iov_cnt, len; 1253 1254 bzero(&smsg, sizeof(smsg)); 1255 smsg.sadb_msg_version = PF_KEY_V2; 1256 smsg.sadb_msg_seq = sadb_msg_seq++; 1257 smsg.sadb_msg_pid = getpid(); 1258 smsg.sadb_msg_len = sizeof(smsg) / 8; 1259 smsg.sadb_msg_type = SADB_FLUSH; 1260 smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC; 1261 1262 iov_cnt = 0; 1263 1264 iov[iov_cnt].iov_base = &smsg; 1265 iov[iov_cnt].iov_len = sizeof(smsg); 1266 iov_cnt++; 1267 1268 len = smsg.sadb_msg_len * 8; 1269 if ((n = writev(fd, iov, iov_cnt)) == -1) { 1270 warn("writev failed"); 1271 return -1; 1272 } 1273 if (n != len) { 1274 warnx("short write"); 1275 return -1; 1276 } 1277 if (pfkey_reply(fd, NULL, NULL) < 0) 1278 return -1; 1279 1280 return 0; 1281 } 1282 1283 static int 1284 pfkey_promisc(void) 1285 { 1286 struct sadb_msg msg; 1287 1288 memset(&msg, 0, sizeof(msg)); 1289 msg.sadb_msg_version = PF_KEY_V2; 1290 msg.sadb_msg_seq = sadb_msg_seq++; 1291 msg.sadb_msg_pid = getpid(); 1292 msg.sadb_msg_len = sizeof(msg) / PFKEYV2_CHUNK; 1293 msg.sadb_msg_type = SADB_X_PROMISC; 1294 msg.sadb_msg_satype = 1; /* enable */ 1295 if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) { 1296 warn("pfkey_promisc: write failed"); 1297 return -1; 1298 } 1299 if (pfkey_reply(fd, NULL, NULL) < 0) 1300 return -1; 1301 return 0; 1302 } 1303 1304 int 1305 pfkey_monitor(int opts) 1306 { 1307 fd_set *rset; 1308 u_int8_t *data; 1309 struct sadb_msg *msg; 1310 ssize_t len, set_size; 1311 int n; 1312 1313 if (pfkey_init() < 0) 1314 return -1; 1315 if (pfkey_promisc() < 0) 1316 return -1; 1317 1318 set_size = howmany(fd + 1, NFDBITS) * sizeof(fd_mask); 1319 if ((rset = malloc(set_size)) == NULL) { 1320 warn("malloc"); 1321 return -1; 1322 } 1323 for (;;) { 1324 memset(rset, 0, set_size); 1325 FD_SET(fd, rset); 1326 if ((n = select(fd+1, rset, NULL, NULL, NULL)) < 0) 1327 err(2, "select"); 1328 if (n == 0) 1329 break; 1330 if (!FD_ISSET(fd, rset)) 1331 continue; 1332 if (pfkey_reply(fd, &data, &len) < 0) 1333 continue; 1334 msg = (struct sadb_msg *)data; 1335 if (msg->sadb_msg_type == SADB_X_PROMISC) { 1336 /* remove extra header from promisc messages */ 1337 if ((msg->sadb_msg_len * PFKEYV2_CHUNK) >= 1338 2 * sizeof(struct sadb_msg)) { 1339 msg++; 1340 } 1341 } 1342 pfkey_monitor_sa(msg, opts); 1343 if (opts & IPSECCTL_OPT_VERBOSE) 1344 pfkey_print_raw(data, len); 1345 memset(data, 0, len); 1346 free(data); 1347 } 1348 close(fd); 1349 return 0; 1350 } 1351 1352 int 1353 pfkey_init(void) 1354 { 1355 if ((fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) == -1) 1356 err(1, "pfkey_init: failed to open PF_KEY socket"); 1357 1358 return 0; 1359 } 1360