diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c
index cb030dbc711b..8d302b260bd1 100644
--- a/sbin/ifconfig/af_inet.c
+++ b/sbin/ifconfig/af_inet.c
@@ -1,323 +1,317 @@
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 #ifndef lint
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <net/if.h>
 
 #include <ctype.h>
 #include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <ifaddrs.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
 #include "ifconfig.h"
 #include "ifconfig_netlink.h"
 
 static struct in_aliasreq in_addreq;
 static struct ifreq in_ridreq;
 static char addr_buf[NI_MAXHOST];	/*for getnameinfo()*/
 extern char *f_inet, *f_addr;
 
 static void
 print_addr(struct sockaddr_in *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->sin_len, addr_buf,
 			    sizeof(addr_buf), NULL, 0, n_flags);
 
 	if (error)
 		inet_ntop(AF_INET, &sin->sin_addr, addr_buf, sizeof(addr_buf));
 	
 	printf("\tinet %s", addr_buf);
 }
 
 #ifdef WITHOUT_NETLINK
 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;
 		if (sin == NULL)
 			sin = &null_sin;
 		printf(" --> %s", inet_ntoa(sin->sin_addr));
 	}
 
 	sin = (struct sockaddr_in *)ifa->ifa_netmask;
 	if (sin == NULL)
 		sin = &null_sin;
 	if (f_inet != NULL && strcmp(f_inet, "cidr") == 0) {
 		int cidr = 32;
 		unsigned long smask;
 
 		smask = ntohl(sin->sin_addr.s_addr);
 		while ((smask & 1) == 0) {
 			smask = smask >> 1;
 			cidr--;
 			if (cidr == 0)
 				break;
 		}
 		printf("/%d", cidr);
 	} else if (f_inet != NULL && strcmp(f_inet, "dotted") == 0)
 		printf(" netmask %s", inet_ntoa(sin->sin_addr));
 	else
 		printf(" netmask 0x%lx", (unsigned long)ntohl(sin->sin_addr.s_addr));
 
 	if (ifa->ifa_flags & IFF_BROADCAST) {
 		sin = (struct sockaddr_in *)ifa->ifa_broadaddr;
 		if (sin != NULL && sin->sin_addr.s_addr != 0)
 			printf(" broadcast %s", inet_ntoa(sin->sin_addr));
 	}
 
 	print_vhid(ifa, " ");
 
 	putchar('\n');
 }
 
 #else
 static struct in_addr
 get_mask(int plen)
 {
 	struct in_addr a;
 
 	a.s_addr = htonl(plen ? ~((1 << (32 - plen)) - 1) : 0);
 
 	return (a);
 }
 
-static struct sockaddr_in *
-satosin(struct sockaddr *sa)
-{
-	return ((struct sockaddr_in *)(void *)sa);
-}
-
 static void
 in_status_nl(struct ifconfig_args *args __unused, struct io_handler *h,
     if_link_t *link, if_addr_t *ifa)
 {
 	struct sockaddr_in *sin = satosin(ifa->ifa_local);
 	int plen = ifa->ifa_prefixlen;
 
 	print_addr(sin);
 
 	if (link->ifi_flags & IFF_POINTOPOINT) {
 		struct sockaddr_in *dst = satosin(ifa->ifa_address);
 
 		printf(" --> %s", inet_ntoa(dst->sin_addr));
 	}
 	if (f_inet != NULL && strcmp(f_inet, "cidr") == 0) {
 		printf("/%d", plen);
 	} else if (f_inet != NULL && strcmp(f_inet, "dotted") == 0)
 		printf(" netmask %s", inet_ntoa(get_mask(plen)));
 	else
 		printf(" netmask 0x%lx", (unsigned long)ntohl(get_mask(plen).s_addr));
 
 	if ((link->ifi_flags & IFF_BROADCAST) && plen != 0)  {
 		struct sockaddr_in *brd = satosin(ifa->ifa_broadcast);
 		if (brd != NULL)
 			printf(" broadcast %s", inet_ntoa(brd->sin_addr));
 	}
 
 	if (ifa->ifaf_vhid != 0)
 		printf(" vhid %d", ifa->ifaf_vhid);
 
 	putchar('\n');
 }
 #endif
 
 #define SIN(x) ((struct sockaddr_in *) &(x))
 static struct sockaddr_in *sintab[] = {
 	SIN(in_ridreq.ifr_addr), SIN(in_addreq.ifra_addr),
 	SIN(in_addreq.ifra_mask), SIN(in_addreq.ifra_broadaddr)
 };
 
 static void
 in_getaddr(const char *s, int which)
 {
 	struct sockaddr_in *sin = sintab[which];
 	struct hostent *hp;
 	struct netent *np;
 
 	sin->sin_len = sizeof(*sin);
 	sin->sin_family = AF_INET;
 
 	if (which == ADDR) {
 		char *p = NULL;
 
 		if((p = strrchr(s, '/')) != NULL) {
 			const char *errstr;
 			/* address is `name/masklen' */
-			int masklen;
+			int masklen = 0;
 			struct sockaddr_in *min = sintab[MASK];
 			*p = '\0';
 			if (!isdigit(*(p + 1)))
 				errstr = "invalid";
 			else
 				masklen = (int)strtonum(p + 1, 0, 32, &errstr);
 			if (errstr != NULL) {
 				*p = '/';
 				errx(1, "%s: bad value (width %s)", s, errstr);
 			}
 			min->sin_family = AF_INET;
 			min->sin_len = sizeof(*min);
 			min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) & 
 				              0xffffffff);
 		}
 	}
 
 	if (inet_aton(s, &sin->sin_addr))
 		return;
 	if ((hp = gethostbyname(s)) != NULL)
 		bcopy(hp->h_addr, (char *)&sin->sin_addr, 
 		    MIN((size_t)hp->h_length, sizeof(sin->sin_addr)));
 	else if ((np = getnetbyname(s)) != NULL)
 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
 	else
 		errx(1, "%s: bad value", s);
 }
 
 static void
 in_postproc(int s, const struct afswtch *afp, int newaddr, int ifflags)
 {
 	if (sintab[ADDR]->sin_len != 0 && sintab[MASK]->sin_len == 0 &&
 	    newaddr && (ifflags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) {
 		warnx("WARNING: setting interface address without mask "
 		    "is deprecated,\ndefault mask may not be correct.");
 	}
 }
 
 static void
 in_status_tunnel(int s)
 {
 	char src[NI_MAXHOST];
 	char dst[NI_MAXHOST];
 	struct ifreq ifr;
 	const struct sockaddr *sa = (const struct sockaddr *) &ifr.ifr_addr;
 
 	memset(&ifr, 0, sizeof(ifr));
 	strlcpy(ifr.ifr_name, name, IFNAMSIZ);
 
 	if (ioctl(s, SIOCGIFPSRCADDR, (caddr_t)&ifr) < 0)
 		return;
 	if (sa->sa_family != AF_INET)
 		return;
 	if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0, NI_NUMERICHOST) != 0)
 		src[0] = '\0';
 
 	if (ioctl(s, SIOCGIFPDSTADDR, (caddr_t)&ifr) < 0)
 		return;
 	if (sa->sa_family != AF_INET)
 		return;
 	if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0, NI_NUMERICHOST) != 0)
 		dst[0] = '\0';
 
 	printf("\ttunnel inet %s --> %s\n", src, dst);
 }
 
 static void
 in_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres)
 {
 	struct in_aliasreq addreq;
 
 	memset(&addreq, 0, sizeof(addreq));
 	strlcpy(addreq.ifra_name, name, IFNAMSIZ);
 	memcpy(&addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
 	memcpy(&addreq.ifra_dstaddr, dstres->ai_addr, dstres->ai_addr->sa_len);
 
 	if (ioctl(s, SIOCSIFPHYADDR, &addreq) < 0)
 		warn("SIOCSIFPHYADDR");
 }
 
 static void
 in_set_vhid(int vhid)
 {
 	in_addreq.ifra_vhid = vhid;
 }
 
 
 static struct afswtch af_inet = {
 	.af_name	= "inet",
 	.af_af		= AF_INET,
 #ifdef WITHOUT_NETLINK
 	.af_status	= in_status,
 #else
 	.af_status_nl	= in_status_nl,
 #endif
 	.af_getaddr	= in_getaddr,
 	.af_postproc	= in_postproc,
 	.af_status_tunnel = in_status_tunnel,
 	.af_settunnel	= in_set_tunnel,
 	.af_setvhid	= in_set_vhid,
 	.af_difaddr	= SIOCDIFADDR,
 	.af_aifaddr	= SIOCAIFADDR,
 	.af_ridreq	= &in_ridreq,
 	.af_addreq	= &in_addreq,
 };
 
 static __constructor void
 inet_ctor(void)
 {
 
 #ifndef RESCUE
 	if (!feature_present("inet"))
 		return;
 #endif
 	af_register(&af_inet);
 }
diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c
index 1bb08c8a6a5a..af4cecf057da 100644
--- a/sbin/ifconfig/af_inet6.c
+++ b/sbin/ifconfig/af_inet6.c
@@ -1,646 +1,643 @@
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 #ifndef lint
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <net/if.h>
 
 #include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <time.h>
 #include <ifaddrs.h>
 
 #include <arpa/inet.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
 #include <netinet6/nd6.h>	/* Define ND6_INFINITE_LIFETIME */
 
 #include "ifconfig.h"
 #include "ifconfig_netlink.h"
 
 static	struct in6_ifreq in6_ridreq;
 static	struct in6_aliasreq in6_addreq =
   { .ifra_flags = 0,
     .ifra_lifetime = { 0, 0, ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME } };
 static	int ip6lifetime;
 
+#ifdef WITHOUT_NETLINK
 static	int prefix(void *, int);
+#endif
 static	char *sec2str(time_t);
 static	int explicit_prefix = 0;
 extern	char *f_inet6, *f_addr;
 
 extern void setnd6flags(const char *, int, int, const struct afswtch *);
 extern void setnd6defif(const char *, int, int, const struct afswtch *);
 extern void nd6_status(int);
 
 static	char addr_buf[NI_MAXHOST];	/*for getnameinfo()*/
 
 static void
 setifprefixlen(const char *addr, int dummy __unused, int s,
     const struct afswtch *afp)
 {
         if (afp->af_getprefix != NULL)
                 afp->af_getprefix(addr, MASK);
 	explicit_prefix = 1;
 }
 
 static void
 setip6flags(const char *dummyaddr __unused, int flag, int dummysoc __unused,
     const struct afswtch *afp)
 {
 	if (afp->af_af != AF_INET6)
 		err(1, "address flags can be set only for inet6 addresses");
 
 	if (flag < 0)
 		in6_addreq.ifra_flags &= ~(-flag);
 	else
 		in6_addreq.ifra_flags |= flag;
 }
 
 static void
 setip6lifetime(const char *cmd, const char *val, int s, 
     const struct afswtch *afp)
 {
 	struct timespec now;
 	time_t newval;
 	char *ep;
 
 	clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 	newval = (time_t)strtoul(val, &ep, 0);
 	if (val == ep)
 		errx(1, "invalid %s", cmd);
 	if (afp->af_af != AF_INET6)
 		errx(1, "%s not allowed for the AF", cmd);
 	if (strcmp(cmd, "vltime") == 0) {
 		in6_addreq.ifra_lifetime.ia6t_expire = now.tv_sec + newval;
 		in6_addreq.ifra_lifetime.ia6t_vltime = newval;
 	} else if (strcmp(cmd, "pltime") == 0) {
 		in6_addreq.ifra_lifetime.ia6t_preferred = now.tv_sec + newval;
 		in6_addreq.ifra_lifetime.ia6t_pltime = newval;
 	}
 }
 
 static void
 setip6pltime(const char *seconds, int dummy __unused, int s, 
     const struct afswtch *afp)
 {
 	setip6lifetime("pltime", seconds, s, afp);
 }
 
 static void
 setip6vltime(const char *seconds, int dummy __unused, int s, 
     const struct afswtch *afp)
 {
 	setip6lifetime("vltime", seconds, s, afp);
 }
 
 static void
 setip6eui64(const char *cmd, int dummy __unused, int s,
     const struct afswtch *afp)
 {
 	struct ifaddrs *ifap, *ifa;
 	const struct sockaddr_in6 *sin6 = NULL;
 	const struct in6_addr *lladdr = NULL;
 	struct in6_addr *in6;
 
 	if (afp->af_af != AF_INET6)
 		errx(EXIT_FAILURE, "%s not allowed for the AF", cmd);
  	in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr;
 	if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0)
 		errx(EXIT_FAILURE, "interface index is already filled");
 	if (getifaddrs(&ifap) != 0)
 		err(EXIT_FAILURE, "getifaddrs");
 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 		if (ifa->ifa_addr->sa_family == AF_INET6 &&
 		    strcmp(ifa->ifa_name, name) == 0) {
-			sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
+			sin6 = (const struct sockaddr_in6 *)satosin6(ifa->ifa_addr);
 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 				lladdr = &sin6->sin6_addr;
 				break;
 			}
 		}
 	}
 	if (!lladdr)
 		errx(EXIT_FAILURE, "could not determine link local address"); 
 
  	memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8);
 
 	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));
 }
 
 #ifdef WITHOUT_NETLINK
 static void
 in6_status(int s __unused, const struct ifaddrs *ifa)
 {
 	struct sockaddr_in6 *sin, null_sin = {};
 	struct in6_ifreq ifr6;
 	int s6;
 	u_int32_t flags6;
 	struct in6_addrlifetime lifetime;
 
 	sin = (struct sockaddr_in6 *)ifa->ifa_addr;
 	if (sin == NULL)
 		return;
 
 	strlcpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
 	if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
 		warn("socket(AF_INET6,SOCK_DGRAM)");
 		return;
 	}
 	ifr6.ifr_addr = *sin;
 	if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
 		warn("ioctl(SIOCGIFAFLAG_IN6)");
 		close(s6);
 		return;
 	}
 	flags6 = ifr6.ifr_ifru.ifru_flags6;
 	memset(&lifetime, 0, sizeof(lifetime));
 	ifr6.ifr_addr = *sin;
 	if (ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr6) < 0) {
 		warn("ioctl(SIOCGIFALIFETIME_IN6)");
 		close(s6);
 		return;
 	}
 	lifetime = ifr6.ifr_ifru.ifru_lifetime;
 	close(s6);
 
 	print_addr(sin);
 
 	if (ifa->ifa_flags & IFF_POINTOPOINT) {
 		sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
 		/*
 		 * some of the interfaces do not have valid destination
 		 * address.
 		 */
 		if (sin != NULL && sin->sin6_family == AF_INET6)
 			print_p2p(sin);
 	}
 
 	sin = (struct sockaddr_in6 *)ifa->ifa_netmask;
 	if (sin == NULL)
 		sin = &null_sin;
 	print_mask(prefix(&sin->sin6_addr, sizeof(struct in6_addr)));
 
 	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)) {
 		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, " ");
 
 	putchar('\n');
 }
 
 #else
 static void
 show_lifetime(struct ifa_cacheinfo *ci)
 {
 	struct timespec now;
 	uint32_t pl, vl;
 
 	if (ci == NULL)
 		return;
 
 	int count = ci->ifa_prefered != ND6_INFINITE_LIFETIME;
 	count += ci->ifa_valid != ND6_INFINITE_LIFETIME;
 	if (count == 0)
 		return;
 
 	pl = (ci->ifa_prefered == ND6_INFINITE_LIFETIME) ? 0 : ci->ifa_prefered;
 	vl = (ci->ifa_valid == ND6_INFINITE_LIFETIME) ? 0 : ci->ifa_valid;
 
 	clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 	print_lifetime("pltime", pl + now.tv_sec, &now);
 	print_lifetime("vltime", vl + now.tv_sec, &now);
 }
 
-static struct sockaddr_in6 *
-satosin6(struct sockaddr *sa)
-{
-	return ((struct sockaddr_in6 *)(void *)sa);
-}
-
 static void
 in6_status_nl(struct ifconfig_args *args __unused, struct io_handler *h,
     if_link_t *link, if_addr_t *ifa)
 {
 	int plen = ifa->ifa_prefixlen;
 	uint32_t scopeid;
 
 	if (ifa->ifa_local == NULL) {
 		/* Non-P2P address */
 		scopeid = satosin6(ifa->ifa_address)->sin6_scope_id;
 		print_addr(satosin6(ifa->ifa_address));
 	} else {
 		scopeid = satosin6(ifa->ifa_local)->sin6_scope_id;
 		print_addr(satosin6(ifa->ifa_local));
 		print_p2p(satosin6(ifa->ifa_address));
 	}
 
 	print_mask(plen);
 	print_flags(ifa->ifaf_flags);
 
 	if (scopeid != 0)
 		printf(" scopeid 0x%x", scopeid);
 
 	show_lifetime(ifa->ifa_cacheinfo);
 
 	if (ifa->ifaf_vhid != 0)
 		printf(" vhid %d", ifa->ifaf_vhid);
 
 	putchar('\n');
 }
 #endif
 
-#define	SIN6(x) ((struct sockaddr_in6 *) &(x))
 static struct	sockaddr_in6 *sin6tab[] = {
-	SIN6(in6_ridreq.ifr_addr), SIN6(in6_addreq.ifra_addr),
-	SIN6(in6_addreq.ifra_prefixmask), SIN6(in6_addreq.ifra_dstaddr)
+	&in6_ridreq.ifr_addr, &in6_addreq.ifra_addr,
+	&in6_addreq.ifra_prefixmask, &in6_addreq.ifra_dstaddr
 };
 
 static void
 in6_getprefix(const char *plen, int which)
 {
 	struct sockaddr_in6 *sin = sin6tab[which];
 	u_char *cp;
 	int len = atoi(plen);
 
 	if ((len < 0) || (len > 128))
 		errx(1, "%s: bad value", plen);
 	sin->sin6_len = sizeof(*sin);
 	if (which != MASK)
 		sin->sin6_family = AF_INET6;
 	if ((len == 0) || (len == 128)) {
 		memset(&sin->sin6_addr, 0xff, sizeof(struct in6_addr));
 		return;
 	}
 	memset((void *)&sin->sin6_addr, 0x00, sizeof(sin->sin6_addr));
 	for (cp = (u_char *)&sin->sin6_addr; len > 7; len -= 8)
 		*cp++ = 0xff;
 	*cp = 0xff << (8 - len);
 }
 
 static void
 in6_getaddr(const char *s, int which)
 {
 	struct sockaddr_in6 *sin = sin6tab[which];
 	struct addrinfo hints, *res;
 	int error = -1;
 
 	newaddr &= 1;
 
 	sin->sin6_len = sizeof(*sin);
 	if (which != MASK)
 		sin->sin6_family = AF_INET6;
 
 	if (which == ADDR) {
 		char *p = NULL;
 		if((p = strrchr(s, '/')) != NULL) {
 			*p = '\0';
 			in6_getprefix(p + 1, MASK);
 			explicit_prefix = 1;
 		}
 	}
 
 	if (sin->sin6_family == AF_INET6) {
 		bzero(&hints, sizeof(struct addrinfo));
 		hints.ai_family = AF_INET6;
 		error = getaddrinfo(s, NULL, &hints, &res);
 		if (error != 0) {
 			if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
 				errx(1, "%s: bad value", s);
 		} else {
 			bcopy(res->ai_addr, sin, res->ai_addrlen);
 			freeaddrinfo(res);
 		}
 	}
 }
 
+#ifdef WITHOUT_NETLINK
 static int
 prefix(void *val, int size)
 {
 	u_char *name = (u_char *)val;
 	int byte, bit, plen = 0;
 
 	for (byte = 0; byte < size; byte++, plen += 8)
 		if (name[byte] != 0xff)
 			break;
 	if (byte == size)
 		return (plen);
 	for (bit = 7; bit != 0; bit--, plen++)
 		if (!(name[byte] & (1 << bit)))
 			break;
 	for (; bit != 0; bit--)
 		if (name[byte] & (1 << bit))
 			return(0);
 	byte++;
 	for (; byte < size; byte++)
 		if (name[byte])
 			return(0);
 	return (plen);
 }
+#endif
 
 static char *
 sec2str(time_t total)
 {
 	static char result[256];
 	int days, hours, mins, secs;
 	int first = 1;
 	char *p = result;
 
 	if (0) {
 		days = total / 3600 / 24;
 		hours = (total / 3600) % 24;
 		mins = (total / 60) % 60;
 		secs = total % 60;
 
 		if (days) {
 			first = 0;
 			p += sprintf(p, "%dd", days);
 		}
 		if (!first || hours) {
 			first = 0;
 			p += sprintf(p, "%dh", hours);
 		}
 		if (!first || mins) {
 			first = 0;
 			p += sprintf(p, "%dm", mins);
 		}
 		sprintf(p, "%ds", secs);
 	} else
 		sprintf(result, "%lu", (unsigned long)total);
 
 	return(result);
 }
 
 static void
 in6_postproc(int s, const struct afswtch *afp, int newaddr __unused,
     int ifflags __unused)
 {
 	if (explicit_prefix == 0) {
 		/* Aggregatable address architecture defines all prefixes
 		   are 64. So, it is convenient to set prefixlen to 64 if
 		   it is not specified. */
 		setifprefixlen("64", 0, s, afp);
 		/* in6_getprefix("64", MASK) if MASK is available here... */
 	}
 }
 
 static void
 in6_status_tunnel(int s)
 {
 	char src[NI_MAXHOST];
 	char dst[NI_MAXHOST];
 	struct in6_ifreq in6_ifr;
 	const struct sockaddr *sa = (const struct sockaddr *) &in6_ifr.ifr_addr;
 
 	memset(&in6_ifr, 0, sizeof(in6_ifr));
 	strlcpy(in6_ifr.ifr_name, name, sizeof(in6_ifr.ifr_name));
 
 	if (ioctl(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr) < 0)
 		return;
 	if (sa->sa_family != AF_INET6)
 		return;
 	if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0,
 	    NI_NUMERICHOST) != 0)
 		src[0] = '\0';
 
 	if (ioctl(s, SIOCGIFPDSTADDR_IN6, (caddr_t)&in6_ifr) < 0)
 		return;
 	if (sa->sa_family != AF_INET6)
 		return;
 	if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0,
 	    NI_NUMERICHOST) != 0)
 		dst[0] = '\0';
 
 	printf("\ttunnel inet6 %s --> %s\n", src, dst);
 }
 
 static void
 in6_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres)
 {
 	struct in6_aliasreq in6_addreq; 
 
 	memset(&in6_addreq, 0, sizeof(in6_addreq));
 	strlcpy(in6_addreq.ifra_name, name, sizeof(in6_addreq.ifra_name));
 	memcpy(&in6_addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
 	memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
 	    dstres->ai_addr->sa_len);
 
 	if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0)
 		warn("SIOCSIFPHYADDR_IN6");
 }
 
 static void
 in6_set_vhid(int vhid)
 {
 	in6_addreq.ifra_vhid = vhid;
 }
 
 static struct cmd inet6_cmds[] = {
 	DEF_CMD_ARG("prefixlen",			setifprefixlen),
 	DEF_CMD("anycast",	IN6_IFF_ANYCAST,	setip6flags),
 	DEF_CMD("tentative",	IN6_IFF_TENTATIVE,	setip6flags),
 	DEF_CMD("-tentative",	-IN6_IFF_TENTATIVE,	setip6flags),
 	DEF_CMD("deprecated",	IN6_IFF_DEPRECATED,	setip6flags),
 	DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED,	setip6flags),
 	DEF_CMD("autoconf",	IN6_IFF_AUTOCONF,	setip6flags),
 	DEF_CMD("-autoconf",	-IN6_IFF_AUTOCONF,	setip6flags),
 	DEF_CMD("prefer_source",IN6_IFF_PREFER_SOURCE,	setip6flags),
 	DEF_CMD("-prefer_source",-IN6_IFF_PREFER_SOURCE,setip6flags),
 	DEF_CMD("accept_rtadv",	ND6_IFF_ACCEPT_RTADV,	setnd6flags),
 	DEF_CMD("-accept_rtadv",-ND6_IFF_ACCEPT_RTADV,	setnd6flags),
 	DEF_CMD("no_radr",	ND6_IFF_NO_RADR,	setnd6flags),
 	DEF_CMD("-no_radr",	-ND6_IFF_NO_RADR,	setnd6flags),
 	DEF_CMD("defaultif",	1,			setnd6defif),
 	DEF_CMD("-defaultif",	-1,			setnd6defif),
 	DEF_CMD("ifdisabled",	ND6_IFF_IFDISABLED,	setnd6flags),
 	DEF_CMD("-ifdisabled",	-ND6_IFF_IFDISABLED,	setnd6flags),
 	DEF_CMD("nud",		ND6_IFF_PERFORMNUD,	setnd6flags),
 	DEF_CMD("-nud",		-ND6_IFF_PERFORMNUD,	setnd6flags),
 	DEF_CMD("auto_linklocal",ND6_IFF_AUTO_LINKLOCAL,setnd6flags),
 	DEF_CMD("-auto_linklocal",-ND6_IFF_AUTO_LINKLOCAL,setnd6flags),
 	DEF_CMD("no_prefer_iface",ND6_IFF_NO_PREFER_IFACE,setnd6flags),
 	DEF_CMD("-no_prefer_iface",-ND6_IFF_NO_PREFER_IFACE,setnd6flags),
 	DEF_CMD("no_dad",	ND6_IFF_NO_DAD,		setnd6flags),
 	DEF_CMD("-no_dad",	-ND6_IFF_NO_DAD,	setnd6flags),
 	DEF_CMD_ARG("pltime",        			setip6pltime),
 	DEF_CMD_ARG("vltime",        			setip6vltime),
 	DEF_CMD("eui64",	0,			setip6eui64),
 #ifdef EXPERIMENTAL
 	DEF_CMD("ipv6_only",	ND6_IFF_IPV6_ONLY_MANUAL,setnd6flags),
 	DEF_CMD("-ipv6_only",	-ND6_IFF_IPV6_ONLY_MANUAL,setnd6flags),
 #endif
 };
 
 static struct afswtch af_inet6 = {
 	.af_name	= "inet6",
 	.af_af		= AF_INET6,
 #ifdef WITHOUT_NETLINK
 	.af_status	= in6_status,
 #else
 	.af_status_nl	= in6_status_nl,
 #endif
 	.af_getaddr	= in6_getaddr,
 	.af_getprefix	= in6_getprefix,
 	.af_other_status = nd6_status,
 	.af_postproc	= in6_postproc,
 	.af_status_tunnel = in6_status_tunnel,
 	.af_settunnel	= in6_set_tunnel,
 	.af_setvhid	= in6_set_vhid,
 	.af_difaddr	= SIOCDIFADDR_IN6,
 	.af_aifaddr	= SIOCAIFADDR_IN6,
 	.af_ridreq	= &in6_addreq,
 	.af_addreq	= &in6_addreq,
 };
 
 static void
 in6_Lopt_cb(const char *optarg __unused)
 {
 	ip6lifetime++;	/* print IPv6 address lifetime */
 }
 static struct option in6_Lopt = {
 	.opt = "L",
 	.opt_usage = "[-L]",
 	.cb = in6_Lopt_cb
 };
 
 static __constructor void
 inet6_ctor(void)
 {
 	size_t i;
 
 #ifndef RESCUE
 	if (!feature_present("inet6"))
 		return;
 #endif
 
 	for (i = 0; i < nitems(inet6_cmds);  i++)
 		cmd_register(&inet6_cmds[i]);
 	af_register(&af_inet6);
 	opt_register(&in6_Lopt);
 }
diff --git a/sbin/ifconfig/carp.c b/sbin/ifconfig/carp.c
index cc38eed4cb4b..2d6c581582b1 100644
--- a/sbin/ifconfig/carp.c
+++ b/sbin/ifconfig/carp.c
@@ -1,264 +1,262 @@
 /*	$FreeBSD$ */
 /*	from $OpenBSD: ifconfig.c,v 1.82 2003/10/19 05:43:35 mcbride Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
  * Copyright (c) 2003 Ryan McBride. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_carp.h>
 
 #include <arpa/inet.h>
 
 #include <ctype.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <err.h>
 #include <errno.h>
 #include <netdb.h>
 
 #include <libifconfig.h>
 
 #include "ifconfig.h"
 
 static const char *carp_states[] = { CARP_STATES };
 
 static void carp_status(int s);
 static void setcarp_vhid(const char *, int, int, const struct afswtch *rafp);
 static void setcarp_callback(int, void *);
 static void setcarp_advbase(const char *,int, int, const struct afswtch *rafp);
 static void setcarp_advskew(const char *, int, int, const struct afswtch *rafp);
 static void setcarp_passwd(const char *, int, int, const struct afswtch *rafp);
 
 static int carpr_vhid = -1;
 static int carpr_advskew = -1;
 static int carpr_advbase = -1;
 static int carpr_state = -1;
 static struct in_addr carp_addr;
 static struct in6_addr carp_addr6;
 static unsigned char const *carpr_key;
 
 static void
 carp_status(int s)
 {
 	struct ifconfig_carp carpr[CARP_MAXVHID];
 	char addr_buf[NI_MAXHOST];
 
 	if (ifconfig_carp_get_info(lifh, name, carpr, CARP_MAXVHID) == -1)
 		return;
 
 	for (size_t i = 0; i < carpr[0].carpr_count; i++) {
 		printf("\tcarp: %s vhid %d advbase %d advskew %d",
 		    carp_states[carpr[i].carpr_state], carpr[i].carpr_vhid,
 		    carpr[i].carpr_advbase, carpr[i].carpr_advskew);
 		if (printkeys && carpr[i].carpr_key[0] != '\0')
 			printf(" key \"%s\"\n", carpr[i].carpr_key);
 		else
 			printf("\n");
 
 		inet_ntop(AF_INET6, &carpr[i].carpr_addr6, addr_buf,
 		    sizeof(addr_buf));
 
 		printf("\t      peer %s peer6 %s\n",
 		    inet_ntoa(carpr[i].carpr_addr), addr_buf);
 	}
 }
 
 static void
 setcarp_vhid(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	carpr_vhid = atoi(val);
 
 	if (carpr_vhid <= 0 || carpr_vhid > CARP_MAXVHID)
 		errx(1, "vhid must be greater than 0 and less than %u",
 		    CARP_MAXVHID);
 
 	if (afp->af_setvhid == NULL)
 		errx(1, "%s doesn't support carp(4)", afp->af_name);
 	afp->af_setvhid(carpr_vhid);
 	callback_register(setcarp_callback, NULL);
 }
 
 static void
 setcarp_callback(int s, void *arg __unused)
 {
 	struct ifconfig_carp carpr = { };
 
 	if (ifconfig_carp_get_vhid(lifh, name, &carpr, carpr_vhid) == -1) {
 		if (ifconfig_err_errno(lifh) != ENOENT)
 			return;
 	}
 
 	carpr.carpr_vhid = carpr_vhid;
 	if (carpr_key != NULL)
 		/* XXX Should hash the password into the key here? */
 		strlcpy(carpr.carpr_key, carpr_key, CARP_KEY_LEN);
 	if (carpr_advskew > -1)
 		carpr.carpr_advskew = carpr_advskew;
 	if (carpr_advbase > -1)
 		carpr.carpr_advbase = carpr_advbase;
 	if (carpr_state > -1)
 		carpr.carpr_state = carpr_state;
 	if (carp_addr.s_addr != INADDR_ANY)
 		carpr.carpr_addr = carp_addr;
 	if (! IN6_IS_ADDR_UNSPECIFIED(&carp_addr6))
 		memcpy(&carpr.carpr_addr6, &carp_addr6,
 		    sizeof(carp_addr6));
 
 	if (ifconfig_carp_set_info(lifh, name, &carpr))
 		err(1, "SIOCSVH");
 }
 
 static void
 setcarp_passwd(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	if (carpr_vhid == -1)
 		errx(1, "passwd requires vhid");
 
 	carpr_key = val;
 }
 
 static void
 setcarp_advskew(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	if (carpr_vhid == -1)
 		errx(1, "advskew requires vhid");
 
 	carpr_advskew = atoi(val);
 }
 
 static void
 setcarp_advbase(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	if (carpr_vhid == -1)
 		errx(1, "advbase requires vhid");
 
 	carpr_advbase = atoi(val);
 }
 
 static void
 setcarp_state(const char *val, int d, int s, const struct afswtch *afp)
 {
 	int i;
 
 	if (carpr_vhid == -1)
 		errx(1, "state requires vhid");
 
 	for (i = 0; i <= CARP_MAXSTATE; i++)
 		if (strcasecmp(carp_states[i], val) == 0) {
 			carpr_state = i;
 			return;
 		}
 
 	errx(1, "unknown state");
 }
 
 static void
 setcarp_peer(const char *val, int d, int s, const struct afswtch *afp)
 {
 	carp_addr.s_addr = inet_addr(val);
 }
 
 static void
 setcarp_mcast(const char *val, int d, int s, const struct afswtch *afp)
 {
 	carp_addr.s_addr = htonl(INADDR_CARP_GROUP);
 }
 
 static void
 setcarp_peer6(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct addrinfo hints, *res;
 
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = AF_INET6;
 	hints.ai_flags = AI_NUMERICHOST;
 
 	if (getaddrinfo(val, NULL, &hints, &res) != 0)
 		errx(1, "Invalid IPv6 address %s", val);
 
 	memcpy(&carp_addr6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
 	    sizeof(carp_addr6));
 	freeaddrinfo(res);
 }
 
 static void
 setcarp_mcast6(const char *val, int d, int s, const struct afswtch *afp)
 {
 	bzero(&carp_addr6, sizeof(carp_addr6));
 	carp_addr6.s6_addr[0] = 0xff;
 	carp_addr6.s6_addr[1] = 0x02;
 	carp_addr6.s6_addr[15] = 0x12;
 }
 
 static struct cmd carp_cmds[] = {
 	DEF_CMD_ARG("advbase",	setcarp_advbase),
 	DEF_CMD_ARG("advskew",	setcarp_advskew),
 	DEF_CMD_ARG("pass",	setcarp_passwd),
 	DEF_CMD_ARG("vhid",	setcarp_vhid),
 	DEF_CMD_ARG("state",	setcarp_state),
 	DEF_CMD_ARG("peer",	setcarp_peer),
 	DEF_CMD("mcast",	0,	setcarp_mcast),
 	DEF_CMD_ARG("peer6",	setcarp_peer6),
 	DEF_CMD("mcast6", 	0,	setcarp_mcast6),
 };
 static struct afswtch af_carp = {
 	.af_name	= "af_carp",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = carp_status,
 };
 
 static __constructor void
 carp_ctor(void)
 {
-	int i;
-
 	/* Default to multicast. */
 	setcarp_mcast(NULL, 0, 0, NULL);
 	setcarp_mcast6(NULL, 0, 0, NULL);
 
-	for (i = 0; i < nitems(carp_cmds);  i++)
+	for (size_t i = 0; i < nitems(carp_cmds);  i++)
 		cmd_register(&carp_cmds[i]);
 	af_register(&af_carp);
 }
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
index 3a78b068eb5d..6bbc63ac9779 100644
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -1,691 +1,689 @@
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
  *
  * Copyright 2001 Wasabi Systems, Inc.
  * All rights reserved.
  *
  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *	This product includes software developed for the NetBSD Project by
  *	Wasabi Systems, Inc.
  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
  *    or promote products derived from this software without specific prior
  *    written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef lint
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_bridgevar.h>
 #include <net/route.h>
 
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <err.h>
 #include <errno.h>
 
 #include <libifconfig.h>
 
 #include "ifconfig.h"
 
 static const char *stpstates[] = { STP_STATES };
 static const char *stpproto[] = { STP_PROTOS };
 static const char *stproles[] = { STP_ROLES };
 
 static int
 get_val(const char *cp, u_long *valp)
 {
 	char *endptr;
 	u_long val;
 
 	errno = 0;
 	val = strtoul(cp, &endptr, 0);
 	if (cp[0] == '\0' || endptr[0] != '\0' || errno == ERANGE)
 		return (-1);
 
 	*valp = val;
 	return (0);
 }
 
 static int
 do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
 {
 	struct ifdrv ifd;
 
 	memset(&ifd, 0, sizeof(ifd));
 
 	strlcpy(ifd.ifd_name, name, sizeof(ifd.ifd_name));
 	ifd.ifd_cmd = op;
 	ifd.ifd_len = argsize;
 	ifd.ifd_data = arg;
 
 	return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
 }
 
 static void
 do_bridgeflag(int sock, const char *ifs, int flag, int set)
 {
 	struct ifbreq req;
 
 	strlcpy(req.ifbr_ifsname, ifs, sizeof(req.ifbr_ifsname));
 
 	if (do_cmd(sock, BRDGGIFFLGS, &req, sizeof(req), 0) < 0)
 		err(1, "unable to get bridge flags");
 
 	if (set)
 		req.ifbr_ifsflags |= flag;
 	else
 		req.ifbr_ifsflags &= ~flag;
 
 	if (do_cmd(sock, BRDGSIFFLGS, &req, sizeof(req), 1) < 0)
 		err(1, "unable to set bridge flags");
 }
 
 static void
 bridge_addresses(int s, const char *prefix)
 {
 	struct ifbaconf ifbac;
 	struct ifbareq *ifba;
 	char *inbuf = NULL, *ninbuf;
-	int i, len = 8192;
+	size_t len = 8192;
 	struct ether_addr ea;
 
 	for (;;) {
 		ninbuf = realloc(inbuf, len);
 		if (ninbuf == NULL)
 			err(1, "unable to allocate address buffer");
 		ifbac.ifbac_len = len;
 		ifbac.ifbac_buf = inbuf = ninbuf;
 		if (do_cmd(s, BRDGRTS, &ifbac, sizeof(ifbac), 0) < 0)
 			err(1, "unable to get address cache");
 		if ((ifbac.ifbac_len + sizeof(*ifba)) < len)
 			break;
 		len *= 2;
 	}
 
-	for (i = 0; i < ifbac.ifbac_len / sizeof(*ifba); i++) {
+	for (unsigned long i = 0; i < ifbac.ifbac_len / sizeof(*ifba); i++) {
 		ifba = ifbac.ifbac_req + i;
 		memcpy(ea.octet, ifba->ifba_dst,
 		    sizeof(ea.octet));
 		printf("%s%s Vlan%d %s %lu ", prefix, ether_ntoa(&ea),
 		    ifba->ifba_vlan, ifba->ifba_ifsname, ifba->ifba_expire);
 		printb("flags", ifba->ifba_flags, IFBAFBITS);
 		printf("\n");
 	}
 
 	free(inbuf);
 }
 
 static void
 bridge_status(int s)
 {
 	struct ifconfig_bridge_status *bridge;
 	struct ifbropreq *params;
 	const char *pad, *prefix;
 	uint8_t lladdr[ETHER_ADDR_LEN];
 	uint16_t bprio;
 
 	if (ifconfig_bridge_get_bridge_status(lifh, name, &bridge) == -1)
 		return;
 
 	params = bridge->params;
 
 	PV2ID(params->ifbop_bridgeid, bprio, lladdr);
 	printf("\tid %s priority %u hellotime %u fwddelay %u\n",
 	    ether_ntoa((struct ether_addr *)lladdr),
 	    params->ifbop_priority,
 	    params->ifbop_hellotime,
 	    params->ifbop_fwddelay);
 	printf("\tmaxage %u holdcnt %u proto %s maxaddr %u timeout %u\n",
 	    params->ifbop_maxage,
 	    params->ifbop_holdcount,
 	    stpproto[params->ifbop_protocol],
 	    bridge->cache_size,
 	    bridge->cache_lifetime);
 	PV2ID(params->ifbop_designated_root, bprio, lladdr);
 	printf("\troot id %s priority %d ifcost %u port %u\n",
 	    ether_ntoa((struct ether_addr *)lladdr),
 	    bprio,
 	    params->ifbop_root_path_cost,
 	    params->ifbop_root_port & 0xfff);
 
 	prefix = "\tmember: ";
 	pad    = "\t        ";
 	for (size_t i = 0; i < bridge->members_count; ++i) {
 		struct ifbreq *member = &bridge->members[i];
 
 		printf("%s%s ", prefix, member->ifbr_ifsname);
 		printb("flags", member->ifbr_ifsflags, IFBIFBITS);
 		printf("\n%s", pad);
 		printf("ifmaxaddr %u port %u priority %u path cost %u",
 		    member->ifbr_addrmax,
 		    member->ifbr_portno,
 		    member->ifbr_priority,
 		    member->ifbr_path_cost);
 		if (member->ifbr_ifsflags & IFBIF_STP) {
 			uint8_t proto = member->ifbr_proto;
 			uint8_t role = member->ifbr_role;
 			uint8_t state = member->ifbr_state;
 
 			if (proto < nitems(stpproto))
 				printf(" proto %s", stpproto[proto]);
 			else
 				printf(" <unknown proto %d>", proto);
 			printf("\n%s", pad);
 			if (role < nitems(stproles))
 				printf("role %s", stproles[role]);
 			else
 				printf("<unknown role %d>", role);
 			if (state < nitems(stpstates))
 				printf(" state %s", stpstates[state]);
 			else
 				printf(" <unknown state %d>", state);
 		}
 		printf("\n");
 	}
 
 	ifconfig_bridge_free_bridge_status(bridge);
 }
 
 static void
 setbridge_add(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbreq req;
 
 	memset(&req, 0, sizeof(req));
 	strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
 	if (do_cmd(s, BRDGADD, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGADD %s",  val);
 }
 
 static void
 setbridge_delete(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbreq req;
 
 	memset(&req, 0, sizeof(req));
 	strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
 	if (do_cmd(s, BRDGDEL, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGDEL %s",  val);
 }
 
 static void
 setbridge_discover(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_DISCOVER, 1);
 }
 
 static void
 unsetbridge_discover(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_DISCOVER, 0);
 }
 
 static void
 setbridge_learn(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_LEARNING,  1);
 }
 
 static void
 unsetbridge_learn(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_LEARNING,  0);
 }
 
 static void
 setbridge_sticky(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_STICKY,  1);
 }
 
 static void
 unsetbridge_sticky(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_STICKY,  0);
 }
 
 static void
 setbridge_span(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbreq req;
 
 	memset(&req, 0, sizeof(req));
 	strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
 	if (do_cmd(s, BRDGADDS, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGADDS %s",  val);
 }
 
 static void
 unsetbridge_span(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbreq req;
 
 	memset(&req, 0, sizeof(req));
 	strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
 	if (do_cmd(s, BRDGDELS, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGDELS %s",  val);
 }
 
 static void
 setbridge_stp(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_STP, 1);
 }
 
 static void
 unsetbridge_stp(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_STP, 0);
 }
 
 static void
 setbridge_edge(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_EDGE, 1);
 }
 
 static void
 unsetbridge_edge(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_EDGE, 0);
 }
 
 static void
 setbridge_autoedge(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_AUTOEDGE, 1);
 }
 
 static void
 unsetbridge_autoedge(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_AUTOEDGE, 0);
 }
 
 static void
 setbridge_ptp(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_PTP, 1);
 }
 
 static void
 unsetbridge_ptp(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_PTP, 0);
 }
 
 static void
 setbridge_autoptp(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_AUTOPTP, 1);
 }
 
 static void
 unsetbridge_autoptp(const char *val, int d, int s, const struct afswtch *afp)
 {
 	do_bridgeflag(s, val, IFBIF_BSTP_AUTOPTP, 0);
 }
 
 static void
 setbridge_flush(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbreq req;
 
 	memset(&req, 0, sizeof(req));
 	req.ifbr_ifsflags = IFBF_FLUSHDYN;
 	if (do_cmd(s, BRDGFLUSH, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGFLUSH");
 }
 
 static void
 setbridge_flushall(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbreq req;
 
 	memset(&req, 0, sizeof(req));
 	req.ifbr_ifsflags = IFBF_FLUSHALL;
 	if (do_cmd(s, BRDGFLUSH, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGFLUSH");
 }
 
 static void
 setbridge_static(const char *val, const char *mac, int s,
     const struct afswtch *afp)
 {
 	struct ifbareq req;
 	struct ether_addr *ea;
 
 	memset(&req, 0, sizeof(req));
 	strlcpy(req.ifba_ifsname, val, sizeof(req.ifba_ifsname));
 
 	ea = ether_aton(mac);
 	if (ea == NULL)
 		errx(1, "%s: invalid address: %s", val, mac);
 
 	memcpy(req.ifba_dst, ea->octet, sizeof(req.ifba_dst));
 	req.ifba_flags = IFBAF_STATIC;
 	req.ifba_vlan = 1; /* XXX allow user to specify */
 
 	if (do_cmd(s, BRDGSADDR, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGSADDR %s",  val);
 }
 
 static void
 setbridge_deladdr(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifbareq req;
 	struct ether_addr *ea;
 
 	memset(&req, 0, sizeof(req));
 
 	ea = ether_aton(val);
 	if (ea == NULL)
 		errx(1, "invalid address: %s",  val);
 
 	memcpy(req.ifba_dst, ea->octet, sizeof(req.ifba_dst));
 
 	if (do_cmd(s, BRDGDADDR, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGDADDR %s",  val);
 }
 
 static void
 setbridge_addr(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	bridge_addresses(s, "");
 }
 
 static void
 setbridge_maxaddr(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xffffffff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_csize = val & 0xffffffff;
 
 	if (do_cmd(s, BRDGSCACHE, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSCACHE %s",  arg);
 }
 
 static void
 setbridge_hellotime(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_hellotime = val & 0xff;
 
 	if (do_cmd(s, BRDGSHT, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSHT %s",  arg);
 }
 
 static void
 setbridge_fwddelay(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_fwddelay = val & 0xff;
 
 	if (do_cmd(s, BRDGSFD, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSFD %s",  arg);
 }
 
 static void
 setbridge_maxage(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_maxage = val & 0xff;
 
 	if (do_cmd(s, BRDGSMA, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSMA %s",  arg);
 }
 
 static void
 setbridge_priority(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xffff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_prio = val & 0xffff;
 
 	if (do_cmd(s, BRDGSPRI, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSPRI %s",  arg);
 }
 
 static void
 setbridge_protocol(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 
 	if (strcasecmp(arg, "stp") == 0) {
 		param.ifbrp_proto = 0;
 	} else if (strcasecmp(arg, "rstp") == 0) {
 		param.ifbrp_proto = 2;
 	} else {
 		errx(1, "unknown stp protocol");
 	}
 
 	if (do_cmd(s, BRDGSPROTO, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSPROTO %s",  arg);
 }
 
 static void
 setbridge_holdcount(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_txhc = val & 0xff;
 
 	if (do_cmd(s, BRDGSTXHC, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSTXHC %s",  arg);
 }
 
 static void
 setbridge_ifpriority(const char *ifn, const char *pri, int s,
     const struct afswtch *afp)
 {
 	struct ifbreq req;
 	u_long val;
 
 	memset(&req, 0, sizeof(req));
 
 	if (get_val(pri, &val) < 0 || (val & ~0xff) != 0)
 		errx(1, "invalid value: %s",  pri);
 
 	strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
 	req.ifbr_priority = val & 0xff;
 
 	if (do_cmd(s, BRDGSIFPRIO, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGSIFPRIO %s",  pri);
 }
 
 static void
 setbridge_ifpathcost(const char *ifn, const char *cost, int s,
     const struct afswtch *afp)
 {
 	struct ifbreq req;
 	u_long val;
 
 	memset(&req, 0, sizeof(req));
 
 	if (get_val(cost, &val) < 0)
 		errx(1, "invalid value: %s",  cost);
 
 	strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
 	req.ifbr_path_cost = val;
 
 	if (do_cmd(s, BRDGSIFCOST, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGSIFCOST %s",  cost);
 }
 
 static void
 setbridge_ifmaxaddr(const char *ifn, const char *arg, int s,
     const struct afswtch *afp)
 {
 	struct ifbreq req;
 	u_long val;
 
 	memset(&req, 0, sizeof(req));
 
 	if (get_val(arg, &val) < 0 || (val & ~0xffffffff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
 	req.ifbr_addrmax = val & 0xffffffff;
 
 	if (do_cmd(s, BRDGSIFAMAX, &req, sizeof(req), 1) < 0)
 		err(1, "BRDGSIFAMAX %s",  arg);
 }
 
 static void
 setbridge_timeout(const char *arg, int d, int s, const struct afswtch *afp)
 {
 	struct ifbrparam param;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xffffffff) != 0)
 		errx(1, "invalid value: %s",  arg);
 
 	param.ifbrp_ctime = val & 0xffffffff;
 
 	if (do_cmd(s, BRDGSTO, &param, sizeof(param), 1) < 0)
 		err(1, "BRDGSTO %s",  arg);
 }
 
 static void
 setbridge_private(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_PRIVATE, 1);
 }
 
 static void
 unsetbridge_private(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	do_bridgeflag(s, val, IFBIF_PRIVATE, 0);
 }
 
 static struct cmd bridge_cmds[] = {
 	DEF_CMD_ARG("addm",		setbridge_add),
 	DEF_CMD_ARG("deletem",		setbridge_delete),
 	DEF_CMD_ARG("discover",		setbridge_discover),
 	DEF_CMD_ARG("-discover",	unsetbridge_discover),
 	DEF_CMD_ARG("learn",		setbridge_learn),
 	DEF_CMD_ARG("-learn",		unsetbridge_learn),
 	DEF_CMD_ARG("sticky",		setbridge_sticky),
 	DEF_CMD_ARG("-sticky",		unsetbridge_sticky),
 	DEF_CMD_ARG("span",		setbridge_span),
 	DEF_CMD_ARG("-span",		unsetbridge_span),
 	DEF_CMD_ARG("stp",		setbridge_stp),
 	DEF_CMD_ARG("-stp",		unsetbridge_stp),
 	DEF_CMD_ARG("edge",		setbridge_edge),
 	DEF_CMD_ARG("-edge",		unsetbridge_edge),
 	DEF_CMD_ARG("autoedge",		setbridge_autoedge),
 	DEF_CMD_ARG("-autoedge",	unsetbridge_autoedge),
 	DEF_CMD_ARG("ptp",		setbridge_ptp),
 	DEF_CMD_ARG("-ptp",		unsetbridge_ptp),
 	DEF_CMD_ARG("autoptp",		setbridge_autoptp),
 	DEF_CMD_ARG("-autoptp",		unsetbridge_autoptp),
 	DEF_CMD("flush", 0,		setbridge_flush),
 	DEF_CMD("flushall", 0,		setbridge_flushall),
 	DEF_CMD_ARG2("static",		setbridge_static),
 	DEF_CMD_ARG("deladdr",		setbridge_deladdr),
 	DEF_CMD("addr",	 1,		setbridge_addr),
 	DEF_CMD_ARG("maxaddr",		setbridge_maxaddr),
 	DEF_CMD_ARG("hellotime",	setbridge_hellotime),
 	DEF_CMD_ARG("fwddelay",		setbridge_fwddelay),
 	DEF_CMD_ARG("maxage",		setbridge_maxage),
 	DEF_CMD_ARG("priority",		setbridge_priority),
 	DEF_CMD_ARG("proto",		setbridge_protocol),
 	DEF_CMD_ARG("holdcnt",		setbridge_holdcount),
 	DEF_CMD_ARG2("ifpriority",	setbridge_ifpriority),
 	DEF_CMD_ARG2("ifpathcost",	setbridge_ifpathcost),
 	DEF_CMD_ARG2("ifmaxaddr",	setbridge_ifmaxaddr),
 	DEF_CMD_ARG("timeout",		setbridge_timeout),
 	DEF_CMD_ARG("private",		setbridge_private),
 	DEF_CMD_ARG("-private",		unsetbridge_private),
 };
 static struct afswtch af_bridge = {
 	.af_name	= "af_bridge",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = bridge_status,
 };
 
 static __constructor void
 bridge_ctor(void)
 {
-	int i;
-
-	for (i = 0; i < nitems(bridge_cmds);  i++)
+	for (size_t i = 0; i < nitems(bridge_cmds);  i++)
 		cmd_register(&bridge_cmds[i]);
 	af_register(&af_bridge);
 }
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index e1467e661657..db275d877c00 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1,1985 +1,1992 @@
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 #ifndef lint
 static const char copyright[] =
 "@(#) Copyright (c) 1983, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n";
 #if 0
 static char sccsid[] = "@(#)ifconfig.c	8.2 (Berkeley) 2/16/94";
 #endif
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #ifdef JAIL
 #include <sys/jail.h>
 #endif
 #include <sys/module.h>
 #include <sys/linker.h>
 #include <sys/nv.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/route.h>
 
 /* IP */
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
 #include <fnmatch.h>
 #include <ifaddrs.h>
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #ifdef JAIL
 #include <jail.h>
 #endif
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include <libifconfig.h>
 
 #include "ifconfig.h"
 
 ifconfig_handle_t *lifh;
 
 /*
  * Since "struct ifreq" is composed of various union members, callers
  * should pay special attention to interpret the value.
  * (.e.g. little/big endian difference in the structure.)
  */
 struct	ifreq ifr;
 
 char	name[IFNAMSIZ];
-char	*descr = NULL;
-size_t	descrlen = 64;
+#ifdef WITHOUT_NETLINK
+static char	*descr = NULL;
+static size_t	descrlen = 64;
+#endif
 static int	setaddr;
 static int	setmask;
 static int	doalias;
 static int	clearaddr;
 int	newaddr = 1;
 int	verbose;
 int	printifname = 0;
 
 struct ifconfig_args args;
 
 int	printkeys = 0;		/* Print keying material for interfaces. */
 int	exit_code = 0;
 
 /* Formatter Strings */
 char	*f_inet, *f_inet6, *f_ether, *f_addr;
 
+#ifdef WITHOUT_NETLINK
 static void list_interfaces_ioctl(struct ifconfig_args *args);
 static	void status(struct ifconfig_args *args, const struct sockaddr_dl *sdl,
 		struct ifaddrs *ifa);
+#endif
 static _Noreturn void usage(void);
 
 static int getifflags(const char *ifname, int us, bool err_ok);
 
 static struct afswtch *af_getbyname(const char *name);
 
-void printifnamemaybe(void);
-
 static struct option *opts = NULL;
 
 struct ifa_order_elt {
 	int if_order;
 	int af_orders[255];
 	struct ifaddrs *ifa;
 	TAILQ_ENTRY(ifa_order_elt) link;
 };
 
 TAILQ_HEAD(ifa_queue, ifa_order_elt);
 
 static struct module_map_entry {
 	const char *ifname;
 	const char *kldname;
 } module_map[] = {
 	{
 		.ifname = "tun",
 		.kldname = "if_tuntap",
 	},
 	{
 		.ifname = "tap",
 		.kldname = "if_tuntap",
 	},
 	{
 		.ifname = "vmnet",
 		.kldname = "if_tuntap",
 	},
 	{
 		.ifname = "ipsec",
 		.kldname = "ipsec",
 	},
 	{
 		/*
 		 * This mapping exists because there is a conflicting enc module
 		 * in CAM.  ifconfig's guessing behavior will attempt to match
 		 * the ifname to a module as well as if_${ifname} and clash with
 		 * CAM enc.  This is an assertion of the correct module to load.
 		 */
 		.ifname = "enc",
 		.kldname = "if_enc",
 	},
 };
 
 
 void
 opt_register(struct option *p)
 {
 	p->next = opts;
 	opts = p;
 }
 
 static void
 usage(void)
 {
 	char options[1024];
 	struct option *p;
 
 	/* XXX not right but close enough for now */
 	options[0] = '\0';
 	for (p = opts; p != NULL; p = p->next) {
 		strlcat(options, p->opt_usage, sizeof(options));
 		strlcat(options, " ", sizeof(options));
 	}
 
 	fprintf(stderr,
 	"usage: ifconfig [-j jail] [-f type:format] %sinterface address_family\n"
 	"                [address [dest_address]] [parameters]\n"
 	"       ifconfig [-j jail] interface create\n"
 	"       ifconfig [-j jail] -a %s[-d] [-m] [-u] [-v] [address_family]\n"
 	"       ifconfig [-j jail] -l [-d] [-u] [address_family]\n"
 	"       ifconfig [-j jail] %s[-d] [-m] [-u] [-v]\n",
 		options, options, options);
 	exit(1);
 }
 
 void
 ioctl_ifcreate(int s, struct ifreq *ifr)
 {
 	if (ioctl(s, SIOCIFCREATE2, ifr) < 0) {
 		switch (errno) {
 		case EEXIST:
 			errx(1, "interface %s already exists", ifr->ifr_name);
 		default:
 			err(1, "SIOCIFCREATE2 (%s)", ifr->ifr_name);
 		}
 	}
 }
 
+#ifdef WITHOUT_NETLINK
 static int
 calcorders(struct ifaddrs *ifa, struct ifa_queue *q)
 {
 	struct ifaddrs *prev;
 	struct ifa_order_elt *cur;
 	unsigned int ord, af, ifa_ord;
 
 	prev = NULL;
 	cur = NULL;
 	ord = 0;
 	ifa_ord = 0;
 
 	while (ifa != NULL) {
 		if (prev == NULL ||
 		    strcmp(ifa->ifa_name, prev->ifa_name) != 0) {
 			cur = calloc(1, sizeof(*cur));
 
 			if (cur == NULL)
 				return (-1);
 
 			TAILQ_INSERT_TAIL(q, cur, link);
 			cur->if_order = ifa_ord ++;
 			cur->ifa = ifa;
 			ord = 0;
 		}
 
 		if (ifa->ifa_addr) {
 			af = ifa->ifa_addr->sa_family;
 
 			if (af < nitems(cur->af_orders) &&
 			    cur->af_orders[af] == 0)
 				cur->af_orders[af] = ++ord;
 		}
 		prev = ifa;
 		ifa = ifa->ifa_next;
 	}
 
 	return (0);
 }
 
 static int
 cmpifaddrs(struct ifaddrs *a, struct ifaddrs *b, struct ifa_queue *q)
 {
 	struct ifa_order_elt *cur, *e1, *e2;
 	unsigned int af1, af2;
 	int ret;
 
 	e1 = e2 = NULL;
 
 	ret = strcmp(a->ifa_name, b->ifa_name);
 	if (ret != 0) {
 		TAILQ_FOREACH(cur, q, link) {
 			if (e1 && e2)
 				break;
 
 			if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0)
 				e1 = cur;
 			else if (strcmp(cur->ifa->ifa_name, b->ifa_name) == 0)
 				e2 = cur;
 		}
 
 		if (!e1 || !e2)
 			return (0);
 		else
 			return (e1->if_order - e2->if_order);
 
 	} else if (a->ifa_addr != NULL && b->ifa_addr != NULL) {
 		TAILQ_FOREACH(cur, q, link) {
 			if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) {
 				e1 = cur;
 				break;
 			}
 		}
 
 		if (!e1)
 			return (0);
 
 		af1 = a->ifa_addr->sa_family;
 		af2 = b->ifa_addr->sa_family;
 
 		if (af1 < nitems(e1->af_orders) && af2 < nitems(e1->af_orders))
 			return (e1->af_orders[af1] - e1->af_orders[af2]);
 	}
 
 	return (0);
 }
+#endif
 
 static void freeformat(void)
 {
 
 	if (f_inet != NULL)
 		free(f_inet);
 	if (f_inet6 != NULL)
 		free(f_inet6);
 	if (f_ether != NULL)
 		free(f_ether);
 	if (f_addr != NULL)
 		free(f_addr);
 }
 
 static void setformat(char *input)
 {
 	char	*formatstr, *category, *modifier; 
 
 	formatstr = strdup(input);
 	while ((category = strsep(&formatstr, ",")) != NULL) {
 		modifier = strchr(category, ':');
 		if (modifier == NULL || modifier[1] == '\0') {
 			warnx("Skipping invalid format specification: %s\n",
 			    category);
 			continue;
 		}
 
 		/* Split the string on the separator, then seek past it */
 		modifier[0] = '\0';
 		modifier++;
 
 		if (strcmp(category, "addr") == 0)
 			f_addr = strdup(modifier);
 		else if (strcmp(category, "ether") == 0)
 			f_ether = strdup(modifier);
 		else if (strcmp(category, "inet") == 0)
 			f_inet = strdup(modifier);
 		else if (strcmp(category, "inet6") == 0)
 			f_inet6 = strdup(modifier);
 	}
 	free(formatstr);
 }
 
+#ifdef WITHOUT_NETLINK
 static struct ifaddrs *
 sortifaddrs(struct ifaddrs *list,
     int (*compare)(struct ifaddrs *, struct ifaddrs *, struct ifa_queue *),
     struct ifa_queue *q)
 {
 	struct ifaddrs *right, *temp, *last, *result, *next, *tail;
 	
 	right = list;
 	temp = list;
 	last = list;
 	result = NULL;
 	next = NULL;
 	tail = NULL;
 
 	if (!list || !list->ifa_next)
 		return (list);
 
 	while (temp && temp->ifa_next) {
 		last = right;
 		right = right->ifa_next;
 		temp = temp->ifa_next->ifa_next;
 	}
 
 	last->ifa_next = NULL;
 
 	list = sortifaddrs(list, compare, q);
 	right = sortifaddrs(right, compare, q);
 
 	while (list || right) {
 
 		if (!right) {
 			next = list;
 			list = list->ifa_next;
 		} else if (!list) {
 			next = right;
 			right = right->ifa_next;
 		} else if (compare(list, right, q) <= 0) {
 			next = list;
 			list = list->ifa_next;
 		} else {
 			next = right;
 			right = right->ifa_next;
 		}
 
 		if (!result)
 			result = next;
 		else
 			tail->ifa_next = next;
 
 		tail = next;
 	}
 
 	return (result);
 }
+#endif
 
-void printifnamemaybe()
+static void
+printifnamemaybe(void)
 {
 	if (printifname)
 		printf("%s\n", name);
 }
 
 static void
 list_interfaces(struct ifconfig_args *args)
 {
 #ifdef WITHOUT_NETLINK
 	list_interfaces_ioctl(args);
 #else
 	list_interfaces_nl(args);
 #endif
 }
 
 static char *
 args_peek(struct ifconfig_args *args)
 {
 	if (args->argc > 0)
 		return (args->argv[0]);
 	return (NULL);
 }
 
 static char *
 args_pop(struct ifconfig_args *args)
 {
 	if (args->argc == 0)
 		return (NULL);
 
 	char *arg = args->argv[0];
 
 	args->argc--;
 	args->argv++;
 
 	return (arg);
 }
 
 static void
 args_parse(struct ifconfig_args *args, int argc, char *argv[])
 {
 	char options[1024];
 	struct option *p;
 	int c;
 
 	/* Parse leading line options */
 	strlcpy(options, "G:adf:j:klmnuv", sizeof(options));
 	for (p = opts; p != NULL; p = p->next)
 		strlcat(options, p->opt, sizeof(options));
 	while ((c = getopt(argc, argv, options)) != -1) {
 		switch (c) {
 		case 'a':	/* scan all interfaces */
 			args->all = true;
 			break;
 		case 'd':	/* restrict scan to "down" interfaces */
 			args->downonly = true;
 			break;
 		case 'f':
 			if (optarg == NULL)
 				usage();
 			setformat(optarg);
 			break;
 		case 'G':
 			if (optarg == NULL || args->all == 0)
 				usage();
 			args->nogroup = optarg;
 			break;
 		case 'j':
 #ifdef JAIL
 			if (optarg == NULL)
 				usage();
 			args->jail_name = optarg;
 #else
 			Perror("not built with jail support");
 #endif
 			break;
 		case 'k':
 			args->printkeys = true;
 			break;
 		case 'l':	/* scan interface names only */
 			args->namesonly++;
 			break;
 		case 'm':	/* show media choices in status */
 			args->supmedia = true;
 			break;
 		case 'n':	/* suppress module loading */
 			args->noload = true;
 			break;
 		case 'u':	/* restrict scan to "up" interfaces */
 			args->uponly = true;
 			break;
 		case 'v':
 			args->verbose++;
 			break;
 		case 'g':
 			if (args->all) {
 				if (optarg == NULL)
 					usage();
 				args->matchgroup = optarg;
 				break;
 			}
 			/* FALLTHROUGH */
 		default:
 			for (p = opts; p != NULL; p = p->next)
 				if (p->opt[0] == c) {
 					p->cb(optarg);
 					break;
 				}
 			if (p == NULL)
 				usage();
 			break;
 		}
 	}
 	argc -= optind;
 	argv += optind;
 
 	/* -l cannot be used with -a or -m */
 	if (args->namesonly && (args->all || args->supmedia))
 		usage();
 
 	/* nonsense.. */
 	if (args->uponly && args->downonly)
 		usage();
 
 	/* no arguments is equivalent to '-a' */
 	if (!args->namesonly && argc < 1)
 		args->all = 1;
 
 	/* -a and -l allow an address family arg to limit the output */
 	if (args->all || args->namesonly) {
 		if (argc > 1)
 			usage();
 
 		if (argc == 1) {
 			const struct afswtch *afp = af_getbyname(*argv);
 
 			if (afp == NULL) {
 				warnx("Address family '%s' unknown.", *argv);
 				usage();
 			}
 			if (afp->af_name != NULL)
 				argc--, argv++;
 			/* leave with afp non-zero */
 			args->afp = afp;
 		}
 	} else {
 		/* not listing, need an argument */
 		if (argc < 1)
 			usage();
 	}
 
 	args->argc = argc;
 	args->argv = argv;
 
 	/* Sync global variables */
 	printkeys = args->printkeys;
 	verbose = args->verbose;
 }
 
 int
 main(int ac, char *av[])
 {
 	char *envformat;
 	size_t iflen;
 	int flags;
 #ifdef JAIL
 	int jid;
 #endif
 	f_inet = f_inet6 = f_ether = f_addr = NULL;
 
 	lifh = ifconfig_open();
 	if (lifh == NULL)
 		err(EXIT_FAILURE, "ifconfig_open");
 
 	envformat = getenv("IFCONFIG_FORMAT");
 	if (envformat != NULL)
 		setformat(envformat);
 
 	/*
 	 * Ensure we print interface name when expected to,
 	 * even if we terminate early due to error.
 	 */
 	atexit(printifnamemaybe);
 
 	args_parse(&args, ac, av);
 
 #ifdef JAIL
 	if (args.jail_name) {
 		jid = jail_getid(args.jail_name);
 		if (jid == -1)
 			Perror("jail not found");
 		if (jail_attach(jid) != 0)
 			Perror("cannot attach to jail");
 	}
 #endif
 
 	if (!args.all && !args.namesonly) {
 		/* not listing, need an argument */
 		args.ifname = args_pop(&args);
 
 		/* check and maybe load support for this interface */
 		ifmaybeload(&args, args.ifname);
 
 		char *arg = args_peek(&args);
 		if (if_nametoindex(args.ifname) == 0) {
 			/*
 			 * NOTE:  We must special-case the `create' command
 			 * right here as we would otherwise fail when trying
 			 * to find the interface.
 			 */
 			if (arg != NULL && (strcmp(arg, "create") == 0 ||
 			    strcmp(arg, "plumb") == 0)) {
 				iflen = strlcpy(name, args.ifname, sizeof(name));
 				if (iflen >= sizeof(name))
 					errx(1, "%s: cloning name too long",
 					    args.ifname);
 				ifconfig(args.argc, args.argv, 1, NULL);
 				exit(exit_code);
 			}
 #ifdef JAIL
 			/*
 			 * NOTE:  We have to special-case the `-vnet' command
 			 * right here as we would otherwise fail when trying
 			 * to find the interface as it lives in another vnet.
 			 */
 			if (arg != NULL && (strcmp(arg, "-vnet") == 0)) {
 				iflen = strlcpy(name, args.ifname, sizeof(name));
 				if (iflen >= sizeof(name))
 					errx(1, "%s: interface name too long",
 					    args.ifname);
 				ifconfig(args.argc, args.argv, 0, NULL);
 				exit(exit_code);
 			}
 #endif
 			errx(1, "interface %s does not exist", args.ifname);
 		} else {
 			/*
 			 * Do not allow use `create` command as hostname if
 			 * address family is not specified.
 			 */
 			if (arg != NULL && (strcmp(arg, "create") == 0 ||
 			    strcmp(arg, "plumb") == 0)) {
 				if (args.argc == 1)
 					errx(1, "interface %s already exists",
 					    args.ifname);
 				args_pop(&args);
 			}
 		}
 	}
 
 	/* Check for address family */
 	if (args.argc > 0) {
 		args.afp = af_getbyname(args_peek(&args));
 		if (args.afp != NULL)
 			args_pop(&args);
 	}
 
 	/*
 	 * Check for a requested configuration action on a single interface,
 	 * which doesn't require building, sorting, and searching the entire
 	 * system address list
 	 */
 	if ((args.argc > 0) && (args.ifname != NULL)) {
 		iflen = strlcpy(name, args.ifname, sizeof(name));
 		if (iflen >= sizeof(name)) {
 			warnx("%s: interface name too long, skipping", args.ifname);
 		} else {
 			flags = getifflags(name, -1, false);
 			if (!(((flags & IFF_CANTCONFIG) != 0) ||
 				(args.downonly && (flags & IFF_UP) != 0) ||
 				(args.uponly && (flags & IFF_UP) == 0)))
 				ifconfig(args.argc, args.argv, 0, args.afp);
 		}
 		goto done;
 	}
 
 	args.allfamilies = args.afp == NULL;
 
 	list_interfaces(&args);
 
 done:
 	freeformat();
 	ifconfig_close(lifh);
 	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);
 	}
 }
 
+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);
+}
+
+#ifdef WITHOUT_NETLINK
 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);
 }
 
-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);
-}
-
-#ifdef WITHOUT_NETLINK
 static void
 list_interfaces_ioctl(struct ifconfig_args *args)
 {
 	struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q);
 	struct ifaddrs *ifap, *sifap, *ifa;
 	struct ifa_order_elt *cur, *tmp;
 	char *namecp = NULL;
 	int ifindex;
 	size_t iflen;
 
 	if (getifaddrs(&ifap) != 0)
 		err(EXIT_FAILURE, "getifaddrs");
 
 	char *cp = NULL;
 	
 	if (calcorders(ifap, &q) != 0)
 		err(EXIT_FAILURE, "calcorders");
 		
 	sifap = sortifaddrs(ifap, cmpifaddrs, &q);
 
 	TAILQ_FOREACH_SAFE(cur, &q, link, tmp)
 		free(cur);
 
 	ifindex = 0;
 	for (ifa = sifap; ifa; ifa = ifa->ifa_next) {
 		struct ifreq paifr = {};
 		const struct sockaddr_dl *sdl;
 
 		strlcpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name));
 		if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) {
 			memcpy(&paifr.ifr_addr, ifa->ifa_addr,
 			    ifa->ifa_addr->sa_len);
 		}
 
 		if (args->ifname != NULL && strcmp(args->ifname, ifa->ifa_name) != 0)
 			continue;
 		if (ifa->ifa_addr->sa_family == AF_LINK)
 			sdl = (const struct sockaddr_dl *) ifa->ifa_addr;
 		else
 			sdl = NULL;
 		if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !args->namesonly)
 			continue;
 		iflen = strlcpy(name, ifa->ifa_name, sizeof(name));
 		if (iflen >= sizeof(name)) {
 			warnx("%s: interface name too long, skipping",
 			    ifa->ifa_name);
 			continue;
 		}
 		cp = ifa->ifa_name;
 
 		if (!match_if_flags(args, ifa->ifa_flags))
 			continue;
 		if (!group_member(ifa->ifa_name, args->matchgroup, args->nogroup))
 			continue;
 		/*
 		 * Are we just listing the interfaces?
 		 */
 		if (args->namesonly) {
 			if (namecp == cp)
 				continue;
 			if (!match_afp(args->afp, ifa->ifa_addr->sa_family, sdl))
 				continue;
 			namecp = cp;
 			ifindex++;
 			if (ifindex > 1)
 				printf(" ");
 			fputs(name, stdout);
 			continue;
 		}
 		ifindex++;
 
 		if (args->argc > 0)
 			ifconfig(args->argc, args->argv, 0, args->afp);
 		else
 			status(args, sdl, ifa);
 	}
 	if (args->namesonly)
 		printf("\n");
 	freeifaddrs(ifap);
 }
 #endif
 
 /*
  * Returns true if an interface should be listed because any its groups
  * matches shell pattern "match" and none of groups matches pattern "nomatch".
  * If any pattern is NULL, corresponding condition is skipped.
  */
 bool
 group_member(const char *ifname, const char *match, const char *nomatch)
 {
 	static int		 sock = -1;
 
 	struct ifgroupreq	 ifgr;
 	struct ifg_req		*ifg;
-	int			 len;
+	unsigned int		 len;
 	bool			 matched, nomatched;
 
 	/* Sanity checks. */
 	if (match == NULL && nomatch == NULL)
 		return (true);
 	if (ifname == NULL)
 		return (false);
 
 	memset(&ifgr, 0, sizeof(ifgr));
 	strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ);
 
 	/* The socket is opened once. Let _exit() close it. */
 	if (sock == -1) {
 		sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
     		if (sock == -1)
             	    errx(1, "%s: socket(AF_LOCAL,SOCK_DGRAM)", __func__);
 	}
 
 	/* Determine amount of memory for the list of groups. */
 	if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
 		if (errno == EINVAL || errno == ENOTTY)
 			return (false);
 		else
 			errx(1, "%s: SIOCGIFGROUP", __func__);
 	}
 
 	/* Obtain the list of groups. */
 	len = ifgr.ifgr_len;
 	ifgr.ifgr_groups =
 	    (struct ifg_req *)calloc(len / sizeof(*ifg), sizeof(*ifg));
 
 	if (ifgr.ifgr_groups == NULL)
 		errx(1, "%s: no memory", __func__);
 	if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
 		errx(1, "%s: SIOCGIFGROUP", __func__);
 
 	/* Perform matching. */
 	matched = false;
 	nomatched = true;
 	for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(*ifg); ifg++) {
 		len -= sizeof(struct ifg_req);
 		if (match)
 			matched |= !fnmatch(match, ifg->ifgrq_group, 0);
 		if (nomatch)
 			nomatched &= fnmatch(nomatch, ifg->ifgrq_group, 0);
 	}
 	free(ifgr.ifgr_groups);
 
 	if (match && !nomatch)
 		return (matched);
 	if (!match && nomatch)
 		return (nomatched);
 	return (matched && nomatched);
 }
 
 static struct afswtch *afs = NULL;
 
 void
 af_register(struct afswtch *p)
 {
 	p->af_next = afs;
 	afs = p;
 }
 
 static struct afswtch *
 af_getbyname(const char *name)
 {
 	struct afswtch *afp;
 
 	for (afp = afs; afp !=  NULL; afp = afp->af_next)
 		if (strcmp(afp->af_name, name) == 0)
 			return afp;
 	return NULL;
 }
 
 struct afswtch *
 af_getbyfamily(int af)
 {
 	struct afswtch *afp;
 
 	for (afp = afs; afp != NULL; afp = afp->af_next)
 		if (afp->af_af == af)
 			return afp;
 	return NULL;
 }
 
 void
 af_other_status(int s)
 {
 	struct afswtch *afp;
 	uint8_t afmask[howmany(AF_MAX, NBBY)];
 
 	memset(afmask, 0, sizeof(afmask));
 	for (afp = afs; afp != NULL; afp = afp->af_next) {
 		if (afp->af_other_status == NULL)
 			continue;
 		if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af))
 			continue;
 		afp->af_other_status(s);
 		setbit(afmask, afp->af_af);
 	}
 }
 
 static void
 af_all_tunnel_status(int s)
 {
 	struct afswtch *afp;
 	uint8_t afmask[howmany(AF_MAX, NBBY)];
 
 	memset(afmask, 0, sizeof(afmask));
 	for (afp = afs; afp != NULL; afp = afp->af_next) {
 		if (afp->af_status_tunnel == NULL)
 			continue;
 		if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af))
 			continue;
 		afp->af_status_tunnel(s);
 		setbit(afmask, afp->af_af);
 	}
 }
 
 static struct cmd *cmds = NULL;
 
 void
 cmd_register(struct cmd *p)
 {
 	p->c_next = cmds;
 	cmds = p;
 }
 
 static const struct cmd *
 cmd_lookup(const char *name, int iscreate)
 {
 	const struct cmd *p;
 
 	for (p = cmds; p != NULL; p = p->c_next)
 		if (strcmp(name, p->c_name) == 0) {
 			if (iscreate) {
 				if (p->c_iscloneop)
 					return p;
 			} else {
 				if (!p->c_iscloneop)
 					return p;
 			}
 		}
 	return NULL;
 }
 
 struct callback {
 	callback_func *cb_func;
 	void	*cb_arg;
 	struct callback *cb_next;
 };
 static struct callback *callbacks = NULL;
 
 void
 callback_register(callback_func *func, void *arg)
 {
 	struct callback *cb;
 
 	cb = malloc(sizeof(struct callback));
 	if (cb == NULL)
 		errx(1, "unable to allocate memory for callback");
 	cb->cb_func = func;
 	cb->cb_arg = arg;
 	cb->cb_next = callbacks;
 	callbacks = cb;
 }
 
 /* specially-handled commands */
 static void setifaddr(const char *, int, int, const struct afswtch *);
 static const struct cmd setifaddr_cmd = DEF_CMD("ifaddr", 0, setifaddr);
 
 static void setifdstaddr(const char *, int, int, const struct afswtch *);
 static const struct cmd setifdstaddr_cmd =
 	DEF_CMD("ifdstaddr", 0, setifdstaddr);
 
 static void
 delifaddr(int s, const struct afswtch *afp)
 {
 	if (afp->af_ridreq == NULL || afp->af_difaddr == 0) {
 		warnx("interface %s cannot change %s addresses!",
 		    name, afp->af_name);
 		clearaddr = 0;
 		return;
 	}
 
 	strlcpy(((struct ifreq *)afp->af_ridreq)->ifr_name, name,
 		sizeof ifr.ifr_name);
 	int ret = ioctl(s, afp->af_difaddr, afp->af_ridreq);
 	if (ret < 0) {
 		if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
 			/* means no previous address for interface */
 		} else
 			Perror("ioctl (SIOCDIFADDR)");
 	}
 }
 
 static void
 addifaddr(int s, const struct afswtch *afp)
 {
 	if (afp->af_addreq == NULL || afp->af_aifaddr == 0) {
 		warnx("interface %s cannot change %s addresses!",
 		      name, afp->af_name);
 		newaddr = 0;
 		return;
 	}
 
 	if (setaddr || setmask) {
 		strlcpy(((struct ifreq *)afp->af_addreq)->ifr_name, name,
 			sizeof ifr.ifr_name);
 		if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0)
 			Perror("ioctl (SIOCAIFADDR)");
 	}
 }
 
 int
 ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp)
 {
 	const struct afswtch *afp, *nafp;
 	const struct cmd *p;
 	struct callback *cb;
 	int s;
 
 	strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
 	afp = NULL;
 	if (uafp != NULL)
 		afp = uafp;
 	/*
 	 * This is the historical "accident" allowing users to configure IPv4
 	 * addresses without the "inet" keyword which while a nice feature has
 	 * proven to complicate other things.  We cannot remove this but only
 	 * make sure we will never have a similar implicit default for IPv6 or
 	 * any other address familiy.  We need a fallback though for
 	 * ifconfig IF up/down etc. to work without INET support as people
 	 * never used ifconfig IF link up/down, etc. either.
 	 */
 #ifndef RESCUE
 #ifdef INET
 	if (afp == NULL && feature_present("inet"))
 		afp = af_getbyname("inet");
 #endif
 #endif
 	if (afp == NULL)
 		afp = af_getbyname("link");
 	if (afp == NULL) {
 		warnx("Please specify an address_family.");
 		usage();
 	}
 top:
 	ifr.ifr_addr.sa_family =
 		afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ?
 		AF_LOCAL : afp->af_af;
 
 	if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 &&
 	    (uafp != NULL || errno != EAFNOSUPPORT ||
 	     (s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0))
 		err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family);
 
 	while (argc > 0) {
 		p = cmd_lookup(*argv, iscreate);
 		if (iscreate && p == NULL) {
 			/*
 			 * Push the clone create callback so the new
 			 * device is created and can be used for any
 			 * remaining arguments.
 			 */
 			cb = callbacks;
 			if (cb == NULL)
 				errx(1, "internal error, no callback");
 			callbacks = cb->cb_next;
 			cb->cb_func(s, cb->cb_arg);
 			iscreate = 0;
 			/*
 			 * Handle any address family spec that
 			 * immediately follows and potentially
 			 * recreate the socket.
 			 */
 			nafp = af_getbyname(*argv);
 			if (nafp != NULL) {
 				argc--, argv++;
 				if (nafp != afp) {
 					close(s);
 					afp = nafp;
 					goto top;
 				}
 			}
 			/*
 			 * Look for a normal parameter.
 			 */
 			continue;
 		}
 		if (p == NULL) {
 			/*
 			 * Not a recognized command, choose between setting
 			 * the interface address and the dst address.
 			 */
 			p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd);
 		}
 		if (p->c_parameter == NEXTARG && p->c_u.c_func) {
 			if (argv[1] == NULL)
 				errx(1, "'%s' requires argument",
 				    p->c_name);
 			p->c_u.c_func(argv[1], 0, s, afp);
 			argc--, argv++;
 		} else if (p->c_parameter == OPTARG && p->c_u.c_func) {
 			p->c_u.c_func(argv[1], 0, s, afp);
 			if (argv[1] != NULL)
 				argc--, argv++;
 		} else if (p->c_parameter == NEXTARG2 && p->c_u.c_func2) {
 			if (argc < 3)
 				errx(1, "'%s' requires 2 arguments",
 				    p->c_name);
 			p->c_u.c_func2(argv[1], argv[2], s, afp);
 			argc -= 2, argv += 2;
 		} else if (p->c_parameter == SPARAM && p->c_u.c_func3) {
 			p->c_u.c_func3(*argv, p->c_sparameter, s, afp);
 		} else if (p->c_u.c_func)
 			p->c_u.c_func(*argv, p->c_parameter, s, afp);
 		argc--, argv++;
 	}
 
 	/*
 	 * Do any post argument processing required by the address family.
 	 */
 	if (afp->af_postproc != NULL)
 		afp->af_postproc(s, afp, newaddr, getifflags(name, s, true));
 	/*
 	 * Do deferred callbacks registered while processing
 	 * command-line arguments.
 	 */
 	for (cb = callbacks; cb != NULL; cb = cb->cb_next)
 		cb->cb_func(s, cb->cb_arg);
 	/*
 	 * Do deferred operations.
 	 */
 	if (clearaddr)
 		delifaddr(s, afp);
 	if (newaddr)
 		addifaddr(s, afp);
 
 	close(s);
 	return(0);
 }
 
 /*ARGSUSED*/
 static void
 setifaddr(const char *addr, int param, int s, const struct afswtch *afp)
 {
 	if (afp->af_getaddr == NULL)
 		return;
 	/*
 	 * Delay the ioctl to set the interface addr until flags are all set.
 	 * The address interpretation may depend on the flags,
 	 * and the flags may change when the address is set.
 	 */
 	setaddr++;
 	if (doalias == 0 && afp->af_af != AF_LINK)
 		clearaddr = 1;
 	afp->af_getaddr(addr, (doalias >= 0 ? ADDR : RIDADDR));
 }
 
 static void
 settunnel(const char *src, const char *dst, int s, const struct afswtch *afp)
 {
 	struct addrinfo *srcres, *dstres;
 	int ecode;
 
 	if (afp->af_settunnel == NULL) {
 		warn("address family %s does not support tunnel setup",
 			afp->af_name);
 		return;
 	}
 
 	if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0)
 		errx(1, "error in parsing address string: %s",
 		    gai_strerror(ecode));
 
 	if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0)
 		errx(1, "error in parsing address string: %s",
 		    gai_strerror(ecode));
 
 	if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family)
 		errx(1,
 		    "source and destination address families do not match");
 
 	afp->af_settunnel(s, srcres, dstres);
 
 	freeaddrinfo(srcres);
 	freeaddrinfo(dstres);
 }
 
 /* ARGSUSED */
 static void
 deletetunnel(const char *vname, int param, int s, const struct afswtch *afp)
 {
 
 	if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0)
 		err(1, "SIOCDIFPHYADDR");
 }
 
 #ifdef JAIL
 static void
 setifvnet(const char *jname, int dummy __unused, int s,
     const struct afswtch *afp)
 {
 	struct ifreq my_ifr;
 
 	memcpy(&my_ifr, &ifr, sizeof(my_ifr));
 	my_ifr.ifr_jid = jail_getid(jname);
 	if (my_ifr.ifr_jid < 0)
 		errx(1, "%s", jail_errmsg);
 	if (ioctl(s, SIOCSIFVNET, &my_ifr) < 0)
 		err(1, "SIOCSIFVNET");
 }
 
 static void
 setifrvnet(const char *jname, int dummy __unused, int s,
     const struct afswtch *afp)
 {
 	struct ifreq my_ifr;
 
 	memcpy(&my_ifr, &ifr, sizeof(my_ifr));
 	my_ifr.ifr_jid = jail_getid(jname);
 	if (my_ifr.ifr_jid < 0)
 		errx(1, "%s", jail_errmsg);
 	if (ioctl(s, SIOCSIFRVNET, &my_ifr) < 0)
 		err(1, "SIOCSIFRVNET(%d, %s)", my_ifr.ifr_jid, my_ifr.ifr_name);
 }
 #endif
 
 static void
 setifnetmask(const char *addr, int dummy __unused, int s,
     const struct afswtch *afp)
 {
 	if (afp->af_getaddr != NULL) {
 		setmask++;
 		afp->af_getaddr(addr, MASK);
 	}
 }
 
 static void
 setifbroadaddr(const char *addr, int dummy __unused, int s,
     const struct afswtch *afp)
 {
 	if (afp->af_getaddr != NULL)
 		afp->af_getaddr(addr, DSTADDR);
 }
 
 static void
 notealias(const char *addr, int param, int s, const struct afswtch *afp)
 {
 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
 	if (setaddr && doalias == 0 && param < 0)
 		if (afp->af_addreq != NULL && afp->af_ridreq != NULL)
 			bcopy((caddr_t)rqtosa(af_addreq),
 			      (caddr_t)rqtosa(af_ridreq),
 			      rqtosa(af_addreq)->sa_len);
 	doalias = param;
 	if (param < 0) {
 		clearaddr = 1;
 		newaddr = 0;
 	} else
 		clearaddr = 0;
 #undef rqtosa
 }
 
 /*ARGSUSED*/
 static void
 setifdstaddr(const char *addr, int param __unused, int s, 
     const struct afswtch *afp)
 {
 	if (afp->af_getaddr != NULL)
 		afp->af_getaddr(addr, DSTADDR);
 }
 
 static int
 getifflags(const char *ifname, int us, bool err_ok)
 {
 	struct ifreq my_ifr;
 	int s;
 	
 	memset(&my_ifr, 0, sizeof(my_ifr));
 	(void) strlcpy(my_ifr.ifr_name, ifname, sizeof(my_ifr.ifr_name));
 	if (us < 0) {
 		if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)
 			err(1, "socket(family AF_LOCAL,SOCK_DGRAM");
 	} else
 		s = us;
  	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) {
 		if (!err_ok) {
 			Perror("ioctl (SIOCGIFFLAGS)");
 			exit(1);
 		}
  	}
 	if (us < 0)
 		close(s);
 	return ((my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16));
 }
 
 /*
  * Note: doing an SIOCIGIFFLAGS scribbles on the union portion
  * of the ifreq structure, which may confuse other parts of ifconfig.
  * Make a private copy so we can avoid that.
  */
 static void
 setifflags(const char *vname, int value, int s, const struct afswtch *afp)
 {
 	struct ifreq		my_ifr;
 	int flags;
 
 	flags = getifflags(name, s, false);
 	if (value < 0) {
 		value = -value;
 		flags &= ~value;
 	} else
 		flags |= value;
 	memset(&my_ifr, 0, sizeof(my_ifr));
 	(void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name));
 	my_ifr.ifr_flags = flags & 0xffff;
 	my_ifr.ifr_flagshigh = flags >> 16;
 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0)
 		Perror(vname);
 }
 
 void
 setifcap(const char *vname, int value, int s, const struct afswtch *afp)
 {
 	int flags;
 
  	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0) {
  		Perror("ioctl (SIOCGIFCAP)");
  		exit(1);
  	}
 	flags = ifr.ifr_curcap;
 	if (value < 0) {
 		value = -value;
 		flags &= ~value;
 	} else
 		flags |= value;
 	flags &= ifr.ifr_reqcap;
 	/* Check for no change in capabilities. */
 	if (ifr.ifr_curcap == flags)
 		return;
 	ifr.ifr_reqcap = flags;
 	if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0)
 		Perror(vname);
 }
 
 void
 setifcapnv(const char *vname, const char *arg, int s, const struct afswtch *afp)
 {
 	nvlist_t *nvcap;
 	void *buf;
 	char *marg, *mopt;
 	size_t nvbuflen;
 	bool neg;
 
 	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0)
 		Perror("ioctl (SIOCGIFCAP)");
 	if ((ifr.ifr_curcap & IFCAP_NV) == 0) {
 		warnx("IFCAP_NV not supported");
 		return; /* Not exit() */
 	}
 
 	marg = strdup(arg);
 	if (marg == NULL)
 		Perror("strdup");
 	nvcap = nvlist_create(0);
 	if (nvcap == NULL)
 		Perror("nvlist_create");
 	while ((mopt = strsep(&marg, ",")) != NULL) {
 		neg = *mopt == '-';
 		if (neg)
 			mopt++;
 		if (strcmp(mopt, "rxtls") == 0) {
 			nvlist_add_bool(nvcap, "rxtls4", !neg);
 			nvlist_add_bool(nvcap, "rxtls6", !neg);
 		} else {
 			nvlist_add_bool(nvcap, mopt, !neg);
 		}
 	}
 	buf = nvlist_pack(nvcap, &nvbuflen);
 	if (buf == NULL) {
 		errx(1, "nvlist_pack error");
 		exit(1);
 	}
 	ifr.ifr_cap_nv.buf_length = ifr.ifr_cap_nv.length = nvbuflen;
 	ifr.ifr_cap_nv.buffer = buf;
 	if (ioctl(s, SIOCSIFCAPNV, (caddr_t)&ifr) < 0)
 		Perror(vname);
 	free(buf);
 	nvlist_destroy(nvcap);
 	free(marg);
 }
 
 static void
 setifmetric(const char *val, int dummy __unused, int s, 
     const struct afswtch *afp)
 {
 	strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
 	ifr.ifr_metric = atoi(val);
 	if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
 		err(1, "ioctl SIOCSIFMETRIC (set metric)");
 }
 
 static void
 setifmtu(const char *val, int dummy __unused, int s, 
     const struct afswtch *afp)
 {
 	strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
 	ifr.ifr_mtu = atoi(val);
 	if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0)
 		err(1, "ioctl SIOCSIFMTU (set mtu)");
 }
 
 static void
 setifpcp(const char *val, int arg __unused, int s, const struct afswtch *afp)
 {
 	u_long ul;
 	char *endp;
 
 	ul = strtoul(val, &endp, 0);
 	if (*endp != '\0')
 		errx(1, "invalid value for pcp");
 	if (ul > 7)
 		errx(1, "value for pcp out of range");
 	ifr.ifr_lan_pcp = ul;
 	if (ioctl(s, SIOCSLANPCP, (caddr_t)&ifr) == -1)
 		err(1, "SIOCSLANPCP");
 }
 
 static void
 disableifpcp(const char *val, int arg __unused, int s,
     const struct afswtch *afp)
 {
 
 	ifr.ifr_lan_pcp = IFNET_PCP_NONE;
 	if (ioctl(s, SIOCSLANPCP, (caddr_t)&ifr) == -1)
 		err(1, "SIOCSLANPCP");
 }
 
 static void
 setifname(const char *val, int dummy __unused, int s, 
     const struct afswtch *afp)
 {
 	char *newname;
 	
 	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 
 	newname = strdup(val);
 	if (newname == NULL)
 		err(1, "no memory to set ifname");
 	ifr.ifr_data = newname;
 	if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) {
 		free(newname);
 		err(1, "ioctl SIOCSIFNAME (set name)");
 	}
 	printifname = 1;
 	strlcpy(name, newname, sizeof(name));
 	free(newname);
 }
 
 /* ARGSUSED */
 static void
 setifdescr(const char *val, int dummy __unused, int s, 
     const struct afswtch *afp)
 {
 	char *newdescr;
 
 	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 	
 	ifr.ifr_buffer.length = strlen(val) + 1;
 	if (ifr.ifr_buffer.length == 1) {
 		ifr.ifr_buffer.buffer = newdescr = NULL;
 		ifr.ifr_buffer.length = 0;
 	} else {
 		newdescr = strdup(val);
 		ifr.ifr_buffer.buffer = newdescr;
 		if (newdescr == NULL) {
 			warn("no memory to set ifdescr");
 			return;
 		}
 	}
 
 	if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0)
 		err(1, "ioctl SIOCSIFDESCR (set descr)");
 
 	free(newdescr);
 }
 
 /* ARGSUSED */
 static void
 unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
 {
 
 	setifdescr("", 0, s, 0);
 }
 
 #define	IFFBITS \
 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \
 "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
 "\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP\25STICKYARP"
 
 #define	IFCAPBITS \
 "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
 "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \
 "\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \
 "\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP\33NOMAP\34TXTLS4\35TXTLS6" \
 "\36VXLAN_HWCSUM\37VXLAN_HWTSO\40TXTLS_RTLMT"
 
 static void
 print_ifcap_nv(struct ifconfig_args *args, int s)
 {
 	nvlist_t *nvcap;
 	const char *nvname;
 	void *buf, *cookie;
 	bool first, val;
 	int type;
 
 	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);
 
 	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0)
 		Perror("ioctl (SIOCGIFCAP)");
 }
 
 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');
 		}
 	}
 }
 
 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);
 }
 
 void
 print_metric(int s)
 {
 	if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1)
 		printf(" metric %d", ifr.ifr_metric);
 }
 
 #ifdef WITHOUT_NETLINK
 static void
 print_mtu(int s)
 {
 	if (ioctl(s, SIOCGIFMTU, &ifr) != -1)
 		printf(" mtu %d", ifr.ifr_mtu);
 }
 
 static void
 print_description(int s)
 {
 	for (;;) {
 		if ((descr = reallocf(descr, descrlen)) != NULL) {
 			ifr.ifr_buffer.buffer = descr;
 			ifr.ifr_buffer.length = descrlen;
 			if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
 				if (ifr.ifr_buffer.buffer == descr) {
 					if (strlen(descr) > 0)
 						printf("\tdescription: %s\n",
 						    descr);
 				} else if (ifr.ifr_buffer.length > descrlen) {
 					descrlen = ifr.ifr_buffer.length;
 					continue;
 				}
 			}
 		} else
 			warn("unable to allocate memory for interface"
 			    "description");
 		break;
 	}
 }
 
 /*
  * 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 (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);
 
 	for (ift = ifa; ift != NULL; ift = ift->ifa_next) {
 		if (ift->ifa_addr == NULL)
 			continue;
 		if (strcmp(ifa->ifa_name, ift->ifa_name) != 0)
 			continue;
 		if (allfamilies) {
 			const struct afswtch *p;
 			p = af_getbyfamily(ift->ifa_addr->sa_family);
 			if (p != NULL && p->af_status != NULL)
 				p->af_status(s, ift);
 		} else if (args->afp->af_af == ift->ifa_addr->sa_family)
 			args->afp->af_status(s, ift);
 	}
 #if 0
 	if (allfamilies || afp->af_af == AF_LINK) {
 		const struct afswtch *lafp;
 
 		/*
 		 * Hack; the link level address is received separately
 		 * from the routing information so any address is not
 		 * handled above.  Cobble together an entry and invoke
 		 * the status method specially.
 		 */
 		lafp = af_getbyname("lladdr");
 		if (lafp != NULL) {
 			info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl;
 			lafp->af_status(s, &info);
 		}
 	}
 #endif
 	if (allfamilies)
 		af_other_status(s);
 	else if (args->afp->af_other_status != NULL)
 		args->afp->af_other_status(s);
 
 	print_ifstatus(s);
 	if (args->verbose > 0)
 		sfp_status(s, &ifr, args->verbose);
 
 	close(s);
 	return;
 }
 #endif
 
 void
 tunnel_status(int s)
 {
 	af_all_tunnel_status(s);
 }
 
 void
 Perror(const char *cmd)
 {
 	switch (errno) {
 
 	case ENXIO:
 		errx(1, "%s: no such interface", cmd);
 		break;
 
 	case EPERM:
 		errx(1, "%s: permission denied", cmd);
 		break;
 
 	default:
 		err(1, "%s", cmd);
 	}
 }
 
 /*
  * Print a value a la the %b format of the kernel's printf
  */
 void
 printb(const char *s, unsigned v, const char *bits)
 {
 	int i, any = 0;
 	char c;
 
 	if (bits && *bits == 8)
 		printf("%s=%o", s, v);
 	else
 		printf("%s=%x", s, v);
 	if (bits) {
 		bits++;
 		putchar('<');
 		while ((i = *bits++) != '\0') {
 			if (v & (1u << (i-1))) {
 				if (any)
 					putchar(',');
 				any = 1;
 				for (; (c = *bits) > 32; bits++)
 					putchar(c);
 			} else
 				for (; *bits > 32; bits++)
 					;
 		}
 		putchar('>');
 	}
 }
 
 void
 print_vhid(const struct ifaddrs *ifa, const char *s)
 {
 	struct if_data *ifd;
 
 	if (ifa->ifa_data == NULL)
 		return;
 
 	ifd = ifa->ifa_data;
 	if (ifd->ifi_vhid == 0)
 		return;
 	
 	printf(" vhid %d", ifd->ifi_vhid);
 }
 
 void
 ifmaybeload(struct ifconfig_args *args, const char *name)
 {
 #define MOD_PREFIX_LEN		3	/* "if_" */
 	struct module_stat mstat;
-	int i, fileid, modid;
+	int fileid, modid;
 	char ifkind[IFNAMSIZ + MOD_PREFIX_LEN], ifname[IFNAMSIZ], *dp;
 	const char *cp;
 	struct module_map_entry *mme;
 	bool found;
 
 	/* loading suppressed by the user */
 	if (args->noload)
 		return;
 
 	/* trim the interface number off the end */
 	strlcpy(ifname, name, sizeof(ifname));
 	dp = ifname + strlen(ifname) - 1;
 	for (; dp > ifname; dp--) {
 		if (isdigit(*dp))
 			*dp = '\0';
 		else
 			break;
 	}
 
 	/* Either derive it from the map or guess otherwise */
 	*ifkind = '\0';
 	found = false;
-	for (i = 0; i < nitems(module_map); ++i) {
+	for (unsigned i = 0; i < nitems(module_map); ++i) {
 		mme = &module_map[i];
 		if (strcmp(mme->ifname, ifname) == 0) {
 			strlcpy(ifkind, mme->kldname, sizeof(ifkind));
 			found = true;
 			break;
 		}
 	}
 
 	/* We didn't have an alias for it... we'll guess. */
 	if (!found) {
 	    /* turn interface and unit into module name */
 	    strlcpy(ifkind, "if_", sizeof(ifkind));
 	    strlcat(ifkind, ifname, sizeof(ifkind));
 	}
 
 	/* scan files in kernel */
 	mstat.version = sizeof(struct module_stat);
 	for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
 		/* scan modules in file */
 		for (modid = kldfirstmod(fileid); modid > 0;
 		     modid = modfnext(modid)) {
 			if (modstat(modid, &mstat) < 0)
 				continue;
 			/* strip bus name if present */
 			if ((cp = strchr(mstat.name, '/')) != NULL) {
 				cp++;
 			} else {
 				cp = mstat.name;
 			}
 			/*
 			 * Is it already loaded?  Don't compare with ifname if
 			 * we were specifically told which kld to use.  Doing
 			 * so could lead to conflicts not trivially solved.
 			 */
 			if ((!found && strcmp(ifname, cp) == 0) ||
 			    strcmp(ifkind, cp) == 0)
 				return;
 		}
 	}
 
 	/*
 	 * Try to load the module.  But ignore failures, because ifconfig can't
 	 * infer the names of all drivers (eg mlx4en(4)).
 	 */
 	(void) kldload(ifkind);
 }
 
 static struct cmd basic_cmds[] = {
 	DEF_CMD("up",		IFF_UP,		setifflags),
 	DEF_CMD("down",		-IFF_UP,	setifflags),
 	DEF_CMD("arp",		-IFF_NOARP,	setifflags),
 	DEF_CMD("-arp",		IFF_NOARP,	setifflags),
 	DEF_CMD("debug",	IFF_DEBUG,	setifflags),
 	DEF_CMD("-debug",	-IFF_DEBUG,	setifflags),
 	DEF_CMD_ARG("description",		setifdescr),
 	DEF_CMD_ARG("descr",			setifdescr),
 	DEF_CMD("-description",	0,		unsetifdescr),
 	DEF_CMD("-descr",	0,		unsetifdescr),
 	DEF_CMD("promisc",	IFF_PPROMISC,	setifflags),
 	DEF_CMD("-promisc",	-IFF_PPROMISC,	setifflags),
 	DEF_CMD("add",		IFF_UP,		notealias),
 	DEF_CMD("alias",	IFF_UP,		notealias),
 	DEF_CMD("-alias",	-IFF_UP,	notealias),
 	DEF_CMD("delete",	-IFF_UP,	notealias),
 	DEF_CMD("remove",	-IFF_UP,	notealias),
 #ifdef notdef
 #define	EN_SWABIPS	0x1000
 	DEF_CMD("swabips",	EN_SWABIPS,	setifflags),
 	DEF_CMD("-swabips",	-EN_SWABIPS,	setifflags),
 #endif
 	DEF_CMD_ARG("netmask",			setifnetmask),
 	DEF_CMD_ARG("metric",			setifmetric),
 	DEF_CMD_ARG("broadcast",		setifbroadaddr),
 	DEF_CMD_ARG2("tunnel",			settunnel),
 	DEF_CMD("-tunnel", 0,			deletetunnel),
 	DEF_CMD("deletetunnel", 0,		deletetunnel),
 #ifdef JAIL
 	DEF_CMD_ARG("vnet",			setifvnet),
 	DEF_CMD_ARG("-vnet",			setifrvnet),
 #endif
 	DEF_CMD("link0",	IFF_LINK0,	setifflags),
 	DEF_CMD("-link0",	-IFF_LINK0,	setifflags),
 	DEF_CMD("link1",	IFF_LINK1,	setifflags),
 	DEF_CMD("-link1",	-IFF_LINK1,	setifflags),
 	DEF_CMD("link2",	IFF_LINK2,	setifflags),
 	DEF_CMD("-link2",	-IFF_LINK2,	setifflags),
 	DEF_CMD("monitor",	IFF_MONITOR,	setifflags),
 	DEF_CMD("-monitor",	-IFF_MONITOR,	setifflags),
 	DEF_CMD("mextpg",	IFCAP_MEXTPG,	setifcap),
 	DEF_CMD("-mextpg",	-IFCAP_MEXTPG,	setifcap),
 	DEF_CMD("staticarp",	IFF_STATICARP,	setifflags),
 	DEF_CMD("-staticarp",	-IFF_STATICARP,	setifflags),
 	DEF_CMD("stickyarp",	IFF_STICKYARP,	setifflags),
 	DEF_CMD("-stickyarp",	-IFF_STICKYARP,	setifflags),
 	DEF_CMD("rxcsum6",	IFCAP_RXCSUM_IPV6,	setifcap),
 	DEF_CMD("-rxcsum6",	-IFCAP_RXCSUM_IPV6,	setifcap),
 	DEF_CMD("txcsum6",	IFCAP_TXCSUM_IPV6,	setifcap),
 	DEF_CMD("-txcsum6",	-IFCAP_TXCSUM_IPV6,	setifcap),
 	DEF_CMD("rxcsum",	IFCAP_RXCSUM,	setifcap),
 	DEF_CMD("-rxcsum",	-IFCAP_RXCSUM,	setifcap),
 	DEF_CMD("txcsum",	IFCAP_TXCSUM,	setifcap),
 	DEF_CMD("-txcsum",	-IFCAP_TXCSUM,	setifcap),
 	DEF_CMD("netcons",	IFCAP_NETCONS,	setifcap),
 	DEF_CMD("-netcons",	-IFCAP_NETCONS,	setifcap),
 	DEF_CMD_ARG("pcp",			setifpcp),
 	DEF_CMD("-pcp", 0,			disableifpcp),
 	DEF_CMD("polling",	IFCAP_POLLING,	setifcap),
 	DEF_CMD("-polling",	-IFCAP_POLLING,	setifcap),
 	DEF_CMD("tso6",		IFCAP_TSO6,	setifcap),
 	DEF_CMD("-tso6",	-IFCAP_TSO6,	setifcap),
 	DEF_CMD("tso4",		IFCAP_TSO4,	setifcap),
 	DEF_CMD("-tso4",	-IFCAP_TSO4,	setifcap),
 	DEF_CMD("tso",		IFCAP_TSO,	setifcap),
 	DEF_CMD("-tso",		-IFCAP_TSO,	setifcap),
 	DEF_CMD("toe",		IFCAP_TOE,	setifcap),
 	DEF_CMD("-toe",		-IFCAP_TOE,	setifcap),
 	DEF_CMD("lro",		IFCAP_LRO,	setifcap),
 	DEF_CMD("-lro",		-IFCAP_LRO,	setifcap),
 	DEF_CMD("txtls",	IFCAP_TXTLS,	setifcap),
 	DEF_CMD("-txtls",	-IFCAP_TXTLS,	setifcap),
 	DEF_CMD_SARG("rxtls",	IFCAP2_RXTLS4_NAME "," IFCAP2_RXTLS6_NAME,
 	    setifcapnv),
 	DEF_CMD_SARG("-rxtls",	"-"IFCAP2_RXTLS4_NAME ",-" IFCAP2_RXTLS6_NAME,
 	    setifcapnv),
 	DEF_CMD("wol",		IFCAP_WOL,	setifcap),
 	DEF_CMD("-wol",		-IFCAP_WOL,	setifcap),
 	DEF_CMD("wol_ucast",	IFCAP_WOL_UCAST,	setifcap),
 	DEF_CMD("-wol_ucast",	-IFCAP_WOL_UCAST,	setifcap),
 	DEF_CMD("wol_mcast",	IFCAP_WOL_MCAST,	setifcap),
 	DEF_CMD("-wol_mcast",	-IFCAP_WOL_MCAST,	setifcap),
 	DEF_CMD("wol_magic",	IFCAP_WOL_MAGIC,	setifcap),
 	DEF_CMD("-wol_magic",	-IFCAP_WOL_MAGIC,	setifcap),
 	DEF_CMD("txrtlmt",	IFCAP_TXRTLMT,	setifcap),
 	DEF_CMD("-txrtlmt",	-IFCAP_TXRTLMT,	setifcap),
 	DEF_CMD("txtlsrtlmt",	IFCAP_TXTLS_RTLMT,	setifcap),
 	DEF_CMD("-txtlsrtlmt",	-IFCAP_TXTLS_RTLMT,	setifcap),
 	DEF_CMD("hwrxtstmp",	IFCAP_HWRXTSTMP,	setifcap),
 	DEF_CMD("-hwrxtstmp",	-IFCAP_HWRXTSTMP,	setifcap),
 	DEF_CMD("normal",	-IFF_LINK0,	setifflags),
 	DEF_CMD("compress",	IFF_LINK0,	setifflags),
 	DEF_CMD("noicmp",	IFF_LINK1,	setifflags),
 	DEF_CMD_ARG("mtu",			setifmtu),
 	DEF_CMD_ARG("name",			setifname),
 };
 
 static __constructor void
 ifconfig_ctor(void)
 {
 	size_t i;
 
 	for (i = 0; i < nitems(basic_cmds);  i++)
 		cmd_register(&basic_cmds[i]);
 }
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index 1df94f357c43..1f60164b7075 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -1,283 +1,301 @@
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
  *
  * Copyright (c) 1997 Peter Wemm.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *      This product includes software developed for the FreeBSD Project
  *	by Peter Wemm.
  * 4. The name of the author may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * so there!
  *
  * $FreeBSD$
  */
 
 #pragma once
 
 #include <libifconfig.h>
 #include <stdbool.h>
 
 #define	__constructor	__attribute__((constructor))
 
 struct afswtch;
 struct cmd;
 
 typedef	void c_func(const char *cmd, int arg, int s, const struct afswtch *afp);
 typedef	void c_func2(const char *arg1, const char *arg2, int s,
     const struct afswtch *afp);
 typedef	void c_func3(const char *cmd, const char *arg, int s,
     const struct afswtch *afp);
 
 struct cmd {
 	const char *c_name;
 	int	c_parameter;
 #define	NEXTARG		0xffffff	/* has following arg */
 #define	NEXTARG2	0xfffffe	/* has 2 following args */
 #define	OPTARG		0xfffffd	/* has optional following arg */
 #define	SPARAM		0xfffffc	/* parameter is string c_sparameter */
 	const char *c_sparameter;
 	union {
 		c_func	*c_func;
 		c_func2	*c_func2;
 		c_func3	*c_func3;
 	} c_u;
 	int	c_iscloneop;
 	struct cmd *c_next;
 };
 void	cmd_register(struct cmd *);
 
 typedef	void callback_func(int s, void *);
 void	callback_register(callback_func *, void *);
 
 /*
  * Macros for declaring command functions and initializing entries.
  */
 #define	DECL_CMD_FUNC(name, cmd, arg) \
 	void name(const char *cmd, int arg, int s, const struct afswtch *afp)
 #define	DECL_CMD_FUNC2(name, arg1, arg2) \
 	void name(const char *arg1, const char *arg2, int s, \
 	    const struct afswtch *afp)
 
 #define	DEF_CMD(name, param, func) {		\
     .c_name = (name),				\
     .c_parameter = (param),			\
     .c_u = { .c_func = (func) },		\
     .c_iscloneop = 0,				\
     .c_next = NULL,				\
 }
 #define	DEF_CMD_ARG(name, func) {		\
     .c_name = (name),				\
     .c_parameter = NEXTARG,			\
     .c_u = { .c_func = (func) },		\
     .c_iscloneop = 0,				\
     .c_next = NULL,				\
 }
 #define	DEF_CMD_OPTARG(name, func) {		\
     .c_name = (name),				\
     .c_parameter = OPTARG,			\
     .c_u = { .c_func = (func) },		\
     .c_iscloneop = 0,				\
     .c_next = NULL,				\
 }
 #define	DEF_CMD_ARG2(name, func) {		\
     .c_name = (name),				\
     .c_parameter = NEXTARG2,			\
     .c_u = { .c_func2 = (func) },		\
     .c_iscloneop = 0,				\
     .c_next = NULL,				\
 }
 #define	DEF_CMD_SARG(name, sparam, func) {	\
     .c_name = (name),				\
     .c_parameter = SPARAM,			\
     .c_sparameter = (sparam),			\
     .c_u = { .c_func3 = (func) },		\
     .c_iscloneop = 0,				\
     .c_next = NULL,				\
 }
 #define	DEF_CLONE_CMD(name, param, func) {	\
     .c_name = (name),				\
     .c_parameter = (param),			\
     .c_u = { .c_func = (func) },		\
     .c_iscloneop = 1,				\
     .c_next = NULL,				\
 }
 #define	DEF_CLONE_CMD_ARG(name, func) {		\
     .c_name = (name),				\
     .c_parameter = NEXTARG,			\
     .c_u = { .c_func = (func) },		\
     .c_iscloneop = 1,				\
     .c_next = NULL,				\
 }
 #define	DEF_CLONE_CMD_ARG2(name, func) {	\
     .c_name = (name),				\
     .c_parameter = NEXTARG2,			\
     .c_u = { .c_func2 = (func) },		\
     .c_iscloneop = 1,				\
     .c_next = NULL,				\
 }
 
 struct ifaddrs;
 struct addrinfo;
 
 enum {
 	RIDADDR,
 	ADDR,
 	MASK,
 	DSTADDR,
 };
 
 struct snl_state;
 struct snl_parsed_addr;
 struct snl_parsed_link;
 typedef struct snl_parsed_link if_link_t;
 typedef struct snl_parsed_addr if_addr_t;
 struct ifconfig_args;
 struct io_handler {
 	int			s;	/* socket to use for ioctls */
 	struct snl_state	*ss;	/* NETLINK_ROUTE snl(3) socket */
 };
 
 typedef void af_setvhid_f(int vhid);
 typedef	void af_status_nl_f(struct ifconfig_args *args, struct io_handler *h,
     if_link_t *link, if_addr_t *ifa);
 
 struct afswtch {
 	const char	*af_name;	/* as given on cmd line, e.g. "inet" */
 	short		af_af;		/* AF_* */
 	/*
 	 * Status is handled one of two ways; if there is an
 	 * address associated with the interface then the
 	 * associated address family af_status method is invoked
 	 * with the appropriate addressin info.  Otherwise, if
 	 * all possible info is to be displayed and af_other_status
 	 * is defined then it is invoked after all address status
 	 * is presented.
 	 */
 #ifndef WITHOUT_NETLINK
 	af_status_nl_f	*af_status_nl;
 #else
 	void		(*af_status)(int, const struct ifaddrs *);
 #endif
 	void		(*af_other_status)(int);
 					/* parse address method */
 	void		(*af_getaddr)(const char *, int);
 					/* parse prefix method (IPv6) */
 	void		(*af_getprefix)(const char *, int);
 	void		(*af_postproc)(int s, const struct afswtch *,
 			    int newaddr, int ifflags);
 	af_setvhid_f	*af_setvhid;	/* Set CARP vhid for an address */
 	u_long		af_difaddr;	/* set dst if address ioctl */
 	u_long		af_aifaddr;	/* set if address ioctl */
 	void		*af_ridreq;	/* */
 	void		*af_addreq;	/* */
 	struct afswtch	*af_next;
 
 	/* XXX doesn't fit model */
 	void		(*af_status_tunnel)(int);
 	void		(*af_settunnel)(int s, struct addrinfo *srcres,
 				struct addrinfo *dstres);
 };
 void	af_register(struct afswtch *);
 
 struct ifconfig_args {
 	bool all;		/* Match everything */
 	bool downonly;		/* Down-only items */
 	bool uponly;		/* Up-only items */
 	bool namesonly;		/* Output only names */
 	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;
 	const char *ifname;	/* Requested interface name */
 	const char *matchgroup;		/* Group name to match */
 	const char *nogroup;		/* Group name to exclude */
 	const struct afswtch *afp;	/* AF we're operating on */
 	const char *jail_name;	/* Jail name or jail id specified */
 };
 
 struct option {
 	const char *opt;
 	const char *opt_usage;
 	void	(*cb)(const char *arg);
 	struct option *next;
 };
 void	opt_register(struct option *);
 
 extern	ifconfig_handle_t *lifh;
 extern	struct ifreq ifr;
 extern	char name[IFNAMSIZ];	/* name of interface */
 extern	int allmedia;
 extern	int printkeys;
 extern	int newaddr;
 extern	int verbose;
 extern	int printifname;
 extern	int exit_code;
 extern struct ifconfig_args args;
+extern	char *f_inet, *f_inet6, *f_ether, *f_addr;
 
 void	setifcap(const char *, int value, int s, const struct afswtch *);
 void	setifcapnv(const char *vname, const char *arg, int s,
 	    const struct afswtch *afp);
 
 void	Perror(const char *cmd);
 void	printb(const char *s, unsigned value, const char *bits);
 
 void	ifmaybeload(struct ifconfig_args *args, const char *name);
 
 typedef int  clone_match_func(const char *);
 typedef void clone_callback_func(int, struct ifreq *);
 void	clone_setdefcallback_prefix(const char *, clone_callback_func *);
 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);
 bool	match_if_flags(struct ifconfig_args *args, int if_flags);
 int	ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp);
 bool	group_member(const char *ifname, const char *match, const char *nomatch);
 void	print_ifcap(struct ifconfig_args *args, int s);
 void	tunnel_status(int s);
 struct afswtch	*af_getbyfamily(int af);
 void	af_other_status(int s);
 void	print_ifstatus(int s);
 void	print_metric(int s);
 
 /* Netlink-related functions */
 void	list_interfaces_nl(struct ifconfig_args *args);
 
 /*
  * XXX expose this so modules that neeed to know of any pending
  * operations on ifmedia can avoid cmd line ordering confusion.
  */
 struct ifmediareq *ifmedia_getstate(void);
 
 void print_vhid(const struct ifaddrs *, const char *);
 
 void ioctl_ifcreate(int s, struct ifreq *);
+
+/* Helpers */
+struct sockaddr_in;
+struct sockaddr_in6;
+struct sockaddr;
+
+static inline struct sockaddr_in6 *
+satosin6(struct sockaddr *sa)
+{
+	return ((struct sockaddr_in6 *)(void *)sa);
+}
+
+static inline struct sockaddr_in *
+satosin(struct sockaddr *sa)
+{
+	return ((struct sockaddr_in *)(void *)sa);
+}
diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c
index 26a42b5866c5..96f945de65b1 100644
--- a/sbin/ifconfig/ifconfig_netlink.c
+++ b/sbin/ifconfig/ifconfig_netlink.c
@@ -1,427 +1,428 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
  * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdbool.h>
 #include <err.h>
 #include <errno.h>
 #include <netdb.h>
 
 #include <sys/bitcount.h>
 #include <sys/param.h>
 #include <sys/linker.h>
 #include <sys/module.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include "ifconfig.h"
 #include "ifconfig_netlink.h"
 
 static const char	*IFFBITS[] = {
 	"UP",			/* 00:0x1 IFF_UP*/
 	"BROADCAST",		/* 01:0x2 IFF_BROADCAST*/
 	"DEBUG",		/* 02:0x4 IFF_DEBUG*/
 	"LOOPBACK",		/* 03:0x8 IFF_LOOPBACK*/
 	"POINTOPOINT",		/* 04:0x10 IFF_POINTOPOINT*/
 	"NEEDSEPOCH",		/* 05:0x20 IFF_NEEDSEPOCH*/
 	"RUNNING",		/* 06:0x40 IFF_DRV_RUNNING*/
 	"NOARP",		/* 07:0x80 IFF_NOARP*/
 	"PROMISC",		/* 08:0x100 IFF_PROMISC*/
 	"ALLMULTI",		/* 09:0x200 IFF_ALLMULTI*/
 	"DRV_OACTIVE",		/* 10:0x400 IFF_DRV_OACTIVE*/
 	"SIMPLEX",		/* 11:0x800 IFF_SIMPLEX*/
 	"LINK0",		/* 12:0x1000 IFF_LINK0*/
 	"LINK1",		/* 13:0x2000 IFF_LINK1*/
 	"LINK2",		/* 14:0x4000 IFF_LINK2*/
 	"MULTICAST",		/* 15:0x8000 IFF_MULTICAST*/
 	"CANTCONFIG",		/* 16:0x10000 IFF_CANTCONFIG*/
 	"PPROMISC",		/* 17:0x20000 IFF_PPROMISC*/
 	"MONITOR",		/* 18:0x40000 IFF_MONITOR*/
 	"STATICARP",		/* 19:0x80000 IFF_STATICARP*/
 	"STICKYARP",		/* 20:0x100000 IFF_STICKYARP*/
 	"DYING",		/* 21:0x200000 IFF_DYING*/
 	"RENAMING",		/* 22:0x400000 IFF_RENAMING*/
 	"NOGROUP",		/* 23:0x800000 IFF_NOGROUP*/
 	"LOWER_UP",		/* 24:0x1000000 IFF_NETLINK_1*/
 };
 
 static void
 print_bits(const char *btype, uint32_t *v, const int v_count,
     const char **names, const int n_count)
 {
 	int num = 0;
 
 	for (int i = 0; i < v_count * 32; i++) {
 		bool is_set = v[i / 32] & (1 << (i % 32));
 		if (i == 31)
 			v++;
 		if (is_set) {
 			if (num++ == 0)
 				printf("<");
 			if (num != 1)
 				printf(",");
 			if (i < n_count)
 				printf("%s", names[i]);
 			else
 				printf("%s_%d", btype, i);
 		}
 	}
 	if (num > 0)
 		printf(">");
 }	
 
 static void
 nl_init_socket(struct snl_state *ss)
 {
 	if (snl_init(ss, NETLINK_ROUTE))
 		return;
 
 	if (modfind("netlink") == -1 && errno == ENOENT) {
 		/* Try to load */
 		if (kldload("netlink") == -1)
 			err(1, "netlink is not loaded and load attempt failed");
 		if (snl_init(ss, NETLINK_ROUTE))
 			return;
 	}
 
 	err(1, "unable to open netlink socket");
 }
 
 struct ifa {
 	struct ifa		*next;
 	uint32_t		count;
 	uint32_t		idx;
 	struct snl_parsed_addr	addr;
 };
 
 struct iface {
 	struct snl_parsed_link	link;
 	struct ifa		*ifa;
 	uint32_t		ifa_count;
 	uint32_t		idx;
 };
 
 struct ifmap {
 	uint32_t		size;
 	uint32_t		count;
 	struct iface		**ifaces;
 };
 
 /*
  * Returns ifmap ifindex->snl_parsed_link.
  * Memory is allocated using snl temporary buffers
  */
 static struct ifmap *
 prepare_ifmap(struct snl_state *ss)
 {
 	struct snl_writer nw = {};
 
 	snl_init_writer(ss, &nw);
 	struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETLINK);
 	hdr->nlmsg_flags |= NLM_F_DUMP;
 	snl_reserve_msg_object(&nw, struct ifinfomsg);
 
 	if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr))
 		return (NULL);
 
 	uint32_t nlmsg_seq = hdr->nlmsg_seq;
 	struct ifmap *ifmap = snl_allocz(ss, sizeof(*ifmap));
 	struct snl_errmsg_data e = {};
 
 	while ((hdr = snl_read_reply_multi(ss, nlmsg_seq, &e)) != NULL) {
 		struct iface *iface = snl_allocz(ss, sizeof(*iface));
 
 		if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_link_parser, &iface->link))
 			continue;
 		if (iface->link.ifi_index >= ifmap->size) {
 			size_t new_size = MAX(ifmap->size, 32);
 
 			while (new_size <= iface->link.ifi_index + 1)
 				new_size *= 2;
 
 			struct iface **ifaces= snl_allocz(ss, new_size * sizeof(void *));
 			memcpy(ifaces, ifmap->ifaces, ifmap->size * sizeof(void *));
 			ifmap->ifaces = ifaces;
 			ifmap->size = new_size;
 		}
 		ifmap->ifaces[iface->link.ifi_index] = iface;
 		ifmap->count++;
 		iface->idx = ifmap->count;
 	}
 	return (ifmap);
 }
 
 static void
 prepare_ifaddrs(struct snl_state *ss, struct ifmap *ifmap)
 {
 	struct snl_writer nw = {};
 
 	snl_init_writer(ss, &nw);
 	struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETADDR);
 	hdr->nlmsg_flags |= NLM_F_DUMP;
 	snl_reserve_msg_object(&nw, struct ifaddrmsg);
 
 	if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr))
 		return;
 
 	uint32_t nlmsg_seq = hdr->nlmsg_seq;
 	struct snl_errmsg_data e = {};
 	uint32_t count = 0;
 
 	while ((hdr = snl_read_reply_multi(ss, nlmsg_seq, &e)) != NULL) {
 		struct ifa *ifa = snl_allocz(ss, sizeof(*ifa));
 
 		if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_addr_parser, &ifa->addr))
 			continue;
 
 		const uint32_t ifindex = ifa->addr.ifa_index;
 		if (ifindex >= ifmap->size || ifmap->ifaces[ifindex] == NULL)
 			continue;
 		struct iface *iface = ifmap->ifaces[ifindex];
 		ifa->next = iface->ifa;
 		ifa->count = ++count;
 		iface->ifa = ifa;
 		iface->ifa_count++;
 	}
 }
 
 static bool
 match_iface(struct ifconfig_args *args, struct iface *iface)
 {
 	if_link_t *link = &iface->link;
 
 	if (args->ifname != NULL && strcmp(args->ifname, link->ifla_ifname))
 		return (false);
 
 	if (!match_if_flags(args, link->ifi_flags))
 		return (false);
 
 	if (!group_member(link->ifla_ifname, args->matchgroup, args->nogroup))
 		return (false);
 
 	if (args->afp == NULL)
 		return (true);
 
 	if (!strcmp(args->afp->af_name, "ether")) {
 		if (link->ifla_address == NULL)
 			return (false);
 
 		struct sockaddr_dl sdl = {
 			.sdl_len = sizeof(struct sockaddr_dl),
 			.sdl_family = AF_LINK,
 			.sdl_type = link->ifi_type,
 			.sdl_alen = NLA_DATA_LEN(link->ifla_address),
 		};
 		return (match_ether(&sdl));
 	}
 	
 	for (struct ifa *ifa = iface->ifa; ifa != NULL; ifa = ifa->next) {
 		if (args->afp->af_af == ifa->addr.ifa_family)
 			return (true);
 	}
 
 	return (false);
 }
 
 /* Sort according to the kernel-provided order */
 static int
 cmp_iface(const void *_a, const void *_b)
 {
 	const struct iface *a = *((const void * const *)_a);
 	const struct iface *b = *((const void * const *)_b);
 
 	return ((a->idx > b->idx) * 2 - 1);
 }
 
 static int
 cmp_ifaddr(const void *_a, const void *_b)
 {
 	const struct ifa *a = *((const void * const *)_a);
 	const struct ifa *b = *((const void * const *)_b);
 
 	if (a->addr.ifa_family != b->addr.ifa_family)
 		return ((a->addr.ifa_family > b->addr.ifa_family) * 2 - 1);
 	return ((a->idx > b->idx) * 2 - 1);
 }
 
 static void
 sort_iface_ifaddrs(struct snl_state *ss, struct iface *iface)
 {
 	if (iface->ifa_count == 0)
 		return;
 
 	struct ifa **sorted_ifaddrs = snl_allocz(ss, iface->ifa_count * sizeof(void *));
 	struct ifa *ifa = iface->ifa;
 
-	for (int i = 0; i < iface->ifa_count; i++) {
+	for (uint32_t i = 0; i < iface->ifa_count; i++) {
 		struct ifa *ifa_next = ifa->next;
 
 		sorted_ifaddrs[i] = ifa;
 		ifa->next = NULL;
 		ifa = ifa_next;
 	}
 	qsort(sorted_ifaddrs, iface->ifa_count, sizeof(void *), cmp_ifaddr);
 	ifa = sorted_ifaddrs[0];
 	iface->ifa = ifa;
-	for (int i = 1; i < iface->ifa_count; i++) {
+	for (uint32_t i = 1; i < iface->ifa_count; i++) {
 		ifa->next = sorted_ifaddrs[i];
 		ifa = sorted_ifaddrs[i];
 	}
 }
 
 static void
 status_nl(struct ifconfig_args *args, struct io_handler *h, struct iface *iface)
 {
 	if_link_t *link = &iface->link;
 
 	printf("%s: ", link->ifla_ifname);
 
 	printf("flags=%x", link->ifi_flags);
 	print_bits("IFF", &link->ifi_flags, 1, IFFBITS, nitems(IFFBITS));
 
 	print_metric(h->s);
 	printf(" mtu %d\n", link->ifla_mtu);
 
 	if (link->ifla_ifalias != NULL)
 		printf("\tdescription: %s\n", link->ifla_ifalias);
 
 	/* TODO: convert to netlink */
 	strlcpy(ifr.ifr_name, link->ifla_ifname, sizeof(ifr.ifr_name));
 	print_ifcap(args, h->s);
 	tunnel_status(h->s);
 
 	if (args->allfamilies | (args->afp != NULL && args->afp->af_af == AF_LINK)) {
 		/* Start with link-level */
 		const struct afswtch *p = af_getbyfamily(AF_LINK);
 		if (p != NULL && link->ifla_address != NULL)
 			p->af_status_nl(args, h, link, NULL);
 	}
 
 	sort_iface_ifaddrs(h->ss, iface);
 
 	for (struct ifa *ifa = iface->ifa; ifa != NULL; ifa = ifa->next) {
 		if (args->allfamilies) {
 			const struct afswtch *p = af_getbyfamily(ifa->addr.ifa_family);
 
 			if (p != NULL)
 				p->af_status_nl(args, h, link, &ifa->addr);
 		} else if (args->afp->af_af == ifa->addr.ifa_family) {
 			const struct afswtch *p = args->afp;
 
 			p->af_status_nl(args, h, link, &ifa->addr);
 		}
 	}
 
 	/* TODO: convert to netlink */
 	if (args->allfamilies)
 		af_other_status(h->s);
 	else if (args->afp->af_other_status != NULL)
 		args->afp->af_other_status(h->s);
 
 	print_ifstatus(h->s);
 	if (args->verbose > 0)
 		sfp_status(h->s, &ifr, args->verbose);
 }
 
 static int
 get_local_socket(void)
 {
 	int s = socket(AF_LOCAL, SOCK_DGRAM, 0);
 	
 	if (s < 0)
 		err(1, "socket(family %u,SOCK_DGRAM)", AF_LOCAL);
 	return (s);
 }
 
 static void
 set_global_ifname(if_link_t *link)
 {
-	int iflen = strlcpy(name, link->ifla_ifname, sizeof(name));
+	size_t iflen = strlcpy(name, link->ifla_ifname, sizeof(name));
+
 	if (iflen >= sizeof(name))
 		errx(1, "%s: cloning name too long", link->ifla_ifname);
 	strlcpy(ifr.ifr_name, link->ifla_ifname, sizeof(ifr.ifr_name));
 }
 
 void
 list_interfaces_nl(struct ifconfig_args *args)
 {
 	struct snl_state ss = {};
 
 	nl_init_socket(&ss);
 
 	struct ifmap *ifmap = prepare_ifmap(&ss);
 	struct iface **sorted_ifaces = snl_allocz(&ss, ifmap->count * sizeof(void *));
-	for (int i = 0, num = 0; i < ifmap->size; i++) {
+	for (uint32_t i = 0, num = 0; i < ifmap->size; i++) {
 		if (ifmap->ifaces[i] != NULL) {
 			sorted_ifaces[num++] = ifmap->ifaces[i];
 			if (num == ifmap->count)
 				break;
 		}
 	}
 	qsort(sorted_ifaces, ifmap->count, sizeof(void *), cmp_iface);
 	prepare_ifaddrs(&ss, ifmap);
 
 	struct io_handler h = {
 		.s = get_local_socket(),
 		.ss = &ss,
 	};
 
-	for (int i = 0, num = 0; i < ifmap->count; i++) {
+	for (uint32_t i = 0, num = 0; i < ifmap->count; i++) {
 		struct iface *iface = sorted_ifaces[i];
 
 		if (!match_iface(args, iface))
 			continue;
 
 		set_global_ifname(&iface->link);
 
 		if (args->namesonly) {
 			if (num++ != 0)
 				printf(" ");
 			fputs(iface->link.ifla_ifname, stdout);
 		} else if (args->argc == 0)
 			status_nl(args, &h, iface);
 		else
 			ifconfig(args->argc, args->argv, 0, args->afp);
 	}
 	if (args->namesonly)
 		printf("\n");
 
 	close(h.s);
 	snl_free(&ss);
 }
 
diff --git a/sbin/ifconfig/ifgroup.c b/sbin/ifconfig/ifgroup.c
index 67dbc7f689f5..fc252d783d40 100644
--- a/sbin/ifconfig/ifgroup.c
+++ b/sbin/ifconfig/ifgroup.c
@@ -1,169 +1,173 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2006 Max Laier. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 #ifndef lint
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <net/if.h>
 
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include <libifconfig.h>
 
 #include "ifconfig.h"
 
 /* ARGSUSED */
 static void
 setifgroup(const char *group_name, int d, int s, const struct afswtch *rafp)
 {
 	struct ifgroupreq ifgr;
 
 	memset(&ifgr, 0, sizeof(ifgr));
 	strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
 
 	if (group_name[0] && isdigit(group_name[strlen(group_name) - 1]))
 		errx(1, "setifgroup: group names may not end in a digit");
 
 	if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
 		errx(1, "setifgroup: group name too long");
 	if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1 && errno != EEXIST)
 		err(1," SIOCAIFGROUP");
 }
 
 /* ARGSUSED */
 static void
 unsetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp)
 {
 	struct ifgroupreq ifgr;
 
 	memset(&ifgr, 0, sizeof(ifgr));
 	strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
 
 	if (group_name[0] && isdigit(group_name[strlen(group_name) - 1]))
 		errx(1, "unsetifgroup: group names may not end in a digit");
 
 	if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
 		errx(1, "unsetifgroup: group name too long");
 	if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1 && errno != ENOENT)
 		err(1, "SIOCDIFGROUP");
 }
 
 static void
 getifgroups(int s)
 {
 	struct ifgroupreq ifgr;
 	size_t cnt;
 
 	if (ifconfig_get_groups(lifh, name, &ifgr) == -1)
 		return;
 
 	cnt = 0;
 	for (size_t i = 0; i < ifgr.ifgr_len / sizeof(struct ifg_req); ++i) {
 		struct ifg_req *ifg = &ifgr.ifgr_groups[i];
 
 		if (strcmp(ifg->ifgrq_group, "all")) {
 			if (cnt == 0)
 				printf("\tgroups:");
 			cnt++;
 			printf(" %s", ifg->ifgrq_group);
 		}
 	}
 	if (cnt)
 		printf("\n");
 
 	free(ifgr.ifgr_groups);
 }
 
 static void
 printgroup(const char *groupname)
 {
 	struct ifgroupreq	 ifgr;
 	struct ifg_req		*ifg;
-	int			 len;
+	unsigned int		 len;
 	int			 s;
 
 	s = socket(AF_LOCAL, SOCK_DGRAM, 0);
 	if (s == -1)
 		err(1, "socket(AF_LOCAL,SOCK_DGRAM)");
 	bzero(&ifgr, sizeof(ifgr));
 	strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name));
 	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
 		if (errno == EINVAL || errno == ENOTTY ||
 		    errno == ENOENT)
 			exit(exit_code);
 		else
 			err(1, "SIOCGIFGMEMB");
 	}
 
 	len = ifgr.ifgr_len;
 	if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
 		err(1, "printgroup");
 	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
 		err(1, "SIOCGIFGMEMB");
 
 	for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
 	    ifg++) {
 		len -= sizeof(struct ifg_req);
 		printf("%s\n", ifg->ifgrq_member);
 	}
 	free(ifgr.ifgr_groups);
 
 	exit(exit_code);
 }
 
 static struct cmd group_cmds[] = {
 	DEF_CMD_ARG("group",	setifgroup),
 	DEF_CMD_ARG("-group",	unsetifgroup),
 };
+
 static struct afswtch af_group = {
 	.af_name	= "af_group",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = getifgroups,
 };
-static struct option group_gopt = { "g:", "[-g groupname]", printgroup };
+
+static struct option group_gopt = {
+	.opt		= "g:",
+	.opt_usage	= "[-g groupname]",
+	.cb		= printgroup,
+};
 
 static __constructor void
 group_ctor(void)
 {
-	int i;
-
-	for (i = 0; i < nitems(group_cmds);  i++)
+	for (size_t i = 0; i < nitems(group_cmds);  i++)
 		cmd_register(&group_cmds[i]);
 	af_register(&af_group);
 	opt_register(&group_gopt);
 }
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index 065a141da0f1..fc47105d9366 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -1,6088 +1,6083 @@
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * Copyright 2001 The Aerospace Corporation.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. The name of The Aerospace Corporation may not be used to endorse or
  *    promote products derived from this software.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * $FreeBSD$
  */
 
 /*-
  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
  * NASA Ames Research Center.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/if_media.h>
 #include <net/route.h>
 
 #include <net80211/ieee80211_ioctl.h>
 #include <net80211/ieee80211_freebsd.h>
 #include <net80211/ieee80211_superg.h>
 #include <net80211/ieee80211_tdma.h>
 #include <net80211/ieee80211_mesh.h>
 #include <net80211/ieee80211_wps.h>
 
 #include <assert.h>
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdarg.h>
 #include <stddef.h>		/* NB: for offsetof */
 #include <locale.h>
 #include <langinfo.h>
 
 #include "ifconfig.h"
 
 #include <lib80211/lib80211_regdomain.h>
 #include <lib80211/lib80211_ioctl.h>
 
 #ifndef IEEE80211_FIXED_RATE_NONE
 #define	IEEE80211_FIXED_RATE_NONE	0xff
 #endif
 
 /* XXX need these publicly defined or similar */
 #ifndef IEEE80211_NODE_AUTH
 #define	IEEE80211_NODE_AUTH	0x000001	/* authorized for data */
 #define	IEEE80211_NODE_QOS	0x000002	/* QoS enabled */
 #define	IEEE80211_NODE_ERP	0x000004	/* ERP enabled */
 #define	IEEE80211_NODE_PWR_MGT	0x000010	/* power save mode enabled */
 #define	IEEE80211_NODE_AREF	0x000020	/* authentication ref held */
 #define	IEEE80211_NODE_HT	0x000040	/* HT enabled */
 #define	IEEE80211_NODE_HTCOMPAT	0x000080	/* HT setup w/ vendor OUI's */
 #define	IEEE80211_NODE_WPS	0x000100	/* WPS association */
 #define	IEEE80211_NODE_TSN	0x000200	/* TSN association */
 #define	IEEE80211_NODE_AMPDU_RX	0x000400	/* AMPDU rx enabled */
 #define	IEEE80211_NODE_AMPDU_TX	0x000800	/* AMPDU tx enabled */
 #define	IEEE80211_NODE_MIMO_PS	0x001000	/* MIMO power save enabled */
 #define	IEEE80211_NODE_MIMO_RTS	0x002000	/* send RTS in MIMO PS */
 #define	IEEE80211_NODE_RIFS	0x004000	/* RIFS enabled */
 #define	IEEE80211_NODE_SGI20	0x008000	/* Short GI in HT20 enabled */
 #define	IEEE80211_NODE_SGI40	0x010000	/* Short GI in HT40 enabled */
 #define	IEEE80211_NODE_ASSOCID	0x020000	/* xmit requires associd */
 #define	IEEE80211_NODE_AMSDU_RX	0x040000	/* AMSDU rx enabled */
 #define	IEEE80211_NODE_AMSDU_TX	0x080000	/* AMSDU tx enabled */
 #define	IEEE80211_NODE_VHT	0x100000	/* VHT enabled */
 #define	IEEE80211_NODE_LDPC	0x200000	/* LDPC enabled */
 #define	IEEE80211_NODE_UAPSD	0x400000	/* UAPSD enabled */
 #endif
 
 /* XXX should also figure out where to put these for k/u-space sharing. */
 #ifndef IEEE80211_FVHT_VHT
 #define	IEEE80211_FVHT_VHT	0x000000001	/* CONF: VHT supported */
 #define	IEEE80211_FVHT_USEVHT40	0x000000002	/* CONF: Use VHT40 */
 #define	IEEE80211_FVHT_USEVHT80	0x000000004	/* CONF: Use VHT80 */
 #define	IEEE80211_FVHT_USEVHT160 0x000000008	/* CONF: Use VHT160 */
 #define	IEEE80211_FVHT_USEVHT80P80 0x000000010	/* CONF: Use VHT 80+80 */
 #endif
 
 /* Helper macros unified. */
 #ifndef	_IEEE80211_MASKSHIFT
 #define	_IEEE80211_MASKSHIFT(_v, _f)	(((_v) & _f) >> _f##_S)
 #endif
 #ifndef	_IEEE80211_SHIFTMASK
 #define	_IEEE80211_SHIFTMASK(_v, _f)	(((_v) << _f##_S) & _f)
 #endif
 
 #define	MAXCHAN	1536		/* max 1.5K channels */
 
 #define	MAXCOL	78
 static	int col;
 static	char spacer;
 
 static void LINE_INIT(char c);
 static void LINE_BREAK(void);
 static void LINE_CHECK(const char *fmt, ...);
 
 static const char *modename[IEEE80211_MODE_MAX] = {
 	[IEEE80211_MODE_AUTO]	  = "auto",
 	[IEEE80211_MODE_11A]	  = "11a",
 	[IEEE80211_MODE_11B]	  = "11b",
 	[IEEE80211_MODE_11G]	  = "11g",
 	[IEEE80211_MODE_FH]	  = "fh",
 	[IEEE80211_MODE_TURBO_A]  = "turboA",
 	[IEEE80211_MODE_TURBO_G]  = "turboG",
 	[IEEE80211_MODE_STURBO_A] = "sturbo",
 	[IEEE80211_MODE_11NA]	  = "11na",
 	[IEEE80211_MODE_11NG]	  = "11ng",
 	[IEEE80211_MODE_HALF]	  = "half",
 	[IEEE80211_MODE_QUARTER]  = "quarter",
 	[IEEE80211_MODE_VHT_2GHZ] = "11acg",
 	[IEEE80211_MODE_VHT_5GHZ] = "11ac",
 };
 
 static void set80211(int s, int type, int val, int len, void *data);
 static int get80211(int s, int type, void *data, int len);
 static int get80211len(int s, int type, void *data, int len, int *plen);
 static int get80211val(int s, int type, int *val);
 static const char *get_string(const char *val, const char *sep,
     u_int8_t *buf, int *lenp);
 static void print_string(const u_int8_t *buf, int len);
 static void print_regdomain(const struct ieee80211_regdomain *, int);
 static void print_channels(int, const struct ieee80211req_chaninfo *,
     int allchans, int verbose);
 static void regdomain_makechannels(struct ieee80211_regdomain_req *,
     const struct ieee80211_devcaps_req *);
 static const char *mesh_linkstate_string(uint8_t state);
 
 static struct ieee80211req_chaninfo *chaninfo;
 static struct ieee80211_regdomain regdomain;
 static int gotregdomain = 0;
 static struct ieee80211_roamparams_req roamparams;
 static int gotroam = 0;
 static struct ieee80211_txparams_req txparams;
 static int gottxparams = 0;
 static struct ieee80211_channel curchan;
 static int gotcurchan = 0;
 static struct ifmediareq *ifmr;
 static int htconf = 0;
 static	int gothtconf = 0;
 
 static void
 gethtconf(int s)
 {
 	if (gothtconf)
 		return;
 	if (get80211val(s, IEEE80211_IOC_HTCONF, &htconf) < 0)
 		warn("unable to get HT configuration information");
 	gothtconf = 1;
 }
 
 /* VHT */
 static int vhtconf = 0;
 static	int gotvhtconf = 0;
 
 static void
 getvhtconf(int s)
 {
 	if (gotvhtconf)
 		return;
 	if (get80211val(s, IEEE80211_IOC_VHTCONF, &vhtconf) < 0)
 		warn("unable to get VHT configuration information");
 	gotvhtconf = 1;
 }
 
 /*
  * Collect channel info from the kernel.  We use this (mostly)
  * to handle mapping between frequency and IEEE channel number.
  */
 static void
 getchaninfo(int s)
 {
 	if (chaninfo != NULL)
 		return;
 	chaninfo = malloc(IEEE80211_CHANINFO_SIZE(MAXCHAN));
 	if (chaninfo == NULL)
 		errx(1, "no space for channel list");
 	if (get80211(s, IEEE80211_IOC_CHANINFO, chaninfo,
 	    IEEE80211_CHANINFO_SIZE(MAXCHAN)) < 0)
 		err(1, "unable to get channel information");
 	ifmr = ifmedia_getstate();
 	gethtconf(s);
 	getvhtconf(s);
 }
 
 static struct regdata *
 getregdata(void)
 {
 	static struct regdata *rdp = NULL;
 	if (rdp == NULL) {
 		rdp = lib80211_alloc_regdata();
 		if (rdp == NULL)
 			errx(-1, "missing or corrupted regdomain database");
 	}
 	return rdp;
 }
 
 /*
  * Given the channel at index i with attributes from,
  * check if there is a channel with attributes to in
  * the channel table.  With suitable attributes this
  * allows the caller to look for promotion; e.g. from
  * 11b > 11g.
  */
 static int
-canpromote(int i, int from, int to)
+canpromote(unsigned int i, uint32_t from, uint32_t to)
 {
 	const struct ieee80211_channel *fc = &chaninfo->ic_chans[i];
 	u_int j;
 
 	if ((fc->ic_flags & from) != from)
 		return i;
 	/* NB: quick check exploiting ordering of chans w/ same frequency */
 	if (i+1 < chaninfo->ic_nchans &&
 	    chaninfo->ic_chans[i+1].ic_freq == fc->ic_freq &&
 	    (chaninfo->ic_chans[i+1].ic_flags & to) == to)
 		return i+1;
 	/* brute force search in case channel list is not ordered */
 	for (j = 0; j < chaninfo->ic_nchans; j++) {
 		const struct ieee80211_channel *tc = &chaninfo->ic_chans[j];
 		if (j != i &&
 		    tc->ic_freq == fc->ic_freq && (tc->ic_flags & to) == to)
 		return j;
 	}
 	return i;
 }
 
 /*
  * Handle channel promotion.  When a channel is specified with
  * only a frequency we want to promote it to the ``best'' channel
  * available.  The channel list has separate entries for 11b, 11g,
  * 11a, and 11n[ga] channels so specifying a frequency w/o any
  * attributes requires we upgrade, e.g. from 11b -> 11g.  This
  * gets complicated when the channel is specified on the same
  * command line with a media request that constrains the available
  * channe list (e.g. mode 11a); we want to honor that to avoid
  * confusing behaviour.
  */
 /*
  * XXX VHT
  */
 static int
-promote(int i)
+promote(unsigned int i)
 {
 	/*
 	 * Query the current mode of the interface in case it's
 	 * constrained (e.g. to 11a).  We must do this carefully
 	 * as there may be a pending ifmedia request in which case
 	 * asking the kernel will give us the wrong answer.  This
 	 * is an unfortunate side-effect of the way ifconfig is
 	 * structure for modularity (yech).
 	 *
 	 * NB: ifmr is actually setup in getchaninfo (above); we
 	 *     assume it's called coincident with to this call so
 	 *     we have a ``current setting''; otherwise we must pass
 	 *     the socket descriptor down to here so we can make
 	 *     the ifmedia_getstate call ourselves.
 	 */
 	int chanmode = ifmr != NULL ? IFM_MODE(ifmr->ifm_current) : IFM_AUTO;
 
 	/* when ambiguous promote to ``best'' */
 	/* NB: we abitrarily pick HT40+ over HT40- */
 	if (chanmode != IFM_IEEE80211_11B)
 		i = canpromote(i, IEEE80211_CHAN_B, IEEE80211_CHAN_G);
 	if (chanmode != IFM_IEEE80211_11G && (htconf & 1)) {
 		i = canpromote(i, IEEE80211_CHAN_G,
 			IEEE80211_CHAN_G | IEEE80211_CHAN_HT20);
 		if (htconf & 2) {
 			i = canpromote(i, IEEE80211_CHAN_G,
 				IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D);
 			i = canpromote(i, IEEE80211_CHAN_G,
 				IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U);
 		}
 	}
 	if (chanmode != IFM_IEEE80211_11A && (htconf & 1)) {
 		i = canpromote(i, IEEE80211_CHAN_A,
 			IEEE80211_CHAN_A | IEEE80211_CHAN_HT20);
 		if (htconf & 2) {
 			i = canpromote(i, IEEE80211_CHAN_A,
 				IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D);
 			i = canpromote(i, IEEE80211_CHAN_A,
 				IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U);
 		}
 	}
 	return i;
 }
 
 static void
-mapfreq(struct ieee80211_channel *chan, int freq, int flags)
+mapfreq(struct ieee80211_channel *chan, uint16_t freq, unsigned int flags)
 {
 	u_int i;
 
 	for (i = 0; i < chaninfo->ic_nchans; i++) {
 		const struct ieee80211_channel *c = &chaninfo->ic_chans[i];
 
 		if (c->ic_freq == freq && (c->ic_flags & flags) == flags) {
 			if (flags == 0) {
 				/* when ambiguous promote to ``best'' */
 				c = &chaninfo->ic_chans[promote(i)];
 			}
 			*chan = *c;
 			return;
 		}
 	}
 	errx(1, "unknown/undefined frequency %u/0x%x", freq, flags);
 }
 
 static void
-mapchan(struct ieee80211_channel *chan, int ieee, int flags)
+mapchan(struct ieee80211_channel *chan, uint8_t ieee, unsigned int flags)
 {
 	u_int i;
 
 	for (i = 0; i < chaninfo->ic_nchans; i++) {
 		const struct ieee80211_channel *c = &chaninfo->ic_chans[i];
 
 		if (c->ic_ieee == ieee && (c->ic_flags & flags) == flags) {
 			if (flags == 0) {
 				/* when ambiguous promote to ``best'' */
 				c = &chaninfo->ic_chans[promote(i)];
 			}
 			*chan = *c;
 			return;
 		}
 	}
 	errx(1, "unknown/undefined channel number %d flags 0x%x", ieee, flags);
 }
 
 static const struct ieee80211_channel *
 getcurchan(int s)
 {
 	if (gotcurchan)
 		return &curchan;
 	if (get80211(s, IEEE80211_IOC_CURCHAN, &curchan, sizeof(curchan)) < 0) {
 		int val;
 		/* fall back to legacy ioctl */
 		if (get80211val(s, IEEE80211_IOC_CHANNEL, &val) < 0)
 			err(-1, "cannot figure out current channel");
 		getchaninfo(s);
 		mapchan(&curchan, val, 0);
 	}
 	gotcurchan = 1;
 	return &curchan;
 }
 
 static enum ieee80211_phymode
 chan2mode(const struct ieee80211_channel *c)
 {
 	if (IEEE80211_IS_CHAN_VHTA(c))
 		return IEEE80211_MODE_VHT_5GHZ;
 	if (IEEE80211_IS_CHAN_VHTG(c))
 		return IEEE80211_MODE_VHT_2GHZ;
 	if (IEEE80211_IS_CHAN_HTA(c))
 		return IEEE80211_MODE_11NA;
 	if (IEEE80211_IS_CHAN_HTG(c))
 		return IEEE80211_MODE_11NG;
 	if (IEEE80211_IS_CHAN_108A(c))
 		return IEEE80211_MODE_TURBO_A;
 	if (IEEE80211_IS_CHAN_108G(c))
 		return IEEE80211_MODE_TURBO_G;
 	if (IEEE80211_IS_CHAN_ST(c))
 		return IEEE80211_MODE_STURBO_A;
 	if (IEEE80211_IS_CHAN_FHSS(c))
 		return IEEE80211_MODE_FH;
 	if (IEEE80211_IS_CHAN_HALF(c))
 		return IEEE80211_MODE_HALF;
 	if (IEEE80211_IS_CHAN_QUARTER(c))
 		return IEEE80211_MODE_QUARTER;
 	if (IEEE80211_IS_CHAN_A(c))
 		return IEEE80211_MODE_11A;
 	if (IEEE80211_IS_CHAN_ANYG(c))
 		return IEEE80211_MODE_11G;
 	if (IEEE80211_IS_CHAN_B(c))
 		return IEEE80211_MODE_11B;
 	return IEEE80211_MODE_AUTO;
 }
 
 static void
 getroam(int s)
 {
 	if (gotroam)
 		return;
 	if (get80211(s, IEEE80211_IOC_ROAM,
 	    &roamparams, sizeof(roamparams)) < 0)
 		err(1, "unable to get roaming parameters");
 	gotroam = 1;
 }
 
 static void
 setroam_cb(int s, void *arg)
 {
 	struct ieee80211_roamparams_req *roam = arg;
 	set80211(s, IEEE80211_IOC_ROAM, 0, sizeof(*roam), roam);
 }
 
 static void
 gettxparams(int s)
 {
 	if (gottxparams)
 		return;
 	if (get80211(s, IEEE80211_IOC_TXPARAMS,
 	    &txparams, sizeof(txparams)) < 0)
 		err(1, "unable to get transmit parameters");
 	gottxparams = 1;
 }
 
 static void
 settxparams_cb(int s, void *arg)
 {
 	struct ieee80211_txparams_req *txp = arg;
 	set80211(s, IEEE80211_IOC_TXPARAMS, 0, sizeof(*txp), txp);
 }
 
 static void
 getregdomain(int s)
 {
 	if (gotregdomain)
 		return;
 	if (get80211(s, IEEE80211_IOC_REGDOMAIN,
 	    &regdomain, sizeof(regdomain)) < 0)
 		err(1, "unable to get regulatory domain info");
 	gotregdomain = 1;
 }
 
 static void
 getdevcaps(int s, struct ieee80211_devcaps_req *dc)
 {
 	if (get80211(s, IEEE80211_IOC_DEVCAPS, dc,
 	    IEEE80211_DEVCAPS_SPACE(dc)) < 0)
 		err(1, "unable to get device capabilities");
 }
 
 static void
 setregdomain_cb(int s, void *arg)
 {
 	struct ieee80211_regdomain_req *req;
 	struct ieee80211_regdomain *rd = arg;
 	struct ieee80211_devcaps_req *dc;
 	struct regdata *rdp = getregdata();
 
 	if (rd->country != NO_COUNTRY) {
 		const struct country *cc;
 		/*
 		 * Check current country seting to make sure it's
 		 * compatible with the new regdomain.  If not, then
 		 * override it with any default country for this
 		 * SKU.  If we cannot arrange a match, then abort.
 		 */
 		cc = lib80211_country_findbycc(rdp, rd->country);
 		if (cc == NULL)
 			errx(1, "unknown ISO country code %d", rd->country);
 		if (cc->rd->sku != rd->regdomain) {
 			const struct regdomain *rp;
 			/*
 			 * Check if country is incompatible with regdomain.
 			 * To enable multiple regdomains for a country code
 			 * we permit a mismatch between the regdomain and
 			 * the country's associated regdomain when the
 			 * regdomain is setup w/o a default country.  For
 			 * example, US is bound to the FCC regdomain but
 			 * we allow US to be combined with FCC3 because FCC3
 			 * has not default country.  This allows bogus
 			 * combinations like FCC3+DK which are resolved when
 			 * constructing the channel list by deferring to the
 			 * regdomain to construct the channel list.
 			 */
 			rp = lib80211_regdomain_findbysku(rdp, rd->regdomain);
 			if (rp == NULL)
 				errx(1, "country %s (%s) is not usable with "
 				    "regdomain %d", cc->isoname, cc->name,
 				    rd->regdomain);
 			else if (rp->cc != NULL && rp->cc != cc)
 				errx(1, "country %s (%s) is not usable with "
 				   "regdomain %s", cc->isoname, cc->name,
 				   rp->name);
 		}
 	}
 	/*
 	 * Fetch the device capabilities and calculate the
 	 * full set of netbands for which we request a new
 	 * channel list be constructed.  Once that's done we
 	 * push the regdomain info + channel list to the kernel.
 	 */
 	dc = malloc(IEEE80211_DEVCAPS_SIZE(MAXCHAN));
 	if (dc == NULL)
 		errx(1, "no space for device capabilities");
 	dc->dc_chaninfo.ic_nchans = MAXCHAN;
 	getdevcaps(s, dc);
 #if 0
 	if (verbose) {
 		printf("drivercaps: 0x%x\n", dc->dc_drivercaps);
 		printf("cryptocaps: 0x%x\n", dc->dc_cryptocaps);
 		printf("htcaps    : 0x%x\n", dc->dc_htcaps);
 		printf("vhtcaps   : 0x%x\n", dc->dc_vhtcaps);
 #if 0
 		memcpy(chaninfo, &dc->dc_chaninfo,
 		    IEEE80211_CHANINFO_SPACE(&dc->dc_chaninfo));
 		print_channels(s, &dc->dc_chaninfo, 1/*allchans*/, 1/*verbose*/);
 #endif
 	}
 #endif
 	req = malloc(IEEE80211_REGDOMAIN_SIZE(dc->dc_chaninfo.ic_nchans));
 	if (req == NULL)
 		errx(1, "no space for regdomain request");
 	req->rd = *rd;
 	regdomain_makechannels(req, dc);
 	if (verbose) {
 		LINE_INIT(':');
 		print_regdomain(rd, 1/*verbose*/);
 		LINE_BREAK();
 		/* blech, reallocate channel list for new data */
 		if (chaninfo != NULL)
 			free(chaninfo);
 		chaninfo = malloc(IEEE80211_CHANINFO_SPACE(&req->chaninfo));
 		if (chaninfo == NULL)
 			errx(1, "no space for channel list");
 		memcpy(chaninfo, &req->chaninfo,
 		    IEEE80211_CHANINFO_SPACE(&req->chaninfo));
 		print_channels(s, &req->chaninfo, 1/*allchans*/, 1/*verbose*/);
 	}
 	if (req->chaninfo.ic_nchans == 0)
 		errx(1, "no channels calculated");
 	set80211(s, IEEE80211_IOC_REGDOMAIN, 0,
 	    IEEE80211_REGDOMAIN_SPACE(req), req);
 	free(req);
 	free(dc);
 }
 
 static int
 ieee80211_mhz2ieee(int freq, int flags)
 {
 	struct ieee80211_channel chan;
 	mapfreq(&chan, freq, flags);
 	return chan.ic_ieee;
 }
 
 static int
 isanyarg(const char *arg)
 {
 	return (strncmp(arg, "-", 1) == 0 ||
 	    strncasecmp(arg, "any", 3) == 0 || strncasecmp(arg, "off", 3) == 0);
 }
 
 static void
 set80211ssid(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int		ssid;
 	int		len;
 	u_int8_t	data[IEEE80211_NWID_LEN];
 
 	ssid = 0;
 	len = strlen(val);
 	if (len > 2 && isdigit((int)val[0]) && val[1] == ':') {
 		ssid = atoi(val)-1;
 		val += 2;
 	}
 
 	bzero(data, sizeof(data));
 	len = sizeof(data);
 	if (get_string(val, NULL, data, &len) == NULL)
 		exit(1);
 
 	set80211(s, IEEE80211_IOC_SSID, ssid, len, data);
 }
 
 static void
 set80211meshid(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int		len;
 	u_int8_t	data[IEEE80211_NWID_LEN];
 
 	memset(data, 0, sizeof(data));
 	len = sizeof(data);
 	if (get_string(val, NULL, data, &len) == NULL)
 		exit(1);
 
 	set80211(s, IEEE80211_IOC_MESH_ID, 0, len, data);
 }	
 
 static void
 set80211stationname(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int			len;
 	u_int8_t		data[33];
 
 	bzero(data, sizeof(data));
 	len = sizeof(data);
 	get_string(val, NULL, data, &len);
 
 	set80211(s, IEEE80211_IOC_STATIONNAME, 0, len, data);
 }
 
 /*
  * Parse a channel specification for attributes/flags.
  * The syntax is:
  *	freq/xx		channel width (5,10,20,40,40+,40-)
  *	freq:mode	channel mode (a,b,g,h,n,t,s,d)
  *
  * These can be combined in either order; e.g. 2437:ng/40.
  * Modes are case insensitive.
  *
  * The result is not validated here; it's assumed to be
  * checked against the channel table fetched from the kernel.
  */ 
-static int
+static unsigned int
 getchannelflags(const char *val, int freq)
 {
 #define	_CHAN_HT	0x80000000
 	const char *cp;
 	int flags;
 	int is_vht = 0;
 
 	flags = 0;
 
 	cp = strchr(val, ':');
 	if (cp != NULL) {
 		for (cp++; isalpha((int) *cp); cp++) {
 			/* accept mixed case */
 			int c = *cp;
 			if (isupper(c))
 				c = tolower(c);
 			switch (c) {
 			case 'a':		/* 802.11a */
 				flags |= IEEE80211_CHAN_A;
 				break;
 			case 'b':		/* 802.11b */
 				flags |= IEEE80211_CHAN_B;
 				break;
 			case 'g':		/* 802.11g */
 				flags |= IEEE80211_CHAN_G;
 				break;
 			case 'v':		/* vht: 802.11ac */
 				is_vht = 1;
 				/* Fallthrough */
 			case 'h':		/* ht = 802.11n */
 			case 'n':		/* 802.11n */
 				flags |= _CHAN_HT;	/* NB: private */
 				break;
 			case 'd':		/* dt = Atheros Dynamic Turbo */
 				flags |= IEEE80211_CHAN_TURBO;
 				break;
 			case 't':		/* ht, dt, st, t */
 				/* dt and unadorned t specify Dynamic Turbo */
 				if ((flags & (IEEE80211_CHAN_STURBO|_CHAN_HT)) == 0)
 					flags |= IEEE80211_CHAN_TURBO;
 				break;
 			case 's':		/* st = Atheros Static Turbo */
 				flags |= IEEE80211_CHAN_STURBO;
 				break;
 			default:
 				errx(-1, "%s: Invalid channel attribute %c\n",
 				    val, *cp);
 			}
 		}
 	}
 	cp = strchr(val, '/');
 	if (cp != NULL) {
 		char *ep;
 		u_long cw = strtoul(cp+1, &ep, 10);
 
 		switch (cw) {
 		case 5:
 			flags |= IEEE80211_CHAN_QUARTER;
 			break;
 		case 10:
 			flags |= IEEE80211_CHAN_HALF;
 			break;
 		case 20:
 			/* NB: this may be removed below */
 			flags |= IEEE80211_CHAN_HT20;
 			break;
 		case 40:
 		case 80:
 		case 160:
 			/* Handle the 80/160 VHT flag */
 			if (cw == 80)
 				flags |= IEEE80211_CHAN_VHT80;
 			else if (cw == 160)
 				flags |= IEEE80211_CHAN_VHT160;
 
 			/* Fallthrough */
 			if (ep != NULL && *ep == '+')
 				flags |= IEEE80211_CHAN_HT40U;
 			else if (ep != NULL && *ep == '-')
 				flags |= IEEE80211_CHAN_HT40D;
 			break;
 		default:
 			errx(-1, "%s: Invalid channel width\n", val);
 		}
 	}
 
 	/*
 	 * Cleanup specifications.
 	 */ 
 	if ((flags & _CHAN_HT) == 0) {
 		/*
 		 * If user specified freq/20 or freq/40 quietly remove
 		 * HT cw attributes depending on channel use.  To give
 		 * an explicit 20/40 width for an HT channel you must
 		 * indicate it is an HT channel since all HT channels
 		 * are also usable for legacy operation; e.g. freq:n/40.
 		 */
 		flags &= ~IEEE80211_CHAN_HT;
 		flags &= ~IEEE80211_CHAN_VHT;
 	} else {
 		/*
 		 * Remove private indicator that this is an HT channel
 		 * and if no explicit channel width has been given
 		 * provide the default settings.
 		 */
 		flags &= ~_CHAN_HT;
 		if ((flags & IEEE80211_CHAN_HT) == 0) {
 			struct ieee80211_channel chan;
 			/*
 			 * Consult the channel list to see if we can use
 			 * HT40+ or HT40- (if both the map routines choose).
 			 */
 			if (freq > 255)
 				mapfreq(&chan, freq, 0);
 			else
 				mapchan(&chan, freq, 0);
 			flags |= (chan.ic_flags & IEEE80211_CHAN_HT);
 		}
 
 		/*
 		 * If VHT is enabled, then also set the VHT flag and the
 		 * relevant channel up/down.
 		 */
 		if (is_vht && (flags & IEEE80211_CHAN_HT)) {
 			/*
 			 * XXX yes, maybe we should just have VHT, and reuse
 			 * HT20/HT40U/HT40D
 			 */
 			if (flags & IEEE80211_CHAN_VHT80)
 				;
 			else if (flags & IEEE80211_CHAN_HT20)
 				flags |= IEEE80211_CHAN_VHT20;
 			else if (flags & IEEE80211_CHAN_HT40U)
 				flags |= IEEE80211_CHAN_VHT40U;
 			else if (flags & IEEE80211_CHAN_HT40D)
 				flags |= IEEE80211_CHAN_VHT40D;
 		}
 	}
 	return flags;
 #undef _CHAN_HT
 }
 
 static void
 getchannel(int s, struct ieee80211_channel *chan, const char *val)
 {
-	int v, flags;
+	unsigned int v, flags;
 	char *eptr;
 
 	memset(chan, 0, sizeof(*chan));
 	if (isanyarg(val)) {
 		chan->ic_freq = IEEE80211_CHAN_ANY;
 		return;
 	}
 	getchaninfo(s);
 	errno = 0;
 	v = strtol(val, &eptr, 10);
 	if (val[0] == '\0' || val == eptr || errno == ERANGE ||
 	    /* channel may be suffixed with nothing, :flag, or /width */
 	    (eptr[0] != '\0' && eptr[0] != ':' && eptr[0] != '/'))
 		errx(1, "invalid channel specification%s",
 		    errno == ERANGE ? " (out of range)" : "");
 	flags = getchannelflags(val, v);
 	if (v > 255) {		/* treat as frequency */
 		mapfreq(chan, v, flags);
 	} else {
 		mapchan(chan, v, flags);
 	}
 }
 
 static void
 set80211channel(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	struct ieee80211_channel chan;
 
 	getchannel(s, &chan, val);
 	set80211(s, IEEE80211_IOC_CURCHAN, 0, sizeof(chan), &chan);
 }
 
 static void
 set80211chanswitch(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	struct ieee80211_chanswitch_req csr;
 
 	getchannel(s, &csr.csa_chan, val);
 	csr.csa_mode = 1;
 	csr.csa_count = 5;
 	set80211(s, IEEE80211_IOC_CHANSWITCH, 0, sizeof(csr), &csr);
 }
 
 static void
 set80211authmode(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int	mode;
 
 	if (strcasecmp(val, "none") == 0) {
 		mode = IEEE80211_AUTH_NONE;
 	} else if (strcasecmp(val, "open") == 0) {
 		mode = IEEE80211_AUTH_OPEN;
 	} else if (strcasecmp(val, "shared") == 0) {
 		mode = IEEE80211_AUTH_SHARED;
 	} else if (strcasecmp(val, "8021x") == 0) {
 		mode = IEEE80211_AUTH_8021X;
 	} else if (strcasecmp(val, "wpa") == 0) {
 		mode = IEEE80211_AUTH_WPA;
 	} else {
 		errx(1, "unknown authmode");
 	}
 
 	set80211(s, IEEE80211_IOC_AUTHMODE, mode, 0, NULL);
 }
 
 static void
 set80211powersavemode(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int	mode;
 
 	if (strcasecmp(val, "off") == 0) {
 		mode = IEEE80211_POWERSAVE_OFF;
 	} else if (strcasecmp(val, "on") == 0) {
 		mode = IEEE80211_POWERSAVE_ON;
 	} else if (strcasecmp(val, "cam") == 0) {
 		mode = IEEE80211_POWERSAVE_CAM;
 	} else if (strcasecmp(val, "psp") == 0) {
 		mode = IEEE80211_POWERSAVE_PSP;
 	} else if (strcasecmp(val, "psp-cam") == 0) {
 		mode = IEEE80211_POWERSAVE_PSP_CAM;
 	} else {
 		errx(1, "unknown powersavemode");
 	}
 
 	set80211(s, IEEE80211_IOC_POWERSAVE, mode, 0, NULL);
 }
 
 static void
 set80211powersave(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	if (d == 0)
 		set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_OFF,
 		    0, NULL);
 	else
 		set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_ON,
 		    0, NULL);
 }
 
 static void
 set80211powersavesleep(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_POWERSAVESLEEP, atoi(val), 0, NULL);
 }
 
 static void
 set80211wepmode(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int	mode;
 
 	if (strcasecmp(val, "off") == 0) {
 		mode = IEEE80211_WEP_OFF;
 	} else if (strcasecmp(val, "on") == 0) {
 		mode = IEEE80211_WEP_ON;
 	} else if (strcasecmp(val, "mixed") == 0) {
 		mode = IEEE80211_WEP_MIXED;
 	} else {
 		errx(1, "unknown wep mode");
 	}
 
 	set80211(s, IEEE80211_IOC_WEP, mode, 0, NULL);
 }
 
 static void
 set80211wep(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_WEP, d, 0, NULL);
 }
 
 static int
 isundefarg(const char *arg)
 {
 	return (strcmp(arg, "-") == 0 || strncasecmp(arg, "undef", 5) == 0);
 }
 
 static void
 set80211weptxkey(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	if (isundefarg(val))
 		set80211(s, IEEE80211_IOC_WEPTXKEY, IEEE80211_KEYIX_NONE, 0, NULL);
 	else
 		set80211(s, IEEE80211_IOC_WEPTXKEY, atoi(val)-1, 0, NULL);
 }
 
 static void
 set80211wepkey(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int		key = 0;
 	int		len;
 	u_int8_t	data[IEEE80211_KEYBUF_SIZE];
 
 	if (isdigit((int)val[0]) && val[1] == ':') {
 		key = atoi(val)-1;
 		val += 2;
 	}
 
 	bzero(data, sizeof(data));
 	len = sizeof(data);
 	get_string(val, NULL, data, &len);
 
 	set80211(s, IEEE80211_IOC_WEPKEY, key, len, data);
 }
 
 /*
  * This function is purely a NetBSD compatibility interface.  The NetBSD
  * interface is too inflexible, but it's there so we'll support it since
  * it's not all that hard.
  */
 static void
 set80211nwkey(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int		txkey;
 	int		i, len;
 	u_int8_t	data[IEEE80211_KEYBUF_SIZE];
 
 	set80211(s, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL);
 
 	if (isdigit((int)val[0]) && val[1] == ':') {
 		txkey = val[0]-'0'-1;
 		val += 2;
 
 		for (i = 0; i < 4; i++) {
 			bzero(data, sizeof(data));
 			len = sizeof(data);
 			val = get_string(val, ",", data, &len);
 			if (val == NULL)
 				exit(1);
 
 			set80211(s, IEEE80211_IOC_WEPKEY, i, len, data);
 		}
 	} else {
 		bzero(data, sizeof(data));
 		len = sizeof(data);
 		get_string(val, NULL, data, &len);
 		txkey = 0;
 
 		set80211(s, IEEE80211_IOC_WEPKEY, 0, len, data);
 
 		bzero(data, sizeof(data));
 		for (i = 1; i < 4; i++)
 			set80211(s, IEEE80211_IOC_WEPKEY, i, 0, data);
 	}
 
 	set80211(s, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL);
 }
 
 static void
 set80211rtsthreshold(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_RTSTHRESHOLD,
 		isundefarg(val) ? IEEE80211_RTS_MAX : atoi(val), 0, NULL);
 }
 
 static void
 set80211protmode(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int	mode;
 
 	if (strcasecmp(val, "off") == 0) {
 		mode = IEEE80211_PROTMODE_OFF;
 	} else if (strcasecmp(val, "cts") == 0) {
 		mode = IEEE80211_PROTMODE_CTS;
 	} else if (strncasecmp(val, "rtscts", 3) == 0) {
 		mode = IEEE80211_PROTMODE_RTSCTS;
 	} else {
 		errx(1, "unknown protection mode");
 	}
 
 	set80211(s, IEEE80211_IOC_PROTMODE, mode, 0, NULL);
 }
 
 static void
 set80211htprotmode(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int	mode;
 
 	if (strcasecmp(val, "off") == 0) {
 		mode = IEEE80211_PROTMODE_OFF;
 	} else if (strncasecmp(val, "rts", 3) == 0) {
 		mode = IEEE80211_PROTMODE_RTSCTS;
 	} else {
 		errx(1, "unknown protection mode");
 	}
 
 	set80211(s, IEEE80211_IOC_HTPROTMODE, mode, 0, NULL);
 }
 
 static void
 set80211txpower(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	double v = atof(val);
 	int txpow;
 
 	txpow = (int) (2*v);
 	if (txpow != 2*v)
 		errx(-1, "invalid tx power (must be .5 dBm units)");
 	set80211(s, IEEE80211_IOC_TXPOWER, txpow, 0, NULL);
 }
 
 #define	IEEE80211_ROAMING_DEVICE	0
 #define	IEEE80211_ROAMING_AUTO		1
 #define	IEEE80211_ROAMING_MANUAL	2
 
 static void
 set80211roaming(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int mode;
 
 	if (strcasecmp(val, "device") == 0) {
 		mode = IEEE80211_ROAMING_DEVICE;
 	} else if (strcasecmp(val, "auto") == 0) {
 		mode = IEEE80211_ROAMING_AUTO;
 	} else if (strcasecmp(val, "manual") == 0) {
 		mode = IEEE80211_ROAMING_MANUAL;
 	} else {
 		errx(1, "unknown roaming mode");
 	}
 	set80211(s, IEEE80211_IOC_ROAMING, mode, 0, NULL);
 }
 
 static void
 set80211wme(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_WME, d, 0, NULL);
 }
 
 static void
 set80211hidessid(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_HIDESSID, d, 0, NULL);
 }
 
 static void
 set80211apbridge(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_APBRIDGE, d, 0, NULL);
 }
 
 static void
 set80211fastframes(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_FF, d, 0, NULL);
 }
 
 static void
 set80211dturbo(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_TURBOP, d, 0, NULL);
 }
 
 static void
 set80211chanlist(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	struct ieee80211req_chanlist chanlist;
 	char *temp, *cp, *tp;
 
 	temp = malloc(strlen(val) + 1);
 	if (temp == NULL)
 		errx(1, "malloc failed");
 	strcpy(temp, val);
 	memset(&chanlist, 0, sizeof(chanlist));
 	cp = temp;
 	for (;;) {
 		int first, last, f, c;
 
 		tp = strchr(cp, ',');
 		if (tp != NULL)
 			*tp++ = '\0';
 		switch (sscanf(cp, "%u-%u", &first, &last)) {
 		case 1:
 			if (first > IEEE80211_CHAN_MAX)
 				errx(-1, "channel %u out of range, max %u",
 					first, IEEE80211_CHAN_MAX);
 			setbit(chanlist.ic_channels, first);
 			break;
 		case 2:
 			if (first > IEEE80211_CHAN_MAX)
 				errx(-1, "channel %u out of range, max %u",
 					first, IEEE80211_CHAN_MAX);
 			if (last > IEEE80211_CHAN_MAX)
 				errx(-1, "channel %u out of range, max %u",
 					last, IEEE80211_CHAN_MAX);
 			if (first > last)
 				errx(-1, "void channel range, %u > %u",
 					first, last);
 			for (f = first; f <= last; f++)
 				setbit(chanlist.ic_channels, f);
 			break;
 		}
 		if (tp == NULL)
 			break;
 		c = *tp;
 		while (isspace(c))
 			tp++;
 		if (!isdigit(c))
 			break;
 		cp = tp;
 	}
 	set80211(s, IEEE80211_IOC_CHANLIST, 0, sizeof(chanlist), &chanlist);
 	free(temp);
 }
 
 static void
 set80211bssid(const char *val, int d, int s, const struct afswtch *rafp)
 {
 
 	if (!isanyarg(val)) {
 		char *temp;
 		struct sockaddr_dl sdl;
 
 		temp = malloc(strlen(val) + 2); /* ':' and '\0' */
 		if (temp == NULL)
 			errx(1, "malloc failed");
 		temp[0] = ':';
 		strcpy(temp + 1, val);
 		sdl.sdl_len = sizeof(sdl);
 		link_addr(temp, &sdl);
 		free(temp);
 		if (sdl.sdl_alen != IEEE80211_ADDR_LEN)
 			errx(1, "malformed link-level address");
 		set80211(s, IEEE80211_IOC_BSSID, 0,
 			IEEE80211_ADDR_LEN, LLADDR(&sdl));
 	} else {
 		uint8_t zerobssid[IEEE80211_ADDR_LEN];
 		memset(zerobssid, 0, sizeof(zerobssid));
 		set80211(s, IEEE80211_IOC_BSSID, 0,
 			IEEE80211_ADDR_LEN, zerobssid);
 	}
 }
 
 static int
 getac(const char *ac)
 {
 	if (strcasecmp(ac, "ac_be") == 0 || strcasecmp(ac, "be") == 0)
 		return WME_AC_BE;
 	if (strcasecmp(ac, "ac_bk") == 0 || strcasecmp(ac, "bk") == 0)
 		return WME_AC_BK;
 	if (strcasecmp(ac, "ac_vi") == 0 || strcasecmp(ac, "vi") == 0)
 		return WME_AC_VI;
 	if (strcasecmp(ac, "ac_vo") == 0 || strcasecmp(ac, "vo") == 0)
 		return WME_AC_VO;
 	errx(1, "unknown wme access class %s", ac);
 }
 
 static
 DECL_CMD_FUNC2(set80211cwmin, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_CWMIN, atoi(val), getac(ac), NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211cwmax, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_CWMAX, atoi(val), getac(ac), NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211aifs, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_AIFS, atoi(val), getac(ac), NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211txoplimit, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_TXOPLIMIT, atoi(val), getac(ac), NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211acm, ac, d)
 {
 	set80211(s, IEEE80211_IOC_WME_ACM, 1, getac(ac), NULL);
 }
 static
 DECL_CMD_FUNC(set80211noacm, ac, d)
 {
 	set80211(s, IEEE80211_IOC_WME_ACM, 0, getac(ac), NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211ackpolicy, ac, d)
 {
 	set80211(s, IEEE80211_IOC_WME_ACKPOLICY, 1, getac(ac), NULL);
 }
 static
 DECL_CMD_FUNC(set80211noackpolicy, ac, d)
 {
 	set80211(s, IEEE80211_IOC_WME_ACKPOLICY, 0, getac(ac), NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211bsscwmin, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_CWMIN, atoi(val),
 		getac(ac)|IEEE80211_WMEPARAM_BSS, NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211bsscwmax, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_CWMAX, atoi(val),
 		getac(ac)|IEEE80211_WMEPARAM_BSS, NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211bssaifs, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_AIFS, atoi(val),
 		getac(ac)|IEEE80211_WMEPARAM_BSS, NULL);
 }
 
 static
 DECL_CMD_FUNC2(set80211bsstxoplimit, ac, val)
 {
 	set80211(s, IEEE80211_IOC_WME_TXOPLIMIT, atoi(val),
 		getac(ac)|IEEE80211_WMEPARAM_BSS, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211dtimperiod, val, d)
 {
 	set80211(s, IEEE80211_IOC_DTIM_PERIOD, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211bintval, val, d)
 {
 	set80211(s, IEEE80211_IOC_BEACON_INTERVAL, atoi(val), 0, NULL);
 }
 
 static void
 set80211macmac(int s, int op, const char *val)
 {
 	char *temp;
 	struct sockaddr_dl sdl;
 
 	temp = malloc(strlen(val) + 2); /* ':' and '\0' */
 	if (temp == NULL)
 		errx(1, "malloc failed");
 	temp[0] = ':';
 	strcpy(temp + 1, val);
 	sdl.sdl_len = sizeof(sdl);
 	link_addr(temp, &sdl);
 	free(temp);
 	if (sdl.sdl_alen != IEEE80211_ADDR_LEN)
 		errx(1, "malformed link-level address");
 	set80211(s, op, 0, IEEE80211_ADDR_LEN, LLADDR(&sdl));
 }
 
 static
 DECL_CMD_FUNC(set80211addmac, val, d)
 {
 	set80211macmac(s, IEEE80211_IOC_ADDMAC, val);
 }
 
 static
 DECL_CMD_FUNC(set80211delmac, val, d)
 {
 	set80211macmac(s, IEEE80211_IOC_DELMAC, val);
 }
 
 static
 DECL_CMD_FUNC(set80211kickmac, val, d)
 {
 	char *temp;
 	struct sockaddr_dl sdl;
 	struct ieee80211req_mlme mlme;
 
 	temp = malloc(strlen(val) + 2); /* ':' and '\0' */
 	if (temp == NULL)
 		errx(1, "malloc failed");
 	temp[0] = ':';
 	strcpy(temp + 1, val);
 	sdl.sdl_len = sizeof(sdl);
 	link_addr(temp, &sdl);
 	free(temp);
 	if (sdl.sdl_alen != IEEE80211_ADDR_LEN)
 		errx(1, "malformed link-level address");
 	memset(&mlme, 0, sizeof(mlme));
 	mlme.im_op = IEEE80211_MLME_DEAUTH;
 	mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE;
 	memcpy(mlme.im_macaddr, LLADDR(&sdl), IEEE80211_ADDR_LEN);
 	set80211(s, IEEE80211_IOC_MLME, 0, sizeof(mlme), &mlme);
 }
 
 static
 DECL_CMD_FUNC(set80211maccmd, val, d)
 {
 	set80211(s, IEEE80211_IOC_MACCMD, d, 0, NULL);
 }
 
 static void
 set80211meshrtmac(int s, int req, const char *val)
 {
 	char *temp;
 	struct sockaddr_dl sdl;
 
 	temp = malloc(strlen(val) + 2); /* ':' and '\0' */
 	if (temp == NULL)
 		errx(1, "malloc failed");
 	temp[0] = ':';
 	strcpy(temp + 1, val);
 	sdl.sdl_len = sizeof(sdl);
 	link_addr(temp, &sdl);
 	free(temp);
 	if (sdl.sdl_alen != IEEE80211_ADDR_LEN)
 		errx(1, "malformed link-level address");
 	set80211(s, IEEE80211_IOC_MESH_RTCMD, req,
 	    IEEE80211_ADDR_LEN, LLADDR(&sdl));
 }
 
 static
 DECL_CMD_FUNC(set80211addmeshrt, val, d)
 {
 	set80211meshrtmac(s, IEEE80211_MESH_RTCMD_ADD, val);
 }
 
 static
 DECL_CMD_FUNC(set80211delmeshrt, val, d)
 {
 	set80211meshrtmac(s, IEEE80211_MESH_RTCMD_DELETE, val);
 }
 
 static
 DECL_CMD_FUNC(set80211meshrtcmd, val, d)
 {
 	set80211(s, IEEE80211_IOC_MESH_RTCMD, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211hwmprootmode, val, d)
 {
 	int mode;
 
 	if (strcasecmp(val, "normal") == 0)
 		mode = IEEE80211_HWMP_ROOTMODE_NORMAL;
 	else if (strcasecmp(val, "proactive") == 0)
 		mode = IEEE80211_HWMP_ROOTMODE_PROACTIVE;
 	else if (strcasecmp(val, "rann") == 0)
 		mode = IEEE80211_HWMP_ROOTMODE_RANN;
 	else
 		mode = IEEE80211_HWMP_ROOTMODE_DISABLED;
 	set80211(s, IEEE80211_IOC_HWMP_ROOTMODE, mode, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211hwmpmaxhops, val, d)
 {
 	set80211(s, IEEE80211_IOC_HWMP_MAXHOPS, atoi(val), 0, NULL);
 }
 
 static void
 set80211pureg(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_PUREG, d, 0, NULL);
 }
 
 static void
 set80211quiet(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_QUIET, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211quietperiod, val, d)
 {
 	set80211(s, IEEE80211_IOC_QUIET_PERIOD, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211quietcount, val, d)
 {
 	set80211(s, IEEE80211_IOC_QUIET_COUNT, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211quietduration, val, d)
 {
 	set80211(s, IEEE80211_IOC_QUIET_DUR, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211quietoffset, val, d)
 {
 	set80211(s, IEEE80211_IOC_QUIET_OFFSET, atoi(val), 0, NULL);
 }
 
 static void
 set80211bgscan(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_BGSCAN, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211bgscanidle, val, d)
 {
 	set80211(s, IEEE80211_IOC_BGSCAN_IDLE, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211bgscanintvl, val, d)
 {
 	set80211(s, IEEE80211_IOC_BGSCAN_INTERVAL, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211scanvalid, val, d)
 {
 	set80211(s, IEEE80211_IOC_SCANVALID, atoi(val), 0, NULL);
 }
 
 /*
  * Parse an optional trailing specification of which netbands
  * to apply a parameter to.  This is basically the same syntax
  * as used for channels but you can concatenate to specify
  * multiple.  For example:
  *	14:abg		apply to 11a, 11b, and 11g
  *	6:ht		apply to 11na and 11ng
  * We don't make a big effort to catch silly things; this is
  * really a convenience mechanism.
  */
 static int
 getmodeflags(const char *val)
 {
 	const char *cp;
 	int flags;
 
 	flags = 0;
 
 	cp = strchr(val, ':');
 	if (cp != NULL) {
 		for (cp++; isalpha((int) *cp); cp++) {
 			/* accept mixed case */
 			int c = *cp;
 			if (isupper(c))
 				c = tolower(c);
 			switch (c) {
 			case 'a':		/* 802.11a */
 				flags |= IEEE80211_CHAN_A;
 				break;
 			case 'b':		/* 802.11b */
 				flags |= IEEE80211_CHAN_B;
 				break;
 			case 'g':		/* 802.11g */
 				flags |= IEEE80211_CHAN_G;
 				break;
 			case 'n':		/* 802.11n */
 				flags |= IEEE80211_CHAN_HT;
 				break;
 			case 'd':		/* dt = Atheros Dynamic Turbo */
 				flags |= IEEE80211_CHAN_TURBO;
 				break;
 			case 't':		/* ht, dt, st, t */
 				/* dt and unadorned t specify Dynamic Turbo */
 				if ((flags & (IEEE80211_CHAN_STURBO|IEEE80211_CHAN_HT)) == 0)
 					flags |= IEEE80211_CHAN_TURBO;
 				break;
 			case 's':		/* st = Atheros Static Turbo */
 				flags |= IEEE80211_CHAN_STURBO;
 				break;
 			case 'h':		/* 1/2-width channels */
 				flags |= IEEE80211_CHAN_HALF;
 				break;
 			case 'q':		/* 1/4-width channels */
 				flags |= IEEE80211_CHAN_QUARTER;
 				break;
 			case 'v':
 				/* XXX set HT too? */
 				flags |= IEEE80211_CHAN_VHT;
 				break;
 			default:
 				errx(-1, "%s: Invalid mode attribute %c\n",
 				    val, *cp);
 			}
 		}
 	}
 	return flags;
 }
 
 #define	_APPLY(_flags, _base, _param, _v) do {				\
     if (_flags & IEEE80211_CHAN_HT) {					\
 	    if ((_flags & (IEEE80211_CHAN_5GHZ|IEEE80211_CHAN_2GHZ)) == 0) {\
 		    _base.params[IEEE80211_MODE_11NA]._param = _v;	\
 		    _base.params[IEEE80211_MODE_11NG]._param = _v;	\
 	    } else if (_flags & IEEE80211_CHAN_5GHZ)			\
 		    _base.params[IEEE80211_MODE_11NA]._param = _v;	\
 	    else							\
 		    _base.params[IEEE80211_MODE_11NG]._param = _v;	\
     }									\
     if (_flags & IEEE80211_CHAN_TURBO) {				\
 	    if ((_flags & (IEEE80211_CHAN_5GHZ|IEEE80211_CHAN_2GHZ)) == 0) {\
 		    _base.params[IEEE80211_MODE_TURBO_A]._param = _v;	\
 		    _base.params[IEEE80211_MODE_TURBO_G]._param = _v;	\
 	    } else if (_flags & IEEE80211_CHAN_5GHZ)			\
 		    _base.params[IEEE80211_MODE_TURBO_A]._param = _v;	\
 	    else							\
 		    _base.params[IEEE80211_MODE_TURBO_G]._param = _v;	\
     }									\
     if (_flags & IEEE80211_CHAN_STURBO)					\
 	    _base.params[IEEE80211_MODE_STURBO_A]._param = _v;		\
     if ((_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)		\
 	    _base.params[IEEE80211_MODE_11A]._param = _v;		\
     if ((_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)		\
 	    _base.params[IEEE80211_MODE_11G]._param = _v;		\
     if ((_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)		\
 	    _base.params[IEEE80211_MODE_11B]._param = _v;		\
     if (_flags & IEEE80211_CHAN_HALF)					\
 	    _base.params[IEEE80211_MODE_HALF]._param = _v;		\
     if (_flags & IEEE80211_CHAN_QUARTER)				\
 	    _base.params[IEEE80211_MODE_QUARTER]._param = _v;		\
 } while (0)
 #define	_APPLY1(_flags, _base, _param, _v) do {				\
     if (_flags & IEEE80211_CHAN_HT) {					\
 	    if (_flags & IEEE80211_CHAN_5GHZ)				\
 		    _base.params[IEEE80211_MODE_11NA]._param = _v;	\
 	    else							\
 		    _base.params[IEEE80211_MODE_11NG]._param = _v;	\
     } else if ((_flags & IEEE80211_CHAN_108A) == IEEE80211_CHAN_108A)	\
 	    _base.params[IEEE80211_MODE_TURBO_A]._param = _v;		\
     else if ((_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G)	\
 	    _base.params[IEEE80211_MODE_TURBO_G]._param = _v;		\
     else if ((_flags & IEEE80211_CHAN_ST) == IEEE80211_CHAN_ST)		\
 	    _base.params[IEEE80211_MODE_STURBO_A]._param = _v;		\
     else if (_flags & IEEE80211_CHAN_HALF)				\
 	    _base.params[IEEE80211_MODE_HALF]._param = _v;		\
     else if (_flags & IEEE80211_CHAN_QUARTER)				\
 	    _base.params[IEEE80211_MODE_QUARTER]._param = _v;		\
     else if ((_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)		\
 	    _base.params[IEEE80211_MODE_11A]._param = _v;		\
     else if ((_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)		\
 	    _base.params[IEEE80211_MODE_11G]._param = _v;		\
     else if ((_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)		\
 	    _base.params[IEEE80211_MODE_11B]._param = _v;		\
 } while (0)
 #define	_APPLY_RATE(_flags, _base, _param, _v) do {			\
     if (_flags & IEEE80211_CHAN_HT) {					\
 	(_v) = (_v / 2) | IEEE80211_RATE_MCS;				\
     }									\
     _APPLY(_flags, _base, _param, _v);					\
 } while (0)
 #define	_APPLY_RATE1(_flags, _base, _param, _v) do {			\
     if (_flags & IEEE80211_CHAN_HT) {					\
 	(_v) = (_v / 2) | IEEE80211_RATE_MCS;				\
     }									\
     _APPLY1(_flags, _base, _param, _v);					\
 } while (0)
 
 static
 DECL_CMD_FUNC(set80211roamrssi, val, d)
 {
 	double v = atof(val);
 	int rssi, flags;
 
 	rssi = (int) (2*v);
 	if (rssi != 2*v)
 		errx(-1, "invalid rssi (must be .5 dBm units)");
 	flags = getmodeflags(val);
 	getroam(s);
 	if (flags == 0) {		/* NB: no flags => current channel */
 		flags = getcurchan(s)->ic_flags;
 		_APPLY1(flags, roamparams, rssi, rssi);
 	} else
 		_APPLY(flags, roamparams, rssi, rssi);
 	callback_register(setroam_cb, &roamparams);
 }
 
 static int
 getrate(const char *val, const char *tag)
 {
 	double v = atof(val);
 	int rate;
 
 	rate = (int) (2*v);
 	if (rate != 2*v)
 		errx(-1, "invalid %s rate (must be .5 Mb/s units)", tag);
 	return rate;		/* NB: returns 2x the specified value */
 }
 
 static
 DECL_CMD_FUNC(set80211roamrate, val, d)
 {
 	int rate, flags;
 
 	rate = getrate(val, "roam");
 	flags = getmodeflags(val);
 	getroam(s);
 	if (flags == 0) {		/* NB: no flags => current channel */
 		flags = getcurchan(s)->ic_flags;
 		_APPLY_RATE1(flags, roamparams, rate, rate);
 	} else
 		_APPLY_RATE(flags, roamparams, rate, rate);
 	callback_register(setroam_cb, &roamparams);
 }
 
 static
 DECL_CMD_FUNC(set80211mcastrate, val, d)
 {
 	int rate, flags;
 
 	rate = getrate(val, "mcast");
 	flags = getmodeflags(val);
 	gettxparams(s);
 	if (flags == 0) {		/* NB: no flags => current channel */
 		flags = getcurchan(s)->ic_flags;
 		_APPLY_RATE1(flags, txparams, mcastrate, rate);
 	} else
 		_APPLY_RATE(flags, txparams, mcastrate, rate);
 	callback_register(settxparams_cb, &txparams);
 }
 
 static
 DECL_CMD_FUNC(set80211mgtrate, val, d)
 {
 	int rate, flags;
 
 	rate = getrate(val, "mgmt");
 	flags = getmodeflags(val);
 	gettxparams(s);
 	if (flags == 0) {		/* NB: no flags => current channel */
 		flags = getcurchan(s)->ic_flags;
 		_APPLY_RATE1(flags, txparams, mgmtrate, rate);
 	} else
 		_APPLY_RATE(flags, txparams, mgmtrate, rate);
 	callback_register(settxparams_cb, &txparams);
 }
 
 static
 DECL_CMD_FUNC(set80211ucastrate, val, d)
 {
 	int flags;
 
 	gettxparams(s);
 	flags = getmodeflags(val);
 	if (isanyarg(val)) {
 		if (flags == 0) {	/* NB: no flags => current channel */
 			flags = getcurchan(s)->ic_flags;
 			_APPLY1(flags, txparams, ucastrate,
 			    IEEE80211_FIXED_RATE_NONE);
 		} else
 			_APPLY(flags, txparams, ucastrate,
 			    IEEE80211_FIXED_RATE_NONE);
 	} else {
 		int rate = getrate(val, "ucast");
 		if (flags == 0) {	/* NB: no flags => current channel */
 			flags = getcurchan(s)->ic_flags;
 			_APPLY_RATE1(flags, txparams, ucastrate, rate);
 		} else
 			_APPLY_RATE(flags, txparams, ucastrate, rate);
 	}
 	callback_register(settxparams_cb, &txparams);
 }
 
 static
 DECL_CMD_FUNC(set80211maxretry, val, d)
 {
 	int v = atoi(val), flags;
 
 	flags = getmodeflags(val);
 	gettxparams(s);
 	if (flags == 0) {		/* NB: no flags => current channel */
 		flags = getcurchan(s)->ic_flags;
 		_APPLY1(flags, txparams, maxretry, v);
 	} else
 		_APPLY(flags, txparams, maxretry, v);
 	callback_register(settxparams_cb, &txparams);
 }
 #undef _APPLY_RATE
 #undef _APPLY
 
 static
 DECL_CMD_FUNC(set80211fragthreshold, val, d)
 {
 	set80211(s, IEEE80211_IOC_FRAGTHRESHOLD,
 		isundefarg(val) ? IEEE80211_FRAG_MAX : atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211bmissthreshold, val, d)
 {
 	set80211(s, IEEE80211_IOC_BMISSTHRESHOLD,
 		isundefarg(val) ? IEEE80211_HWBMISS_MAX : atoi(val), 0, NULL);
 }
 
 static void
 set80211burst(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_BURST, d, 0, NULL);
 }
 
 static void
 set80211doth(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_DOTH, d, 0, NULL);
 }
 
 static void
 set80211dfs(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_DFS, d, 0, NULL);
 }
 
 static void
 set80211shortgi(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_SHORTGI,
 		d ? (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) : 0,
 		0, NULL);
 }
 
 /* XXX 11ac density/size is different */
 static void
 set80211ampdu(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int ampdu;
 
 	if (get80211val(s, IEEE80211_IOC_AMPDU, &ampdu) < 0)
 		errx(-1, "cannot set AMPDU setting");
 	if (d < 0) {
 		d = -d;
 		ampdu &= ~d;
 	} else
 		ampdu |= d;
 	set80211(s, IEEE80211_IOC_AMPDU, ampdu, 0, NULL);
 }
 
 static void
 set80211stbc(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int stbc;
 
 	if (get80211val(s, IEEE80211_IOC_STBC, &stbc) < 0)
 		errx(-1, "cannot set STBC setting");
 	if (d < 0) {
 		d = -d;
 		stbc &= ~d;
 	} else
 		stbc |= d;
 	set80211(s, IEEE80211_IOC_STBC, stbc, 0, NULL);
 }
 
 static void
 set80211ldpc(const char *val, int d, int s, const struct afswtch *rafp)
 {
         int ldpc;
  
         if (get80211val(s, IEEE80211_IOC_LDPC, &ldpc) < 0)
                 errx(-1, "cannot set LDPC setting");
         if (d < 0) {
                 d = -d;
                 ldpc &= ~d;
         } else
                 ldpc |= d;
         set80211(s, IEEE80211_IOC_LDPC, ldpc, 0, NULL);
 }
 
 static void
 set80211uapsd(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_UAPSD, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211ampdulimit, val, d)
 {
 	int v;
 
 	switch (atoi(val)) {
 	case 8:
 	case 8*1024:
 		v = IEEE80211_HTCAP_MAXRXAMPDU_8K;
 		break;
 	case 16:
 	case 16*1024:
 		v = IEEE80211_HTCAP_MAXRXAMPDU_16K;
 		break;
 	case 32:
 	case 32*1024:
 		v = IEEE80211_HTCAP_MAXRXAMPDU_32K;
 		break;
 	case 64:
 	case 64*1024:
 		v = IEEE80211_HTCAP_MAXRXAMPDU_64K;
 		break;
 	default:
 		errx(-1, "invalid A-MPDU limit %s", val);
 	}
 	set80211(s, IEEE80211_IOC_AMPDU_LIMIT, v, 0, NULL);
 }
 
 /* XXX 11ac density/size is different */
 static
 DECL_CMD_FUNC(set80211ampdudensity, val, d)
 {
 	int v;
 
 	if (isanyarg(val) || strcasecmp(val, "na") == 0)
 		v = IEEE80211_HTCAP_MPDUDENSITY_NA;
 	else switch ((int)(atof(val)*4)) {
 	case 0:
 		v = IEEE80211_HTCAP_MPDUDENSITY_NA;
 		break;
 	case 1:
 		v = IEEE80211_HTCAP_MPDUDENSITY_025;
 		break;
 	case 2:
 		v = IEEE80211_HTCAP_MPDUDENSITY_05;
 		break;
 	case 4:
 		v = IEEE80211_HTCAP_MPDUDENSITY_1;
 		break;
 	case 8:
 		v = IEEE80211_HTCAP_MPDUDENSITY_2;
 		break;
 	case 16:
 		v = IEEE80211_HTCAP_MPDUDENSITY_4;
 		break;
 	case 32:
 		v = IEEE80211_HTCAP_MPDUDENSITY_8;
 		break;
 	case 64:
 		v = IEEE80211_HTCAP_MPDUDENSITY_16;
 		break;
 	default:
 		errx(-1, "invalid A-MPDU density %s", val);
 	}
 	set80211(s, IEEE80211_IOC_AMPDU_DENSITY, v, 0, NULL);
 }
 
 static void
 set80211amsdu(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int amsdu;
 
 	if (get80211val(s, IEEE80211_IOC_AMSDU, &amsdu) < 0)
 		err(-1, "cannot get AMSDU setting");
 	if (d < 0) {
 		d = -d;
 		amsdu &= ~d;
 	} else
 		amsdu |= d;
 	set80211(s, IEEE80211_IOC_AMSDU, amsdu, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211amsdulimit, val, d)
 {
 	set80211(s, IEEE80211_IOC_AMSDU_LIMIT, atoi(val), 0, NULL);
 }
 
 static void
 set80211puren(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_PUREN, d, 0, NULL);
 }
 
 static void
 set80211htcompat(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_HTCOMPAT, d, 0, NULL);
 }
 
 static void
 set80211htconf(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_HTCONF, d, 0, NULL);
 	htconf = d;
 }
 
 static void
 set80211dwds(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_DWDS, d, 0, NULL);
 }
 
 static void
 set80211inact(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_INACTIVITY, d, 0, NULL);
 }
 
 static void
 set80211tsn(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_TSN, d, 0, NULL);
 }
 
 static void
 set80211dotd(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_DOTD, d, 0, NULL);
 }
 
 static void
 set80211smps(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_SMPS, d, 0, NULL);
 }
 
 static void
 set80211rifs(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_RIFS, d, 0, NULL);
 }
 
 static void
 set80211vhtconf(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	if (get80211val(s, IEEE80211_IOC_VHTCONF, &vhtconf) < 0)
 		errx(-1, "cannot set VHT setting");
 	printf("%s: vhtconf=0x%08x, d=%d\n", __func__, vhtconf, d);
 	if (d < 0) {
 		d = -d;
 		vhtconf &= ~d;
 	} else
 		vhtconf |= d;
 	printf("%s: vhtconf is now 0x%08x\n", __func__, vhtconf);
 	set80211(s, IEEE80211_IOC_VHTCONF, vhtconf, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211tdmaslot, val, d)
 {
 	set80211(s, IEEE80211_IOC_TDMA_SLOT, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211tdmaslotcnt, val, d)
 {
 	set80211(s, IEEE80211_IOC_TDMA_SLOTCNT, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211tdmaslotlen, val, d)
 {
 	set80211(s, IEEE80211_IOC_TDMA_SLOTLEN, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211tdmabintval, val, d)
 {
 	set80211(s, IEEE80211_IOC_TDMA_BINTERVAL, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211meshttl, val, d)
 {
 	set80211(s, IEEE80211_IOC_MESH_TTL, atoi(val), 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211meshforward, val, d)
 {
 	set80211(s, IEEE80211_IOC_MESH_FWRD, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211meshgate, val, d)
 {
 	set80211(s, IEEE80211_IOC_MESH_GATE, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211meshpeering, val, d)
 {
 	set80211(s, IEEE80211_IOC_MESH_AP, d, 0, NULL);
 }
 
 static
 DECL_CMD_FUNC(set80211meshmetric, val, d)
 {
 	char v[12];
 	
 	memcpy(v, val, sizeof(v));
 	set80211(s, IEEE80211_IOC_MESH_PR_METRIC, 0, 0, v);
 }
 
 static
 DECL_CMD_FUNC(set80211meshpath, val, d)
 {
 	char v[12];
 	
 	memcpy(v, val, sizeof(v));
 	set80211(s, IEEE80211_IOC_MESH_PR_PATH, 0, 0, v);
 }
 
 static int
 regdomain_sort(const void *a, const void *b)
 {
 #define	CHAN_ALL \
 	(IEEE80211_CHAN_ALLTURBO|IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)
 	const struct ieee80211_channel *ca = a;
 	const struct ieee80211_channel *cb = b;
 
 	return ca->ic_freq == cb->ic_freq ?
 	    (ca->ic_flags & CHAN_ALL) - (cb->ic_flags & CHAN_ALL) :
 	    ca->ic_freq - cb->ic_freq;
 #undef CHAN_ALL
 }
 
 static const struct ieee80211_channel *
 chanlookup(const struct ieee80211_channel chans[], int nchans,
 	int freq, int flags)
 {
 	int i;
 
 	flags &= IEEE80211_CHAN_ALLTURBO;
 	for (i = 0; i < nchans; i++) {
 		const struct ieee80211_channel *c = &chans[i];
 		if (c->ic_freq == freq &&
 		    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
 			return c;
 	}
 	return NULL;
 }
 
 static int
-chanfind(const struct ieee80211_channel chans[], int nchans, int flags)
+chanfind(const struct ieee80211_channel chans[], int nchans, unsigned int flags)
 {
-	int i;
-
-	for (i = 0; i < nchans; i++) {
+	for (int i = 0; i < nchans; i++) {
 		const struct ieee80211_channel *c = &chans[i];
 		if ((c->ic_flags & flags) == flags)
 			return 1;
 	}
 	return 0;
 }
 
 /*
  * Check channel compatibility.
  */
 static int
 checkchan(const struct ieee80211req_chaninfo *avail, int freq, int flags)
 {
 	flags &= ~REQ_FLAGS;
 	/*
 	 * Check if exact channel is in the calibration table;
 	 * everything below is to deal with channels that we
 	 * want to include but that are not explicitly listed.
 	 */
 	if (chanlookup(avail->ic_chans, avail->ic_nchans, freq, flags) != NULL)
 		return 1;
 	if (flags & IEEE80211_CHAN_GSM) {
 		/*
 		 * XXX GSM frequency mapping is handled in the kernel
 		 * so we cannot find them in the calibration table;
 		 * just accept the channel and the kernel will reject
 		 * the channel list if it's wrong.
 		 */
 		return 1;
 	}
 	/*
 	 * If this is a 1/2 or 1/4 width channel allow it if a full
 	 * width channel is present for this frequency, and the device
 	 * supports fractional channels on this band.  This is a hack
 	 * that avoids bloating the calibration table; it may be better
 	 * by per-band attributes though (we are effectively calculating
 	 * this attribute by scanning the channel list ourself).
 	 */
 	if ((flags & (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER)) == 0)
 		return 0;
 	if (chanlookup(avail->ic_chans, avail->ic_nchans, freq,
 	    flags &~ (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER)) == NULL)
 		return 0;
 	if (flags & IEEE80211_CHAN_HALF) {
 		return chanfind(avail->ic_chans, avail->ic_nchans,
 		    IEEE80211_CHAN_HALF |
 		       (flags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ)));
 	} else {
 		return chanfind(avail->ic_chans, avail->ic_nchans,
 		    IEEE80211_CHAN_QUARTER |
 			(flags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ)));
 	}
 }
 
 static void
 regdomain_addchans(struct ieee80211req_chaninfo *ci,
 	const netband_head *bands,
 	const struct ieee80211_regdomain *reg,
 	uint32_t chanFlags,
 	const struct ieee80211req_chaninfo *avail)
 {
 	const struct netband *nb;
 	const struct freqband *b;
 	struct ieee80211_channel *c, *prev;
 	int freq, hi_adj, lo_adj, channelSep;
 	uint32_t flags;
 
 	hi_adj = (chanFlags & IEEE80211_CHAN_HT40U) ? -20 : 0;
 	lo_adj = (chanFlags & IEEE80211_CHAN_HT40D) ? 20 : 0;
 	channelSep = (chanFlags & IEEE80211_CHAN_2GHZ) ? 0 : 40;
 
 	LIST_FOREACH(nb, bands, next) {
 		b = nb->band;
 		if (verbose) {
 			printf("%s:", __func__);
 			printb(" chanFlags", chanFlags, IEEE80211_CHAN_BITS);
 			printb(" bandFlags", nb->flags | b->flags,
 			    IEEE80211_CHAN_BITS);
 			putchar('\n');
 		}
 		prev = NULL;
 
 		for (freq = b->freqStart + lo_adj;
 		     freq <= b->freqEnd + hi_adj; freq += b->chanSep) {
 			/*
 			 * Construct flags for the new channel.  We take
 			 * the attributes from the band descriptions except
 			 * for HT40 which is enabled generically (i.e. +/-
 			 * extension channel) in the band description and
 			 * then constrained according by channel separation.
 			 */
 			flags = nb->flags | b->flags;
 
 			/*
 			 * VHT first - HT is a subset.
 			 */
 			if (flags & IEEE80211_CHAN_VHT) {
 				if ((chanFlags & IEEE80211_CHAN_VHT20) &&
 				    (flags & IEEE80211_CHAN_VHT20) == 0) {
 					if (verbose)
 						printf("%u: skip, not a "
 						    "VHT20 channel\n", freq);
 					continue;
 				}
 				if ((chanFlags & IEEE80211_CHAN_VHT40) &&
 				    (flags & IEEE80211_CHAN_VHT40) == 0) {
 					if (verbose)
 						printf("%u: skip, not a "
 						    "VHT40 channel\n", freq);
 					continue;
 				}
 				if ((chanFlags & IEEE80211_CHAN_VHT80) &&
 				    (flags & IEEE80211_CHAN_VHT80) == 0) {
 					if (verbose)
 						printf("%u: skip, not a "
 						    "VHT80 channel\n", freq);
 					continue;
 				}
 				if ((chanFlags & IEEE80211_CHAN_VHT160) &&
 				    (flags & IEEE80211_CHAN_VHT160) == 0) {
 					if (verbose)
 						printf("%u: skip, not a "
 						    "VHT160 channel\n", freq);
 					continue;
 				}
 				if ((chanFlags & IEEE80211_CHAN_VHT80P80) &&
 				    (flags & IEEE80211_CHAN_VHT80P80) == 0) {
 					if (verbose)
 						printf("%u: skip, not a "
 						    "VHT80+80 channel\n", freq);
 					continue;
 				}
 				flags &= ~IEEE80211_CHAN_VHT;
 				flags |= chanFlags & IEEE80211_CHAN_VHT;
 			}
 
 			/* Now, constrain HT */
 			if (flags & IEEE80211_CHAN_HT) {
 				/*
 				 * HT channels are generated specially; we're
 				 * called to add HT20, HT40+, and HT40- chan's
 				 * so we need to expand only band specs for
 				 * the HT channel type being added.
 				 */
 				if ((chanFlags & IEEE80211_CHAN_HT20) &&
 				    (flags & IEEE80211_CHAN_HT20) == 0) {
 					if (verbose)
 						printf("%u: skip, not an "
 						    "HT20 channel\n", freq);
 					continue;
 				}
 				if ((chanFlags & IEEE80211_CHAN_HT40) &&
 				    (flags & IEEE80211_CHAN_HT40) == 0) {
 					if (verbose)
 						printf("%u: skip, not an "
 						    "HT40 channel\n", freq);
 					continue;
 				}
 				/* NB: HT attribute comes from caller */
 				flags &= ~IEEE80211_CHAN_HT;
 				flags |= chanFlags & IEEE80211_CHAN_HT;
 			}
 			/*
 			 * Check if device can operate on this frequency.
 			 */
 			if (!checkchan(avail, freq, flags)) {
 				if (verbose) {
 					printf("%u: skip, ", freq);
 					printb("flags", flags,
 					    IEEE80211_CHAN_BITS);
 					printf(" not available\n");
 				}
 				continue;
 			}
 			if ((flags & REQ_ECM) && !reg->ecm) {
 				if (verbose)
 					printf("%u: skip, ECM channel\n", freq);
 				continue;
 			}
 			if ((flags & REQ_INDOOR) && reg->location == 'O') {
 				if (verbose)
 					printf("%u: skip, indoor channel\n",
 					    freq);
 				continue;
 			}
 			if ((flags & REQ_OUTDOOR) && reg->location == 'I') {
 				if (verbose)
 					printf("%u: skip, outdoor channel\n",
 					    freq);
 				continue;
 			}
 			if ((flags & IEEE80211_CHAN_HT40) &&
 			    prev != NULL && (freq - prev->ic_freq) < channelSep) {
 				if (verbose)
 					printf("%u: skip, only %u channel "
 					    "separation, need %d\n", freq, 
 					    freq - prev->ic_freq, channelSep);
 				continue;
 			}
 			if (ci->ic_nchans == IEEE80211_CHAN_MAX) {
 				if (verbose)
 					printf("%u: skip, channel table full\n",
 					    freq);
 				break;
 			}
 			c = &ci->ic_chans[ci->ic_nchans++];
 			memset(c, 0, sizeof(*c));
 			c->ic_freq = freq;
 			c->ic_flags = flags;
 		if (c->ic_flags & IEEE80211_CHAN_DFS)
 				c->ic_maxregpower = nb->maxPowerDFS;
 			else
 				c->ic_maxregpower = nb->maxPower;
 			if (verbose) {
 				printf("[%3d] add freq %u ",
 				    ci->ic_nchans-1, c->ic_freq);
 				printb("flags", c->ic_flags, IEEE80211_CHAN_BITS);
 				printf(" power %u\n", c->ic_maxregpower);
 			}
 			/* NB: kernel fills in other fields */
 			prev = c;
 		}
 	}
 }
 
 static void
 regdomain_makechannels(
 	struct ieee80211_regdomain_req *req,
 	const struct ieee80211_devcaps_req *dc)
 {
 	struct regdata *rdp = getregdata();
 	const struct country *cc;
 	const struct ieee80211_regdomain *reg = &req->rd;
 	struct ieee80211req_chaninfo *ci = &req->chaninfo;
 	const struct regdomain *rd;
 
 	/*
 	 * Locate construction table for new channel list.  We treat
 	 * the regdomain/SKU as definitive so a country can be in
 	 * multiple with different properties (e.g. US in FCC+FCC3).
 	 * If no regdomain is specified then we fallback on the country
 	 * code to find the associated regdomain since countries always
 	 * belong to at least one regdomain.
 	 */
 	if (reg->regdomain == 0) {
 		cc = lib80211_country_findbycc(rdp, reg->country);
 		if (cc == NULL)
 			errx(1, "internal error, country %d not found",
 			    reg->country);
 		rd = cc->rd;
 	} else
 		rd = lib80211_regdomain_findbysku(rdp, reg->regdomain);
 	if (rd == NULL)
 		errx(1, "internal error, regdomain %d not found",
 			    reg->regdomain);
 	if (rd->sku != SKU_DEBUG) {
 		/*
 		 * regdomain_addchans incrememnts the channel count for
 		 * each channel it adds so initialize ic_nchans to zero.
 		 * Note that we know we have enough space to hold all possible
 		 * channels because the devcaps list size was used to
 		 * allocate our request.
 		 */
 		ci->ic_nchans = 0;
 		if (!LIST_EMPTY(&rd->bands_11b))
 			regdomain_addchans(ci, &rd->bands_11b, reg,
 			    IEEE80211_CHAN_B, &dc->dc_chaninfo);
 		if (!LIST_EMPTY(&rd->bands_11g))
 			regdomain_addchans(ci, &rd->bands_11g, reg,
 			    IEEE80211_CHAN_G, &dc->dc_chaninfo);
 		if (!LIST_EMPTY(&rd->bands_11a))
 			regdomain_addchans(ci, &rd->bands_11a, reg,
 			    IEEE80211_CHAN_A, &dc->dc_chaninfo);
 		if (!LIST_EMPTY(&rd->bands_11na) && dc->dc_htcaps != 0) {
 			regdomain_addchans(ci, &rd->bands_11na, reg,
 			    IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,
 			    &dc->dc_chaninfo);
 			if (dc->dc_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
 				regdomain_addchans(ci, &rd->bands_11na, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U,
 				    &dc->dc_chaninfo);
 				regdomain_addchans(ci, &rd->bands_11na, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D,
 				    &dc->dc_chaninfo);
 			}
 		}
 		if (!LIST_EMPTY(&rd->bands_11ac) && dc->dc_vhtcaps != 0) {
 			regdomain_addchans(ci, &rd->bands_11ac, reg,
 			    IEEE80211_CHAN_A | IEEE80211_CHAN_HT20 |
 			    IEEE80211_CHAN_VHT20,
 			    &dc->dc_chaninfo);
 
 			/* VHT40 is a function of HT40.. */
 			if (dc->dc_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
 				    IEEE80211_CHAN_VHT40U,
 				    &dc->dc_chaninfo);
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
 				    IEEE80211_CHAN_VHT40D,
 				    &dc->dc_chaninfo);
 			}
 
 			/* VHT80 is mandatory (and so should be VHT40 above). */
 			if (1) {
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
 				    IEEE80211_CHAN_VHT80,
 				    &dc->dc_chaninfo);
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
 				    IEEE80211_CHAN_VHT80,
 				    &dc->dc_chaninfo);
 			}
 
 			/* VHT160 */
 			if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(
 			    dc->dc_vhtcaps)) {
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
 				    IEEE80211_CHAN_VHT160,
 				    &dc->dc_chaninfo);
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
 				    IEEE80211_CHAN_VHT160,
 				    &dc->dc_chaninfo);
 			}
 
 			/* VHT80P80 */
 			if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(
 			    dc->dc_vhtcaps)) {
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
 				    IEEE80211_CHAN_VHT80P80,
 				    &dc->dc_chaninfo);
 				regdomain_addchans(ci, &rd->bands_11ac, reg,
 				    IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
 				    IEEE80211_CHAN_VHT80P80,
 				    &dc->dc_chaninfo);
 			}
 		}
 
 		if (!LIST_EMPTY(&rd->bands_11ng) && dc->dc_htcaps != 0) {
 			regdomain_addchans(ci, &rd->bands_11ng, reg,
 			    IEEE80211_CHAN_G | IEEE80211_CHAN_HT20,
 			    &dc->dc_chaninfo);
 			if (dc->dc_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
 				regdomain_addchans(ci, &rd->bands_11ng, reg,
 				    IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U,
 				    &dc->dc_chaninfo);
 				regdomain_addchans(ci, &rd->bands_11ng, reg,
 				    IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D,
 				    &dc->dc_chaninfo);
 			}
 		}
 		qsort(ci->ic_chans, ci->ic_nchans, sizeof(ci->ic_chans[0]),
 		    regdomain_sort);
 	} else
 		memcpy(ci, &dc->dc_chaninfo,
 		    IEEE80211_CHANINFO_SPACE(&dc->dc_chaninfo));
 }
 
 static void
 list_countries(void)
 {
 	struct regdata *rdp = getregdata();
 	const struct country *cp;
 	const struct regdomain *dp;
 	int i;
 
 	i = 0;
 	printf("\nCountry codes:\n");
 	LIST_FOREACH(cp, &rdp->countries, next) {
 		printf("%2s %-15.15s%s", cp->isoname,
 		    cp->name, ((i+1)%4) == 0 ? "\n" : " ");
 		i++;
 	}
 	i = 0;
 	printf("\nRegulatory domains:\n");
 	LIST_FOREACH(dp, &rdp->domains, next) {
 		printf("%-15.15s%s", dp->name, ((i+1)%4) == 0 ? "\n" : " ");
 		i++;
 	}
 	printf("\n");
 }
 
 static void
 defaultcountry(const struct regdomain *rd)
 {
 	struct regdata *rdp = getregdata();
 	const struct country *cc;
 
 	cc = lib80211_country_findbycc(rdp, rd->cc->code);
 	if (cc == NULL)
 		errx(1, "internal error, ISO country code %d not "
 		    "defined for regdomain %s", rd->cc->code, rd->name);
 	regdomain.country = cc->code;
 	regdomain.isocc[0] = cc->isoname[0];
 	regdomain.isocc[1] = cc->isoname[1];
 }
 
 static
 DECL_CMD_FUNC(set80211regdomain, val, d)
 {
 	struct regdata *rdp = getregdata();
 	const struct regdomain *rd;
 
 	rd = lib80211_regdomain_findbyname(rdp, val);
 	if (rd == NULL) {
 		char *eptr;
 		long sku = strtol(val, &eptr, 0);
 
 		if (eptr != val)
 			rd = lib80211_regdomain_findbysku(rdp, sku);
 		if (eptr == val || rd == NULL)
 			errx(1, "unknown regdomain %s", val);
 	}
 	getregdomain(s);
 	regdomain.regdomain = rd->sku;
 	if (regdomain.country == 0 && rd->cc != NULL) {
 		/*
 		 * No country code setup and there's a default
 		 * one for this regdomain fill it in.
 		 */
 		defaultcountry(rd);
 	}
 	callback_register(setregdomain_cb, &regdomain);
 }
 
 static
 DECL_CMD_FUNC(set80211country, val, d)
 {
 	struct regdata *rdp = getregdata();
 	const struct country *cc;
 
 	cc = lib80211_country_findbyname(rdp, val);
 	if (cc == NULL) {
 		char *eptr;
 		long code = strtol(val, &eptr, 0);
 
 		if (eptr != val)
 			cc = lib80211_country_findbycc(rdp, code);
 		if (eptr == val || cc == NULL)
 			errx(1, "unknown ISO country code %s", val);
 	}
 	getregdomain(s);
 	regdomain.regdomain = cc->rd->sku;
 	regdomain.country = cc->code;
 	regdomain.isocc[0] = cc->isoname[0];
 	regdomain.isocc[1] = cc->isoname[1];
 	callback_register(setregdomain_cb, &regdomain);
 }
 
 static void
 set80211location(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	getregdomain(s);
 	regdomain.location = d;
 	callback_register(setregdomain_cb, &regdomain);
 }
 
 static void
 set80211ecm(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	getregdomain(s);
 	regdomain.ecm = d;
 	callback_register(setregdomain_cb, &regdomain);
 }
 
 static void
 LINE_INIT(char c)
 {
 	spacer = c;
 	if (c == '\t')
 		col = 8;
 	else
 		col = 1;
 }
 
 static void
 LINE_BREAK(void)
 {
 	if (spacer != '\t') {
 		printf("\n");
 		spacer = '\t';
 	}
 	col = 8;		/* 8-col tab */
 }
 
 static void
 LINE_CHECK(const char *fmt, ...)
 {
 	char buf[80];
 	va_list ap;
 	int n;
 
 	va_start(ap, fmt);
 	n = vsnprintf(buf+1, sizeof(buf)-1, fmt, ap);
 	va_end(ap);
 	col += 1+n;
 	if (col > MAXCOL) {
 		LINE_BREAK();
 		col += n;
 	}
 	buf[0] = spacer;
 	printf("%s", buf);
 	spacer = ' ';
 }
 
 static int
 getmaxrate(const uint8_t rates[15], uint8_t nrates)
 {
 	int i, maxrate = -1;
 
 	for (i = 0; i < nrates; i++) {
 		int rate = rates[i] & IEEE80211_RATE_VAL;
 		if (rate > maxrate)
 			maxrate = rate;
 	}
 	return maxrate / 2;
 }
 
 static const char *
 getcaps(int capinfo)
 {
 	static char capstring[32];
 	char *cp = capstring;
 
 	if (capinfo & IEEE80211_CAPINFO_ESS)
 		*cp++ = 'E';
 	if (capinfo & IEEE80211_CAPINFO_IBSS)
 		*cp++ = 'I';
 	if (capinfo & IEEE80211_CAPINFO_CF_POLLABLE)
 		*cp++ = 'c';
 	if (capinfo & IEEE80211_CAPINFO_CF_POLLREQ)
 		*cp++ = 'C';
 	if (capinfo & IEEE80211_CAPINFO_PRIVACY)
 		*cp++ = 'P';
 	if (capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
 		*cp++ = 'S';
 	if (capinfo & IEEE80211_CAPINFO_PBCC)
 		*cp++ = 'B';
 	if (capinfo & IEEE80211_CAPINFO_CHNL_AGILITY)
 		*cp++ = 'A';
 	if (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)
 		*cp++ = 's';
 	if (capinfo & IEEE80211_CAPINFO_RSN)
 		*cp++ = 'R';
 	if (capinfo & IEEE80211_CAPINFO_DSSSOFDM)
 		*cp++ = 'D';
 	*cp = '\0';
 	return capstring;
 }
 
 static const char *
 getflags(int flags)
 {
 	static char flagstring[32];
 	char *cp = flagstring;
 
 	if (flags & IEEE80211_NODE_AUTH)
 		*cp++ = 'A';
 	if (flags & IEEE80211_NODE_QOS)
 		*cp++ = 'Q';
 	if (flags & IEEE80211_NODE_ERP)
 		*cp++ = 'E';
 	if (flags & IEEE80211_NODE_PWR_MGT)
 		*cp++ = 'P';
 	if (flags & IEEE80211_NODE_HT) {
 		*cp++ = 'H';
 		if (flags & IEEE80211_NODE_HTCOMPAT)
 			*cp++ = '+';
 	}
 	if (flags & IEEE80211_NODE_VHT)
 		*cp++ = 'V';
 	if (flags & IEEE80211_NODE_WPS)
 		*cp++ = 'W';
 	if (flags & IEEE80211_NODE_TSN)
 		*cp++ = 'N';
 	if (flags & IEEE80211_NODE_AMPDU_TX)
 		*cp++ = 'T';
 	if (flags & IEEE80211_NODE_AMPDU_RX)
 		*cp++ = 'R';
 	if (flags & IEEE80211_NODE_MIMO_PS) {
 		*cp++ = 'M';
 		if (flags & IEEE80211_NODE_MIMO_RTS)
 			*cp++ = '+';
 	}
 	if (flags & IEEE80211_NODE_RIFS)
 		*cp++ = 'I';
 	if (flags & IEEE80211_NODE_SGI40) {
 		*cp++ = 'S';
 		if (flags & IEEE80211_NODE_SGI20)
 			*cp++ = '+';
 	} else if (flags & IEEE80211_NODE_SGI20)
 		*cp++ = 's';
 	if (flags & IEEE80211_NODE_AMSDU_TX)
 		*cp++ = 't';
 	if (flags & IEEE80211_NODE_AMSDU_RX)
 		*cp++ = 'r';
 	if (flags & IEEE80211_NODE_UAPSD)
 		*cp++ = 'U';
 	if (flags & IEEE80211_NODE_LDPC)
 		*cp++ = 'L';
 	*cp = '\0';
 	return flagstring;
 }
 
 static void
-printie(const char* tag, const uint8_t *ie, size_t ielen, int maxlen)
+printie(const char* tag, const uint8_t *ie, size_t ielen, unsigned int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		maxlen -= strlen(tag)+2;
 		if (2*ielen > maxlen)
 			maxlen--;
 		printf("<");
 		for (; ielen > 0; ie++, ielen--) {
 			if (maxlen-- <= 0)
 				break;
 			printf("%02x", *ie);
 		}
 		if (ielen != 0)
 			printf("-");
 		printf(">");
 	}
 }
 
 #define LE_READ_2(p)					\
 	((u_int16_t)					\
 	 ((((const u_int8_t *)(p))[0]      ) |		\
 	  (((const u_int8_t *)(p))[1] <<  8)))
 #define LE_READ_4(p)					\
 	((u_int32_t)					\
 	 ((((const u_int8_t *)(p))[0]      ) |		\
 	  (((const u_int8_t *)(p))[1] <<  8) |		\
 	  (((const u_int8_t *)(p))[2] << 16) |		\
 	  (((const u_int8_t *)(p))[3] << 24)))
 
 /*
  * NB: The decoding routines assume a properly formatted ie
  *     which should be safe as the kernel only retains them
  *     if they parse ok.
  */
 
 static void
 printwmeparam(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	static const char *acnames[] = { "BE", "BK", "VO", "VI" };
 	const struct ieee80211_wme_param *wme =
 	    (const struct ieee80211_wme_param *) ie;
 	int i;
 
 	printf("%s", tag);
 	if (!verbose)
 		return;
 	printf("<qosinfo 0x%x", wme->param_qosInfo);
 	ie += offsetof(struct ieee80211_wme_param, params_acParams);
 	for (i = 0; i < WME_NUM_AC; i++) {
 		const struct ieee80211_wme_acparams *ac =
 		    &wme->params_acParams[i];
 
 		printf(" %s[%saifsn %u cwmin %u cwmax %u txop %u]", acnames[i],
 		    _IEEE80211_MASKSHIFT(ac->acp_aci_aifsn, WME_PARAM_ACM) ?
 			"acm " : "",
 		    _IEEE80211_MASKSHIFT(ac->acp_aci_aifsn, WME_PARAM_AIFSN),
 		    _IEEE80211_MASKSHIFT(ac->acp_logcwminmax,
 			WME_PARAM_LOGCWMIN),
 		    _IEEE80211_MASKSHIFT(ac->acp_logcwminmax,
 			WME_PARAM_LOGCWMAX),
 		    LE_READ_2(&ac->acp_txop));
 	}
 	printf(">");
 }
 
 static void
 printwmeinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_wme_info *wme =
 		    (const struct ieee80211_wme_info *) ie;
 		printf("<version 0x%x info 0x%x>",
 		    wme->wme_version, wme->wme_info);
 	}
 }
 
 static void
 printvhtcap(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_ie_vhtcap *vhtcap =
 		    (const struct ieee80211_ie_vhtcap *) ie;
 		uint32_t vhtcap_info = LE_READ_4(&vhtcap->vht_cap_info);
 
 		printf("<cap 0x%08x", vhtcap_info);
 		printf(" rx_mcs_map 0x%x",
 		    LE_READ_2(&vhtcap->supp_mcs.rx_mcs_map));
 		printf(" rx_highest %d",
 		    LE_READ_2(&vhtcap->supp_mcs.rx_highest) & 0x1fff);
 		printf(" tx_mcs_map 0x%x",
 		    LE_READ_2(&vhtcap->supp_mcs.tx_mcs_map));
 		printf(" tx_highest %d",
 		    LE_READ_2(&vhtcap->supp_mcs.tx_highest) & 0x1fff);
 
 		printf(">");
 	}
 }
 
 static void
 printvhtinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_ie_vht_operation *vhtinfo =
 		    (const struct ieee80211_ie_vht_operation *) ie;
 
 		printf("<chw %d freq1_idx %d freq2_idx %d basic_mcs_set 0x%04x>",
 		    vhtinfo->chan_width,
 		    vhtinfo->center_freq_seg1_idx,
 		    vhtinfo->center_freq_seg2_idx,
 		    LE_READ_2(&vhtinfo->basic_mcs_set));
 	}
 }
 
 static void
 printvhtpwrenv(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	static const char *txpwrmap[] = {
 		"20",
 		"40",
 		"80",
 		"160",
 	};
 	if (verbose) {
 		const struct ieee80211_ie_vht_txpwrenv *vhtpwr =
 		    (const struct ieee80211_ie_vht_txpwrenv *) ie;
-		int i, n;
+		size_t i, n;
 		const char *sep = "";
 
 		/* Get count; trim at ielen */
 		n = (vhtpwr->tx_info &
 		    IEEE80211_VHT_TXPWRENV_INFO_COUNT_MASK) + 1;
 		/* Trim at ielen */
-		if (n > ielen - 3)
+		if (n + 3 > ielen)
 			n = ielen - 3;
 		printf("<tx_info 0x%02x pwr:[", vhtpwr->tx_info);
 		for (i = 0; i < n; i++) {
 			printf("%s%s:%.2f", sep, txpwrmap[i],
 			    ((float) ((int8_t) ie[i+3])) / 2.0);
 			sep = " ";
 		}
 
 		printf("]>");
 	}
 }
 
 static void
 printhtcap(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_ie_htcap *htcap =
 		    (const struct ieee80211_ie_htcap *) ie;
 		const char *sep;
 		int i, j;
 
 		printf("<cap 0x%x param 0x%x",
 		    LE_READ_2(&htcap->hc_cap), htcap->hc_param);
 		printf(" mcsset[");
 		sep = "";
 		for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++)
 			if (isset(htcap->hc_mcsset, i)) {
 				for (j = i+1; j < IEEE80211_HTRATE_MAXSIZE; j++)
 					if (isclr(htcap->hc_mcsset, j))
 						break;
 				j--;
 				if (i == j)
 					printf("%s%u", sep, i);
 				else
 					printf("%s%u-%u", sep, i, j);
 				i += j-i;
 				sep = ",";
 			}
 		printf("] extcap 0x%x txbf 0x%x antenna 0x%x>",
 		    LE_READ_2(&htcap->hc_extcap),
 		    LE_READ_4(&htcap->hc_txbf),
 		    htcap->hc_antenna);
 	}
 }
 
 static void
 printhtinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_ie_htinfo *htinfo =
 		    (const struct ieee80211_ie_htinfo *) ie;
 		const char *sep;
 		int i, j;
 
 		printf("<ctl %u, %x,%x,%x,%x", htinfo->hi_ctrlchannel,
 		    htinfo->hi_byte1, htinfo->hi_byte2, htinfo->hi_byte3,
 		    LE_READ_2(&htinfo->hi_byte45));
 		printf(" basicmcs[");
 		sep = "";
 		for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++)
 			if (isset(htinfo->hi_basicmcsset, i)) {
 				for (j = i+1; j < IEEE80211_HTRATE_MAXSIZE; j++)
 					if (isclr(htinfo->hi_basicmcsset, j))
 						break;
 				j--;
 				if (i == j)
 					printf("%s%u", sep, i);
 				else
 					printf("%s%u-%u", sep, i, j);
 				i += j-i;
 				sep = ",";
 			}
 		printf("]>");
 	}
 }
 
 static void
 printathie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_ath_ie *ath =
 			(const struct ieee80211_ath_ie *)ie;
 
 		printf("<");
 		if (ath->ath_capability & ATHEROS_CAP_TURBO_PRIME)
 			printf("DTURBO,");
 		if (ath->ath_capability & ATHEROS_CAP_COMPRESSION)
 			printf("COMP,");
 		if (ath->ath_capability & ATHEROS_CAP_FAST_FRAME)
 			printf("FF,");
 		if (ath->ath_capability & ATHEROS_CAP_XR)
 			printf("XR,");
 		if (ath->ath_capability & ATHEROS_CAP_AR)
 			printf("AR,");
 		if (ath->ath_capability & ATHEROS_CAP_BURST)
 			printf("BURST,");
 		if (ath->ath_capability & ATHEROS_CAP_WME)
 			printf("WME,");
 		if (ath->ath_capability & ATHEROS_CAP_BOOST)
 			printf("BOOST,");
 		printf("0x%x>", LE_READ_2(ath->ath_defkeyix));
 	}
 }
 
 
 static void
 printmeshconf(const char *tag, const uint8_t *ie, size_t ielen, int maxlen)
 {
 
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_meshconf_ie *mconf =
 			(const struct ieee80211_meshconf_ie *)ie;
 		printf("<PATH:");
 		if (mconf->conf_pselid == IEEE80211_MESHCONF_PATH_HWMP)
 			printf("HWMP");
 		else
 			printf("UNKNOWN");
 		printf(" LINK:");
 		if (mconf->conf_pmetid == IEEE80211_MESHCONF_METRIC_AIRTIME)
 			printf("AIRTIME");
 		else
 			printf("UNKNOWN");
 		printf(" CONGESTION:");
 		if (mconf->conf_ccid == IEEE80211_MESHCONF_CC_DISABLED)
 			printf("DISABLED");
 		else
 			printf("UNKNOWN");
 		printf(" SYNC:");
 		if (mconf->conf_syncid == IEEE80211_MESHCONF_SYNC_NEIGHOFF)
 			printf("NEIGHOFF");
 		else
 			printf("UNKNOWN");
 		printf(" AUTH:");
 		if (mconf->conf_authid == IEEE80211_MESHCONF_AUTH_DISABLED)
 			printf("DISABLED");
 		else
 			printf("UNKNOWN");
 		printf(" FORM:0x%x CAPS:0x%x>", mconf->conf_form,
 		    mconf->conf_cap);
 	}
 }
 
 static void
 printbssload(const char *tag, const uint8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_bss_load_ie *bssload =
 		    (const struct ieee80211_bss_load_ie *) ie;
 		printf("<sta count %d, chan load %d, aac %d>",
 		    LE_READ_2(&bssload->sta_count),
 		    bssload->chan_load,
 		    bssload->aac);
 	}
 }
 
 static void
 printapchanrep(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const struct ieee80211_ap_chan_report_ie *ap =
 		    (const struct ieee80211_ap_chan_report_ie *) ie;
 		const char *sep = "";
-		int i;
 
 		printf("<class %u, chan:[", ap->i_class);
 
-		for (i = 3; i < ielen; i++) {
+		for (size_t i = 3; i < ielen; i++) {
 			printf("%s%u", sep, ie[i]);
 			sep = ",";
 		}
 		printf("]>");
 	}
 }
 
 static const char *
 wpa_cipher(const u_int8_t *sel)
 {
 #define	WPA_SEL(x)	(((x)<<24)|WPA_OUI)
 	u_int32_t w = LE_READ_4(sel);
 
 	switch (w) {
 	case WPA_SEL(WPA_CSE_NULL):
 		return "NONE";
 	case WPA_SEL(WPA_CSE_WEP40):
 		return "WEP40";
 	case WPA_SEL(WPA_CSE_WEP104):
 		return "WEP104";
 	case WPA_SEL(WPA_CSE_TKIP):
 		return "TKIP";
 	case WPA_SEL(WPA_CSE_CCMP):
 		return "AES-CCMP";
 	}
 	return "?";		/* NB: so 1<< is discarded */
 #undef WPA_SEL
 }
 
 static const char *
 wpa_keymgmt(const u_int8_t *sel)
 {
 #define	WPA_SEL(x)	(((x)<<24)|WPA_OUI)
 	u_int32_t w = LE_READ_4(sel);
 
 	switch (w) {
 	case WPA_SEL(WPA_ASE_8021X_UNSPEC):
 		return "8021X-UNSPEC";
 	case WPA_SEL(WPA_ASE_8021X_PSK):
 		return "8021X-PSK";
 	case WPA_SEL(WPA_ASE_NONE):
 		return "NONE";
 	}
 	return "?";
 #undef WPA_SEL
 }
 
 static void
 printwpaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	u_int8_t len = ie[1];
 
 	printf("%s", tag);
 	if (verbose) {
 		const char *sep;
 		int n;
 
 		ie += 6, len -= 4;		/* NB: len is payload only */
 
 		printf("<v%u", LE_READ_2(ie));
 		ie += 2, len -= 2;
 
 		printf(" mc:%s", wpa_cipher(ie));
 		ie += 4, len -= 4;
 
 		/* unicast ciphers */
 		n = LE_READ_2(ie);
 		ie += 2, len -= 2;
 		sep = " uc:";
 		for (; n > 0; n--) {
 			printf("%s%s", sep, wpa_cipher(ie));
 			ie += 4, len -= 4;
 			sep = "+";
 		}
 
 		/* key management algorithms */
 		n = LE_READ_2(ie);
 		ie += 2, len -= 2;
 		sep = " km:";
 		for (; n > 0; n--) {
 			printf("%s%s", sep, wpa_keymgmt(ie));
 			ie += 4, len -= 4;
 			sep = "+";
 		}
 
 		if (len > 2)		/* optional capabilities */
 			printf(", caps 0x%x", LE_READ_2(ie));
 		printf(">");
 	}
 }
 
 static const char *
 rsn_cipher(const u_int8_t *sel)
 {
 #define	RSN_SEL(x)	(((x)<<24)|RSN_OUI)
 	u_int32_t w = LE_READ_4(sel);
 
 	switch (w) {
 	case RSN_SEL(RSN_CSE_NULL):
 		return "NONE";
 	case RSN_SEL(RSN_CSE_WEP40):
 		return "WEP40";
 	case RSN_SEL(RSN_CSE_WEP104):
 		return "WEP104";
 	case RSN_SEL(RSN_CSE_TKIP):
 		return "TKIP";
 	case RSN_SEL(RSN_CSE_CCMP):
 		return "AES-CCMP";
 	case RSN_SEL(RSN_CSE_WRAP):
 		return "AES-OCB";
 	}
 	return "?";
 #undef WPA_SEL
 }
 
 static const char *
 rsn_keymgmt(const u_int8_t *sel)
 {
 #define	RSN_SEL(x)	(((x)<<24)|RSN_OUI)
 	u_int32_t w = LE_READ_4(sel);
 
 	switch (w) {
 	case RSN_SEL(RSN_ASE_8021X_UNSPEC):
 		return "8021X-UNSPEC";
 	case RSN_SEL(RSN_ASE_8021X_PSK):
 		return "8021X-PSK";
 	case RSN_SEL(RSN_ASE_NONE):
 		return "NONE";
 	}
 	return "?";
 #undef RSN_SEL
 }
 
 static void
 printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose) {
 		const char *sep;
 		int n;
 
 		ie += 2, ielen -= 2;
 
 		printf("<v%u", LE_READ_2(ie));
 		ie += 2, ielen -= 2;
 
 		printf(" mc:%s", rsn_cipher(ie));
 		ie += 4, ielen -= 4;
 
 		/* unicast ciphers */
 		n = LE_READ_2(ie);
 		ie += 2, ielen -= 2;
 		sep = " uc:";
 		for (; n > 0; n--) {
 			printf("%s%s", sep, rsn_cipher(ie));
 			ie += 4, ielen -= 4;
 			sep = "+";
 		}
 
 		/* key management algorithms */
 		n = LE_READ_2(ie);
 		ie += 2, ielen -= 2;
 		sep = " km:";
 		for (; n > 0; n--) {
 			printf("%s%s", sep, rsn_keymgmt(ie));
 			ie += 4, ielen -= 4;
 			sep = "+";
 		}
 
 		if (ielen > 2)		/* optional capabilities */
 			printf(", caps 0x%x", LE_READ_2(ie));
 		/* XXXPMKID */
 		printf(">");
 	}
 }
 
 #define BE_READ_2(p)					\
 	((u_int16_t)					\
 	 ((((const u_int8_t *)(p))[1]      ) |		\
 	  (((const u_int8_t *)(p))[0] <<  8)))
 
 static void
 printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	u_int8_t len = ie[1];
 
 	printf("%s", tag);
 	if (verbose) {
 		static const char *dev_pass_id[] = {
 			"D",	/* Default (PIN) */
 			"U",	/* User-specified */
 			"M",	/* Machine-specified */
 			"K",	/* Rekey */
 			"P",	/* PushButton */
 			"R"	/* Registrar-specified */
 		};
 		int n;
 		int f;
 
 		ie +=6, len -= 4;		/* NB: len is payload only */
 
 		/* WPS IE in Beacon and Probe Resp frames have different fields */
 		printf("<");
 		while (len) {
 			uint16_t tlv_type = BE_READ_2(ie);
 			uint16_t tlv_len  = BE_READ_2(ie + 2);
 			uint16_t cfg_mthd;
 
 			/* some devices broadcast invalid WPS frames */
 			if (tlv_len > len) {
 				printf("bad frame length tlv_type=0x%02x "
 				    "tlv_len=%d len=%d", tlv_type, tlv_len,
 				    len);
 				break;
 			}
 
 			ie += 4, len -= 4;
 
 			switch (tlv_type) {
 			case IEEE80211_WPS_ATTR_VERSION:
 				printf("v:%d.%d", *ie >> 4, *ie & 0xf);
 				break;
 			case IEEE80211_WPS_ATTR_AP_SETUP_LOCKED:
 				printf(" ap_setup:%s", *ie ? "locked" :
 				    "unlocked");
 				break;
 			case IEEE80211_WPS_ATTR_CONFIG_METHODS:
 			case IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
 				if (tlv_type == IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS)
 					printf(" sel_reg_cfg_mthd:");
 				else
 					printf(" cfg_mthd:" );
 				cfg_mthd = BE_READ_2(ie);
 				f = 0;
 				for (n = 15; n >= 0; n--) {
 					if (f) {
 						printf(",");
 						f = 0;
 					}
 					switch (cfg_mthd & (1 << n)) {
 					case 0:
 						break;
 					case IEEE80211_WPS_CONFIG_USBA:
 						printf("usba");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_ETHERNET:
 						printf("ethernet");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_LABEL:
 						printf("label");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_DISPLAY:
 						if (!(cfg_mthd &
 						    (IEEE80211_WPS_CONFIG_VIRT_DISPLAY |
 						    IEEE80211_WPS_CONFIG_PHY_DISPLAY)))
 						    {
 							printf("display");
 							f++;
 						}
 						break;
 					case IEEE80211_WPS_CONFIG_EXT_NFC_TOKEN:
 						printf("ext_nfc_tokenk");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_INT_NFC_TOKEN:
 						printf("int_nfc_token");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_NFC_INTERFACE:
 						printf("nfc_interface");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_PUSHBUTTON:
 						if (!(cfg_mthd &
 						    (IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON |
 						    IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON))) {
 							printf("push_button");
 							f++;
 						}
 						break;
 					case IEEE80211_WPS_CONFIG_KEYPAD:
 						printf("keypad");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON:
 						printf("virtual_push_button");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON:
 						printf("physical_push_button");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_P2PS:
 						printf("p2ps");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_VIRT_DISPLAY:
 						printf("virtual_display");
 						f++;
 						break;
 					case IEEE80211_WPS_CONFIG_PHY_DISPLAY:
 						printf("physical_display");
 						f++;
 						break;
 					default:
 						printf("unknown_wps_config<%04x>",
 						    cfg_mthd & (1 << n));
 						f++;
 						break;
 					}
 				}
 				break;
 			case IEEE80211_WPS_ATTR_DEV_NAME:
 				printf(" device_name:<%.*s>", tlv_len, ie);
 				break;
 			case IEEE80211_WPS_ATTR_DEV_PASSWORD_ID:
 				n = LE_READ_2(ie);
-				if (n < nitems(dev_pass_id))
+				if (n < (int)nitems(dev_pass_id))
 					printf(" dpi:%s", dev_pass_id[n]);
 				break;
 			case IEEE80211_WPS_ATTR_MANUFACTURER:
 				printf(" manufacturer:<%.*s>", tlv_len, ie);
 				break;
 			case IEEE80211_WPS_ATTR_MODEL_NAME:
 				printf(" model_name:<%.*s>", tlv_len, ie);
 				break;
 			case IEEE80211_WPS_ATTR_MODEL_NUMBER:
 				printf(" model_number:<%.*s>", tlv_len, ie);
 				break;
 			case IEEE80211_WPS_ATTR_PRIMARY_DEV_TYPE:
 				printf(" prim_dev:");
 				for (n = 0; n < tlv_len; n++)
 					printf("%02x", ie[n]);
 				break;
 			case IEEE80211_WPS_ATTR_RF_BANDS:
 				printf(" rf:");
 				f = 0;
 				for (n = 7; n >= 0; n--) {
 					if (f) {
 						printf(",");
 						f = 0;
 					}
 					switch (*ie & (1 << n)) {
 					case 0:
 						break;
 					case IEEE80211_WPS_RF_BAND_24GHZ:
 						printf("2.4Ghz");
 						f++;
 						break;
 					case IEEE80211_WPS_RF_BAND_50GHZ:
 						printf("5Ghz");
 						f++;
 						break;
 					case IEEE80211_WPS_RF_BAND_600GHZ:
 						printf("60Ghz");
 						f++;
 						break;
 					default:
 						printf("unknown<%02x>",
 						    *ie & (1 << n));
 						f++;
 						break;
 					}
 				}
 				break;
 			case IEEE80211_WPS_ATTR_RESPONSE_TYPE:
 				printf(" resp_type:0x%02x", *ie);
 				break;
 			case IEEE80211_WPS_ATTR_SELECTED_REGISTRAR:
 				printf(" sel:%s", *ie ? "T" : "F");
 				break;
 			case IEEE80211_WPS_ATTR_SERIAL_NUMBER:
 				printf(" serial_number:<%.*s>", tlv_len, ie);
 				break;
 			case IEEE80211_WPS_ATTR_UUID_E:
 				printf(" uuid-e:");
 				for (n = 0; n < (tlv_len - 1); n++)
 					printf("%02x-", ie[n]);
 				printf("%02x", ie[n]);
 				break;
 			case IEEE80211_WPS_ATTR_VENDOR_EXT:
 				printf(" vendor:");
 				for (n = 0; n < tlv_len; n++)
 					printf("%02x", ie[n]);
 				break;
 			case IEEE80211_WPS_ATTR_WPS_STATE:
 				switch (*ie) {
 				case IEEE80211_WPS_STATE_NOT_CONFIGURED:
 					printf(" state:N");
 					break;
 				case IEEE80211_WPS_STATE_CONFIGURED:
 					printf(" state:C");
 					break;
 				default:
 					printf(" state:B<%02x>", *ie);
 					break;
 				}
 				break;
 			default:
 				printf(" unknown_wps_attr:0x%x", tlv_type);
 				break;
 			}
 			ie += tlv_len, len -= tlv_len;
 		}
 		printf(">");
 	}
 }
 
 static void
 printtdmaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	printf("%s", tag);
 	if (verbose && ielen >= sizeof(struct ieee80211_tdma_param)) {
 		const struct ieee80211_tdma_param *tdma =
 		   (const struct ieee80211_tdma_param *) ie;
 
 		/* XXX tstamp */
 		printf("<v%u slot:%u slotcnt:%u slotlen:%u bintval:%u inuse:0x%x>",
 		    tdma->tdma_version, tdma->tdma_slot, tdma->tdma_slotcnt,
 		    LE_READ_2(&tdma->tdma_slotlen), tdma->tdma_bintval,
 		    tdma->tdma_inuse[0]);
 	}
 }
 
 /*
  * Copy the ssid string contents into buf, truncating to fit.  If the
  * ssid is entirely printable then just copy intact.  Otherwise convert
  * to hexadecimal.  If the result is truncated then replace the last
  * three characters with "...".
  */
 static int
 copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len)
 {
 	const u_int8_t *p; 
 	size_t maxlen;
 	u_int i;
 
 	if (essid_len > bufsize)
 		maxlen = bufsize;
 	else
 		maxlen = essid_len;
 	/* determine printable or not */
 	for (i = 0, p = essid; i < maxlen; i++, p++) {
 		if (*p < ' ' || *p > 0x7e)
 			break;
 	}
 	if (i != maxlen) {		/* not printable, print as hex */
 		if (bufsize < 3)
 			return 0;
 		strlcpy(buf, "0x", bufsize);
 		bufsize -= 2;
 		p = essid;
 		for (i = 0; i < maxlen && bufsize >= 2; i++) {
 			sprintf(&buf[2+2*i], "%02x", p[i]);
 			bufsize -= 2;
 		}
 		if (i != essid_len)
 			memcpy(&buf[2+2*i-3], "...", 3);
 	} else {			/* printable, truncate as needed */
 		memcpy(buf, essid, maxlen);
 		if (maxlen != essid_len)
 			memcpy(&buf[maxlen-3], "...", 3);
 	}
 	return maxlen;
 }
 
 static void
 printssid(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	char ssid[2*IEEE80211_NWID_LEN+1];
 
 	printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1]), ssid);
 }
 
 static void
 printrates(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	const char *sep;
-	int i;
 
 	printf("%s", tag);
 	sep = "<";
-	for (i = 2; i < ielen; i++) {
+	for (size_t i = 2; i < ielen; i++) {
 		printf("%s%s%d", sep,
 		    ie[i] & IEEE80211_RATE_BASIC ? "B" : "",
 		    ie[i] & IEEE80211_RATE_VAL);
 		sep = ",";
 	}
 	printf(">");
 }
 
 static void
 printcountry(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
 {
 	const struct ieee80211_country_ie *cie =
 	   (const struct ieee80211_country_ie *) ie;
 	int i, nbands, schan, nchan;
 
 	printf("%s<%c%c%c", tag, cie->cc[0], cie->cc[1], cie->cc[2]);
 	nbands = (cie->len - 3) / sizeof(cie->band[0]);
 	for (i = 0; i < nbands; i++) {
 		schan = cie->band[i].schan;
 		nchan = cie->band[i].nchan;
 		if (nchan != 1)
 			printf(" %u-%u,%u", schan, schan + nchan-1,
 			    cie->band[i].maxtxpwr);
 		else
 			printf(" %u,%u", schan, cie->band[i].maxtxpwr);
 	}
 	printf(">");
 }
 
 static __inline int
 iswpaoui(const u_int8_t *frm)
 {
 	return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
 }
 
 static __inline int
 iswmeinfo(const u_int8_t *frm)
 {
 	return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
 		frm[6] == WME_INFO_OUI_SUBTYPE;
 }
 
 static __inline int
 iswmeparam(const u_int8_t *frm)
 {
 	return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
 		frm[6] == WME_PARAM_OUI_SUBTYPE;
 }
 
 static __inline int
 isatherosoui(const u_int8_t *frm)
 {
 	return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
 }
 
 static __inline int
 istdmaoui(const uint8_t *frm)
 {
 	return frm[1] > 3 && LE_READ_4(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI);
 }
 
 static __inline int
 iswpsoui(const uint8_t *frm)
 {
 	return frm[1] > 3 && LE_READ_4(frm+2) == ((WPS_OUI_TYPE<<24)|WPA_OUI);
 }
 
 static const char *
 iename(int elemid)
 {
 	static char iename_buf[64];
 	switch (elemid) {
 	case IEEE80211_ELEMID_FHPARMS:	return " FHPARMS";
 	case IEEE80211_ELEMID_CFPARMS:	return " CFPARMS";
 	case IEEE80211_ELEMID_TIM:	return " TIM";
 	case IEEE80211_ELEMID_IBSSPARMS:return " IBSSPARMS";
 	case IEEE80211_ELEMID_BSSLOAD:	return " BSSLOAD";
 	case IEEE80211_ELEMID_CHALLENGE:return " CHALLENGE";
 	case IEEE80211_ELEMID_PWRCNSTR:	return " PWRCNSTR";
 	case IEEE80211_ELEMID_PWRCAP:	return " PWRCAP";
 	case IEEE80211_ELEMID_TPCREQ:	return " TPCREQ";
 	case IEEE80211_ELEMID_TPCREP:	return " TPCREP";
 	case IEEE80211_ELEMID_SUPPCHAN:	return " SUPPCHAN";
 	case IEEE80211_ELEMID_CSA:	return " CSA";
 	case IEEE80211_ELEMID_MEASREQ:	return " MEASREQ";
 	case IEEE80211_ELEMID_MEASREP:	return " MEASREP";
 	case IEEE80211_ELEMID_QUIET:	return " QUIET";
 	case IEEE80211_ELEMID_IBSSDFS:	return " IBSSDFS";
 	case IEEE80211_ELEMID_RESERVED_47:
 					return " RESERVED_47";
 	case IEEE80211_ELEMID_MOBILITY_DOMAIN:
 					return " MOBILITY_DOMAIN";
 	case IEEE80211_ELEMID_RRM_ENACAPS:
 					return " RRM_ENCAPS";
 	case IEEE80211_ELEMID_OVERLAP_BSS_SCAN_PARAM:
 					return " OVERLAP_BSS";
 	case IEEE80211_ELEMID_TPC:	return " TPC";
 	case IEEE80211_ELEMID_CCKM:	return " CCKM";
 	case IEEE80211_ELEMID_EXTCAP:	return " EXTCAP";
 	}
 	snprintf(iename_buf, sizeof(iename_buf), " UNKNOWN_ELEMID_%d",
 	    elemid);
 	return (const char *) iename_buf;
 }
 
 static void
-printies(const u_int8_t *vp, int ielen, int maxcols)
+printies(const u_int8_t *vp, int ielen, unsigned int maxcols)
 {
 	while (ielen > 0) {
 		switch (vp[0]) {
 		case IEEE80211_ELEMID_SSID:
 			if (verbose)
 				printssid(" SSID", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_RATES:
 		case IEEE80211_ELEMID_XRATES:
 			if (verbose)
 				printrates(vp[0] == IEEE80211_ELEMID_RATES ?
 				    " RATES" : " XRATES", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_DSPARMS:
 			if (verbose)
 				printf(" DSPARMS<%u>", vp[2]);
 			break;
 		case IEEE80211_ELEMID_COUNTRY:
 			if (verbose)
 				printcountry(" COUNTRY", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_ERP:
 			if (verbose)
 				printf(" ERP<0x%x>", vp[2]);
 			break;
 		case IEEE80211_ELEMID_VENDOR:
 			if (iswpaoui(vp))
 				printwpaie(" WPA", vp, 2+vp[1], maxcols);
 			else if (iswmeinfo(vp))
 				printwmeinfo(" WME", vp, 2+vp[1], maxcols);
 			else if (iswmeparam(vp))
 				printwmeparam(" WME", vp, 2+vp[1], maxcols);
 			else if (isatherosoui(vp))
 				printathie(" ATH", vp, 2+vp[1], maxcols);
 			else if (iswpsoui(vp))
 				printwpsie(" WPS", vp, 2+vp[1], maxcols);
 			else if (istdmaoui(vp))
 				printtdmaie(" TDMA", vp, 2+vp[1], maxcols);
 			else if (verbose)
 				printie(" VEN", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_RSN:
 			printrsnie(" RSN", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_HTCAP:
 			printhtcap(" HTCAP", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_HTINFO:
 			if (verbose)
 				printhtinfo(" HTINFO", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_MESHID:
 			if (verbose)
 				printssid(" MESHID", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_MESHCONF:
 			printmeshconf(" MESHCONF", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_VHT_CAP:
 			printvhtcap(" VHTCAP", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_VHT_OPMODE:
 			printvhtinfo(" VHTOPMODE", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_VHT_PWR_ENV:
 			printvhtpwrenv(" VHTPWRENV", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_BSSLOAD:
 			printbssload(" BSSLOAD", vp, 2+vp[1], maxcols);
 			break;
 		case IEEE80211_ELEMID_APCHANREP:
 			printapchanrep(" APCHANREP", vp, 2+vp[1], maxcols);
 			break;
 		default:
 			if (verbose)
 				printie(iename(vp[0]), vp, 2+vp[1], maxcols);
 			break;
 		}
 		ielen -= 2+vp[1];
 		vp += 2+vp[1];
 	}
 }
 
 static void
 printmimo(const struct ieee80211_mimo_info *mi)
 {
 	int i;
 	int r = 0;
 
 	for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
 		if (mi->ch[i].rssi != 0) {
 			r = 1;
 			break;
 		}
 	}
 
 	/* NB: don't muddy display unless there's something to show */
 	if (r == 0)
 		return;
 
 	/* XXX TODO: ignore EVM; secondary channels for now */
 	printf(" (rssi %.1f:%.1f:%.1f:%.1f nf %d:%d:%d:%d)",
 	    mi->ch[0].rssi[0] / 2.0,
 	    mi->ch[1].rssi[0] / 2.0,
 	    mi->ch[2].rssi[0] / 2.0,
 	    mi->ch[3].rssi[0] / 2.0,
 	    mi->ch[0].noise[0],
 	    mi->ch[1].noise[0],
 	    mi->ch[2].noise[0],
 	    mi->ch[3].noise[0]);
 }
 
 static void
 printbssidname(const struct ether_addr *n)
 {
 	char name[MAXHOSTNAMELEN + 1];
 
 	if (ether_ntohost(name, n) != 0)
 		return;
 
 	printf(" (%s)", name);
 }
 
 static void
 list_scan(int s)
 {
 	uint8_t buf[24*1024];
 	char ssid[IEEE80211_NWID_LEN+1];
 	const uint8_t *cp;
 	int len, idlen;
 
 	if (get80211len(s, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf), &len) < 0)
 		errx(1, "unable to get scan results");
-	if (len < sizeof(struct ieee80211req_scan_result))
+	if (len < (int)sizeof(struct ieee80211req_scan_result))
 		return;
 
 	getchaninfo(s);
 
 	printf("%-*.*s  %-17.17s  %4s %4s   %-7s  %3s %4s\n"
 		, IEEE80211_NWID_LEN, IEEE80211_NWID_LEN, "SSID/MESH ID"
 		, "BSSID"
 		, "CHAN"
 		, "RATE"
 		, " S:N"
 		, "INT"
 		, "CAPS"
 	);
 	cp = buf;
 	do {
 		const struct ieee80211req_scan_result *sr;
 		const uint8_t *vp, *idp;
 
-		sr = (const struct ieee80211req_scan_result *) cp;
+		sr = (const struct ieee80211req_scan_result *)(const void *) cp;
 		vp = cp + sr->isr_ie_off;
 		if (sr->isr_meshid_len) {
 			idp = vp + sr->isr_ssid_len;
 			idlen = sr->isr_meshid_len;
 		} else {
 			idp = vp;
 			idlen = sr->isr_ssid_len;
 		}
 		printf("%-*.*s  %s  %3d  %3dM %4d:%-4d %4d %-4.4s"
 			, IEEE80211_NWID_LEN
 			  , copy_essid(ssid, IEEE80211_NWID_LEN, idp, idlen)
 			  , ssid
 			, ether_ntoa((const struct ether_addr *) sr->isr_bssid)
 			, ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags)
 			, getmaxrate(sr->isr_rates, sr->isr_nrates)
 			, (sr->isr_rssi/2)+sr->isr_noise, sr->isr_noise
 			, sr->isr_intval
 			, getcaps(sr->isr_capinfo)
 		);
 		printies(vp + sr->isr_ssid_len + sr->isr_meshid_len,
 		    sr->isr_ie_len, 24);
 		printbssidname((const struct ether_addr *)sr->isr_bssid);
 		printf("\n");
 		cp += sr->isr_len, len -= sr->isr_len;
-	} while (len >= sizeof(struct ieee80211req_scan_result));
+	} while (len >= (int)sizeof(struct ieee80211req_scan_result));
 }
 
 static void
 scan_and_wait(int s)
 {
 	struct ieee80211_scan_req sr;
 	struct ieee80211req ireq;
 	int sroute;
 
 	sroute = socket(PF_ROUTE, SOCK_RAW, 0);
 	if (sroute < 0) {
 		perror("socket(PF_ROUTE,SOCK_RAW)");
 		return;
 	}
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
 	ireq.i_type = IEEE80211_IOC_SCAN_REQ;
 
 	memset(&sr, 0, sizeof(sr));
 	sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE
 		    | IEEE80211_IOC_SCAN_BGSCAN
 		    | IEEE80211_IOC_SCAN_NOPICK
 		    | IEEE80211_IOC_SCAN_ONCE;
 	sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
 	sr.sr_nssid = 0;
 
 	ireq.i_data = &sr;
 	ireq.i_len = sizeof(sr);
 	/*
 	 * NB: only root can trigger a scan so ignore errors. Also ignore
 	 * possible errors from net80211, even if no new scan could be
 	 * started there might still be a valid scan cache.
 	 */
 	if (ioctl(s, SIOCS80211, &ireq) == 0) {
 		char buf[2048];
 		struct if_announcemsghdr *ifan;
 		struct rt_msghdr *rtm;
 
 		do {
 			if (read(sroute, buf, sizeof(buf)) < 0) {
 				perror("read(PF_ROUTE)");
 				break;
 			}
 			rtm = (struct rt_msghdr *) buf;
 			if (rtm->rtm_version != RTM_VERSION)
 				break;
 			ifan = (struct if_announcemsghdr *) rtm;
 		} while (rtm->rtm_type != RTM_IEEE80211 ||
 		    ifan->ifan_what != RTM_IEEE80211_SCAN);
 	}
 	close(sroute);
 }
 
 static
 DECL_CMD_FUNC(set80211scan, val, d)
 {
 	scan_and_wait(s);
 	list_scan(s);
 }
 
 static enum ieee80211_opmode get80211opmode(int s);
 
 static int
 gettxseq(const struct ieee80211req_sta_info *si)
 {
 	int i, txseq;
 
 	if ((si->isi_state & IEEE80211_NODE_QOS) == 0)
 		return si->isi_txseqs[0];
 	/* XXX not right but usually what folks want */
 	txseq = 0;
 	for (i = 0; i < IEEE80211_TID_SIZE; i++)
 		if (si->isi_txseqs[i] > txseq)
 			txseq = si->isi_txseqs[i];
 	return txseq;
 }
 
 static int
 getrxseq(const struct ieee80211req_sta_info *si)
 {
-	int i, rxseq;
+	int rxseq;
 
 	if ((si->isi_state & IEEE80211_NODE_QOS) == 0)
 		return si->isi_rxseqs[0];
 	/* XXX not right but usually what folks want */
 	rxseq = 0;
-	for (i = 0; i < IEEE80211_TID_SIZE; i++)
+	for (unsigned int i = 0; i < IEEE80211_TID_SIZE; i++)
 		if (si->isi_rxseqs[i] > rxseq)
 			rxseq = si->isi_rxseqs[i];
 	return rxseq;
 }
 
 static void
 list_stations(int s)
 {
 	union {
 		struct ieee80211req_sta_req req;
 		uint8_t buf[24*1024];
 	} u;
 	enum ieee80211_opmode opmode = get80211opmode(s);
 	const uint8_t *cp;
 	int len;
 
 	/* broadcast address =>'s get all stations */
 	(void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN);
 	if (opmode == IEEE80211_M_STA) {
 		/*
 		 * Get information about the associated AP.
 		 */
 		(void) get80211(s, IEEE80211_IOC_BSSID,
 		    u.req.is_u.macaddr, IEEE80211_ADDR_LEN);
 	}
 	if (get80211len(s, IEEE80211_IOC_STA_INFO, &u, sizeof(u), &len) < 0)
 		errx(1, "unable to get station information");
-	if (len < sizeof(struct ieee80211req_sta_info))
+	if (len < (int)sizeof(struct ieee80211req_sta_info))
 		return;
 
 	getchaninfo(s);
 
 	if (opmode == IEEE80211_M_MBSS)
 		printf("%-17.17s %4s %5s %5s %7s %4s %4s %4s %6s %6s\n"
 			, "ADDR"
 			, "CHAN"
 			, "LOCAL"
 			, "PEER"
 			, "STATE"
 			, "RATE"
 			, "RSSI"
 			, "IDLE"
 			, "TXSEQ"
 			, "RXSEQ"
 		);
 	else
 		printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %-12s\n"
 			, "ADDR"
 			, "AID"
 			, "CHAN"
 			, "RATE"
 			, "RSSI"
 			, "IDLE"
 			, "TXSEQ"
 			, "RXSEQ"
 			, "CAPS"
 			, "FLAG"
 		);
 	cp = (const uint8_t *) u.req.info;
 	do {
 		const struct ieee80211req_sta_info *si;
 
 		si = (const struct ieee80211req_sta_info *) cp;
 		if (si->isi_len < sizeof(*si))
 			break;
 		if (opmode == IEEE80211_M_MBSS)
 			printf("%s %4d %5x %5x %7.7s %3dM %4.1f %4d %6d %6d"
 				, ether_ntoa((const struct ether_addr*)
 				    si->isi_macaddr)
 				, ieee80211_mhz2ieee(si->isi_freq,
 				    si->isi_flags)
 				, si->isi_localid
 				, si->isi_peerid
 				, mesh_linkstate_string(si->isi_peerstate)
 				, si->isi_txmbps/2
 				, si->isi_rssi/2.
 				, si->isi_inact
 				, gettxseq(si)
 				, getrxseq(si)
 			);
 		else
 			printf("%s %4u %4d %3dM %4.1f %4d %6d %6d %-4.4s %-12.12s"
 				, ether_ntoa((const struct ether_addr*)
 				    si->isi_macaddr)
 				, IEEE80211_AID(si->isi_associd)
 				, ieee80211_mhz2ieee(si->isi_freq,
 				    si->isi_flags)
 				, si->isi_txmbps/2
 				, si->isi_rssi/2.
 				, si->isi_inact
 				, gettxseq(si)
 				, getrxseq(si)
 				, getcaps(si->isi_capinfo)
 				, getflags(si->isi_state)
 			);
 		printies(cp + si->isi_ie_off, si->isi_ie_len, 24);
 		printmimo(&si->isi_mimo);
 		printf("\n");
 		cp += si->isi_len, len -= si->isi_len;
-	} while (len >= sizeof(struct ieee80211req_sta_info));
+	} while (len >= (int)sizeof(struct ieee80211req_sta_info));
 }
 
 static const char *
 mesh_linkstate_string(uint8_t state)
 {
 	static const char *state_names[] = {
 	    [0] = "IDLE",
 	    [1] = "OPEN-TX",
 	    [2] = "OPEN-RX",
 	    [3] = "CONF-RX",
 	    [4] = "ESTAB",
 	    [5] = "HOLDING",
 	};
 
 	if (state >= nitems(state_names)) {
 		static char buf[10];
 		snprintf(buf, sizeof(buf), "#%u", state);
 		return buf;
 	} else
 		return state_names[state];
 }
 
 static const char *
 get_chaninfo(const struct ieee80211_channel *c, int precise,
 	char buf[], size_t bsize)
 {
 	buf[0] = '\0';
 	if (IEEE80211_IS_CHAN_FHSS(c))
 		strlcat(buf, " FHSS", bsize);
 	if (IEEE80211_IS_CHAN_A(c))
 		strlcat(buf, " 11a", bsize);
 	else if (IEEE80211_IS_CHAN_ANYG(c))
 		strlcat(buf, " 11g", bsize);
 	else if (IEEE80211_IS_CHAN_B(c))
 		strlcat(buf, " 11b", bsize);
 	if (IEEE80211_IS_CHAN_HALF(c))
 		strlcat(buf, "/10MHz", bsize);
 	if (IEEE80211_IS_CHAN_QUARTER(c))
 		strlcat(buf, "/5MHz", bsize);
 	if (IEEE80211_IS_CHAN_TURBO(c))
 		strlcat(buf, " Turbo", bsize);
 	if (precise) {
 		if (IEEE80211_IS_CHAN_VHT80P80(c))
 			strlcat(buf, " vht/80p80", bsize);
 		else if (IEEE80211_IS_CHAN_VHT160(c))
 			strlcat(buf, " vht/160", bsize);
 		else if (IEEE80211_IS_CHAN_VHT80(c) &&
 		    IEEE80211_IS_CHAN_HT40D(c))
 			strlcat(buf, " vht/80-", bsize);
 		else if (IEEE80211_IS_CHAN_VHT80(c) &&
 		    IEEE80211_IS_CHAN_HT40U(c))
 			strlcat(buf, " vht/80+", bsize);
 		else if (IEEE80211_IS_CHAN_VHT80(c))
 			strlcat(buf, " vht/80", bsize);
 		else if (IEEE80211_IS_CHAN_VHT40D(c))
 			strlcat(buf, " vht/40-", bsize);
 		else if (IEEE80211_IS_CHAN_VHT40U(c))
 			strlcat(buf, " vht/40+", bsize);
 		else if (IEEE80211_IS_CHAN_VHT20(c))
 			strlcat(buf, " vht/20", bsize);
 		else if (IEEE80211_IS_CHAN_HT20(c))
 			strlcat(buf, " ht/20", bsize);
 		else if (IEEE80211_IS_CHAN_HT40D(c))
 			strlcat(buf, " ht/40-", bsize);
 		else if (IEEE80211_IS_CHAN_HT40U(c))
 			strlcat(buf, " ht/40+", bsize);
 	} else {
 		if (IEEE80211_IS_CHAN_VHT(c))
 			strlcat(buf, " vht", bsize);
 		else if (IEEE80211_IS_CHAN_HT(c))
 			strlcat(buf, " ht", bsize);
 	}
 	return buf;
 }
 
 static void
 print_chaninfo(const struct ieee80211_channel *c, int verb)
 {
 	char buf[14];
 
 	if (verb)
 		printf("Channel %3u : %u%c%c%c%c%c MHz%-14.14s",
 		    ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq,
 		    IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ',
 		    IEEE80211_IS_CHAN_DFS(c) ? 'D' : ' ',
 		    IEEE80211_IS_CHAN_RADAR(c) ? 'R' : ' ',
 		    IEEE80211_IS_CHAN_CWINT(c) ? 'I' : ' ',
 		    IEEE80211_IS_CHAN_CACDONE(c) ? 'C' : ' ',
 		    get_chaninfo(c, verb, buf, sizeof(buf)));
 	else
 	printf("Channel %3u : %u%c MHz%-14.14s",
 	    ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq,
 	    IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ',
 	    get_chaninfo(c, verb, buf, sizeof(buf)));
 
 }
 
 static int
 chanpref(const struct ieee80211_channel *c)
 {
 
 	if (IEEE80211_IS_CHAN_VHT80P80(c))
 		return 90;
 	if (IEEE80211_IS_CHAN_VHT160(c))
 		return 80;
 	if (IEEE80211_IS_CHAN_VHT80(c))
 		return 70;
 	if (IEEE80211_IS_CHAN_VHT40(c))
 		return 60;
 	if (IEEE80211_IS_CHAN_VHT20(c))
 		return 50;
 	if (IEEE80211_IS_CHAN_HT40(c))
 		return 40;
 	if (IEEE80211_IS_CHAN_HT20(c))
 		return 30;
 	if (IEEE80211_IS_CHAN_HALF(c))
 		return 10;
 	if (IEEE80211_IS_CHAN_QUARTER(c))
 		return 5;
 	if (IEEE80211_IS_CHAN_TURBO(c))
 		return 25;
 	if (IEEE80211_IS_CHAN_A(c))
 		return 20;
 	if (IEEE80211_IS_CHAN_G(c))
 		return 20;
 	if (IEEE80211_IS_CHAN_B(c))
 		return 15;
 	if (IEEE80211_IS_CHAN_PUREG(c))
 		return 15;
 	return 0;
 }
 
 static void
 print_channels(int s, const struct ieee80211req_chaninfo *chans,
 	int allchans, int verb)
 {
 	struct ieee80211req_chaninfo *achans;
 	uint8_t reported[IEEE80211_CHAN_BYTES];
 	const struct ieee80211_channel *c;
-	int i, half;
+	unsigned int i, half;
 
 	achans = malloc(IEEE80211_CHANINFO_SPACE(chans));
 	if (achans == NULL)
 		errx(1, "no space for active channel list");
 	achans->ic_nchans = 0;
 	memset(reported, 0, sizeof(reported));
 	if (!allchans) {
 		struct ieee80211req_chanlist active;
 
 		if (get80211(s, IEEE80211_IOC_CHANLIST, &active, sizeof(active)) < 0)
 			errx(1, "unable to get active channel list");
 		for (i = 0; i < chans->ic_nchans; i++) {
 			c = &chans->ic_chans[i];
 			if (!isset(active.ic_channels, c->ic_ieee))
 				continue;
 			/*
 			 * Suppress compatible duplicates unless
 			 * verbose.  The kernel gives us it's
 			 * complete channel list which has separate
 			 * entries for 11g/11b and 11a/turbo.
 			 */
 			if (isset(reported, c->ic_ieee) && !verb) {
 				/* XXX we assume duplicates are adjacent */
 				achans->ic_chans[achans->ic_nchans-1] = *c;
 			} else {
 				achans->ic_chans[achans->ic_nchans++] = *c;
 				setbit(reported, c->ic_ieee);
 			}
 		}
 	} else {
 		for (i = 0; i < chans->ic_nchans; i++) {
 			c = &chans->ic_chans[i];
 			/* suppress duplicates as above */
 			if (isset(reported, c->ic_ieee) && !verb) {
 				/* XXX we assume duplicates are adjacent */
 				struct ieee80211_channel *a =
 				    &achans->ic_chans[achans->ic_nchans-1];
 				if (chanpref(c) > chanpref(a))
 					*a = *c;
 			} else {
 				achans->ic_chans[achans->ic_nchans++] = *c;
 				setbit(reported, c->ic_ieee);
 			}
 		}
 	}
 	half = achans->ic_nchans / 2;
 	if (achans->ic_nchans % 2)
 		half++;
 
 	for (i = 0; i < achans->ic_nchans / 2; i++) {
 		print_chaninfo(&achans->ic_chans[i], verb);
 		print_chaninfo(&achans->ic_chans[half+i], verb);
 		printf("\n");
 	}
 	if (achans->ic_nchans % 2) {
 		print_chaninfo(&achans->ic_chans[i], verb);
 		printf("\n");
 	}
 	free(achans);
 }
 
 static void
 list_channels(int s, int allchans)
 {
 	getchaninfo(s);
 	print_channels(s, chaninfo, allchans, verbose);
 }
 
 static void
 print_txpow(const struct ieee80211_channel *c)
 {
 	printf("Channel %3u : %u MHz %3.1f reg %2d  ",
 	    c->ic_ieee, c->ic_freq,
 	    c->ic_maxpower/2., c->ic_maxregpower);
 }
 
 static void
 print_txpow_verbose(const struct ieee80211_channel *c)
 {
 	print_chaninfo(c, 1);
 	printf("min %4.1f dBm  max %3.1f dBm  reg %2d dBm",
 	    c->ic_minpower/2., c->ic_maxpower/2., c->ic_maxregpower);
 	/* indicate where regulatory cap limits power use */
 	if (c->ic_maxpower > 2*c->ic_maxregpower)
 		printf(" <");
 }
 
 static void
 list_txpow(int s)
 {
 	struct ieee80211req_chaninfo *achans;
 	uint8_t reported[IEEE80211_CHAN_BYTES];
 	struct ieee80211_channel *c, *prev;
-	int i, half;
+	unsigned int i, half;
 
 	getchaninfo(s);
 	achans = malloc(IEEE80211_CHANINFO_SPACE(chaninfo));
 	if (achans == NULL)
 		errx(1, "no space for active channel list");
 	achans->ic_nchans = 0;
 	memset(reported, 0, sizeof(reported));
 	for (i = 0; i < chaninfo->ic_nchans; i++) {
 		c = &chaninfo->ic_chans[i];
 		/* suppress duplicates as above */
 		if (isset(reported, c->ic_ieee) && !verbose) {
 			/* XXX we assume duplicates are adjacent */
 			assert(achans->ic_nchans > 0);
 			prev = &achans->ic_chans[achans->ic_nchans-1];
 			/* display highest power on channel */
 			if (c->ic_maxpower > prev->ic_maxpower)
 				*prev = *c;
 		} else {
 			achans->ic_chans[achans->ic_nchans++] = *c;
 			setbit(reported, c->ic_ieee);
 		}
 	}
 	if (!verbose) {
 		half = achans->ic_nchans / 2;
 		if (achans->ic_nchans % 2)
 			half++;
 
 		for (i = 0; i < achans->ic_nchans / 2; i++) {
 			print_txpow(&achans->ic_chans[i]);
 			print_txpow(&achans->ic_chans[half+i]);
 			printf("\n");
 		}
 		if (achans->ic_nchans % 2) {
 			print_txpow(&achans->ic_chans[i]);
 			printf("\n");
 		}
 	} else {
 		for (i = 0; i < achans->ic_nchans; i++) {
 			print_txpow_verbose(&achans->ic_chans[i]);
 			printf("\n");
 		}
 	}
 	free(achans);
 }
 
 static void
 list_keys(int s)
 {
 }
 
 static void
 list_capabilities(int s)
 {
 	struct ieee80211_devcaps_req *dc;
 
 	if (verbose)
 		dc = malloc(IEEE80211_DEVCAPS_SIZE(MAXCHAN));
 	else
 		dc = malloc(IEEE80211_DEVCAPS_SIZE(1));
 	if (dc == NULL)
 		errx(1, "no space for device capabilities");
 	dc->dc_chaninfo.ic_nchans = verbose ? MAXCHAN : 1;
 	getdevcaps(s, dc);
 	printb("drivercaps", dc->dc_drivercaps, IEEE80211_C_BITS);
 	if (dc->dc_cryptocaps != 0 || verbose) {
 		putchar('\n');
 		printb("cryptocaps", dc->dc_cryptocaps, IEEE80211_CRYPTO_BITS);
 	}
 	if (dc->dc_htcaps != 0 || verbose) {
 		putchar('\n');
 		printb("htcaps", dc->dc_htcaps, IEEE80211_HTCAP_BITS);
 	}
 	if (dc->dc_vhtcaps != 0 || verbose) {
 		putchar('\n');
 		printb("vhtcaps", dc->dc_vhtcaps, IEEE80211_VHTCAP_BITS);
 	}
 
 	putchar('\n');
 	if (verbose) {
 		chaninfo = &dc->dc_chaninfo;	/* XXX */
 		print_channels(s, &dc->dc_chaninfo, 1/*allchans*/, verbose);
 	}
 	free(dc);
 }
 
 static int
 get80211wme(int s, int param, int ac, int *val)
 {
 	struct ieee80211req ireq;
 
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
 	ireq.i_type = param;
 	ireq.i_len = ac;
 	if (ioctl(s, SIOCG80211, &ireq) < 0) {
 		warn("cannot get WME parameter %d, ac %d%s",
 		    param, ac & IEEE80211_WMEPARAM_VAL,
 		    ac & IEEE80211_WMEPARAM_BSS ? " (BSS)" : "");
 		return -1;
 	}
 	*val = ireq.i_val;
 	return 0;
 }
 
 static void
 list_wme_aci(int s, const char *tag, int ac)
 {
 	int val;
 
 	printf("\t%s", tag);
 
 	/* show WME BSS parameters */
 	if (get80211wme(s, IEEE80211_IOC_WME_CWMIN, ac, &val) != -1)
 		printf(" cwmin %2u", val);
 	if (get80211wme(s, IEEE80211_IOC_WME_CWMAX, ac, &val) != -1)
 		printf(" cwmax %2u", val);
 	if (get80211wme(s, IEEE80211_IOC_WME_AIFS, ac, &val) != -1)
 		printf(" aifs %2u", val);
 	if (get80211wme(s, IEEE80211_IOC_WME_TXOPLIMIT, ac, &val) != -1)
 		printf(" txopLimit %3u", val);
 	if (get80211wme(s, IEEE80211_IOC_WME_ACM, ac, &val) != -1) {
 		if (val)
 			printf(" acm");
 		else if (verbose)
 			printf(" -acm");
 	}
 	/* !BSS only */
 	if ((ac & IEEE80211_WMEPARAM_BSS) == 0) {
 		if (get80211wme(s, IEEE80211_IOC_WME_ACKPOLICY, ac, &val) != -1) {
 			if (!val)
 				printf(" -ack");
 			else if (verbose)
 				printf(" ack");
 		}
 	}
 	printf("\n");
 }
 
 static void
 list_wme(int s)
 {
 	static const char *acnames[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" };
 	int ac;
 
 	if (verbose) {
 		/* display both BSS and local settings */
 		for (ac = WME_AC_BE; ac <= WME_AC_VO; ac++) {
 	again:
 			if (ac & IEEE80211_WMEPARAM_BSS)
 				list_wme_aci(s, "     ", ac);
 			else
 				list_wme_aci(s, acnames[ac], ac);
 			if ((ac & IEEE80211_WMEPARAM_BSS) == 0) {
 				ac |= IEEE80211_WMEPARAM_BSS;
 				goto again;
 			} else
 				ac &= ~IEEE80211_WMEPARAM_BSS;
 		}
 	} else {
 		/* display only channel settings */
 		for (ac = WME_AC_BE; ac <= WME_AC_VO; ac++)
 			list_wme_aci(s, acnames[ac], ac);
 	}
 }
 
 static void
 list_roam(int s)
 {
 	const struct ieee80211_roamparam *rp;
 	int mode;
 
 	getroam(s);
 	for (mode = IEEE80211_MODE_11A; mode < IEEE80211_MODE_MAX; mode++) {
 		rp = &roamparams.params[mode];
 		if (rp->rssi == 0 && rp->rate == 0)
 			continue;
 		if (mode == IEEE80211_MODE_11NA ||
 		    mode == IEEE80211_MODE_11NG ||
 		    mode == IEEE80211_MODE_VHT_2GHZ ||
 		    mode == IEEE80211_MODE_VHT_5GHZ) {
 			if (rp->rssi & 1)
 				LINE_CHECK("roam:%-7.7s rssi %2u.5dBm  MCS %2u    ",
 				    modename[mode], rp->rssi/2,
 				    rp->rate &~ IEEE80211_RATE_MCS);
 			else
 				LINE_CHECK("roam:%-7.7s rssi %4udBm  MCS %2u    ",
 				    modename[mode], rp->rssi/2,
 				    rp->rate &~ IEEE80211_RATE_MCS);
 		} else {
 			if (rp->rssi & 1)
 				LINE_CHECK("roam:%-7.7s rssi %2u.5dBm rate %2u Mb/s",
 				    modename[mode], rp->rssi/2, rp->rate/2);
 			else
 				LINE_CHECK("roam:%-7.7s rssi %4udBm rate %2u Mb/s",
 				    modename[mode], rp->rssi/2, rp->rate/2);
 		}
 	}
 }
 
 /* XXX TODO: rate-to-string method... */
 static const char*
 get_mcs_mbs_rate_str(uint8_t rate)
 {
 	return (rate & IEEE80211_RATE_MCS) ? "MCS " : "Mb/s";
 }
 
 static uint8_t
 get_rate_value(uint8_t rate)
 {
 	if (rate & IEEE80211_RATE_MCS)
 		return (rate &~ IEEE80211_RATE_MCS);
 	return (rate / 2);
 }
 
 static void
 list_txparams(int s)
 {
 	const struct ieee80211_txparam *tp;
 	int mode;
 
 	gettxparams(s);
 	for (mode = IEEE80211_MODE_11A; mode < IEEE80211_MODE_MAX; mode++) {
 		tp = &txparams.params[mode];
 		if (tp->mgmtrate == 0 && tp->mcastrate == 0)
 			continue;
 		if (mode == IEEE80211_MODE_11NA ||
 		    mode == IEEE80211_MODE_11NG ||
 		    mode == IEEE80211_MODE_VHT_2GHZ ||
 		    mode == IEEE80211_MODE_VHT_5GHZ) {
 			if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
 				LINE_CHECK("%-7.7s ucast NONE    mgmt %2u %s "
 				    "mcast %2u %s maxretry %u",
 				    modename[mode],
 				    get_rate_value(tp->mgmtrate),
 				    get_mcs_mbs_rate_str(tp->mgmtrate),
 				    get_rate_value(tp->mcastrate),
 				    get_mcs_mbs_rate_str(tp->mcastrate),
 				    tp->maxretry);
 			else
 				LINE_CHECK("%-7.7s ucast %2u MCS  mgmt %2u %s "
 				    "mcast %2u %s maxretry %u",
 				    modename[mode],
 				    tp->ucastrate &~ IEEE80211_RATE_MCS,
 				    get_rate_value(tp->mgmtrate),
 				    get_mcs_mbs_rate_str(tp->mgmtrate),
 				    get_rate_value(tp->mcastrate),
 				    get_mcs_mbs_rate_str(tp->mcastrate),
 				    tp->maxretry);
 		} else {
 			if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
 				LINE_CHECK("%-7.7s ucast NONE    mgmt %2u Mb/s "
 				    "mcast %2u Mb/s maxretry %u",
 				    modename[mode],
 				    tp->mgmtrate/2,
 				    tp->mcastrate/2, tp->maxretry);
 			else
 				LINE_CHECK("%-7.7s ucast %2u Mb/s mgmt %2u Mb/s "
 				    "mcast %2u Mb/s maxretry %u",
 				    modename[mode],
 				    tp->ucastrate/2, tp->mgmtrate/2,
 				    tp->mcastrate/2, tp->maxretry);
 		}
 	}
 }
 
 static void
 printpolicy(int policy)
 {
 	switch (policy) {
 	case IEEE80211_MACCMD_POLICY_OPEN:
 		printf("policy: open\n");
 		break;
 	case IEEE80211_MACCMD_POLICY_ALLOW:
 		printf("policy: allow\n");
 		break;
 	case IEEE80211_MACCMD_POLICY_DENY:
 		printf("policy: deny\n");
 		break;
 	case IEEE80211_MACCMD_POLICY_RADIUS:
 		printf("policy: radius\n");
 		break;
 	default:
 		printf("policy: unknown (%u)\n", policy);
 		break;
 	}
 }
 
 static void
 list_mac(int s)
 {
 	struct ieee80211req ireq;
 	struct ieee80211req_maclist *acllist;
 	int i, nacls, policy, len;
 	uint8_t *data;
 	char c;
 
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name)); /* XXX ?? */
 	ireq.i_type = IEEE80211_IOC_MACCMD;
 	ireq.i_val = IEEE80211_MACCMD_POLICY;
 	if (ioctl(s, SIOCG80211, &ireq) < 0) {
 		if (errno == EINVAL) {
 			printf("No acl policy loaded\n");
 			return;
 		}
 		err(1, "unable to get mac policy");
 	}
 	policy = ireq.i_val;
 	if (policy == IEEE80211_MACCMD_POLICY_OPEN) {
 		c = '*';
 	} else if (policy == IEEE80211_MACCMD_POLICY_ALLOW) {
 		c = '+';
 	} else if (policy == IEEE80211_MACCMD_POLICY_DENY) {
 		c = '-';
 	} else if (policy == IEEE80211_MACCMD_POLICY_RADIUS) {
 		c = 'r';		/* NB: should never have entries */
 	} else {
 		printf("policy: unknown (%u)\n", policy);
 		c = '?';
 	}
 	if (verbose || c == '?')
 		printpolicy(policy);
 
 	ireq.i_val = IEEE80211_MACCMD_LIST;
 	ireq.i_len = 0;
 	if (ioctl(s, SIOCG80211, &ireq) < 0)
 		err(1, "unable to get mac acl list size");
 	if (ireq.i_len == 0) {		/* NB: no acls */
 		if (!(verbose || c == '?'))
 			printpolicy(policy);
 		return;
 	}
 	len = ireq.i_len;
 
 	data = malloc(len);
 	if (data == NULL)
 		err(1, "out of memory for acl list");
 
 	ireq.i_data = data;
 	if (ioctl(s, SIOCG80211, &ireq) < 0)
 		err(1, "unable to get mac acl list");
 	nacls = len / sizeof(*acllist);
 	acllist = (struct ieee80211req_maclist *) data;
 	for (i = 0; i < nacls; i++)
 		printf("%c%s\n", c, ether_ntoa(
 			(const struct ether_addr *) acllist[i].ml_macaddr));
 	free(data);
 }
 
 static void
 print_regdomain(const struct ieee80211_regdomain *reg, int verb)
 {
 	if ((reg->regdomain != 0 &&
 	    reg->regdomain != reg->country) || verb) {
 		const struct regdomain *rd =
 		    lib80211_regdomain_findbysku(getregdata(), reg->regdomain);
 		if (rd == NULL)
 			LINE_CHECK("regdomain %d", reg->regdomain);
 		else
 			LINE_CHECK("regdomain %s", rd->name);
 	}
 	if (reg->country != 0 || verb) {
 		const struct country *cc =
 		    lib80211_country_findbycc(getregdata(), reg->country);
 		if (cc == NULL)
 			LINE_CHECK("country %d", reg->country);
 		else
 			LINE_CHECK("country %s", cc->isoname);
 	}
 	if (reg->location == 'I')
 		LINE_CHECK("indoor");
 	else if (reg->location == 'O')
 		LINE_CHECK("outdoor");
 	else if (verb)
 		LINE_CHECK("anywhere");
 	if (reg->ecm)
 		LINE_CHECK("ecm");
 	else if (verb)
 		LINE_CHECK("-ecm");
 }
 
 static void
 list_regdomain(int s, int channelsalso)
 {
 	getregdomain(s);
 	if (channelsalso) {
 		getchaninfo(s);
 		spacer = ':';
 		print_regdomain(&regdomain, 1);
 		LINE_BREAK();
 		print_channels(s, chaninfo, 1/*allchans*/, 1/*verbose*/);
 	} else
 		print_regdomain(&regdomain, verbose);
 }
 
 static void
 list_mesh(int s)
 {
 	struct ieee80211req ireq;
 	struct ieee80211req_mesh_route routes[128];
 	struct ieee80211req_mesh_route *rt;
 
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
 	ireq.i_type = IEEE80211_IOC_MESH_RTCMD;
 	ireq.i_val = IEEE80211_MESH_RTCMD_LIST;
 	ireq.i_data = &routes;
 	ireq.i_len = sizeof(routes);
 	if (ioctl(s, SIOCG80211, &ireq) < 0)
 	 	err(1, "unable to get the Mesh routing table");
 
 	printf("%-17.17s %-17.17s %4s %4s %4s %6s %s\n"
 		, "DEST"
 		, "NEXT HOP"
 		, "HOPS"
 		, "METRIC"
 		, "LIFETIME"
 		, "MSEQ"
 		, "FLAGS");
 
-	for (rt = &routes[0]; rt - &routes[0] < ireq.i_len / sizeof(*rt); rt++){
+	for (unsigned int i = 0; i < ireq.i_len / sizeof(*rt); i++) {
+		rt = &routes[i];
 		printf("%s ",
 		    ether_ntoa((const struct ether_addr *)rt->imr_dest));
 		printf("%s %4u   %4u   %6u %6u    %c%c\n",
 			ether_ntoa((const struct ether_addr *)rt->imr_nexthop),
 			rt->imr_nhops, rt->imr_metric, rt->imr_lifetime,
 			rt->imr_lastmseq,
 			(rt->imr_flags & IEEE80211_MESHRT_FLAGS_DISCOVER) ?
 			    'D' :
 			(rt->imr_flags & IEEE80211_MESHRT_FLAGS_VALID) ?
 			    'V' : '!',
 			(rt->imr_flags & IEEE80211_MESHRT_FLAGS_PROXY) ?
 			    'P' :
 			(rt->imr_flags & IEEE80211_MESHRT_FLAGS_GATE) ?
 			    'G' :' ');
 	}
 }
 
 static
 DECL_CMD_FUNC(set80211list, arg, d)
 {
 #define	iseq(a,b)	(strncasecmp(a,b,sizeof(b)-1) == 0)
 
 	LINE_INIT('\t');
 
 	if (iseq(arg, "sta"))
 		list_stations(s);
 	else if (iseq(arg, "scan") || iseq(arg, "ap"))
 		list_scan(s);
 	else if (iseq(arg, "chan") || iseq(arg, "freq"))
 		list_channels(s, 1);
 	else if (iseq(arg, "active"))
 		list_channels(s, 0);
 	else if (iseq(arg, "keys"))
 		list_keys(s);
 	else if (iseq(arg, "caps"))
 		list_capabilities(s);
 	else if (iseq(arg, "wme") || iseq(arg, "wmm"))
 		list_wme(s);
 	else if (iseq(arg, "mac"))
 		list_mac(s);
 	else if (iseq(arg, "txpow"))
 		list_txpow(s);
 	else if (iseq(arg, "roam"))
 		list_roam(s);
 	else if (iseq(arg, "txparam") || iseq(arg, "txparm"))
 		list_txparams(s);
 	else if (iseq(arg, "regdomain"))
 		list_regdomain(s, 1);
 	else if (iseq(arg, "countries"))
 		list_countries();
 	else if (iseq(arg, "mesh"))
 		list_mesh(s);
 	else
 		errx(1, "Don't know how to list %s for %s", arg, name);
 	LINE_BREAK();
 #undef iseq
 }
 
 static enum ieee80211_opmode
 get80211opmode(int s)
 {
 	struct ifmediareq ifmr;
 
 	(void) memset(&ifmr, 0, sizeof(ifmr));
 	(void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
 
 	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
 		if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
 			if (ifmr.ifm_current & IFM_FLAG0)
 				return IEEE80211_M_AHDEMO;
 			else
 				return IEEE80211_M_IBSS;
 		}
 		if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
 			return IEEE80211_M_HOSTAP;
 		if (ifmr.ifm_current & IFM_IEEE80211_IBSS)
 			return IEEE80211_M_IBSS;
 		if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
 			return IEEE80211_M_MONITOR;
 		if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
 			return IEEE80211_M_MBSS;
 	}
 	return IEEE80211_M_STA;
 }
 
 #if 0
 static void
 printcipher(int s, struct ieee80211req *ireq, int keylenop)
 {
 	switch (ireq->i_val) {
 	case IEEE80211_CIPHER_WEP:
 		ireq->i_type = keylenop;
 		if (ioctl(s, SIOCG80211, ireq) != -1)
 			printf("WEP-%s", 
 			    ireq->i_len <= 5 ? "40" :
 			    ireq->i_len <= 13 ? "104" : "128");
 		else
 			printf("WEP");
 		break;
 	case IEEE80211_CIPHER_TKIP:
 		printf("TKIP");
 		break;
 	case IEEE80211_CIPHER_AES_OCB:
 		printf("AES-OCB");
 		break;
 	case IEEE80211_CIPHER_AES_CCM:
 		printf("AES-CCM");
 		break;
 	case IEEE80211_CIPHER_CKIP:
 		printf("CKIP");
 		break;
 	case IEEE80211_CIPHER_NONE:
 		printf("NONE");
 		break;
 	default:
 		printf("UNKNOWN (0x%x)", ireq->i_val);
 		break;
 	}
 }
 #endif
 
 static void
 printkey(const struct ieee80211req_key *ik)
 {
 	static const uint8_t zerodata[IEEE80211_KEYBUF_SIZE];
 	u_int keylen = ik->ik_keylen;
 	int printcontents;
 
 	printcontents = printkeys &&
 		(memcmp(ik->ik_keydata, zerodata, keylen) != 0 || verbose);
 	if (printcontents)
 		LINE_BREAK();
 	switch (ik->ik_type) {
 	case IEEE80211_CIPHER_WEP:
 		/* compatibility */
 		LINE_CHECK("wepkey %u:%s", ik->ik_keyix+1,
 		    keylen <= 5 ? "40-bit" :
 		    keylen <= 13 ? "104-bit" : "128-bit");
 		break;
 	case IEEE80211_CIPHER_TKIP:
 		if (keylen > 128/8)
 			keylen -= 128/8;	/* ignore MIC for now */
 		LINE_CHECK("TKIP %u:%u-bit", ik->ik_keyix+1, 8*keylen);
 		break;
 	case IEEE80211_CIPHER_AES_OCB:
 		LINE_CHECK("AES-OCB %u:%u-bit", ik->ik_keyix+1, 8*keylen);
 		break;
 	case IEEE80211_CIPHER_AES_CCM:
 		LINE_CHECK("AES-CCM %u:%u-bit", ik->ik_keyix+1, 8*keylen);
 		break;
 	case IEEE80211_CIPHER_CKIP:
 		LINE_CHECK("CKIP %u:%u-bit", ik->ik_keyix+1, 8*keylen);
 		break;
 	case IEEE80211_CIPHER_NONE:
 		LINE_CHECK("NULL %u:%u-bit", ik->ik_keyix+1, 8*keylen);
 		break;
 	default:
 		LINE_CHECK("UNKNOWN (0x%x) %u:%u-bit",
 			ik->ik_type, ik->ik_keyix+1, 8*keylen);
 		break;
 	}
 	if (printcontents) {
 		u_int i;
 
 		printf(" <");
 		for (i = 0; i < keylen; i++)
 			printf("%02x", ik->ik_keydata[i]);
 		printf(">");
 		if (ik->ik_type != IEEE80211_CIPHER_WEP &&
 		    (ik->ik_keyrsc != 0 || verbose))
 			printf(" rsc %ju", (uintmax_t)ik->ik_keyrsc);
 		if (ik->ik_type != IEEE80211_CIPHER_WEP &&
 		    (ik->ik_keytsc != 0 || verbose))
 			printf(" tsc %ju", (uintmax_t)ik->ik_keytsc);
 		if (ik->ik_flags != 0 && verbose) {
 			const char *sep = " ";
 
 			if (ik->ik_flags & IEEE80211_KEY_XMIT)
 				printf("%stx", sep), sep = "+";
 			if (ik->ik_flags & IEEE80211_KEY_RECV)
 				printf("%srx", sep), sep = "+";
 			if (ik->ik_flags & IEEE80211_KEY_DEFAULT)
 				printf("%sdef", sep), sep = "+";
 		}
 		LINE_BREAK();
 	}
 }
 
 static void
 printrate(const char *tag, int v, int defrate, int defmcs)
 {
 	if ((v & IEEE80211_RATE_MCS) == 0) {
 		if (v != defrate) {
 			if (v & 1)
 				LINE_CHECK("%s %d.5", tag, v/2);
 			else
 				LINE_CHECK("%s %d", tag, v/2);
 		}
 	} else {
 		if (v != defmcs)
 			LINE_CHECK("%s %d", tag, v &~ 0x80);
 	}
 }
 
 static int
 getid(int s, int ix, void *data, size_t len, int *plen, int mesh)
 {
 	struct ieee80211req ireq;
 
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
 	ireq.i_type = (!mesh) ? IEEE80211_IOC_SSID : IEEE80211_IOC_MESH_ID;
 	ireq.i_val = ix;
 	ireq.i_data = data;
 	ireq.i_len = len;
 	if (ioctl(s, SIOCG80211, &ireq) < 0)
 		return -1;
 	*plen = ireq.i_len;
 	return 0;
 }
 
 static int
 getdevicename(int s, void *data, size_t len, int *plen)
 {
 	struct ieee80211req ireq;
 
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
 	ireq.i_type = IEEE80211_IOC_IC_NAME;
 	ireq.i_val = -1;
 	ireq.i_data = data;
 	ireq.i_len = len;
 	if (ioctl(s, SIOCG80211, &ireq) < 0)
 		return (-1);
 	*plen = ireq.i_len;
 	return (0);
 }
 
 static void
 ieee80211_status(int s)
 {
 	static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
 	enum ieee80211_opmode opmode = get80211opmode(s);
 	int i, num, wpa, wme, bgscan, bgscaninterval, val, len, wepmode;
 	uint8_t data[32];
 	const struct ieee80211_channel *c;
 	const struct ieee80211_roamparam *rp;
 	const struct ieee80211_txparam *tp;
 
 	if (getid(s, -1, data, sizeof(data), &len, 0) < 0) {
 		/* If we can't get the SSID, this isn't an 802.11 device. */
 		return;
 	}
 
 	/*
 	 * Invalidate cached state so printing status for multiple
 	 * if's doesn't reuse the first interfaces' cached state.
 	 */
 	gotcurchan = 0;
 	gotroam = 0;
 	gottxparams = 0;
 	gothtconf = 0;
 	gotregdomain = 0;
 
 	printf("\t");
 	if (opmode == IEEE80211_M_MBSS) {
 		printf("meshid ");
 		getid(s, 0, data, sizeof(data), &len, 1);
 		print_string(data, len);
 	} else {
 		if (get80211val(s, IEEE80211_IOC_NUMSSIDS, &num) < 0)
 			num = 0;
 		printf("ssid ");
 		if (num > 1) {
 			for (i = 0; i < num; i++) {
 				if (getid(s, i, data, sizeof(data), &len, 0) >= 0 && len > 0) {
 					printf(" %d:", i + 1);
 					print_string(data, len);
 				}
 			}
 		} else
 			print_string(data, len);
 	}
 	c = getcurchan(s);
 	if (c->ic_freq != IEEE80211_CHAN_ANY) {
 		char buf[14];
 		printf(" channel %d (%u MHz%s)", c->ic_ieee, c->ic_freq,
 			get_chaninfo(c, 1, buf, sizeof(buf)));
 	} else if (verbose)
 		printf(" channel UNDEF");
 
 	if (get80211(s, IEEE80211_IOC_BSSID, data, IEEE80211_ADDR_LEN) >= 0 &&
 	    (memcmp(data, zerobssid, sizeof(zerobssid)) != 0 || verbose)) {
 		printf(" bssid %s", ether_ntoa((struct ether_addr *)data));
 		printbssidname((struct ether_addr *)data);
 	}
 
 	if (get80211len(s, IEEE80211_IOC_STATIONNAME, data, sizeof(data), &len) != -1) {
 		printf("\n\tstationname ");
 		print_string(data, len);
 	}
 
 	spacer = ' ';		/* force first break */
 	LINE_BREAK();
 
 	list_regdomain(s, 0);
 
 	wpa = 0;
 	if (get80211val(s, IEEE80211_IOC_AUTHMODE, &val) != -1) {
 		switch (val) {
 		case IEEE80211_AUTH_NONE:
 			LINE_CHECK("authmode NONE");
 			break;
 		case IEEE80211_AUTH_OPEN:
 			LINE_CHECK("authmode OPEN");
 			break;
 		case IEEE80211_AUTH_SHARED:
 			LINE_CHECK("authmode SHARED");
 			break;
 		case IEEE80211_AUTH_8021X:
 			LINE_CHECK("authmode 802.1x");
 			break;
 		case IEEE80211_AUTH_WPA:
 			if (get80211val(s, IEEE80211_IOC_WPA, &wpa) < 0)
 				wpa = 1;	/* default to WPA1 */
 			switch (wpa) {
 			case 2:
 				LINE_CHECK("authmode WPA2/802.11i");
 				break;
 			case 3:
 				LINE_CHECK("authmode WPA1+WPA2/802.11i");
 				break;
 			default:
 				LINE_CHECK("authmode WPA");
 				break;
 			}
 			break;
 		case IEEE80211_AUTH_AUTO:
 			LINE_CHECK("authmode AUTO");
 			break;
 		default:
 			LINE_CHECK("authmode UNKNOWN (0x%x)", val);
 			break;
 		}
 	}
 
 	if (wpa || verbose) {
 		if (get80211val(s, IEEE80211_IOC_WPS, &val) != -1) {
 			if (val)
 				LINE_CHECK("wps");
 			else if (verbose)
 				LINE_CHECK("-wps");
 		}
 		if (get80211val(s, IEEE80211_IOC_TSN, &val) != -1) {
 			if (val)
 				LINE_CHECK("tsn");
 			else if (verbose)
 				LINE_CHECK("-tsn");
 		}
 		if (ioctl(s, IEEE80211_IOC_COUNTERMEASURES, &val) != -1) {
 			if (val)
 				LINE_CHECK("countermeasures");
 			else if (verbose)
 				LINE_CHECK("-countermeasures");
 		}
 #if 0
 		/* XXX not interesting with WPA done in user space */
 		ireq.i_type = IEEE80211_IOC_KEYMGTALGS;
 		if (ioctl(s, SIOCG80211, &ireq) != -1) {
 		}
 
 		ireq.i_type = IEEE80211_IOC_MCASTCIPHER;
 		if (ioctl(s, SIOCG80211, &ireq) != -1) {
 			LINE_CHECK("mcastcipher ");
 			printcipher(s, &ireq, IEEE80211_IOC_MCASTKEYLEN);
 			spacer = ' ';
 		}
 
 		ireq.i_type = IEEE80211_IOC_UCASTCIPHER;
 		if (ioctl(s, SIOCG80211, &ireq) != -1) {
 			LINE_CHECK("ucastcipher ");
 			printcipher(s, &ireq, IEEE80211_IOC_UCASTKEYLEN);
 		}
 
 		if (wpa & 2) {
 			ireq.i_type = IEEE80211_IOC_RSNCAPS;
 			if (ioctl(s, SIOCG80211, &ireq) != -1) {
 				LINE_CHECK("RSN caps 0x%x", ireq.i_val);
 				spacer = ' ';
 			}
 		}
 
 		ireq.i_type = IEEE80211_IOC_UCASTCIPHERS;
 		if (ioctl(s, SIOCG80211, &ireq) != -1) {
 		}
 #endif
 	}
 
 	if (get80211val(s, IEEE80211_IOC_WEP, &wepmode) != -1 &&
 	    wepmode != IEEE80211_WEP_NOSUP) {
 
 		switch (wepmode) {
 		case IEEE80211_WEP_OFF:
 			LINE_CHECK("privacy OFF");
 			break;
 		case IEEE80211_WEP_ON:
 			LINE_CHECK("privacy ON");
 			break;
 		case IEEE80211_WEP_MIXED:
 			LINE_CHECK("privacy MIXED");
 			break;
 		default:
 			LINE_CHECK("privacy UNKNOWN (0x%x)", wepmode);
 			break;
 		}
 
 		/*
 		 * If we get here then we've got WEP support so we need
 		 * to print WEP status.
 		 */
 
 		if (get80211val(s, IEEE80211_IOC_WEPTXKEY, &val) < 0) {
 			warn("WEP support, but no tx key!");
 			goto end;
 		}
 		if (val != -1)
 			LINE_CHECK("deftxkey %d", val+1);
 		else if (wepmode != IEEE80211_WEP_OFF || verbose)
 			LINE_CHECK("deftxkey UNDEF");
 
 		if (get80211val(s, IEEE80211_IOC_NUMWEPKEYS, &num) < 0) {
 			warn("WEP support, but no NUMWEPKEYS support!");
 			goto end;
 		}
 
 		for (i = 0; i < num; i++) {
 			struct ieee80211req_key ik;
 
 			memset(&ik, 0, sizeof(ik));
 			ik.ik_keyix = i;
 			if (get80211(s, IEEE80211_IOC_WPAKEY, &ik, sizeof(ik)) < 0) {
 				warn("WEP support, but can get keys!");
 				goto end;
 			}
 			if (ik.ik_keylen != 0) {
 				if (verbose)
 					LINE_BREAK();
 				printkey(&ik);
 			}
 		}
 		if (i > 0 && verbose)
 			LINE_BREAK();
 end:
 		;
 	}
 
 	if (get80211val(s, IEEE80211_IOC_POWERSAVE, &val) != -1 &&
 	    val != IEEE80211_POWERSAVE_NOSUP ) {
 		if (val != IEEE80211_POWERSAVE_OFF || verbose) {
 			switch (val) {
 			case IEEE80211_POWERSAVE_OFF:
 				LINE_CHECK("powersavemode OFF");
 				break;
 			case IEEE80211_POWERSAVE_CAM:
 				LINE_CHECK("powersavemode CAM");
 				break;
 			case IEEE80211_POWERSAVE_PSP:
 				LINE_CHECK("powersavemode PSP");
 				break;
 			case IEEE80211_POWERSAVE_PSP_CAM:
 				LINE_CHECK("powersavemode PSP-CAM");
 				break;
 			}
 			if (get80211val(s, IEEE80211_IOC_POWERSAVESLEEP, &val) != -1)
 				LINE_CHECK("powersavesleep %d", val);
 		}
 	}
 
 	if (get80211val(s, IEEE80211_IOC_TXPOWER, &val) != -1) {
 		if (val & 1)
 			LINE_CHECK("txpower %d.5", val/2);
 		else
 			LINE_CHECK("txpower %d", val/2);
 	}
 	if (verbose) {
 		if (get80211val(s, IEEE80211_IOC_TXPOWMAX, &val) != -1)
 			LINE_CHECK("txpowmax %.1f", val/2.);
 	}
 
 	if (get80211val(s, IEEE80211_IOC_DOTD, &val) != -1) {
 		if (val)
 			LINE_CHECK("dotd");
 		else if (verbose)
 			LINE_CHECK("-dotd");
 	}
 
 	if (get80211val(s, IEEE80211_IOC_RTSTHRESHOLD, &val) != -1) {
 		if (val != IEEE80211_RTS_MAX || verbose)
 			LINE_CHECK("rtsthreshold %d", val);
 	}
 
 	if (get80211val(s, IEEE80211_IOC_FRAGTHRESHOLD, &val) != -1) {
 		if (val != IEEE80211_FRAG_MAX || verbose)
 			LINE_CHECK("fragthreshold %d", val);
 	}
 	if (opmode == IEEE80211_M_STA || verbose) {
 		if (get80211val(s, IEEE80211_IOC_BMISSTHRESHOLD, &val) != -1) {
 			if (val != IEEE80211_HWBMISS_MAX || verbose)
 				LINE_CHECK("bmiss %d", val);
 		}
 	}
 
 	if (!verbose) {
 		gettxparams(s);
 		tp = &txparams.params[chan2mode(c)];
 		printrate("ucastrate", tp->ucastrate,
 		    IEEE80211_FIXED_RATE_NONE, IEEE80211_FIXED_RATE_NONE);
 		printrate("mcastrate", tp->mcastrate, 2*1,
 		    IEEE80211_RATE_MCS|0);
 		printrate("mgmtrate", tp->mgmtrate, 2*1,
 		    IEEE80211_RATE_MCS|0);
 		if (tp->maxretry != 6)		/* XXX */
 			LINE_CHECK("maxretry %d", tp->maxretry);
 	} else {
 		LINE_BREAK();
 		list_txparams(s);
 	}
 
 	bgscaninterval = -1;
 	(void) get80211val(s, IEEE80211_IOC_BGSCAN_INTERVAL, &bgscaninterval);
 
 	if (get80211val(s, IEEE80211_IOC_SCANVALID, &val) != -1) {
 		if (val != bgscaninterval || verbose)
 			LINE_CHECK("scanvalid %u", val);
 	}
 
 	bgscan = 0;
 	if (get80211val(s, IEEE80211_IOC_BGSCAN, &bgscan) != -1) {
 		if (bgscan)
 			LINE_CHECK("bgscan");
 		else if (verbose)
 			LINE_CHECK("-bgscan");
 	}
 	if (bgscan || verbose) {
 		if (bgscaninterval != -1)
 			LINE_CHECK("bgscanintvl %u", bgscaninterval);
 		if (get80211val(s, IEEE80211_IOC_BGSCAN_IDLE, &val) != -1)
 			LINE_CHECK("bgscanidle %u", val);
 		if (!verbose) {
 			getroam(s);
 			rp = &roamparams.params[chan2mode(c)];
 			if (rp->rssi & 1)
 				LINE_CHECK("roam:rssi %u.5", rp->rssi/2);
 			else
 				LINE_CHECK("roam:rssi %u", rp->rssi/2);
 			LINE_CHECK("roam:rate %s%u",
 			    (rp->rate & IEEE80211_RATE_MCS) ? "MCS " : "",
 			    get_rate_value(rp->rate));
 		} else {
 			LINE_BREAK();
 			list_roam(s);
 			LINE_BREAK();
 		}
 	}
 
 	if (IEEE80211_IS_CHAN_ANYG(c) || verbose) {
 		if (get80211val(s, IEEE80211_IOC_PUREG, &val) != -1) {
 			if (val)
 				LINE_CHECK("pureg");
 			else if (verbose)
 				LINE_CHECK("-pureg");
 		}
 		if (get80211val(s, IEEE80211_IOC_PROTMODE, &val) != -1) {
 			switch (val) {
 			case IEEE80211_PROTMODE_OFF:
 				LINE_CHECK("protmode OFF");
 				break;
 			case IEEE80211_PROTMODE_CTS:
 				LINE_CHECK("protmode CTS");
 				break;
 			case IEEE80211_PROTMODE_RTSCTS:
 				LINE_CHECK("protmode RTSCTS");
 				break;
 			default:
 				LINE_CHECK("protmode UNKNOWN (0x%x)", val);
 				break;
 			}
 		}
 	}
 
 	if (IEEE80211_IS_CHAN_HT(c) || verbose) {
 		gethtconf(s);
 		switch (htconf & 3) {
 		case 0:
 		case 2:
 			LINE_CHECK("-ht");
 			break;
 		case 1:
 			LINE_CHECK("ht20");
 			break;
 		case 3:
 			if (verbose)
 				LINE_CHECK("ht");
 			break;
 		}
 		if (get80211val(s, IEEE80211_IOC_HTCOMPAT, &val) != -1) {
 			if (!val)
 				LINE_CHECK("-htcompat");
 			else if (verbose)
 				LINE_CHECK("htcompat");
 		}
 		if (get80211val(s, IEEE80211_IOC_AMPDU, &val) != -1) {
 			switch (val) {
 			case 0:
 				LINE_CHECK("-ampdu");
 				break;
 			case 1:
 				LINE_CHECK("ampdutx -ampdurx");
 				break;
 			case 2:
 				LINE_CHECK("-ampdutx ampdurx");
 				break;
 			case 3:
 				if (verbose)
 					LINE_CHECK("ampdu");
 				break;
 			}
 		}
 		/* XXX 11ac density/size is different */
 		if (get80211val(s, IEEE80211_IOC_AMPDU_LIMIT, &val) != -1) {
 			switch (val) {
 			case IEEE80211_HTCAP_MAXRXAMPDU_8K:
 				LINE_CHECK("ampdulimit 8k");
 				break;
 			case IEEE80211_HTCAP_MAXRXAMPDU_16K:
 				LINE_CHECK("ampdulimit 16k");
 				break;
 			case IEEE80211_HTCAP_MAXRXAMPDU_32K:
 				LINE_CHECK("ampdulimit 32k");
 				break;
 			case IEEE80211_HTCAP_MAXRXAMPDU_64K:
 				LINE_CHECK("ampdulimit 64k");
 				break;
 			}
 		}
 		/* XXX 11ac density/size is different */
 		if (get80211val(s, IEEE80211_IOC_AMPDU_DENSITY, &val) != -1) {
 			switch (val) {
 			case IEEE80211_HTCAP_MPDUDENSITY_NA:
 				if (verbose)
 					LINE_CHECK("ampdudensity NA");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_025:
 				LINE_CHECK("ampdudensity .25");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_05:
 				LINE_CHECK("ampdudensity .5");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_1:
 				LINE_CHECK("ampdudensity 1");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_2:
 				LINE_CHECK("ampdudensity 2");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_4:
 				LINE_CHECK("ampdudensity 4");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_8:
 				LINE_CHECK("ampdudensity 8");
 				break;
 			case IEEE80211_HTCAP_MPDUDENSITY_16:
 				LINE_CHECK("ampdudensity 16");
 				break;
 			}
 		}
 		if (get80211val(s, IEEE80211_IOC_AMSDU, &val) != -1) {
 			switch (val) {
 			case 0:
 				LINE_CHECK("-amsdu");
 				break;
 			case 1:
 				LINE_CHECK("amsdutx -amsdurx");
 				break;
 			case 2:
 				LINE_CHECK("-amsdutx amsdurx");
 				break;
 			case 3:
 				if (verbose)
 					LINE_CHECK("amsdu");
 				break;
 			}
 		}
 		/* XXX amsdu limit */
 		if (get80211val(s, IEEE80211_IOC_SHORTGI, &val) != -1) {
 			if (val)
 				LINE_CHECK("shortgi");
 			else if (verbose)
 				LINE_CHECK("-shortgi");
 		}
 		if (get80211val(s, IEEE80211_IOC_HTPROTMODE, &val) != -1) {
 			if (val == IEEE80211_PROTMODE_OFF)
 				LINE_CHECK("htprotmode OFF");
 			else if (val != IEEE80211_PROTMODE_RTSCTS)
 				LINE_CHECK("htprotmode UNKNOWN (0x%x)", val);
 			else if (verbose)
 				LINE_CHECK("htprotmode RTSCTS");
 		}
 		if (get80211val(s, IEEE80211_IOC_PUREN, &val) != -1) {
 			if (val)
 				LINE_CHECK("puren");
 			else if (verbose)
 				LINE_CHECK("-puren");
 		}
 		if (get80211val(s, IEEE80211_IOC_SMPS, &val) != -1) {
 			if (val == IEEE80211_HTCAP_SMPS_DYNAMIC)
 				LINE_CHECK("smpsdyn");
 			else if (val == IEEE80211_HTCAP_SMPS_ENA)
 				LINE_CHECK("smps");
 			else if (verbose)
 				LINE_CHECK("-smps");
 		}
 		if (get80211val(s, IEEE80211_IOC_RIFS, &val) != -1) {
 			if (val)
 				LINE_CHECK("rifs");
 			else if (verbose)
 				LINE_CHECK("-rifs");
 		}
 
 		/* XXX VHT STBC? */
 		if (get80211val(s, IEEE80211_IOC_STBC, &val) != -1) {
 			switch (val) {
 			case 0:
 				LINE_CHECK("-stbc");
 				break;
 			case 1:
 				LINE_CHECK("stbctx -stbcrx");
 				break;
 			case 2:
 				LINE_CHECK("-stbctx stbcrx");
 				break;
 			case 3:
 				if (verbose)
 					LINE_CHECK("stbc");
 				break;
 			}
 		}
 		if (get80211val(s, IEEE80211_IOC_LDPC, &val) != -1) {
 			switch (val) {
 			case 0:
 				LINE_CHECK("-ldpc");
 				break;
 			case 1:
 				LINE_CHECK("ldpctx -ldpcrx");
 				break;
 			case 2:
 				LINE_CHECK("-ldpctx ldpcrx");
 				break;
 			case 3:
 				if (verbose)
 					LINE_CHECK("ldpc");
 				break;
 			}
 		}
 		if (get80211val(s, IEEE80211_IOC_UAPSD, &val) != -1) {
 			switch (val) {
 			case 0:
 				LINE_CHECK("-uapsd");
 				break;
 			case 1:
 				LINE_CHECK("uapsd");
 				break;
 			}
 		}
 	}
 
 	if (IEEE80211_IS_CHAN_VHT(c) || verbose) {
 		getvhtconf(s);
 		if (vhtconf & IEEE80211_FVHT_VHT)
 			LINE_CHECK("vht");
 		else
 			LINE_CHECK("-vht");
 		if (vhtconf & IEEE80211_FVHT_USEVHT40)
 			LINE_CHECK("vht40");
 		else
 			LINE_CHECK("-vht40");
 		if (vhtconf & IEEE80211_FVHT_USEVHT80)
 			LINE_CHECK("vht80");
 		else
 			LINE_CHECK("-vht80");
 		if (vhtconf & IEEE80211_FVHT_USEVHT160)
 			LINE_CHECK("vht160");
 		else
 			LINE_CHECK("-vht160");
 		if (vhtconf & IEEE80211_FVHT_USEVHT80P80)
 			LINE_CHECK("vht80p80");
 		else
 			LINE_CHECK("-vht80p80");
 	}
 
 	if (get80211val(s, IEEE80211_IOC_WME, &wme) != -1) {
 		if (wme)
 			LINE_CHECK("wme");
 		else if (verbose)
 			LINE_CHECK("-wme");
 	} else
 		wme = 0;
 
 	if (get80211val(s, IEEE80211_IOC_BURST, &val) != -1) {
 		if (val)
 			LINE_CHECK("burst");
 		else if (verbose)
 			LINE_CHECK("-burst");
 	}
 
 	if (get80211val(s, IEEE80211_IOC_FF, &val) != -1) {
 		if (val)
 			LINE_CHECK("ff");
 		else if (verbose)
 			LINE_CHECK("-ff");
 	}
 	if (get80211val(s, IEEE80211_IOC_TURBOP, &val) != -1) {
 		if (val)
 			LINE_CHECK("dturbo");
 		else if (verbose)
 			LINE_CHECK("-dturbo");
 	}
 	if (get80211val(s, IEEE80211_IOC_DWDS, &val) != -1) {
 		if (val)
 			LINE_CHECK("dwds");
 		else if (verbose)
 			LINE_CHECK("-dwds");
 	}
 
 	if (opmode == IEEE80211_M_HOSTAP) {
 		if (get80211val(s, IEEE80211_IOC_HIDESSID, &val) != -1) {
 			if (val)
 				LINE_CHECK("hidessid");
 			else if (verbose)
 				LINE_CHECK("-hidessid");
 		}
 		if (get80211val(s, IEEE80211_IOC_APBRIDGE, &val) != -1) {
 			if (!val)
 				LINE_CHECK("-apbridge");
 			else if (verbose)
 				LINE_CHECK("apbridge");
 		}
 		if (get80211val(s, IEEE80211_IOC_DTIM_PERIOD, &val) != -1)
 			LINE_CHECK("dtimperiod %u", val);
 
 		if (get80211val(s, IEEE80211_IOC_DOTH, &val) != -1) {
 			if (!val)
 				LINE_CHECK("-doth");
 			else if (verbose)
 				LINE_CHECK("doth");
 		}
 		if (get80211val(s, IEEE80211_IOC_DFS, &val) != -1) {
 			if (!val)
 				LINE_CHECK("-dfs");
 			else if (verbose)
 				LINE_CHECK("dfs");
 		}
 		if (get80211val(s, IEEE80211_IOC_INACTIVITY, &val) != -1) {
 			if (!val)
 				LINE_CHECK("-inact");
 			else if (verbose)
 				LINE_CHECK("inact");
 		}
 	} else {
 		if (get80211val(s, IEEE80211_IOC_ROAMING, &val) != -1) {
 			if (val != IEEE80211_ROAMING_AUTO || verbose) {
 				switch (val) {
 				case IEEE80211_ROAMING_DEVICE:
 					LINE_CHECK("roaming DEVICE");
 					break;
 				case IEEE80211_ROAMING_AUTO:
 					LINE_CHECK("roaming AUTO");
 					break;
 				case IEEE80211_ROAMING_MANUAL:
 					LINE_CHECK("roaming MANUAL");
 					break;
 				default:
 					LINE_CHECK("roaming UNKNOWN (0x%x)",
 						val);
 					break;
 				}
 			}
 		}
 	}
 
 	if (opmode == IEEE80211_M_AHDEMO) {
 		if (get80211val(s, IEEE80211_IOC_TDMA_SLOT, &val) != -1)
 			LINE_CHECK("tdmaslot %u", val);
 		if (get80211val(s, IEEE80211_IOC_TDMA_SLOTCNT, &val) != -1)
 			LINE_CHECK("tdmaslotcnt %u", val);
 		if (get80211val(s, IEEE80211_IOC_TDMA_SLOTLEN, &val) != -1)
 			LINE_CHECK("tdmaslotlen %u", val);
 		if (get80211val(s, IEEE80211_IOC_TDMA_BINTERVAL, &val) != -1)
 			LINE_CHECK("tdmabintval %u", val);
 	} else if (get80211val(s, IEEE80211_IOC_BEACON_INTERVAL, &val) != -1) {
 		/* XXX default define not visible */
 		if (val != 100 || verbose)
 			LINE_CHECK("bintval %u", val);
 	}
 
 	if (wme && verbose) {
 		LINE_BREAK();
 		list_wme(s);
 	}
 
 	if (opmode == IEEE80211_M_MBSS) {
 		if (get80211val(s, IEEE80211_IOC_MESH_TTL, &val) != -1) {
 			LINE_CHECK("meshttl %u", val);
 		}
 		if (get80211val(s, IEEE80211_IOC_MESH_AP, &val) != -1) {
 			if (val)
 				LINE_CHECK("meshpeering");
 			else
 				LINE_CHECK("-meshpeering");
 		}
 		if (get80211val(s, IEEE80211_IOC_MESH_FWRD, &val) != -1) {
 			if (val)
 				LINE_CHECK("meshforward");
 			else
 				LINE_CHECK("-meshforward");
 		}
 		if (get80211val(s, IEEE80211_IOC_MESH_GATE, &val) != -1) {
 			if (val)
 				LINE_CHECK("meshgate");
 			else
 				LINE_CHECK("-meshgate");
 		}
 		if (get80211len(s, IEEE80211_IOC_MESH_PR_METRIC, data, 12,
 		    &len) != -1) {
 			data[len] = '\0';
 			LINE_CHECK("meshmetric %s", data);
 		}
 		if (get80211len(s, IEEE80211_IOC_MESH_PR_PATH, data, 12,
 		    &len) != -1) {
 			data[len] = '\0';
 			LINE_CHECK("meshpath %s", data);
 		}
 		if (get80211val(s, IEEE80211_IOC_HWMP_ROOTMODE, &val) != -1) {
 			switch (val) {
 			case IEEE80211_HWMP_ROOTMODE_DISABLED:
 				LINE_CHECK("hwmprootmode DISABLED");
 				break;
 			case IEEE80211_HWMP_ROOTMODE_NORMAL:
 				LINE_CHECK("hwmprootmode NORMAL");
 				break;
 			case IEEE80211_HWMP_ROOTMODE_PROACTIVE:
 				LINE_CHECK("hwmprootmode PROACTIVE");
 				break;
 			case IEEE80211_HWMP_ROOTMODE_RANN:
 				LINE_CHECK("hwmprootmode RANN");
 				break;
 			default:
 				LINE_CHECK("hwmprootmode UNKNOWN(%d)", val);
 				break;
 			}
 		}
 		if (get80211val(s, IEEE80211_IOC_HWMP_MAXHOPS, &val) != -1) {
 			LINE_CHECK("hwmpmaxhops %u", val);
 		}
 	}
 
 	LINE_BREAK();
 
 	if (getdevicename(s, data, sizeof(data), &len) < 0)
 		return;
 	LINE_CHECK("parent interface: %s", data);
 
 	LINE_BREAK();
 }
 
 static int
 get80211(int s, int type, void *data, int len)
 {
 
 	return (lib80211_get80211(s, name, type, data, len));
 }
 
 static int
 get80211len(int s, int type, void *data, int len, int *plen)
 {
 
 	return (lib80211_get80211len(s, name, type, data, len, plen));
 }
 
 static int
 get80211val(int s, int type, int *val)
 {
 
 	return (lib80211_get80211val(s, name, type, val));
 }
 
 static void
 set80211(int s, int type, int val, int len, void *data)
 {
 	int ret;
 
 	ret = lib80211_set80211(s, name, type, val, len, data);
 	if (ret < 0)
 		err(1, "SIOCS80211");
 }
 
 static const char *
 get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp)
 {
 	int len;
 	int hexstr;
 	u_int8_t *p;
 
 	len = *lenp;
 	p = buf;
 	hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x');
 	if (hexstr)
 		val += 2;
 	for (;;) {
 		if (*val == '\0')
 			break;
 		if (sep != NULL && strchr(sep, *val) != NULL) {
 			val++;
 			break;
 		}
 		if (hexstr) {
 			if (!isxdigit((u_char)val[0])) {
 				warnx("bad hexadecimal digits");
 				return NULL;
 			}
 			if (!isxdigit((u_char)val[1])) {
 				warnx("odd count hexadecimal digits");
 				return NULL;
 			}
 		}
 		if (p >= buf + len) {
 			if (hexstr)
 				warnx("hexadecimal digits too long");
 			else
 				warnx("string too long");
 			return NULL;
 		}
 		if (hexstr) {
 #define	tohex(x)	(isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
 			*p++ = (tohex((u_char)val[0]) << 4) |
 			    tohex((u_char)val[1]);
 #undef tohex
 			val += 2;
 		} else
 			*p++ = *val++;
 	}
 	len = p - buf;
 	/* The string "-" is treated as the empty string. */
 	if (!hexstr && len == 1 && buf[0] == '-') {
 		len = 0;
 		memset(buf, 0, *lenp);
 	} else if (len < *lenp)
 		memset(p, 0, *lenp - len);
 	*lenp = len;
 	return val;
 }
 
 static void
 print_string(const u_int8_t *buf, int len)
 {
 	int i;
 	int hasspc;
 	int utf8;
 
 	i = 0;
 	hasspc = 0;
 
 	setlocale(LC_CTYPE, "");
 	utf8 = strncmp("UTF-8", nl_langinfo(CODESET), 5) == 0;
 
 	for (; i < len; i++) {
 		if (!isprint(buf[i]) && buf[i] != '\0' && !utf8)
 			break;
 		if (isspace(buf[i]))
 			hasspc++;
 	}
 	if (i == len || utf8) {
 		if (hasspc || len == 0 || buf[0] == '\0')
 			printf("\"%.*s\"", len, buf);
 		else
 			printf("%.*s", len, buf);
 	} else {
 		printf("0x");
 		for (i = 0; i < len; i++)
 			printf("%02x", buf[i]);
 	}
 }
 
 static void
 setdefregdomain(int s)
 {
 	struct regdata *rdp = getregdata();
 	const struct regdomain *rd;
 
 	/* Check if regdomain/country was already set by a previous call. */
 	/* XXX is it possible? */
 	if (regdomain.regdomain != 0 ||
 	    regdomain.country != CTRY_DEFAULT)
 		return;
 
 	getregdomain(s);
 
 	/* Check if it was already set by the driver. */
 	if (regdomain.regdomain != 0 ||
 	    regdomain.country != CTRY_DEFAULT)
 		return;
 
 	/* Set FCC/US as default. */
 	rd = lib80211_regdomain_findbysku(rdp, SKU_FCC);
 	if (rd == NULL)
 		errx(1, "FCC regdomain was not found");
 
 	regdomain.regdomain = rd->sku;
 	if (rd->cc != NULL)
 		defaultcountry(rd);
 
 	/* Send changes to net80211. */
 	setregdomain_cb(s, &regdomain);
 
 	/* Cleanup (so it can be overridden by subsequent parameters). */
 	regdomain.regdomain = 0;
 	regdomain.country = CTRY_DEFAULT;
 	regdomain.isocc[0] = 0;
 	regdomain.isocc[1] = 0;
 }
 
 /*
  * Virtual AP cloning support.
  */
 static struct ieee80211_clone_params params = {
 	.icp_opmode	= IEEE80211_M_STA,	/* default to station mode */
 };
 
 static void
 wlan_create(int s, struct ifreq *ifr)
 {
 	static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
 	char orig_name[IFNAMSIZ];
 
 	if (params.icp_parent[0] == '\0')
 		errx(1, "must specify a parent device (wlandev) when creating "
 		    "a wlan device");
 	if (params.icp_opmode == IEEE80211_M_WDS &&
 	    memcmp(params.icp_bssid, zerobssid, sizeof(zerobssid)) == 0)
 		errx(1, "no bssid specified for WDS (use wlanbssid)");
 	ifr->ifr_data = (caddr_t) &params;
 	ioctl_ifcreate(s, ifr);
 
 	/* XXX preserve original name for ifclonecreate(). */
 	strlcpy(orig_name, name, sizeof(orig_name));
 	strlcpy(name, ifr->ifr_name, sizeof(name));
 
 	setdefregdomain(s);
 
 	strlcpy(name, orig_name, sizeof(name));
 }
 
 static
 DECL_CMD_FUNC(set80211clone_wlandev, arg, d)
 {
 	strlcpy(params.icp_parent, arg, IFNAMSIZ);
 }
 
 static
 DECL_CMD_FUNC(set80211clone_wlanbssid, arg, d)
 {
 	const struct ether_addr *ea;
 
 	ea = ether_aton(arg);
 	if (ea == NULL)
 		errx(1, "%s: cannot parse bssid", arg);
 	memcpy(params.icp_bssid, ea->octet, IEEE80211_ADDR_LEN);
 }
 
 static
 DECL_CMD_FUNC(set80211clone_wlanaddr, arg, d)
 {
 	const struct ether_addr *ea;
 
 	ea = ether_aton(arg);
 	if (ea == NULL)
 		errx(1, "%s: cannot parse address", arg);
 	memcpy(params.icp_macaddr, ea->octet, IEEE80211_ADDR_LEN);
 	params.icp_flags |= IEEE80211_CLONE_MACADDR;
 }
 
 static
 DECL_CMD_FUNC(set80211clone_wlanmode, arg, d)
 {
 #define	iseq(a,b)	(strncasecmp(a,b,sizeof(b)-1) == 0)
 	if (iseq(arg, "sta"))
 		params.icp_opmode = IEEE80211_M_STA;
 	else if (iseq(arg, "ahdemo") || iseq(arg, "adhoc-demo"))
 		params.icp_opmode = IEEE80211_M_AHDEMO;
 	else if (iseq(arg, "ibss") || iseq(arg, "adhoc"))
 		params.icp_opmode = IEEE80211_M_IBSS;
 	else if (iseq(arg, "ap") || iseq(arg, "host"))
 		params.icp_opmode = IEEE80211_M_HOSTAP;
 	else if (iseq(arg, "wds"))
 		params.icp_opmode = IEEE80211_M_WDS;
 	else if (iseq(arg, "monitor"))
 		params.icp_opmode = IEEE80211_M_MONITOR;
 	else if (iseq(arg, "tdma")) {
 		params.icp_opmode = IEEE80211_M_AHDEMO;
 		params.icp_flags |= IEEE80211_CLONE_TDMA;
 	} else if (iseq(arg, "mesh") || iseq(arg, "mp")) /* mesh point */
 		params.icp_opmode = IEEE80211_M_MBSS;
 	else
 		errx(1, "Don't know to create %s for %s", arg, name);
 #undef iseq
 }
 
 static void
 set80211clone_beacons(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	/* NB: inverted sense */
 	if (d)
 		params.icp_flags &= ~IEEE80211_CLONE_NOBEACONS;
 	else
 		params.icp_flags |= IEEE80211_CLONE_NOBEACONS;
 }
 
 static void
 set80211clone_bssid(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	if (d)
 		params.icp_flags |= IEEE80211_CLONE_BSSID;
 	else
 		params.icp_flags &= ~IEEE80211_CLONE_BSSID;
 }
 
 static void
 set80211clone_wdslegacy(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	if (d)
 		params.icp_flags |= IEEE80211_CLONE_WDSLEGACY;
 	else
 		params.icp_flags &= ~IEEE80211_CLONE_WDSLEGACY;
 }
 
 static struct cmd ieee80211_cmds[] = {
 	DEF_CMD_ARG("ssid",		set80211ssid),
 	DEF_CMD_ARG("nwid",		set80211ssid),
 	DEF_CMD_ARG("meshid",		set80211meshid),
 	DEF_CMD_ARG("stationname",	set80211stationname),
 	DEF_CMD_ARG("station",		set80211stationname),	/* BSD/OS */
 	DEF_CMD_ARG("channel",		set80211channel),
 	DEF_CMD_ARG("authmode",		set80211authmode),
 	DEF_CMD_ARG("powersavemode",	set80211powersavemode),
 	DEF_CMD("powersave",	1,	set80211powersave),
 	DEF_CMD("-powersave",	0,	set80211powersave),
 	DEF_CMD_ARG("powersavesleep", 	set80211powersavesleep),
 	DEF_CMD_ARG("wepmode",		set80211wepmode),
 	DEF_CMD("wep",		1,	set80211wep),
 	DEF_CMD("-wep",		0,	set80211wep),
 	DEF_CMD_ARG("deftxkey",		set80211weptxkey),
 	DEF_CMD_ARG("weptxkey",		set80211weptxkey),
 	DEF_CMD_ARG("wepkey",		set80211wepkey),
 	DEF_CMD_ARG("nwkey",		set80211nwkey),		/* NetBSD */
 	DEF_CMD("-nwkey",	0,	set80211wep),		/* NetBSD */
 	DEF_CMD_ARG("rtsthreshold",	set80211rtsthreshold),
 	DEF_CMD_ARG("protmode",		set80211protmode),
 	DEF_CMD_ARG("txpower",		set80211txpower),
 	DEF_CMD_ARG("roaming",		set80211roaming),
 	DEF_CMD("wme",		1,	set80211wme),
 	DEF_CMD("-wme",		0,	set80211wme),
 	DEF_CMD("wmm",		1,	set80211wme),
 	DEF_CMD("-wmm",		0,	set80211wme),
 	DEF_CMD("hidessid",	1,	set80211hidessid),
 	DEF_CMD("-hidessid",	0,	set80211hidessid),
 	DEF_CMD("apbridge",	1,	set80211apbridge),
 	DEF_CMD("-apbridge",	0,	set80211apbridge),
 	DEF_CMD_ARG("chanlist",		set80211chanlist),
 	DEF_CMD_ARG("bssid",		set80211bssid),
 	DEF_CMD_ARG("ap",		set80211bssid),
 	DEF_CMD("scan",	0,		set80211scan),
 	DEF_CMD_ARG("list",		set80211list),
 	DEF_CMD_ARG2("cwmin",		set80211cwmin),
 	DEF_CMD_ARG2("cwmax",		set80211cwmax),
 	DEF_CMD_ARG2("aifs",		set80211aifs),
 	DEF_CMD_ARG2("txoplimit",	set80211txoplimit),
 	DEF_CMD_ARG("acm",		set80211acm),
 	DEF_CMD_ARG("-acm",		set80211noacm),
 	DEF_CMD_ARG("ack",		set80211ackpolicy),
 	DEF_CMD_ARG("-ack",		set80211noackpolicy),
 	DEF_CMD_ARG2("bss:cwmin",	set80211bsscwmin),
 	DEF_CMD_ARG2("bss:cwmax",	set80211bsscwmax),
 	DEF_CMD_ARG2("bss:aifs",	set80211bssaifs),
 	DEF_CMD_ARG2("bss:txoplimit",	set80211bsstxoplimit),
 	DEF_CMD_ARG("dtimperiod",	set80211dtimperiod),
 	DEF_CMD_ARG("bintval",		set80211bintval),
 	DEF_CMD("mac:open",	IEEE80211_MACCMD_POLICY_OPEN,	set80211maccmd),
 	DEF_CMD("mac:allow",	IEEE80211_MACCMD_POLICY_ALLOW,	set80211maccmd),
 	DEF_CMD("mac:deny",	IEEE80211_MACCMD_POLICY_DENY,	set80211maccmd),
 	DEF_CMD("mac:radius",	IEEE80211_MACCMD_POLICY_RADIUS,	set80211maccmd),
 	DEF_CMD("mac:flush",	IEEE80211_MACCMD_FLUSH,		set80211maccmd),
 	DEF_CMD("mac:detach",	IEEE80211_MACCMD_DETACH,	set80211maccmd),
 	DEF_CMD_ARG("mac:add",		set80211addmac),
 	DEF_CMD_ARG("mac:del",		set80211delmac),
 	DEF_CMD_ARG("mac:kick",		set80211kickmac),
 	DEF_CMD("pureg",	1,	set80211pureg),
 	DEF_CMD("-pureg",	0,	set80211pureg),
 	DEF_CMD("ff",		1,	set80211fastframes),
 	DEF_CMD("-ff",		0,	set80211fastframes),
 	DEF_CMD("dturbo",	1,	set80211dturbo),
 	DEF_CMD("-dturbo",	0,	set80211dturbo),
 	DEF_CMD("bgscan",	1,	set80211bgscan),
 	DEF_CMD("-bgscan",	0,	set80211bgscan),
 	DEF_CMD_ARG("bgscanidle",	set80211bgscanidle),
 	DEF_CMD_ARG("bgscanintvl",	set80211bgscanintvl),
 	DEF_CMD_ARG("scanvalid",	set80211scanvalid),
 	DEF_CMD("quiet",	1,	set80211quiet),
 	DEF_CMD("-quiet",	0,	set80211quiet),
 	DEF_CMD_ARG("quiet_count",	set80211quietcount),
 	DEF_CMD_ARG("quiet_period",	set80211quietperiod),
 	DEF_CMD_ARG("quiet_duration",	set80211quietduration),
 	DEF_CMD_ARG("quiet_offset",	set80211quietoffset),
 	DEF_CMD_ARG("roam:rssi",	set80211roamrssi),
 	DEF_CMD_ARG("roam:rate",	set80211roamrate),
 	DEF_CMD_ARG("mcastrate",	set80211mcastrate),
 	DEF_CMD_ARG("ucastrate",	set80211ucastrate),
 	DEF_CMD_ARG("mgtrate",		set80211mgtrate),
 	DEF_CMD_ARG("mgmtrate",		set80211mgtrate),
 	DEF_CMD_ARG("maxretry",		set80211maxretry),
 	DEF_CMD_ARG("fragthreshold",	set80211fragthreshold),
 	DEF_CMD("burst",	1,	set80211burst),
 	DEF_CMD("-burst",	0,	set80211burst),
 	DEF_CMD_ARG("bmiss",		set80211bmissthreshold),
 	DEF_CMD_ARG("bmissthreshold",	set80211bmissthreshold),
 	DEF_CMD("shortgi",	1,	set80211shortgi),
 	DEF_CMD("-shortgi",	0,	set80211shortgi),
 	DEF_CMD("ampdurx",	2,	set80211ampdu),
 	DEF_CMD("-ampdurx",	-2,	set80211ampdu),
 	DEF_CMD("ampdutx",	1,	set80211ampdu),
 	DEF_CMD("-ampdutx",	-1,	set80211ampdu),
 	DEF_CMD("ampdu",	3,	set80211ampdu),		/* NB: tx+rx */
 	DEF_CMD("-ampdu",	-3,	set80211ampdu),
 	DEF_CMD_ARG("ampdulimit",	set80211ampdulimit),
 	DEF_CMD_ARG("ampdudensity",	set80211ampdudensity),
 	DEF_CMD("amsdurx",	2,	set80211amsdu),
 	DEF_CMD("-amsdurx",	-2,	set80211amsdu),
 	DEF_CMD("amsdutx",	1,	set80211amsdu),
 	DEF_CMD("-amsdutx",	-1,	set80211amsdu),
 	DEF_CMD("amsdu",	3,	set80211amsdu),		/* NB: tx+rx */
 	DEF_CMD("-amsdu",	-3,	set80211amsdu),
 	DEF_CMD_ARG("amsdulimit",	set80211amsdulimit),
 	DEF_CMD("stbcrx",	2,	set80211stbc),
 	DEF_CMD("-stbcrx",	-2,	set80211stbc),
 	DEF_CMD("stbctx",	1,	set80211stbc),
 	DEF_CMD("-stbctx",	-1,	set80211stbc),
 	DEF_CMD("stbc",		3,	set80211stbc),		/* NB: tx+rx */
 	DEF_CMD("-stbc",	-3,	set80211stbc),
 	DEF_CMD("ldpcrx",	2,	set80211ldpc),
 	DEF_CMD("-ldpcrx",	-2,	set80211ldpc),
 	DEF_CMD("ldpctx",	1,	set80211ldpc),
 	DEF_CMD("-ldpctx",	-1,	set80211ldpc),
 	DEF_CMD("ldpc",		3,	set80211ldpc),		/* NB: tx+rx */
 	DEF_CMD("-ldpc",	-3,	set80211ldpc),
 	DEF_CMD("uapsd",	1,	set80211uapsd),
 	DEF_CMD("-uapsd",	0,	set80211uapsd),
 	DEF_CMD("puren",	1,	set80211puren),
 	DEF_CMD("-puren",	0,	set80211puren),
 	DEF_CMD("doth",		1,	set80211doth),
 	DEF_CMD("-doth",	0,	set80211doth),
 	DEF_CMD("dfs",		1,	set80211dfs),
 	DEF_CMD("-dfs",		0,	set80211dfs),
 	DEF_CMD("htcompat",	1,	set80211htcompat),
 	DEF_CMD("-htcompat",	0,	set80211htcompat),
 	DEF_CMD("dwds",		1,	set80211dwds),
 	DEF_CMD("-dwds",	0,	set80211dwds),
 	DEF_CMD("inact",	1,	set80211inact),
 	DEF_CMD("-inact",	0,	set80211inact),
 	DEF_CMD("tsn",		1,	set80211tsn),
 	DEF_CMD("-tsn",		0,	set80211tsn),
 	DEF_CMD_ARG("regdomain",	set80211regdomain),
 	DEF_CMD_ARG("country",		set80211country),
 	DEF_CMD("indoor",	'I',	set80211location),
 	DEF_CMD("-indoor",	'O',	set80211location),
 	DEF_CMD("outdoor",	'O',	set80211location),
 	DEF_CMD("-outdoor",	'I',	set80211location),
 	DEF_CMD("anywhere",	' ',	set80211location),
 	DEF_CMD("ecm",		1,	set80211ecm),
 	DEF_CMD("-ecm",		0,	set80211ecm),
 	DEF_CMD("dotd",		1,	set80211dotd),
 	DEF_CMD("-dotd",	0,	set80211dotd),
 	DEF_CMD_ARG("htprotmode",	set80211htprotmode),
 	DEF_CMD("ht20",		1,	set80211htconf),
 	DEF_CMD("-ht20",	0,	set80211htconf),
 	DEF_CMD("ht40",		3,	set80211htconf),	/* NB: 20+40 */
 	DEF_CMD("-ht40",	0,	set80211htconf),
 	DEF_CMD("ht",		3,	set80211htconf),	/* NB: 20+40 */
 	DEF_CMD("-ht",		0,	set80211htconf),
 	DEF_CMD("vht",		IEEE80211_FVHT_VHT,		set80211vhtconf),
 	DEF_CMD("-vht",		0,				set80211vhtconf),
 	DEF_CMD("vht40",	IEEE80211_FVHT_USEVHT40,	set80211vhtconf),
 	DEF_CMD("-vht40",	-IEEE80211_FVHT_USEVHT40,	set80211vhtconf),
 	DEF_CMD("vht80",	IEEE80211_FVHT_USEVHT80,	set80211vhtconf),
 	DEF_CMD("-vht80",	-IEEE80211_FVHT_USEVHT80,	set80211vhtconf),
 	DEF_CMD("vht160",	IEEE80211_FVHT_USEVHT160,	set80211vhtconf),
 	DEF_CMD("-vht160",	-IEEE80211_FVHT_USEVHT160,	set80211vhtconf),
 	DEF_CMD("vht80p80",	IEEE80211_FVHT_USEVHT80P80,	set80211vhtconf),
 	DEF_CMD("-vht80p80",	-IEEE80211_FVHT_USEVHT80P80,	set80211vhtconf),
 	DEF_CMD("rifs",		1,	set80211rifs),
 	DEF_CMD("-rifs",	0,	set80211rifs),
 	DEF_CMD("smps",		IEEE80211_HTCAP_SMPS_ENA,	set80211smps),
 	DEF_CMD("smpsdyn",	IEEE80211_HTCAP_SMPS_DYNAMIC,	set80211smps),
 	DEF_CMD("-smps",	IEEE80211_HTCAP_SMPS_OFF,	set80211smps),
 	/* XXX for testing */
 	DEF_CMD_ARG("chanswitch",	set80211chanswitch),
 
 	DEF_CMD_ARG("tdmaslot",		set80211tdmaslot),
 	DEF_CMD_ARG("tdmaslotcnt",	set80211tdmaslotcnt),
 	DEF_CMD_ARG("tdmaslotlen",	set80211tdmaslotlen),
 	DEF_CMD_ARG("tdmabintval",	set80211tdmabintval),
 
 	DEF_CMD_ARG("meshttl",		set80211meshttl),
 	DEF_CMD("meshforward",	1,	set80211meshforward),
 	DEF_CMD("-meshforward",	0,	set80211meshforward),
 	DEF_CMD("meshgate",	1,	set80211meshgate),
 	DEF_CMD("-meshgate",	0,	set80211meshgate),
 	DEF_CMD("meshpeering",	1,	set80211meshpeering),
 	DEF_CMD("-meshpeering",	0,	set80211meshpeering),
 	DEF_CMD_ARG("meshmetric",	set80211meshmetric),
 	DEF_CMD_ARG("meshpath",		set80211meshpath),
 	DEF_CMD("meshrt:flush",	IEEE80211_MESH_RTCMD_FLUSH,	set80211meshrtcmd),
 	DEF_CMD_ARG("meshrt:add",	set80211addmeshrt),
 	DEF_CMD_ARG("meshrt:del",	set80211delmeshrt),
 	DEF_CMD_ARG("hwmprootmode",	set80211hwmprootmode),
 	DEF_CMD_ARG("hwmpmaxhops",	set80211hwmpmaxhops),
 
 	/* vap cloning support */
 	DEF_CLONE_CMD_ARG("wlanaddr",	set80211clone_wlanaddr),
 	DEF_CLONE_CMD_ARG("wlanbssid",	set80211clone_wlanbssid),
 	DEF_CLONE_CMD_ARG("wlandev",	set80211clone_wlandev),
 	DEF_CLONE_CMD_ARG("wlanmode",	set80211clone_wlanmode),
 	DEF_CLONE_CMD("beacons", 1,	set80211clone_beacons),
 	DEF_CLONE_CMD("-beacons", 0,	set80211clone_beacons),
 	DEF_CLONE_CMD("bssid",	1,	set80211clone_bssid),
 	DEF_CLONE_CMD("-bssid",	0,	set80211clone_bssid),
 	DEF_CLONE_CMD("wdslegacy", 1,	set80211clone_wdslegacy),
 	DEF_CLONE_CMD("-wdslegacy", 0,	set80211clone_wdslegacy),
 };
 static struct afswtch af_ieee80211 = {
 	.af_name	= "af_ieee80211",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = ieee80211_status,
 };
 
 static __constructor void
 ieee80211_ctor(void)
 {
-	int i;
-
-	for (i = 0; i < nitems(ieee80211_cmds);  i++)
+	for (size_t i = 0; i < nitems(ieee80211_cmds);  i++)
 		cmd_register(&ieee80211_cmds[i]);
 	af_register(&af_ieee80211);
 	clone_setdefcallback_prefix("wlan", wlan_create);
 }
diff --git a/sbin/ifconfig/iflagg.c b/sbin/ifconfig/iflagg.c
index 48d7450076a9..4040d423cc6a 100644
--- a/sbin/ifconfig/iflagg.c
+++ b/sbin/ifconfig/iflagg.c
@@ -1,355 +1,351 @@
 /*-
  */
 
 #ifndef lint
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_lagg.h>
 #include <net/ieee8023ad_lacp.h>
 #include <net/route.h>
 
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <err.h>
 #include <errno.h>
 
 #include <libifconfig.h>
 
 #include "ifconfig.h"
 
 static struct iflaggparam params = {
 	.lagg_type = LAGG_TYPE_DEFAULT,
 };
 
 static char lacpbuf[120];	/* LACP peer '[(a,a,a),(p,p,p)]' */
 
 static void
 setlaggport(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_reqport rp;
 
 	bzero(&rp, sizeof(rp));
 	strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
 	strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
 
 	/*
 	 * Do not exit with an error here.  Doing so permits a
 	 * failed NIC to take down an entire lagg.
 	 *
 	 * Don't error at all if the port is already in the lagg.
 	 */
 	if (ioctl(s, SIOCSLAGGPORT, &rp) && errno != EEXIST) {
 		warnx("%s %s: SIOCSLAGGPORT: %s",
 		    name, val, strerror(errno));
 		exit_code = 1;
 	}
 }
 
 static void
 unsetlaggport(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_reqport rp;
 
 	bzero(&rp, sizeof(rp));
 	strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
 	strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
 
 	if (ioctl(s, SIOCSLAGGDELPORT, &rp))
 		err(1, "SIOCSLAGGDELPORT");
 }
 
 static void
 setlaggproto(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_protos lpr[] = LAGG_PROTOS;
 	struct lagg_reqall ra;
-	int i;
 
 	bzero(&ra, sizeof(ra));
 	ra.ra_proto = LAGG_PROTO_MAX;
 
-	for (i = 0; i < nitems(lpr); i++) {
+	for (size_t i = 0; i < nitems(lpr); i++) {
 		if (strcmp(val, lpr[i].lpr_name) == 0) {
 			ra.ra_proto = lpr[i].lpr_proto;
 			break;
 		}
 	}
 	if (ra.ra_proto == LAGG_PROTO_MAX)
 		errx(1, "Invalid aggregation protocol: %s", val);
 
 	strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
 	if (ioctl(s, SIOCSLAGG, &ra) != 0)
 		err(1, "SIOCSLAGG");
 }
 
 static void
 setlaggflowidshift(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_reqopts ro;
 
 	bzero(&ro, sizeof(ro));
 	ro.ro_opts = LAGG_OPT_FLOWIDSHIFT;
 	strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
 	ro.ro_flowid_shift = (int)strtol(val, NULL, 10);
 	if (ro.ro_flowid_shift & ~LAGG_OPT_FLOWIDSHIFT_MASK)
 		errx(1, "Invalid flowid_shift option: %s", val);
 	
 	if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
 		err(1, "SIOCSLAGGOPTS");
 }
 
 static void
 setlaggrr_limit(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_reqopts ro;
 	
 	bzero(&ro, sizeof(ro));
 	strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
 	ro.ro_opts = LAGG_OPT_RR_LIMIT;
 	ro.ro_bkt = (uint32_t)strtoul(val, NULL, 10);
 	if (ro.ro_bkt == 0)
 		errx(1, "Invalid round-robin stride: %s", val);
 
 	if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
 		err(1, "SIOCSLAGGOPTS");
 }
 
 static void
 setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_reqopts ro;
 
 	bzero(&ro, sizeof(ro));
 	ro.ro_opts = d;
 	switch (ro.ro_opts) {
 	case LAGG_OPT_USE_FLOWID:
 	case -LAGG_OPT_USE_FLOWID:
 	case LAGG_OPT_USE_NUMA:
 	case -LAGG_OPT_USE_NUMA:
 	case LAGG_OPT_LACP_STRICT:
 	case -LAGG_OPT_LACP_STRICT:
 	case LAGG_OPT_LACP_TXTEST:
 	case -LAGG_OPT_LACP_TXTEST:
 	case LAGG_OPT_LACP_RXTEST:
 	case -LAGG_OPT_LACP_RXTEST:
 	case LAGG_OPT_LACP_FAST_TIMO:
 	case -LAGG_OPT_LACP_FAST_TIMO:
 		break;
 	default:
 		err(1, "Invalid lagg option");
 	}
 	strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
 	
 	if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
 		err(1, "SIOCSLAGGOPTS");
 }
 
 static void
 setlagghash(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct lagg_reqflags rf;
 	char *str, *tmp, *tok;
 
 
 	rf.rf_flags = 0;
 	str = tmp = strdup(val);
 	while ((tok = strsep(&tmp, ",")) != NULL) {
 		if (strcmp(tok, "l2") == 0)
 			rf.rf_flags |= LAGG_F_HASHL2;
 		else if (strcmp(tok, "l3") == 0)
 			rf.rf_flags |= LAGG_F_HASHL3;
 		else if (strcmp(tok, "l4") == 0)
 			rf.rf_flags |= LAGG_F_HASHL4;
 		else
 			errx(1, "Invalid lagghash option: %s", tok);
 	}
 	free(str);
 	if (rf.rf_flags == 0)
 		errx(1, "No lagghash options supplied");
 
 	strlcpy(rf.rf_ifname, name, sizeof(rf.rf_ifname));
 	if (ioctl(s, SIOCSLAGGHASH, &rf))
 		err(1, "SIOCSLAGGHASH");
 }
 
 static char *
 lacp_format_mac(const uint8_t *mac, char *buf, size_t buflen)
 {
 	snprintf(buf, buflen, "%02X-%02X-%02X-%02X-%02X-%02X",
 	    (int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3],
 	    (int)mac[4], (int)mac[5]);
 
 	return (buf);
 }
 
 static char *
 lacp_format_peer(struct lacp_opreq *req, const char *sep)
 {
 	char macbuf1[20];
 	char macbuf2[20];
 
 	snprintf(lacpbuf, sizeof(lacpbuf),
 	    "[(%04X,%s,%04X,%04X,%04X),%s(%04X,%s,%04X,%04X,%04X)]",
 	    req->actor_prio,
 	    lacp_format_mac(req->actor_mac, macbuf1, sizeof(macbuf1)),
 	    req->actor_key, req->actor_portprio, req->actor_portno, sep,
 	    req->partner_prio,
 	    lacp_format_mac(req->partner_mac, macbuf2, sizeof(macbuf2)),
 	    req->partner_key, req->partner_portprio, req->partner_portno);
 
 	return(lacpbuf);
 }
 
 static void
 lagg_status(int s)
 {
 	struct lagg_protos protos[] = LAGG_PROTOS;
 	struct ifconfig_lagg_status *lagg;
 	struct lagg_reqall *ra;
 	struct lagg_reqflags *rf;
 	struct lagg_reqopts *ro;
 	struct lagg_reqport *ports;
 	struct lacp_opreq *lp;
 	const char *proto;
 
 	if (ifconfig_lagg_get_lagg_status(lifh, name, &lagg) == -1)
 		return;
 
 	ra = lagg->ra;
 	rf = lagg->rf;
 	ro = lagg->ro;
 	ports = ra->ra_port;
 
 	proto = "<unknown>";
 	for (size_t i = 0; i < nitems(protos); ++i) {
 		if (ra->ra_proto == protos[i].lpr_proto) {
 			proto = protos[i].lpr_name;
 			break;
 		}
 	}
 	printf("\tlaggproto %s", proto);
 
 	if (rf->rf_flags & LAGG_F_HASHMASK) {
 		const char *sep = "";
 
 		printf(" lagghash ");
 		if (rf->rf_flags & LAGG_F_HASHL2) {
 			printf("%sl2", sep);
 			sep = ",";
 		}
 		if (rf->rf_flags & LAGG_F_HASHL3) {
 			printf("%sl3", sep);
 			sep = ",";
 		}
 		if (rf->rf_flags & LAGG_F_HASHL4) {
 			printf("%sl4", sep);
 			sep = ",";
 		}
 	}
 	putchar('\n');
 	if (verbose) {
 		printf("\tlagg options:\n");
 		printb("\t\tflags", ro->ro_opts, LAGG_OPT_BITS);
 		putchar('\n');
 		printf("\t\tflowid_shift: %d\n", ro->ro_flowid_shift);
 		if (ra->ra_proto == LAGG_PROTO_ROUNDROBIN)
 			printf("\t\trr_limit: %d\n", ro->ro_bkt);
 		printf("\tlagg statistics:\n");
 		printf("\t\tactive ports: %d\n", ro->ro_active);
 		printf("\t\tflapping: %u\n", ro->ro_flapping);
 		if (ra->ra_proto == LAGG_PROTO_LACP) {
 			lp = &ra->ra_lacpreq;
 			printf("\tlag id: %s\n",
 			    lacp_format_peer(lp, "\n\t\t "));
 		}
 	}
 
-	for (size_t i = 0; i < ra->ra_ports; ++i) {
+	for (size_t i = 0; i < (size_t)ra->ra_ports; ++i) {
 		lp = &ports[i].rp_lacpreq;
 		printf("\tlaggport: %s ", ports[i].rp_portname);
 		printb("flags", ports[i].rp_flags, LAGG_PORT_BITS);
 		if (verbose && ra->ra_proto == LAGG_PROTO_LACP)
 			printb(" state", lp->actor_state, LACP_STATE_BITS);
 		putchar('\n');
 		if (verbose && ra->ra_proto == LAGG_PROTO_LACP)
 			printf("\t\t%s\n",
 			    lacp_format_peer(lp, "\n\t\t "));
 	}
 
 	ifconfig_lagg_free_lagg_status(lagg);
 }
 
 static
 DECL_CMD_FUNC(setlaggtype, arg, d)
 {
 	static const struct lagg_types lt[] = LAGG_TYPES;
-	int i;
 
-	for (i = 0; i < nitems(lt); i++) {
+	for (size_t i = 0; i < nitems(lt); i++) {
 		if (strcmp(arg, lt[i].lt_name) == 0) {
 			params.lagg_type = lt[i].lt_value;
 			return;
 		}
 	}
 	errx(1, "invalid lagg type: %s", arg);
 }
 
 static void
 lagg_create(int s, struct ifreq *ifr)
 {
 	ifr->ifr_data = (caddr_t) &params;
 	ioctl_ifcreate(s, ifr);
 }
 
 static struct cmd lagg_cmds[] = {
 	DEF_CLONE_CMD_ARG("laggtype",   setlaggtype),
 	DEF_CMD_ARG("laggport",		setlaggport),
 	DEF_CMD_ARG("-laggport",	unsetlaggport),
 	DEF_CMD_ARG("laggproto",	setlaggproto),
 	DEF_CMD_ARG("lagghash",		setlagghash),
 	DEF_CMD("use_flowid",	LAGG_OPT_USE_FLOWID,	setlaggsetopt),
 	DEF_CMD("-use_flowid",	-LAGG_OPT_USE_FLOWID,	setlaggsetopt),
 	DEF_CMD("use_numa",	LAGG_OPT_USE_NUMA,	setlaggsetopt),
 	DEF_CMD("-use_numa",	-LAGG_OPT_USE_NUMA,	setlaggsetopt),
 	DEF_CMD("lacp_strict",	LAGG_OPT_LACP_STRICT,	setlaggsetopt),
 	DEF_CMD("-lacp_strict",	-LAGG_OPT_LACP_STRICT,	setlaggsetopt),
 	DEF_CMD("lacp_txtest",	LAGG_OPT_LACP_TXTEST,	setlaggsetopt),
 	DEF_CMD("-lacp_txtest",	-LAGG_OPT_LACP_TXTEST,	setlaggsetopt),
 	DEF_CMD("lacp_rxtest",	LAGG_OPT_LACP_RXTEST,	setlaggsetopt),
 	DEF_CMD("-lacp_rxtest",	-LAGG_OPT_LACP_RXTEST,	setlaggsetopt),
 	DEF_CMD("lacp_fast_timeout",	LAGG_OPT_LACP_FAST_TIMO,	setlaggsetopt),
 	DEF_CMD("-lacp_fast_timeout",	-LAGG_OPT_LACP_FAST_TIMO,	setlaggsetopt),
 	DEF_CMD_ARG("flowid_shift",	setlaggflowidshift),
 	DEF_CMD_ARG("rr_limit",		setlaggrr_limit),
 };
 static struct afswtch af_lagg = {
 	.af_name	= "af_lagg",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = lagg_status,
 };
 
 static __constructor void
 lagg_ctor(void)
 {
-	int i;
-
-	for (i = 0; i < nitems(lagg_cmds);  i++)
+	for (size_t i = 0; i < nitems(lagg_cmds);  i++)
 		cmd_register(&lagg_cmds[i]);
 	af_register(&af_lagg);
 	clone_setdefcallback_prefix("lagg", lagg_create);
 }
diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c
index 3014d19b00ff..510c74b8be21 100644
--- a/sbin/ifconfig/ifmedia.c
+++ b/sbin/ifconfig/ifmedia.c
@@ -1,494 +1,492 @@
 /*	$NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $	*/
 /* $FreeBSD$ */
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
  *
  * Copyright (c) 1997 Jason R. Thorpe.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *      This product includes software developed for the NetBSD Project
  *	by Jason R. Thorpe.
  * 4. The name of the author may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/if_media.h>
 #include <net/route.h>
 
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include <libifconfig.h>
 
 #include "ifconfig.h"
 
 static void domediaopt(const char *, bool, int);
 static ifmedia_t get_media_subtype(ifmedia_t, const char *);
 static ifmedia_t get_media_mode(ifmedia_t, const char *);
 static ifmedia_t get_media_options(ifmedia_t, const char *);
 static void print_media(ifmedia_t, bool);
 static void print_media_ifconfig(ifmedia_t);
 
 static void
 media_status(int s)
 {
 	struct ifmediareq *ifmr;
 
 	if (ifconfig_media_get_mediareq(lifh, name, &ifmr) == -1)
 		return;
 
 	if (ifmr->ifm_count == 0) {
 		warnx("%s: no media types?", name);
 		goto free;
 	}
 
 	printf("\tmedia: ");
 	print_media(ifmr->ifm_current, true);
 	if (ifmr->ifm_active != ifmr->ifm_current) {
 		putchar(' ');
 		putchar('(');
 		print_media(ifmr->ifm_active, false);
 		putchar(')');
 	}
 
 	putchar('\n');
 
 	if (ifmr->ifm_status & IFM_AVALID) {
 		struct ifdownreason ifdr;
 		const char *status;
 
 		status = ifconfig_media_get_status(ifmr);
 		printf("\tstatus: %s", status);
 		if (strcmp(status, "no carrier") == 0 &&
 		    ifconfig_media_get_downreason(lifh, name, &ifdr) == 0) {
 			switch (ifdr.ifdr_reason) {
 			case IFDR_REASON_MSG:
 				printf(" (%s)", ifdr.ifdr_msg);
 				break;
 			case IFDR_REASON_VENDOR:
 				printf(" (vendor code %d)",
 				    ifdr.ifdr_vendor);
 				break;
 			default:
 				break;
 			}
 		}
 		putchar('\n');
 	}
 
 	if (args.supmedia) {
 		printf("\tsupported media:\n");
-		for (size_t i = 0; i < ifmr->ifm_count; ++i) {
+		for (int i = 0; i < ifmr->ifm_count; ++i) {
 			printf("\t\t");
 			print_media_ifconfig(ifmr->ifm_ulist[i]);
 			putchar('\n');
 		}
 	}
 free:
 	free(ifmr);
 }
 
 struct ifmediareq *
 ifmedia_getstate(void)
 {
 	static struct ifmediareq *ifmr = NULL;
 
 	if (ifmr != NULL)
 		return (ifmr);
 
 	if (ifconfig_media_get_mediareq(lifh, name, &ifmr) == -1)
 		errc(1, ifconfig_err_errno(lifh),
 		    "%s: ifconfig_media_get_mediareq", name);
 
 	if (ifmr->ifm_count == 0)
 		errx(1, "%s: no media types?", name);
 
 	return (ifmr);
 }
 
 static void
 setifmediacallback(int s, void *arg)
 {
 	struct ifmediareq *ifmr = (struct ifmediareq *)arg;
 	static bool did_it = false;
 
 	if (!did_it) {
 		ifr.ifr_media = ifmr->ifm_current;
 		if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
 			err(1, "SIOCSIFMEDIA (media)");
 		free(ifmr);
 		did_it = true;
 	}
 }
 
 static void
 setmedia(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifmediareq *ifmr;
 	int subtype;
 
 	ifmr = ifmedia_getstate();
 
 	/*
 	 * We are primarily concerned with the top-level type.
 	 * However, "current" may be only IFM_NONE, so we just look
 	 * for the top-level type in the first "supported type"
 	 * entry.
 	 *
 	 * (I'm assuming that all supported media types for a given
 	 * interface will be the same top-level type..)
 	 */
 	subtype = get_media_subtype(ifmr->ifm_ulist[0], val);
 
 	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 	ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) |
 	    IFM_TYPE(ifmr->ifm_ulist[0]) | subtype;
 
 	ifmr->ifm_current = ifr.ifr_media;
 	callback_register(setifmediacallback, (void *)ifmr);
 }
 
 static void
 setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	domediaopt(val, false, s);
 }
 
 static void
 unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
 {
 
 	domediaopt(val, true, s);
 }
 
 static void
 domediaopt(const char *val, bool clear, int s)
 {
 	struct ifmediareq *ifmr;
 	ifmedia_t options;
 
 	ifmr = ifmedia_getstate();
 
 	options = get_media_options(ifmr->ifm_ulist[0], val);
 
 	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 	ifr.ifr_media = ifmr->ifm_current;
 	if (clear)
 		ifr.ifr_media &= ~options;
 	else {
 		if (options & IFM_HDX) {
 			ifr.ifr_media &= ~IFM_FDX;
 			options &= ~IFM_HDX;
 		}
 		ifr.ifr_media |= options;
 	}
 	ifmr->ifm_current = ifr.ifr_media;
 	callback_register(setifmediacallback, (void *)ifmr);
 }
 
 static void
 setmediainst(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifmediareq *ifmr;
 	int inst;
 
 	ifmr = ifmedia_getstate();
 
 	inst = atoi(val);
 	if (inst < 0 || inst > (int)IFM_INST_MAX)
 		errx(1, "invalid media instance: %s", val);
 
 	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 	ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT;
 
 	ifmr->ifm_current = ifr.ifr_media;
 	callback_register(setifmediacallback, (void *)ifmr);
 }
 
 static void
 setmediamode(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifmediareq *ifmr;
 	int mode;
 
 	ifmr = ifmedia_getstate();
 
 	mode = get_media_mode(ifmr->ifm_ulist[0], val);
 
 	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 	ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
 
 	ifmr->ifm_current = ifr.ifr_media;
 	callback_register(setifmediacallback, (void *)ifmr);
 }
 
 static ifmedia_t
 get_media_subtype(ifmedia_t media, const char *val)
 {
 	ifmedia_t subtype;
 
 	subtype = ifconfig_media_lookup_subtype(media, val);
 	if (subtype != INVALID_IFMEDIA)
 		return (subtype);
 	switch (errno) {
 	case EINVAL:
 		errx(EXIT_FAILURE, "unknown media type 0x%x", media);
 	case ENOENT:
 		errx(EXIT_FAILURE, "unknown media subtype: %s", val);
 	default:
 		err(EXIT_FAILURE, "ifconfig_media_lookup_subtype");
 	}
 	/*NOTREACHED*/
 }
 
 static ifmedia_t
 get_media_mode(ifmedia_t media, const char *val)
 {
 	ifmedia_t mode;
 
 	mode = ifconfig_media_lookup_mode(media, val);
 	if (mode != INVALID_IFMEDIA)
 		return (mode);
 	switch (errno) {
 	case EINVAL:
 		errx(EXIT_FAILURE, "unknown media type 0x%x", media);
 	case ENOENT:
 		return (INVALID_IFMEDIA);
 	default:
 		err(EXIT_FAILURE, "ifconfig_media_lookup_subtype");
 	}
 	/*NOTREACHED*/
 }
 
 static ifmedia_t
 get_media_options(ifmedia_t media, const char *val)
 {
 	ifmedia_t *options;
 	const char **optnames;
 	char *opts, *opt;
 	size_t nopts;
 	int rval;
 
 	/*
 	 * We muck with the string, so copy it.
 	 */
 	opts = strdup(val);
 	if (opts == NULL)
 		err(EXIT_FAILURE, "strdup");
 
 	/*
 	 * Split the comma-delimited list into separate strings.
 	 */
 	nopts = 0;
 	for (opt = opts; (opt = strtok(opt, ",")) != NULL; opt = NULL)
 		++nopts;
 	if (nopts == 0) {
 		free(opts);
 		return (0);
 	}
 	optnames = calloc(nopts, sizeof(*optnames));
 	if (optnames == NULL)
 		err(EXIT_FAILURE, "calloc");
 	opt = opts;
 	for (size_t i = 0; i < nopts; ++i) {
 		optnames[i] = opt;
 		opt = strchr(opt, '\0') + 1;
 	}
 
 	/*
 	 * Look up the options in the user-provided list.
 	 */
 	options = ifconfig_media_lookup_options(media, optnames, nopts);
 	if (options == NULL)
 		err(EXIT_FAILURE, "ifconfig_media_lookup_options");
 	rval = 0;
 	for (size_t i = 0; i < nopts; ++i) {
 		if (options[i] == INVALID_IFMEDIA)
 			errx(EXIT_FAILURE, "unknown option: %s", optnames[i]);
 		rval |= options[i];
 	}
 	free(options);
 	free(optnames);
 	free(opts);
 	return (rval);
 }
 
 static void
 print_media(ifmedia_t media, bool print_toptype)
 {
 	const char *val, **options;
 
 	val = ifconfig_media_get_type(media);
 	if (val == NULL) {
 		printf("<unknown type>");
 		return;
 	} else if (print_toptype) {
 		printf("%s", val);
 	}
 
 	val = ifconfig_media_get_subtype(media);
 	if (val == NULL) {
 		printf("<unknown subtype>");
 		return;
 	}
 
 	if (print_toptype)
 		putchar(' ');
 
 	printf("%s", val);
 
 	if (print_toptype) {
 		val = ifconfig_media_get_mode(media);
 		if (val != NULL && strcasecmp("autoselect", val) != 0)
 			printf(" mode %s", val);
 	}
 
 	options = ifconfig_media_get_options(media);
 	if (options != NULL && options[0] != NULL) {
 		printf(" <%s", options[0]);
 		for (size_t i = 1; options[i] != NULL; ++i)
 			printf(",%s", options[i]);
 		printf(">");
 	}
 	free(options);
 
 	if (print_toptype && IFM_INST(media) != 0)
 		printf(" instance %d", IFM_INST(media));
 }
 
 static void
 print_media_ifconfig(ifmedia_t media)
 {
 	const char *val, **options;
 
 	val = ifconfig_media_get_type(media);
 	if (val == NULL) {
 		printf("<unknown type>");
 		return;
 	}
 
 	/*
 	 * Don't print the top-level type; it's not like we can
 	 * change it, or anything.
 	 */
 
 	val = ifconfig_media_get_subtype(media);
 	if (val == NULL) {
 		printf("<unknown subtype>");
 		return;
 	}
 
 	printf("media %s", val);
 
 	val = ifconfig_media_get_mode(media);
 	if (val != NULL)
 		printf(" mode %s", val);
 
 	options = ifconfig_media_get_options(media);
 	if (options != NULL && options[0] != NULL) {
 		printf(" mediaopt %s", options[0]);
 		for (size_t i = 1; options[i] != NULL; ++i)
 			printf(",%s", options[i]);
 	}
 	free(options);
 
 	if (IFM_INST(media) != 0)
 		printf(" instance %d", IFM_INST(media));
 }
 
 /**********************************************************************
  * ...until here.
  **********************************************************************/
 
 static struct cmd media_cmds[] = {
 	DEF_CMD_ARG("media",	setmedia),
 	DEF_CMD_ARG("mode",	setmediamode),
 	DEF_CMD_ARG("mediaopt",	setmediaopt),
 	DEF_CMD_ARG("-mediaopt",unsetmediaopt),
 	DEF_CMD_ARG("inst",	setmediainst),
 	DEF_CMD_ARG("instance",	setmediainst),
 };
 static struct afswtch af_media = {
 	.af_name	= "af_media",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = media_status,
 };
 
 static __constructor void
 ifmedia_ctor(void)
 {
-	size_t i;
-
-	for (i = 0; i < nitems(media_cmds);  i++)
+	for (size_t i = 0; i < nitems(media_cmds);  i++)
 		cmd_register(&media_cmds[i]);
 	af_register(&af_media);
 }
diff --git a/sbin/ifconfig/ifpfsync.c b/sbin/ifconfig/ifpfsync.c
index e5118fff36af..eb214ed6e634 100644
--- a/sbin/ifconfig/ifpfsync.c
+++ b/sbin/ifconfig/ifpfsync.c
@@ -1,409 +1,407 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003 Ryan McBride. All rights reserved.
  * Copyright (c) 2004 Max Laier. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * $FreeBSD$
  */
 
 #include <sys/param.h>
 #include <sys/errno.h>
 #include <sys/ioctl.h>
 #include <sys/nv.h>
 #include <sys/socket.h>
 
 #include <net/if.h>
 #include <netinet/in.h>
 #include <net/pfvar.h>
 #include <net/if_pfsync.h>
 #include <net/route.h>
 #include <arpa/inet.h>
 
 #include <err.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include "ifconfig.h"
 
 void setpfsync_syncdev(const char *, int, int, const struct afswtch *);
 void unsetpfsync_syncdev(const char *, int, int, const struct afswtch *);
 void setpfsync_syncpeer(const char *, int, int, const struct afswtch *);
 void unsetpfsync_syncpeer(const char *, int, int, const struct afswtch *);
 void setpfsync_syncpeer(const char *, int, int, const struct afswtch *);
 void setpfsync_maxupd(const char *, int, int, const struct afswtch *);
 void setpfsync_defer(const char *, int, int, const struct afswtch *);
 void pfsync_status(int);
 
 static int
 pfsync_do_ioctl(int s, uint cmd, nvlist_t **nvl)
 {
 	void *data;
 	size_t nvlen;
 
 	data = nvlist_pack(*nvl, &nvlen);
 
 	ifr.ifr_cap_nv.buffer = malloc(IFR_CAP_NV_MAXBUFSIZE);
 	memcpy(ifr.ifr_cap_nv.buffer, data, nvlen);
 	ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE;
 	ifr.ifr_cap_nv.length = nvlen;
 	free(data);
 
 	if (ioctl(s, cmd, (caddr_t)&ifr) == -1) {
 		free(ifr.ifr_cap_nv.buffer);
 		return -1;
 	}
 
 	nvlist_destroy(*nvl);
 	*nvl = NULL;
 
 	*nvl = nvlist_unpack(ifr.ifr_cap_nv.buffer, ifr.ifr_cap_nv.length, 0);
 	if (*nvl == NULL) {
 		free(ifr.ifr_cap_nv.buffer);
 		return (EIO);
 	}
 
 	free(ifr.ifr_cap_nv.buffer);
 	return (errno);
 }
 
 static nvlist_t *
 pfsync_sockaddr_to_syncpeer_nvlist(struct sockaddr_storage *sa)
 {
 	nvlist_t *nvl;
 
 	nvl = nvlist_create(0);
 	if (nvl == NULL) {
 		return (nvl);
 	}
 
 	switch (sa->ss_family) {
 #ifdef INET
 	case AF_INET: {
 		struct sockaddr_in *in = (struct sockaddr_in *)sa;
 		nvlist_add_number(nvl, "af", in->sin_family);
 		nvlist_add_binary(nvl, "address", in, sizeof(*in));
 		break;
 	}
 #endif
 #ifdef INET6
 	case AF_INET6: {
 		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
 		nvlist_add_number(nvl, "af", in6->sin6_family);
 		nvlist_add_binary(nvl, "address", in6, sizeof(*in6));
 		break;
 	}
 #endif
 	default:
 		nvlist_add_number(nvl, "af", AF_UNSPEC);
 		nvlist_add_binary(nvl, "address", sa, sizeof(*sa));
 		break;
 	}
 
 	return (nvl);
 }
 
 static int
 pfsync_syncpeer_nvlist_to_sockaddr(const nvlist_t *nvl,
     struct sockaddr_storage *sa)
 {
 	int af;
 
 	if (!nvlist_exists_number(nvl, "af"))
 		return (EINVAL);
 	if (!nvlist_exists_binary(nvl, "address"))
 		return (EINVAL);
 
 	af = nvlist_get_number(nvl, "af");
 
 	switch (af) {
 #ifdef INET
 	case AF_INET: {
 		struct sockaddr_in *in = (struct sockaddr_in *)sa;
 		size_t len;
 		const void *addr = nvlist_get_binary(nvl, "address", &len);
 		in->sin_family = af;
 		if (len != sizeof(*in))
 			return (EINVAL);
 
 		memcpy(in, addr, sizeof(*in));
 		break;
 	}
 #endif
 #ifdef INET6
 	case AF_INET6: {
 		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
 		size_t len;
 		const void *addr = nvlist_get_binary(nvl, "address", &len);
 		if (len != sizeof(*in6))
 			return (EINVAL);
 
 		memcpy(in6, addr, sizeof(*in6));
 		break;
 	}
 #endif
 	default:
 		return (EINVAL);
 	}
 
 	return (0);
 }
 
 void
 setpfsync_syncdev(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	nvlist_t *nvl = nvlist_create(0);
 
 	if (strlen(val) > IFNAMSIZ)
 		errx(1, "interface name %s is too long", val);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCGETPFSYNCNV");
 
 	if (nvlist_exists_string(nvl, "syncdev"))
 		nvlist_free_string(nvl, "syncdev");
 
 	nvlist_add_string(nvl, "syncdev", val);
 
 	if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCSETPFSYNCNV");
 }
 
 /* ARGSUSED */
 void
 unsetpfsync_syncdev(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	nvlist_t *nvl = nvlist_create(0);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCGETPFSYNCNV");
 
 	if (nvlist_exists_string(nvl, "syncdev"))
 		nvlist_free_string(nvl, "syncdev");
 
 	nvlist_add_string(nvl, "syncdev", "");
 
 	if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCSETPFSYNCNV");
 }
 
 /* ARGSUSED */
 void
 setpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	struct addrinfo *peerres;
 	struct sockaddr_storage addr;
 	int ecode;
 
 	nvlist_t *nvl = nvlist_create(0);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCGETPFSYNCNV");
 
 	if ((ecode = getaddrinfo(val, NULL, NULL, &peerres)) != 0)
 		errx(1, "error in parsing address string: %s",
 		    gai_strerror(ecode));
 
 	switch (peerres->ai_family) {
 #ifdef INET
 	case AF_INET: {
 		struct sockaddr_in *sin = (struct sockaddr_in *)
 					      peerres->ai_addr;
 
 		if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
 			errx(1, "syncpeer address cannot be multicast");
 
 		memcpy(&addr, sin, sizeof(*sin));
 		break;
 	}
 #endif
 	default:
 		errx(1, "syncpeer address %s not supported", val);
 	}
 
 	if (nvlist_exists_nvlist(nvl, "syncpeer"))
 		nvlist_free_nvlist(nvl, "syncpeer");
 
 	nvlist_add_nvlist(nvl, "syncpeer",
 	    pfsync_sockaddr_to_syncpeer_nvlist(&addr));
 
 	if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCSETPFSYNCNV");
 
 	nvlist_destroy(nvl);
 	freeaddrinfo(peerres);
 }
 
 /* ARGSUSED */
 void
 unsetpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	struct sockaddr_storage addr;
 	memset(&addr, 0, sizeof(addr));
 
 	nvlist_t *nvl = nvlist_create(0);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCGETPFSYNCNV");
 
 	if (nvlist_exists_nvlist(nvl, "syncpeer"))
 		nvlist_free_nvlist(nvl, "syncpeer");
 
 	nvlist_add_nvlist(nvl, "syncpeer",
 	    pfsync_sockaddr_to_syncpeer_nvlist(&addr));
 
 	if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCSETPFSYNCNV");
 
 	nvlist_destroy(nvl);
 }
 
 /* ARGSUSED */
 void
 setpfsync_maxupd(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int maxupdates;
 	nvlist_t *nvl = nvlist_create(0);
 
 	maxupdates = atoi(val);
 	if ((maxupdates < 0) || (maxupdates > 255))
 		errx(1, "maxupd %s: out of range", val);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCGETPFSYNCNV");
 
 	nvlist_free_number(nvl, "maxupdates");
 	nvlist_add_number(nvl, "maxupdates", maxupdates);
 
 	if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCSETPFSYNCNV");
 
 	nvlist_destroy(nvl);
 }
 
 /* ARGSUSED */
 void
 setpfsync_defer(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	nvlist_t *nvl = nvlist_create(0);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCGETPFSYNCNV");
 
 	nvlist_free_number(nvl, "flags");
 	nvlist_add_number(nvl, "flags", d ? PFSYNCF_DEFER : 0);
 
 	if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
 		err(1, "SIOCSETPFSYNCNV");
 
 	nvlist_destroy(nvl);
 }
 
 void
 pfsync_status(int s)
 {
 	nvlist_t *nvl;
 	char syncdev[IFNAMSIZ];
 	char syncpeer_str[NI_MAXHOST];
 	struct sockaddr_storage syncpeer;
-	int maxupdates;
-	int flags;
+	int maxupdates = 0;
+	int flags = 0;
 	int error;
 
 	nvl = nvlist_create(0);
 
 	if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) {
 		nvlist_destroy(nvl);
 		return;
 	}
 
 	memset((char *)&syncdev, 0, IFNAMSIZ);
 	if (nvlist_exists_string(nvl, "syncdev"))
 		strlcpy(syncdev, nvlist_get_string(nvl, "syncdev"),
 		    IFNAMSIZ);
 	if (nvlist_exists_number(nvl, "maxupdates"))
 		maxupdates = nvlist_get_number(nvl, "maxupdates");
 	if (nvlist_exists_number(nvl, "flags"))
 		flags = nvlist_get_number(nvl, "flags");
 	if (nvlist_exists_nvlist(nvl, "syncpeer")) {
 		pfsync_syncpeer_nvlist_to_sockaddr(nvlist_get_nvlist(nvl,
 							     "syncpeer"),
 		    &syncpeer);
 	}
 
 	nvlist_destroy(nvl);
 
 	if (syncdev[0] != '\0' || syncpeer.ss_family != AF_UNSPEC)
 		printf("\t");
 
 	if (syncdev[0] != '\0')
 		printf("syncdev: %s ", syncdev);
 
 	if (syncpeer.ss_family == AF_INET &&
 	    ((struct sockaddr_in *)&syncpeer)->sin_addr.s_addr !=
 		htonl(INADDR_PFSYNC_GROUP)) {
 
 		struct sockaddr *syncpeer_sa =
 		    (struct sockaddr *)&syncpeer;
 		if ((error = getnameinfo(syncpeer_sa, syncpeer_sa->sa_len,
 			 syncpeer_str, sizeof(syncpeer_str), NULL, 0,
 			 NI_NUMERICHOST)) != 0)
 			errx(1, "getnameinfo: %s", gai_strerror(error));
 		printf("syncpeer: %s ", syncpeer_str);
 	}
 
 	printf("maxupd: %d ", maxupdates);
 	printf("defer: %s\n", (flags & PFSYNCF_DEFER) ? "on" : "off");
 	printf("\tsyncok: %d\n", (flags & PFSYNCF_OK) ? 1 : 0);
 }
 
 static struct cmd pfsync_cmds[] = {
 	DEF_CMD_ARG("syncdev",		setpfsync_syncdev),
 	DEF_CMD("-syncdev",	1,	unsetpfsync_syncdev),
 	DEF_CMD_ARG("syncif",		setpfsync_syncdev),
 	DEF_CMD("-syncif",	1,	unsetpfsync_syncdev),
 	DEF_CMD_ARG("syncpeer",		setpfsync_syncpeer),
 	DEF_CMD("-syncpeer",	1,	unsetpfsync_syncpeer),
 	DEF_CMD_ARG("maxupd",		setpfsync_maxupd),
 	DEF_CMD("defer",	1,	setpfsync_defer),
 	DEF_CMD("-defer",	0,	setpfsync_defer),
 };
 static struct afswtch af_pfsync = {
 	.af_name	= "af_pfsync",
 	.af_af		= AF_UNSPEC,
 	.af_other_status = pfsync_status,
 };
 
 static __constructor void
 pfsync_ctor(void)
 {
-	int i;
-
-	for (i = 0; i < nitems(pfsync_cmds);  i++)
+	for (size_t i = 0; i < nitems(pfsync_cmds);  i++)
 		cmd_register(&pfsync_cmds[i]);
 	af_register(&af_pfsync);
 }
diff --git a/sbin/ifconfig/ifstf.c b/sbin/ifconfig/ifstf.c
index f6c3cb5d5447..035793ccd98f 100644
--- a/sbin/ifconfig/ifstf.c
+++ b/sbin/ifconfig/ifstf.c
@@ -1,152 +1,150 @@
 /*-
  * Copyright 2013 Ermal Luci
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/route.h>
 
 #include <netinet/in.h>
 #include <sys/mbuf.h>
 #include <net/if_stf.h>
 #include <arpa/inet.h>
 
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <err.h>
 #include <errno.h>
 
 #include "ifconfig.h"
 
 static int
 do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
 {
 	struct ifdrv ifd;
 
 	memset(&ifd, 0, sizeof(ifd));
 
 	strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name));
 	ifd.ifd_cmd = op;
 	ifd.ifd_len = argsize;
 	ifd.ifd_data = arg;
 
 	return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
 }
 
 static void
 stf_status(int s)
 {
 	struct stfv4args param;
 
 	if (do_cmd(s, STF6RD_GV4NET, &param, sizeof(param), 0) < 0)
 		return;
 
 	printf("\tv4net %s/%d -> ", inet_ntoa(param.srcv4_addr),
 	    param.v4_prefixlen ? param.v4_prefixlen : 32);
 	printf("tv4br %s\n", inet_ntoa(param.braddr));
 }
 
 static void
 setstf_br(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct stfv4args req;
 	struct sockaddr_in sin;
 
 	memset(&req, 0, sizeof(req));
 
 	sin.sin_len = sizeof(sin);
 	sin.sin_family = AF_INET;
 
 	if (!inet_aton(val, &sin.sin_addr))
 		errx(1, "%s: bad value", val);
 
 	req.braddr = sin.sin_addr;
 	if (do_cmd(s, STF6RD_SBR, &req, sizeof(req), 1) < 0)
 		err(1, "STF6RD_SBR%s",  val);
 }
 
 static void
 setstf_set(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct stfv4args req;
 	struct sockaddr_in sin;
 	const char *errstr;
 	char *p = NULL;
 
 	memset(&req, 0, sizeof(req));
 
 	sin.sin_len = sizeof(sin);
 	sin.sin_family = AF_INET;
 
 	p = strrchr(val, '/');
 	if (p == NULL)
 		errx(2, "Wrong argument given");
 
 	*p = '\0';
 	req.v4_prefixlen = (int)strtonum(p + 1, 0, 32, &errstr);
 	if (errstr != NULL || req.v4_prefixlen == 0) {
 		*p = '/';
 		errx(1, "%s: bad value (prefix length %s)", val, errstr);
 	}
 
 	if (!inet_aton(val, &sin.sin_addr))
 		errx(1, "%s: bad value", val);
 
 	memcpy(&req.srcv4_addr, &sin.sin_addr, sizeof(req.srcv4_addr));
 	if (do_cmd(s, STF6RD_SV4NET, &req, sizeof(req), 1) < 0)
 		err(1, "STF6RD_SV4NET %s",  val);
 }
 
 static struct cmd stf_cmds[] = {
 	DEF_CMD_ARG("stfv4net",		setstf_set),
 	DEF_CMD_ARG("stfv4br",		setstf_br),
 };
 
 static struct afswtch af_stf = {
 	.af_name		= "af_stf",
 	.af_af			= AF_UNSPEC,
 	.af_other_status	= stf_status,
 };
 
 static __constructor void
 stf_ctor(void)
 {
-	int i;
-
-	for (i = 0; i < nitems(stf_cmds);  i++)
+	for (size_t i = 0; i < nitems(stf_cmds);  i++)
 		cmd_register(&stf_cmds[i]);
 	af_register(&af_stf);
 }
diff --git a/sbin/ifconfig/ifvxlan.c b/sbin/ifconfig/ifvxlan.c
index fda435343a16..131bbc105973 100644
--- a/sbin/ifconfig/ifvxlan.c
+++ b/sbin/ifconfig/ifvxlan.c
@@ -1,645 +1,645 @@
 /*-
  * Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice unmodified, this list of conditions, and the following
  *    disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
 #include <stdlib.h>
 #include <stdint.h>
 #include <unistd.h>
 #include <netdb.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_vxlan.h>
 #include <net/route.h>
 #include <netinet/in.h>
 
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <err.h>
 #include <errno.h>
 
 #include "ifconfig.h"
 
 static struct ifvxlanparam params = {
 	.vxlp_vni	= VXLAN_VNI_MAX,
 };
 
 static int
 get_val(const char *cp, u_long *valp)
 {
 	char *endptr;
 	u_long val;
 
 	errno = 0;
 	val = strtoul(cp, &endptr, 0);
 	if (cp[0] == '\0' || endptr[0] != '\0' || errno == ERANGE)
 		return (-1);
 
 	*valp = val;
 	return (0);
 }
 
 static int
 do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
 {
 	struct ifdrv ifd;
 
 	bzero(&ifd, sizeof(ifd));
 
 	strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name));
 	ifd.ifd_cmd = op;
 	ifd.ifd_len = argsize;
 	ifd.ifd_data = arg;
 
 	return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
 }
 
 static int
 vxlan_exists(int sock)
 {
 	struct ifvxlancfg cfg;
 
 	bzero(&cfg, sizeof(cfg));
 
 	return (do_cmd(sock, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) != -1);
 }
 
 static void
 vxlan_status(int s)
 {
 	struct ifvxlancfg cfg;
 	char src[NI_MAXHOST], dst[NI_MAXHOST];
 	char srcport[NI_MAXSERV], dstport[NI_MAXSERV];
 	struct sockaddr *lsa, *rsa;
 	int vni, mc, ipv6;
 
 	bzero(&cfg, sizeof(cfg));
 
 	if (do_cmd(s, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) < 0)
 		return;
 
 	vni = cfg.vxlc_vni;
 	lsa = &cfg.vxlc_local_sa.sa;
 	rsa = &cfg.vxlc_remote_sa.sa;
 	ipv6 = rsa->sa_family == AF_INET6;
 
 	/* Just report nothing if the network identity isn't set yet. */
 	if (vni >= VXLAN_VNI_MAX)
 		return;
 
 	if (getnameinfo(lsa, lsa->sa_len, src, sizeof(src),
 	    srcport, sizeof(srcport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
 		src[0] = srcport[0] = '\0';
 	if (getnameinfo(rsa, rsa->sa_len, dst, sizeof(dst),
 	    dstport, sizeof(dstport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
 		dst[0] = dstport[0] = '\0';
 
 	if (!ipv6) {
-		struct sockaddr_in *sin = (struct sockaddr_in *)rsa;
+		struct sockaddr_in *sin = satosin(rsa);
 		mc = IN_MULTICAST(ntohl(sin->sin_addr.s_addr));
 	} else {
-		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rsa;
+		struct sockaddr_in6 *sin6 = satosin6(rsa);
 		mc = IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr);
 	}
 
 	printf("\tvxlan vni %d", vni);
 	printf(" local %s%s%s:%s", ipv6 ? "[" : "", src, ipv6 ? "]" : "",
 	    srcport);
 	printf(" %s %s%s%s:%s", mc ? "group" : "remote", ipv6 ? "[" : "",
 	    dst, ipv6 ? "]" : "", dstport);
 
 	if (verbose) {
 		printf("\n\t\tconfig: ");
 		printf("%slearning portrange %d-%d ttl %d",
 		    cfg.vxlc_learn ? "" : "no", cfg.vxlc_port_min,
 		    cfg.vxlc_port_max, cfg.vxlc_ttl);
 		printf("\n\t\tftable: ");
 		printf("cnt %d max %d timeout %d",
 		    cfg.vxlc_ftable_cnt, cfg.vxlc_ftable_max,
 		    cfg.vxlc_ftable_timeout);
 	}
 
 	putchar('\n');
 }
 
 #define _LOCAL_ADDR46 \
     (VXLAN_PARAM_WITH_LOCAL_ADDR4 | VXLAN_PARAM_WITH_LOCAL_ADDR6)
 #define _REMOTE_ADDR46 \
     (VXLAN_PARAM_WITH_REMOTE_ADDR4 | VXLAN_PARAM_WITH_REMOTE_ADDR6)
 
 static void
 vxlan_check_params(void)
 {
 
 	if ((params.vxlp_with & _LOCAL_ADDR46) == _LOCAL_ADDR46)
 		errx(1, "cannot specify both local IPv4 and IPv6 addresses");
 	if ((params.vxlp_with & _REMOTE_ADDR46) == _REMOTE_ADDR46)
 		errx(1, "cannot specify both remote IPv4 and IPv6 addresses");
 	if ((params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4 &&
 	     params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) ||
 	    (params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6 &&
 	     params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4))
 		errx(1, "cannot mix IPv4 and IPv6 addresses");
 }
 
 #undef _LOCAL_ADDR46
 #undef _REMOTE_ADDR46
 
 static void
 vxlan_cb(int s, void *arg)
 {
 
 }
 
 static void
 vxlan_create(int s, struct ifreq *ifr)
 {
 
 	vxlan_check_params();
 
 	ifr->ifr_data = (caddr_t) &params;
 	ioctl_ifcreate(s, ifr);
 }
 
 static
 DECL_CMD_FUNC(setvxlan_vni, arg, d)
 {
 	struct ifvxlancmd cmd;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || val >= VXLAN_VNI_MAX)
 		errx(1, "invalid network identifier: %s", arg);
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_VNI;
 		params.vxlp_vni = val;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_vni = val;
 
 	if (do_cmd(s, VXLAN_CMD_SET_VNI, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_VNI");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_local, addr, d)
 {
 	struct ifvxlancmd cmd;
 	struct addrinfo *ai;
 	struct sockaddr *sa;
 	int error;
 
 	bzero(&cmd, sizeof(cmd));
 
 	if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
 		errx(1, "error in parsing local address string: %s",
 		    gai_strerror(error));
 
 	sa = ai->ai_addr;
 
 	switch (ai->ai_family) {
 #ifdef INET
 	case AF_INET: {
-		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+		struct sockaddr_in *sin = satosin(sa);
 
 		if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
 			errx(1, "local address cannot be multicast");
 
 		cmd.vxlcmd_sa.in4 = *sin;
 		break;
 	}
 #endif
 #ifdef INET6
 	case AF_INET6: {
-		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+		struct sockaddr_in6 *sin6 = satosin6(sa);
 
 		if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
 			errx(1, "local address cannot be multicast");
 
 		cmd.vxlcmd_sa.in6 = *sin6;
 		break;
 	}
 #endif
 	default:
 		errx(1, "local address %s not supported", addr);
 	}
 
 	freeaddrinfo(ai);
 
 	if (!vxlan_exists(s)) {
 		if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
 			params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR4;
 			params.vxlp_local_sa.in4 = cmd.vxlcmd_sa.in4;
 		} else {
 			params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR6;
 			params.vxlp_local_sa.in6 = cmd.vxlcmd_sa.in6;
 		}
 		return;
 	}
 
 	if (do_cmd(s, VXLAN_CMD_SET_LOCAL_ADDR, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_LOCAL_ADDR");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_remote, addr, d)
 {
 	struct ifvxlancmd cmd;
 	struct addrinfo *ai;
 	struct sockaddr *sa;
 	int error;
 
 	bzero(&cmd, sizeof(cmd));
 
 	if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
 		errx(1, "error in parsing remote address string: %s",
 		    gai_strerror(error));
 
 	sa = ai->ai_addr;
 
 	switch (ai->ai_family) {
 #ifdef INET
 	case AF_INET: {
-		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+		struct sockaddr_in *sin = satosin(sa);
 
 		if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
 			errx(1, "remote address cannot be multicast");
 
 		cmd.vxlcmd_sa.in4 = *sin;
 		break;
 	}
 #endif
 #ifdef INET6
 	case AF_INET6: {
-		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+		struct sockaddr_in6 *sin6 = satosin6(sa);
 
 		if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
 			errx(1, "remote address cannot be multicast");
 
 		cmd.vxlcmd_sa.in6 = *sin6;
 		break;
 	}
 #endif
 	default:
 		errx(1, "remote address %s not supported", addr);
 	}
 
 	freeaddrinfo(ai);
 
 	if (!vxlan_exists(s)) {
 		if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
 			params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
 			params.vxlp_remote_sa.in4 = cmd.vxlcmd_sa.in4;
 		} else {
 			params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
 			params.vxlp_remote_sa.in6 = cmd.vxlcmd_sa.in6;
 		}
 		return;
 	}
 
 	if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_group, addr, d)
 {
 	struct ifvxlancmd cmd;
 	struct addrinfo *ai;
 	struct sockaddr *sa;
 	int error;
 
 	bzero(&cmd, sizeof(cmd));
 
 	if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
 		errx(1, "error in parsing group address string: %s",
 		    gai_strerror(error));
 
 	sa = ai->ai_addr;
 
 	switch (ai->ai_family) {
 #ifdef INET
 	case AF_INET: {
-		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+		struct sockaddr_in *sin = satosin(sa);
 
 		if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
 			errx(1, "group address must be multicast");
 
 		cmd.vxlcmd_sa.in4 = *sin;
 		break;
 	}
 #endif
 #ifdef INET6
 	case AF_INET6: {
-		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+		struct sockaddr_in6 *sin6 = satosin6(sa);
 
 		if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
 			errx(1, "group address must be multicast");
 
 		cmd.vxlcmd_sa.in6 = *sin6;
 		break;
 	}
 #endif
 	default:
 		errx(1, "group address %s not supported", addr);
 	}
 
 	freeaddrinfo(ai);
 
 	if (!vxlan_exists(s)) {
 		if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
 			params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
 			params.vxlp_remote_sa.in4 = cmd.vxlcmd_sa.in4;
 		} else {
 			params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
 			params.vxlp_remote_sa.in6 = cmd.vxlcmd_sa.in6;
 		}
 		return;
 	}
 
 	if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_local_port, arg, d)
 {
 	struct ifvxlancmd cmd;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
 		errx(1, "invalid local port: %s", arg);
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_PORT;
 		params.vxlp_local_port = val;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_port = val;
 
 	if (do_cmd(s, VXLAN_CMD_SET_LOCAL_PORT, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_LOCAL_PORT");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_remote_port, arg, d)
 {
 	struct ifvxlancmd cmd;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
 		errx(1, "invalid remote port: %s", arg);
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_PORT;
 		params.vxlp_remote_port = val;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_port = val;
 
 	if (do_cmd(s, VXLAN_CMD_SET_REMOTE_PORT, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_REMOTE_PORT");
 }
 
 static
 DECL_CMD_FUNC2(setvxlan_port_range, arg1, arg2)
 {
 	struct ifvxlancmd cmd;
 	u_long min, max;
 
 	if (get_val(arg1, &min) < 0 || min >= UINT16_MAX)
 		errx(1, "invalid port range minimum: %s", arg1);
 	if (get_val(arg2, &max) < 0 || max >= UINT16_MAX)
 		errx(1, "invalid port range maximum: %s", arg2);
 	if (max < min)
 		errx(1, "invalid port range");
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_PORT_RANGE;
 		params.vxlp_min_port = min;
 		params.vxlp_max_port = max;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_port_min = min;
 	cmd.vxlcmd_port_max = max;
 
 	if (do_cmd(s, VXLAN_CMD_SET_PORT_RANGE, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_PORT_RANGE");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_timeout, arg, d)
 {
 	struct ifvxlancmd cmd;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
 		errx(1, "invalid timeout value: %s", arg);
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_TIMEOUT;
 		params.vxlp_ftable_timeout = val & 0xFFFFFFFF;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_ftable_timeout = val & 0xFFFFFFFF;
 
 	if (do_cmd(s, VXLAN_CMD_SET_FTABLE_TIMEOUT, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_FTABLE_TIMEOUT");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_maxaddr, arg, d)
 {
 	struct ifvxlancmd cmd;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
 		errx(1, "invalid maxaddr value: %s",  arg);
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_MAX;
 		params.vxlp_ftable_max = val & 0xFFFFFFFF;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_ftable_max = val & 0xFFFFFFFF;
 
 	if (do_cmd(s, VXLAN_CMD_SET_FTABLE_MAX, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_FTABLE_MAX");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_dev, arg, d)
 {
 	struct ifvxlancmd cmd;
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_MULTICAST_IF;
 		strlcpy(params.vxlp_mc_ifname, arg,
 		    sizeof(params.vxlp_mc_ifname));
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	strlcpy(cmd.vxlcmd_ifname, arg, sizeof(cmd.vxlcmd_ifname));
 
 	if (do_cmd(s, VXLAN_CMD_SET_MULTICAST_IF, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_MULTICAST_IF");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_ttl, arg, d)
 {
 	struct ifvxlancmd cmd;
 	u_long val;
 
 	if (get_val(arg, &val) < 0 || val > 256)
 		errx(1, "invalid TTL value: %s", arg);
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_TTL;
 		params.vxlp_ttl = val;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	cmd.vxlcmd_ttl = val;
 
 	if (do_cmd(s, VXLAN_CMD_SET_TTL, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_TTL");
 }
 
 static
 DECL_CMD_FUNC(setvxlan_learn, arg, d)
 {
 	struct ifvxlancmd cmd;
 
 	if (!vxlan_exists(s)) {
 		params.vxlp_with |= VXLAN_PARAM_WITH_LEARN;
 		params.vxlp_learn = d;
 		return;
 	}
 
 	bzero(&cmd, sizeof(cmd));
 	if (d != 0)
 		cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_LEARN;
 
 	if (do_cmd(s, VXLAN_CMD_SET_LEARN, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_SET_LEARN");
 }
 
 static void
 setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp)
 {
 	struct ifvxlancmd cmd;
 
 	bzero(&cmd, sizeof(cmd));
 	if (d != 0)
 		cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_FLUSH_ALL;
 
 	if (do_cmd(s, VXLAN_CMD_FLUSH, &cmd, sizeof(cmd), 1) < 0)
 		err(1, "VXLAN_CMD_FLUSH");
 }
 
 static struct cmd vxlan_cmds[] = {
 
 	DEF_CLONE_CMD_ARG("vni",                setvxlan_vni),
 	DEF_CLONE_CMD_ARG("vxlanid",		setvxlan_vni),
 	DEF_CLONE_CMD_ARG("vxlanlocal",		setvxlan_local),
 	DEF_CLONE_CMD_ARG("vxlanremote",	setvxlan_remote),
 	DEF_CLONE_CMD_ARG("vxlangroup",		setvxlan_group),
 	DEF_CLONE_CMD_ARG("vxlanlocalport",	setvxlan_local_port),
 	DEF_CLONE_CMD_ARG("vxlanremoteport",	setvxlan_remote_port),
 	DEF_CLONE_CMD_ARG2("vxlanportrange",	setvxlan_port_range),
 	DEF_CLONE_CMD_ARG("vxlantimeout",	setvxlan_timeout),
 	DEF_CLONE_CMD_ARG("vxlanmaxaddr",	setvxlan_maxaddr),
 	DEF_CLONE_CMD_ARG("vxlandev",		setvxlan_dev),
 	DEF_CLONE_CMD_ARG("vxlanttl",		setvxlan_ttl),
 	DEF_CLONE_CMD("vxlanlearn", 1,		setvxlan_learn),
 	DEF_CLONE_CMD("-vxlanlearn", 0,		setvxlan_learn),
 
 	DEF_CMD_ARG("vni",			setvxlan_vni),
 	DEF_CMD_ARG("vxlanid",			setvxlan_vni),
 	DEF_CMD_ARG("vxlanlocal",		setvxlan_local),
 	DEF_CMD_ARG("vxlanremote",		setvxlan_remote),
 	DEF_CMD_ARG("vxlangroup",		setvxlan_group),
 	DEF_CMD_ARG("vxlanlocalport",		setvxlan_local_port),
 	DEF_CMD_ARG("vxlanremoteport",		setvxlan_remote_port),
 	DEF_CMD_ARG2("vxlanportrange",		setvxlan_port_range),
 	DEF_CMD_ARG("vxlantimeout",		setvxlan_timeout),
 	DEF_CMD_ARG("vxlanmaxaddr",		setvxlan_maxaddr),
 	DEF_CMD_ARG("vxlandev",			setvxlan_dev),
 	DEF_CMD_ARG("vxlanttl",			setvxlan_ttl),
 	DEF_CMD("vxlanlearn", 1,		setvxlan_learn),
 	DEF_CMD("-vxlanlearn", 0,		setvxlan_learn),
 
 	DEF_CMD("vxlanflush", 0,		setvxlan_flush),
 	DEF_CMD("vxlanflushall", 1,		setvxlan_flush),
 
 	DEF_CMD("vxlanhwcsum",	IFCAP_VXLAN_HWCSUM,	setifcap),
 	DEF_CMD("-vxlanhwcsum",	-IFCAP_VXLAN_HWCSUM,	setifcap),
 	DEF_CMD("vxlanhwtso",	IFCAP_VXLAN_HWTSO,	setifcap),
 	DEF_CMD("-vxlanhwtso",	-IFCAP_VXLAN_HWTSO,	setifcap),
 };
 
 static struct afswtch af_vxlan = {
 	.af_name		= "af_vxlan",
 	.af_af			= AF_UNSPEC,
 	.af_other_status	= vxlan_status,
 };
 
 static __constructor void
 vxlan_ctor(void)
 {
 	size_t i;
 
 	for (i = 0; i < nitems(vxlan_cmds); i++)
 		cmd_register(&vxlan_cmds[i]);
 	af_register(&af_vxlan);
 	callback_register(vxlan_cb, NULL);
 	clone_setdefcallback_prefix("vxlan", vxlan_create);
 }