Address.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 "Utils.hpp"
  35. #include "MAC.hpp"
  36. #include "Constants.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. * @return Hexadecimal string
  179. */
  180. inline std::string toString() const
  181. {
  182. char buf[16];
  183. sprintf(buf,"%.10llx",(unsigned long long)_a);
  184. return std::string(buf);
  185. };
  186. /**
  187. * @return True if this address is not zero
  188. */
  189. inline operator bool() const throw() { return (_a); }
  190. /**
  191. * @return Sum of all bytes in address
  192. */
  193. inline unsigned int sum() const
  194. throw()
  195. {
  196. return (unsigned int)(((_a >> 32) & 0xff) + ((_a >> 24) & 0xff) + ((_a >> 16) & 0xff) + ((_a >> 8) & 0xff) + (_a & 0xff));
  197. }
  198. /**
  199. * Check if this address is reserved
  200. *
  201. * The all-zero null address and any address beginning with 0xff are
  202. * reserved. (0xff is reserved for future use to designate possibly
  203. * longer addresses, addresses based on IPv6 innards, etc.)
  204. *
  205. * @return True if address is reserved and may not be used
  206. */
  207. inline bool isReserved() const
  208. throw()
  209. {
  210. return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX));
  211. }
  212. /**
  213. * @param i Value from 0 to 4 (inclusive)
  214. * @return Byte at said position (address interpreted in big-endian order)
  215. */
  216. inline unsigned char operator[](unsigned int i) const throw() { return (unsigned char)((_a >> (32 - (i * 8))) & 0xff); }
  217. inline bool operator==(const Address &a) const throw() { return (_a == a._a); }
  218. inline bool operator!=(const Address &a) const throw() { return (_a != a._a); }
  219. inline bool operator>(const Address &a) const throw() { return (_a > a._a); }
  220. inline bool operator<(const Address &a) const throw() { return (_a < a._a); }
  221. inline bool operator>=(const Address &a) const throw() { return (_a >= a._a); }
  222. inline bool operator<=(const Address &a) const throw() { return (_a <= a._a); }
  223. private:
  224. uint64_t _a;
  225. };
  226. } // namespace ZeroTier
  227. #endif