diff options
| author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-01-23 14:15:00 -0800 |
|---|---|---|
| committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-01-23 14:15:00 -0800 |
| commit | 2f37ea842fc15790406d770a487725e70c1aa98c (patch) | |
| tree | a1199a556d8b25c1da11dbff880605ef6ee354d6 /node/InetAddress.hpp | |
| parent | 9232ba1da05a6f4f884d7d5d5d644ec3ca6dad33 (diff) | |
| download | infinitytier-2f37ea842fc15790406d770a487725e70c1aa98c.tar.gz infinitytier-2f37ea842fc15790406d770a487725e70c1aa98c.zip | |
Couple of Windows fixes, get rid of ips()/allIps() distinction in EthernetTap. (Will need to be fixed on Unix now... later.)
Diffstat (limited to 'node/InetAddress.hpp')
| -rw-r--r-- | node/InetAddress.hpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index d90574e5..49729017 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -35,6 +35,7 @@ #include <string> #include "Constants.hpp" +#include "Utils.hpp" #ifdef __WINDOWS__ #include <WinSock2.h> @@ -189,6 +190,28 @@ public: } /** + * @return True if this is a link-local IP address + */ + inline bool 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; + } + return false; + } + + /** * @return ASCII IP/port format representation */ std::string toString() const; @@ -234,6 +257,31 @@ public: } /** + * Construct a full netmask as an InetAddress + */ + inline InetAddress netmask() const + throw() + { + InetAddress r(*this); + switch(_sa.saddr.sa_family) { + case AF_INET: + r._sa.sin.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; + 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))); + bitsLeft -= 8; + } else bf[i] = (unsigned char)0; + } + } break; + } + return r; + } + + /** * @return True if this is an IPv4 address */ inline bool isV4() const throw() { return (_sa.saddr.sa_family == AF_INET); } |
