Module Name: src Committed By: roy Date: Fri Sep 30 16:47:56 UTC 2016
Modified Files: src/sbin/ifconfig: af_inet.c af_inet6.c Log Message: ifaddrs has more data than just the address. Use it instead of making pointless ioctl calls. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sbin/ifconfig/af_inet.c cvs rdiff -u -r1.36 -r1.37 src/sbin/ifconfig/af_inet6.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/ifconfig/af_inet.c diff -u src/sbin/ifconfig/af_inet.c:1.20 src/sbin/ifconfig/af_inet.c:1.21 --- src/sbin/ifconfig/af_inet.c:1.20 Tue Sep 13 00:20:51 2016 +++ src/sbin/ifconfig/af_inet.c Fri Sep 30 16:47:56 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: af_inet.c,v 1.20 2016/09/13 00:20:51 christos Exp $ */ +/* $NetBSD: af_inet.c,v 1.21 2016/09/30 16:47:56 roy Exp $ */ /* * Copyright (c) 1983, 1993 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: af_inet.c,v 1.20 2016/09/13 00:20:51 christos Exp $"); +__RCSID("$NetBSD: af_inet.c,v 1.21 2016/09/30 16:47:56 roy Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -62,11 +62,10 @@ __RCSID("$NetBSD: af_inet.c,v 1.20 2016/ static void in_constructor(void) __attribute__((constructor)); static void in_status(prop_dictionary_t, prop_dictionary_t, bool); static void in_commit_address(prop_dictionary_t, prop_dictionary_t); -static bool in_addr_flags(struct ifaddrs *, int); static bool in_addr_tentative(struct ifaddrs *); static bool in_addr_tentative_or_detached(struct ifaddrs *); -static void in_alias(const char *, prop_dictionary_t, prop_dictionary_t, - struct in_aliasreq *); +static void in_alias(struct ifaddrs *, prop_dictionary_t, prop_dictionary_t, + bool); static struct afswtch af = { .af_name = "inet", .af_af = AF_INET, .af_status = in_status, @@ -76,94 +75,50 @@ static struct afswtch af = { }; static void -in_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv, - struct in_aliasreq *creq) +in_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv, + bool alias) { - struct ifreq ifr; - bool alias; - int s; - unsigned short flags; - struct in_aliasreq in_addreq; - const struct sockaddr_in * const asin = &in_addreq.ifra_addr; - const struct sockaddr_in * const dsin = &in_addreq.ifra_dstaddr; - const struct sockaddr_in * const bsin = &in_addreq.ifra_broadaddr; + struct sockaddr_in sin; char hbuf[NI_MAXHOST]; const int niflag = Nflag ? 0 : NI_NUMERICHOST; + char fbuf[1024]; if (lflag) return; - alias = true; - - /* Get the non-alias address for this interface. */ - if ((s = getsock(AF_INET)) == -1) { - if (errno == EAFNOSUPPORT) - return; - err(EXIT_FAILURE, "socket"); - } - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (prog_ioctl(s, SIOCGIFADDR, &ifr) == -1) { - if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) - return; - warn("SIOCGIFADDR"); - } - /* If creq and ifr are the same address, this is not an alias. */ - if (memcmp(&ifr.ifr_addr, &creq->ifra_addr, sizeof(ifr.ifr_addr)) == 0) - alias = false; - in_addreq = *creq; - if (prog_ioctl(s, SIOCGIFALIAS, &in_addreq) == -1) { - if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { - return; - } else - warn("SIOCGIFALIAS"); - } - - if (getnameinfo((const struct sockaddr *)asin, asin->sin_len, + if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, hbuf, sizeof(hbuf), NULL, 0, niflag)) strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ printf("\tinet %s%s", alias ? "alias " : "", hbuf); - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - if (flags & IFF_POINTOPOINT) { - if (getnameinfo((const struct sockaddr *)dsin, dsin->sin_len, + if (ifa->ifa_flags & IFF_POINTOPOINT) { + if (getnameinfo(ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, hbuf, sizeof(hbuf), NULL, 0, niflag)) strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ printf(" -> %s", hbuf); } - printf(" netmask 0x%x", ntohl(in_addreq.ifra_mask.sin_addr.s_addr)); + memcpy(&sin, ifa->ifa_netmask, ifa->ifa_netmask->sa_len); + printf(" netmask 0x%x", ntohl(sin.sin_addr.s_addr)); - if (flags & IFF_BROADCAST) { - if (getnameinfo((const struct sockaddr *)bsin, bsin->sin_len, + if (ifa->ifa_flags & IFF_BROADCAST) { + if (getnameinfo(ifa->ifa_broadaddr, ifa->ifa_broadaddr->sa_len, hbuf, sizeof(hbuf), NULL, 0, niflag)) strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ printf(" broadcast %s", hbuf); } -#ifdef IN_IFF_TENTATIVE - memcpy(&ifr.ifr_addr, &creq->ifra_addr, creq->ifra_addr.sin_len); - if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFAFLAG_IN"); - } else { - char fbuf[1024]; - (void)snprintb(fbuf, sizeof(fbuf), IN_IFFBITS, - ifr.ifr_addrflags); - printf(" flags %s", fbuf); - } -#endif + (void)snprintb(fbuf, sizeof(fbuf), IN_IFFBITS, ifa->ifa_addrflags); + printf(" flags %s", fbuf); } static void in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) { struct ifaddrs *ifap, *ifa; - struct in_aliasreq ifra; bool printprefs = false; const char *ifname; + int alias = 0; if ((ifname = getifname(env)) == NULL) err(EXIT_FAILURE, "%s: getifname", __func__); @@ -178,13 +133,8 @@ in_status(prop_dictionary_t env, prop_di continue; if (ifa->ifa_addr->sa_family != AF_INET) continue; - if (sizeof(ifra.ifra_addr) < ifa->ifa_addr->sa_len) - continue; - - memset(&ifra, 0, sizeof(ifra)); - estrlcpy(ifra.ifra_name, ifa->ifa_name, sizeof(ifra.ifra_name)); - memcpy(&ifra.ifra_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); - in_alias(ifa->ifa_name, env, oenv, &ifra); + /* The first address is not an alias. */ + in_alias(ifa, env, oenv, alias++); if (printprefs) ifa_print_preference(ifa->ifa_name, ifa->ifa_addr); printf("\n"); @@ -244,7 +194,7 @@ static bool in_addr_tentative(struct ifaddrs *ifa) { -#ifdef IN_IFF_TENTATIVE +#ifdef SIOCGIFAFLAG_IN return in_addr_flags(ifa, IN_IFF_TENTATIVE); #else return false; @@ -255,7 +205,7 @@ static bool in_addr_tentative_or_detached(struct ifaddrs *ifa) { -#ifdef IN_IFF_TENTATIVE +#ifdef SIOCGIFAFLAG_IN return in_addr_flags(ifa, IN_IFF_TENTATIVE | IN_IFF_DETACHED); #else return false; Index: src/sbin/ifconfig/af_inet6.c diff -u src/sbin/ifconfig/af_inet6.c:1.36 src/sbin/ifconfig/af_inet6.c:1.37 --- src/sbin/ifconfig/af_inet6.c:1.36 Tue Sep 13 00:20:51 2016 +++ src/sbin/ifconfig/af_inet6.c Fri Sep 30 16:47:56 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: af_inet6.c,v 1.36 2016/09/13 00:20:51 christos Exp $ */ +/* $NetBSD: af_inet6.c,v 1.37 2016/09/30 16:47:56 roy Exp $ */ /* * Copyright (c) 1983, 1993 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: af_inet6.c,v 1.36 2016/09/13 00:20:51 christos Exp $"); +__RCSID("$NetBSD: af_inet6.c,v 1.37 2016/09/30 16:47:56 roy Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -60,8 +60,7 @@ __RCSID("$NetBSD: af_inet6.c,v 1.36 2016 #include "prog_ops.h" static void in6_constructor(void) __attribute__((constructor)); -static void in6_alias(const char *, prop_dictionary_t, prop_dictionary_t, - struct in6_ifreq *); +static void in6_alias(struct ifaddrs *, prop_dictionary_t, prop_dictionary_t); static void in6_commit_address(prop_dictionary_t, prop_dictionary_t); static int setia6eui64_impl(prop_dictionary_t, struct in6_aliasreq *); @@ -72,7 +71,6 @@ static int setia6vltime_impl(prop_dictio static int setia6lifetime(prop_dictionary_t, int64_t, time_t *, uint32_t *); static void in6_status(prop_dictionary_t, prop_dictionary_t, bool); -static bool in6_addr_flags(struct ifaddrs *ifa, int); static bool in6_addr_tentative(struct ifaddrs *ifa); static bool in6_addr_tentative_or_detached(struct ifaddrs *ifa); @@ -262,46 +260,25 @@ setia6eui64_impl(prop_dictionary_t env, /* XXX not really an alias */ void -in6_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv, - struct in6_ifreq *creq) +in6_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv) { - struct in6_ifreq ifr6; struct sockaddr_in6 *sin6; char hbuf[NI_MAXHOST]; u_int32_t scopeid; - int s; const int niflag = Nflag ? 0 : NI_NUMERICHOST; - unsigned short flags; - - /* Get the non-alias address for this interface. */ - if ((s = getsock(AF_INET6)) == -1) { - if (errno == EAFNOSUPPORT) - return; - err(EXIT_FAILURE, "socket"); - } - - sin6 = &creq->ifr_addr; + char fbuf[1024]; + sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); scopeid = sin6->sin6_scope_id; if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len, hbuf, sizeof(hbuf), NULL, 0, niflag)) strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ printf("\tinet6 %s", hbuf); + inet6_putscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - if (flags & IFF_POINTOPOINT) { - ifr6 = *creq; - if (prog_ioctl(s, SIOCGIFDSTADDR_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFDSTADDR_IN6"); - memset(&ifr6.ifr_addr, 0, sizeof(ifr6.ifr_addr)); - ifr6.ifr_addr.sin6_family = AF_INET6; - ifr6.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); - } - sin6 = &ifr6.ifr_addr; + if (ifa->ifa_flags & IFF_POINTOPOINT) { + sin6 = (struct sockaddr_in6 *)ifa->ifa_dstaddr; inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); hbuf[0] = '\0'; if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, @@ -310,33 +287,30 @@ in6_alias(const char *ifname, prop_dicti printf(" -> %s", hbuf); } - ifr6 = *creq; - if (prog_ioctl(s, SIOCGIFNETMASK_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFNETMASK_IN6"); - } else { - sin6 = &ifr6.ifr_addr; - printf(" prefixlen %d", prefix(&sin6->sin6_addr, - sizeof(struct in6_addr))); - } - - ifr6 = *creq; - if (prog_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFAFLAG_IN6"); - } else { - char fbuf[1024]; - (void)snprintb(fbuf, sizeof(fbuf), IN6_IFFBITS, - ifr6.ifr_ifru.ifru_flags6); - printf(" flags %s", fbuf); - } + sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask; + printf(" prefixlen %d", prefix(&sin6->sin6_addr, + sizeof(struct in6_addr))); + + (void)snprintb(fbuf, sizeof(fbuf), IN6_IFFBITS, ifa->ifa_addrflags); + printf(" flags %s", fbuf); if (scopeid) printf(" scopeid 0x%x", scopeid); if (get_flag('L')) { + int s; + struct in6_ifreq ifr6; struct in6_addrlifetime *lifetime; - ifr6 = *creq; + + if ((s = getsock(AF_INET6)) == -1) { + if (errno == EAFNOSUPPORT) + return; + err(EXIT_FAILURE, "socket"); + } + + memset(&ifr6, 0, sizeof(ifr6)); + estrlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); + memcpy(&ifr6.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); lifetime = &ifr6.ifr_ifru.ifru_lifetime; if (prog_ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) == -1) { if (errno != EADDRNOTAVAIL) @@ -366,7 +340,6 @@ static void in6_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) { struct ifaddrs *ifap, *ifa; - struct in6_ifreq ifr; const char *ifname; bool printprefs = false; @@ -381,13 +354,7 @@ in6_status(prop_dictionary_t env, prop_d continue; if (ifa->ifa_addr->sa_family != AF_INET6) continue; - if (sizeof(ifr.ifr_addr) < ifa->ifa_addr->sa_len) - continue; - - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); - memcpy(&ifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); - in6_alias(ifname, env, oenv, &ifr); + in6_alias(ifa, env, oenv); if (printprefs) ifa_print_preference(ifa->ifa_name, ifa->ifa_addr); printf("\n");