1 /* $OpenBSD: util.c,v 1.25 2014/02/21 20:52:38 markus Exp $ */ 2 3 /* 4 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/socket.h> 22 #include <sys/uio.h> 23 24 #include <netdb.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include <string.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <ctype.h> 32 #include <event.h> 33 34 #include "iked.h" 35 #include "ikev2.h" 36 37 void 38 socket_set_blockmode(int fd, enum blockmodes bm) 39 { 40 int flags; 41 42 if ((flags = fcntl(fd, F_GETFL, 0)) == -1) 43 fatal("fcntl F_GETFL"); 44 45 if (bm == BM_NONBLOCK) 46 flags |= O_NONBLOCK; 47 else 48 flags &= ~O_NONBLOCK; 49 50 if ((flags = fcntl(fd, F_SETFL, flags)) == -1) 51 fatal("fcntl F_SETFL"); 52 } 53 54 int 55 socket_af(struct sockaddr *sa, in_port_t port) 56 { 57 errno = 0; 58 switch (sa->sa_family) { 59 case AF_INET: 60 ((struct sockaddr_in *)sa)->sin_port = port; 61 ((struct sockaddr_in *)sa)->sin_len = 62 sizeof(struct sockaddr_in); 63 break; 64 case AF_INET6: 65 ((struct sockaddr_in6 *)sa)->sin6_port = port; 66 ((struct sockaddr_in6 *)sa)->sin6_len = 67 sizeof(struct sockaddr_in6); 68 break; 69 default: 70 errno = EPFNOSUPPORT; 71 return (-1); 72 } 73 74 return (0); 75 } 76 77 in_port_t 78 socket_getport(struct sockaddr *sa) 79 { 80 switch (sa->sa_family) { 81 case AF_INET: 82 return (ntohs(((struct sockaddr_in *)sa)->sin_port)); 83 case AF_INET6: 84 return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); 85 default: 86 return (0); 87 } 88 89 /* NOTREACHED */ 90 return (0); 91 } 92 93 int 94 socket_setport(struct sockaddr *sa, in_port_t port) 95 { 96 switch (sa->sa_family) { 97 case AF_INET: 98 ((struct sockaddr_in *)sa)->sin_port = htons(port); 99 break; 100 case AF_INET6: 101 ((struct sockaddr_in6 *)sa)->sin6_port = htons(port); 102 break; 103 default: 104 return (-1); 105 } 106 return (0); 107 } 108 109 int 110 socket_getaddr(int s, struct sockaddr_storage *ss) 111 { 112 socklen_t sslen; 113 114 return (getsockname(s, (struct sockaddr *)ss, &sslen)); 115 } 116 117 int 118 socket_bypass(int s, struct sockaddr *sa) 119 { 120 int v, *a; 121 int a4[] = { 122 IPPROTO_IP, 123 IP_AUTH_LEVEL, 124 IP_ESP_TRANS_LEVEL, 125 IP_ESP_NETWORK_LEVEL, 126 #ifdef IPV6_IPCOMP_LEVEL 127 IP_IPCOMP_LEVEL 128 #endif 129 }; 130 int a6[] = { 131 IPPROTO_IPV6, 132 IPV6_AUTH_LEVEL, 133 IPV6_ESP_TRANS_LEVEL, 134 IPV6_ESP_NETWORK_LEVEL, 135 #ifdef IPV6_IPCOMP_LEVEL 136 IPV6_IPCOMP_LEVEL 137 #endif 138 }; 139 140 switch (sa->sa_family) { 141 case AF_INET: 142 a = a4; 143 break; 144 case AF_INET6: 145 a = a6; 146 break; 147 default: 148 log_warn("%s: invalid address family", __func__); 149 return (-1); 150 } 151 152 v = IPSEC_LEVEL_BYPASS; 153 if (setsockopt(s, a[0], a[1], &v, sizeof(v)) == -1) { 154 log_warn("%s: AUTH_LEVEL", __func__); 155 return (-1); 156 } 157 if (setsockopt(s, a[0], a[2], &v, sizeof(v)) == -1) { 158 log_warn("%s: ESP_TRANS_LEVEL", __func__); 159 return (-1); 160 } 161 if (setsockopt(s, a[0], a[3], &v, sizeof(v)) == -1) { 162 log_warn("%s: ESP_NETWORK_LEVEL", __func__); 163 return (-1); 164 } 165 #ifdef IP_IPCOMP_LEVEL 166 if (setsockopt(s, a[0], a[4], &v, sizeof(v)) == -1) { 167 log_warn("%s: IPCOMP_LEVEL", __func__); 168 return (-1); 169 } 170 #endif 171 172 return (0); 173 } 174 175 int 176 udp_bind(struct sockaddr *sa, in_port_t port) 177 { 178 int s, val; 179 180 if (socket_af(sa, port) == -1) { 181 log_warn("%s: failed to set UDP port", __func__); 182 return (-1); 183 } 184 185 if ((s = socket(sa->sa_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) { 186 log_warn("%s: failed to get UDP socket", __func__); 187 return (-1); 188 } 189 190 /* Skip IPsec processing (don't encrypt) for IKE messages */ 191 if (socket_bypass(s, sa) == -1) { 192 log_warn("%s: failed to bypass IPsec on IKE socket", 193 __func__); 194 goto bad; 195 } 196 197 val = 1; 198 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) { 199 log_warn("%s: failed to set reuseport", __func__); 200 goto bad; 201 } 202 val = 1; 203 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) { 204 log_warn("%s: failed to set reuseaddr", __func__); 205 goto bad; 206 } 207 208 if (sa->sa_family == AF_INET) { 209 val = 1; 210 if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, 211 &val, sizeof(int)) == -1) { 212 log_warn("%s: failed to set IPv4 packet info", 213 __func__); 214 goto bad; 215 } 216 } else { 217 val = 1; 218 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 219 &val, sizeof(int)) == -1) { 220 log_warn("%s: failed to set IPv6 packet info", 221 __func__); 222 goto bad; 223 } 224 } 225 226 if (bind(s, sa, sa->sa_len) == -1) { 227 log_warn("%s: failed to bind UDP socket", __func__); 228 goto bad; 229 } 230 231 return (s); 232 bad: 233 close(s); 234 return (-1); 235 } 236 237 int 238 sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen) 239 { 240 struct sockaddr_in *a4, *b4; 241 struct sockaddr_in6 *a6, *b6; 242 u_int32_t av[4], bv[4], mv[4]; 243 244 if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC) 245 return (0); 246 else if (a->sa_family > b->sa_family) 247 return (1); 248 else if (a->sa_family < b->sa_family) 249 return (-1); 250 251 if (prefixlen == -1) 252 memset(&mv, 0xff, sizeof(mv)); 253 254 switch (a->sa_family) { 255 case AF_INET: 256 a4 = (struct sockaddr_in *)a; 257 b4 = (struct sockaddr_in *)b; 258 259 av[0] = a4->sin_addr.s_addr; 260 bv[0] = b4->sin_addr.s_addr; 261 if (prefixlen != -1) 262 mv[0] = prefixlen2mask(prefixlen); 263 264 if ((av[0] & mv[0]) > (bv[0] & mv[0])) 265 return (1); 266 if ((av[0] & mv[0]) < (bv[0] & mv[0])) 267 return (-1); 268 break; 269 case AF_INET6: 270 a6 = (struct sockaddr_in6 *)a; 271 b6 = (struct sockaddr_in6 *)b; 272 273 memcpy(&av, &a6->sin6_addr.s6_addr, 16); 274 memcpy(&bv, &b6->sin6_addr.s6_addr, 16); 275 if (prefixlen != -1) 276 prefixlen2mask6(prefixlen, mv); 277 278 if ((av[3] & mv[3]) > (bv[3] & mv[3])) 279 return (1); 280 if ((av[3] & mv[3]) < (bv[3] & mv[3])) 281 return (-1); 282 if ((av[2] & mv[2]) > (bv[2] & mv[2])) 283 return (1); 284 if ((av[2] & mv[2]) < (bv[2] & mv[2])) 285 return (-1); 286 if ((av[1] & mv[1]) > (bv[1] & mv[1])) 287 return (1); 288 if ((av[1] & mv[1]) < (bv[1] & mv[1])) 289 return (-1); 290 if ((av[0] & mv[0]) > (bv[0] & mv[0])) 291 return (1); 292 if ((av[0] & mv[0]) < (bv[0] & mv[0])) 293 return (-1); 294 break; 295 } 296 297 return (0); 298 } 299 300 ssize_t 301 recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from, 302 socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen) 303 { 304 struct iovec iov; 305 struct msghdr msg; 306 struct cmsghdr *cmsg; 307 struct in6_pktinfo *pkt6; 308 struct sockaddr_in *in; 309 struct sockaddr_in6 *in6; 310 ssize_t ret; 311 union { 312 struct cmsghdr hdr; 313 char buf[CMSG_SPACE(sizeof(struct sockaddr_storage))]; 314 } cmsgbuf; 315 316 bzero(&msg, sizeof(msg)); 317 bzero(&cmsgbuf.buf, sizeof(cmsgbuf.buf)); 318 319 iov.iov_base = buf; 320 iov.iov_len = len; 321 msg.msg_iov = &iov; 322 msg.msg_iovlen = 1; 323 msg.msg_name = from; 324 msg.msg_namelen = *fromlen; 325 msg.msg_control = &cmsgbuf.buf; 326 msg.msg_controllen = sizeof(cmsgbuf.buf); 327 328 if ((ret = recvmsg(s, &msg, 0)) == -1) 329 return (-1); 330 331 *fromlen = from->sa_len; 332 *tolen = 0; 333 334 if (getsockname(s, to, tolen) != 0) 335 *tolen = 0; 336 337 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 338 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 339 switch (from->sa_family) { 340 case AF_INET: 341 if (cmsg->cmsg_level == IPPROTO_IP && 342 cmsg->cmsg_type == IP_RECVDSTADDR) { 343 in = (struct sockaddr_in *)to; 344 in->sin_family = AF_INET; 345 in->sin_len = *tolen = sizeof(*in); 346 memcpy(&in->sin_addr, CMSG_DATA(cmsg), 347 sizeof(struct in_addr)); 348 } 349 break; 350 case AF_INET6: 351 if (cmsg->cmsg_level == IPPROTO_IPV6 && 352 cmsg->cmsg_type == IPV6_PKTINFO) { 353 in6 = (struct sockaddr_in6 *)to; 354 in6->sin6_family = AF_INET6; 355 in6->sin6_len = *tolen = sizeof(*in6); 356 pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg); 357 memcpy(&in6->sin6_addr, &pkt6->ipi6_addr, 358 sizeof(struct in6_addr)); 359 if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) 360 in6->sin6_scope_id = 361 pkt6->ipi6_ifindex; 362 } 363 break; 364 } 365 } 366 367 return (ret); 368 } 369 370 const char * 371 print_spi(u_int64_t spi, int size) 372 { 373 static char buf[IKED_CYCLE_BUFFERS][32]; 374 static int i = 0; 375 char *ptr; 376 377 ptr = buf[i]; 378 379 switch (size) { 380 case 2: 381 snprintf(ptr, 32, "0x%04x", (u_int16_t)spi); 382 break; 383 case 4: 384 snprintf(ptr, 32, "0x%08x", (u_int32_t)spi); 385 break; 386 case 8: 387 snprintf(ptr, 32, "0x%016llx", spi); 388 break; 389 default: 390 snprintf(ptr, 32, "%llu", spi); 391 break; 392 } 393 394 if (++i >= IKED_CYCLE_BUFFERS) 395 i = 0; 396 397 return (ptr); 398 } 399 400 const char * 401 print_map(u_int type, struct iked_constmap *map) 402 { 403 u_int i; 404 static char buf[IKED_CYCLE_BUFFERS][32]; 405 static int idx = 0; 406 const char *name = NULL; 407 408 if (idx >= IKED_CYCLE_BUFFERS) 409 idx = 0; 410 bzero(buf[idx], sizeof(buf[idx])); 411 412 for (i = 0; map[i].cm_name != NULL; i++) { 413 if (map[i].cm_type == type) 414 name = map[i].cm_name; 415 } 416 417 if (name == NULL) 418 snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type); 419 else 420 strlcpy(buf[idx], name, sizeof(buf[idx])); 421 422 return (buf[idx++]); 423 } 424 425 void 426 lc_string(char *str) 427 { 428 for (; *str != '\0'; str++) 429 *str = tolower((unsigned char)*str); 430 } 431 432 void 433 print_hex(u_int8_t *buf, off_t offset, size_t length) 434 { 435 u_int i; 436 extern int verbose; 437 438 if (verbose < 3 || !length) 439 return; 440 441 for (i = 0; i < length; i++) { 442 if (i && (i % 4) == 0) { 443 if ((i % 32) == 0) 444 print_debug("\n"); 445 else 446 print_debug(" "); 447 } 448 print_debug("%02x", buf[offset + i]); 449 } 450 print_debug("\n"); 451 } 452 453 void 454 print_hexval(u_int8_t *buf, off_t offset, size_t length) 455 { 456 u_int i; 457 extern int verbose; 458 459 if (verbose < 2 || !length) 460 return; 461 462 print_debug("0x"); 463 for (i = 0; i < length; i++) 464 print_debug("%02x", buf[offset + i]); 465 print_debug("\n"); 466 } 467 468 const char * 469 print_bits(u_short v, u_char *bits) 470 { 471 static char buf[IKED_CYCLE_BUFFERS][BUFSIZ]; 472 static int idx = 0; 473 u_int i, any = 0, j = 0; 474 u_char c; 475 476 if (!bits) 477 return (""); 478 479 if (++idx >= IKED_CYCLE_BUFFERS) 480 idx = 0; 481 482 bzero(buf[idx], sizeof(buf[idx])); 483 484 bits++; 485 while ((i = *bits++)) { 486 if (v & (1 << (i-1))) { 487 if (any) { 488 buf[idx][j++] = ','; 489 if (j >= sizeof(buf[idx])) 490 return (buf[idx]); 491 } 492 any = 1; 493 for (; (c = *bits) > 32; bits++) { 494 buf[idx][j++] = tolower((unsigned char)c); 495 if (j >= sizeof(buf[idx])) 496 return (buf[idx]); 497 } 498 } else 499 for (; *bits > 32; bits++) 500 ; 501 } 502 503 return (buf[idx]); 504 } 505 506 u_int8_t 507 mask2prefixlen(struct sockaddr *sa) 508 { 509 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; 510 in_addr_t ina = sa_in->sin_addr.s_addr; 511 512 if (ina == 0) 513 return (0); 514 else 515 return (33 - ffs(ntohl(ina))); 516 } 517 518 u_int8_t 519 mask2prefixlen6(struct sockaddr *sa) 520 { 521 struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa; 522 u_int8_t l = 0, *ap, *ep; 523 524 /* 525 * sin6_len is the size of the sockaddr so substract the offset of 526 * the possibly truncated sin6_addr struct. 527 */ 528 ap = (u_int8_t *)&sa_in6->sin6_addr; 529 ep = (u_int8_t *)sa_in6 + sa_in6->sin6_len; 530 for (; ap < ep; ap++) { 531 /* this "beauty" is adopted from sbin/route/show.c ... */ 532 switch (*ap) { 533 case 0xff: 534 l += 8; 535 break; 536 case 0xfe: 537 l += 7; 538 return (l); 539 case 0xfc: 540 l += 6; 541 return (l); 542 case 0xf8: 543 l += 5; 544 return (l); 545 case 0xf0: 546 l += 4; 547 return (l); 548 case 0xe0: 549 l += 3; 550 return (l); 551 case 0xc0: 552 l += 2; 553 return (l); 554 case 0x80: 555 l += 1; 556 return (l); 557 case 0x00: 558 return (l); 559 default: 560 return (0); 561 } 562 } 563 564 return (l); 565 } 566 567 u_int32_t 568 prefixlen2mask(u_int8_t prefixlen) 569 { 570 if (prefixlen == 0) 571 return (0); 572 573 if (prefixlen > 32) 574 prefixlen = 32; 575 576 return (htonl(0xffffffff << (32 - prefixlen))); 577 } 578 579 struct in6_addr * 580 prefixlen2mask6(u_int8_t prefixlen, u_int32_t *mask) 581 { 582 static struct in6_addr s6; 583 int i; 584 585 if (prefixlen > 128) 586 prefixlen = 128; 587 588 bzero(&s6, sizeof(s6)); 589 for (i = 0; i < prefixlen / 8; i++) 590 s6.s6_addr[i] = 0xff; 591 i = prefixlen % 8; 592 if (i) 593 s6.s6_addr[prefixlen / 8] = 0xff00 >> i; 594 595 memcpy(mask, &s6, sizeof(s6)); 596 597 return (&s6); 598 } 599 600 const char * 601 print_host(struct sockaddr *sa, char *buf, size_t len) 602 { 603 static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7]; 604 static int idx = 0; 605 char pbuf[7]; 606 in_port_t port; 607 608 if (buf == NULL) { 609 buf = sbuf[idx]; 610 len = sizeof(sbuf[idx]); 611 if (++idx >= IKED_CYCLE_BUFFERS) 612 idx = 0; 613 } 614 615 if (sa->sa_family == AF_UNSPEC) { 616 strlcpy(buf, "any", len); 617 return (buf); 618 } 619 620 if (getnameinfo(sa, sa->sa_len, 621 buf, len, NULL, 0, NI_NUMERICHOST) != 0) { 622 buf[0] = '\0'; 623 return (NULL); 624 } 625 626 if ((port = socket_getport(sa)) != 0) { 627 snprintf(pbuf, sizeof(pbuf), ":%d", port); 628 (void)strlcat(buf, pbuf, len); 629 } 630 631 return (buf); 632 } 633 634 char * 635 get_string(u_int8_t *ptr, size_t len) 636 { 637 size_t i; 638 char *str; 639 640 for (i = 0; i < len; i++) 641 if (!isprint(ptr[i])) 642 break; 643 644 if ((str = calloc(1, i + 1)) == NULL) 645 return (NULL); 646 memcpy(str, ptr, i); 647 648 return (str); 649 } 650 651 const char * 652 print_proto(u_int8_t proto) 653 { 654 struct protoent *p; 655 static char buf[IKED_CYCLE_BUFFERS][BUFSIZ]; 656 static int idx = 0; 657 658 if (idx >= IKED_CYCLE_BUFFERS) 659 idx = 0; 660 661 if ((p = getprotobynumber(proto)) != NULL) 662 strlcpy(buf[idx], p->p_name, sizeof(buf[idx])); 663 else 664 snprintf(buf[idx], sizeof(buf), "%u", proto); 665 666 667 return (buf[idx++]); 668 } 669 670 int 671 expand_string(char *label, size_t len, const char *srch, const char *repl) 672 { 673 char *tmp; 674 char *p, *q; 675 676 if ((tmp = calloc(1, len)) == NULL) { 677 log_debug("expand_string: calloc"); 678 return (-1); 679 } 680 p = q = label; 681 while ((q = strstr(p, srch)) != NULL) { 682 *q = '\0'; 683 if ((strlcat(tmp, p, len) >= len) || 684 (strlcat(tmp, repl, len) >= len)) { 685 log_debug("expand_string: string too long"); 686 free(tmp); 687 return (-1); 688 } 689 q += strlen(srch); 690 p = q; 691 } 692 if (strlcat(tmp, p, len) >= len) { 693 log_debug("expand_string: string too long"); 694 free(tmp); 695 return (-1); 696 } 697 strlcpy(label, tmp, len); /* always fits */ 698 free(tmp); 699 700 return (0); 701 } 702 703 u_int8_t * 704 string2unicode(const char *ascii, size_t *outlen) 705 { 706 u_int8_t *uc = NULL; 707 size_t i, len = strlen(ascii); 708 709 if ((uc = calloc(1, (len * 2) + 2)) == NULL) 710 return (NULL); 711 712 for (i = 0; i < len; i++) { 713 /* XXX what about the byte order? */ 714 uc[i * 2] = ascii[i]; 715 } 716 *outlen = len * 2; 717 718 return (uc); 719 } 720