Hi,

printing the netmask in hex seems to be a historical artifact in ifconfig;
I always wondered about it and I never got used to it.

The following diff changes ifconfig output to print contiguous
netmasks in CIDR notation.  Non-contiguous netmasks will still be
printed in full, tunnels will print explicit "prefixlen" because it is
not unambiguous where the mask belongs to in this case.

lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> rdomain 1 mtu 32768
        index 7 priority 0 llprio 3
        groups: lo
        inet6 ::1/128
        inet6 fe80::1%lo1/64 scopeid 0x7
        inet 10.2.1.100 netmask 0xffff00ff
        inet 10.3.100.1/24

A similar change has been done in NetBSD and FreeBSD is doing the
FreeBSD thing by providing an -f command-line button to select one of
three output modes ...

Thoughts?

Reyk

Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.334
diff -u -p -u -p -r1.334 ifconfig.c
--- sbin/ifconfig/ifconfig.c    13 Dec 2016 01:36:21 -0000      1.334
+++ sbin/ifconfig/ifconfig.c    13 Dec 2016 09:36:52 -0000
@@ -3138,6 +3138,7 @@ void
 in_status(int force)
 {
        struct sockaddr_in *sin, sin2;
+       int prefixlen;
 
        getsock(AF_INET);
        if (s < 0) {
@@ -3177,7 +3178,14 @@ in_status(int force)
                sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
                printf(" --> %s", inet_ntoa(sin->sin_addr));
        }
-       printf(" netmask 0x%x", ntohl(netmask.sin_addr.s_addr));
+       prefixlen = prefix(&netmask.sin_addr.s_addr,
+           sizeof(netmask.sin_addr.s_addr));
+       if (prefixlen == -1)
+               printf(" netmask 0x%x", ntohl(netmask.sin_addr.s_addr));
+       else if (flags & IFF_POINTOPOINT)
+               printf("prefixlen %d", prefixlen);
+       else
+               printf("/%d", prefixlen);
        if (flags & IFF_BROADCAST) {
                memcpy(&ifr.ifr_addr, &sin2, sizeof(sin2));
                if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
@@ -3224,6 +3232,7 @@ in6_alias(struct in6_ifreq *creq)
        u_int32_t scopeid;
        char hbuf[NI_MAXHOST];
        const int niflag = NI_NUMERICHOST;
+       int prefixlen;
 
        /* Get the non-alias address for this interface. */
        getsock(AF_INET6);
@@ -3269,8 +3278,17 @@ in6_alias(struct in6_ifreq *creq)
                        warn("SIOCGIFNETMASK_IN6");
        } else {
                sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
-               printf(" prefixlen %d", prefix(&sin6->sin6_addr,
-                   sizeof(struct in6_addr)));
+               prefixlen = prefix(&sin6->sin6_addr,
+                   sizeof(struct in6_addr));
+               if (prefixlen == -1) {
+                       if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
+                           hbuf, sizeof(hbuf), NULL, 0, niflag) != 0)
+                               strlcpy(hbuf, "", sizeof hbuf);
+                       printf(" netmask %s", hbuf);
+               } else if (flags & IFF_POINTOPOINT) {
+                       printf(" prefixlen %d", prefixlen);
+               } else
+                       printf("/%d", prefixlen);
        }
 
        (void) memset(&ifr6, 0, sizeof(ifr6));
@@ -5559,11 +5577,11 @@ prefix(void *val, int size)
                        break;
        for (; bit != 0; bit--)
                if (nam[byte] & (1 << bit))
-                       return (0);
+                       return (-1);
        byte++;
        for (; byte < size; byte++)
                if (nam[byte])
-                       return (0);
+                       return (-1);
        return (plen);
 }
 

Reply via email to