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