• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
parse_rtattr(struct rtattr * tb[],int max,struct rtattr * rta,int len)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 
recvaddrs(int fd,struct ifaddrs ** ifa,__u32 seq)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 
getifaddrs(struct ifaddrs ** ifa0)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 
freeifaddrs(struct ifaddrs * ifa0)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
if_maxindex()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
clear_myaddr(db)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 *
find_myaddr(db,p)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
grab_myaddrs()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
suitable_ifaddr(ifname,ifaddr)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
suitable_ifaddr6(ifname,ifaddr)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
update_myaddrs()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
autoconf_myaddrsport()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
getmyaddrsport(local)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 *
newmyaddr()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 *
dupmyaddr(struct myaddrs * old)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
insmyaddr(new,head)827 insmyaddr(new, head)
828 	struct myaddrs *new;
829 	struct myaddrs **head;
830 {
831 	new->next = *head;
832 	*head = new;
833 }
834 
835 void
delmyaddr(myaddr)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
initmyaddr()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
getsockmyaddr(my)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