pool.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <asiolink/io_address.h>
  15. #include <dhcpsrv/addr_utilities.h>
  16. #include <dhcpsrv/pool.h>
  17. #include <sstream>
  18. using namespace isc::asiolink;
  19. namespace isc {
  20. namespace dhcp {
  21. Pool::Pool(Lease::Type type, const isc::asiolink::IOAddress& first,
  22. const isc::asiolink::IOAddress& last)
  23. :id_(getNextID()), first_(first), last_(last), type_(type) {
  24. }
  25. bool Pool::inRange(const isc::asiolink::IOAddress& addr) const {
  26. return (first_.smallerEqual(addr) && addr.smallerEqual(last_));
  27. }
  28. std::string
  29. Pool::toText() const {
  30. std::stringstream tmp;
  31. tmp << "type=" << Lease::typeToText(type_) << ", " << first_
  32. << "-" << last_;
  33. return (tmp.str());
  34. }
  35. Pool4::Pool4(const isc::asiolink::IOAddress& first,
  36. const isc::asiolink::IOAddress& last)
  37. :Pool(Lease::TYPE_V4, first, last) {
  38. // check if specified address boundaries are sane
  39. if (!first.isV4() || !last.isV4()) {
  40. isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
  41. }
  42. if (last < first) {
  43. isc_throw(BadValue, "Upper boundary is smaller than lower boundary.");
  44. }
  45. // This is IPv4 pool, which only has one type. We can calculate
  46. // the number of theoretically possible leases in it. As there's 2^32
  47. // possible IPv4 addresses, we'll be able to accurately store that
  48. // info.
  49. leases_count_ = addrsInRange(first, last);
  50. }
  51. Pool4::Pool4( const isc::asiolink::IOAddress& prefix, uint8_t prefix_len)
  52. :Pool(Lease::TYPE_V4, prefix, IOAddress("0.0.0.0")) {
  53. // check if the prefix is sane
  54. if (!prefix.isV4()) {
  55. isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
  56. }
  57. // check if the prefix length is sane
  58. if (prefix_len == 0 || prefix_len > 32) {
  59. isc_throw(BadValue, "Invalid prefix length");
  60. }
  61. // Let's now calculate the last address in defined pool
  62. last_ = lastAddrInPrefix(prefix, prefix_len);
  63. // This is IPv4 pool, which only has one type. We can calculate
  64. // the number of theoretically possible leases in it. As there's 2^32
  65. // possible IPv4 addresses, we'll be able to accurately store that
  66. // info.
  67. leases_count_ = addrsInRange(prefix, last_);
  68. }
  69. Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& first,
  70. const isc::asiolink::IOAddress& last)
  71. :Pool(type, first, last), prefix_len_(128) {
  72. // check if specified address boundaries are sane
  73. if (!first.isV6() || !last.isV6()) {
  74. isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
  75. }
  76. if ( (type != Lease::TYPE_NA) && (type != Lease::TYPE_TA) &&
  77. (type != Lease::TYPE_PD)) {
  78. isc_throw(BadValue, "Invalid Pool6 type: " << static_cast<int>(type)
  79. << ", must be TYPE_IA, TYPE_TA or TYPE_PD");
  80. }
  81. if (last < first) {
  82. isc_throw(BadValue, "Upper boundary is smaller than lower boundary.");
  83. // This check is a bit strict. If we decide that it is too strict,
  84. // we need to comment it and uncomment lines below.
  85. // On one hand, letting the user specify 2001::f - 2001::1 is nice, but
  86. // on the other hand, 2001::1 may be a typo and the user really meant
  87. // 2001::1:0 (or 1 followed by some hex digit), so a at least a warning
  88. // would be useful.
  89. // first_ = last;
  90. // last_ = first;
  91. }
  92. // TYPE_PD is not supported by this constructor. first-last style
  93. // parameters are for IA and TA only. There is another dedicated
  94. // constructor for that (it uses prefix/length)
  95. if ((type != Lease::TYPE_NA) && (type != Lease::TYPE_TA)) {
  96. isc_throw(BadValue, "Invalid Pool6 type specified:"
  97. << static_cast<int>(type));
  98. }
  99. // Let's calculate the theoretical number of leases in this pool.
  100. // If the pool is extremely large (i.e. contains more than 2^64 addresses,
  101. // we'll just cap it at max value of uint64_t).
  102. leases_count_ = addrsInRange(first, last);
  103. }
  104. Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix,
  105. uint8_t prefix_len, uint8_t delegated_len /* = 128 */)
  106. :Pool(type, prefix, IOAddress("::")), prefix_len_(delegated_len) {
  107. // check if the prefix is sane
  108. if (!prefix.isV6()) {
  109. isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
  110. }
  111. // check if the prefix length is sane
  112. if (prefix_len == 0 || prefix_len > 128) {
  113. isc_throw(BadValue, "Invalid prefix length: " << prefix_len);
  114. }
  115. if (prefix_len > delegated_len) {
  116. isc_throw(BadValue, "Delegated length (" << static_cast<int>(delegated_len)
  117. << ") must be longer than or equal to prefix length ("
  118. << static_cast<int>(prefix_len) << ")");
  119. }
  120. if ( ( (type == Lease::TYPE_NA) || (type == Lease::TYPE_TA)) &&
  121. (delegated_len != 128)) {
  122. isc_throw(BadValue, "For IA or TA pools, delegated prefix length must "
  123. << " be 128.");
  124. }
  125. /// @todo: We should probably implement checks against weird addresses
  126. /// here, like ::, starting with fe80, starting with ff etc. .
  127. // Let's now calculate the last address in defined pool
  128. last_ = lastAddrInPrefix(prefix, prefix_len);
  129. // Let's calculate the theoretical number of leases in this pool.
  130. // For addresses, we could use addrsInRange(prefix, last_), but it's
  131. // much faster to do calculations on prefix lengths.
  132. leases_count_ = prefixesInRange(prefix_len, delegated_len);
  133. }
  134. std::string
  135. Pool6::toText() const {
  136. std::stringstream tmp;
  137. tmp << "type=" << Lease::typeToText(type_) << ", " << first_
  138. << "-" << last_ << ", delegated_len="
  139. << static_cast<int>(prefix_len_);
  140. return (tmp.str());
  141. }
  142. }; // end of isc::dhcp namespace
  143. }; // end of isc namespace