diff options
author | ume <ume@FreeBSD.org> | 2002-05-20 15:01:19 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2002-05-20 15:01:19 +0000 |
commit | d2bc88b0d8377dba477e0e7aa90b9ffae7258b63 (patch) | |
tree | e83c2be2c637b83389d48bb779195c67657e580b /sbin/route | |
parent | 85aa3f836d74b6a56e946ff36ce9a2466fe00fef (diff) | |
download | FreeBSD-src-d2bc88b0d8377dba477e0e7aa90b9ffae7258b63.zip FreeBSD-src-d2bc88b0d8377dba477e0e7aa90b9ffae7258b63.tar.gz |
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
Diffstat (limited to 'sbin/route')
-rw-r--r-- | sbin/route/route.c | 33 |
1 files changed, 33 insertions, 0 deletions
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); } |