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 94 static unsigned int if_maxindex __P((void)); 95 #endif 96 static struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *)); 97 static int suitable_ifaddr __P((const char *, const struct sockaddr *)); 98 #ifdef INET6 99 static 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 108 struct 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 117 static 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 127 static 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 209 skip_it: 210 h = NLMSG_NEXT(h, status); 211 } 212 if (msg.msg_flags & MSG_TRUNC) 213 continue; 214 } 215 return; 216 } 217 218 static 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 267 static 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 281 static unsigned int 282 if_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 297 void 298 clear_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 310 static struct myaddrs * 311 find_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 335 void 336 grab_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 */ 569 static int 570 suitable_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 593 static int 594 suitable_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 642 int 643 update_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 */ 717 int 718 autoconf_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 */ 751 u_short 752 getmyaddrsport(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 781 struct myaddrs * 782 newmyaddr() 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 799 struct myaddrs * 800 dupmyaddr(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 826 void 827 insmyaddr(new, head) 828 struct myaddrs *new; 829 struct myaddrs **head; 830 { 831 new->next = *head; 832 *head = new; 833 } 834 835 void 836 delmyaddr(myaddr) 837 struct myaddrs *myaddr; 838 { 839 if (myaddr->addr) 840 racoon_free(myaddr->addr); 841 racoon_free(myaddr); 842 } 843 844 int 845 initmyaddr() 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. */ 893 int 894 getsockmyaddr(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