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