1/* $NetBSD: grabmyaddr.c,v 1.4.6.3 2008/06/18 07:30:18 mgrooms Exp $ */ 2 3/* Id: grabmyaddr.c,v 1.27 2006/04/06 16:27:05 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/ioctl.h> 40 41#include <net/if.h> 42#if defined(__FreeBSD__) && __FreeBSD__ >= 3 43#include <net/if_var.h> 44#endif 45#if defined(__NetBSD__) || defined(__FreeBSD__) || \ 46 (defined(__APPLE__) && defined(__MACH__)) 47#include <netinet/in.h> 48#include <netinet6/in6_var.h> 49#endif 50#include <net/route.h> 51 52#include <stdlib.h> 53#include <stdio.h> 54#include <string.h> 55#include <errno.h> 56#ifdef HAVE_UNISTD_H 57#include <unistd.h> 58#endif 59#include <netdb.h> 60#ifdef HAVE_GETIFADDRS 61#include <ifaddrs.h> 62#include <net/if.h> 63#endif 64 65#include "var.h" 66#include "misc.h" 67#include "vmbuf.h" 68#include "plog.h" 69#include "sockmisc.h" 70#include "debug.h" 71 72#include "localconf.h" 73#include "handler.h" 74#include "grabmyaddr.h" 75#include "sockmisc.h" 76#include "isakmp_var.h" 77#include "gcmalloc.h" 78#include "nattraversal.h" 79 80#ifdef __linux__ 81#include <linux/types.h> 82#include <linux/rtnetlink.h> 83#ifndef HAVE_GETIFADDRS 84#define HAVE_GETIFADDRS 85#define NEED_LINUX_GETIFADDRS 86#endif 87#endif 88 89#ifdef ANDROID_CHANGES 90#include "NetdClient.h" 91#endif 92 93#ifndef HAVE_GETIFADDRS 94static unsigned int if_maxindex __P((void)); 95#endif 96static struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *)); 97static int suitable_ifaddr __P((const char *, const struct sockaddr *)); 98#ifdef INET6 99static int suitable_ifaddr6 __P((const char *, const struct sockaddr *)); 100#endif 101 102#ifdef NEED_LINUX_GETIFADDRS 103 104/* We could do this _much_ better. kame racoon in its current form 105 * will esentially die at frequent changes of address configuration. 106 */ 107 108struct ifaddrs 109{ 110 struct ifaddrs *ifa_next; 111 char ifa_name[16]; 112 int ifa_ifindex; 113 struct sockaddr *ifa_addr; 114 struct sockaddr_storage ifa_addrbuf; 115}; 116 117static int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) 118{ 119 while (RTA_OK(rta, len)) { 120 if (rta->rta_type <= max) 121 tb[rta->rta_type] = rta; 122 rta = RTA_NEXT(rta,len); 123 } 124 return 0; 125} 126 127static void recvaddrs(int fd, struct ifaddrs **ifa, __u32 seq) 128{ 129 char buf[8192]; 130 struct sockaddr_nl nladdr; 131 struct iovec iov = { buf, sizeof(buf) }; 132 struct ifaddrmsg *m; 133 struct rtattr * rta_tb[IFA_MAX+1]; 134 struct ifaddrs *I; 135 136 while (1) { 137 int status; 138 struct nlmsghdr *h; 139 140 struct msghdr msg = { 141 (void*)&nladdr, sizeof(nladdr), 142 &iov, 1, 143 NULL, 0, 144 0 145 }; 146 147 status = recvmsg(fd, &msg, 0); 148 149 if (status < 0) 150 continue; 151 152 if (status == 0) 153 return; 154 155 if (nladdr.nl_pid) /* Message not from kernel */ 156 continue; 157 158 h = (struct nlmsghdr*)buf; 159 while (NLMSG_OK(h, status)) { 160 if (h->nlmsg_seq != seq) 161 goto skip_it; 162 163 if (h->nlmsg_type == NLMSG_DONE) 164 return; 165 166 if (h->nlmsg_type == NLMSG_ERROR) 167 return; 168 169 if (h->nlmsg_type != RTM_NEWADDR) 170 goto skip_it; 171 172 m = NLMSG_DATA(h); 173 174 if (m->ifa_family != AF_INET && 175 m->ifa_family != AF_INET6) 176 goto skip_it; 177 178 if (m->ifa_flags&IFA_F_TENTATIVE) 179 goto skip_it; 180 181 memset(rta_tb, 0, sizeof(rta_tb)); 182 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(m), h->nlmsg_len - NLMSG_LENGTH(sizeof(*m))); 183 184 if (rta_tb[IFA_LOCAL] == NULL) 185 rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 186 if (rta_tb[IFA_LOCAL] == NULL) 187 goto skip_it; 188 189 I = malloc(sizeof(struct ifaddrs)); 190 if (!I) 191 return; 192 memset(I, 0, sizeof(*I)); 193 194 I->ifa_ifindex = m->ifa_index; 195 I->ifa_addr = (struct sockaddr*)&I->ifa_addrbuf; 196 I->ifa_addr->sa_family = m->ifa_family; 197 if (m->ifa_family == AF_INET) { 198 struct sockaddr_in *sin = (void*)I->ifa_addr; 199 memcpy(&sin->sin_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 4); 200 } else { 201 struct sockaddr_in6 *sin = (void*)I->ifa_addr; 202 memcpy(&sin->sin6_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 16); 203 if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) 204 sin->sin6_scope_id = I->ifa_ifindex; 205 } 206 I->ifa_next = *ifa; 207 *ifa = I; 208 209skip_it: 210 h = NLMSG_NEXT(h, status); 211 } 212 if (msg.msg_flags & MSG_TRUNC) 213 continue; 214 } 215 return; 216} 217 218static int getifaddrs(struct ifaddrs **ifa0) 219{ 220 struct { 221 struct nlmsghdr nlh; 222 struct rtgenmsg g; 223 } req; 224 struct sockaddr_nl nladdr; 225 static __u32 seq; 226 struct ifaddrs *i; 227 int fd; 228 229 fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 230 if (fd < 0) 231 return -1; 232 233 memset(&nladdr, 0, sizeof(nladdr)); 234 nladdr.nl_family = AF_NETLINK; 235 236 req.nlh.nlmsg_len = sizeof(req); 237 req.nlh.nlmsg_type = RTM_GETADDR; 238 req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; 239 req.nlh.nlmsg_pid = 0; 240 req.nlh.nlmsg_seq = ++seq; 241 req.g.rtgen_family = AF_UNSPEC; 242 243 if (sendto(fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) { 244 close(fd); 245 return -1; 246 } 247 248 *ifa0 = NULL; 249 250 recvaddrs(fd, ifa0, seq); 251 252 close(fd); 253 254 fd = socket(AF_INET, SOCK_DGRAM, 0); 255 256 for (i=*ifa0; i; i = i->ifa_next) { 257 struct ifreq ifr; 258 ifr.ifr_ifindex = i->ifa_ifindex; 259 ioctl(fd, SIOCGIFNAME, (void*)&ifr); 260 memcpy(i->ifa_name, ifr.ifr_name, 16); 261 } 262 close(fd); 263 264 return 0; 265} 266 267static void freeifaddrs(struct ifaddrs *ifa0) 268{ 269 struct ifaddrs *i; 270 271 while (ifa0) { 272 i = ifa0; 273 ifa0 = i->ifa_next; 274 free(i); 275 } 276} 277 278#endif 279 280#ifndef HAVE_GETIFADDRS 281static unsigned int 282if_maxindex() 283{ 284 struct if_nameindex *p, *p0; 285 unsigned int max = 0; 286 287 p0 = if_nameindex(); 288 for (p = p0; p && p->if_index && p->if_name; p++) { 289 if (max < p->if_index) 290 max = p->if_index; 291 } 292 if_freenameindex(p0); 293 return max; 294} 295#endif 296 297void 298clear_myaddr(db) 299 struct myaddrs **db; 300{ 301 struct myaddrs *p; 302 303 while (*db) { 304 p = (*db)->next; 305 delmyaddr(*db); 306 *db = p; 307 } 308} 309 310static struct myaddrs * 311find_myaddr(db, p) 312 struct myaddrs *db; 313 struct myaddrs *p; 314{ 315 struct myaddrs *q; 316 char h1[NI_MAXHOST], h2[NI_MAXHOST]; 317 318 if (getnameinfo(p->addr, sysdep_sa_len(p->addr), h1, sizeof(h1), NULL, 0, 319 NI_NUMERICHOST | niflags) != 0) 320 return NULL; 321 322 for (q = db; q; q = q->next) { 323 if (p->addr->sa_family != q->addr->sa_family) 324 continue; 325 if (getnameinfo(q->addr, sysdep_sa_len(q->addr), h2, sizeof(h2), 326 NULL, 0, NI_NUMERICHOST | niflags) != 0) 327 return NULL; 328 if (strcmp(h1, h2) == 0) 329 return q; 330 } 331 332 return NULL; 333} 334 335void 336grab_myaddrs() 337{ 338#ifdef HAVE_GETIFADDRS 339 struct myaddrs *p, *q, *old; 340 struct ifaddrs *ifa0, *ifap; 341#ifdef INET6 342 struct sockaddr_in6 *sin6; 343#endif 344 345 char addr1[NI_MAXHOST]; 346 347 if (getifaddrs(&ifa0)) { 348 plog(LLV_ERROR, LOCATION, NULL, 349 "getifaddrs failed: %s\n", strerror(errno)); 350 exit(1); 351 /*NOTREACHED*/ 352 } 353 354 old = lcconf->myaddrs; 355 356 for (ifap = ifa0; ifap; ifap = ifap->ifa_next) { 357 if (! ifap->ifa_addr) 358 continue; 359 360 if (ifap->ifa_addr->sa_family != AF_INET 361#ifdef INET6 362 && ifap->ifa_addr->sa_family != AF_INET6 363#endif 364 ) 365 continue; 366 367 if (!suitable_ifaddr(ifap->ifa_name, ifap->ifa_addr)) { 368 plog(LLV_ERROR, LOCATION, NULL, 369 "unsuitable address: %s %s\n", 370 ifap->ifa_name, 371 saddrwop2str(ifap->ifa_addr)); 372 continue; 373 } 374 375 p = newmyaddr(); 376 if (p == NULL) { 377 exit(1); 378 /*NOTREACHED*/ 379 } 380 p->addr = dupsaddr(ifap->ifa_addr); 381 if (p->addr == NULL) { 382 exit(1); 383 /*NOTREACHED*/ 384 } 385#ifdef INET6 386#ifdef __KAME__ 387 if (ifap->ifa_addr->sa_family == AF_INET6) { 388 sin6 = (struct sockaddr_in6 *)p->addr; 389 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) 390 || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 391 sin6->sin6_scope_id = 392 ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); 393 sin6->sin6_addr.s6_addr[2] = 0; 394 sin6->sin6_addr.s6_addr[3] = 0; 395 } 396 } 397#else /* !__KAME__ */ 398 if (ifap->ifa_addr->sa_family == AF_INET6) { 399 sin6 = (struct sockaddr_in6 *)p->addr; 400 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) 401 || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 402 sin6->sin6_scope_id = 403 if_nametoindex(ifap->ifa_name); 404 } 405 } 406 407#endif 408#endif 409 if (getnameinfo(p->addr, sysdep_sa_len(p->addr), 410 addr1, sizeof(addr1), 411 NULL, 0, 412 NI_NUMERICHOST | niflags)) 413 strlcpy(addr1, "(invalid)", sizeof(addr1)); 414 plog(LLV_DEBUG, LOCATION, NULL, 415 "my interface: %s (%s)\n", 416 addr1, ifap->ifa_name); 417 q = find_myaddr(old, p); 418#ifdef ANDROID_CHANGES 419 if (q) { 420 protectFromVpn(q->sock); 421 } 422#endif 423 if (q) 424 p->sock = q->sock; 425 else 426 p->sock = -1; 427 p->next = lcconf->myaddrs; 428 lcconf->myaddrs = p; 429 } 430 431 freeifaddrs(ifa0); 432 433 clear_myaddr(&old); 434 435#else /*!HAVE_GETIFADDRS*/ 436 int s; 437 unsigned int maxif; 438 int len; 439 struct ifreq *iflist; 440 struct ifconf ifconf; 441 struct ifreq *ifr, *ifr_end; 442 struct myaddrs *p, *q, *old; 443#ifdef INET6 444#ifdef __KAME__ 445 struct sockaddr_in6 *sin6; 446#endif 447#endif 448 449 char addr1[NI_MAXHOST]; 450 451 maxif = if_maxindex() + 1; 452 len = maxif * sizeof(struct sockaddr_storage) * 4; /* guess guess */ 453 454 iflist = (struct ifreq *)racoon_malloc(len); 455 if (!iflist) { 456 plog(LLV_ERROR, LOCATION, NULL, 457 "failed to allocate buffer\n"); 458 exit(1); 459 /*NOTREACHED*/ 460 } 461 462 if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 463 plog(LLV_ERROR, LOCATION, NULL, 464 "socket(SOCK_DGRAM) failed: %s\n", 465 strerror(errno)); 466 exit(1); 467 /*NOTREACHED*/ 468 } 469#ifdef ANDROID_CHANGES 470 protectFromVpn(s); 471#endif 472 473 memset(&ifconf, 0, sizeof(ifconf)); 474 ifconf.ifc_req = iflist; 475 ifconf.ifc_len = len; 476 if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) { 477 close(s); 478 plog(LLV_ERROR, LOCATION, NULL, 479 "ioctl(SIOCGIFCONF) failed: %s\n", 480 strerror(errno)); 481 exit(1); 482 /*NOTREACHED*/ 483 } 484 close(s); 485 486 old = lcconf->myaddrs; 487 488 /* Look for this interface in the list */ 489 ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len); 490 491#define _IFREQ_LEN(p) \ 492 (sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) > sizeof(struct ifreq) \ 493 ? sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) : sizeof(struct ifreq)) 494 495 for (ifr = ifconf.ifc_req; 496 ifr < ifr_end; 497 ifr = (struct ifreq *)((caddr_t)ifr + _IFREQ_LEN(ifr))) { 498 499 switch (ifr->ifr_addr.sa_family) { 500 case AF_INET: 501#ifdef INET6 502 case AF_INET6: 503#endif 504 if (!suitable_ifaddr(ifr->ifr_name, &ifr->ifr_addr)) { 505 plog(LLV_ERROR, LOCATION, NULL, 506 "unsuitable address: %s %s\n", 507 ifr->ifr_name, 508 saddrwop2str(&ifr->ifr_addr)); 509 continue; 510 } 511 512 p = newmyaddr(); 513 if (p == NULL) { 514 exit(1); 515 /*NOTREACHED*/ 516 } 517 p->addr = dupsaddr(&ifr->ifr_addr); 518 if (p->addr == NULL) { 519 exit(1); 520 /*NOTREACHED*/ 521 } 522#ifdef INET6 523#ifdef __KAME__ 524 sin6 = (struct sockaddr_in6 *)p->addr; 525 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) 526 || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 527 sin6->sin6_scope_id = 528 ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); 529 sin6->sin6_addr.s6_addr[2] = 0; 530 sin6->sin6_addr.s6_addr[3] = 0; 531 } 532#endif 533#endif 534 if (getnameinfo(p->addr, sysdep_sa_len(p->addr), 535 addr1, sizeof(addr1), 536 NULL, 0, 537 NI_NUMERICHOST | niflags)) 538 strlcpy(addr1, "(invalid)", sizeof(addr1)); 539 plog(LLV_DEBUG, LOCATION, NULL, 540 "my interface: %s (%s)\n", 541 addr1, ifr->ifr_name); 542 q = find_myaddr(old, p); 543#ifdef ANDROID_CHANGES 544 if (q) { 545 protectFromVpn(q->sock); 546 } 547#endif 548 if (q) 549 p->sock = q->sock; 550 else 551 p->sock = -1; 552 p->next = lcconf->myaddrs; 553 lcconf->myaddrs = p; 554 break; 555 default: 556 break; 557 } 558 } 559 560 clear_myaddr(&old); 561 562 racoon_free(iflist); 563#endif /*HAVE_GETIFADDRS*/ 564} 565 566/* 567 * check the interface is suitable or not 568 */ 569static int 570suitable_ifaddr(ifname, ifaddr) 571 const char *ifname; 572 const struct sockaddr *ifaddr; 573{ 574#ifdef ENABLE_HYBRID 575 /* Exclude any address we got through ISAKMP mode config */ 576 if (exclude_cfg_addr(ifaddr) == 0) 577 return 0; 578#endif 579 switch(ifaddr->sa_family) { 580 case AF_INET: 581 return 1; 582#ifdef INET6 583 case AF_INET6: 584 return suitable_ifaddr6(ifname, ifaddr); 585#endif 586 default: 587 return 0; 588 } 589 /*NOTREACHED*/ 590} 591 592#ifdef INET6 593static int 594suitable_ifaddr6(ifname, ifaddr) 595 const char *ifname; 596 const struct sockaddr *ifaddr; 597{ 598#ifndef __linux__ 599 struct in6_ifreq ifr6; 600 int s; 601#endif 602 603 if (ifaddr->sa_family != AF_INET6) 604 return 0; 605 606#ifndef __linux__ 607 s = socket(PF_INET6, SOCK_DGRAM, 0); 608 if (s == -1) { 609 plog(LLV_ERROR, LOCATION, NULL, 610 "socket(SOCK_DGRAM) failed:%s\n", strerror(errno)); 611 return 0; 612 } 613#ifdef ANDROID_CHANGES 614 protectFromVpn(s); 615#endif 616 617 memset(&ifr6, 0, sizeof(ifr6)); 618 strncpy(ifr6.ifr_name, ifname, strlen(ifname)); 619 620 ifr6.ifr_addr = *(const struct sockaddr_in6 *)ifaddr; 621 622 if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { 623 plog(LLV_ERROR, LOCATION, NULL, 624 "ioctl(SIOCGIFAFLAG_IN6) failed:%s\n", strerror(errno)); 625 close(s); 626 return 0; 627 } 628 629 close(s); 630 631 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED 632 || ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED 633 || ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST) 634 return 0; 635#endif 636 637 /* suitable */ 638 return 1; 639} 640#endif 641 642int 643update_myaddrs() 644{ 645#ifdef __linux__ 646 char msg[BUFSIZ]; 647 int len; 648 struct nlmsghdr *h = (void*)msg; 649 len = read(lcconf->rtsock, msg, sizeof(msg)); 650 if (len < 0) 651 return errno == ENOBUFS; 652 if (len < sizeof(*h)) 653 return 0; 654 if (h->nlmsg_pid) /* not from kernel! */ 655 return 0; 656 if (h->nlmsg_type == RTM_NEWLINK) 657 return 0; 658 plog(LLV_DEBUG, LOCATION, NULL, 659 "netlink signals update interface address list\n"); 660 return 1; 661#else 662 char msg[BUFSIZ]; 663 int len; 664 struct rt_msghdr *rtm; 665 666 len = read(lcconf->rtsock, msg, sizeof(msg)); 667 if (len < 0) { 668 plog(LLV_ERROR, LOCATION, NULL, 669 "read(PF_ROUTE) failed: %s\n", 670 strerror(errno)); 671 return 0; 672 } 673 rtm = (struct rt_msghdr *)msg; 674 if (len < rtm->rtm_msglen) { 675 plog(LLV_ERROR, LOCATION, NULL, 676 "read(PF_ROUTE) short read\n"); 677 return 0; 678 } 679 if (rtm->rtm_version != RTM_VERSION) { 680 plog(LLV_ERROR, LOCATION, NULL, 681 "routing socket version mismatch\n"); 682 close(lcconf->rtsock); 683 lcconf->rtsock = -1; 684 return 0; 685 } 686 switch (rtm->rtm_type) { 687 case RTM_NEWADDR: 688 case RTM_DELADDR: 689 case RTM_DELETE: 690 case RTM_IFINFO: 691 break; 692 case RTM_MISS: 693 /* ignore this message silently */ 694 return 0; 695 default: 696 plog(LLV_DEBUG, LOCATION, NULL, 697 "msg %d not interesting\n", rtm->rtm_type); 698 return 0; 699 } 700 /* XXX more filters here? */ 701 702 plog(LLV_DEBUG, LOCATION, NULL, 703 "caught rtm:%d, need update interface address list\n", 704 rtm->rtm_type); 705 return 1; 706#endif /* __linux__ */ 707} 708 709/* 710 * initialize default port for ISAKMP to send, if no "listen" 711 * directive is specified in config file. 712 * 713 * DO NOT listen to wildcard addresses. if you receive packets to 714 * wildcard address, you'll be in trouble (DoS attack possible by 715 * broadcast storm). 716 */ 717int 718autoconf_myaddrsport() 719{ 720 struct myaddrs *p; 721 int n; 722 723 plog(LLV_DEBUG, LOCATION, NULL, 724 "configuring default isakmp port.\n"); 725 726#ifdef ENABLE_NATT 727 if (natt_enabled_in_rmconf ()) { 728 plog(LLV_NOTIFY, LOCATION, NULL, "NAT-T is enabled, autoconfiguring ports\n"); 729 for (p = lcconf->myaddrs; p; p = p->next) { 730 struct myaddrs *new; 731 if (! p->udp_encap) { 732 new = dupmyaddr(p); 733 new->udp_encap = 1; 734 } 735 } 736 } 737#endif 738 739 for (p = lcconf->myaddrs, n = 0; p; p = p->next, n++) { 740 set_port (p->addr, p->udp_encap ? lcconf->port_isakmp_natt : lcconf->port_isakmp); 741 } 742 plog(LLV_DEBUG, LOCATION, NULL, 743 "%d addrs are configured successfully\n", n); 744 745 return 0; 746} 747 748/* 749 * get a port number to which racoon binded. 750 */ 751u_short 752getmyaddrsport(local) 753 struct sockaddr *local; 754{ 755 struct myaddrs *p, *bestmatch = NULL; 756 u_short bestmatch_port = PORT_ISAKMP; 757 758 /* get a relative port */ 759 for (p = lcconf->myaddrs; p; p = p->next) { 760 if (!p->addr) 761 continue; 762 if (cmpsaddrwop(local, p->addr)) 763 continue; 764 765 /* use first matching address regardless of port */ 766 if (!bestmatch) { 767 bestmatch = p; 768 continue; 769 } 770 771 /* matching address with port PORT_ISAKMP */ 772 if (extract_port(p->addr) == PORT_ISAKMP) { 773 bestmatch = p; 774 bestmatch_port = PORT_ISAKMP; 775 } 776 } 777 778 return bestmatch_port; 779} 780 781struct myaddrs * 782newmyaddr() 783{ 784 struct myaddrs *new; 785 786 new = racoon_calloc(1, sizeof(*new)); 787 if (new == NULL) { 788 plog(LLV_ERROR, LOCATION, NULL, 789 "failed to allocate buffer for myaddrs.\n"); 790 return NULL; 791 } 792 793 new->next = NULL; 794 new->addr = NULL; 795 796 return new; 797} 798 799struct myaddrs * 800dupmyaddr(struct myaddrs *old) 801{ 802 struct myaddrs *new; 803 804 new = racoon_calloc(1, sizeof(*new)); 805 if (new == NULL) { 806 plog(LLV_ERROR, LOCATION, NULL, 807 "failed to allocate buffer for myaddrs.\n"); 808 return NULL; 809 } 810 811 /* Copy the whole structure and set the differences. */ 812 memcpy (new, old, sizeof (*new)); 813 new->addr = dupsaddr (old->addr); 814 if (new->addr == NULL) { 815 plog(LLV_ERROR, LOCATION, NULL, 816 "failed to allocate buffer for myaddrs.\n"); 817 racoon_free(new); 818 return NULL; 819 } 820 new->next = old->next; 821 old->next = new; 822 823 return new; 824} 825 826void 827insmyaddr(new, head) 828 struct myaddrs *new; 829 struct myaddrs **head; 830{ 831 new->next = *head; 832 *head = new; 833} 834 835void 836delmyaddr(myaddr) 837 struct myaddrs *myaddr; 838{ 839 if (myaddr->addr) 840 racoon_free(myaddr->addr); 841 racoon_free(myaddr); 842} 843 844int 845initmyaddr() 846{ 847 /* initialize routing socket */ 848 lcconf->rtsock = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); 849 if (lcconf->rtsock < 0) { 850 plog(LLV_ERROR, LOCATION, NULL, 851 "socket(PF_ROUTE) failed: %s", 852 strerror(errno)); 853 return -1; 854 } 855 856#ifdef __linux__ 857 { 858 struct sockaddr_nl nl; 859 u_int addr_len; 860 861 memset(&nl, 0, sizeof(nl)); 862 nl.nl_family = AF_NETLINK; 863 nl.nl_groups = RTMGRP_IPV4_IFADDR|RTMGRP_LINK|RTMGRP_IPV6_IFADDR; 864 865 if (bind(lcconf->rtsock, (struct sockaddr*)&nl, sizeof(nl)) < 0) { 866 plog(LLV_ERROR, LOCATION, NULL, 867 "bind(PF_NETLINK) failed: %s\n", 868 strerror(errno)); 869 return -1; 870 } 871 addr_len = sizeof(nl); 872 if (getsockname(lcconf->rtsock, (struct sockaddr*)&nl, &addr_len) < 0) { 873 plog(LLV_ERROR, LOCATION, NULL, 874 "getsockname(PF_NETLINK) failed: %s\n", 875 strerror(errno)); 876 return -1; 877 } 878 } 879#endif 880 881 if (lcconf->myaddrs == NULL && lcconf->autograbaddr == 1) { 882 grab_myaddrs(); 883 884 if (autoconf_myaddrsport() < 0) 885 return -1; 886 } 887 888 return 0; 889} 890 891/* select the socket to be sent */ 892/* should implement other method. */ 893int 894getsockmyaddr(my) 895 struct sockaddr *my; 896{ 897 struct myaddrs *p, *lastresort = NULL; 898#if defined(INET6) && defined(__linux__) 899 struct myaddrs *match_wo_scope_id = NULL; 900 int check_wo_scope_id = (my->sa_family == AF_INET6) && 901 IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)my)->sin6_addr); 902#endif 903 904 for (p = lcconf->myaddrs; p; p = p->next) { 905 if (p->addr == NULL) 906 continue; 907 if (my->sa_family == p->addr->sa_family) { 908 lastresort = p; 909 } else continue; 910 if (sysdep_sa_len(my) == sysdep_sa_len(p->addr) 911 && memcmp(my, p->addr, sysdep_sa_len(my)) == 0) { 912 break; 913 } 914#if defined(INET6) && defined(__linux__) 915 if (check_wo_scope_id && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)p->addr)->sin6_addr) && 916 /* XXX: this depends on sin6_scope_id to be last 917 * item in struct sockaddr_in6 */ 918 memcmp(my, p->addr, 919 sysdep_sa_len(my) - sizeof(uint32_t)) == 0) { 920 match_wo_scope_id = p; 921 } 922#endif 923 } 924#if defined(INET6) && defined(__linux__) 925 if (!p) 926 p = match_wo_scope_id; 927#endif 928 if (!p) 929 p = lastresort; 930 if (!p) { 931 plog(LLV_ERROR, LOCATION, NULL, 932 "no socket matches address family %d\n", 933 my->sa_family); 934 return -1; 935 } 936 937 return p->sock; 938} 939