diff options
author | Hajimu UMEMOTO <ume@FreeBSD.org> | 2002-05-20 15:01:19 +0000 |
---|---|---|
committer | Hajimu UMEMOTO <ume@FreeBSD.org> | 2002-05-20 15:01:19 +0000 |
commit | 5818927a00282d71f202c8bb2c106b4d14e52453 (patch) | |
tree | e83c2be2c637b83389d48bb779195c67657e580b /sbin/route | |
parent | e9e705b0df81b36cfc5cbdf4106bddffb92c1c4b (diff) | |
download | src-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/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 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); } |