io_address.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. // Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #ifndef IO_ADDRESS_H
  7. #define IO_ADDRESS_H 1
  8. // IMPORTANT NOTE: only very few ASIO headers files can be included in
  9. // this file. In particular, asio.hpp should never be included here.
  10. // See the description of the namespace below.
  11. #include <unistd.h> // for some network system calls
  12. #include <stdint.h> // for uint32_t
  13. #include <boost/asio/ip/address.hpp>
  14. #include <functional>
  15. #include <string>
  16. #include <vector>
  17. #include <exceptions/exceptions.h>
  18. namespace isc {
  19. namespace asiolink {
  20. /// Defines length of IPv6 address.
  21. const static size_t V6ADDRESS_LEN = 16;
  22. /// Defines length of IPv4 address.
  23. const static size_t V4ADDRESS_LEN = 4;
  24. /// \brief The \c IOAddress class represents an IP addresses (version
  25. /// agnostic)
  26. ///
  27. /// This class is a wrapper for the ASIO \c ip::address class.
  28. class IOAddress {
  29. public:
  30. ///
  31. /// \name Constructors and Destructor
  32. ///
  33. /// This class is copyable. We use default versions of copy constructor
  34. /// and the assignment operator.
  35. /// We use the default destructor.
  36. //@{
  37. /// \brief Constructor from string.
  38. ///
  39. /// This constructor converts a textual representation of IPv4 and IPv6
  40. /// addresses into an IOAddress object.
  41. /// If \c address_str is not a valid representation of any type of
  42. /// address, an exception of class \c IOError will be thrown.
  43. /// This constructor allocates memory for the object, and if that fails
  44. /// a corresponding standard exception will be thrown.
  45. ///
  46. /// \param address_str Textual representation of address.
  47. IOAddress(const std::string& address_str);
  48. /// \brief Constructor from an ASIO \c ip::address object.
  49. ///
  50. /// This constructor is intended to be used within the wrapper
  51. /// implementation; user applications of the wrapper API won't use it.
  52. ///
  53. /// This constructor never throws an exception.
  54. ///
  55. /// \param asio_address The ASIO \c ip::address to be converted.
  56. IOAddress(const boost::asio::ip::address& asio_address);
  57. //@}
  58. /// @brief Constructor for ip::address_v4 object.
  59. ///
  60. /// This constructor is intended to be used when constructing
  61. /// IPv4 address out of uint32_t type. Passed value must be in
  62. /// network byte order
  63. ///
  64. /// @param v4address IPv4 address represented by uint32_t
  65. IOAddress(uint32_t v4address);
  66. /// \brief Convert the address to a string.
  67. ///
  68. /// This method is basically expected to be exception free, but
  69. /// generating the string will involve resource allocation,
  70. /// and if it fails the corresponding standard exception will be thrown.
  71. ///
  72. /// \return A string representation of the address.
  73. std::string toText() const;
  74. /// \brief Returns the address family
  75. ///
  76. /// \return AF_INET for IPv4 or AF_INET6 for IPv6.
  77. short getFamily() const;
  78. /// \brief Convenience function to check for an IPv4 address
  79. ///
  80. /// \return true if the address is a V4 address
  81. bool isV4() const {
  82. return (asio_address_.is_v4());
  83. }
  84. /// \brief Convenience function to check if it is an IPv4 zero address.
  85. ///
  86. /// \return true if the address is the zero IPv4 address.
  87. bool isV4Zero() const {
  88. return (equals(IPV4_ZERO_ADDRESS()));
  89. }
  90. /// \brief Convenience function to check if it is an IPv4 broadcast
  91. /// address.
  92. ///
  93. /// \return true if the address is the broadcast IPv4 address.
  94. bool isV4Bcast() const {
  95. return (equals(IPV4_BCAST_ADDRESS()));
  96. }
  97. /// \brief Convenience function to check for an IPv6 address
  98. ///
  99. /// \return true if the address is a V6 address
  100. bool isV6() const {
  101. return (asio_address_.is_v6());
  102. }
  103. /// \brief Convenience function to check if it is an IPv4 zero address.
  104. ///
  105. /// \return true if the address is the zero IPv4 address.
  106. bool isV6Zero() const {
  107. return (equals(IPV6_ZERO_ADDRESS()));
  108. }
  109. /// \brief checks whether and address is IPv6 and is link-local
  110. ///
  111. /// \return true if the address is IPv6 link-local, false otherwise
  112. bool isV6LinkLocal() const;
  113. /// \brief checks whether and address is IPv6 and is multicast
  114. ///
  115. /// \return true if the address is IPv6 multicast, false otherwise
  116. bool isV6Multicast() const;
  117. /// \brief Creates an address from over wire data.
  118. ///
  119. /// \param family AF_NET for IPv4 or AF_NET6 for IPv6.
  120. /// \param data pointer to first char of data
  121. ///
  122. /// \return Created IOAddress object
  123. static IOAddress fromBytes(short family, const uint8_t* data);
  124. /// \brief Return address as set of bytes
  125. ///
  126. /// \return Contents of the address as a set of bytes in network-byte
  127. /// order.
  128. std::vector<uint8_t> toBytes() const;
  129. /// \brief Compare addresses for equality
  130. ///
  131. /// \param other Address to compare against.
  132. ///
  133. /// \return true if addresses are equal, false if not.
  134. bool equals(const IOAddress& other) const {
  135. return (asio_address_ == other.asio_address_);
  136. }
  137. /// \brief Compare addresses for equality
  138. ///
  139. /// \param other Address to compare against.
  140. ///
  141. /// \return true if addresses are equal, false if not.
  142. bool operator==(const IOAddress& other) const {
  143. return equals(other);
  144. }
  145. /// \brief Compare addresses for inequality
  146. ///
  147. /// \param other Address to compare against.
  148. ///
  149. /// \return false if addresses are equal, true if not.
  150. bool nequals(const IOAddress& other) const {
  151. return (!equals(other));
  152. }
  153. /// \brief Checks if one address is smaller than the other
  154. ///
  155. /// \param other Address to compare against.
  156. ///
  157. /// \return true if this address is smaller than the other address.
  158. ///
  159. /// It is useful for comparing which address is bigger.
  160. /// Operations within one protocol family are obvious.
  161. /// Comparisons between v4 and v6 will always return v4
  162. /// being smaller. This follows boost::boost::asio::ip implementation
  163. bool lessThan(const IOAddress& other) const {
  164. if (this->getFamily() == other.getFamily()) {
  165. if (this->getFamily() == AF_INET6) {
  166. return (this->asio_address_.to_v6() < other.asio_address_.to_v6());
  167. } else {
  168. return (this->asio_address_.to_v4() < other.asio_address_.to_v4());
  169. }
  170. }
  171. return (this->getFamily() < other.getFamily());
  172. }
  173. /// \brief Checks if one address is smaller or equal than the other
  174. ///
  175. /// \param other Address to compare against.
  176. ///
  177. /// \return true if this address is smaller than the other address.
  178. bool smallerEqual(const IOAddress& other) const {
  179. if (equals(other)) {
  180. return (true);
  181. }
  182. return (lessThan(other));
  183. }
  184. /// \brief Checks if one address is smaller than the other
  185. ///
  186. /// \param other Address to compare against.
  187. ///
  188. /// See \ref lessThan method for details.
  189. bool operator<(const IOAddress& other) const {
  190. return (lessThan(other));
  191. }
  192. /// \brief Checks if one address is smaller or equal than the other
  193. ///
  194. /// \param other Address to compare against.
  195. ///
  196. /// See \ref smallerEqual method for details.
  197. bool operator<=(const IOAddress& other) const {
  198. return (smallerEqual(other));
  199. }
  200. /// \brief Compare addresses for inequality
  201. ///
  202. /// \param other Address to compare against.
  203. ///
  204. /// \return false if addresses are equal, true if not.
  205. bool operator!=(const IOAddress& other) const {
  206. return (nequals(other));
  207. }
  208. /// @brief Subtracts one address from another (a - b)
  209. ///
  210. /// Treats addresses as integers and subtracts them. For example:
  211. /// @code
  212. /// 192.0.2.5 - 192.0.2.0 = 0.0.0.5
  213. /// fe80::abcd - fe80:: = ::abcd
  214. /// @endcode
  215. ///
  216. /// It is possible to subtract greater from lesser address, e.g.
  217. /// 192.168.56.10 - 192.168.67.20, but please do understand that
  218. /// the address space is a finite field in mathematical sense, so
  219. /// you may end up with a result that is greater then any of the
  220. /// addresses you specified. Also, subtraction is not commutative,
  221. /// so a - b != b - a.
  222. ///
  223. /// This operation is essential for calculating the number of
  224. /// leases in a pool, where we need to calculate (max - min).
  225. /// @throw BadValue if addresses are of different family
  226. /// @param a address to be subtracted from
  227. /// @param b address to be subtracted
  228. /// @return IOAddress object that represents the difference
  229. static IOAddress subtract(const IOAddress& a, const IOAddress& b);
  230. /// @brief Returns an address increased by one
  231. ///
  232. /// This method works for both IPv4 and IPv6 addresses. For example,
  233. /// increase 192.0.2.255 will become 192.0.3.0.
  234. ///
  235. /// Address space is a finite field in the mathematical sense, so keep
  236. /// in mind that the address space "loops". 255.255.255.255 increased
  237. /// by one gives 0.0.0.0. The same is true for maximum value of IPv6
  238. /// (all 1's) looping to ::.
  239. ///
  240. /// @todo Determine if we have a use-case for increasing the address
  241. /// by more than one. Increase by one is used in AllocEngine. This method
  242. /// could take extra parameter that specifies the value by which the
  243. /// address should be increased.
  244. ///
  245. /// @param addr address to be increased
  246. /// @return address increased by one
  247. static IOAddress
  248. increase(const IOAddress& addr);
  249. /// \brief Converts IPv4 address to uint32_t
  250. ///
  251. /// Will throw BadValue exception if that is not IPv4
  252. /// address.
  253. ///
  254. /// \return uint32_t that represents IPv4 address in
  255. /// network byte order
  256. uint32_t toUint32() const;
  257. /// @name Methods returning @c IOAddress objects encapsulating typical addresses.
  258. ///
  259. //@{
  260. /// @brief Returns an address set to all zeros.
  261. static const IOAddress& IPV4_ZERO_ADDRESS() {
  262. static IOAddress address(0);
  263. return (address);
  264. }
  265. /// @brief Returns a "255.255.255.255" broadcast address.
  266. static const IOAddress& IPV4_BCAST_ADDRESS() {
  267. static IOAddress address(0xFFFFFFFF);
  268. return (address);
  269. }
  270. /// @brief Returns an IPv6 zero address.
  271. static const IOAddress& IPV6_ZERO_ADDRESS() {
  272. static IOAddress address("::");
  273. return (address);
  274. }
  275. //@}
  276. private:
  277. boost::asio::ip::address asio_address_;
  278. };
  279. /// \brief Insert the IOAddress as a string into stream.
  280. ///
  281. /// This method converts the \c address into a string and inserts it
  282. /// into the output stream \c os.
  283. ///
  284. /// This function overloads the global operator<< to behave as described
  285. /// in ostream::operator<< but applied to \c IOAddress objects.
  286. ///
  287. /// \param os A \c std::ostream object on which the insertion operation is
  288. /// performed.
  289. /// \param address The \c IOAddress object output by the operation.
  290. /// \return A reference to the same \c std::ostream object referenced by
  291. /// parameter \c os after the insertion operation.
  292. std::ostream&
  293. operator<<(std::ostream& os, const IOAddress& address);
  294. } // namespace asiolink
  295. } // namespace isc
  296. #endif // IO_ADDRESS_H