aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorHajimu UMEMOTO <ume@FreeBSD.org>2002-05-20 15:01:19 +0000
committerHajimu UMEMOTO <ume@FreeBSD.org>2002-05-20 15:01:19 +0000
commit5818927a00282d71f202c8bb2c106b4d14e52453 (patch)
treee83c2be2c637b83389d48bb779195c67657e580b /sbin
parente9e705b0df81b36cfc5cbdf4106bddffb92c1c4b (diff)
downloadsrc-5818927a00282d71f202c8bb2c106b4d14e52453.tar.gz
src-5818927a00282d71f202c8bb2c106b4d14e52453.zip
Try to guess prefixlen for guessable cases.
- /0 if matches ::/128 - /64 if matches 2000::/3 and lowermost 64 bit is all 0 - /128 if matches 2000::/3 and lowermost 64 bit is non-zero 0 Obtained from: KAME/NetBSD
Notes
Notes: svn path=/head/; revision=96997
Diffstat (limited to 'sbin')
-rw-r--r--sbin/route/route.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 676526f7a2d9..83ec02e0350d 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -859,6 +859,37 @@ inet_makenetandmask(net, sin, bits)
sin->sin_len = 1 + cp - (char *)sin;
}
+#ifdef INET6
+/*
+ * XXX the function may need more improvement...
+ */
+static void
+inet6_makenetandmask(sin6)
+ struct sockaddr_in6 *sin6;
+{
+ char *plen;
+ struct in6_addr in6;
+
+ plen = NULL;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
+ sin6->sin6_scope_id == 0) {
+ plen = "0";
+ } else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
+ /* aggregatable global unicast - RFC2374 */
+ memset(&in6, 0, sizeof(in6));
+ if (!memcmp(&sin6->sin6_addr.s6_addr[8], &in6.s6_addr[8], 8))
+ plen = "64";
+ else
+ plen = "128";
+ }
+
+ if (plen) {
+ rtm_addrs |= RTA_NETMASK;
+ prefixlen(plen);
+ }
+}
+#endif
+
/*
* Interpret an argument as a network address of some kind,
* returning 1 if a host address, 0 if a network address.
@@ -980,6 +1011,8 @@ getaddr(which, s, hpp)
su->sin6.sin6_scope_id = 0;
}
#endif
+ if (which == RTA_DST)
+ inet6_makenetandmask(&su->sin6);
freeaddrinfo(res);
return (0);
}