summaryrefslogtreecommitdiff
path: root/node/InetAddress.hpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@zerotier.com>2014-01-23 14:15:00 -0800
committerAdam Ierymenko <adam.ierymenko@zerotier.com>2014-01-23 14:15:00 -0800
commit2f37ea842fc15790406d770a487725e70c1aa98c (patch)
treea1199a556d8b25c1da11dbff880605ef6ee354d6 /node/InetAddress.hpp
parent9232ba1da05a6f4f884d7d5d5d644ec3ca6dad33 (diff)
downloadinfinitytier-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.hpp48
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); }