1 /* $OpenBSD: pfkey.c,v 1.53 2012/06/30 14:51:31 naddy 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 case ENCXF_AES_128_CTR: 498 case ENCXF_AES_192_CTR: 499 case ENCXF_AES_256_CTR: 500 sa.sadb_sa_encrypt = SADB_X_EALG_AESCTR; 501 break; 502 case ENCXF_AES_128_GCM: 503 case ENCXF_AES_192_GCM: 504 case ENCXF_AES_256_GCM: 505 sa.sadb_sa_encrypt = SADB_X_EALG_AESGCM16; 506 break; 507 case ENCXF_AES_128_GMAC: 508 case ENCXF_AES_192_GMAC: 509 case ENCXF_AES_256_GMAC: 510 sa.sadb_sa_encrypt = SADB_X_EALG_AESGMAC; 511 break; 512 case ENCXF_BLOWFISH: 513 sa.sadb_sa_encrypt = SADB_X_EALG_BLF; 514 break; 515 case ENCXF_CAST128: 516 sa.sadb_sa_encrypt = SADB_X_EALG_CAST; 517 break; 518 case ENCXF_NULL: 519 sa.sadb_sa_encrypt = SADB_EALG_NULL; 520 break; 521 default: 522 warnx("unsupported encryption algorithm %d", 523 xfs->encxf->id); 524 } 525 } 526 if (xfs && xfs->compxf) { 527 switch (xfs->compxf->id) { 528 case COMPXF_DEFLATE: 529 sa.sadb_sa_encrypt = SADB_X_CALG_DEFLATE; 530 break; 531 case COMPXF_LZS: 532 sa.sadb_sa_encrypt = SADB_X_CALG_LZS; 533 break; 534 default: 535 warnx("unsupported compression algorithm %d", 536 xfs->compxf->id); 537 } 538 } 539 540 bzero(&sa_src, sizeof(sa_src)); 541 sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8; 542 sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 543 544 bzero(&sa_dst, sizeof(sa_dst)); 545 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 546 sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 547 548 if (action == SADB_ADD && !authkey && !enckey && satype != 549 SADB_X_SATYPE_IPCOMP && satype != SADB_X_SATYPE_IPIP) { /* XXX ENCNULL */ 550 warnx("no key specified"); 551 return -1; 552 } 553 if (authkey) { 554 bzero(&sa_authkey, sizeof(sa_authkey)); 555 sa_authkey.sadb_key_len = (sizeof(sa_authkey) + 556 ((authkey->len + 7) / 8) * 8) / 8; 557 sa_authkey.sadb_key_exttype = SADB_EXT_KEY_AUTH; 558 sa_authkey.sadb_key_bits = 8 * authkey->len; 559 } 560 if (enckey) { 561 bzero(&sa_enckey, sizeof(sa_enckey)); 562 sa_enckey.sadb_key_len = (sizeof(sa_enckey) + 563 ((enckey->len + 7) / 8) * 8) / 8; 564 sa_enckey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 565 sa_enckey.sadb_key_bits = 8 * enckey->len; 566 } 567 568 iov_cnt = 0; 569 570 /* header */ 571 iov[iov_cnt].iov_base = &smsg; 572 iov[iov_cnt].iov_len = sizeof(smsg); 573 iov_cnt++; 574 575 /* sa */ 576 iov[iov_cnt].iov_base = &sa; 577 iov[iov_cnt].iov_len = sizeof(sa); 578 smsg.sadb_msg_len += sa.sadb_sa_len; 579 iov_cnt++; 580 581 /* src addr */ 582 iov[iov_cnt].iov_base = &sa_src; 583 iov[iov_cnt].iov_len = sizeof(sa_src); 584 iov_cnt++; 585 iov[iov_cnt].iov_base = &ssrc; 586 iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len); 587 smsg.sadb_msg_len += sa_src.sadb_address_len; 588 iov_cnt++; 589 590 /* dst addr */ 591 iov[iov_cnt].iov_base = &sa_dst; 592 iov[iov_cnt].iov_len = sizeof(sa_dst); 593 iov_cnt++; 594 iov[iov_cnt].iov_base = &sdst; 595 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 596 smsg.sadb_msg_len += sa_dst.sadb_address_len; 597 iov_cnt++; 598 599 if (authkey) { 600 /* authentication key */ 601 iov[iov_cnt].iov_base = &sa_authkey; 602 iov[iov_cnt].iov_len = sizeof(sa_authkey); 603 iov_cnt++; 604 iov[iov_cnt].iov_base = authkey->data; 605 iov[iov_cnt].iov_len = ((authkey->len + 7) / 8) * 8; 606 smsg.sadb_msg_len += sa_authkey.sadb_key_len; 607 iov_cnt++; 608 } 609 if (enckey) { 610 /* encryption key */ 611 iov[iov_cnt].iov_base = &sa_enckey; 612 iov[iov_cnt].iov_len = sizeof(sa_enckey); 613 iov_cnt++; 614 iov[iov_cnt].iov_base = enckey->data; 615 iov[iov_cnt].iov_len = ((enckey->len + 7) / 8) * 8; 616 smsg.sadb_msg_len += sa_enckey.sadb_key_len; 617 iov_cnt++; 618 } 619 620 len = smsg.sadb_msg_len * 8; 621 if ((n = writev(sd, iov, iov_cnt)) == -1) { 622 warn("writev failed"); 623 ret = -1; 624 } else if (n != len) { 625 warnx("short write"); 626 ret = -1; 627 } 628 629 return ret; 630 } 631 632 static int 633 pfkey_sagroup(int sd, u_int8_t satype, u_int8_t satype2, u_int8_t action, 634 struct ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_addr_wrap *dst2, 635 u_int32_t spi2) 636 { 637 struct sadb_msg smsg; 638 struct sadb_sa sa1, sa2; 639 struct sadb_address sa_dst, sa_dst2; 640 struct sockaddr_storage sdst, sdst2; 641 struct sadb_protocol sa_proto; 642 struct iovec iov[IOV_CNT]; 643 ssize_t n; 644 int iov_cnt, len, ret = 0; 645 646 bzero(&sdst, sizeof(sdst)); 647 sdst.ss_family = dst->af; 648 switch (dst->af) { 649 case AF_INET: 650 ((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4; 651 sdst.ss_len = sizeof(struct sockaddr_in); 652 break; 653 case AF_INET6: 654 ((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6; 655 sdst.ss_len = sizeof(struct sockaddr_in6); 656 break; 657 default: 658 warnx("unsupported address family %d", dst->af); 659 return -1; 660 } 661 662 bzero(&sdst2, sizeof(sdst2)); 663 sdst2.ss_family = dst2->af; 664 switch (dst2->af) { 665 case AF_INET: 666 ((struct sockaddr_in *)&sdst2)->sin_addr = dst2->address.v4; 667 sdst2.ss_len = sizeof(struct sockaddr_in); 668 break; 669 case AF_INET6: 670 ((struct sockaddr_in6 *)&sdst2)->sin6_addr = dst2->address.v6; 671 sdst2.ss_len = sizeof(struct sockaddr_in6); 672 break; 673 default: 674 warnx("unsupported address family %d", dst2->af); 675 return -1; 676 } 677 678 bzero(&smsg, sizeof(smsg)); 679 smsg.sadb_msg_version = PF_KEY_V2; 680 smsg.sadb_msg_seq = sadb_msg_seq++; 681 smsg.sadb_msg_pid = getpid(); 682 smsg.sadb_msg_len = sizeof(smsg) / 8; 683 smsg.sadb_msg_type = action; 684 smsg.sadb_msg_satype = satype; 685 686 bzero(&sa1, sizeof(sa1)); 687 sa1.sadb_sa_len = sizeof(sa1) / 8; 688 sa1.sadb_sa_exttype = SADB_EXT_SA; 689 sa1.sadb_sa_spi = htonl(spi); 690 sa1.sadb_sa_state = SADB_SASTATE_MATURE; 691 692 bzero(&sa2, sizeof(sa2)); 693 sa2.sadb_sa_len = sizeof(sa2) / 8; 694 sa2.sadb_sa_exttype = SADB_X_EXT_SA2; 695 sa2.sadb_sa_spi = htonl(spi2); 696 sa2.sadb_sa_state = SADB_SASTATE_MATURE; 697 iov_cnt = 0; 698 699 bzero(&sa_dst, sizeof(sa_dst)); 700 sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 701 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 702 703 bzero(&sa_dst2, sizeof(sa_dst2)); 704 sa_dst2.sadb_address_exttype = SADB_X_EXT_DST2; 705 sa_dst2.sadb_address_len = (sizeof(sa_dst2) + ROUNDUP(sdst2.ss_len)) / 8; 706 707 bzero(&sa_proto, sizeof(sa_proto)); 708 sa_proto.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; 709 sa_proto.sadb_protocol_len = sizeof(sa_proto) / 8; 710 sa_proto.sadb_protocol_direction = 0; 711 sa_proto.sadb_protocol_proto = satype2; 712 713 /* header */ 714 iov[iov_cnt].iov_base = &smsg; 715 iov[iov_cnt].iov_len = sizeof(smsg); 716 iov_cnt++; 717 718 /* sa */ 719 iov[iov_cnt].iov_base = &sa1; 720 iov[iov_cnt].iov_len = sizeof(sa1); 721 smsg.sadb_msg_len += sa1.sadb_sa_len; 722 iov_cnt++; 723 724 /* dst addr */ 725 iov[iov_cnt].iov_base = &sa_dst; 726 iov[iov_cnt].iov_len = sizeof(sa_dst); 727 iov_cnt++; 728 iov[iov_cnt].iov_base = &sdst; 729 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 730 smsg.sadb_msg_len += sa_dst.sadb_address_len; 731 iov_cnt++; 732 733 /* second sa */ 734 iov[iov_cnt].iov_base = &sa2; 735 iov[iov_cnt].iov_len = sizeof(sa2); 736 smsg.sadb_msg_len += sa2.sadb_sa_len; 737 iov_cnt++; 738 739 /* second dst addr */ 740 iov[iov_cnt].iov_base = &sa_dst2; 741 iov[iov_cnt].iov_len = sizeof(sa_dst2); 742 iov_cnt++; 743 iov[iov_cnt].iov_base = &sdst2; 744 iov[iov_cnt].iov_len = ROUNDUP(sdst2.ss_len); 745 smsg.sadb_msg_len += sa_dst2.sadb_address_len; 746 iov_cnt++; 747 748 /* SA type */ 749 iov[iov_cnt].iov_base = &sa_proto; 750 iov[iov_cnt].iov_len = sizeof(sa_proto); 751 smsg.sadb_msg_len += sa_proto.sadb_protocol_len; 752 iov_cnt++; 753 754 len = smsg.sadb_msg_len * 8; 755 if ((n = writev(sd, iov, iov_cnt)) == -1) { 756 warn("writev failed"); 757 ret = -1; 758 } else if (n != len) { 759 warnx("short write"); 760 ret = -1; 761 } 762 763 return (ret); 764 } 765 766 static int 767 pfkey_reply(int sd, u_int8_t **datap, ssize_t *lenp) 768 { 769 struct sadb_msg hdr; 770 ssize_t len; 771 u_int8_t *data; 772 773 if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) { 774 warnx("short read"); 775 return -1; 776 } 777 len = hdr.sadb_msg_len * PFKEYV2_CHUNK; 778 if ((data = malloc(len)) == NULL) 779 err(1, "pfkey_reply: malloc"); 780 if (read(sd, data, len) != len) { 781 warn("PF_KEY short read"); 782 bzero(data, len); 783 free(data); 784 return -1; 785 } 786 if (datap) { 787 *datap = data; 788 if (lenp) 789 *lenp = len; 790 } else { 791 bzero(data, len); 792 free(data); 793 } 794 if (datap == NULL && hdr.sadb_msg_errno != 0) { 795 errno = hdr.sadb_msg_errno; 796 if (errno != EEXIST) { 797 warn("PF_KEY failed"); 798 return -1; 799 } 800 } 801 return 0; 802 } 803 804 int 805 pfkey_parse(struct sadb_msg *msg, struct ipsec_rule *rule) 806 { 807 struct sadb_ext *ext; 808 struct sadb_address *saddr; 809 struct sadb_protocol *sproto; 810 struct sadb_ident *sident; 811 struct sockaddr *sa; 812 struct sockaddr_in *sa_in; 813 struct sockaddr_in6 *sa_in6; 814 int len; 815 816 switch (msg->sadb_msg_satype) { 817 case SADB_SATYPE_ESP: 818 rule->satype = IPSEC_ESP; 819 break; 820 case SADB_SATYPE_AH: 821 rule->satype = IPSEC_AH; 822 break; 823 case SADB_X_SATYPE_IPCOMP: 824 rule->satype = IPSEC_IPCOMP; 825 break; 826 case SADB_X_SATYPE_IPIP: 827 rule->satype = IPSEC_IPIP; 828 break; 829 default: 830 return (1); 831 } 832 833 for (ext = (struct sadb_ext *)(msg + 1); 834 (size_t)((u_int8_t *)ext - (u_int8_t *)msg) < 835 msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0; 836 ext = (struct sadb_ext *)((u_int8_t *)ext + 837 ext->sadb_ext_len * PFKEYV2_CHUNK)) { 838 switch (ext->sadb_ext_type) { 839 case SADB_EXT_ADDRESS_SRC: 840 saddr = (struct sadb_address *)ext; 841 sa = (struct sockaddr *)(saddr + 1); 842 843 rule->local = calloc(1, sizeof(struct ipsec_addr_wrap)); 844 if (rule->local == NULL) 845 err(1, "pfkey_parse: calloc"); 846 847 rule->local->af = sa->sa_family; 848 switch (sa->sa_family) { 849 case AF_INET: 850 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 851 &rule->local->address.v4, 852 sizeof(struct in_addr)); 853 set_ipmask(rule->local, 32); 854 break; 855 case AF_INET6: 856 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 857 &rule->local->address.v6, 858 sizeof(struct in6_addr)); 859 set_ipmask(rule->local, 128); 860 break; 861 default: 862 return (1); 863 } 864 break; 865 866 867 case SADB_EXT_ADDRESS_DST: 868 saddr = (struct sadb_address *)ext; 869 sa = (struct sockaddr *)(saddr + 1); 870 871 rule->peer = calloc(1, sizeof(struct ipsec_addr_wrap)); 872 if (rule->peer == NULL) 873 err(1, "pfkey_parse: calloc"); 874 875 rule->peer->af = sa->sa_family; 876 switch (sa->sa_family) { 877 case AF_INET: 878 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 879 &rule->peer->address.v4, 880 sizeof(struct in_addr)); 881 set_ipmask(rule->peer, 32); 882 break; 883 case AF_INET6: 884 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 885 &rule->peer->address.v6, 886 sizeof(struct in6_addr)); 887 set_ipmask(rule->peer, 128); 888 break; 889 default: 890 return (1); 891 } 892 break; 893 894 case SADB_EXT_IDENTITY_SRC: 895 sident = (struct sadb_ident *)ext; 896 len = (sident->sadb_ident_len * sizeof(uint64_t)) - 897 sizeof(struct sadb_ident); 898 899 if (rule->auth == NULL) { 900 rule->auth = calloc(1, sizeof(struct 901 ipsec_auth)); 902 if (rule->auth == NULL) 903 err(1, "pfkey_parse: calloc"); 904 } 905 906 rule->auth->srcid = calloc(1, len); 907 if (rule->auth->srcid == NULL) 908 err(1, "pfkey_parse: calloc"); 909 910 strlcpy(rule->auth->srcid, (char *)(sident + 1), len); 911 break; 912 913 case SADB_EXT_IDENTITY_DST: 914 sident = (struct sadb_ident *)ext; 915 len = (sident->sadb_ident_len * sizeof(uint64_t)) - 916 sizeof(struct sadb_ident); 917 918 if (rule->auth == NULL) { 919 rule->auth = calloc(1, sizeof(struct 920 ipsec_auth)); 921 if (rule->auth == NULL) 922 err(1, "pfkey_parse: calloc"); 923 } 924 925 rule->auth->dstid = calloc(1, len); 926 if (rule->auth->dstid == NULL) 927 err(1, "pfkey_parse: calloc"); 928 929 strlcpy(rule->auth->dstid, (char *)(sident + 1), len); 930 break; 931 932 case SADB_X_EXT_PROTOCOL: 933 sproto = (struct sadb_protocol *)ext; 934 if (sproto->sadb_protocol_direction == 0) 935 rule->proto = sproto->sadb_protocol_proto; 936 break; 937 938 case SADB_X_EXT_FLOW_TYPE: 939 sproto = (struct sadb_protocol *)ext; 940 941 switch (sproto->sadb_protocol_direction) { 942 case IPSP_DIRECTION_IN: 943 rule->direction = IPSEC_IN; 944 break; 945 case IPSP_DIRECTION_OUT: 946 rule->direction = IPSEC_OUT; 947 break; 948 default: 949 return (1); 950 } 951 switch (sproto->sadb_protocol_proto) { 952 case SADB_X_FLOW_TYPE_USE: 953 rule->flowtype = TYPE_USE; 954 break; 955 case SADB_X_FLOW_TYPE_ACQUIRE: 956 rule->flowtype = TYPE_ACQUIRE; 957 break; 958 case SADB_X_FLOW_TYPE_REQUIRE: 959 rule->flowtype = TYPE_REQUIRE; 960 break; 961 case SADB_X_FLOW_TYPE_DENY: 962 rule->flowtype = TYPE_DENY; 963 break; 964 case SADB_X_FLOW_TYPE_BYPASS: 965 rule->flowtype = TYPE_BYPASS; 966 break; 967 case SADB_X_FLOW_TYPE_DONTACQ: 968 rule->flowtype = TYPE_DONTACQ; 969 break; 970 default: 971 rule->flowtype = TYPE_UNKNOWN; 972 break; 973 } 974 break; 975 976 case SADB_X_EXT_SRC_FLOW: 977 saddr = (struct sadb_address *)ext; 978 sa = (struct sockaddr *)(saddr + 1); 979 980 if (rule->src == NULL) { 981 rule->src = calloc(1, 982 sizeof(struct ipsec_addr_wrap)); 983 if (rule->src == NULL) 984 err(1, "pfkey_parse: calloc"); 985 } 986 987 rule->src->af = sa->sa_family; 988 switch (sa->sa_family) { 989 case AF_INET: 990 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 991 &rule->src->address.v4, 992 sizeof(struct in_addr)); 993 rule->sport = 994 ((struct sockaddr_in *)sa)->sin_port; 995 break; 996 case AF_INET6: 997 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 998 &rule->src->address.v6, 999 sizeof(struct in6_addr)); 1000 rule->sport = 1001 ((struct sockaddr_in6 *)sa)->sin6_port; 1002 break; 1003 default: 1004 return (1); 1005 } 1006 break; 1007 1008 case SADB_X_EXT_DST_FLOW: 1009 saddr = (struct sadb_address *)ext; 1010 sa = (struct sockaddr *)(saddr + 1); 1011 1012 if (rule->dst == NULL) { 1013 rule->dst = calloc(1, 1014 sizeof(struct ipsec_addr_wrap)); 1015 if (rule->dst == NULL) 1016 err(1, "pfkey_parse: calloc"); 1017 } 1018 1019 rule->dst->af = sa->sa_family; 1020 switch (sa->sa_family) { 1021 case AF_INET: 1022 bcopy(&((struct sockaddr_in *)sa)->sin_addr, 1023 &rule->dst->address.v4, 1024 sizeof(struct in_addr)); 1025 rule->dport = 1026 ((struct sockaddr_in *)sa)->sin_port; 1027 break; 1028 case AF_INET6: 1029 bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr, 1030 &rule->dst->address.v6, 1031 sizeof(struct in6_addr)); 1032 rule->dport = 1033 ((struct sockaddr_in6 *)sa)->sin6_port; 1034 break; 1035 default: 1036 return (1); 1037 } 1038 break; 1039 1040 1041 case SADB_X_EXT_SRC_MASK: 1042 saddr = (struct sadb_address *)ext; 1043 sa = (struct sockaddr *)(saddr + 1); 1044 1045 if (rule->src == NULL) { 1046 rule->src = calloc(1, 1047 sizeof(struct ipsec_addr_wrap)); 1048 if (rule->src == NULL) 1049 err(1, "pfkey_parse: calloc"); 1050 } 1051 1052 rule->src->af = sa->sa_family; 1053 switch (sa->sa_family) { 1054 case AF_INET: 1055 sa_in = (struct sockaddr_in *)sa; 1056 bcopy(&sa_in->sin_addr, &rule->src->mask.v4, 1057 sizeof(struct in_addr)); 1058 break; 1059 case AF_INET6: 1060 sa_in6 = (struct sockaddr_in6 *)sa; 1061 bcopy(&sa_in6->sin6_addr, &rule->src->mask.v6, 1062 sizeof(struct in6_addr)); 1063 break; 1064 1065 default: 1066 return (1); 1067 } 1068 break; 1069 1070 case SADB_X_EXT_DST_MASK: 1071 saddr = (struct sadb_address *)ext; 1072 sa = (struct sockaddr *)(saddr + 1); 1073 1074 if (rule->dst == NULL) { 1075 rule->dst = calloc(1, 1076 sizeof(struct ipsec_addr_wrap)); 1077 if (rule->dst == NULL) 1078 err(1, "pfkey_parse: calloc"); 1079 } 1080 1081 rule->dst->af = sa->sa_family; 1082 switch (sa->sa_family) { 1083 case AF_INET: 1084 sa_in = (struct sockaddr_in *)sa; 1085 bcopy(&sa_in->sin_addr, &rule->dst->mask.v4, 1086 sizeof(struct in_addr)); 1087 break; 1088 case AF_INET6: 1089 sa_in6 = (struct sockaddr_in6 *)sa; 1090 bcopy(&sa_in6->sin6_addr, &rule->dst->mask.v6, 1091 sizeof(struct in6_addr)); 1092 break; 1093 default: 1094 return (1); 1095 } 1096 break; 1097 1098 default: 1099 return (1); 1100 } 1101 } 1102 1103 return (0); 1104 } 1105 1106 int 1107 pfkey_ipsec_establish(int action, struct ipsec_rule *r) 1108 { 1109 int ret; 1110 u_int8_t satype, satype2, direction; 1111 1112 if (r->type == RULE_FLOW) { 1113 switch (r->satype) { 1114 case IPSEC_ESP: 1115 satype = SADB_SATYPE_ESP; 1116 break; 1117 case IPSEC_AH: 1118 satype = SADB_SATYPE_AH; 1119 break; 1120 case IPSEC_IPCOMP: 1121 satype = SADB_X_SATYPE_IPCOMP; 1122 break; 1123 case IPSEC_IPIP: 1124 satype = SADB_X_SATYPE_IPIP; 1125 break; 1126 default: 1127 return -1; 1128 } 1129 1130 switch (r->direction) { 1131 case IPSEC_IN: 1132 direction = IPSP_DIRECTION_IN; 1133 break; 1134 case IPSEC_OUT: 1135 direction = IPSP_DIRECTION_OUT; 1136 break; 1137 default: 1138 return -1; 1139 } 1140 1141 switch (action) { 1142 case ACTION_ADD: 1143 ret = pfkey_flow(fd, satype, SADB_X_ADDFLOW, direction, 1144 r->proto, r->src, r->sport, r->dst, r->dport, 1145 r->local, r->peer, r->auth, r->flowtype); 1146 break; 1147 case ACTION_DELETE: 1148 /* No peer for flow deletion. */ 1149 ret = pfkey_flow(fd, satype, SADB_X_DELFLOW, direction, 1150 r->proto, r->src, r->sport, r->dst, r->dport, 1151 NULL, NULL, NULL, r->flowtype); 1152 break; 1153 default: 1154 return -1; 1155 } 1156 } else if (r->type == RULE_SA) { 1157 switch (r->satype) { 1158 case IPSEC_AH: 1159 satype = SADB_SATYPE_AH; 1160 break; 1161 case IPSEC_ESP: 1162 satype = SADB_SATYPE_ESP; 1163 break; 1164 case IPSEC_IPCOMP: 1165 satype = SADB_X_SATYPE_IPCOMP; 1166 break; 1167 case IPSEC_TCPMD5: 1168 satype = SADB_X_SATYPE_TCPSIGNATURE; 1169 break; 1170 case IPSEC_IPIP: 1171 satype = SADB_X_SATYPE_IPIP; 1172 break; 1173 default: 1174 return -1; 1175 } 1176 switch (action) { 1177 case ACTION_ADD: 1178 ret = pfkey_sa(fd, satype, SADB_ADD, r->spi, 1179 r->src, r->dst, r->xfs, r->authkey, r->enckey, 1180 r->tmode); 1181 break; 1182 case ACTION_DELETE: 1183 ret = pfkey_sa(fd, satype, SADB_DELETE, r->spi, 1184 r->src, r->dst, r->xfs, NULL, NULL, r->tmode); 1185 break; 1186 default: 1187 return -1; 1188 } 1189 } else if (r->type == RULE_GROUP) { 1190 switch (r->satype) { 1191 case IPSEC_AH: 1192 satype = SADB_SATYPE_AH; 1193 break; 1194 case IPSEC_ESP: 1195 satype = SADB_SATYPE_ESP; 1196 break; 1197 case IPSEC_IPCOMP: 1198 satype = SADB_X_SATYPE_IPCOMP; 1199 break; 1200 case IPSEC_TCPMD5: 1201 satype = SADB_X_SATYPE_TCPSIGNATURE; 1202 break; 1203 case IPSEC_IPIP: 1204 satype = SADB_X_SATYPE_IPIP; 1205 break; 1206 default: 1207 return -1; 1208 } 1209 switch (r->proto2) { 1210 case IPSEC_AH: 1211 satype2 = SADB_SATYPE_AH; 1212 break; 1213 case IPSEC_ESP: 1214 satype2 = SADB_SATYPE_ESP; 1215 break; 1216 case IPSEC_IPCOMP: 1217 satype2 = SADB_X_SATYPE_IPCOMP; 1218 break; 1219 case IPSEC_TCPMD5: 1220 satype2 = SADB_X_SATYPE_TCPSIGNATURE; 1221 break; 1222 case IPSEC_IPIP: 1223 satype2 = SADB_X_SATYPE_IPIP; 1224 break; 1225 default: 1226 return -1; 1227 } 1228 switch (action) { 1229 case ACTION_ADD: 1230 ret = pfkey_sagroup(fd, satype, satype2, 1231 SADB_X_GRPSPIS, r->dst, r->spi, r->dst2, r->spi2); 1232 break; 1233 case ACTION_DELETE: 1234 return 0; 1235 default: 1236 return -1; 1237 } 1238 } else 1239 return -1; 1240 1241 if (ret < 0) 1242 return -1; 1243 if (pfkey_reply(fd, NULL, NULL) < 0) 1244 return -1; 1245 1246 return 0; 1247 } 1248 1249 int 1250 pfkey_ipsec_flush(void) 1251 { 1252 struct sadb_msg smsg; 1253 struct iovec iov[IOV_CNT]; 1254 ssize_t n; 1255 int iov_cnt, len; 1256 1257 bzero(&smsg, sizeof(smsg)); 1258 smsg.sadb_msg_version = PF_KEY_V2; 1259 smsg.sadb_msg_seq = sadb_msg_seq++; 1260 smsg.sadb_msg_pid = getpid(); 1261 smsg.sadb_msg_len = sizeof(smsg) / 8; 1262 smsg.sadb_msg_type = SADB_FLUSH; 1263 smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC; 1264 1265 iov_cnt = 0; 1266 1267 iov[iov_cnt].iov_base = &smsg; 1268 iov[iov_cnt].iov_len = sizeof(smsg); 1269 iov_cnt++; 1270 1271 len = smsg.sadb_msg_len * 8; 1272 if ((n = writev(fd, iov, iov_cnt)) == -1) { 1273 warn("writev failed"); 1274 return -1; 1275 } 1276 if (n != len) { 1277 warnx("short write"); 1278 return -1; 1279 } 1280 if (pfkey_reply(fd, NULL, NULL) < 0) 1281 return -1; 1282 1283 return 0; 1284 } 1285 1286 static int 1287 pfkey_promisc(void) 1288 { 1289 struct sadb_msg msg; 1290 1291 memset(&msg, 0, sizeof(msg)); 1292 msg.sadb_msg_version = PF_KEY_V2; 1293 msg.sadb_msg_seq = sadb_msg_seq++; 1294 msg.sadb_msg_pid = getpid(); 1295 msg.sadb_msg_len = sizeof(msg) / PFKEYV2_CHUNK; 1296 msg.sadb_msg_type = SADB_X_PROMISC; 1297 msg.sadb_msg_satype = 1; /* enable */ 1298 if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) { 1299 warn("pfkey_promisc: write failed"); 1300 return -1; 1301 } 1302 if (pfkey_reply(fd, NULL, NULL) < 0) 1303 return -1; 1304 return 0; 1305 } 1306 1307 int 1308 pfkey_monitor(int opts) 1309 { 1310 fd_set *rset; 1311 u_int8_t *data; 1312 struct sadb_msg *msg; 1313 ssize_t len, set_size; 1314 int n; 1315 1316 if (pfkey_init() < 0) 1317 return -1; 1318 if (pfkey_promisc() < 0) 1319 return -1; 1320 1321 set_size = howmany(fd + 1, NFDBITS) * sizeof(fd_mask); 1322 if ((rset = malloc(set_size)) == NULL) { 1323 warn("malloc"); 1324 return -1; 1325 } 1326 for (;;) { 1327 memset(rset, 0, set_size); 1328 FD_SET(fd, rset); 1329 if ((n = select(fd+1, rset, NULL, NULL, NULL)) < 0) 1330 err(2, "select"); 1331 if (n == 0) 1332 break; 1333 if (!FD_ISSET(fd, rset)) 1334 continue; 1335 if (pfkey_reply(fd, &data, &len) < 0) 1336 continue; 1337 msg = (struct sadb_msg *)data; 1338 if (msg->sadb_msg_type == SADB_X_PROMISC) { 1339 /* remove extra header from promisc messages */ 1340 if ((msg->sadb_msg_len * PFKEYV2_CHUNK) >= 1341 2 * sizeof(struct sadb_msg)) { 1342 msg++; 1343 } 1344 } 1345 pfkey_monitor_sa(msg, opts); 1346 if (opts & IPSECCTL_OPT_VERBOSE) 1347 pfkey_print_raw(data, len); 1348 memset(data, 0, len); 1349 free(data); 1350 } 1351 close(fd); 1352 free(rset); 1353 return 0; 1354 } 1355 1356 int 1357 pfkey_init(void) 1358 { 1359 if ((fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) == -1) 1360 err(1, "pfkey_init: failed to open PF_KEY socket"); 1361 1362 return 0; 1363 } 1364