Address.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * ZeroTier One - Global Peer to Peer Ethernet
  3. * Copyright (C) 2011-2014 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. unsigned char *p = (unsigned char *)b.appendField(ZT_ADDRESS_LENGTH);
  138. *(p++) = (unsigned char)((_a >> 32) & 0xff);
  139. *(p++) = (unsigned char)((_a >> 24) & 0xff);
  140. *(p++) = (unsigned char)((_a >> 16) & 0xff);
  141. *(p++) = (unsigned char)((_a >> 8) & 0xff);
  142. *p = (unsigned char)(_a & 0xff);
  143. }
  144. /**
  145. * @return Integer containing address (0 to 2^40)
  146. */
  147. inline uint64_t toInt() const
  148. throw()
  149. {
  150. return _a;
  151. }
  152. /**
  153. * Derive a MAC whose first octet is the ZeroTier LAN standard
  154. *
  155. * @return Ethernet MAC derived from address
  156. */
  157. inline MAC toMAC() const
  158. throw()
  159. {
  160. MAC m;
  161. m.data[0] = ZT_MAC_FIRST_OCTET;
  162. copyTo(m.data + 1,ZT_ADDRESS_LENGTH);
  163. return m;
  164. }
  165. /**
  166. * @param mac MAC address to check
  167. * @return True if this address would have this MAC
  168. */
  169. inline bool wouldHaveMac(const MAC &mac) const
  170. throw()
  171. {
  172. return ((mac.data[0] == ZT_MAC_FIRST_OCTET)&&
  173. (mac.data[1] == (unsigned char)((_a >> 32) & 0xff))&&
  174. (mac.data[2] == (unsigned char)((_a >> 24) & 0xff))&&
  175. (mac.data[3] == (unsigned char)((_a >> 16) & 0xff))&&
  176. (mac.data[4] == (unsigned char)((_a >> 8) & 0xff))&&
  177. (mac.data[5] == (unsigned char)(_a & 0xff)));
  178. }
  179. /**
  180. * @return Hexadecimal string
  181. */
  182. inline std::string toString() const
  183. {
  184. char buf[16];
  185. Utils::snprintf(buf,sizeof(buf),"%.10llx",(unsigned long long)_a);
  186. return std::string(buf);
  187. };
  188. /**
  189. * @return True if this address is not zero
  190. */
  191. inline operator bool() const throw() { return (_a != 0); }
  192. /**
  193. * Set to null/zero
  194. */
  195. inline void zero() throw() { _a = 0; }
  196. /**
  197. * Check if this address is reserved
  198. *
  199. * The all-zero null address and any address beginning with 0xff are
  200. * reserved. (0xff is reserved for future use to designate possibly
  201. * longer addresses, addresses based on IPv6 innards, etc.)
  202. *
  203. * @return True if address is reserved and may not be used
  204. */
  205. inline bool isReserved() const
  206. throw()
  207. {
  208. return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX));
  209. }
  210. /**
  211. * @param i Value from 0 to 4 (inclusive)
  212. * @return Byte at said position (address interpreted in big-endian order)
  213. */
  214. inline unsigned char operator[](unsigned int i) const throw() { return (unsigned char)((_a >> (32 - (i * 8))) & 0xff); }
  215. inline bool operator==(const Address &a) const throw() { return (_a == a._a); }
  216. inline bool operator!=(const Address &a) const throw() { return (_a != a._a); }
  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. private:
  222. uint64_t _a;
  223. };
  224. } // namespace ZeroTier
  225. #endif