From 5818927a00282d71f202c8bb2c106b4d14e52453 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Mon, 20 May 2002 15:01:19 +0000 Subject: [PATCH] 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 --- sbin/route/route.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) 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); }