Implement isPrivateNetworkAddress() for IPv6

This commit is contained in:
Cameron Gutman
2019-07-15 00:16:17 -07:00
parent 6245934462
commit 25dfbcfd41
+43 -4
View File
@@ -348,13 +348,26 @@ int resolveHostName(const char* host, int family, int tcpTestPort, struct sockad
#endif #endif
} }
int isPrivateNetworkAddress(struct sockaddr_storage* address) { #ifndef __vita__
unsigned int addr; int isInSubnetV6(struct sockaddr_in6* sin6, unsigned char* subnet, int prefixLength) {
int i;
// We only count IPv4 addresses as possibly private for now for (i = 0; i < prefixLength; i++) {
if (address->ss_family != AF_INET) { unsigned char mask = 1 << (i % 8);
if ((sin6->sin6_addr.s6_addr[i / 8] & mask) != (subnet[i / 8] & mask)) {
return 0; return 0;
} }
}
return 1;
}
#endif
int isPrivateNetworkAddress(struct sockaddr_storage* address) {
// We only count IPv4 addresses as possibly private for now
if (address->ss_family == AF_INET) {
unsigned int addr;
memcpy(&addr, &((struct sockaddr_in*)address)->sin_addr, sizeof(addr)); memcpy(&addr, &((struct sockaddr_in*)address)->sin_addr, sizeof(addr));
addr = htonl(addr); addr = htonl(addr);
@@ -371,6 +384,32 @@ int isPrivateNetworkAddress(struct sockaddr_storage* address) {
else if ((addr & 0xFFFF0000) == 0xC0A80000) { else if ((addr & 0xFFFF0000) == 0xC0A80000) {
return 1; return 1;
} }
// 169.254.0.0/16
else if ((addr & 0xFFFF0000) == 0xA9FE0000) {
return 1;
}
}
#ifndef __vita__
else if (address->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)address;
static unsigned char linkLocalPrefix[] = {0xfe, 0x80};
static unsigned char siteLocalPrefix[] = {0xfe, 0xc0};
static unsigned char uniqueLocalPrefix[] = {0xfc, 0x00};
// fe80::/10
if (isInSubnetV6(sin6, linkLocalPrefix, 10)) {
return 1;
}
// fec0::/10
else if (isInSubnetV6(sin6, siteLocalPrefix, 10)) {
return 1;
}
// fc00::/7
else if (isInSubnetV6(sin6, uniqueLocalPrefix, 7)) {
return 1;
}
}
#endif
return 0; return 0;
} }