Home | History | Annotate | Download | only in racoon
      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