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
This commit is contained in:
parent
d91f8db5f1
commit
d1cd0344f7
@ -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;
|
||||
|
@ -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");
|
||||
struct timespec now;
|
||||
|
||||
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");
|
||||
clock_gettime(CLOCK_MONOTONIC_FAST, &now);
|
||||
print_lifetime("pltime", lifetime.ia6t_preferred, &now);
|
||||
print_lifetime("vltime", lifetime.ia6t_expire, &now);
|
||||
}
|
||||
|
||||
print_vhid(ifa, " ");
|
||||
|
@ -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
|
||||
|
@ -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 @@ main(int argc, char *argv[])
|
||||
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);
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user