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