Subject: bin/21860: ifconfig doesn't allow addr/N notation for INET6
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kre@munnari.OZ.AU>
List: netbsd-bugs
Date: 06/12/2003 01:30:19
>Number:         21860
>Category:       bin
>Synopsis:       ifconfig doesn't allow addr/N notation for INET6
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 11 18:32:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Robert Elz
>Release:        NetBSD 1.6T  -- current of 2003-06-11
>Organization:
	Prince of SOngkla University
>Environment:
System: NetBSD fuchsia.cs.mu.OZ.AU 1.6T NetBSD 1.6T (FUCHSIA) #46: Wed May 28 02:52:32 ICT 2003 kre@fuchsia.cs.mu.OZ.AU:/usr/obj/sys/FUCHSIA i386
Architecture: i386
Machine: i386
>Description:
	man 8 ifconfig says ...

netmask mask    (inet, inet6, and ISO) Specify how much of the address to
		reserve for subdividing networks into sub-networks.
		[...]
		For INET and INET6 addresses, the netmask can also be
		given with slash-notation after the address (e.g
	        192.168.17.3/24).

	which is true for INET addresses, but was not for INET6 (though
	ifconfig has a code path that is not compiled which would allow
	this - on the other hand, that path would not allow anything but
	literal addresses for INET6 - no DNS names).

>How-To-Repeat:
	Try
		ifconfig <iface> inet6 4567::1/64
	and watch it complain, after failing to find "4567::1/64" in the
	DNS (which for me at least, takes a noticeable time to happen).

>Fix:
	Apply the patch below.

	This also corrects a trivial wording issue in an error message
	if a FQDN (or any DN) is given, which turns out to have more
	than one address - the message used to say the name resolved to
	multiple "hosts".   "Addresses" is better.

Index: ifconfig.c
===================================================================
RCS file: /local/NetBSD/repository/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.136
diff -u -r1.136 ifconfig.c
--- ifconfig.c	2003/05/17 23:07:22	1.136
+++ ifconfig.c	2003/06/11 18:27:43
@@ -2718,7 +2718,13 @@
 	struct sockaddr_in6 *sin6 = sin6tab[which];
 	struct addrinfo hints, *res;
 	int error;
+	char *slash = NULL;
 
+	if (which == ADDR) {
+		if ((slash = strrchr(str, '/')) != NULL)
+			*slash = '\0';
+	}
+
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = AF_INET6;
 	hints.ai_socktype = SOCK_DGRAM;
@@ -2726,10 +2732,16 @@
 	hints.ai_flags = AI_NUMERICHOST;
 #endif
 	error = getaddrinfo(str, "0", &hints, &res);
+	if (error && slash) {
+		/* try again treating the '/' as part of the name */
+		*slash = '/';
+		slash = NULL;
+		error = getaddrinfo(str, "0", &hints, &res);
+	}
 	if (error)
 		errx(EXIT_FAILURE, "%s: %s", str, gai_strerror(error));
 	if (res->ai_next)
-		errx(EXIT_FAILURE, "%s: resolved to multiple hosts", str);
+		errx(EXIT_FAILURE, "%s: resolved to multiple addresses", str);
 	if (res->ai_addrlen != sizeof(struct sockaddr_in6))
 		errx(EXIT_FAILURE, "%s: bad value", str);
 	memcpy(sin6, res->ai_addr, res->ai_addrlen);
@@ -2738,6 +2750,10 @@
 		*(u_int16_t *)&sin6->sin6_addr.s6_addr[2] =
 			htons(sin6->sin6_scope_id);
 		sin6->sin6_scope_id = 0;
+	}
+	if (slash) {
+		in6_getprefix(slash + 1, MASK);
+		explicit_prefix = 1;
 	}
 #else
 	struct sockaddr_in6 *gasin = sin6tab[which];
>Release-Note:
>Audit-Trail:
>Unformatted: