Address.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. /**
  61. * @param bits Raw address -- 5 bytes, big-endian byte order
  62. */
  63. Address(const void *bits)
  64. throw()
  65. {
  66. setTo(bits);
  67. }
  68. inline Address &operator=(const Address &a)
  69. throw()
  70. {
  71. _a = a._a;
  72. return *this;
  73. }
  74. inline Address &operator=(const uint64_t a)
  75. throw()
  76. {
  77. _a = (a & 0xffffffffffULL);
  78. return *this;
  79. }
  80. /**
  81. * @param bits Raw address -- 5 bytes, big-endian byte order
  82. */
  83. inline void setTo(const void *bits)
  84. throw()
  85. {
  86. const unsigned char *b = (const unsigned char *)bits;
  87. uint64_t a = ((uint64_t)*b++) << 32;
  88. a |= ((uint64_t)*b++) << 24;
  89. a |= ((uint64_t)*b++) << 16;
  90. a |= ((uint64_t)*b++) << 8;
  91. a |= ((uint64_t)*b);
  92. _a = a;
  93. }
  94. /**
  95. * @param bits Buffer to hold 5-byte address in big-endian byte order
  96. */
  97. inline void copyTo(void *bits) const
  98. throw()
  99. {
  100. unsigned char *b = (unsigned char *)bits;
  101. *(b++) = (unsigned char)((_a >> 32) & 0xff);
  102. *(b++) = (unsigned char)((_a >> 24) & 0xff);
  103. *(b++) = (unsigned char)((_a >> 16) & 0xff);
  104. *(b++) = (unsigned char)((_a >> 8) & 0xff);
  105. *b = (unsigned char)(_a & 0xff);
  106. }
  107. /**
  108. * Append to a buffer in big-endian byte order
  109. *
  110. * @param b Buffer to append to
  111. */
  112. template<unsigned int C>
  113. inline void appendTo(Buffer<C> &b) const
  114. throw(std::out_of_range)
  115. {
  116. b.append((unsigned char)((_a >> 32) & 0xff));
  117. b.append((unsigned char)((_a >> 24) & 0xff));
  118. b.append((unsigned char)((_a >> 16) & 0xff));
  119. b.append((unsigned char)((_a >> 8) & 0xff));
  120. b.append((unsigned char)(_a & 0xff));
  121. }
  122. /**
  123. * @return String containing address as 5 binary bytes
  124. */
  125. inline std::string toBinaryString() const
  126. {
  127. std::string b;
  128. b.push_back((char)((_a >> 32) & 0xff));
  129. b.push_back((char)((_a >> 24) & 0xff));
  130. b.push_back((char)((_a >> 16) & 0xff));
  131. b.push_back((char)((_a >> 8) & 0xff));
  132. b.push_back((char)(_a & 0xff));
  133. return b;
  134. }
  135. /**
  136. * @return Integer containing address (0 to 2^40)
  137. */
  138. inline uint64_t toInt() const
  139. throw()
  140. {
  141. return _a;
  142. }
  143. /**
  144. * Derive a MAC whose first octet is the ZeroTier LAN standard
  145. *
  146. * @return Ethernet MAC derived from address
  147. */
  148. inline MAC toMAC() const
  149. throw()
  150. {
  151. MAC m;
  152. copyTo(m.data);
  153. return m;
  154. }
  155. /**
  156. * @return Hexadecimal string
  157. */
  158. inline std::string toString() const
  159. {
  160. char buf[16];
  161. sprintf(buf,"%.10llx",_a);
  162. return std::string(buf);
  163. };
  164. /**
  165. * @return True if this address is not zero
  166. */
  167. inline operator bool() const throw() { return (_a); }
  168. /**
  169. * @return Sum of all bytes in address
  170. */
  171. inline unsigned int sum() const
  172. throw()
  173. {
  174. return (unsigned int)(((_a >> 32) & 0xff) + ((_a >> 24) & 0xff) + ((_a >> 16) & 0xff) + ((_a >> 8) & 0xff) + (_a & 0xff));
  175. }
  176. /**
  177. * Check if this address is reserved
  178. *
  179. * The all-zero null address and any address beginning with 0xff are
  180. * reserved. (0xff is reserved for future use to designate possibly
  181. * longer addresses, addresses based on IPv6 innards, etc.)
  182. *
  183. * @return True if address is reserved and may not be used
  184. */
  185. inline bool isReserved() const
  186. throw()
  187. {
  188. return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX));
  189. }
  190. /**
  191. * @param i Value from 0 to 4 (inclusive)
  192. * @return Byte at said position (address interpreted in big-endian order)
  193. */
  194. inline unsigned char operator[](unsigned int i) const throw() { return (unsigned char)((_a >> (32 - (i * 8))) & 0xff); }
  195. inline bool operator==(const Address &a) const throw() { return (_a == a._a); }
  196. inline bool operator!=(const Address &a) const throw() { return (_a != a._a); }
  197. inline bool operator>(const Address &a) const throw() { return (_a > a._a); }
  198. inline bool operator<(const Address &a) const throw() { return (_a < a._a); }
  199. inline bool operator>=(const Address &a) const throw() { return (_a >= a._a); }
  200. inline bool operator<=(const Address &a) const throw() { return (_a <= a._a); }
  201. private:
  202. uint64_t _a;
  203. };
  204. } // namespace ZeroTier
  205. #endif