subnet.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright (C) 2012 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 <dhcp/addr_utilities.h>
  15. #include <asiolink/io_address.h>
  16. #include <dhcp/subnet.h>
  17. #include <dhcp/pool.h>
  18. using namespace isc::asiolink;
  19. namespace isc {
  20. namespace dhcp {
  21. Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
  22. const Triplet<uint32_t>& t1,
  23. const Triplet<uint32_t>& t2,
  24. const Triplet<uint32_t>& valid_lifetime)
  25. :id_(getNextID()), prefix_(prefix), prefix_len_(len), t1_(t1),
  26. t2_(t2), valid_(valid_lifetime) {
  27. if ( (prefix.getFamily() == AF_INET6 && len > 128) ||
  28. (prefix.getFamily() == AF_INET && len > 32) ) {
  29. isc_throw(BadValue, "Invalid prefix length specified for subnet: " << len);
  30. }
  31. }
  32. bool Subnet::inRange(const isc::asiolink::IOAddress& addr) const {
  33. IOAddress first = firstAddrInPrefix(prefix_, prefix_len_);
  34. IOAddress last = lastAddrInPrefix(prefix_, prefix_len_);
  35. return ((first <= addr) && (addr <= last));
  36. }
  37. Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
  38. const Triplet<uint32_t>& t1,
  39. const Triplet<uint32_t>& t2,
  40. const Triplet<uint32_t>& valid_lifetime)
  41. :Subnet(prefix, length, t1, t2, valid_lifetime) {
  42. if (prefix.getFamily() != AF_INET) {
  43. isc_throw(BadValue, "Non IPv4 prefix " << prefix.toText()
  44. << " specified in subnet4");
  45. }
  46. }
  47. void Subnet4::addPool4(const Pool4Ptr& pool) {
  48. IOAddress first_addr = pool->getFirstAddress();
  49. IOAddress last_addr = pool->getLastAddress();
  50. if (!inRange(first_addr) || !inRange(last_addr)) {
  51. isc_throw(BadValue, "Pool4 (" << first_addr.toText() << "-" << last_addr.toText()
  52. << " does not belong in this (" << prefix_ << "/" << prefix_len_
  53. << ") subnet4");
  54. }
  55. /// @todo: Check that pools do not overlap
  56. pools_.push_back(pool);
  57. }
  58. Pool4Ptr Subnet4::getPool4(const isc::asiolink::IOAddress& hint /* = IOAddress("::")*/ ) {
  59. Pool4Ptr candidate;
  60. for (Pool4Collection::iterator pool = pools_.begin(); pool != pools_.end(); ++pool) {
  61. // if we won't find anything better, then let's just use the first pool
  62. if (!candidate) {
  63. candidate = *pool;
  64. }
  65. // if the client provided a pool and there's a pool that hint is valid in,
  66. // then let's use that pool
  67. if ((*pool)->inRange(hint)) {
  68. return (*pool);
  69. }
  70. }
  71. return (candidate);
  72. }
  73. Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
  74. const Triplet<uint32_t>& t1,
  75. const Triplet<uint32_t>& t2,
  76. const Triplet<uint32_t>& preferred_lifetime,
  77. const Triplet<uint32_t>& valid_lifetime)
  78. :Subnet(prefix, length, t1, t2, valid_lifetime),
  79. preferred_(preferred_lifetime){
  80. if (prefix.getFamily() != AF_INET6) {
  81. isc_throw(BadValue, "Non IPv6 prefix " << prefix.toText()
  82. << " specified in subnet6");
  83. }
  84. }
  85. void Subnet6::addPool6(const Pool6Ptr& pool) {
  86. IOAddress first_addr = pool->getFirstAddress();
  87. IOAddress last_addr = pool->getLastAddress();
  88. if (!inRange(first_addr) || !inRange(last_addr)) {
  89. isc_throw(BadValue, "Pool6 (" << first_addr.toText() << "-" << last_addr.toText()
  90. << " does not belong in this (" << prefix_ << "/" << prefix_len_
  91. << ") subnet6");
  92. }
  93. /// @todo: Check that pools do not overlap
  94. pools_.push_back(pool);
  95. }
  96. Pool6Ptr Subnet6::getPool6(const isc::asiolink::IOAddress& hint /* = IOAddress("::")*/ ) {
  97. Pool6Ptr candidate;
  98. for (Pool6Collection::iterator pool = pools_.begin(); pool != pools_.end(); ++pool) {
  99. // if we won't find anything better, then let's just use the first pool
  100. if (!candidate) {
  101. candidate = *pool;
  102. }
  103. // if the client provided a pool and there's a pool that hint is valid in,
  104. // then let's use that pool
  105. if ((*pool)->inRange(hint)) {
  106. return (*pool);
  107. }
  108. }
  109. return (candidate);
  110. }
  111. } // end of isc::dhcp namespace
  112. } // end of isc namespace