1 /* $NetBSD: sockmisc.c,v 1.11 2008/04/02 19:02:50 manu Exp $ */ 2 3 /* Id: sockmisc.c,v 1.24 2006/05/07 21:32:59 manubsd Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/uio.h> 40 41 #include <netinet/in.h> 42 #include PATH_IPSEC_H 43 44 #if defined(INET6) && !defined(INET6_ADVAPI) && \ 45 defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR) 46 #define IPV6_RECVDSTADDR IP_RECVDSTADDR 47 #endif 48 49 #include <stdlib.h> 50 #include <stdio.h> 51 #include <string.h> 52 #include <errno.h> 53 #ifdef HAVE_UNISTD_H 54 #include <unistd.h> 55 #endif 56 57 #include "var.h" 58 #include "misc.h" 59 #include "vmbuf.h" 60 #include "plog.h" 61 #include "sockmisc.h" 62 #include "debug.h" 63 #include "gcmalloc.h" 64 #include "debugrm.h" 65 #include "libpfkey.h" 66 67 #ifdef NOUSE_PRIVSEP 68 #define BIND bind 69 #define SOCKET socket 70 #define SETSOCKOPT setsockopt 71 #else 72 #include "admin.h" 73 #include "privsep.h" 74 #define BIND privsep_bind 75 #define SOCKET privsep_socket 76 #define SETSOCKOPT privsep_setsockopt 77 #endif 78 79 const int niflags = 0; 80 81 /* 82 * compare two sockaddr without port number. 83 * OUT: 0: equal. 84 * 1: not equal. 85 */ 86 int 87 cmpsaddrwop(addr1, addr2) 88 const struct sockaddr *addr1; 89 const struct sockaddr *addr2; 90 { 91 caddr_t sa1, sa2; 92 93 if (addr1 == 0 && addr2 == 0) 94 return 0; 95 if (addr1 == 0 || addr2 == 0) 96 return 1; 97 98 #ifdef __linux__ 99 if (addr1->sa_family != addr2->sa_family) 100 return 1; 101 #else 102 if (addr1->sa_len != addr2->sa_len 103 || addr1->sa_family != addr2->sa_family) 104 return 1; 105 106 #endif /* __linux__ */ 107 108 switch (addr1->sa_family) { 109 case AF_INET: 110 sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; 111 sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; 112 if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) 113 return 1; 114 break; 115 #ifdef INET6 116 case AF_INET6: 117 sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; 118 sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; 119 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) 120 return 1; 121 if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != 122 ((struct sockaddr_in6 *)addr2)->sin6_scope_id) 123 return 1; 124 break; 125 #endif 126 default: 127 return 1; 128 } 129 130 return 0; 131 } 132 133 /* 134 * compare two sockaddr with port, taking care wildcard. 135 * addr1 is a subject address, addr2 is in a database entry. 136 * OUT: 0: equal. 137 * 1: not equal. 138 */ 139 int 140 cmpsaddrwild(addr1, addr2) 141 const struct sockaddr *addr1; 142 const struct sockaddr *addr2; 143 { 144 caddr_t sa1, sa2; 145 u_short port1, port2; 146 147 if (addr1 == 0 && addr2 == 0) 148 return 0; 149 if (addr1 == 0 || addr2 == 0) 150 return 1; 151 152 #ifdef __linux__ 153 if (addr1->sa_family != addr2->sa_family) 154 return 1; 155 #else 156 if (addr1->sa_len != addr2->sa_len 157 || addr1->sa_family != addr2->sa_family) 158 return 1; 159 160 #endif /* __linux__ */ 161 162 switch (addr1->sa_family) { 163 case AF_INET: 164 sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; 165 sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; 166 port1 = ((struct sockaddr_in *)addr1)->sin_port; 167 port2 = ((struct sockaddr_in *)addr2)->sin_port; 168 if (!(port1 == IPSEC_PORT_ANY || 169 port2 == IPSEC_PORT_ANY || 170 port1 == port2)) 171 return 1; 172 if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) 173 return 1; 174 break; 175 #ifdef INET6 176 case AF_INET6: 177 sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; 178 sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; 179 port1 = ((struct sockaddr_in6 *)addr1)->sin6_port; 180 port2 = ((struct sockaddr_in6 *)addr2)->sin6_port; 181 if (!(port1 == IPSEC_PORT_ANY || 182 port2 == IPSEC_PORT_ANY || 183 port1 == port2)) 184 return 1; 185 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) 186 return 1; 187 if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != 188 ((struct sockaddr_in6 *)addr2)->sin6_scope_id) 189 return 1; 190 break; 191 #endif 192 default: 193 return 1; 194 } 195 196 return 0; 197 } 198 199 /* 200 * compare two sockaddr with strict match on port. 201 * OUT: 0: equal. 202 * 1: not equal. 203 */ 204 int 205 cmpsaddrstrict(addr1, addr2) 206 const struct sockaddr *addr1; 207 const struct sockaddr *addr2; 208 { 209 caddr_t sa1, sa2; 210 u_short port1, port2; 211 212 if (addr1 == 0 && addr2 == 0) 213 return 0; 214 if (addr1 == 0 || addr2 == 0) 215 return 1; 216 217 #ifdef __linux__ 218 if (addr1->sa_family != addr2->sa_family) 219 return 1; 220 #else 221 if (addr1->sa_len != addr2->sa_len 222 || addr1->sa_family != addr2->sa_family) 223 return 1; 224 225 #endif /* __linux__ */ 226 227 switch (addr1->sa_family) { 228 case AF_INET: 229 sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; 230 sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; 231 port1 = ((struct sockaddr_in *)addr1)->sin_port; 232 port2 = ((struct sockaddr_in *)addr2)->sin_port; 233 if (port1 != port2) 234 return 1; 235 if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) 236 return 1; 237 break; 238 #ifdef INET6 239 case AF_INET6: 240 sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; 241 sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; 242 port1 = ((struct sockaddr_in6 *)addr1)->sin6_port; 243 port2 = ((struct sockaddr_in6 *)addr2)->sin6_port; 244 if (port1 != port2) 245 return 1; 246 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) 247 return 1; 248 if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != 249 ((struct sockaddr_in6 *)addr2)->sin6_scope_id) 250 return 1; 251 break; 252 #endif 253 default: 254 return 1; 255 } 256 257 return 0; 258 } 259 260 /* get local address against the destination. */ 261 struct sockaddr * 262 getlocaladdr(remote) 263 struct sockaddr *remote; 264 { 265 struct sockaddr *local; 266 u_int local_len = sizeof(struct sockaddr_storage); 267 int s; /* for dummy connection */ 268 269 /* allocate buffer */ 270 if ((local = racoon_calloc(1, local_len)) == NULL) { 271 plog(LLV_ERROR, LOCATION, NULL, 272 "failed to get address buffer.\n"); 273 goto err; 274 } 275 276 /* get real interface received packet */ 277 if ((s = SOCKET(remote->sa_family, SOCK_DGRAM, 0)) < 0) { 278 plog(LLV_ERROR, LOCATION, NULL, 279 "socket (%s)\n", strerror(errno)); 280 goto err; 281 } 282 283 setsockopt_bypass(s, remote->sa_family); 284 285 if (connect(s, remote, sysdep_sa_len(remote)) < 0) { 286 plog(LLV_ERROR, LOCATION, NULL, 287 "connect (%s)\n", strerror(errno)); 288 close(s); 289 goto err; 290 } 291 292 if (getsockname(s, local, &local_len) < 0) { 293 plog(LLV_ERROR, LOCATION, NULL, 294 "getsockname (%s)\n", strerror(errno)); 295 close(s); 296 return NULL; 297 } 298 299 close(s); 300 return local; 301 302 err: 303 if (local != NULL) 304 racoon_free(local); 305 return NULL; 306 } 307 308 /* 309 * Receive packet, with src/dst information. It is assumed that necessary 310 * setsockopt() have already performed on socket. 311 */ 312 int 313 recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen) 314 int s; 315 void *buf; 316 size_t buflen; 317 int flags; 318 struct sockaddr *from; 319 socklen_t *fromlen; 320 struct sockaddr *to; 321 u_int *tolen; 322 { 323 int otolen; 324 u_int len; 325 struct sockaddr_storage ss; 326 struct msghdr m; 327 struct cmsghdr *cm; 328 struct iovec iov[2]; 329 u_char cmsgbuf[256]; 330 #if defined(INET6) && defined(INET6_ADVAPI) 331 struct in6_pktinfo *pi; 332 #endif /*INET6_ADVAPI*/ 333 struct sockaddr_in *sin; 334 #ifdef INET6 335 struct sockaddr_in6 *sin6; 336 #endif 337 338 len = sizeof(ss); 339 if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) { 340 plog(LLV_ERROR, LOCATION, NULL, 341 "getsockname (%s)\n", strerror(errno)); 342 return -1; 343 } 344 345 m.msg_name = (caddr_t)from; 346 m.msg_namelen = *fromlen; 347 iov[0].iov_base = (caddr_t)buf; 348 iov[0].iov_len = buflen; 349 m.msg_iov = iov; 350 m.msg_iovlen = 1; 351 memset(cmsgbuf, 0, sizeof(cmsgbuf)); 352 cm = (struct cmsghdr *)cmsgbuf; 353 m.msg_control = (caddr_t)cm; 354 m.msg_controllen = sizeof(cmsgbuf); 355 if ((len = recvmsg(s, &m, flags)) < 0) { 356 plog(LLV_ERROR, LOCATION, NULL, 357 "recvmsg (%s)\n", strerror(errno)); 358 return -1; 359 } 360 *fromlen = m.msg_namelen; 361 362 otolen = *tolen; 363 *tolen = 0; 364 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m); 365 m.msg_controllen != 0 && cm; 366 cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) { 367 #if 0 368 plog(LLV_ERROR, LOCATION, NULL, 369 "cmsg %d %d\n", cm->cmsg_level, cm->cmsg_type);) 370 #endif 371 #if defined(INET6) && defined(INET6_ADVAPI) 372 if (ss.ss_family == AF_INET6 373 && cm->cmsg_level == IPPROTO_IPV6 374 && cm->cmsg_type == IPV6_PKTINFO 375 && otolen >= sizeof(*sin6)) { 376 pi = (struct in6_pktinfo *)(CMSG_DATA(cm)); 377 *tolen = sizeof(*sin6); 378 sin6 = (struct sockaddr_in6 *)to; 379 memset(sin6, 0, sizeof(*sin6)); 380 sin6->sin6_family = AF_INET6; 381 #ifndef __linux__ 382 sin6->sin6_len = sizeof(*sin6); 383 #endif 384 memcpy(&sin6->sin6_addr, &pi->ipi6_addr, 385 sizeof(sin6->sin6_addr)); 386 /* XXX other cases, such as site-local? */ 387 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 388 sin6->sin6_scope_id = pi->ipi6_ifindex; 389 else 390 sin6->sin6_scope_id = 0; 391 sin6->sin6_port = 392 ((struct sockaddr_in6 *)&ss)->sin6_port; 393 otolen = -1; /* "to" already set */ 394 continue; 395 } 396 #endif 397 #ifdef __linux__ 398 if (ss.ss_family == AF_INET 399 && cm->cmsg_level == IPPROTO_IP 400 && cm->cmsg_type == IP_PKTINFO 401 && otolen >= sizeof(sin)) { 402 struct in_pktinfo *pi = (struct in_pktinfo *)(CMSG_DATA(cm)); 403 *tolen = sizeof(*sin); 404 sin = (struct sockaddr_in *)to; 405 memset(sin, 0, sizeof(*sin)); 406 sin->sin_family = AF_INET; 407 memcpy(&sin->sin_addr, &pi->ipi_addr, 408 sizeof(sin->sin_addr)); 409 sin->sin_port = 410 ((struct sockaddr_in *)&ss)->sin_port; 411 otolen = -1; /* "to" already set */ 412 continue; 413 } 414 #endif 415 #if defined(INET6) && defined(IPV6_RECVDSTADDR) 416 if (ss.ss_family == AF_INET6 417 && cm->cmsg_level == IPPROTO_IPV6 418 && cm->cmsg_type == IPV6_RECVDSTADDR 419 && otolen >= sizeof(*sin6)) { 420 *tolen = sizeof(*sin6); 421 sin6 = (struct sockaddr_in6 *)to; 422 memset(sin6, 0, sizeof(*sin6)); 423 sin6->sin6_family = AF_INET6; 424 sin6->sin6_len = sizeof(*sin6); 425 memcpy(&sin6->sin6_addr, CMSG_DATA(cm), 426 sizeof(sin6->sin6_addr)); 427 sin6->sin6_port = 428 ((struct sockaddr_in6 *)&ss)->sin6_port; 429 otolen = -1; /* "to" already set */ 430 continue; 431 } 432 #endif 433 #ifndef __linux__ 434 if (ss.ss_family == AF_INET 435 && cm->cmsg_level == IPPROTO_IP 436 && cm->cmsg_type == IP_RECVDSTADDR 437 && otolen >= sizeof(*sin)) { 438 *tolen = sizeof(*sin); 439 sin = (struct sockaddr_in *)to; 440 memset(sin, 0, sizeof(*sin)); 441 sin->sin_family = AF_INET; 442 sin->sin_len = sizeof(*sin); 443 memcpy(&sin->sin_addr, CMSG_DATA(cm), 444 sizeof(sin->sin_addr)); 445 sin->sin_port = ((struct sockaddr_in *)&ss)->sin_port; 446 otolen = -1; /* "to" already set */ 447 continue; 448 } 449 #endif 450 } 451 452 return len; 453 } 454 455 /* send packet, with fixing src/dst address pair. */ 456 int 457 sendfromto(s, buf, buflen, src, dst, cnt) 458 int s, cnt; 459 const void *buf; 460 size_t buflen; 461 struct sockaddr *src; 462 struct sockaddr *dst; 463 { 464 struct sockaddr_storage ss; 465 u_int len; 466 int i; 467 468 if (src->sa_family != dst->sa_family) { 469 plog(LLV_ERROR, LOCATION, NULL, 470 "address family mismatch\n"); 471 return -1; 472 } 473 474 len = sizeof(ss); 475 if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) { 476 plog(LLV_ERROR, LOCATION, NULL, 477 "getsockname (%s)\n", strerror(errno)); 478 return -1; 479 } 480 481 plog(LLV_DEBUG, LOCATION, NULL, 482 "sockname %s\n", saddr2str((struct sockaddr *)&ss)); 483 plog(LLV_DEBUG, LOCATION, NULL, 484 "send packet from %s\n", saddr2str(src)); 485 plog(LLV_DEBUG, LOCATION, NULL, 486 "send packet to %s\n", saddr2str(dst)); 487 488 if (src->sa_family != ss.ss_family) { 489 plog(LLV_ERROR, LOCATION, NULL, 490 "address family mismatch\n"); 491 return -1; 492 } 493 494 switch (src->sa_family) { 495 #if defined(INET6) && defined(INET6_ADVAPI) 496 // XXX: This block wasn't compiled on Linux - does it work? 497 case AF_INET6: 498 { 499 struct msghdr m; 500 struct cmsghdr *cm; 501 struct iovec iov[2]; 502 u_char cmsgbuf[256]; 503 struct in6_pktinfo *pi; 504 int ifindex; 505 struct sockaddr_in6 src6, dst6; 506 507 memcpy(&src6, src, sizeof(src6)); 508 memcpy(&dst6, dst, sizeof(dst6)); 509 510 /* XXX take care of other cases, such as site-local */ 511 ifindex = 0; 512 if (IN6_IS_ADDR_LINKLOCAL(&src6.sin6_addr) 513 || IN6_IS_ADDR_MULTICAST(&src6.sin6_addr)) { 514 ifindex = src6.sin6_scope_id; /*???*/ 515 } 516 517 /* XXX some sanity check on dst6.sin6_scope_id */ 518 519 /* flowinfo for IKE? mmm, maybe useful but for now make it 0 */ 520 src6.sin6_flowinfo = dst6.sin6_flowinfo = 0; 521 522 memset(&m, 0, sizeof(m)); 523 m.msg_name = (caddr_t)&dst6; 524 m.msg_namelen = sizeof(dst6); 525 iov[0].iov_base = (char *)buf; 526 iov[0].iov_len = buflen; 527 m.msg_iov = iov; 528 m.msg_iovlen = 1; 529 530 memset(cmsgbuf, 0, sizeof(cmsgbuf)); 531 cm = (struct cmsghdr *)cmsgbuf; 532 m.msg_control = (caddr_t)cm; 533 m.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); 534 535 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 536 cm->cmsg_level = IPPROTO_IPV6; 537 cm->cmsg_type = IPV6_PKTINFO; 538 pi = (struct in6_pktinfo *)CMSG_DATA(cm); 539 memcpy(&pi->ipi6_addr, &src6.sin6_addr, sizeof(src6.sin6_addr)); 540 pi->ipi6_ifindex = ifindex; 541 542 plog(LLV_DEBUG, LOCATION, NULL, 543 "src6 %s %d\n", 544 saddr2str((struct sockaddr *)&src6), 545 src6.sin6_scope_id); 546 plog(LLV_DEBUG, LOCATION, NULL, 547 "dst6 %s %d\n", 548 saddr2str((struct sockaddr *)&dst6), 549 dst6.sin6_scope_id); 550 551 for (i = 0; i < cnt; i++) { 552 len = sendmsg(s, &m, 0 /*MSG_DONTROUTE*/); 553 if (len < 0) { 554 plog(LLV_ERROR, LOCATION, NULL, 555 "sendmsg (%s)\n", strerror(errno)); 556 return -1; 557 } 558 plog(LLV_DEBUG, LOCATION, NULL, 559 "%d times of %d bytes message will be sent " 560 "to %s\n", 561 i + 1, len, saddr2str(dst)); 562 } 563 plogdump(LLV_DEBUG, (char *)buf, buflen); 564 565 return len; 566 } 567 #endif 568 #ifdef __linux__ 569 case AF_INET: 570 { 571 struct msghdr m; 572 struct cmsghdr *cm; 573 struct iovec iov[2]; 574 u_char cmsgbuf[256]; 575 struct in_pktinfo *pi; 576 int ifindex = 0; 577 struct sockaddr_in src6, dst6; 578 579 memcpy(&src6, src, sizeof(src6)); 580 memcpy(&dst6, dst, sizeof(dst6)); 581 582 memset(&m, 0, sizeof(m)); 583 m.msg_name = (caddr_t)&dst6; 584 m.msg_namelen = sizeof(dst6); 585 iov[0].iov_base = (char *)buf; 586 iov[0].iov_len = buflen; 587 m.msg_iov = iov; 588 m.msg_iovlen = 1; 589 590 memset(cmsgbuf, 0, sizeof(cmsgbuf)); 591 cm = (struct cmsghdr *)cmsgbuf; 592 m.msg_control = (caddr_t)cm; 593 m.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); 594 595 cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); 596 cm->cmsg_level = IPPROTO_IP; 597 cm->cmsg_type = IP_PKTINFO; 598 pi = (struct in_pktinfo *)CMSG_DATA(cm); 599 memcpy(&pi->ipi_spec_dst, &src6.sin_addr, sizeof(src6.sin_addr)); 600 pi->ipi_ifindex = ifindex; 601 602 plog(LLV_DEBUG, LOCATION, NULL, 603 "src4 %s\n", 604 saddr2str((struct sockaddr *)&src6)); 605 plog(LLV_DEBUG, LOCATION, NULL, 606 "dst4 %s\n", 607 saddr2str((struct sockaddr *)&dst6)); 608 609 for (i = 0; i < cnt; i++) { 610 len = sendmsg(s, &m, 0 /*MSG_DONTROUTE*/); 611 if (len < 0) { 612 plog(LLV_ERROR, LOCATION, NULL, 613 "sendmsg (%s)\n", strerror(errno)); 614 return -1; 615 } 616 plog(LLV_DEBUG, LOCATION, NULL, 617 "%d times of %d bytes message will be sent " 618 "to %s\n", 619 i + 1, len, saddr2str(dst)); 620 } 621 plogdump(LLV_DEBUG, (char *)buf, buflen); 622 623 return len; 624 } 625 #endif /* __linux__ */ 626 default: 627 { 628 int needclose = 0; 629 int sendsock; 630 631 if (ss.ss_family == src->sa_family && memcmp(&ss, src, sysdep_sa_len(src)) == 0) { 632 sendsock = s; 633 needclose = 0; 634 } else { 635 int yes = 1; 636 /* 637 * Use newly opened socket for sending packets. 638 * NOTE: this is unsafe, because if the peer is quick enough 639 * the packet from the peer may be queued into sendsock. 640 * Better approach is to prepare bind'ed udp sockets for 641 * each of the interface addresses. 642 */ 643 sendsock = SOCKET(src->sa_family, SOCK_DGRAM, 0); 644 if (sendsock < 0) { 645 plog(LLV_ERROR, LOCATION, NULL, 646 "socket (%s)\n", strerror(errno)); 647 return -1; 648 } 649 if (setsockopt(sendsock, SOL_SOCKET, 650 #ifdef __linux__ 651 SO_REUSEADDR, 652 #else 653 SO_REUSEPORT, 654 #endif 655 (void *)&yes, sizeof(yes)) < 0) { 656 plog(LLV_ERROR, LOCATION, NULL, 657 "setsockopt SO_REUSEPORT (%s)\n", 658 strerror(errno)); 659 close(sendsock); 660 return -1; 661 } 662 #ifdef IPV6_USE_MIN_MTU 663 if (src->sa_family == AF_INET6 && 664 setsockopt(sendsock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, 665 (void *)&yes, sizeof(yes)) < 0) { 666 plog(LLV_ERROR, LOCATION, NULL, 667 "setsockopt IPV6_USE_MIN_MTU (%s)\n", 668 strerror(errno)); 669 close(sendsock); 670 return -1; 671 } 672 #endif 673 if (setsockopt_bypass(sendsock, src->sa_family) < 0) { 674 close(sendsock); 675 return -1; 676 } 677 678 if (BIND(sendsock, (struct sockaddr *)src, 679 sysdep_sa_len(src)) < 0) { 680 plog(LLV_ERROR, LOCATION, NULL, 681 "bind 1 (%s)\n", strerror(errno)); 682 close(sendsock); 683 return -1; 684 } 685 needclose = 1; 686 } 687 688 for (i = 0; i < cnt; i++) { 689 len = sendto(sendsock, buf, buflen, 0, dst, sysdep_sa_len(dst)); 690 if (len < 0) { 691 plog(LLV_ERROR, LOCATION, NULL, 692 "sendto (%s)\n", strerror(errno)); 693 if (needclose) 694 close(sendsock); 695 return len; 696 } 697 plog(LLV_DEBUG, LOCATION, NULL, 698 "%d times of %d bytes message will be sent " 699 "to %s\n", 700 i + 1, len, saddr2str(dst)); 701 } 702 plogdump(LLV_DEBUG, (char *)buf, buflen); 703 704 if (needclose) 705 close(sendsock); 706 707 return len; 708 } 709 } 710 } 711 712 int 713 setsockopt_bypass(so, family) 714 int so, family; 715 { 716 int level; 717 char *buf; 718 char *policy; 719 720 switch (family) { 721 case AF_INET: 722 level = IPPROTO_IP; 723 break; 724 #ifdef INET6 725 case AF_INET6: 726 level = IPPROTO_IPV6; 727 break; 728 #endif 729 default: 730 plog(LLV_ERROR, LOCATION, NULL, 731 "unsupported address family %d\n", family); 732 return -1; 733 } 734 735 policy = "in bypass"; 736 buf = ipsec_set_policy(policy, strlen(policy)); 737 if (buf == NULL) { 738 plog(LLV_ERROR, LOCATION, NULL, 739 "ipsec_set_policy (%s)\n", 740 ipsec_strerror()); 741 return -1; 742 } 743 if (SETSOCKOPT(so, level, 744 (level == IPPROTO_IP ? 745 IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), 746 buf, ipsec_get_policylen(buf)) < 0) { 747 plog(LLV_ERROR, LOCATION, NULL, 748 "setsockopt IP_IPSEC_POLICY (%s)\n", 749 strerror(errno)); 750 return -1; 751 } 752 racoon_free(buf); 753 754 policy = "out bypass"; 755 buf = ipsec_set_policy(policy, strlen(policy)); 756 if (buf == NULL) { 757 plog(LLV_ERROR, LOCATION, NULL, 758 "ipsec_set_policy (%s)\n", 759 ipsec_strerror()); 760 return -1; 761 } 762 if (SETSOCKOPT(so, level, 763 (level == IPPROTO_IP ? 764 IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), 765 buf, ipsec_get_policylen(buf)) < 0) { 766 plog(LLV_ERROR, LOCATION, NULL, 767 "setsockopt IP_IPSEC_POLICY (%s)\n", 768 strerror(errno)); 769 return -1; 770 } 771 racoon_free(buf); 772 773 return 0; 774 } 775 776 struct sockaddr * 777 newsaddr(len) 778 int len; 779 { 780 struct sockaddr *new; 781 782 if ((new = racoon_calloc(1, len)) == NULL) { 783 plog(LLV_ERROR, LOCATION, NULL, 784 "%s\n", strerror(errno)); 785 goto out; 786 } 787 788 #ifdef __linux__ 789 if (len == sizeof (struct sockaddr_in6)) 790 new->sa_family = AF_INET6; 791 else 792 new->sa_family = AF_INET; 793 #else 794 /* initial */ 795 new->sa_len = len; 796 #endif 797 out: 798 return new; 799 } 800 801 struct sockaddr * 802 dupsaddr(src) 803 struct sockaddr *src; 804 { 805 struct sockaddr *dst; 806 807 dst = racoon_calloc(1, sysdep_sa_len(src)); 808 if (dst == NULL) { 809 plog(LLV_ERROR, LOCATION, NULL, 810 "%s\n", strerror(errno)); 811 return NULL; 812 } 813 814 memcpy(dst, src, sysdep_sa_len(src)); 815 816 return dst; 817 } 818 819 char * 820 saddr2str(saddr) 821 const struct sockaddr *saddr; 822 { 823 static char buf[NI_MAXHOST + NI_MAXSERV + 10]; 824 char addr[NI_MAXHOST], port[NI_MAXSERV]; 825 826 if (saddr == NULL) 827 return NULL; 828 829 if (saddr->sa_family == AF_UNSPEC) 830 snprintf (buf, sizeof(buf), "%s", "anonymous"); 831 else { 832 GETNAMEINFO(saddr, addr, port); 833 snprintf(buf, sizeof(buf), "%s[%s]", addr, port); 834 } 835 836 return buf; 837 } 838 839 char * 840 saddrwop2str(saddr) 841 const struct sockaddr *saddr; 842 { 843 static char buf[NI_MAXHOST + NI_MAXSERV + 10]; 844 char addr[NI_MAXHOST]; 845 846 if (saddr == NULL) 847 return NULL; 848 849 GETNAMEINFO_NULL(saddr, addr); 850 snprintf(buf, sizeof(buf), "%s", addr); 851 852 return buf; 853 } 854 855 char * 856 naddrwop2str(const struct netaddr *naddr) 857 { 858 static char buf[NI_MAXHOST + 10]; 859 static const struct sockaddr sa_any; /* this is initialized to all zeros */ 860 861 if (naddr == NULL) 862 return NULL; 863 864 if (memcmp(&naddr->sa, &sa_any, sizeof(sa_any)) == 0) 865 snprintf(buf, sizeof(buf), "%s", "any"); 866 else { 867 snprintf(buf, sizeof(buf), "%s", saddrwop2str(&naddr->sa.sa)); 868 snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf), "/%ld", naddr->prefix); 869 } 870 return buf; 871 } 872 873 char * 874 naddrwop2str_fromto(const char *format, const struct netaddr *saddr, 875 const struct netaddr *daddr) 876 { 877 static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; 878 char *src, *dst; 879 880 src = racoon_strdup(naddrwop2str(saddr)); 881 dst = racoon_strdup(naddrwop2str(daddr)); 882 STRDUP_FATAL(src); 883 STRDUP_FATAL(dst); 884 /* WARNING: Be careful about the format string! Don't 885 ever pass in something that a user can modify!!! */ 886 snprintf (buf, sizeof(buf), format, src, dst); 887 racoon_free (src); 888 racoon_free (dst); 889 890 return buf; 891 } 892 893 char * 894 saddr2str_fromto(format, saddr, daddr) 895 const char *format; 896 const struct sockaddr *saddr; 897 const struct sockaddr *daddr; 898 { 899 static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; 900 char *src, *dst; 901 902 src = racoon_strdup(saddr2str(saddr)); 903 dst = racoon_strdup(saddr2str(daddr)); 904 STRDUP_FATAL(src); 905 STRDUP_FATAL(dst); 906 /* WARNING: Be careful about the format string! Don't 907 ever pass in something that a user can modify!!! */ 908 snprintf (buf, sizeof(buf), format, src, dst); 909 racoon_free (src); 910 racoon_free (dst); 911 912 return buf; 913 } 914 915 struct sockaddr * 916 str2saddr(host, port) 917 char *host; 918 char *port; 919 { 920 struct addrinfo hints, *res; 921 struct sockaddr *saddr; 922 int error; 923 924 memset(&hints, 0, sizeof(hints)); 925 hints.ai_family = PF_UNSPEC; 926 hints.ai_socktype = SOCK_DGRAM; 927 hints.ai_flags = AI_NUMERICHOST; 928 error = getaddrinfo(host, port, &hints, &res); 929 if (error != 0) { 930 plog(LLV_ERROR, LOCATION, NULL, 931 "getaddrinfo(%s%s%s): %s\n", 932 host, port ? "," : "", port ? port : "", 933 gai_strerror(error)); 934 return NULL; 935 } 936 if (res->ai_next != NULL) { 937 plog(LLV_WARNING, LOCATION, NULL, 938 "getaddrinfo(%s%s%s): " 939 "resolved to multiple address, " 940 "taking the first one\n", 941 host, port ? "," : "", port ? port : ""); 942 } 943 saddr = racoon_malloc(res->ai_addrlen); 944 if (saddr == NULL) { 945 plog(LLV_ERROR, LOCATION, NULL, 946 "failed to allocate buffer.\n"); 947 freeaddrinfo(res); 948 return NULL; 949 } 950 memcpy(saddr, res->ai_addr, res->ai_addrlen); 951 freeaddrinfo(res); 952 953 return saddr; 954 } 955 956 void 957 mask_sockaddr(a, b, l) 958 struct sockaddr *a; 959 const struct sockaddr *b; 960 size_t l; 961 { 962 size_t i; 963 u_int8_t *p, alen; 964 965 switch (b->sa_family) { 966 case AF_INET: 967 alen = sizeof(struct in_addr); 968 p = (u_int8_t *)&((struct sockaddr_in *)a)->sin_addr; 969 break; 970 #ifdef INET6 971 case AF_INET6: 972 alen = sizeof(struct in6_addr); 973 p = (u_int8_t *)&((struct sockaddr_in6 *)a)->sin6_addr; 974 break; 975 #endif 976 default: 977 plog(LLV_ERROR, LOCATION, NULL, 978 "invalid family: %d\n", b->sa_family); 979 exit(1); 980 } 981 982 if ((alen << 3) < l) { 983 plog(LLV_ERROR, LOCATION, NULL, 984 "unexpected inconsistency: %d %zu\n", b->sa_family, l); 985 exit(1); 986 } 987 988 memcpy(a, b, sysdep_sa_len(b)); 989 p[l / 8] &= (0xff00 >> (l % 8)) & 0xff; 990 for (i = l / 8 + 1; i < alen; i++) 991 p[i] = 0x00; 992 } 993 994 /* Compute a score describing how "accurate" a netaddr is for a given sockaddr. 995 * Examples: 996 * Return values for address 10.20.30.40 [port 500] and given netaddresses... 997 * 10.10.0.0/16 => -1 ... doesn't match 998 * 0.0.0.0/0 => 0 ... matches, but only 0 bits. 999 * 10.20.0.0/16 => 16 ... 16 bits match 1000 * 10.20.30.0/24 => 24 ... guess what ;-) 1001 * 10.20.30.40/32 => 32 ... whole address match 1002 * 10.20.30.40:500 => 33 ... both address and port match 1003 * 10.20.30.40:501 => -1 ... port doesn't match and isn't 0 (=any) 1004 */ 1005 int 1006 naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) 1007 { 1008 static const struct netaddr naddr_any; /* initialized to all-zeros */ 1009 struct sockaddr sa; 1010 u_int16_t naddr_port, saddr_port; 1011 int port_score; 1012 1013 if (!naddr || !saddr) { 1014 plog(LLV_ERROR, LOCATION, NULL, 1015 "Call with null args: naddr=%p, saddr=%p\n", 1016 naddr, saddr); 1017 return -1; 1018 } 1019 1020 /* Wildcard address matches, but only 0 bits. */ 1021 if (memcmp(naddr, &naddr_any, sizeof(naddr_any)) == 0) 1022 return 0; 1023 1024 /* If families don't match we really can't do much... */ 1025 if (naddr->sa.sa.sa_family != saddr->sa_family) 1026 return -1; 1027 1028 /* If port check fail don't bother to check addresses. */ 1029 naddr_port = extract_port(&naddr->sa.sa); 1030 saddr_port = extract_port(saddr); 1031 if (naddr_port == 0 || saddr_port == 0) /* wildcard match */ 1032 port_score = 0; 1033 else if (naddr_port == saddr_port) /* exact match */ 1034 port_score = 1; 1035 else /* mismatch :-) */ 1036 return -1; 1037 1038 /* Here it comes - compare network addresses. */ 1039 mask_sockaddr(&sa, saddr, naddr->prefix); 1040 if (loglevel >= LLV_DEBUG) { /* debug only */ 1041 char *a1, *a2, *a3; 1042 a1 = racoon_strdup(naddrwop2str(naddr)); 1043 a2 = racoon_strdup(saddrwop2str(saddr)); 1044 a3 = racoon_strdup(saddrwop2str(&sa)); 1045 STRDUP_FATAL(a1); 1046 STRDUP_FATAL(a2); 1047 STRDUP_FATAL(a3); 1048 plog(LLV_DEBUG, LOCATION, NULL, 1049 "naddr=%s, saddr=%s (masked=%s)\n", 1050 a1, a2, a3); 1051 free(a1); 1052 free(a2); 1053 free(a3); 1054 } 1055 if (cmpsaddrwop(&sa, &naddr->sa.sa) == 0) 1056 return naddr->prefix + port_score; 1057 1058 return -1; 1059 } 1060 1061 /* Some usefull functions for sockaddr port manipulations. */ 1062 u_int16_t 1063 extract_port (const struct sockaddr *addr) 1064 { 1065 u_int16_t port = 0; 1066 1067 if (!addr) 1068 return port; 1069 1070 switch (addr->sa_family) { 1071 case AF_INET: 1072 port = ((struct sockaddr_in *)addr)->sin_port; 1073 break; 1074 case AF_INET6: 1075 port = ((struct sockaddr_in6 *)addr)->sin6_port; 1076 break; 1077 default: 1078 plog(LLV_ERROR, LOCATION, NULL, "unknown AF: %u\n", addr->sa_family); 1079 break; 1080 } 1081 1082 return ntohs(port); 1083 } 1084 1085 u_int16_t * 1086 get_port_ptr (struct sockaddr *addr) 1087 { 1088 u_int16_t *port_ptr; 1089 1090 if (!addr) 1091 return NULL; 1092 1093 switch (addr->sa_family) { 1094 case AF_INET: 1095 port_ptr = &(((struct sockaddr_in *)addr)->sin_port); 1096 break; 1097 case AF_INET6: 1098 port_ptr = &(((struct sockaddr_in6 *)addr)->sin6_port); 1099 break; 1100 default: 1101 plog(LLV_ERROR, LOCATION, NULL, "unknown AF: %u\n", addr->sa_family); 1102 return NULL; 1103 break; 1104 } 1105 1106 return port_ptr; 1107 } 1108 1109 u_int16_t * 1110 set_port (struct sockaddr *addr, u_int16_t new_port) 1111 { 1112 u_int16_t *port_ptr; 1113 1114 port_ptr = get_port_ptr (addr); 1115 1116 if (port_ptr) 1117 *port_ptr = htons(new_port); 1118 1119 return port_ptr; 1120 } 1121