1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* $NetBSD: grabmyaddr.c,v 1.4.6.3 2008/06/18 07:30:18 mgrooms Exp $ */ 2c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 3c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* Id: grabmyaddr.c,v 1.27 2006/04/06 16:27:05 manubsd Exp */ 4c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved. 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met: 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer. 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer in the 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * documentation and/or other materials provided with the distribution. 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * may be used to endorse or promote products derived from this software 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * without specific prior written permission. 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE. 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h" 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h> 37c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <sys/param.h> 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h> 39c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <sys/ioctl.h> 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <net/if.h> 42c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if defined(__FreeBSD__) && __FreeBSD__ >= 3 43c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <net/if_var.h> 44c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 45c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if defined(__NetBSD__) || defined(__FreeBSD__) || \ 46c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh (defined(__APPLE__) && defined(__MACH__)) 47c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <netinet/in.h> 48c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <netinet6/in6_var.h> 49c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 50c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <net/route.h> 51c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 52c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <stdlib.h> 53c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <stdio.h> 54c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <string.h> 55c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <errno.h> 56c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef HAVE_UNISTD_H 57c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <unistd.h> 58f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif 59c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <netdb.h> 60c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef HAVE_GETIFADDRS 61c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <ifaddrs.h> 62c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <net/if.h> 63c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h" 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h" 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h" 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h" 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h" 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h" 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h" 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h" 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "grabmyaddr.h" 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h" 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h" 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h" 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "nattraversal.h" 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 80c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __linux__ 81c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <linux/types.h> 82c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <linux/rtnetlink.h> 83c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef HAVE_GETIFADDRS 84c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define HAVE_GETIFADDRS 85c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define NEED_LINUX_GETIFADDRS 86c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 87c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 89c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef HAVE_GETIFADDRS 90c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic unsigned int if_maxindex __P((void)); 91c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 92c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *)); 93c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int suitable_ifaddr __P((const char *, const struct sockaddr *)); 94c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6 95c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int suitable_ifaddr6 __P((const char *, const struct sockaddr *)); 96c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 98c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef NEED_LINUX_GETIFADDRS 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 100c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* We could do this _much_ better. kame racoon in its current form 101c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * will esentially die at frequent changes of address configuration. 102c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */ 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 104c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstruct ifaddrs 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 106c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifaddrs *ifa_next; 107c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char ifa_name[16]; 108c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int ifa_ifindex; 109c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr *ifa_addr; 110c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_storage ifa_addrbuf; 111c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}; 112f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 113c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) 114c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{ 115c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh while (RTA_OK(rta, len)) { 116c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (rta->rta_type <= max) 117c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh tb[rta->rta_type] = rta; 118c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh rta = RTA_NEXT(rta,len); 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 120c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 123c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic void recvaddrs(int fd, struct ifaddrs **ifa, __u32 seq) 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 125c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char buf[8192]; 126c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_nl nladdr; 127c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct iovec iov = { buf, sizeof(buf) }; 128c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifaddrmsg *m; 129c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct rtattr * rta_tb[IFA_MAX+1]; 130c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifaddrs *I; 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh while (1) { 133c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int status; 134c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct nlmsghdr *h; 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 136c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct msghdr msg = { 137c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh (void*)&nladdr, sizeof(nladdr), 138c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh &iov, 1, 139c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NULL, 0, 140c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 0 141c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh }; 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 143c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh status = recvmsg(fd, &msg, 0); 144f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 145c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (status < 0) 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang continue; 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 148c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (status == 0) 149c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return; 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 151c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (nladdr.nl_pid) /* Message not from kernel */ 152c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 154c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh h = (struct nlmsghdr*)buf; 155c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh while (NLMSG_OK(h, status)) { 156c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (h->nlmsg_seq != seq) 157c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto skip_it; 158c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 159c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (h->nlmsg_type == NLMSG_DONE) 160c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return; 161c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 162c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (h->nlmsg_type == NLMSG_ERROR) 163c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return; 164c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 165c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (h->nlmsg_type != RTM_NEWADDR) 166c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto skip_it; 167c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 168c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh m = NLMSG_DATA(h); 169c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 170c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (m->ifa_family != AF_INET && 171c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh m->ifa_family != AF_INET6) 172c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto skip_it; 173c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 174c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (m->ifa_flags&IFA_F_TENTATIVE) 175c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto skip_it; 176c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 177c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memset(rta_tb, 0, sizeof(rta_tb)); 178c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(m), h->nlmsg_len - NLMSG_LENGTH(sizeof(*m))); 179c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 180c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (rta_tb[IFA_LOCAL] == NULL) 181c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 182c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (rta_tb[IFA_LOCAL] == NULL) 183c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto skip_it; 184c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 185c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh I = malloc(sizeof(struct ifaddrs)); 186c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!I) 187c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return; 188c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memset(I, 0, sizeof(*I)); 189c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 190c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh I->ifa_ifindex = m->ifa_index; 191c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh I->ifa_addr = (struct sockaddr*)&I->ifa_addrbuf; 192c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh I->ifa_addr->sa_family = m->ifa_family; 193c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (m->ifa_family == AF_INET) { 194c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_in *sin = (void*)I->ifa_addr; 195c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memcpy(&sin->sin_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 4); 196c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } else { 197c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_in6 *sin = (void*)I->ifa_addr; 198c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memcpy(&sin->sin6_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 16); 199c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) 200c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin->sin6_scope_id = I->ifa_ifindex; 201c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 202c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh I->ifa_next = *ifa; 203c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *ifa = I; 204c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 205c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehskip_it: 206c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh h = NLMSG_NEXT(h, status); 207c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 208c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (msg.msg_flags & MSG_TRUNC) 209c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 210f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 211c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return; 212f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 214c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int getifaddrs(struct ifaddrs **ifa0) 215f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 216c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct { 217c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct nlmsghdr nlh; 218c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct rtgenmsg g; 219c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } req; 220c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_nl nladdr; 221c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh static __u32 seq; 222c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifaddrs *i; 223c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int fd; 2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 225c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 226c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (fd < 0) 227c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return -1; 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 229c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memset(&nladdr, 0, sizeof(nladdr)); 230c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh nladdr.nl_family = AF_NETLINK; 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 232c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh req.nlh.nlmsg_len = sizeof(req); 233c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh req.nlh.nlmsg_type = RTM_GETADDR; 234c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; 235c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh req.nlh.nlmsg_pid = 0; 236c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh req.nlh.nlmsg_seq = ++seq; 237c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh req.g.rtgen_family = AF_UNSPEC; 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 239c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (sendto(fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) { 240c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(fd); 241f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return -1; 242f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 244c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *ifa0 = NULL; 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 246c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh recvaddrs(fd, ifa0, seq); 2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 248c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(fd); 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 250c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh fd = socket(AF_INET, SOCK_DGRAM, 0); 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 252c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (i=*ifa0; i; i = i->ifa_next) { 253c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifreq ifr; 254c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifr.ifr_ifindex = i->ifa_ifindex; 255c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ioctl(fd, SIOCGIFNAME, (void*)&ifr); 256c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memcpy(i->ifa_name, ifr.ifr_name, 16); 2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 258c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(fd); 259c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 260c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 263c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic void freeifaddrs(struct ifaddrs *ifa0) 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 265c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifaddrs *i; 266f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 267c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh while (ifa0) { 268c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh i = ifa0; 269c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifa0 = i->ifa_next; 270c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh free(i); 271c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 274c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 275c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 276c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef HAVE_GETIFADDRS 277c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic unsigned int 278c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehif_maxindex() 279f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 280c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct if_nameindex *p, *p0; 281c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh unsigned int max = 0; 2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 283c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p0 = if_nameindex(); 284c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (p = p0; p && p->if_index && p->if_name; p++) { 285c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (max < p->if_index) 286c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh max = p->if_index; 2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 288c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if_freenameindex(p0); 289c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return max; 2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 291c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 294c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehclear_myaddr(db) 295c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs **db; 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 297c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p; 2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 299c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh while (*db) { 300c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = (*db)->next; 301c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh delmyaddr(*db); 302c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *db = p; 3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 304f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 305c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 306c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic struct myaddrs * 307c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehfind_myaddr(db, p) 308c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *db; 309c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p; 310f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 311c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *q; 312c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char h1[NI_MAXHOST], h2[NI_MAXHOST]; 3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 314c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (getnameinfo(p->addr, sysdep_sa_len(p->addr), h1, sizeof(h1), NULL, 0, 315c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NI_NUMERICHOST | niflags) != 0) 316c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return NULL; 3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 318c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (q = db; q; q = q->next) { 319c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (p->addr->sa_family != q->addr->sa_family) 320c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 321c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (getnameinfo(q->addr, sysdep_sa_len(q->addr), h2, sizeof(h2), 322c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NULL, 0, NI_NUMERICHOST | niflags) != 0) 323c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return NULL; 324c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (strcmp(h1, h2) == 0) 325c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return q; 3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 328c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return NULL; 329f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 331c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid 332c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehgrab_myaddrs() 333f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 334c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef HAVE_GETIFADDRS 335c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p, *q, *old; 336c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifaddrs *ifa0, *ifap; 337c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6 338c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_in6 *sin6; 339c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 341c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char addr1[NI_MAXHOST]; 3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 343c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (getifaddrs(&ifa0)) { 344c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 345c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "getifaddrs failed: %s\n", strerror(errno)); 346c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 347c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 348c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 350c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh old = lcconf->myaddrs; 3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 352c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (ifap = ifa0; ifap; ifap = ifap->ifa_next) { 353c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (! ifap->ifa_addr) 354c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 356c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ifap->ifa_addr->sa_family != AF_INET 3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6 358c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh && ifap->ifa_addr->sa_family != AF_INET6 359c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 360c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ) 361c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 363c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!suitable_ifaddr(ifap->ifa_name, ifap->ifa_addr)) { 364c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 365c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "unsuitable address: %s %s\n", 366c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifap->ifa_name, 367c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh saddrwop2str(ifap->ifa_addr)); 368c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 369c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 370f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 371c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = newmyaddr(); 372c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (p == NULL) { 373c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 374c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 375c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 376c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->addr = dupsaddr(ifap->ifa_addr); 377c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (p->addr == NULL) { 378c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 379c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 380c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 381c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6 382c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __KAME__ 383c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ifap->ifa_addr->sa_family == AF_INET6) { 384c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6 = (struct sockaddr_in6 *)p->addr; 385c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) 386c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 387c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_scope_id = 388c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); 389c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_addr.s6_addr[2] = 0; 390c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_addr.s6_addr[3] = 0; 391c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 392c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 393c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else /* !__KAME__ */ 394c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ifap->ifa_addr->sa_family == AF_INET6) { 395c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6 = (struct sockaddr_in6 *)p->addr; 396c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) 397c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 398c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_scope_id = 399c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if_nametoindex(ifap->ifa_name); 400c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 401c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 402c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 403c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 404c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 405c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (getnameinfo(p->addr, sysdep_sa_len(p->addr), 406c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh addr1, sizeof(addr1), 407c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NULL, 0, 408c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NI_NUMERICHOST | niflags)) 409c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strlcpy(addr1, "(invalid)", sizeof(addr1)); 410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 411c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "my interface: %s (%s)\n", 412c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh addr1, ifap->ifa_name); 413c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh q = find_myaddr(old, p); 414c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (q) 415c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->sock = q->sock; 416c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh else 417c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->sock = -1; 418c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->next = lcconf->myaddrs; 419c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh lcconf->myaddrs = p; 420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 422c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh freeifaddrs(ifa0); 4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 424c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh clear_myaddr(&old); 4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 426c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else /*!HAVE_GETIFADDRS*/ 427c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int s; 428c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh unsigned int maxif; 429c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int len; 430c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifreq *iflist; 431c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifconf ifconf; 432c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct ifreq *ifr, *ifr_end; 433c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p, *q, *old; 434c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6 435c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __KAME__ 436c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_in6 *sin6; 437c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 438f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif 4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 440c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char addr1[NI_MAXHOST]; 4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 442c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh maxif = if_maxindex() + 1; 443c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh len = maxif * sizeof(struct sockaddr_storage) * 4; /* guess guess */ 444f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 445c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iflist = (struct ifreq *)racoon_malloc(len); 446c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!iflist) { 447c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 448c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "failed to allocate buffer\n"); 449c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 450c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 451c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 453c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 454c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 455c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "socket(SOCK_DGRAM) failed: %s\n", 456c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strerror(errno)); 457c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 458c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 459c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 460c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memset(&ifconf, 0, sizeof(ifconf)); 461c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifconf.ifc_req = iflist; 462c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifconf.ifc_len = len; 463c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) { 464c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(s); 465c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 466c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "ioctl(SIOCGIFCONF) failed: %s\n", 467c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strerror(errno)); 468c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 469c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 470c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 471c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(s); 4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 473c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh old = lcconf->myaddrs; 4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 475c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* Look for this interface in the list */ 476c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len); 477f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 478c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define _IFREQ_LEN(p) \ 479c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh (sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) > sizeof(struct ifreq) \ 480c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ? sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) : sizeof(struct ifreq)) 481f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 482c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (ifr = ifconf.ifc_req; 483c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifr < ifr_end; 484c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifr = (struct ifreq *)((caddr_t)ifr + _IFREQ_LEN(ifr))) { 485f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 486c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh switch (ifr->ifr_addr.sa_family) { 487c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET: 488f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#ifdef INET6 489c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET6: 490f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif 491c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!suitable_ifaddr(ifr->ifr_name, &ifr->ifr_addr)) { 492c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 493c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "unsuitable address: %s %s\n", 494c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifr->ifr_name, 495c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh saddrwop2str(&ifr->ifr_addr)); 496c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 497c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 498c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 499c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = newmyaddr(); 500c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (p == NULL) { 501c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 502c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 503c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 504c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->addr = dupsaddr(&ifr->ifr_addr); 505c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (p->addr == NULL) { 506c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh exit(1); 507c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 508c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 509c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6 510c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __KAME__ 511c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6 = (struct sockaddr_in6 *)p->addr; 512c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) 513c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 514c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_scope_id = 515c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); 516c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_addr.s6_addr[2] = 0; 517c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sin6->sin6_addr.s6_addr[3] = 0; 518c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 519c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 520c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 521c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (getnameinfo(p->addr, sysdep_sa_len(p->addr), 522c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh addr1, sizeof(addr1), 523c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NULL, 0, 524c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh NI_NUMERICHOST | niflags)) 525c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strlcpy(addr1, "(invalid)", sizeof(addr1)); 526c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 527c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "my interface: %s (%s)\n", 528c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh addr1, ifr->ifr_name); 529c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh q = find_myaddr(old, p); 530c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (q) 531c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->sock = q->sock; 532c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh else 533c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->sock = -1; 534c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p->next = lcconf->myaddrs; 535c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh lcconf->myaddrs = p; 536c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 537c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh default: 538c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 539c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 540f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 541f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 542c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh clear_myaddr(&old); 5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 544c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh racoon_free(iflist); 545c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif /*HAVE_GETIFADDRS*/ 5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 548c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* 549c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * check the interface is suitable or not 550c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */ 551f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic int 552c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehsuitable_ifaddr(ifname, ifaddr) 553c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh const char *ifname; 554c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh const struct sockaddr *ifaddr; 5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 556c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_HYBRID 557c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* Exclude any address we got through ISAKMP mode config */ 558c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (exclude_cfg_addr(ifaddr) == 0) 559c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 560c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 561c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh switch(ifaddr->sa_family) { 562c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET: 563c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 1; 564f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#ifdef INET6 565c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET6: 566c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return suitable_ifaddr6(ifname, ifaddr); 5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 568c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh default: 569c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 571c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /*NOTREACHED*/ 5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 574c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6 575f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic int 576c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehsuitable_ifaddr6(ifname, ifaddr) 577c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh const char *ifname; 578c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh const struct sockaddr *ifaddr; 5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 580c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef __linux__ 581c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct in6_ifreq ifr6; 582c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int s; 583c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 585c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ifaddr->sa_family != AF_INET6) 586c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 587c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 588c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef __linux__ 589c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh s = socket(PF_INET6, SOCK_DGRAM, 0); 590c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (s == -1) { 591c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 592c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "socket(SOCK_DGRAM) failed:%s\n", strerror(errno)); 593c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 596c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memset(&ifr6, 0, sizeof(ifr6)); 597c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strncpy(ifr6.ifr_name, ifname, strlen(ifname)); 5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 599c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ifr6.ifr_addr = *(const struct sockaddr_in6 *)ifaddr; 6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 601c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { 6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 603c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "ioctl(SIOCGIFAFLAG_IN6) failed:%s\n", strerror(errno)); 604c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(s); 605c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 608c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(s); 609c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 610c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED 611c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh || ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED 612c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh || ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST) 613c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 614c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 615c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 616c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* suitable */ 617c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 1; 6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 619c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 621c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint 622c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehupdate_myaddrs() 6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 624c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __linux__ 625c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char msg[BUFSIZ]; 626c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int len; 627c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct nlmsghdr *h = (void*)msg; 628c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh len = read(lcconf->rtsock, msg, sizeof(msg)); 629c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (len < 0) 630c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return errno == ENOBUFS; 631c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (len < sizeof(*h)) 632c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 633c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (h->nlmsg_pid) /* not from kernel! */ 634c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 635c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (h->nlmsg_type == RTM_NEWLINK) 636c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 637c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 638c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "netlink signals update interface address list\n"); 639c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 1; 640c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else 641c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh char msg[BUFSIZ]; 642c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int len; 643c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct rt_msghdr *rtm; 6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 645c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh len = read(lcconf->rtsock, msg, sizeof(msg)); 646c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (len < 0) { 647c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 648c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "read(PF_ROUTE) failed: %s\n", 649c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strerror(errno)); 650c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 651f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 652c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh rtm = (struct rt_msghdr *)msg; 653c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (len < rtm->rtm_msglen) { 6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 655c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "read(PF_ROUTE) short read\n"); 656c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 657c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 658c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (rtm->rtm_version != RTM_VERSION) { 659c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 660c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "routing socket version mismatch\n"); 661c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh close(lcconf->rtsock); 662c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh lcconf->rtsock = -1; 663c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 664c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 665c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh switch (rtm->rtm_type) { 666c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case RTM_NEWADDR: 667c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case RTM_DELADDR: 668c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case RTM_DELETE: 669c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case RTM_IFINFO: 670c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 671c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case RTM_MISS: 672c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* ignore this message silently */ 673c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 674c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh default: 675c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 676c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "msg %d not interesting\n", rtm->rtm_type); 677c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 679c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* XXX more filters here? */ 680c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 681c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 682c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "caught rtm:%d, need update interface address list\n", 683c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh rtm->rtm_type); 684c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 1; 685c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif /* __linux__ */ 686f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 688c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* 689c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * initialize default port for ISAKMP to send, if no "listen" 690c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * directive is specified in config file. 691c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * 692c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * DO NOT listen to wildcard addresses. if you receive packets to 693c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * wildcard address, you'll be in trouble (DoS attack possible by 694c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * broadcast storm). 695c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */ 696c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint 697c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehautoconf_myaddrsport() 698f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 699c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p; 700c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int n; 701f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 702c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 703c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "configuring default isakmp port.\n"); 7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 705c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_NATT 706c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (natt_enabled_in_rmconf ()) { 707c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_NOTIFY, LOCATION, NULL, "NAT-T is enabled, autoconfiguring ports\n"); 708c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (p = lcconf->myaddrs; p; p = p->next) { 709c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *new; 710c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (! p->udp_encap) { 711c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new = dupmyaddr(p); 712c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new->udp_encap = 1; 713c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 714c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 715f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 716f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif 717f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 718c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (p = lcconf->myaddrs, n = 0; p; p = p->next, n++) { 719c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh set_port (p->addr, p->udp_encap ? lcconf->port_isakmp_natt : lcconf->port_isakmp); 720c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 721c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, 722c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "%d addrs are configured successfully\n", n); 723f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 724c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 725c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} 726f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 727c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* 728c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * get a port number to which racoon binded. 729c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */ 730c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehu_short 731c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehgetmyaddrsport(local) 732c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr *local; 7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 734c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p, *bestmatch = NULL; 735c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh u_short bestmatch_port = PORT_ISAKMP; 736f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 737c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* get a relative port */ 738c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (p = lcconf->myaddrs; p; p = p->next) { 739c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!p->addr) 740c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 741c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (cmpsaddrwop(local, p->addr)) 742c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 743f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 744c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* use first matching address regardless of port */ 745c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!bestmatch) { 746c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh bestmatch = p; 747c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 748c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 749f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 750c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* matching address with port PORT_ISAKMP */ 751c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (extract_port(p->addr) == PORT_ISAKMP) { 752c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh bestmatch = p; 753c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh bestmatch_port = PORT_ISAKMP; 754c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 755c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 757c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return bestmatch_port; 7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 760c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstruct myaddrs * 761c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehnewmyaddr() 7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 763c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *new; 764f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 765c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new = racoon_calloc(1, sizeof(*new)); 766c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (new == NULL) { 767c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 768c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "failed to allocate buffer for myaddrs.\n"); 769c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return NULL; 7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 771c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 772c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new->next = NULL; 773c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new->addr = NULL; 774c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 775c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return new; 776f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 778c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstruct myaddrs * 779c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehdupmyaddr(struct myaddrs *old) 780f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 781c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *new; 7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 783c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new = racoon_calloc(1, sizeof(*new)); 784c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (new == NULL) { 785c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 786c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "failed to allocate buffer for myaddrs.\n"); 787c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return NULL; 788f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 790c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* Copy the whole structure and set the differences. */ 791c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memcpy (new, old, sizeof (*new)); 792c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new->addr = dupsaddr (old->addr); 793c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (new->addr == NULL) { 794c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 795c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "failed to allocate buffer for myaddrs.\n"); 796c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh racoon_free(new); 797c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return NULL; 7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 799c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new->next = old->next; 800c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh old->next = new; 801f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 802c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return new; 803f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 804f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 805c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid 806c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehinsmyaddr(new, head) 807c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *new; 808c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs **head; 809f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 810c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh new->next = *head; 811c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *head = new; 812c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} 813c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 814c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid 815c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehdelmyaddr(myaddr) 816c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *myaddr; 817c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{ 818c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (myaddr->addr) 819c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh racoon_free(myaddr->addr); 820c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh racoon_free(myaddr); 821c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} 822f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 823c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint 824c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehinitmyaddr() 825c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{ 826c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* initialize routing socket */ 827c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh lcconf->rtsock = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); 828c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (lcconf->rtsock < 0) { 8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 830f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh "socket(PF_ROUTE) failed: %s", 831f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh strerror(errno)); 8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 835c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __linux__ 836c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh { 837c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr_nl nl; 838c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh u_int addr_len; 8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 840c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memset(&nl, 0, sizeof(nl)); 841c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh nl.nl_family = AF_NETLINK; 842c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh nl.nl_groups = RTMGRP_IPV4_IFADDR|RTMGRP_LINK|RTMGRP_IPV6_IFADDR; 843c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 844c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (bind(lcconf->rtsock, (struct sockaddr*)&nl, sizeof(nl)) < 0) { 845c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 846c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "bind(PF_NETLINK) failed: %s\n", 847c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strerror(errno)); 848c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return -1; 8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 850c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh addr_len = sizeof(nl); 851c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (getsockname(lcconf->rtsock, (struct sockaddr*)&nl, &addr_len) < 0) { 852c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 853c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "getsockname(PF_NETLINK) failed: %s\n", 854c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh strerror(errno)); 855c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return -1; 856c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 857c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 858c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (lcconf->myaddrs == NULL && lcconf->autograbaddr == 1) { 861c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh grab_myaddrs(); 8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (autoconf_myaddrsport() < 0) 864c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return -1; 865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 867c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return 0; 868c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} 8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 870c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* select the socket to be sent */ 871c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* should implement other method. */ 872c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint 873c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehgetsockmyaddr(my) 874c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct sockaddr *my; 875c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{ 876c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *p, *lastresort = NULL; 877c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if defined(INET6) && defined(__linux__) 878c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct myaddrs *match_wo_scope_id = NULL; 879c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int check_wo_scope_id = (my->sa_family == AF_INET6) && 880c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)my)->sin6_addr); 881f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif 882c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 883c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh for (p = lcconf->myaddrs; p; p = p->next) { 884c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (p->addr == NULL) 885c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh continue; 886c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (my->sa_family == p->addr->sa_family) { 887c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh lastresort = p; 888c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } else continue; 889c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (sysdep_sa_len(my) == sysdep_sa_len(p->addr) 890c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh && memcmp(my, p->addr, sysdep_sa_len(my)) == 0) { 891c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 892c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 893c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if defined(INET6) && defined(__linux__) 894c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (check_wo_scope_id && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)p->addr)->sin6_addr) && 895c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* XXX: this depends on sin6_scope_id to be last 896c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * item in struct sockaddr_in6 */ 897c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh memcmp(my, p->addr, 898c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sysdep_sa_len(my) - sizeof(uint32_t)) == 0) { 899c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh match_wo_scope_id = p; 900c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 901c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 902c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 903c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if defined(INET6) && defined(__linux__) 904c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!p) 905c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = match_wo_scope_id; 906c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 907c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!p) 908c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = lastresort; 909c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (!p) { 910c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 911c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "no socket matches address family %d\n", 912c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh my->sa_family); 913c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return -1; 914c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 915c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 916c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return p->sock; 917c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} 918