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