diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-01-05 01:54:51 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-01-05 01:54:51 +0000 |
commit | d32ab4f9ef9ff71bfad38f9aad0fa6b42400e96b (patch) | |
tree | 1759b1dd11affcfa1498bf0c142922bdde4bae5a /usr.sbin/rtsold/if.c | |
parent | 94a111eedec4fd64f875c29bb5d623c000bbc8c1 (diff) |
avoid use of kvm (sync with latest kame)
Diffstat (limited to 'usr.sbin/rtsold/if.c')
-rw-r--r-- | usr.sbin/rtsold/if.c | 174 |
1 files changed, 78 insertions, 96 deletions
diff --git a/usr.sbin/rtsold/if.c b/usr.sbin/rtsold/if.c index 314d1c902a8..a991234a161 100644 --- a/usr.sbin/rtsold/if.c +++ b/usr.sbin/rtsold/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.2 1999/12/09 15:10:49 itojun Exp $ */ +/* $OpenBSD: if.c,v 1.3 2000/01/05 01:54:50 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -64,15 +64,14 @@ #include <string.h> #include <fcntl.h> #include <errno.h> -#include <kvm.h> -#include <nlist.h> #include <limits.h> #include "rtsold.h" static int ifsock; -static int getifa __P((char *name, struct in6_ifaddr *ifap)); +static int get_llflag __P((const char *name)); +static unsigned int if_maxindex __P((void)); static void get_rtaddrs __P((int addrs, struct sockaddr *sa, struct sockaddr **rti_info)); @@ -91,7 +90,7 @@ int interface_up(char *name) { struct ifreq ifr; - struct in6_ifaddr ifa; + int llflag; strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); @@ -111,24 +110,24 @@ interface_up(char *name) warnmsg(LOG_DEBUG, __FUNCTION__, "checking if %s is ready...", name); - if (getifa(name, &ifa) < 0) { + llflag = get_llflag(name); + if (llflag < 0) { warnmsg(LOG_WARNING, __FUNCTION__, - "getifa() failed, anyway I'll try"); + "get_llflag() failed, anyway I'll try"); return 0; } - if (!(ifa.ia6_flags & IN6_IFF_NOTREADY)) { + if (!(llflag & IN6_IFF_NOTREADY)) { warnmsg(LOG_DEBUG, __FUNCTION__, "%s is ready", name); return(0); - } - else { - if (ifa.ia6_flags & IN6_IFF_TENTATIVE) { + } else { + if (llflag & IN6_IFF_TENTATIVE) { warnmsg(LOG_DEBUG, __FUNCTION__, "%s is tentative", name); return IFS_TENTATIVE; } - if (ifa.ia6_flags & IN6_IFF_DUPLICATED) + if (llflag & IN6_IFF_DUPLICATED) warnmsg(LOG_DEBUG, __FUNCTION__, "%s is duplicated", name); return -1; @@ -310,105 +309,88 @@ getinet6sysctl(int code) /*------------------------------------------------------------*/ -static struct nlist nl[] = { -#define N_IFNET 0 - { "_ifnet" }, - { "" }, -}; - -#define KREAD(x, y, z) { \ - if (kvm_read(kvmd, (u_long)x, (void *)y, sizeof(z)) != sizeof(z)) { \ - warnmsg(LOG_ERR, __FUNCTION__, "kvm_read failed"); \ - goto bad; \ - } \ - } - +/* get ia6_flags for link-local addr on if. returns -1 on error. */ static int -getifa(char *name, struct in6_ifaddr *ifap) +get_llflag(const char *name) { - u_short index; - kvm_t *kvmd = NULL; - char buf[_POSIX2_LINE_MAX]; - struct ifnet *ifp; - struct ifnet ifnet; - struct in6_ifaddr *ifa; - - if (!ifap) + int s; + unsigned int maxif; + struct ifreq *iflist; + struct ifconf ifconf; + struct ifreq *ifr, *ifr_end; + struct sockaddr_in6 *sin6; + struct in6_ifreq ifr6; + + maxif = if_maxindex() + 1; + iflist = (struct ifreq *)malloc(maxif * BUFSIZ); /* XXX */ + if (iflist == NULL) { + warnmsg(LOG_ERR, __FUNCTION__, "not enough core"); exit(1); - - index = (u_short)if_nametoindex(name); - if (index == 0) { - warnmsg(LOG_ERR, __FUNCTION__, "if_nametoindex failed for %s", - name); - goto bad; - } - if ((kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf)) == NULL) { - warnmsg(LOG_ERR, __FUNCTION__, "kvm_openfiles failed"); - goto bad; - } - if (kvm_nlist(kvmd, nl) < 0) { - warnmsg(LOG_ERR, __FUNCTION__, "kvm_nlist failed"); - goto bad; - } - if (nl[N_IFNET].n_value == 0) { - warnmsg(LOG_ERR, __FUNCTION__, "symbol \"%s\" not found", - nl[N_IFNET].n_name); - goto bad; } - KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *); - while (ifp) { - KREAD(ifp, &ifnet, struct ifnet); - if (ifnet.if_index == index) - break; -#if defined(__NetBSD__) || defined(__OpenBSD__) - ifp = TAILQ_NEXT(&ifnet, if_list); -#elif defined(__FreeBSD__) && __FreeBSD__ >= 3 - ifp = TAILQ_NEXT(&ifnet, if_link); -#else - ifp = ifnet.if_next; -#endif + if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "socket(SOCK_DGRAM): %s", + strerror(errno)); + exit(1); } - if (!ifp) { - warnmsg(LOG_ERR, __FUNCTION__, "interface \"%s\" not found", - name); - goto bad; + memset(&ifconf, 0, sizeof(ifconf)); + ifconf.ifc_req = iflist; + ifconf.ifc_len = maxif * BUFSIZ; /* XXX */ + if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGIFCONF): %s", + strerror(errno)); + exit(1); } -#if defined(__NetBSD__) || defined(__OpenBSD__) - ifa = (struct in6_ifaddr *)TAILQ_FIRST(&ifnet.if_addrlist); -#elif defined(__FreeBSD__) && __FreeBSD__ >= 3 - ifa = (struct in6_ifaddr *)TAILQ_FIRST(&ifnet.if_addrhead); -#else - ifa = (struct in6_ifaddr *)ifnet.if_addrlist; -#endif - while (ifa) { - KREAD(ifa, ifap, *ifap); - if (ifap->ia_addr.sin6_family == AF_INET6 - && IN6_IS_ADDR_LINKLOCAL(&ifap->ia_addr.sin6_addr)) { - kvm_close(kvmd); - return 0; + /* Look for this interface in the list */ + ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len); + for (ifr = ifconf.ifc_req; + ifr < ifr_end; + ifr = (struct ifreq *) ((char *) &ifr->ifr_addr + + ifr->ifr_addr.sa_len)) { + if (strlen(ifr->ifr_name) != strlen(name) + || strncmp(ifr->ifr_name, name, strlen(name)) != 0) + continue; + if (ifr->ifr_addr.sa_family != AF_INET6) + continue; + sin6 = (struct sockaddr_in6 *)&ifr->ifr_addr; + if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + continue; + + memset(&ifr6, 0, sizeof(ifr6)); + strcpy(ifr6.ifr_name, name); + memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len); + if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, + "ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno)); + exit(1); } -#if defined(__NetBSD__) || defined(__OpenBSD__) - ifa = (struct in6_ifaddr *) - TAILQ_NEXT((struct ifaddr *)ifap, ifa_list); -#elif defined(__FreeBSD__) && __FreeBSD__ >= 3 - ifa = (struct in6_ifaddr *) - TAILQ_NEXT((struct ifaddr *)ifap, ifa_link); -#else - ifa = (struct in6_ifaddr *)(((struct ifaddr *)ifap)->ifa_next); -#endif + free(iflist); + close(s); + return ifr6.ifr_ifru.ifru_flags6; } - warnmsg(LOG_ERR, __FUNCTION__, "no IPv6 link-local address for %s", - name); - bad: - if (kvmd) - kvm_close(kvmd); + free(iflist); + close(s); return -1; } +static unsigned int +if_maxindex() +{ + struct if_nameindex *p, *p0; + unsigned int max = 0; + + p0 = if_nameindex(); + for (p = p0; p && p->if_index && p->if_name; p++) { + if (max < p->if_index) + max = p->if_index; + } + if_freenameindex(p0); + return max; +} + static void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) { |