summaryrefslogtreecommitdiff
path: root/usr.sbin/rtsold/if.c
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-01-05 01:54:51 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-01-05 01:54:51 +0000
commitd32ab4f9ef9ff71bfad38f9aad0fa6b42400e96b (patch)
tree1759b1dd11affcfa1498bf0c142922bdde4bae5a /usr.sbin/rtsold/if.c
parent94a111eedec4fd64f875c29bb5d623c000bbc8c1 (diff)
avoid use of kvm (sync with latest kame)
Diffstat (limited to 'usr.sbin/rtsold/if.c')
-rw-r--r--usr.sbin/rtsold/if.c174
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)
{