summaryrefslogtreecommitdiff
path: root/node/InetAddress.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/InetAddress.cpp')
-rw-r--r--node/InetAddress.cpp79
1 files changed, 53 insertions, 26 deletions
diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp
index 1942c4cd..f35eb9c3 100644
--- a/node/InetAddress.cpp
+++ b/node/InetAddress.cpp
@@ -77,14 +77,12 @@ InetAddress::IpScope InetAddress::ipScope() const
if ((ip & 0xffff0000) == 0xc0a80000) return IP_SCOPE_PRIVATE; // 192.168.0.0/16
break;
case 0xff: return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable)
- default:
- switch(ip >> 28) {
- case 0xe: return IP_SCOPE_MULTICAST; // 224.0.0.0/4
- case 0xf: return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable)
- default: return IP_SCOPE_GLOBAL; // everything else
- }
- break;
}
+ switch(ip >> 28) {
+ case 0xe: return IP_SCOPE_MULTICAST; // 224.0.0.0/4
+ case 0xf: return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable)
+ }
+ return IP_SCOPE_GLOBAL;
} break;
case AF_INET6: {
@@ -236,7 +234,6 @@ void InetAddress::fromString(const std::string &ipSlashPort)
}
InetAddress InetAddress::netmask() const
- throw()
{
InetAddress r(*this);
switch(r.ss_family) {
@@ -244,36 +241,40 @@ InetAddress InetAddress::netmask() const
reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits())));
break;
case AF_INET6: {
- unsigned char *bf = reinterpret_cast<unsigned char *>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
- signed int bitsLeft = (signed int)netmaskBits();
- for(unsigned int i=0;i<16;++i) {
- if (bitsLeft > 0) {
- bf[i] |= (unsigned char)((bitsLeft >= 8) ? 0x00 : (0xff >> bitsLeft));
- bitsLeft -= 8;
- }
- }
+ uint64_t nm[2];
+ const unsigned int bits = netmaskBits();
+ nm[0] = Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
+ nm[1] = Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
+ memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16);
} break;
}
return r;
}
InetAddress InetAddress::broadcast() const
- throw()
+{
+ if (ss_family == AF_INET) {
+ InetAddress r(*this);
+ reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits()));
+ return r;
+ }
+ return InetAddress();
+}
+
+InetAddress InetAddress::network() const
{
InetAddress r(*this);
switch(r.ss_family) {
case AF_INET:
- reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits()));
+ reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits())));
break;
case AF_INET6: {
- unsigned char *bf = reinterpret_cast<unsigned char *>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
- signed int bitsLeft = (signed int)netmaskBits();
- for(unsigned int i=0;i<16;++i) {
- if (bitsLeft > 0) {
- bf[i] |= (unsigned char)((bitsLeft >= 8) ? 0x00 : (0xff >> bitsLeft));
- bitsLeft -= 8;
- }
- }
+ uint64_t nm[2];
+ const unsigned int bits = netmaskBits();
+ memcpy(nm,reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,16);
+ nm[0] &= Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
+ nm[1] &= Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
+ memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16);
} break;
}
return r;
@@ -399,4 +400,30 @@ InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac)
return InetAddress(sin6);
}
+InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress)
+ throw()
+{
+ InetAddress r;
+ struct sockaddr_in6 *const sin6 = reinterpret_cast<struct sockaddr_in6 *>(&r);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_addr.s6_addr[0] = 0xfd;
+ sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 56);
+ sin6->sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 48);
+ sin6->sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 40);
+ sin6->sin6_addr.s6_addr[4] = (uint8_t)(nwid >> 32);
+ sin6->sin6_addr.s6_addr[5] = (uint8_t)(nwid >> 24);
+ sin6->sin6_addr.s6_addr[6] = (uint8_t)(nwid >> 16);
+ sin6->sin6_addr.s6_addr[7] = (uint8_t)(nwid >> 8);
+ sin6->sin6_addr.s6_addr[8] = (uint8_t)nwid;
+ sin6->sin6_addr.s6_addr[9] = 0x99;
+ sin6->sin6_addr.s6_addr[10] = 0x93;
+ sin6->sin6_addr.s6_addr[11] = (uint8_t)(zeroTierAddress >> 32);
+ sin6->sin6_addr.s6_addr[12] = (uint8_t)(zeroTierAddress >> 24);
+ sin6->sin6_addr.s6_addr[13] = (uint8_t)(zeroTierAddress >> 16);
+ sin6->sin6_addr.s6_addr[14] = (uint8_t)(zeroTierAddress >> 8);
+ sin6->sin6_addr.s6_addr[15] = (uint8_t)zeroTierAddress;
+ sin6->sin6_port = Utils::hton((uint16_t)88); // /88 includes 0xfd + network ID, discriminating by device ID below that
+ return r;
+}
+
} // namespace ZeroTier