Home | History | Annotate | Download | only in racoon
      1 /*	$NetBSD: grabmyaddr.c,v 1.28 2011/03/14 17:18:12 tteras Exp $	*/
      2 /*
      3  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
      4  * Copyright (C) 2008 Timo Teras <timo.teras (at) iki.fi>.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the project nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include "config.h"
     33 
     34 #include <errno.h>
     35 #include <fcntl.h>
     36 #include <unistd.h>
     37 #include <string.h>
     38 #include <sys/types.h>
     39 #include <sys/queue.h>
     40 #include <sys/socket.h>
     41 
     42 #ifdef __linux__
     43 #include <linux/netlink.h>
     44 #include <linux/rtnetlink.h>
     45 #define USE_NETLINK
     46 #else
     47 #include <net/route.h>
     48 #include <net/if.h>
     49 #include <net/if_dl.h>
     50 #include <sys/sysctl.h>
     51 #define USE_ROUTE
     52 #endif
     53 
     54 #include "var.h"
     55 #include "misc.h"
     56 #include "vmbuf.h"
     57 #include "plog.h"
     58 #include "sockmisc.h"
     59 #include "session.h"
     60 #include "debug.h"
     61 
     62 #include "localconf.h"
     63 #include "handler.h"
     64 #include "grabmyaddr.h"
     65 #include "sockmisc.h"
     66 #include "isakmp_var.h"
     67 #include "gcmalloc.h"
     68 #include "nattraversal.h"
     69 
     70 static int kernel_receive __P((void *ctx, int fd));
     71 static int kernel_open_socket __P((void));
     72 static void kernel_sync __P((void));
     73 
     74 struct myaddr {
     75 	LIST_ENTRY(myaddr) chain;
     76 	struct sockaddr_storage addr;
     77 	int fd;
     78 	int udp_encap;
     79 };
     80 
     81 static LIST_HEAD(_myaddr_list_, myaddr) configured, opened;
     82 
     83 static void
     84 myaddr_delete(my)
     85 	struct myaddr *my;
     86 {
     87 	if (my->fd != -1)
     88 		isakmp_close(my->fd);
     89 	LIST_REMOVE(my, chain);
     90 	racoon_free(my);
     91 }
     92 
     93 static int
     94 myaddr_configured(addr)
     95 	struct sockaddr *addr;
     96 {
     97 	struct myaddr *cfg;
     98 
     99 	if (LIST_EMPTY(&configured))
    100 		return TRUE;
    101 
    102 	LIST_FOREACH(cfg, &configured, chain) {
    103 		if (cmpsaddr(addr, (struct sockaddr *) &cfg->addr) <= CMPSADDR_WILDPORT_MATCH)
    104 			return TRUE;
    105 	}
    106 
    107 	return FALSE;
    108 }
    109 
    110 static int
    111 myaddr_open(addr, udp_encap)
    112 	struct sockaddr *addr;
    113 	int udp_encap;
    114 {
    115 	struct myaddr *my;
    116 
    117 	/* Already open? */
    118 	LIST_FOREACH(my, &opened, chain) {
    119 		if (cmpsaddr(addr, (struct sockaddr *) &my->addr) <= CMPSADDR_WILDPORT_MATCH)
    120 			return TRUE;
    121 	}
    122 
    123 	my = racoon_calloc(1, sizeof(struct myaddr));
    124 	if (my == NULL)
    125 		return FALSE;
    126 
    127 	memcpy(&my->addr, addr, sysdep_sa_len(addr));
    128 	my->fd = isakmp_open(addr, udp_encap);
    129 	if (my->fd < 0) {
    130 		racoon_free(my);
    131 		return FALSE;
    132 	}
    133 	my->udp_encap = udp_encap;
    134 	LIST_INSERT_HEAD(&opened, my, chain);
    135 	return TRUE;
    136 }
    137 
    138 static int
    139 myaddr_open_all_configured(addr)
    140 	struct sockaddr *addr;
    141 {
    142 	/* create all configured, not already opened addresses */
    143 	struct myaddr *cfg, *my;
    144 
    145 	if (addr != NULL) {
    146 		switch (addr->sa_family) {
    147 		case AF_INET:
    148 #ifdef INET6
    149 		case AF_INET6:
    150 #endif
    151 			break;
    152 		default:
    153 			return FALSE;
    154 		}
    155 	}
    156 
    157 	LIST_FOREACH(cfg, &configured, chain) {
    158 		if (addr != NULL &&
    159 		    cmpsaddr(addr, (struct sockaddr *) &cfg->addr) > CMPSADDR_WILDPORT_MATCH)
    160 			continue;
    161 		if (!myaddr_open((struct sockaddr *) &cfg->addr, cfg->udp_encap))
    162 			return FALSE;
    163 	}
    164 	if (LIST_EMPTY(&configured)) {
    165 #ifdef ENABLE_HYBRID
    166 		/* Exclude any address we got through ISAKMP mode config */
    167 		if (exclude_cfg_addr(addr) == 0)
    168 			return FALSE;
    169 #endif
    170 		set_port(addr, lcconf->port_isakmp);
    171 		myaddr_open(addr, FALSE);
    172 #ifdef ENABLE_NATT
    173 		set_port(addr, lcconf->port_isakmp_natt);
    174 		myaddr_open(addr, TRUE);
    175 #endif
    176 	}
    177 	return TRUE;
    178 }
    179 
    180 static void
    181 myaddr_close_all_open(addr)
    182 	struct sockaddr *addr;
    183 {
    184 	/* delete all matching open sockets */
    185 	struct myaddr *my, *next;
    186 
    187 	for (my = LIST_FIRST(&opened); my; my = next) {
    188 		next = LIST_NEXT(my, chain);
    189 
    190 		if (cmpsaddr((struct sockaddr *) addr,
    191 			     (struct sockaddr *) &my->addr)
    192 		    <= CMPSADDR_WOP_MATCH)
    193 			myaddr_delete(my);
    194 	}
    195 }
    196 
    197 static void
    198 myaddr_flush_list(list)
    199 	struct _myaddr_list_ *list;
    200 {
    201 	struct myaddr *my, *next;
    202 
    203 	for (my = LIST_FIRST(list); my; my = next) {
    204 		next = LIST_NEXT(my, chain);
    205 		myaddr_delete(my);
    206 	}
    207 }
    208 
    209 void
    210 myaddr_flush()
    211 {
    212 	myaddr_flush_list(&configured);
    213 }
    214 
    215 int
    216 myaddr_listen(addr, udp_encap)
    217 	struct sockaddr *addr;
    218 	int udp_encap;
    219 {
    220 	struct myaddr *my;
    221 
    222 	if (sysdep_sa_len(addr) > sizeof(my->addr)) {
    223 		plog(LLV_ERROR, LOCATION, NULL,
    224 		     "sockaddr size larger than sockaddr_storage\n");
    225 		return -1;
    226 	}
    227 
    228 	my = racoon_calloc(1, sizeof(struct myaddr));
    229 	if (my == NULL)
    230 		return -1;
    231 
    232 	memcpy(&my->addr, addr, sysdep_sa_len(addr));
    233 	my->udp_encap = udp_encap;
    234 	my->fd = -1;
    235 	LIST_INSERT_HEAD(&configured, my, chain);
    236 
    237 	return 0;
    238 }
    239 
    240 void
    241 myaddr_sync()
    242 {
    243 	struct myaddr *my, *next;
    244 
    245 	if (!lcconf->strict_address) {
    246 		kernel_sync();
    247 
    248 		/* delete all existing listeners which are not configured */
    249 		for (my = LIST_FIRST(&opened); my; my = next) {
    250 			next = LIST_NEXT(my, chain);
    251 
    252 			if (!myaddr_configured((struct sockaddr *) &my->addr))
    253 				myaddr_delete(my);
    254 		}
    255 	}
    256 }
    257 
    258 int
    259 myaddr_getfd(addr)
    260         struct sockaddr *addr;
    261 {
    262 	struct myaddr *my;
    263 
    264 	LIST_FOREACH(my, &opened, chain) {
    265 		if (cmpsaddr((struct sockaddr *) &my->addr, addr) <= CMPSADDR_WILDPORT_MATCH)
    266 			return my->fd;
    267 	}
    268 
    269 	return -1;
    270 }
    271 
    272 int
    273 myaddr_getsport(addr)
    274 	struct sockaddr *addr;
    275 {
    276 	struct myaddr *my;
    277 
    278 	LIST_FOREACH(my, &opened, chain) {
    279 		if (cmpsaddr((struct sockaddr *) &my->addr, addr) <= CMPSADDR_WILDPORT_MATCH)
    280 			return extract_port((struct sockaddr *) &my->addr);
    281 	}
    282 
    283 	return PORT_ISAKMP;
    284 }
    285 
    286 void
    287 myaddr_init_lists()
    288 {
    289 	LIST_INIT(&configured);
    290 	LIST_INIT(&opened);
    291 }
    292 
    293 int
    294 myaddr_init()
    295 {
    296         if (!lcconf->strict_address) {
    297 		lcconf->rtsock = kernel_open_socket();
    298 		if (lcconf->rtsock < 0)
    299 			return -1;
    300 		monitor_fd(lcconf->rtsock, kernel_receive, NULL, 0);
    301 	} else {
    302 		lcconf->rtsock = -1;
    303 		if (!myaddr_open_all_configured(NULL))
    304 			return -1;
    305 	}
    306 	return 0;
    307 }
    308 
    309 void
    310 myaddr_close()
    311 {
    312 	myaddr_flush_list(&configured);
    313 	myaddr_flush_list(&opened);
    314 	if (lcconf->rtsock != -1) {
    315 		unmonitor_fd(lcconf->rtsock);
    316 		close(lcconf->rtsock);
    317 	}
    318 }
    319 
    320 #if defined(USE_NETLINK)
    321 
    322 static int netlink_fd = -1;
    323 
    324 #define NLMSG_TAIL(nmsg) \
    325 	((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
    326 
    327 static void
    328 parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
    329 {
    330 	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
    331 	while (RTA_OK(rta, len)) {
    332 		if (rta->rta_type <= max)
    333 			tb[rta->rta_type] = rta;
    334 		rta = RTA_NEXT(rta,len);
    335 	}
    336 }
    337 
    338 static int
    339 netlink_add_rtattr_l(struct nlmsghdr *n, int maxlen, int type,
    340 		     const void *data, int alen)
    341 {
    342 	int len = RTA_LENGTH(alen);
    343 	struct rtattr *rta;
    344 
    345 	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
    346 		return FALSE;
    347 
    348 	rta = NLMSG_TAIL(n);
    349 	rta->rta_type = type;
    350 	rta->rta_len = len;
    351 	memcpy(RTA_DATA(rta), data, alen);
    352 	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
    353 	return TRUE;
    354 }
    355 
    356 static int
    357 netlink_enumerate(fd, family, type)
    358 	int fd;
    359 	int family;
    360 	int type;
    361 {
    362 	struct {
    363 		struct nlmsghdr nlh;
    364 		struct rtgenmsg g;
    365 	} req;
    366 	struct sockaddr_nl addr;
    367 	static __u32 seq = 0;
    368 
    369 	memset(&addr, 0, sizeof(addr));
    370 	addr.nl_family = AF_NETLINK;
    371 
    372 	memset(&req, 0, sizeof(req));
    373 	req.nlh.nlmsg_len = sizeof(req);
    374 	req.nlh.nlmsg_type = type;
    375 	req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
    376 	req.nlh.nlmsg_pid = 0;
    377 	req.nlh.nlmsg_seq = ++seq;
    378 	req.g.rtgen_family = family;
    379 
    380 	return sendto(fd, (void *) &req, sizeof(req), 0,
    381 		      (struct sockaddr *) &addr, sizeof(addr)) >= 0;
    382 }
    383 
    384 static void
    385 netlink_add_del_address(int add, struct sockaddr *saddr)
    386 {
    387 	plog(LLV_DEBUG, LOCATION, NULL,
    388 	     "Netlink: address %s %s\n",
    389 	     saddrwop2str((struct sockaddr *) saddr),
    390 	     add ? "added" : "deleted");
    391 
    392 	if (add)
    393 		myaddr_open_all_configured(saddr);
    394 	else
    395 		myaddr_close_all_open(saddr);
    396 }
    397 
    398 #ifdef INET6
    399 static int
    400 netlink_process_addr(struct nlmsghdr *h)
    401 {
    402 	struct sockaddr_storage addr;
    403 	struct ifaddrmsg *ifa;
    404 	struct rtattr *rta[IFA_MAX+1];
    405 	struct sockaddr_in6 *sin6;
    406 
    407 	ifa = NLMSG_DATA(h);
    408 	parse_rtattr(rta, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h));
    409 
    410 	if (ifa->ifa_family != AF_INET6)
    411 		return 0;
    412 	if (ifa->ifa_flags & IFA_F_TENTATIVE)
    413 		return 0;
    414 	if (rta[IFA_LOCAL] == NULL)
    415 		rta[IFA_LOCAL] = rta[IFA_ADDRESS];
    416 	if (rta[IFA_LOCAL] == NULL)
    417 		return 0;
    418 
    419 	memset(&addr, 0, sizeof(addr));
    420 	addr.ss_family = ifa->ifa_family;
    421 	sin6 = (struct sockaddr_in6 *) &addr;
    422 	memcpy(&sin6->sin6_addr, RTA_DATA(rta[IFA_LOCAL]),
    423 		sizeof(sin6->sin6_addr));
    424 	if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
    425 		return 0;
    426 	sin6->sin6_scope_id = ifa->ifa_index;
    427 
    428 	netlink_add_del_address(h->nlmsg_type == RTM_NEWADDR,
    429 				(struct sockaddr *) &addr);
    430 
    431 	return 0;
    432 }
    433 #endif
    434 
    435 static int
    436 netlink_route_is_local(int family, const unsigned char *addr, size_t addr_len)
    437 {
    438 	struct {
    439 		struct nlmsghdr n;
    440 		struct rtmsg    r;
    441 		char            buf[1024];
    442 	} req;
    443 	struct rtmsg *r = NLMSG_DATA(&req.n);
    444 	struct rtattr *rta[RTA_MAX+1];
    445 	struct sockaddr_nl nladdr;
    446 	ssize_t rlen;
    447 
    448 	memset(&req, 0, sizeof(req));
    449 	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    450 	req.n.nlmsg_flags = NLM_F_REQUEST;
    451 	req.n.nlmsg_type = RTM_GETROUTE;
    452 	req.r.rtm_family = family;
    453 	netlink_add_rtattr_l(&req.n, sizeof(req), RTA_DST,
    454 			     addr, addr_len);
    455 	req.r.rtm_dst_len = addr_len * 8;
    456 
    457 	memset(&nladdr, 0, sizeof(nladdr));
    458 	nladdr.nl_family = AF_NETLINK;
    459 
    460 	if (sendto(netlink_fd, &req, sizeof(req), 0,
    461 		   (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0)
    462 		return 0;
    463 	rlen = recv(netlink_fd, &req, sizeof(req), 0);
    464 	if (rlen < 0)
    465 		return 0;
    466 
    467 	return  req.n.nlmsg_type == RTM_NEWROUTE &&
    468 		req.r.rtm_type == RTN_LOCAL;
    469 }
    470 
    471 static int
    472 netlink_process_route(struct nlmsghdr *h)
    473 {
    474 	struct sockaddr_storage addr;
    475 	struct rtmsg *rtm;
    476 	struct rtattr *rta[RTA_MAX+1];
    477 	struct sockaddr_in *sin;
    478 #ifdef INET6
    479 	struct sockaddr_in6 *sin6;
    480 #endif
    481 
    482 	rtm = NLMSG_DATA(h);
    483 
    484 	/* local IP addresses get local route in the local table */
    485 	if (rtm->rtm_type != RTN_LOCAL ||
    486 	    rtm->rtm_table != RT_TABLE_LOCAL)
    487 		return 0;
    488 
    489 	parse_rtattr(rta, IFA_MAX, RTM_RTA(rtm), IFA_PAYLOAD(h));
    490 	if (rta[RTA_DST] == NULL)
    491  		return 0;
    492 
    493 	/* setup the socket address */
    494 	memset(&addr, 0, sizeof(addr));
    495 	addr.ss_family = rtm->rtm_family;
    496 	switch (rtm->rtm_family) {
    497 	case AF_INET:
    498 		sin = (struct sockaddr_in *) &addr;
    499 		memcpy(&sin->sin_addr, RTA_DATA(rta[RTA_DST]),
    500 			sizeof(sin->sin_addr));
    501 		break;
    502 #ifdef INET6
    503 	case AF_INET6:
    504 		sin6 = (struct sockaddr_in6 *) &addr;
    505 		memcpy(&sin6->sin6_addr, RTA_DATA(rta[RTA_DST]),
    506 			sizeof(sin6->sin6_addr));
    507 		/* Link-local addresses are handled with RTM_NEWADDR
    508 		 * notifications */
    509 		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
    510 			return 0;
    511 		break;
    512 #endif
    513 	default:
    514 		return 0;
    515 	}
    516 
    517 	/* If local route was deleted, check if there is still local
    518 	 * route for the same IP on another interface */
    519 	if (h->nlmsg_type == RTM_DELROUTE &&
    520 	    netlink_route_is_local(rtm->rtm_family,
    521 				   RTA_DATA(rta[RTA_DST]),
    522 				   RTA_PAYLOAD(rta[RTA_DST]))) {
    523 		plog(LLV_DEBUG, LOCATION, NULL,
    524 			"Netlink: not deleting %s yet, it exists still\n",
    525 			saddrwop2str((struct sockaddr *) &addr));
    526 		return 0;
    527 	}
    528 
    529 	netlink_add_del_address(h->nlmsg_type == RTM_NEWROUTE,
    530 				(struct sockaddr *) &addr);
    531 	return 0;
    532 }
    533 
    534 static int
    535 netlink_process(struct nlmsghdr *h)
    536 {
    537 	switch (h->nlmsg_type) {
    538 #ifdef INET6
    539 	case RTM_NEWADDR:
    540 	case RTM_DELADDR:
    541 		return netlink_process_addr(h);
    542 #endif
    543 	case RTM_NEWROUTE:
    544 	case RTM_DELROUTE:
    545 		return netlink_process_route(h);
    546 	}
    547 	return 0;
    548 }
    549 
    550 static int
    551 kernel_receive(ctx, fd)
    552 	void *ctx;
    553 	int fd;
    554 {
    555 	struct sockaddr_nl nladdr;
    556 	struct iovec iov;
    557 	struct msghdr msg = {
    558 		.msg_name = &nladdr,
    559 		.msg_namelen = sizeof(nladdr),
    560 		.msg_iov = &iov,
    561 		.msg_iovlen = 1,
    562 	};
    563 	struct nlmsghdr *h;
    564 	int len, status;
    565 	char buf[16*1024];
    566 
    567 	iov.iov_base = buf;
    568 	while (1) {
    569 		iov.iov_len = sizeof(buf);
    570 		status = recvmsg(fd, &msg, MSG_DONTWAIT);
    571 		if (status < 0) {
    572 			if (errno == EINTR)
    573 				continue;
    574 			if (errno == EAGAIN)
    575 				return FALSE;
    576 			continue;
    577 		}
    578 		if (status == 0)
    579 			return FALSE;
    580 
    581 		h = (struct nlmsghdr *) buf;
    582 		while (NLMSG_OK(h, status)) {
    583 			netlink_process(h);
    584 			h = NLMSG_NEXT(h, status);
    585 		}
    586 	}
    587 
    588 	return TRUE;
    589 }
    590 
    591 static int
    592 netlink_open_socket()
    593 {
    594 	int fd;
    595 
    596 	fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    597 	if (fd < 0) {
    598 		plog(LLV_ERROR, LOCATION, NULL,
    599 			"socket(PF_NETLINK) failed: %s",
    600 			strerror(errno));
    601 		return -1;
    602 	}
    603 	close_on_exec(fd);
    604 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
    605 		plog(LLV_WARNING, LOCATION, NULL,
    606 		     "failed to put socket in non-blocking mode\n");
    607 
    608 	return fd;
    609 }
    610 
    611 static int
    612 kernel_open_socket()
    613 {
    614 	struct sockaddr_nl nl;
    615 	int fd;
    616 
    617 	if (netlink_fd < 0) {
    618 		netlink_fd = netlink_open_socket();
    619 		if (netlink_fd < 0)
    620 			return -1;
    621 	}
    622 
    623 	fd = netlink_open_socket();
    624 	if (fd < 0)
    625 		return fd;
    626 
    627 	/* We monitor IPv4 addresses using RTMGRP_IPV4_ROUTE group
    628 	 * the get the RTN_LOCAL routes which are automatically added
    629 	 * by kernel. This is because:
    630 	 *  - Linux kernel has a bug that calling bind() immediately
    631 	 *    after IPv4 RTM_NEWADDR event can fail
    632 	 *  - if IP is configured in multiple interfaces, we get
    633 	 *    RTM_DELADDR for each of them. RTN_LOCAL gets deleted only
    634 	 *    after the last IP address is deconfigured.
    635 	 * The latter reason is also why I chose to use route
    636 	 * notifications for IPv6. However, we do need to use RTM_NEWADDR
    637 	 * for the link-local IPv6 addresses to get the interface index
    638 	 * that is needed in bind().
    639 	 */
    640 	memset(&nl, 0, sizeof(nl));
    641 	nl.nl_family = AF_NETLINK;
    642 	nl.nl_groups = RTMGRP_IPV4_ROUTE
    643 #ifdef INET6
    644 			| RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE
    645 #endif
    646 			;
    647 	if (bind(fd, (struct sockaddr*) &nl, sizeof(nl)) < 0) {
    648 		plog(LLV_ERROR, LOCATION, NULL,
    649 		     "bind(PF_NETLINK) failed: %s\n",
    650 		     strerror(errno));
    651 		close(fd);
    652 		return -1;
    653 	}
    654 	return fd;
    655 }
    656 
    657 static void
    658 kernel_sync()
    659 {
    660 	int fd = lcconf->rtsock;
    661 
    662 	/* refresh addresses */
    663 	if (!netlink_enumerate(fd, PF_UNSPEC, RTM_GETROUTE)) {
    664 		plog(LLV_ERROR, LOCATION, NULL,
    665 		     "unable to enumerate addresses: %s\n",
    666 		     strerror(errno));
    667 	}
    668 	while (kernel_receive(NULL, fd) == TRUE);
    669 
    670 #ifdef INET6
    671 	if (!netlink_enumerate(fd, PF_INET6, RTM_GETADDR)) {
    672 		plog(LLV_ERROR, LOCATION, NULL,
    673 		     "unable to enumerate addresses: %s\n",
    674 		     strerror(errno));
    675 	}
    676 	while (kernel_receive(NULL, fd) == TRUE);
    677 #endif
    678 }
    679 
    680 #elif defined(USE_ROUTE)
    681 
    682 #define ROUNDUP(a) \
    683   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
    684 
    685 #define SAROUNDUP(X)   ROUNDUP(((struct sockaddr *)(X))->sa_len)
    686 
    687 static size_t
    688 parse_address(start, end, dest)
    689 	caddr_t start;
    690 	caddr_t end;
    691 	struct sockaddr_storage *dest;
    692 {
    693 	int len;
    694 
    695 	if (start >= end)
    696 		return 0;
    697 
    698 	len = SAROUNDUP(start);
    699 	if (start + len > end)
    700 		return end - start;
    701 
    702 	if (dest != NULL && len <= sizeof(struct sockaddr_storage))
    703 		memcpy(dest, start, len);
    704 
    705 	return len;
    706 }
    707 
    708 static void
    709 parse_addresses(start, end, flags, addr)
    710 	caddr_t start;
    711 	caddr_t end;
    712 	int flags;
    713 	struct sockaddr_storage *addr;
    714 {
    715 	memset(addr, 0, sizeof(*addr));
    716 	if (flags & RTA_DST)
    717 		start += parse_address(start, end, NULL);
    718 	if (flags & RTA_GATEWAY)
    719 		start += parse_address(start, end, NULL);
    720 	if (flags & RTA_NETMASK)
    721 		start += parse_address(start, end, NULL);
    722 	if (flags & RTA_GENMASK)
    723 		start += parse_address(start, end, NULL);
    724 	if (flags & RTA_IFP)
    725 		start += parse_address(start, end, NULL);
    726 	if (flags & RTA_IFA)
    727 		start += parse_address(start, end, addr);
    728 	if (flags & RTA_AUTHOR)
    729 		start += parse_address(start, end, NULL);
    730 	if (flags & RTA_BRD)
    731 		start += parse_address(start, end, NULL);
    732 }
    733 
    734 static void
    735 kernel_handle_message(msg)
    736 	caddr_t msg;
    737 {
    738 	struct rt_msghdr *rtm = (struct rt_msghdr *) msg;
    739 	struct ifa_msghdr *ifa = (struct ifa_msghdr *) msg;
    740 	struct sockaddr_storage addr;
    741 
    742 	switch (rtm->rtm_type) {
    743 	case RTM_NEWADDR:
    744 		parse_addresses(ifa + 1, msg + ifa->ifam_msglen,
    745 				ifa->ifam_addrs, &addr);
    746 		myaddr_open_all_configured((struct sockaddr *) &addr);
    747 		break;
    748 	case RTM_DELADDR:
    749 		parse_addresses(ifa + 1, msg + ifa->ifam_msglen,
    750 				ifa->ifam_addrs, &addr);
    751 		myaddr_close_all_open((struct sockaddr *) &addr);
    752 		break;
    753 	case RTM_ADD:
    754 	case RTM_DELETE:
    755 	case RTM_CHANGE:
    756 	case RTM_MISS:
    757 	case RTM_IFINFO:
    758 #ifdef RTM_OIFINFO
    759 	case RTM_OIFINFO:
    760 #endif
    761 #ifdef RTM_NEWMADDR
    762 	case RTM_NEWMADDR:
    763 	case RTM_DELMADDR:
    764 #endif
    765 #ifdef RTM_IFANNOUNCE
    766 	case RTM_IFANNOUNCE:
    767 #endif
    768 		break;
    769 	default:
    770 		plog(LLV_WARNING, LOCATION, NULL,
    771 		     "unrecognized route message with rtm_type: %d",
    772 		     rtm->rtm_type);
    773 		break;
    774 	}
    775 }
    776 
    777 static int
    778 kernel_receive(ctx, fd)
    779 	void *ctx;
    780 	int fd;
    781 {
    782 	char buf[16*1024];
    783 	struct rt_msghdr *rtm = (struct rt_msghdr *) buf;
    784 	int len;
    785 
    786 	len = read(fd, &buf, sizeof(buf));
    787 	if (len <= 0) {
    788 		if (len < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
    789 			plog(LLV_WARNING, LOCATION, NULL,
    790 			     "routing socket error: %s", strerror(errno));
    791 		return FALSE;
    792 	}
    793 
    794 	if (rtm->rtm_msglen != len) {
    795 		plog(LLV_WARNING, LOCATION, NULL,
    796 		     "kernel_receive: rtm->rtm_msglen %d, len %d, type %d\n",
    797 		     rtm->rtm_msglen, len, rtm->rtm_type);
    798 		return FALSE;
    799 	}
    800 
    801 	kernel_handle_message(buf);
    802 	return TRUE;
    803 }
    804 
    805 static int
    806 kernel_open_socket()
    807 {
    808 	int fd;
    809 
    810 	fd = socket(PF_ROUTE, SOCK_RAW, 0);
    811 	if (fd < 0) {
    812 		plog(LLV_ERROR, LOCATION, NULL,
    813 			"socket(PF_ROUTE) failed: %s",
    814 			strerror(errno));
    815 		return -1;
    816 	}
    817 	close_on_exec(fd);
    818 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
    819 		plog(LLV_WARNING, LOCATION, NULL,
    820 		     "failed to put socket in non-blocking mode\n");
    821 
    822 	return fd;
    823 }
    824 
    825 static void
    826 kernel_sync()
    827 {
    828 	caddr_t ref, buf, end;
    829 	size_t bufsiz;
    830 	struct if_msghdr *ifm;
    831 	struct interface *ifp;
    832 
    833 #define MIBSIZ 6
    834 	int mib[MIBSIZ] = {
    835 		CTL_NET,
    836 		PF_ROUTE,
    837 		0,
    838 		0, /*  AF_INET & AF_INET6 */
    839 		NET_RT_IFLIST,
    840 		0
    841 	};
    842 
    843 	if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) {
    844 		plog(LLV_WARNING, LOCATION, NULL,
    845 		     "sysctl() error: %s", strerror(errno));
    846 		return;
    847 	}
    848 
    849 	ref = buf = racoon_malloc(bufsiz);
    850 
    851 	if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) >= 0) {
    852 		/* Parse both interfaces and addresses. */
    853 		for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) {
    854 			ifm = (struct if_msghdr *) buf;
    855 			kernel_handle_message(buf);
    856 		}
    857 	} else {
    858 		plog(LLV_WARNING, LOCATION, NULL,
    859 		     "sysctl() error: %s", strerror(errno));
    860 	}
    861 
    862 	racoon_free(ref);
    863 }
    864 
    865 #else
    866 
    867 #error No supported interface to monitor local addresses.
    868 
    869 #endif
    870