Subject: bin/21856: Changes to route(8) to allow /n instead of -prefixlen for INET6
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kre@munnari.OZ.AU>
List: netbsd-bugs
Date: 06/11/2003 21:30:47
>Number:         21856
>Category:       bin
>Synopsis:       Changes to route(8) to allow /n instead of -prefixlen 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 14:38: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 delta.cs.mu.OZ.AU 1.6T NetBSD 1.6T (DELTA) #42: Thu May 29 12:23:16 ICT 2003 kre@fuchsia.cs.mu.OZ.AU:/usr/obj/sys/DELTA i386
Architecture: i386
Machine: i386
>Description:
	The route command (route(8)) was recently enhanced to allow
	IPv4 routes to be specified using the a.b.c.d/N notation for
	specifying the netmask as a prefix length.   However, IPv6
	routes (where, if anything, this notation is needed more)
	still required -prefixlen to set the prefix length (or actually
	specifying a netmask, which would be weird indeed).

	A bunch of other minor bugs got swatted at the same time (but
	I resisted the temptation to either nuke "route show" or fix
	it to actually do something useful).

>How-To-Repeat:
	try
		route add -inet6 2000::/3 `route -s get -inet6 default`
	and watch it fail (and it isn't the "route get" that is the problem).

	Also try
		route add 10.11.12.13/32 <anywhere>
	and watch it add a network route instead of a host route.

	Or try
		route -q add 1.0.0.0 <anywhere> 0
	and get a usage message, instead of the warning that would
	be printed without -q.
>Fix:
	Apply the following patch.   This also moved AF_APPLETALK
	out of the SMALL version of the code (appletalk in an install
	floppy?   Why?   That should recover any space otherwise consumed,
	and probably more).

	There is no patch for the man page, the change that was made
	there when /nn was added for IPv4 doesn't say "IPv4 only" so
	I think it is fine for IPv4 & IPv6 as it now stands.

Index: route.c
===================================================================
RCS file: /local/NetBSD/repository/src/sbin/route/route.c,v
retrieving revision 1.65
diff -u -r1.65 route.c
--- route.c	2003/06/03 04:41:42	1.65
+++ route.c	2003/06/11 14:13:38
@@ -269,10 +269,10 @@
 				af = AF_INET6;
 				break;
 #endif
+#ifndef SMALL
 			case K_ATALK:
 				af = AF_APPLETALK;
 				break;
-#ifndef SMALL
 			case K_XNS:
 				af = AF_NS;
 				break;
@@ -586,13 +586,13 @@
 		(void)snprintf(line, sizeof line, "iso %s",
 		    iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));
 		break;
-#endif /* SMALL */
 
 	case AF_APPLETALK:
 		(void) snprintf(line, sizeof(line), "atalk %d.%d",
 		    ((struct sockaddr_at *)sa)->sat_addr.s_net,
 		    ((struct sockaddr_at *)sa)->sat_addr.s_node);
 		break;
+#endif /* SMALL */
 
 	default:
 		(void)snprintf(line, sizeof line, "(%d) %s",
@@ -741,13 +741,13 @@
 		(void)snprintf(line, sizeof line, "iso %s",
 		    iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));
 		break;
-#endif /* SMALL */
 
 	case AF_APPLETALK:
 		(void) snprintf(line, sizeof(line), "atalk %d.%d",
 		    ((struct sockaddr_at *)sa)->sat_addr.s_net,
 		    ((struct sockaddr_at *)sa)->sat_addr.s_node);
 		break;
+#endif /* SMALL */
 
 	default:
 		(void)snprintf(line, sizeof line, "af %d: %s",
@@ -808,10 +808,12 @@
 				aflen = sizeof(union sockunion);
 				break;
 
+#ifndef SMALL
 			case K_ATALK:
 				af = AF_APPLETALK;
 				aflen = sizeof(struct sockaddr_at);
 				break;
+#endif
 
 			case K_INET:
 				af = AF_INET;
@@ -956,17 +958,19 @@
 				ret = atoi(*argv);
 
 				if (ret == 0) {
-				    if (!qflag && strcmp(*argv, "0") == 0)
-				        warnx("%s, %s",
-					    "old usage of trailing 0",
-					    "assuming route to if");
-				    else
+				    if (strcmp(*argv, "0") == 0) {
+					if (!qflag)  {
+					    warnx("%s, %s",
+						"old usage of trailing 0",
+						"assuming route to if");
+					}
+				    } else
 					usage((char *)NULL);
 				    iflag = 1;
 				    continue;
 				} else if (ret > 0 && ret < 10) {
 				    if (!qflag) {
-				        warnx("%s, %s",
+					warnx("%s, %s",
 					    "old usage of trailing digit",
 					    "assuming route via gateway");
 				    }
@@ -977,9 +981,11 @@
 			}
 		}
 	}
-	if (forcehost)
+	if (forcehost && forcenet)
+		errx(1, "-host and -net conflict");
+	else if (forcehost)
 		ishost = 1;
-	if (forcenet)
+	else if (forcenet)
 		ishost = 0;
 	flags |= RTF_UP;
 	if (ishost)
@@ -1193,18 +1199,27 @@
 	case AF_INET6:
 	    {
 		struct addrinfo hints, *res;
+		char *slash = 0;
 
+		if (which == RTA_DST && (slash = (strrchr(s, '/'))) != 0)
+			*slash = '\0';
 		memset(&hints, 0, sizeof(hints));
 		hints.ai_family = afamily;	/*AF_INET6*/
 		hints.ai_flags = AI_NUMERICHOST;
 		hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
 		if (getaddrinfo(s, "0", &hints, &res) != 0) {
 			hints.ai_flags = 0;
+			if (slash) {
+				*slash = '/';
+				slash = 0;
+			}
 			if (getaddrinfo(s, "0", &hints, &res) != 0) {
 				(void) fprintf(stderr, "%s: bad value\n", s);
 				exit(1);
 			}
 		}
+		if (slash)
+			*slash = '/';
 		if (sizeof(su->sin6) != res->ai_addrlen) {
 			(void) fprintf(stderr, "%s: bad value\n", s);
 			exit(1);
@@ -1226,6 +1241,8 @@
 		}
 #endif
 		if (hints.ai_flags == AI_NUMERICHOST) {
+			if (slash)
+				return (prefixlen(slash + 1));
 			if (which == RTA_DST)
 				return (inet6_makenetandmask(&su->sin6));
 			return (0);
@@ -1266,6 +1283,7 @@
 		sockaddr(s, &su->sa);
 		return (1);
 
+#ifndef SMALL
 	case AF_APPLETALK:
 		t = strchr (s, '.');
 		if (!t) {
@@ -1282,6 +1300,7 @@
 		su->sat.sat_addr.s_node = val;
 		rtm_addrs |= RTA_NETMASK;
 		return(forcehost || su->sat.sat_addr.s_node != 0);
+#endif
 
 	case AF_LINK:
 		link_addr(s, &su->sdl);
@@ -1300,8 +1319,7 @@
 		*t = '\0';
 		if ((val = inet_addr(s)) != INADDR_NONE) {
 			inet_makenetandmask(htonl(val), &su->sin);
-			prefixlen(&t[1]);
-			return (0);
+			return prefixlen(&t[1]);
 		}
 		*t = '/';
 	}
@@ -1596,8 +1614,8 @@
 #ifdef INET6
 	case AF_INET6:
 #endif
-	case AF_APPLETALK:
 #ifndef SMALL
+	case AF_APPLETALK:
 	case AF_NS:
 	case AF_CCITT:
 #endif /* SMALL */
@@ -1971,10 +1989,12 @@
 		(void) printf("%s: inet %s; ",
 		    which, inet_ntoa(su->sin.sin_addr));
 		break;
+#ifndef SMALL
 	case AF_APPLETALK:
 		(void) printf("%s: atalk %d.%d; ",
 		    which, su->sat.sat_addr.s_net, su->sat.sat_addr.s_node);
 		break;
+#endif
 	case AF_LINK:
 		(void) printf("%s: link %s; ",
 		    which, link_ntoa(&su->sdl));
>Release-Note:
>Audit-Trail:
>Unformatted: