diff options
-rw-r--r-- | libc/include/netinet/in6.h | 4 | ||||
-rw-r--r-- | libc/netbsd/net/getaddrinfo.c | 54 |
2 files changed, 41 insertions, 17 deletions
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h index 2f5fee1..efd5c0a 100644 --- a/libc/include/netinet/in6.h +++ b/libc/include/netinet/in6.h @@ -60,6 +60,10 @@ #define IN6_IS_ADDR_SITELOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) +/* RFC 4193. */ +#define IN6_IS_ADDR_ULA(a) \ + (((a)->s6_addr[0] & 0xfe) == 0xfc) + #define IN6_IS_ADDR_MULTICAST(a) \ (((__const uint8_t *) (a))[0] == 0xff) diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c index 895662e..e4d8c56 100644 --- a/libc/netbsd/net/getaddrinfo.c +++ b/libc/netbsd/net/getaddrinfo.c @@ -1319,11 +1319,13 @@ _get_scope(const struct sockaddr *addr) if (IN_LOOPBACK(na) || /* 127.0.0.0/8 */ (na & 0xffff0000) == 0xa9fe0000) { /* 169.254.0.0/16 */ return IPV6_ADDR_SCOPE_LINKLOCAL; - } else if ((na & 0xff000000) == 0x0a000000 || /* 10.0.0.0/8 */ - (na & 0xfff00000) == 0xac100000 || /* 172.16.0.0/12 */ - (na & 0xffff0000) == 0xc0a80000) { /* 192.168.0.0/16 */ - return IPV6_ADDR_SCOPE_SITELOCAL; } else { + /* + * According to draft-ietf-6man-rfc3484-revise-01 section 2.3, + * it is best not to treat the private IPv4 ranges + * (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) as being + * in a special scope, so we don't. + */ return IPV6_ADDR_SCOPE_GLOBAL; } } else { @@ -1345,9 +1347,13 @@ _get_scope(const struct sockaddr *addr) #define IN6_IS_ADDR_6TO4(a) \ (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02)) +/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */ +#define IN6_IS_ADDR_6BONE(a) \ + (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe)) + /* * Get the label for a given IPv4/IPv6 address. - * RFC 3484, section 2.1, plus Teredo added in with label 5. + * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01. */ /*ARGSUSED*/ @@ -1355,19 +1361,27 @@ static int _get_label(const struct sockaddr *addr) { if (addr->sa_family == AF_INET) { - return 4; + return 3; } else if (addr->sa_family == AF_INET6) { const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) { return 0; - } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) { + } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) { + return 1; + } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { return 3; + } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { + return 4; } else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) { return 5; - } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { - return 2; + } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) { + return 10; + } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) { + return 11; + } else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) { + return 12; } else { - return 1; + return 2; } } else { /* @@ -1380,7 +1394,7 @@ _get_label(const struct sockaddr *addr) /* * Get the precedence for a given IPv4/IPv6 address. - * RFC 3484, section 2.1, plus Teredo added in with precedence 25. + * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01. */ /*ARGSUSED*/ @@ -1388,22 +1402,28 @@ static int _get_precedence(const struct sockaddr *addr) { if (addr->sa_family == AF_INET) { - return 10; + return 30; } else if (addr->sa_family == AF_INET6) { const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) { + return 60; + } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) { return 50; - } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) { + } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { + return 30; + } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { return 20; } else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) { - return 25; - } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { - return 30; + return 10; + } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) || + IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) || + IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) { + return 1; } else { return 40; } } else { - return 5; + return 1; } } |