diff options
Diffstat (limited to 'node/InetAddress.cpp')
-rw-r--r-- | node/InetAddress.cpp | 320 |
1 files changed, 113 insertions, 207 deletions
diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 45781f42..9452086a 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -45,24 +45,29 @@ const InetAddress InetAddress::DEFAULT6((const void *)0,16,0); void InetAddress::set(const std::string &ip,unsigned int port) throw() { - memset(&_sa,0,sizeof(_sa)); if (ip.find(':') != std::string::npos) { - _sa.sin6.sin6_family = AF_INET6; - _sa.sin6.sin6_port = Utils::hton((uint16_t)port); - if (inet_pton(AF_INET6,ip.c_str(),(void *)&(_sa.sin6.sin6_addr.s6_addr)) <= 0) - _sa.saddr.sa_family = 0; + struct sockaddr_in6 sin6; + memset(&sin6,0,sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = Utils::hton((uint16_t)port); + if (inet_pton(AF_INET6,ip.c_str(),(void *)&(sin6.sin6_addr.s6_addr)) <= 0) + memset(this,0,sizeof(InetAddress)); + else *this = sin6; } else { - _sa.sin.sin_family = AF_INET; - _sa.sin.sin_port = Utils::hton((uint16_t)port); - if (inet_pton(AF_INET,ip.c_str(),(void *)&(_sa.sin.sin_addr.s_addr)) <= 0) - _sa.saddr.sa_family = 0; + struct sockaddr_in sin; + memset(&sin,0,sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = Utils::hton((uint16_t)port); + if (inet_pton(AF_INET,ip.c_str(),(void *)&(sin.sin_addr.s_addr)) <= 0) + memset(this,0,sizeof(InetAddress)); + else *this = sin; } } void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) throw() { - memset(&_sa,0,sizeof(_sa)); + memset(this,0,sizeof(InetAddress)); if (ipLen == 4) { setV4(); if (ipBytes) @@ -79,59 +84,87 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) bool InetAddress::isLinkLocal() const throw() { - if (_sa.saddr.sa_family == AF_INET) - return ((Utils::ntoh((uint32_t)_sa.sin.sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000); - else if (_sa.saddr.sa_family == AF_INET6) { - if (_sa.sin6.sin6_addr.s6_addr[0] != 0xfe) return false; - if (_sa.sin6.sin6_addr.s6_addr[1] != 0x80) return false; - if (_sa.sin6.sin6_addr.s6_addr[2] != 0x00) return false; - if (_sa.sin6.sin6_addr.s6_addr[3] != 0x00) return false; - if (_sa.sin6.sin6_addr.s6_addr[4] != 0x00) return false; - if (_sa.sin6.sin6_addr.s6_addr[5] != 0x00) return false; - if (_sa.sin6.sin6_addr.s6_addr[6] != 0x00) return false; - if (_sa.sin6.sin6_addr.s6_addr[7] != 0x00) return false; - return true; + static const unsigned char v6llPrefix[8] = { 0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00 }; + switch(ss_family) { + case AF_INET: + return ((Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000); + case AF_INET6: + return (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,v6llPrefix,8) == 0); } return false; } -bool InetAddress::isDefaultRoute() const - throw() +std::string InetAddress::toString() const { - if (_sa.saddr.sa_family == AF_INET) - return ((_sa.sin.sin_addr.s_addr == 0)&&(_sa.sin.sin_port == 0)); - else if (_sa.saddr.sa_family == AF_INET6) - return ((Utils::isZero(_sa.sin6.sin6_addr.s6_addr,16))&&(_sa.sin6.sin6_port == 0)); - return false; + char buf[128]; + switch(ss_family) { + case AF_INET: + Utils::snprintf(buf,sizeof(buf),"%d.%d.%d.%d/%d", + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[0], + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[1], + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[2], + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[3], + (int)Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port)) + ); + return std::string(buf); + case AF_INET6: + Utils::snprintf(buf,sizeof(buf),"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d", + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[0]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[1]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[2]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[3]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[4]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[5]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[6]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[7]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[8]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[9]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[10]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[11]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[12]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[13]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[14]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[15]), + (int)Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port)) + ); + return std::string(buf); + } + return std::string(); } -std::string InetAddress::toString() const +std::string InetAddress::toIpString() const { - char buf[128],buf2[128]; - - switch(_sa.saddr.sa_family) { + char buf[128]; + switch(ss_family) { case AF_INET: -#ifdef __WINDOWS__ - if (inet_ntop(AF_INET,(PVOID)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) { -#else - if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) { -#endif - Utils::snprintf(buf2,sizeof(buf2),"%s/%u",buf,(unsigned int)ntohs(_sa.sin.sin_port)); - return std::string(buf2); - } - break; + Utils::snprintf(buf,sizeof(buf),"%d.%d.%d.%d", + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[0], + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[1], + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[2], + (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[3] + ); + return std::string(buf); case AF_INET6: -#ifdef __WINDOWS__ - if (inet_ntop(AF_INET6,(PVOID)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) { -#else - if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) { -#endif - Utils::snprintf(buf2,sizeof(buf2),"%s/%u",buf,(unsigned int)ntohs(_sa.sin6.sin6_port)); - return std::string(buf2); - } - break; + Utils::snprintf(buf,sizeof(buf),"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[0]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[1]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[2]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[3]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[4]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[5]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[6]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[7]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[8]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[9]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[10]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[11]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[12]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[13]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[14]), + (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[15]) + ); + return std::string(buf); } - return std::string(); } @@ -148,48 +181,22 @@ void InetAddress::fromString(const std::string &ipSlashPort) } } -std::string InetAddress::toIpString() const -{ - char buf[128]; - switch(_sa.saddr.sa_family) { - case AF_INET: -#ifdef __WINDOWS__ - if (inet_ntop(AF_INET,(PVOID)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) - return std::string(buf); -#else - if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) - return std::string(buf); -#endif - break; - case AF_INET6: -#ifdef __WINDOWS__ - if (inet_ntop(AF_INET6,(PVOID)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) - return std::string(buf); -#else - if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) - return std::string(buf); -#endif - break; - } - return std::string(); -} - InetAddress InetAddress::netmask() const throw() { InetAddress r(*this); - switch(_sa.saddr.sa_family) { + switch(r.ss_family) { case AF_INET: - r._sa.sin.sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffff << (32 - 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 = (unsigned char *)r._sa.sin6.sin6_addr.s6_addr; + 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) ? 0xff : (0xff << (8 - bitsLeft))); + bf[i] |= (unsigned char)((bitsLeft >= 8) ? 0x00 : (0xff >> bitsLeft)); bitsLeft -= 8; - } else bf[i] = (unsigned char)0; + } } } break; } @@ -200,12 +207,12 @@ InetAddress InetAddress::broadcast() const throw() { InetAddress r(*this); - switch(_sa.saddr.sa_family) { + switch(r.ss_family) { case AF_INET: - r._sa.sin.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 >> netmaskBits())); break; case AF_INET6: { - unsigned char *bf = (unsigned char *)r._sa.sin6.sin6_addr.s6_addr; + 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) { @@ -218,130 +225,29 @@ InetAddress InetAddress::broadcast() const return r; } -bool InetAddress::sameNetworkAs(const InetAddress &ipnet) const - throw() -{ - if (_sa.saddr.sa_family != ipnet._sa.saddr.sa_family) - return false; - - unsigned int bits = netmaskBits(); - if (bits != ipnet.netmaskBits()) - return false; - if (!bits) - return true; - switch(_sa.saddr.sa_family) { - case AF_INET: - if (bits >= 32) bits = 32; - break; - case AF_INET6: - if (bits >= 128) bits = 128; - break; - default: - return false; - } - - const uint8_t *a = (const uint8_t *)rawIpData(); - const uint8_t *b = (const uint8_t *)ipnet.rawIpData(); - while (bits >= 8) { - if (*(a++) != *(b++)) - return false; - bits -= 8; - } - bits = 8 - bits; - return ((*a >> bits) == (*b >> bits)); -} - -bool InetAddress::within(const InetAddress &ipnet) const - throw() -{ - if (_sa.saddr.sa_family != ipnet._sa.saddr.sa_family) - return false; - - unsigned int bits = ipnet.netmaskBits(); - switch(_sa.saddr.sa_family) { - case AF_INET: - if (bits > 32) return false; - break; - case AF_INET6: - if (bits > 128) return false; - break; - default: return false; - } - - const uint8_t *a = (const uint8_t *)rawIpData(); - const uint8_t *b = (const uint8_t *)ipnet.rawIpData(); - while (bits >= 8) { - if (*(a++) != *(b++)) - return false; - bits -= 8; - } - if (bits) { - uint8_t mask = ((0xff << (8 - bits)) & 0xff); - return ((*a & mask) == (*b & mask)); - } else return true; -} - -bool InetAddress::operator==(const InetAddress &a) const - throw() -{ - if (_sa.saddr.sa_family == AF_INET) { - if (a._sa.saddr.sa_family == AF_INET) - return ((_sa.sin.sin_addr.s_addr == a._sa.sin.sin_addr.s_addr)&&(_sa.sin.sin_port == a._sa.sin.sin_port)); - return false; - } else if (_sa.saddr.sa_family == AF_INET6) { - if (a._sa.saddr.sa_family == AF_INET6) { - if (_sa.sin6.sin6_port == a._sa.sin6.sin6_port) - return (!memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,sizeof(_sa.sin6.sin6_addr.s6_addr))); - } - return false; - } else return (memcmp(&_sa,&a._sa,sizeof(_sa)) == 0); -} - -bool InetAddress::operator<(const InetAddress &a) const - throw() -{ - if (_sa.saddr.sa_family < a._sa.saddr.sa_family) - return true; - else if (_sa.saddr.sa_family == a._sa.saddr.sa_family) { - if (_sa.saddr.sa_family == AF_INET) { - unsigned long x = Utils::ntoh((uint32_t)_sa.sin.sin_addr.s_addr); - unsigned long y = Utils::ntoh((uint32_t)a._sa.sin.sin_addr.s_addr); - if (x == y) - return (Utils::ntoh((uint16_t)_sa.sin.sin_port) < Utils::ntoh((uint16_t)a._sa.sin.sin_port)); - else return (x < y); - } else if (_sa.saddr.sa_family == AF_INET6) { - int cmp = (int)memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16); - if (cmp == 0) - return (Utils::ntoh((uint16_t)_sa.sin6.sin6_port) < Utils::ntoh((uint16_t)a._sa.sin6.sin6_port)); - else return (cmp < 0); - } else return (memcmp(&_sa,&a._sa,sizeof(_sa)) < 0); - } - return false; -} - InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) throw() { - InetAddress ip; - ip._sa.saddr.sa_family = AF_INET6; - ip._sa.sin6.sin6_addr.s6_addr[0] = 0xfe; - ip._sa.sin6.sin6_addr.s6_addr[1] = 0x80; - ip._sa.sin6.sin6_addr.s6_addr[2] = 0x00; - ip._sa.sin6.sin6_addr.s6_addr[3] = 0x00; - ip._sa.sin6.sin6_addr.s6_addr[4] = 0x00; - ip._sa.sin6.sin6_addr.s6_addr[5] = 0x00; - ip._sa.sin6.sin6_addr.s6_addr[6] = 0x00; - ip._sa.sin6.sin6_addr.s6_addr[7] = 0x00; - ip._sa.sin6.sin6_addr.s6_addr[8] = mac[0] & 0xfd; - ip._sa.sin6.sin6_addr.s6_addr[9] = mac[1]; - ip._sa.sin6.sin6_addr.s6_addr[10] = mac[2]; - ip._sa.sin6.sin6_addr.s6_addr[11] = 0xff; - ip._sa.sin6.sin6_addr.s6_addr[12] = 0xfe; - ip._sa.sin6.sin6_addr.s6_addr[13] = mac[3]; - ip._sa.sin6.sin6_addr.s6_addr[14] = mac[4]; - ip._sa.sin6.sin6_addr.s6_addr[15] = mac[5]; - ip._sa.sin6.sin6_port = Utils::hton((uint16_t)64); - return ip; + struct sockaddr_in6 sin6; + sin6.sin6_family = AF_INET6; + sin6.sin6_addr.s6_addr[0] = 0xfe; + sin6.sin6_addr.s6_addr[1] = 0x80; + sin6.sin6_addr.s6_addr[2] = 0x00; + sin6.sin6_addr.s6_addr[3] = 0x00; + sin6.sin6_addr.s6_addr[4] = 0x00; + sin6.sin6_addr.s6_addr[5] = 0x00; + sin6.sin6_addr.s6_addr[6] = 0x00; + sin6.sin6_addr.s6_addr[7] = 0x00; + sin6.sin6_addr.s6_addr[8] = mac[0] & 0xfd; + sin6.sin6_addr.s6_addr[9] = mac[1]; + sin6.sin6_addr.s6_addr[10] = mac[2]; + sin6.sin6_addr.s6_addr[11] = 0xff; + sin6.sin6_addr.s6_addr[12] = 0xfe; + sin6.sin6_addr.s6_addr[13] = mac[3]; + sin6.sin6_addr.s6_addr[14] = mac[4]; + sin6.sin6_addr.s6_addr[15] = mac[5]; + sin6.sin6_port = Utils::hton((uint16_t)64); + return InetAddress(sin6); } } // namespace ZeroTier |