Module Name: src Committed By: bouyer Date: Sun May 3 13:17:52 UTC 2009
Modified Files: src/lib/libc/net [netbsd-5]: getifaddrs.3 getifaddrs.c src/sbin/ifconfig [netbsd-5]: af_link.c ifconfig.c util.c util.h Log Message: Pull up following revision(s) (requested by dyoung in ticket #730): sbin/ifconfig/af_link.c: revisions 1.4 - 1.6 sbin/ifconfig/util.h: revision 1.7 sbin/ifconfig/util.c: revisions 1.10, 1.11 lib/libc/net/getifaddrs.c: revision 1.12 lib/libc/net/getifaddrs.3: revision 1.10 sbin/ifconfig/ifconfig.c: revisions 1.216 - 1.218 Fix indentation: change spaces to tabs. Use getnameinfo(3) to render a human-readable link-layer address in the 'address: ' line, just as we do in the 'link xx:xx:...:xx' line. There's no use casting a socket address to sockaddr_dl, only to cast it back to sockaddr, so don't do it. Cosmetic: add some whitespace for my ease of reading. To make sure that we always print the active link-layer address in the 'address: ' field, don't treat the first address as the active address, but search the link-layer addresses for the ones flagged IFLR_ACTIVE, and print those. Extract a subroutine, print_link_addresses(), for printing link-layer addresses. For non-AF_LINK ifaddrs, ifa_data is NULL. AFAICT, this has always been so. Say so in the documentation. Bring getifaddrs(3) behavior in line with the documentation: the ifa_data member of every AF_LINK struct ifaddrs points at the corresponding struct if_data. In ifconfig(8), do not try to suppress duplicate AF_LINK ifaddrs by checking for a NULL ifa_data. Don't copy out two AF_LINK struct ifaddrs for each active link-layer address. getifaddrs(3) used to copy out one ifaddrs for the kernel's RTM_IFINFO message, and one more for the kernel's RTM_NEWADDR message. I suppress the first duplicate with a highly conservative change that wastes a little bit of ifaddrs storage. The storage is not leaked. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.8.38.1 src/lib/libc/net/getifaddrs.3 cvs rdiff -u -r1.11 -r1.11.12.1 src/lib/libc/net/getifaddrs.c cvs rdiff -u -r1.3 -r1.3.2.1 src/sbin/ifconfig/af_link.c cvs rdiff -u -r1.213.2.1 -r1.213.2.2 src/sbin/ifconfig/ifconfig.c cvs rdiff -u -r1.8 -r1.8.2.1 src/sbin/ifconfig/util.c cvs rdiff -u -r1.6 -r1.6.2.1 src/sbin/ifconfig/util.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/net/getifaddrs.3 diff -u src/lib/libc/net/getifaddrs.3:1.8 src/lib/libc/net/getifaddrs.3:1.8.38.1 --- src/lib/libc/net/getifaddrs.3:1.8 Wed Apr 16 13:34:42 2003 +++ src/lib/libc/net/getifaddrs.3 Sun May 3 13:17:52 2009 @@ -1,4 +1,4 @@ -.\" $NetBSD: getifaddrs.3,v 1.8 2003/04/16 13:34:42 wiz Exp $ +.\" $NetBSD: getifaddrs.3,v 1.8.38.1 2009/05/03 13:17:52 bouyer Exp $ .\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp .\" .\" Copyright (c) 1995, 1999 @@ -114,10 +114,7 @@ .Fa struct if_data .Pq as defined in include file Aq Pa net/if.h which contains various interface attributes and statistics. -For all other address families, it contains a pointer to the -.Fa struct ifa_data -.Pq as defined in include file Aq Pa net/if.h -which contains per-address interface statistics. +For all other address families, it is NULL. .Pp The data returned by .Fn getifaddrs Index: src/lib/libc/net/getifaddrs.c diff -u src/lib/libc/net/getifaddrs.c:1.11 src/lib/libc/net/getifaddrs.c:1.11.12.1 --- src/lib/libc/net/getifaddrs.c:1.11 Thu Dec 6 22:51:57 2007 +++ src/lib/libc/net/getifaddrs.c Sun May 3 13:17:52 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: getifaddrs.c,v 1.11 2007/12/06 22:51:57 dyoung Exp $ */ +/* $NetBSD: getifaddrs.c,v 1.11.12.1 2009/05/03 13:17:52 bouyer Exp $ */ /* * Copyright (c) 1995, 1999 @@ -27,7 +27,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: getifaddrs.c,v 1.11 2007/12/06 22:51:57 dyoung Exp $"); +__RCSID("$NetBSD: getifaddrs.c,v 1.11.12.1 2009/05/03 13:17:52 bouyer Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -64,12 +64,11 @@ size_t needed; char *buf; char *next; - struct ifaddrs *cif = 0; + struct ifaddrs cif; char *p, *p0; struct rt_msghdr *rtm; struct if_msghdr *ifm; struct ifa_msghdr *ifam; - struct sockaddr_dl *dl; struct sockaddr *sa; struct ifaddrs *ifa, *ift; u_short idx = 0; @@ -103,10 +102,12 @@ case RTM_IFINFO: ifm = (struct if_msghdr *)(void *)rtm; if (ifm->ifm_addrs & RTA_IFP) { + const struct sockaddr_dl *dl; + idx = ifm->ifm_index; ++icnt; dl = (struct sockaddr_dl *)(void *)(ifm + 1); - dcnt += SA_RLEN((struct sockaddr *)(void*)dl) + + dcnt += SA_RLEN((const struct sockaddr *)(const void *)dl) + ALIGNBYTES; dcnt += sizeof(ifm->ifm_data); ncnt += dl->sdl_nlen + 1; @@ -181,28 +182,28 @@ case RTM_IFINFO: ifm = (struct if_msghdr *)(void *)rtm; if (ifm->ifm_addrs & RTA_IFP) { + const struct sockaddr_dl *dl; + idx = ifm->ifm_index; dl = (struct sockaddr_dl *)(void *)(ifm + 1); - cif = ift; - ift->ifa_name = names; - ift->ifa_flags = (int)ifm->ifm_flags; + memset(&cif, 0, sizeof(cif)); + + cif.ifa_name = names; + cif.ifa_flags = (int)ifm->ifm_flags; memcpy(names, dl->sdl_data, (size_t)dl->sdl_nlen); names[dl->sdl_nlen] = 0; names += dl->sdl_nlen + 1; - ift->ifa_addr = (struct sockaddr *)(void *)data; - memcpy(data, dl, (size_t)((struct sockaddr *) - (void *)dl)->sa_len); - data += SA_RLEN((struct sockaddr *)(void *)dl); + cif.ifa_addr = (struct sockaddr *)(void *)data; + memcpy(data, dl, (size_t)dl->sdl_len); + data += SA_RLEN((const struct sockaddr *)(const void *)dl); /* ifm_data needs to be aligned */ - ift->ifa_data = data = (void *)ALIGN(data); + cif.ifa_data = data = (void *)ALIGN(data); memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); data += sizeof(ifm->ifm_data); - - ift = (ift->ifa_next = ift + 1); } else idx = 0; break; @@ -214,8 +215,8 @@ if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) break; - ift->ifa_name = cif->ifa_name; - ift->ifa_flags = cif->ifa_flags; + ift->ifa_name = cif.ifa_name; + ift->ifa_flags = cif.ifa_flags; ift->ifa_data = NULL; p = (char *)(void *)(ifam + 1); /* Scan to look for length of address */ @@ -244,6 +245,8 @@ (struct sockaddr *)(void *)data; memcpy(data, p, len); data += len; + if (ift->ifa_addr->sa_family == AF_LINK) + ift->ifa_data = cif.ifa_data; break; case RTAX_NETMASK: Index: src/sbin/ifconfig/af_link.c diff -u src/sbin/ifconfig/af_link.c:1.3 src/sbin/ifconfig/af_link.c:1.3.2.1 --- src/sbin/ifconfig/af_link.c:1.3 Wed Jul 2 07:44:14 2008 +++ src/sbin/ifconfig/af_link.c Sun May 3 13:17:52 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: af_link.c,v 1.3 2008/07/02 07:44:14 dyoung Exp $ */ +/* $NetBSD: af_link.c,v 1.3.2.1 2009/05/03 13:17:52 bouyer Exp $ */ /*- * Copyright (c) 2008 David Young. All rights reserved. @@ -27,7 +27,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: af_link.c,v 1.3 2008/07/02 07:44:14 dyoung Exp $"); +__RCSID("$NetBSD: af_link.c,v 1.3.2.1 2009/05/03 13:17:52 bouyer Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -74,56 +74,7 @@ static void link_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) { - const char *delim, *ifname; - int i, s; - struct ifaddrs *ifa, *ifap; - const struct sockaddr_dl *sdl; - struct if_laddrreq iflr; - const uint8_t *octets; - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "%s: getifname", __func__); - - if ((s = getsock(AF_LINK)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - if (getifaddrs(&ifap) == -1) - err(EXIT_FAILURE, "%s: getifaddrs", __func__); - - memset(&iflr, 0, sizeof(iflr)); - - strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name)); - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ifname, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_LINK) - continue; - if (ifa->ifa_data != NULL) - continue; - - sdl = satocsdl(ifa->ifa_addr); - - memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len, - sizeof(iflr.addr))); - iflr.flags = IFLR_PREFIX; - iflr.prefixlen = sdl->sdl_alen * NBBY; - - if (ioctl(s, SIOCGLIFADDR, &iflr) == -1) - err(EXIT_FAILURE, "%s: ioctl", __func__); - - if ((iflr.flags & IFLR_ACTIVE) != 0) - continue; - - octets = (const uint8_t *)&sdl->sdl_data[sdl->sdl_nlen]; - - delim = "\tlink "; - for (i = 0; i < sdl->sdl_alen; i++) { - printf("%s%02" PRIx8, delim, octets[i]); - delim = ":"; - } - printf("\n"); - } + print_link_addresses(env, false); } static int Index: src/sbin/ifconfig/ifconfig.c diff -u src/sbin/ifconfig/ifconfig.c:1.213.2.1 src/sbin/ifconfig/ifconfig.c:1.213.2.2 --- src/sbin/ifconfig/ifconfig.c:1.213.2.1 Sat Apr 4 18:22:54 2009 +++ src/sbin/ifconfig/ifconfig.c Sun May 3 13:17:52 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ifconfig.c,v 1.213.2.1 2009/04/04 18:22:54 snj Exp $ */ +/* $NetBSD: ifconfig.c,v 1.213.2.2 2009/05/03 13:17:52 bouyer Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1983, 1993\ The Regents of the University of California. All rights reserved."); -__RCSID("$NetBSD: ifconfig.c,v 1.213.2.1 2009/04/04 18:22:54 snj Exp $"); +__RCSID("$NetBSD: ifconfig.c,v 1.213.2.2 2009/05/03 13:17:52 bouyer Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -126,7 +126,7 @@ static int setifmtu(prop_dictionary_t, prop_dictionary_t); static int setifnetmask(prop_dictionary_t, prop_dictionary_t); static int setifprefixlen(prop_dictionary_t, prop_dictionary_t); -static void status(const struct sockaddr_dl *, prop_dictionary_t, +static void status(const struct sockaddr *, prop_dictionary_t, prop_dictionary_t); static void usage(void); @@ -724,7 +724,7 @@ { struct ifaddrs *ifap, *ifa; struct ifreq ifr; - const struct sockaddr_dl *sdl = NULL; + const struct sockaddr *sdl = NULL; prop_dictionary_t env, oenv; int idx; char *p; @@ -754,7 +754,7 @@ if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) continue; if (ifa->ifa_addr->sa_family == AF_LINK) - sdl = (const struct sockaddr_dl *) ifa->ifa_addr; + sdl = ifa->ifa_addr; if (p && strcmp(p, ifa->ifa_name) == 0) continue; if (!prop_dictionary_set_cstring(env, "if", ifa->ifa_name)) @@ -1144,7 +1144,7 @@ * specified, show it and it only; otherwise, show them all. */ void -status(const struct sockaddr_dl *sdl, prop_dictionary_t env, +status(const struct sockaddr *sdl, prop_dictionary_t env, prop_dictionary_t oenv) { const struct if_data *ifi; @@ -1152,7 +1152,6 @@ statistics_func_t *statistics_f; struct ifdatareq ifdr; struct ifreq ifr; - char hbuf[NI_MAXHOST]; char fbuf[BUFSIZ]; int af, s; const char *ifname; @@ -1202,11 +1201,7 @@ SIMPLEQ_FOREACH(status_f, &status_funcs, f_next) (*status_f->f_func)(env, oenv); - if (sdl != NULL && - getnameinfo((const struct sockaddr *)sdl, sdl->sdl_len, - hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0 && - hbuf[0] != '\0') - printf("\taddress: %s\n", hbuf); + print_link_addresses(env, true); media_status(env, oenv); @@ -1215,7 +1210,7 @@ estrlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name)); - if (ioctl(s, zflag ? SIOCZIFDATA:SIOCGIFDATA, &ifdr) == -1) + if (ioctl(s, zflag ? SIOCZIFDATA : SIOCGIFDATA, &ifdr) == -1) err(EXIT_FAILURE, zflag ? "SIOCZIFDATA" : "SIOCGIFDATA"); ifi = &ifdr.ifdr_data; Index: src/sbin/ifconfig/util.c diff -u src/sbin/ifconfig/util.c:1.8 src/sbin/ifconfig/util.c:1.8.2.1 --- src/sbin/ifconfig/util.c:1.8 Wed Jul 2 07:44:15 2008 +++ src/sbin/ifconfig/util.c Sun May 3 13:17:52 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: util.c,v 1.8 2008/07/02 07:44:15 dyoung Exp $ */ +/* $NetBSD: util.c,v 1.8.2.1 2009/05/03 13:17:52 bouyer Exp $ */ /*- * Copyright (c) 2008 David Young. All rights reserved. @@ -27,12 +27,13 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: util.c,v 1.8 2008/07/02 07:44:15 dyoung Exp $"); +__RCSID("$NetBSD: util.c,v 1.8.2.1 2009/05/03 13:17:52 bouyer Exp $"); #endif /* not lint */ #include <ctype.h> #include <err.h> #include <errno.h> +#include <netdb.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -40,9 +41,14 @@ #include <unistd.h> #include <util.h> +#include <sys/param.h> +#include <sys/types.h> #include <sys/socket.h> +#include <ifaddrs.h> + #include <sys/ioctl.h> #include <net/if.h> +#include <net/if_dl.h> #include <netinet/in.h> /* XXX */ #include "env.h" @@ -230,6 +236,58 @@ return direct_ioctl(env, cmd, &ifr); } +void +print_link_addresses(prop_dictionary_t env, bool print_active_only) +{ + char hbuf[NI_MAXHOST]; + const char *ifname; + int s; + struct ifaddrs *ifa, *ifap; + const struct sockaddr_dl *sdl; + struct if_laddrreq iflr; + + if ((ifname = getifname(env)) == NULL) + err(EXIT_FAILURE, "%s: getifname", __func__); + + if ((s = getsock(AF_LINK)) == -1) + err(EXIT_FAILURE, "%s: getsock", __func__); + + if (getifaddrs(&ifap) == -1) + err(EXIT_FAILURE, "%s: getifaddrs", __func__); + + memset(&iflr, 0, sizeof(iflr)); + + strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name)); + + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifname, ifa->ifa_name) != 0) + continue; + if (ifa->ifa_addr->sa_family != AF_LINK) + continue; + + sdl = satocsdl(ifa->ifa_addr); + + memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len, + sizeof(iflr.addr))); + iflr.flags = IFLR_PREFIX; + iflr.prefixlen = sdl->sdl_alen * NBBY; + + if (ioctl(s, SIOCGLIFADDR, &iflr) == -1) + err(EXIT_FAILURE, "%s: ioctl", __func__); + + if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only) + continue; + + if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0 && + hbuf[0] != '\0') { + printf("\t%s %s\n", + print_active_only ? "address:" : "link", hbuf); + } + } + freeifaddrs(ifap); +} + #ifdef INET6 /* KAME idiosyncrasy */ void Index: src/sbin/ifconfig/util.h diff -u src/sbin/ifconfig/util.h:1.6 src/sbin/ifconfig/util.h:1.6.2.1 --- src/sbin/ifconfig/util.h:1.6 Wed Jul 2 07:44:15 2008 +++ src/sbin/ifconfig/util.h Sun May 3 13:17:52 2009 @@ -13,6 +13,7 @@ SIMPLEQ_ENTRY(afswtch) af_next; }; +void print_link_addresses(prop_dictionary_t, bool); const char *get_string(const char *, const char *, u_int8_t *, int *); const struct afswtch *lookup_af_byname(const char *); const struct afswtch *lookup_af_bynum(int);