Browse Source

[2324] inPool methods added to Subnet4 and Subnet6

Tomek Mrugalski 12 years ago
parent
commit
3e189b431f

+ 33 - 0
src/lib/dhcp/subnet.cc

@@ -86,6 +86,23 @@ Pool4Ptr Subnet4::getPool4(const isc::asiolink::IOAddress& hint /* = IOAddress("
     return (candidate);
 }
 
+bool Subnet4::inPool(const isc::asiolink::IOAddress& addr) const {
+
+    // Let's start with checking if it even belongs to that subnet.
+    if (!inRange(addr)) {
+        return (false);
+    }
+
+    for (Pool4Collection::const_iterator pool = pools_.begin(); pool != pools_.end(); ++pool) {
+        if ((*pool)->inRange(addr)) {
+            return (true);
+        }
+    }
+    // there's no pool that address belongs to
+    return (false);
+}
+
+
 Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
                  const Triplet<uint32_t>& t1,
                  const Triplet<uint32_t>& t2,
@@ -132,5 +149,21 @@ Pool6Ptr Subnet6::getPool6(const isc::asiolink::IOAddress& hint /* = IOAddress("
     return (candidate);
 }
 
+bool Subnet6::inPool(const isc::asiolink::IOAddress& addr) const {
+
+    // Let's start with checking if it even belongs to that subnet.
+    if (!inRange(addr)) {
+        return (false);
+    }
+
+    for (Pool6Collection::const_iterator pool = pools_.begin(); pool != pools_.end(); ++pool) {
+        if ((*pool)->inRange(addr)) {
+            return (true);
+        }
+    }
+    // there's no pool that address belongs to
+    return (false);
+}
+
 } // end of isc::dhcp namespace
 } // end of isc namespace

+ 29 - 0
src/lib/dhcp/subnet.h

@@ -43,6 +43,19 @@ public:
     /// @brief checks if specified address is in range
     bool inRange(const isc::asiolink::IOAddress& addr) const;
 
+    /// @brief checks if the specified address is in pools
+    ///
+    /// Note the difference between inSubnet() and inPool(). For a given
+    /// subnet (e.g. 2001::/64) there may be one or more pools defined
+    /// that may or may not cover entire subnet, e.g. pool 2001::1-2001::10).
+    /// inPool() returning true implies inSubnet(), but the reverse implication
+    /// is not always true. For the given example, 2001::abc would return
+    /// true for inSubnet(), but false for inPool() check.
+    ///
+    /// @param addr this address will be checked if it belongs to any pools in that subnet
+    /// @return true if the address is in any of the pools
+    virtual bool inPool(const isc::asiolink::IOAddress& addr) const = 0;
+
     /// @brief return valid-lifetime for addresses in that prefix
     Triplet<uint32_t> getValid() const {
         return (valid_);
@@ -157,6 +170,14 @@ public:
         return pools_;
     }
 
+    /// @brief checks if the specified address is in pools
+    ///
+    /// See the description in \ref Subnet::inPool().
+    ///
+    /// @param addr this address will be checked if it belongs to any pools in that subnet
+    /// @return true if the address is in any of the pools
+    bool inPool(const isc::asiolink::IOAddress& addr) const;
+
 protected:
     /// @brief collection of pools in that list
     Pool4Collection pools_;
@@ -217,6 +238,14 @@ public:
         return pools_;
     }
 
+    /// @brief checks if the specified address is in pools
+    ///
+    /// See the description in \ref Subnet::inPool().
+    ///
+    /// @param addr this address will be checked if it belongs to any pools in that subnet
+    /// @return true if the address is in any of the pools
+    bool inPool(const isc::asiolink::IOAddress& addr) const;
+
 protected:
     /// @brief collection of pools in that list
     Pool6Collection pools_;

+ 0 - 1
src/lib/dhcp/tests/pool_unittest.cc

@@ -179,4 +179,3 @@ TEST(Pool6Test, unique_id) {
 }
 
 }; // end of anonymous namespace
-

+ 71 - 1
src/lib/dhcp/tests/subnet_unittest.cc

@@ -104,6 +104,41 @@ TEST(Subnet4Test, Subnet4_Pool4_checks) {
     EXPECT_THROW(subnet->addPool4(pool3), BadValue);
 }
 
+// This test verifies that inRange() and inPool() methods work properly.
+TEST(Subnet4Test, inRangeinPool) {
+    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.0.0"), 8, 1, 2, 3));
+
+    // this one is in subnet
+    Pool4Ptr pool1(new Pool4(IOAddress("192.2.0.0"), 16));
+    subnet->addPool4(pool1);
+
+    // 192.1.1.1 belongs to the subnet...
+    EXPECT_TRUE(subnet->inRange(IOAddress("192.1.1.1")));
+
+    // ... but it does not belong to any pool within
+    EXPECT_FALSE(subnet->inPool(IOAddress("192.1.1.1")));
+
+    // the last address that is in range, but out of pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("192.1.255.255")));
+    EXPECT_FALSE(subnet->inPool(IOAddress("192.1.255.255")));
+
+    // the first address that is in range, in pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("192.2.0.0")));
+    EXPECT_TRUE (subnet->inPool(IOAddress("192.2.0.0")));
+
+    // let's try something in the middle as well
+    EXPECT_TRUE(subnet->inRange(IOAddress("192.2.3.4")));
+    EXPECT_TRUE (subnet->inPool(IOAddress("192.2.3.4")));
+
+    // the last address that is in range, in pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("192.2.255.255")));
+    EXPECT_TRUE (subnet->inPool(IOAddress("192.2.255.255")));
+
+    // the first address that is in range, but out of pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("192.3.0.0")));
+    EXPECT_FALSE(subnet->inPool(IOAddress("192.3.0.0")));
+}
+
 // Tests for Subnet6
 
 TEST(Subnet6Test, constructor) {
@@ -161,7 +196,6 @@ TEST(Subnet6Test, Pool6InSubnet6) {
     mypool = subnet->getPool6(IOAddress("2001:db8:1:3::dead:beef"));
 
     EXPECT_EQ(mypool, pool3);
-
 }
 
 TEST(Subnet6Test, Subnet6_Pool6_checks) {
@@ -187,4 +221,40 @@ TEST(Subnet6Test, Subnet6_Pool6_checks) {
     EXPECT_THROW(subnet->addPool6(pool4), BadValue);
 }
 
+// This test verifies that inRange() and inPool() methods work properly.
+TEST(Subnet6Test, inRangeinPool) {
+    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));
+
+    // this one is in subnet
+    Pool6Ptr pool1(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8::10"),
+                             IOAddress("2001:db8::20")));
+    subnet->addPool6(pool1);
+
+    // 192.1.1.1 belongs to the subnet...
+    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::1")));
+    // ... but it does not belong to any pool within
+    EXPECT_FALSE(subnet->inPool(IOAddress("2001:db8::1")));
+
+    // the last address that is in range, but out of pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::f")));
+    EXPECT_FALSE(subnet->inPool(IOAddress("2001:db8::f")));
+
+    // the first address that is in range, in pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::10")));
+    EXPECT_TRUE (subnet->inPool(IOAddress("2001:db8::10")));
+
+    // let's try something in the middle as well
+    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::18")));
+    EXPECT_TRUE (subnet->inPool(IOAddress("2001:db8::18")));
+
+    // the last address that is in range, in pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::20")));
+    EXPECT_TRUE (subnet->inPool(IOAddress("2001:db8::20")));
+
+    // the first address that is in range, but out of pool
+    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::21")));
+    EXPECT_FALSE(subnet->inPool(IOAddress("2001:db8::21")));
+}
+
+
 };