Address.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * ZeroTier One - Global Peer to Peer Ethernet
  3. * Copyright (C) 2012-2013 ZeroTier Networks LLC
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * --
  19. *
  20. * ZeroTier may be used and distributed under the terms of the GPLv3, which
  21. * are available at: http://www.gnu.org/licenses/gpl-3.0.html
  22. *
  23. * If you would like to embed ZeroTier into a commercial application or
  24. * redistribute it in a modified binary form, please contact ZeroTier Networks
  25. * LLC. Start here: http://www.zerotier.com/
  26. */
  27. #ifndef _ZT_ADDRESS_HPP
  28. #define _ZT_ADDRESS_HPP
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <stdint.h>
  32. #include <string.h>
  33. #include <string>
  34. #include "Constants.hpp"
  35. #include "Utils.hpp"
  36. #include "MAC.hpp"
  37. #include "Buffer.hpp"
  38. namespace ZeroTier {
  39. /**
  40. * A ZeroTier address
  41. */
  42. class Address
  43. {
  44. public:
  45. Address()
  46. throw() :
  47. _a(0)
  48. {
  49. }
  50. Address(const Address &a)
  51. throw() :
  52. _a(a._a)
  53. {
  54. }
  55. Address(uint64_t a)
  56. throw() :
  57. _a(a & 0xffffffffffULL)
  58. {
  59. }
  60. Address(const char *s)
  61. throw()
  62. {
  63. unsigned char foo[ZT_ADDRESS_LENGTH];
  64. setTo(foo,Utils::unhex(s,foo,ZT_ADDRESS_LENGTH));
  65. }
  66. Address(const std::string &s)
  67. throw()
  68. {
  69. unsigned char foo[ZT_ADDRESS_LENGTH];
  70. setTo(foo,Utils::unhex(s.c_str(),foo,ZT_ADDRESS_LENGTH));
  71. }
  72. /**
  73. * @param bits Raw address -- 5 bytes, big-endian byte order
  74. * @param len Length of array
  75. */
  76. Address(const void *bits,unsigned int len)
  77. throw()
  78. {
  79. setTo(bits,len);
  80. }
  81. inline Address &operator=(const Address &a)
  82. throw()
  83. {
  84. _a = a._a;
  85. return *this;
  86. }
  87. inline Address &operator=(const uint64_t a)
  88. throw()
  89. {
  90. _a = (a & 0xffffffffffULL);
  91. return *this;
  92. }
  93. /**
  94. * @param bits Raw address -- 5 bytes, big-endian byte order
  95. * @param len Length of array
  96. */
  97. inline void setTo(const void *bits,unsigned int len)
  98. throw()
  99. {
  100. if (len < ZT_ADDRESS_LENGTH) {
  101. _a = 0;
  102. return;
  103. }
  104. const unsigned char *b = (const unsigned char *)bits;
  105. uint64_t a = ((uint64_t)*b++) << 32;
  106. a |= ((uint64_t)*b++) << 24;
  107. a |= ((uint64_t)*b++) << 16;
  108. a |= ((uint64_t)*b++) << 8;
  109. a |= ((uint64_t)*b);
  110. _a = a;
  111. }
  112. /**
  113. * @param bits Buffer to hold 5-byte address in big-endian byte order
  114. * @param len Length of array
  115. */
  116. inline void copyTo(void *bits,unsigned int len) const
  117. throw()
  118. {
  119. if (len < ZT_ADDRESS_LENGTH)
  120. return;
  121. unsigned char *b = (unsigned char *)bits;
  122. *(b++) = (unsigned char)((_a >> 32) & 0xff);
  123. *(b++) = (unsigned char)((_a >> 24) & 0xff);
  124. *(b++) = (unsigned char)((_a >> 16) & 0xff);
  125. *(b++) = (unsigned char)((_a >> 8) & 0xff);
  126. *b = (unsigned char)(_a & 0xff);
  127. }
  128. /**
  129. * Append to a buffer in big-endian byte order
  130. *
  131. * @param b Buffer to append to
  132. */
  133. template<unsigned int C>
  134. inline void appendTo(Buffer<C> &b) const
  135. throw(std::out_of_range)
  136. {
  137. b.append((unsigned char)((_a >> 32) & 0xff));
  138. b.append((unsigned char)((_a >> 24) & 0xff));
  139. b.append((unsigned char)((_a >> 16) & 0xff));
  140. b.append((unsigned char)((_a >> 8) & 0xff));
  141. b.append((unsigned char)(_a & 0xff));
  142. }
  143. /**
  144. * @return String containing address as 5 binary bytes
  145. */
  146. inline std::string toBinaryString() const
  147. {
  148. std::string b;
  149. b.push_back((char)((_a >> 32) & 0xff));
  150. b.push_back((char)((_a >> 24) & 0xff));
  151. b.push_back((char)((_a >> 16) & 0xff));
  152. b.push_back((char)((_a >> 8) & 0xff));
  153. b.push_back((char)(_a & 0xff));
  154. return b;
  155. }
  156. /**
  157. * @return Integer containing address (0 to 2^40)
  158. */
  159. inline uint64_t toInt() const
  160. throw()
  161. {
  162. return _a;
  163. }
  164. /**
  165. * Derive a MAC whose first octet is the ZeroTier LAN standard
  166. *
  167. * @return Ethernet MAC derived from address
  168. */
  169. inline MAC toMAC() const
  170. throw()
  171. {
  172. MAC m;
  173. m.data[0] = ZT_MAC_FIRST_OCTET;
  174. copyTo(m.data + 1,ZT_ADDRESS_LENGTH);
  175. return m;
  176. }
  177. /**
  178. * @param mac MAC address to check
  179. * @return True if this address would have this MAC
  180. */
  181. inline bool wouldHaveMac(const MAC &mac) const
  182. throw()
  183. {
  184. if (mac.data[0] != ZT_MAC_FIRST_OCTET)
  185. return false;
  186. if (mac.data[1] != (unsigned char)((_a >> 32) & 0xff))
  187. return false;
  188. if (mac.data[2] != (unsigned char)((_a >> 24) & 0xff))
  189. return false;
  190. if (mac.data[3] != (unsigned char)((_a >> 16) & 0xff))
  191. return false;
  192. if (mac.data[4] != (unsigned char)((_a >> 8) & 0xff))
  193. return false;
  194. if (mac.data[5] != (unsigned char)(_a & 0xff))
  195. return false;
  196. return true;
  197. }
  198. /**
  199. * @return Hexadecimal string
  200. */
  201. inline std::string toString() const
  202. {
  203. char buf[16];
  204. Utils::snprintf(buf,sizeof(buf),"%.10llx",(unsigned long long)_a);
  205. return std::string(buf);
  206. };
  207. /**
  208. * @return True if this address is not zero
  209. */
  210. inline operator bool() const throw() { return (_a != 0); }
  211. /**
  212. * Set to null/zero
  213. */
  214. inline void zero()
  215. throw()
  216. {
  217. _a = 0;
  218. }
  219. /**
  220. * Check if this address is reserved
  221. *
  222. * The all-zero null address and any address beginning with 0xff are
  223. * reserved. (0xff is reserved for future use to designate possibly
  224. * longer addresses, addresses based on IPv6 innards, etc.)
  225. *
  226. * @return True if address is reserved and may not be used
  227. */
  228. inline bool isReserved() const
  229. throw()
  230. {
  231. return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX));
  232. }
  233. /**
  234. * @param i Value from 0 to 4 (inclusive)
  235. * @return Byte at said position (address interpreted in big-endian order)
  236. */
  237. inline unsigned char operator[](unsigned int i) const throw() { return (unsigned char)((_a >> (32 - (i * 8))) & 0xff); }
  238. inline bool operator==(const Address &a) const throw() { return (_a == a._a); }
  239. inline bool operator!=(const Address &a) const throw() { return (_a != a._a); }
  240. inline bool operator>(const Address &a) const throw() { return (_a > a._a); }
  241. inline bool operator<(const Address &a) const throw() { return (_a < a._a); }
  242. inline bool operator>=(const Address &a) const throw() { return (_a >= a._a); }
  243. inline bool operator<=(const Address &a) const throw() { return (_a <= a._a); }
  244. private:
  245. uint64_t _a;
  246. };
  247. } // namespace ZeroTier
  248. #endif