From nobody Mon May 15 13:38:00 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QKgRY1v3Gz4Bcsg; Mon, 15 May 2023 13:38:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QKgRY17hCz4W03; Mon, 15 May 2023 13:38:01 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684157881; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zZsR/ySFCChTAw2qX2N0P97fja41NKeCq7Jqy7jSbPk=; b=ZqBc9GQVOz/JRAsqa1XJ93HjqcU3LzGJSY4t7vKUEt5+i5IeMLQH2Umq8ekIWY3mZyW1v/ zdydrSm33AQWM6sIfEAnkQDXIHCVzDaFTd4FGLL44VPc0FW6crD2bC8ly8B7dNux876B/I mErd378u16AubsTigGuX07iW1o3h4ku5BRJ4UGyP2usJRV+MSbNsDTGT+KNMwff0U/V1gD J2SCPzuhnB8eOC26xIIv55AIr3j3vFo32yUtXMHpWeW2pXQVio3uTZrF38VHgdqbnEENC+ 9Z/tsi7wqxre4K9XJ4E6eIiEE1236j8ahbrPtqPYqIaV/UusL1e9SOpBN8wA5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684157881; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zZsR/ySFCChTAw2qX2N0P97fja41NKeCq7Jqy7jSbPk=; b=g8yzXgX2y9X+VWppdpyiglEQpmyJ4MzinJlM2yuKHF4l1f6JffLipHMqCE3BPedlTuCuk+ Ct9b23fqxAO0HGCjuYrHaXmDpOaZLAIBvM1b/hvAwCioDWFtMXJrWVE2UKvNs+6hZXVQUV GF8j8WfX/rz1hlm/lGjOuvITz44XHPOmYEbD+vySgwt3iCLXT0Fg5YT6fvbOkTSOXb95z1 PuSYWE4anjfliP931OISqHDSrSZY696vkkLfRkSv3+LMkqPOXEiGWk0j0JHB/fyuHD3P2d iJHtcdKZuYdz5n6pZ1y0CK6avu9ygwymOjEzA+grvu6Ul6AptZHV+FYN1Sifqg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1684157881; a=rsa-sha256; cv=none; b=aP5ukvlasbE0uXjRkYqGyH9lF730vlvV13XWFpqu4A9Tn9aAET+6L+ZBnz0eLASBBLC0Bu 3k3fvEOjVaGZqrKRv0et0JOZaLV4NC29IuEtyLpu1EcZjG4S3PqtAkGuP+r8KWrnmZH4py 1hvjaloRG4eDcazE10qg5twlv3JTgXxbJQlaGOzDI1JxUodEqLJ2CgSUxBM1/NVI5MgpaF AOqIoe+AMLUHKcZ7hE0H58QDxIbp5K8xRbnl2xAm8VyJmiGlhLGBw8KHQf0m4VYCHMaeX4 uYM+bZIeWSLeO/7uyikZp7+b6TG/dGXUopkBzSSD95/kBhX4Z3/nGPgTkv0pGg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QKgRY06PXzjBf; Mon, 15 May 2023 13:38:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 34FDc0Km059456; Mon, 15 May 2023 13:38:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 34FDc0oc059455; Mon, 15 May 2023 13:38:00 GMT (envelope-from git) Date: Mon, 15 May 2023 13:38:00 GMT Message-Id: <202305151338.34FDc0oc059455@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Alexander V. Chernikov" Subject: git: d1cd0344f7b7 - main - ifconfig: split printing functions into smaller per-type chunks. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: melifaro X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d1cd0344f7b7d81beda04c3cb8cfee99351c3eb8 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=d1cd0344f7b7d81beda04c3cb8cfee99351c3eb8 commit d1cd0344f7b7d81beda04c3cb8cfee99351c3eb8 Author: Alexander V. Chernikov AuthorDate: 2023-05-15 12:17:54 +0000 Commit: Alexander V. Chernikov CommitDate: 2023-05-15 13:37:27 +0000 ifconfig: split printing functions into smaller per-type chunks. This change is a prerequisite for netlink conversion. No functional changes intended. Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D40033 MFC after: 2 weeks --- sbin/ifconfig/af_inet.c | 21 ++-- sbin/ifconfig/af_inet6.c | 154 +++++++++++++++------------ sbin/ifconfig/af_link.c | 67 +++++++----- sbin/ifconfig/ifconfig.c | 271 +++++++++++++++++++++++++++++------------------ sbin/ifconfig/ifconfig.h | 3 + 5 files changed, 305 insertions(+), 211 deletions(-) diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index c5c40de155d6..6ce11fa2d673 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -60,16 +60,9 @@ static char addr_buf[NI_MAXHOST]; /*for getnameinfo()*/ extern char *f_inet, *f_addr; static void -in_status(int s __unused, const struct ifaddrs *ifa) +print_addr(struct sockaddr_in *sin) { - struct sockaddr_in *sin, null_sin; int error, n_flags; - - memset(&null_sin, 0, sizeof(null_sin)); - - sin = (struct sockaddr_in *)ifa->ifa_addr; - if (sin == NULL) - return; if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0) n_flags = 0; @@ -85,6 +78,18 @@ in_status(int s __unused, const struct ifaddrs *ifa) inet_ntop(AF_INET, &sin->sin_addr, addr_buf, sizeof(addr_buf)); printf("\tinet %s", addr_buf); +} + +static void +in_status(int s __unused, const struct ifaddrs *ifa) +{ + struct sockaddr_in *sin, null_sin = {}; + + sin = (struct sockaddr_in *)ifa->ifa_addr; + if (sin == NULL) + return; + + print_addr(sin); if (ifa->ifa_flags & IFF_POINTOPOINT) { sin = (struct sockaddr_in *)ifa->ifa_dstaddr; diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 08902b934ad8..49049ba2c376 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -168,20 +168,88 @@ setip6eui64(const char *cmd, int dummy __unused, int s, freeifaddrs(ifap); } +static void +print_addr(struct sockaddr_in6 *sin) +{ + int error, n_flags; + + if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0) + n_flags = 0; + else if (f_addr != NULL && strcmp(f_addr, "host") == 0) + n_flags = NI_NOFQDN; + else + n_flags = NI_NUMERICHOST; + error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, + addr_buf, sizeof(addr_buf), NULL, 0, + n_flags); + if (error != 0) + inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, + sizeof(addr_buf)); + printf("\tinet6 %s", addr_buf); +} + +static void +print_p2p(struct sockaddr_in6 *sin) +{ + int error; + + error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, addr_buf, + sizeof(addr_buf), NULL, 0, NI_NUMERICHOST); + + if (error != 0) + inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, sizeof(addr_buf)); + printf(" --> %s", addr_buf); +} + +static void +print_mask(int plen) +{ + if (f_inet6 != NULL && strcmp(f_inet6, "cidr") == 0) + printf("/%d", plen); + else + printf(" prefixlen %d", plen); +} + +static void +print_flags(int flags6) +{ + if ((flags6 & IN6_IFF_ANYCAST) != 0) + printf(" anycast"); + if ((flags6 & IN6_IFF_TENTATIVE) != 0) + printf(" tentative"); + if ((flags6 & IN6_IFF_DUPLICATED) != 0) + printf(" duplicated"); + if ((flags6 & IN6_IFF_DETACHED) != 0) + printf(" detached"); + if ((flags6 & IN6_IFF_DEPRECATED) != 0) + printf(" deprecated"); + if ((flags6 & IN6_IFF_AUTOCONF) != 0) + printf(" autoconf"); + if ((flags6 & IN6_IFF_TEMPORARY) != 0) + printf(" temporary"); + if ((flags6 & IN6_IFF_PREFER_SOURCE) != 0) + printf(" prefer_source"); + +} + +static void +print_lifetime(const char *prepend, time_t px_time, struct timespec *now) +{ + printf(" %s", prepend); + if (px_time == 0) + printf(" infty"); + + printf(" %s", px_time < now->tv_sec ? "0" : sec2str(px_time - now->tv_sec)); +} + static void in6_status(int s __unused, const struct ifaddrs *ifa) { - struct sockaddr_in6 *sin, null_sin; + struct sockaddr_in6 *sin, null_sin = {}; struct in6_ifreq ifr6; int s6; u_int32_t flags6; struct in6_addrlifetime lifetime; - struct timespec now; - int error, n_flags; - - clock_gettime(CLOCK_MONOTONIC_FAST, &now); - - memset(&null_sin, 0, sizeof(null_sin)); sin = (struct sockaddr_in6 *)ifa->ifa_addr; if (sin == NULL) @@ -209,19 +277,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa) lifetime = ifr6.ifr_ifru.ifru_lifetime; close(s6); - if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0) - n_flags = 0; - else if (f_addr != NULL && strcmp(f_addr, "host") == 0) - n_flags = NI_NOFQDN; - else - n_flags = NI_NUMERICHOST; - error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, - addr_buf, sizeof(addr_buf), NULL, 0, - n_flags); - if (error != 0) - inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, - sizeof(addr_buf)); - printf("\tinet6 %s", addr_buf); + print_addr(sin); if (ifa->ifa_flags & IFF_POINTOPOINT) { sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr; @@ -229,67 +285,27 @@ in6_status(int s __unused, const struct ifaddrs *ifa) * some of the interfaces do not have valid destination * address. */ - if (sin != NULL && sin->sin6_family == AF_INET6) { - int error; - - error = getnameinfo((struct sockaddr *)sin, - sin->sin6_len, addr_buf, - sizeof(addr_buf), NULL, 0, - NI_NUMERICHOST); - if (error != 0) - inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, - sizeof(addr_buf)); - printf(" --> %s", addr_buf); - } + if (sin != NULL && sin->sin6_family == AF_INET6) + print_p2p(sin); } sin = (struct sockaddr_in6 *)ifa->ifa_netmask; if (sin == NULL) sin = &null_sin; - if (f_inet6 != NULL && strcmp(f_inet6, "cidr") == 0) - printf("/%d", prefix(&sin->sin6_addr, - sizeof(struct in6_addr))); - else - printf(" prefixlen %d", prefix(&sin->sin6_addr, - sizeof(struct in6_addr))); + print_mask(prefix(&sin->sin6_addr, sizeof(struct in6_addr))); - if ((flags6 & IN6_IFF_ANYCAST) != 0) - printf(" anycast"); - if ((flags6 & IN6_IFF_TENTATIVE) != 0) - printf(" tentative"); - if ((flags6 & IN6_IFF_DUPLICATED) != 0) - printf(" duplicated"); - if ((flags6 & IN6_IFF_DETACHED) != 0) - printf(" detached"); - if ((flags6 & IN6_IFF_DEPRECATED) != 0) - printf(" deprecated"); - if ((flags6 & IN6_IFF_AUTOCONF) != 0) - printf(" autoconf"); - if ((flags6 & IN6_IFF_TEMPORARY) != 0) - printf(" temporary"); - if ((flags6 & IN6_IFF_PREFER_SOURCE) != 0) - printf(" prefer_source"); + print_flags(flags6); if (((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id) printf(" scopeid 0x%x", ((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id); if (ip6lifetime && (lifetime.ia6t_preferred || lifetime.ia6t_expire)) { - printf(" pltime"); - if (lifetime.ia6t_preferred) { - printf(" %s", lifetime.ia6t_preferred < now.tv_sec - ? "0" : - sec2str(lifetime.ia6t_preferred - now.tv_sec)); - } else - printf(" infty"); - - printf(" vltime"); - if (lifetime.ia6t_expire) { - printf(" %s", lifetime.ia6t_expire < now.tv_sec - ? "0" : - sec2str(lifetime.ia6t_expire - now.tv_sec)); - } else - printf(" infty"); + struct timespec now; + + clock_gettime(CLOCK_MONOTONIC_FAST, &now); + print_lifetime("pltime", lifetime.ia6t_preferred, &now); + print_lifetime("vltime", lifetime.ia6t_expire, &now); } print_vhid(ifa, " "); diff --git a/sbin/ifconfig/af_link.c b/sbin/ifconfig/af_link.c index fb7a235b2f49..f651ddc51cb4 100644 --- a/sbin/ifconfig/af_link.c +++ b/sbin/ifconfig/af_link.c @@ -56,34 +56,54 @@ static struct ifreq link_ridreq; extern char *f_ether; +static void +print_ether(const struct ether_addr *addr, const char *prefix) +{ + char *ether_format = ether_ntoa(addr); + + if (f_ether != NULL && strcmp(f_ether, "dash") == 0) { + char *format_char; + + while ((format_char = strchr(ether_format, ':')) != NULL) { + *format_char = '-'; + } + } + printf("\t%s %s\n", prefix, ether_format); +} + +static void +print_lladdr(struct sockaddr_dl *sdl) +{ + if (match_ether(sdl)) { + print_ether((struct ether_addr *)LLADDR(sdl), "ether"); + } else { + int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; + printf("\tlladdr %s\n", link_ntoa(sdl) + n); + } +} + +static void +print_pcp(int s) +{ + if (ioctl(s, SIOCGLANPCP, (caddr_t)&ifr) == 0 && + ifr.ifr_lan_pcp != IFNET_PCP_NONE) + printf("\tpcp %d\n", ifr.ifr_lan_pcp); +} + static void link_status(int s __unused, const struct ifaddrs *ifa) { /* XXX no const 'cuz LLADDR is defined wrong */ struct sockaddr_dl *sdl; - char *ether_format, *format_char; struct ifreq ifr; - int n, rc, sock_hw; + int rc, sock_hw; static const u_char laggaddr[6] = {0}; sdl = (struct sockaddr_dl *) ifa->ifa_addr; if (sdl == NULL || sdl->sdl_alen == 0) return; - if ((sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_L2VLAN || - sdl->sdl_type == IFT_BRIDGE) && sdl->sdl_alen == ETHER_ADDR_LEN) { - ether_format = ether_ntoa((struct ether_addr *)LLADDR(sdl)); - if (f_ether != NULL && strcmp(f_ether, "dash") == 0) { - while ((format_char = strchr(ether_format, ':')) != - NULL) { - *format_char = '-'; - } - } - printf("\tether %s\n", ether_format); - } else { - n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; - printf("\tlladdr %s\n", link_ntoa(sdl) + n); - } + print_lladdr(sdl); /* * Best-effort (i.e. failures are silent) to get original @@ -118,20 +138,9 @@ link_status(int s __unused, const struct ifaddrs *ifa) memcmp(ifr.ifr_addr.sa_data, LLADDR(sdl), sdl->sdl_alen) == 0) goto pcp; - ether_format = ether_ntoa((const struct ether_addr *) - &ifr.ifr_addr.sa_data); - if (f_ether != NULL && strcmp(f_ether, "dash") == 0) { - for (format_char = strchr(ether_format, ':'); - format_char != NULL; - format_char = strchr(ether_format, ':')) - *format_char = '-'; - } - printf("\thwaddr %s\n", ether_format); - + print_ether((const struct ether_addr *)&ifr.ifr_addr.sa_data, "hwaddr"); pcp: - if (ioctl(s, SIOCGLANPCP, (caddr_t)&ifr) == 0 && - ifr.ifr_lan_pcp != IFNET_PCP_NONE) - printf("\tpcp %d\n", ifr.ifr_lan_pcp); + print_pcp(s); } static void diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 957a8fd7fb98..15a40f1c5601 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -611,6 +611,7 @@ main(int argc, char *argv[]) } args.afp = afp; + args.allfamilies = afp == NULL; args.argc = argc; args.argv = argv; @@ -622,6 +623,46 @@ done: exit(exit_code); } +bool +match_ether(const struct sockaddr_dl *sdl) +{ + switch (sdl->sdl_type) { + case IFT_ETHER: + case IFT_L2VLAN: + case IFT_BRIDGE: + if (sdl->sdl_alen == ETHER_ADDR_LEN) + return (true); + default: + return (false); + } +} + +static bool +match_afp(const struct afswtch *afp, int sa_family, const struct sockaddr_dl *sdl) +{ + if (afp == NULL) + return (true); + /* special case for "ether" address family */ + if (!strcmp(afp->af_name, "ether")) { + if (sdl == NULL && !match_ether(sdl)) + return (false); + return (true); + } + return (afp->af_af == sa_family); +} + +static bool +match_if_flags(struct ifconfig_args *args, int if_flags) +{ + if ((if_flags & IFF_CANTCONFIG) != 0) + return (false); + if (args->downonly && (if_flags & IFF_UP) != 0) + return (false); + if (args->uponly && (if_flags & IFF_UP) == 0) + return (false); + return (true); +} + static void list_interfaces(struct ifconfig_args *args) { @@ -672,11 +713,7 @@ list_interfaces(struct ifconfig_args *args) } cp = ifa->ifa_name; - if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0) - continue; - if (args->downonly && (ifa->ifa_flags & IFF_UP) != 0) - continue; - if (args->uponly && (ifa->ifa_flags & IFF_UP) == 0) + if (!match_if_flags(args, ifa->ifa_flags)) continue; if (!group_member(ifa->ifa_name, args->matchgroup, args->nogroup)) continue; @@ -686,21 +723,8 @@ list_interfaces(struct ifconfig_args *args) if (args->namesonly) { if (namecp == cp) continue; - if (args->afp != NULL) { - /* special case for "ether" address family */ - if (!strcmp(args->afp->af_name, "ether")) { - if (sdl == NULL || - (sdl->sdl_type != IFT_ETHER && - sdl->sdl_type != IFT_L2VLAN && - sdl->sdl_type != IFT_BRIDGE) || - sdl->sdl_alen != ETHER_ADDR_LEN) - continue; - } else { - if (ifa->ifa_addr->sa_family - != args->afp->af_af) - continue; - } - } + if (!match_afp(args->afp, ifa->ifa_addr->sa_family, sdl)) + continue; namecp = cp; ifindex++; if (ifindex > 1) @@ -1432,44 +1456,110 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp) "\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP\33NOMAP\34TXTLS4\35TXTLS6" \ "\36VXLAN_HWCSUM\37VXLAN_HWTSO\40TXTLS_RTLMT" -/* - * Print the status of the interface. If an address family was - * specified, show only it; otherwise, show them all. - */ static void -status(struct ifconfig_args *args, const struct sockaddr_dl *sdl, - struct ifaddrs *ifa) +print_ifcap_nv(struct ifconfig_args *args, int s) { - struct ifaddrs *ift; - struct ifstat ifs; nvlist_t *nvcap; const char *nvname; void *buf, *cookie; - int allfamilies, s, type; bool first, val; + int type; - if (args->afp == NULL) { - allfamilies = 1; - ifr.ifr_addr.sa_family = AF_LOCAL; - } else { - allfamilies = 0; - ifr.ifr_addr.sa_family = - args->afp->af_af == AF_LINK ? AF_LOCAL : args->afp->af_af; + buf = malloc(IFR_CAP_NV_MAXBUFSIZE); + if (buf == NULL) + Perror("malloc"); + ifr.ifr_cap_nv.buffer = buf; + ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE; + if (ioctl(s, SIOCGIFCAPNV, (caddr_t)&ifr) != 0) + Perror("ioctl (SIOCGIFCAPNV)"); + nvcap = nvlist_unpack(ifr.ifr_cap_nv.buffer, + ifr.ifr_cap_nv.length, 0); + if (nvcap == NULL) + Perror("nvlist_unpack"); + printf("\toptions"); + cookie = NULL; + for (first = true;; first = false) { + nvname = nvlist_next(nvcap, &type, &cookie); + if (nvname == NULL) { + printf("\n"); + break; + } + if (type == NV_TYPE_BOOL) { + val = nvlist_get_bool(nvcap, nvname); + if (val) { + printf("%c%s", + first ? ' ' : ',', nvname); + } + } } - strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (args->supmedia) { + printf("\tcapabilities"); + cookie = NULL; + for (first = true;; first = false) { + nvname = nvlist_next(nvcap, &type, + &cookie); + if (nvname == NULL) { + printf("\n"); + break; + } + if (type == NV_TYPE_BOOL) + printf("%c%s", first ? ' ' : + ',', nvname); + } + } + nvlist_destroy(nvcap); + free(buf); - s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); - if (s < 0) - err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); + if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0) + Perror("ioctl (SIOCGIFCAP)"); +} - printf("%s: ", name); - printb("flags", ifa->ifa_flags, IFFBITS); +static void +print_ifcap(struct ifconfig_args *args, int s) +{ + if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0) + return; + + if ((ifr.ifr_curcap & IFCAP_NV) != 0) + print_ifcap_nv(args, s); + else { + printb("\toptions", ifr.ifr_curcap, IFCAPBITS); + putchar('\n'); + if (args->supmedia && ifr.ifr_reqcap != 0) { + printb("\tcapabilities", ifr.ifr_reqcap, + IFCAPBITS); + putchar('\n'); + } + } +} + +static void +print_ifstatus(int s) +{ + struct ifstat ifs; + + strlcpy(ifs.ifs_name, name, sizeof ifs.ifs_name); + if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) + printf("%s", ifs.ascii); +} + +static void +print_metric(int s) +{ if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1) printf(" metric %d", ifr.ifr_metric); +} + +static void +print_mtu(int s) +{ if (ioctl(s, SIOCGIFMTU, &ifr) != -1) printf(" mtu %d", ifr.ifr_mtu); - putchar('\n'); +} +static void +print_description(int s) +{ for (;;) { if ((descr = reallocf(descr, descrlen)) != NULL) { ifr.ifr_buffer.buffer = descr; @@ -1489,66 +1579,40 @@ status(struct ifconfig_args *args, const struct sockaddr_dl *sdl, "description"); break; } +} - if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { - if ((ifr.ifr_curcap & IFCAP_NV) != 0) { - buf = malloc(IFR_CAP_NV_MAXBUFSIZE); - if (buf == NULL) - Perror("malloc"); - ifr.ifr_cap_nv.buffer = buf; - ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE; - if (ioctl(s, SIOCGIFCAPNV, (caddr_t)&ifr) != 0) - Perror("ioctl (SIOCGIFCAPNV)"); - nvcap = nvlist_unpack(ifr.ifr_cap_nv.buffer, - ifr.ifr_cap_nv.length, 0); - if (nvcap == NULL) - Perror("nvlist_unpack"); - printf("\toptions"); - cookie = NULL; - for (first = true;; first = false) { - nvname = nvlist_next(nvcap, &type, &cookie); - if (nvname == NULL) { - printf("\n"); - break; - } - if (type == NV_TYPE_BOOL) { - val = nvlist_get_bool(nvcap, nvname); - if (val) { - printf("%c%s", - first ? ' ' : ',', nvname); - } - } - } - if (args->supmedia) { - printf("\tcapabilities"); - cookie = NULL; - for (first = true;; first = false) { - nvname = nvlist_next(nvcap, &type, - &cookie); - if (nvname == NULL) { - printf("\n"); - break; - } - if (type == NV_TYPE_BOOL) - printf("%c%s", first ? ' ' : - ',', nvname); - } - } - nvlist_destroy(nvcap); - free(buf); +/* + * Print the status of the interface. If an address family was + * specified, show only it; otherwise, show them all. + */ +static void +status(struct ifconfig_args *args, const struct sockaddr_dl *sdl, + struct ifaddrs *ifa) +{ + struct ifaddrs *ift; + int s; + bool allfamilies = args->afp == NULL; - if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0) - Perror("ioctl (SIOCGIFCAP)"); - } else if (ifr.ifr_curcap != 0) { - printb("\toptions", ifr.ifr_curcap, IFCAPBITS); - putchar('\n'); - if (args->supmedia && ifr.ifr_reqcap != 0) { - printb("\tcapabilities", ifr.ifr_reqcap, - IFCAPBITS); - putchar('\n'); - } - } - } + if (args->afp == NULL) + ifr.ifr_addr.sa_family = AF_LOCAL; + else + ifr.ifr_addr.sa_family = + args->afp->af_af == AF_LINK ? AF_LOCAL : args->afp->af_af; + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + + s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); + + printf("%s: ", name); + printb("flags", ifa->ifa_flags, IFFBITS); + print_metric(s); + print_mtu(s); + putchar('\n'); + + print_description(s); + + print_ifcap(args, s); tunnel_status(s); @@ -1587,10 +1651,7 @@ status(struct ifconfig_args *args, const struct sockaddr_dl *sdl, else if (args->afp->af_other_status != NULL) args->afp->af_other_status(s); - strlcpy(ifs.ifs_name, name, sizeof ifs.ifs_name); - if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) - printf("%s", ifs.ascii); - + print_ifstatus(s); if (args->verbose > 0) sfp_status(s, &ifr, args->verbose); diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index b58b577f4328..e65c26a031e6 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -191,6 +191,7 @@ struct ifconfig_args { bool noload; /* Do not load relevant kernel modules */ bool supmedia; /* Supported media */ bool printkeys; /* Print security keys */ + bool allfamilies; /* Print all families */ int verbose; /* verbosity level */ int argc; char **argv; @@ -235,6 +236,8 @@ void clone_setdefcallback_filter(clone_match_func *, clone_callback_func *); void sfp_status(int s, struct ifreq *ifr, int verbose); +struct sockaddr_dl; +bool match_ether(const struct sockaddr_dl *sdl); /* * XXX expose this so modules that neeed to know of any pending * operations on ifmedia can avoid cmd line ordering confusion.