Subject: bin/8719: ifconfig could accept netmask in slash-notation
To: None <gnats-bugs@gnats.netbsd.org>
From: Johan Danielsson <joda@pdc.kth.se>
List: netbsd-bugs
Date: 10/31/1999 07:18:46
>Number:         8719
>Category:       bin
>Synopsis:       ifconfig could accept netmask in slash-notation
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Oct 31 07:18:00 1999
>Last-Modified:
>Originator:     Johan Danielsson
>Organization:
>Release:        1999-10-29
>Environment:
	<machine, os, target, libraries (multiple lines)>
System: NetBSD blubb.pdc.kth.se 1.4L NetBSD 1.4L (BLUBB) #15: Tue Oct 19 18:13:13 CEST 1999 joda@blubb.pdc.kth.se:/usr/misc/src/netbsd/anoncvs/syssrc/sys/arch/i386/compile/BLUBB i386


>Description:

Digital UNIX didn't, for a long time, work correctly with class-less
networks. You could subnet, but you couldn't supernet. This is not a
problem with NetBSD, but one nice feature they did add when they
finally fixed this, was the ability to specify the netmask in
slash-notation. That is, you can write:

        ifconfig foo0 10.0.0.1/27

instead of

        ifconfig foo0 10.0.0.1 netmask 0xffffffe0

I personally think it's much easier to remember the size of the
network in bits than in netmask address style (and it's faster to
type).

>How-To-Repeat:
>Fix:

This patch for ifconfig should DTRT with IP (4 and 6) addresses. I
don't know if you ever want to add a netmask to anything but ADDR type
addresses.

Known problem: this patch makes it harder to assign addresses with
slashes in them (like `my-fynny/host.foo.org'), but a hostname can't
contain a slash anyway, so it might not be a big problem. You can
still add an extra slash and a netmask.

I don't know anything about the other address types, or if this could
apply to any of them too.

--- ifconfig.c	1999/07/29 15:40:48	1.58
+++ ifconfig.c	1999/10/29 15:59:58
@@ -1780,6 +1780,27 @@
 	if (which != MASK)
 		sin->sin_family = AF_INET;
 
+	if (which == ADDR) {
+		char *p = NULL;
+	    
+		if((p = strrchr(s, '/')) != NULL) {
+			/* address is `name/masklen' */
+			int masklen;
+			int ret;
+			struct sockaddr_in *min = sintab[MASK];
+			*p = '\0';
+			ret = sscanf(p+1, "%u", &masklen);
+			if(ret != 1 || (masklen < 0 || masklen > 32)) {
+				*p = '/';
+				errx(1, "%s: bad value", s);
+			}
+			min->sin_len = sizeof(*min);
+			min->sin_addr.s_addr = 
+				htonl(~((1LL << (32 - masklen)) - 1) & 
+				      0xffffffff);
+		}
+	}
+
 	if (inet_aton(s, &sin->sin_addr) == 0) {
 		if ((hp = gethostbyname(s)) != NULL)
 			(void) memcpy(&sin->sin_addr, hp->h_addr, hp->h_length);
@@ -1840,6 +1861,15 @@
 	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 (inet_pton(AF_INET6, s, &sin->sin6_addr) <= 0)
 		errx(1, "%s: bad value", s);
>Audit-Trail:
>Unformatted: