From d2bc88b0d8377dba477e0e7aa90b9ffae7258b63 Mon Sep 17 00:00:00 2001 From: ume Date: Mon, 20 May 2002 15:01:19 +0000 Subject: 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(+) (limited to 'sbin/route') diff --git a/sbin/route/route.c b/sbin/route/route.c index 676526f..83ec02e 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); } -- cgit v1.1