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