On Tue, Dec 13, 2016 at 12:14:10PM +0100, Martin Pieuchot wrote:
> On 13/12/16(Tue) 11:32, Reyk Floeter wrote:
> > [...] 
> > Simple reasons: this is a different discussion or diff.  If we would
> > want to remove non-contiguous netmasks completely, it should be done
> > in the stack.  Until then, it is better that ifconfig can cope with
> > them.
> 
> The stack no longer support them.  But nobody did the work to fully
> clean it.
> 

Good to know, I got confused by the /* Non contiguous mask. */ comment
in rtable.c and the fact that you can set it in lo(4).

> I agree with Peter, if it's not extra work for you to remove that from
> ifconfig(8) that's one step towards cleaning this.
> 

Sure, I didn't disagree with Peter if it is already deprecated in OpenBSD.

It has to be fixed in the kernel, but what about catching it in
ifconfig already (only for IPv6 since v6 never supported it):

# ifconfig lo1 10.3.1.100 netmask 255.255.0.255
ifconfig: invalid non-contiguous netmask

Updated diff below.

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 11:54:31 -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,12 @@ 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 (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 +3230,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 +3276,12 @@ 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 (flags & IFF_POINTOPOINT)
+                       printf(" prefixlen %d", prefixlen);
+               else
+                       printf("/%d", prefixlen);
        }
 
        (void) memset(&ifr6, 0, sizeof(ifr6));
@@ -5386,6 +5397,10 @@ in_getaddr(const char *s, int which)
                else
                        errx(1, "%s: bad value", s);
        }
+
+       if (which == MASK &&
+           prefix(&sin->sin_addr, sizeof(sin->sin_addr)) == -1)
+               errx(1, "invalid non-contiguous netmask");
 }
 
 /* ARGSUSED */
@@ -5559,11 +5574,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