From 902f3d8946e083f4a9c8e75cab9f3c59b04d4dea Mon Sep 17 00:00:00 2001 From: kre Date: Sat, 1 Oct 2016 20:59:49 +0000 Subject: [PATCH] Return to printing explicit "netmask 0x...." in the case that the mask set is non-contiguous. We don't prohibit setting such things (even if they are basically useless) so they can be set by accident. ifconfig ifN 10.0.0.1 netmask 225.0.0.0 produced ifN .. inet 10.0.0.1/8 with the previous form (since 225 is 0xE1), now it produces ifN ... inet 10.0.0.1 netmask 0xe1000000 If the "netmask" form ever appears in ifconfig output, it (now) means that the netmask is non-contig, which should make that case obvious (whther intended, or set by accident) --- sbin/ifconfig/af_inet.c | 42 ++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index f726ea691649..c7848c8c3952 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -1,4 +1,4 @@ -/* $NetBSD: af_inet.c,v 1.23 2016/10/01 15:10:58 roy Exp $ */ +/* $NetBSD: af_inet.c,v 1.24 2016/10/01 20:59:49 kre Exp $ */ /* * Copyright (c) 1983, 1993 @@ -31,7 +31,7 @@ #include #ifndef lint -__RCSID("$NetBSD: af_inet.c,v 1.23 2016/10/01 15:10:58 roy Exp $"); +__RCSID("$NetBSD: af_inet.c,v 1.24 2016/10/01 20:59:49 kre Exp $"); #endif /* not lint */ #include @@ -64,6 +64,7 @@ static void in_status(prop_dictionary_t, prop_dictionary_t, bool); static void in_commit_address(prop_dictionary_t, prop_dictionary_t); static bool in_addr_tentative(struct ifaddrs *); static bool in_addr_tentative_or_detached(struct ifaddrs *); +static in_addr_t in_netmask(struct sockaddr *);; static int in_prefixlen(struct sockaddr *); static void in_alias(struct ifaddrs *, prop_dictionary_t, prop_dictionary_t); @@ -74,17 +75,34 @@ static struct afswtch af = { .af_addr_tentative_or_detached = in_addr_tentative_or_detached }; -static int -in_prefixlen(struct sockaddr *sa) +static in_addr_t +in_netmask(struct sockaddr *sa) { struct sockaddr_in sin; - in_addr_t mask; - int cidr; memset(&sin, 0, sizeof(sin)); memcpy(&sin, sa, sa->sa_len); - mask = ntohl(sin.sin_addr.s_addr); - cidr = 33 - ffs(mask); + return ntohl(sin.sin_addr.s_addr); +} + +static int +in_prefixlen(struct sockaddr *sa) +{ + in_addr_t mask; + int cidr; + + mask = in_netmask(sa); + if (mask == 0) /* mask 0 ==> /0 */ + return 0; + + cidr = 33 - ffs(mask); /* 33 - (1 .. 32) -> 32 .. 1 */ + + if (cidr < 32) { /* more than 1 bit in mask */ + /* check for non-contig netmask */ + if ((mask ^ (((1 << cidr) - 1) << (32 - cidr))) != 0) + return -1; /* noncontig, no pfxlen */ + } + return cidr; } @@ -93,6 +111,7 @@ in_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv) { char hbuf[NI_MAXHOST]; const int niflag = Nflag ? 0 : NI_NUMERICHOST; + int pfxlen; char fbuf[1024]; if (lflag) @@ -102,7 +121,9 @@ in_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv) hbuf, sizeof(hbuf), NULL, 0, niflag)) strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ printf("\tinet %s", hbuf); - printf("/%d", in_prefixlen(ifa->ifa_netmask)); + pfxlen = in_prefixlen(ifa->ifa_netmask); + if (pfxlen >= 0) + printf("/%d", pfxlen); if (ifa->ifa_flags & IFF_POINTOPOINT) { if (getnameinfo(ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, @@ -111,6 +132,9 @@ in_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv) printf(" -> %s", hbuf); } + if (pfxlen < 0) + printf(" netmask %#x", in_netmask(ifa->ifa_netmask)); + if (ifa->ifa_flags & IFF_BROADCAST) { if (getnameinfo(ifa->ifa_broadaddr, ifa->ifa_broadaddr->sa_len, hbuf, sizeof(hbuf), NULL, 0, niflag))