|
@@ -15,16 +15,70 @@
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
#include <acl/ip_check.h>
|
|
|
+#include <boost/scoped_ptr.hpp>
|
|
|
|
|
|
using namespace isc::acl;
|
|
|
using namespace std;
|
|
|
|
|
|
-// Declare a derived class to allow the abstract function to be declared
|
|
|
-// as a concrete one.
|
|
|
+/// *** Free Function Tests ***
|
|
|
+
|
|
|
+TEST(IpFunctionCheck, CreateNetmask) {
|
|
|
+
|
|
|
+ // 8-bit tests: invalid arguments should throw.
|
|
|
+ EXPECT_THROW(createNetmask<uint8_t>(9), isc::OutOfRange);
|
|
|
+
|
|
|
+ // Check on all possible 8-bit values. Use a signed type to generate a
|
|
|
+ // variable with the most significant bits set, as right-shifting it is
|
|
|
+ // guaranteed to introduce additional bits.
|
|
|
+ int8_t expected8 = 0x80;
|
|
|
+ for (size_t i = 1; i <= 8; ++i, expected8 >>= 1) {
|
|
|
+ EXPECT_EQ(static_cast<uint8_t>(expected8), createNetmask<uint8_t>(i));
|
|
|
+ }
|
|
|
+ EXPECT_EQ(0, createNetmask<uint8_t>(0));
|
|
|
+
|
|
|
+ // Do the same for 32 bits.
|
|
|
+ EXPECT_THROW(createNetmask<int32_t>(33), isc::OutOfRange);
|
|
|
+
|
|
|
+ // Check on all possible 8-bit values
|
|
|
+ int32_t expected32 = 0x80000000;
|
|
|
+ for (size_t i = 1; i <= 32; ++i, expected32 >>= 1) {
|
|
|
+ EXPECT_EQ(static_cast<uint32_t>(expected32),
|
|
|
+ createNetmask<uint32_t>(i));
|
|
|
+ }
|
|
|
+ EXPECT_EQ(0, createNetmask<uint32_t>(0));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(IpFunctionCheck, SplitIp) {
|
|
|
+ pair<string, uint32_t> result;
|
|
|
+
|
|
|
+ result = splitIpAddress("192.0.2.1/24", 32);
|
|
|
+ EXPECT_EQ(string("192.0.2.1"), result.first);
|
|
|
+ EXPECT_EQ(24, result.second);
|
|
|
+
|
|
|
+ result = splitIpAddress("192.0.2.1/32", 32);
|
|
|
+ EXPECT_EQ(string("192.0.2.1"), result.first);
|
|
|
+ EXPECT_EQ(32, result.second);
|
|
|
+
|
|
|
+ result = splitIpAddress("2001:db8::/128", 128);
|
|
|
+ EXPECT_EQ(string("2001:db8::"), result.first);
|
|
|
+ EXPECT_EQ(128, result.second);
|
|
|
+
|
|
|
+ EXPECT_THROW(splitIpAddress("2001:db8::/129", 128), isc::OutOfRange);
|
|
|
+ EXPECT_THROW(splitIpAddress("2001:db8::/xxxx", 32), isc::InvalidParameter);
|
|
|
+ EXPECT_THROW(splitIpAddress("2001:db8::/32/s", 32), isc::InvalidParameter);
|
|
|
+}
|
|
|
+
|
|
|
+// *** IPV4 Tests ***
|
|
|
+
|
|
|
+// Declare a derived class to allow a definition of the match() method to be
|
|
|
+// provided.
|
|
|
+//
|
|
|
+// In this case, the match will check a uint32_t variable representing an IPV4
|
|
|
+// address.
|
|
|
|
|
|
class DerivedV4Check : public Ipv4Check<uint32_t> {
|
|
|
public:
|
|
|
- // Basic constructor
|
|
|
+ // Basic (and default) constructor
|
|
|
DerivedV4Check(uint32_t address = 1, size_t masksize = 32,
|
|
|
bool inverse = false) :
|
|
|
Ipv4Check<uint32_t>(address, masksize, inverse)
|
|
@@ -35,6 +89,23 @@ public:
|
|
|
Ipv4Check<uint32_t>(address, inverse)
|
|
|
{}
|
|
|
|
|
|
+ // Copy constructor
|
|
|
+ DerivedV4Check(const DerivedV4Check& other) : Ipv4Check<uint32_t>(other)
|
|
|
+ {}
|
|
|
+
|
|
|
+ // Assignment operator
|
|
|
+ DerivedV4Check& operator=(const DerivedV4Check& other) {
|
|
|
+ if (this != &other) {
|
|
|
+ Ipv4Check<uint32_t>::operator=(other);
|
|
|
+ }
|
|
|
+ return (*this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Clone method
|
|
|
+ virtual IpBaseCheck<uint32_t>* clone() const {
|
|
|
+ return (new DerivedV4Check(*this));
|
|
|
+ }
|
|
|
+
|
|
|
// Destructor
|
|
|
virtual ~DerivedV4Check()
|
|
|
{}
|
|
@@ -45,54 +116,31 @@ public:
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// Check that a default constructor can be instantiated.
|
|
|
|
|
|
-/// Tests of the free functions.
|
|
|
-
|
|
|
-TEST(Ipv4Check, CreateNetmask) {
|
|
|
- size_t i;
|
|
|
-
|
|
|
- // 8-bit tests.
|
|
|
-
|
|
|
- // Invalid arguments should throw.
|
|
|
- EXPECT_THROW(createNetmask<uint8_t>(9), isc::OutOfRange);
|
|
|
-
|
|
|
- // Check on all possible 8-bit values. Use a signed type to generate a
|
|
|
- // variable with the most significant bits set, as right-shifting it is
|
|
|
- // guaranteed to introduce additional bits.
|
|
|
- int8_t expected8;
|
|
|
- for (i = 1, expected8 = 0x80; i <= 8; ++i, expected8 >>= 1) {
|
|
|
- EXPECT_EQ(static_cast<uint8_t>(expected8),
|
|
|
- createNetmask<uint8_t>(i));
|
|
|
- }
|
|
|
- EXPECT_EQ(0, createNetmask<uint8_t>(0));
|
|
|
+TEST(Ipv4Check, V4DefaultConstructor) {
|
|
|
+ DerivedV4Check acl1;
|
|
|
|
|
|
- // Do the same for 32 bits.
|
|
|
- EXPECT_THROW(createNetmask<int32_t>(33), isc::OutOfRange);
|
|
|
-
|
|
|
- // Check on all possible 8-bit values
|
|
|
- int32_t expected32;
|
|
|
- for (i = 1, expected32 = 0x80000000; i <= 32; ++i, expected32 >>= 1) {
|
|
|
- EXPECT_EQ(static_cast<uint32_t>(expected32),
|
|
|
- createNetmask<uint32_t>(i));
|
|
|
- }
|
|
|
- EXPECT_EQ(0, createNetmask<uint32_t>(0));
|
|
|
+ // The test is needed to avoid the unused variable causing a warning or
|
|
|
+ // getting optimised away.
|
|
|
+ EXPECT_EQ(1, acl1.getAddress());
|
|
|
}
|
|
|
-// IPV4 tests
|
|
|
|
|
|
-// Check that the constructor expands the network mask and stores the elements
|
|
|
-// correctly. For these tests, we don't worry about the type of the context,
|
|
|
-// so we declare it as an int.
|
|
|
+// Check that the constructor stores the elements correctly. As the address
|
|
|
+// is provided in the correct (network-byte order) format, the real test is
|
|
|
+// checking that the network mask is stored in the correct byte order.
|
|
|
|
|
|
TEST(Ipv4Check, V4ConstructorAddress) {
|
|
|
DerivedV4Check acl1(0x12345678);
|
|
|
EXPECT_EQ(0x12345678, acl1.getAddress());
|
|
|
}
|
|
|
|
|
|
-// The mask is stored in network byte order, so the pattern expected must
|
|
|
-// also be converted to network byte order for the comparison to succeed.
|
|
|
TEST(Ipv4Check, V4ConstructorMask) {
|
|
|
// Valid values. Address of "1" is used as a placeholder
|
|
|
DerivedV4Check acl1(1, 1);
|
|
|
+
|
|
|
+ // The mask is stored in network byte order, so the pattern expected must
|
|
|
+ // also be converted to network byte order for the comparison to succeed.
|
|
|
uint32_t expected = htonl(0x80000000);
|
|
|
EXPECT_EQ(expected, acl1.getNetmask());
|
|
|
EXPECT_EQ(1, acl1.getMasksize());
|
|
@@ -120,29 +168,61 @@ TEST(Ipv4Check, V4ConstructorInverse) {
|
|
|
}
|
|
|
|
|
|
TEST(Ipv4Check, V4StringConstructor) {
|
|
|
- DerivedV4Check acl1("127.0.0.1");
|
|
|
- uint32_t expected = htonl(0x7f000001);
|
|
|
+ DerivedV4Check acl1("192.168.132.255");
|
|
|
+ uint32_t expected = htonl(0xc0a884ff);
|
|
|
EXPECT_EQ(expected, acl1.getAddress());
|
|
|
EXPECT_EQ(32, acl1.getMasksize());
|
|
|
|
|
|
- DerivedV4Check acl2("255.255.255.0/24");
|
|
|
- expected = htonl(0xffffff00);
|
|
|
+ DerivedV4Check acl2("192.0.2.0/24");
|
|
|
+ expected = htonl(0xc0000200);
|
|
|
EXPECT_EQ(expected, acl2.getAddress());
|
|
|
EXPECT_EQ(24, acl2.getMasksize());
|
|
|
|
|
|
- EXPECT_THROW(DerivedV4Check("255.255.255.0/0"), isc::OutOfRange);
|
|
|
- EXPECT_THROW(DerivedV4Check("255.255.255.0/33"), isc::OutOfRange);
|
|
|
- EXPECT_THROW(DerivedV4Check("255.255.255.0/24/3"), isc::InvalidParameter);
|
|
|
- EXPECT_THROW(DerivedV4Check("255.255.255.0/ww"), isc::InvalidParameter);
|
|
|
+ EXPECT_THROW(DerivedV4Check("192.0.2.0/0"), isc::OutOfRange);
|
|
|
+ EXPECT_THROW(DerivedV4Check("192.0.2.0/33"), isc::OutOfRange);
|
|
|
+ EXPECT_THROW(DerivedV4Check("192.0.2.0/24/3"), isc::InvalidParameter);
|
|
|
+ EXPECT_THROW(DerivedV4Check("192.0.2.0/ww"), isc::InvalidParameter);
|
|
|
EXPECT_THROW(DerivedV4Check("aa.255.255.0/ww"), isc::InvalidParameter);
|
|
|
}
|
|
|
|
|
|
+TEST(Ipv4Check, V4CopyConstructor) {
|
|
|
+ DerivedV4Check acl1("127.0.0.1/16", true);
|
|
|
+ DerivedV4Check acl2(acl1);
|
|
|
+
|
|
|
+ EXPECT_EQ(acl1.getAddress(), acl2.getAddress());
|
|
|
+ EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
|
|
|
+ EXPECT_EQ(acl1.getNetmask(), acl2.getNetmask());
|
|
|
+ EXPECT_EQ(acl1.getInverse(), acl2.getInverse());
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Ipv4Check, V4AssignmentOperator) {
|
|
|
+ DerivedV4Check acl1("127.0.0.1/16", true);
|
|
|
+ DerivedV4Check acl2("192.1.2.3/12", false);
|
|
|
+
|
|
|
+ acl2 = acl1;
|
|
|
+ EXPECT_EQ(acl1.getAddress(), acl2.getAddress());
|
|
|
+ EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
|
|
|
+ EXPECT_EQ(acl1.getNetmask(), acl2.getNetmask());
|
|
|
+ EXPECT_EQ(acl1.getInverse(), acl2.getInverse());
|
|
|
+}
|
|
|
+
|
|
|
+TEST(IPv4Check, V4Clone) {
|
|
|
+ DerivedV4Check acl1("127.0.0.1/16", true);
|
|
|
+
|
|
|
+ boost::scoped_ptr<DerivedV4Check> acl2(
|
|
|
+ static_cast<DerivedV4Check*>(acl1.clone()));
|
|
|
+ EXPECT_EQ(acl1.getAddress(), acl2->getAddress());
|
|
|
+ EXPECT_EQ(acl1.getMasksize(), acl2->getMasksize());
|
|
|
+ EXPECT_EQ(acl1.getNetmask(), acl2->getNetmask());
|
|
|
+ EXPECT_EQ(acl1.getInverse(), acl2->getInverse());
|
|
|
+}
|
|
|
+
|
|
|
// Check that the comparison works - note that "matches" just calls the
|
|
|
// internal compare() code.
|
|
|
//
|
|
|
-// Note that addresses passed to the class are expected to be in network-
|
|
|
-// byte order. Therefore for the comparisons to work as expected, we must
|
|
|
-// convert the values to network-byte order first.
|
|
|
+// As before, note that addresses passed to the class are expected to be in
|
|
|
+// network-byte order. Therefore for the comparisons to work as expected, we
|
|
|
+// must convert the values to network-byte order first.
|
|
|
|
|
|
TEST(Ipv4Check, V4Compare) {
|
|
|
// Exact address - match if given address matches stored address.
|
|
@@ -172,17 +252,24 @@ TEST(Ipv4Check, V4Compare) {
|
|
|
EXPECT_FALSE(acl4.matches(htonl(0x2345ffff)));
|
|
|
EXPECT_TRUE(acl4.matches(htonl(0x23460000)));
|
|
|
EXPECT_TRUE(acl4.matches(htonl(0x2346ffff)));
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
|
-// IPV6 tests
|
|
|
|
|
|
-// Declare a derived class to allow the abstract function to be declared
|
|
|
-// as a concrete one.
|
|
|
+// *** IPV6 Tests ***
|
|
|
+//
|
|
|
+// Declare a derived class to allow a definition of the match() method to be
|
|
|
+// provided.
|
|
|
+//
|
|
|
+// In this case, the match will check a vector of uint8_t s representing an IPV6
|
|
|
+// address.
|
|
|
|
|
|
class DerivedV6Check : public Ipv6Check<vector<uint8_t> > {
|
|
|
public:
|
|
|
+ // default constructor
|
|
|
+ DerivedV6Check() : Ipv6Check<vector<uint8_t> >()
|
|
|
+ {}
|
|
|
+
|
|
|
// Basic constructor
|
|
|
DerivedV6Check(const uint8_t* address, size_t masksize = 128,
|
|
|
bool inverse = false) :
|
|
@@ -194,6 +281,11 @@ public:
|
|
|
Ipv6Check<vector<uint8_t> >(address, inverse)
|
|
|
{}
|
|
|
|
|
|
+ // Clone method
|
|
|
+ virtual IpBaseCheck<vector<uint8_t> >* clone() const {
|
|
|
+ return (new DerivedV6Check(*this));
|
|
|
+ }
|
|
|
+
|
|
|
// Destructor
|
|
|
virtual ~DerivedV6Check()
|
|
|
{}
|
|
@@ -262,9 +354,15 @@ static const uint8_t MASK_128[] = {
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
|
};
|
|
|
|
|
|
-// Check that the constructor expands the network mask and stores the elements
|
|
|
-// correctly. For these tests, we don't worry about the type of the context,
|
|
|
-// so we declare it as an int.
|
|
|
+// Check that a default constructor can be instantiated.
|
|
|
+
|
|
|
+TEST(Ipv6Check, V6DefaultConstructor) {
|
|
|
+ DerivedV6Check acl1;
|
|
|
+
|
|
|
+ // The test is needed to avoid the unused variable causing a warning or
|
|
|
+ // getting optimised away.
|
|
|
+ EXPECT_EQ(0, acl1.getMasksize());
|
|
|
+}
|
|
|
|
|
|
TEST(Ipv6Check, V6ConstructorAddress) {
|
|
|
DerivedV6Check acl1(V6ADDR_1);
|
|
@@ -273,11 +371,9 @@ TEST(Ipv6Check, V6ConstructorAddress) {
|
|
|
EXPECT_TRUE(equal(stored.begin(), stored.end(), V6ADDR_1));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-// The mask is stored in network byte order, so the pattern expected must
|
|
|
-// also be converted to network byte order for the comparison to succeed.
|
|
|
TEST(Ipv6Check, V6ConstructorMask) {
|
|
|
- // Valid values.
|
|
|
+
|
|
|
+ // Valid masks...
|
|
|
DerivedV6Check acl1(V6ADDR_1, 1);
|
|
|
vector<uint8_t> stored = acl1.getNetmask();
|
|
|
EXPECT_EQ(sizeof(MASK_1), stored.size());
|
|
@@ -304,7 +400,6 @@ TEST(Ipv6Check, V6ConstructorMask) {
|
|
|
EXPECT_THROW(DerivedV6Check(V6ADDR_1, 129), isc::OutOfRange);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
TEST(Ipv6Check, V6ConstructorInverse) {
|
|
|
// Valid values. Address/mask of "1" is used as a placeholder
|
|
|
DerivedV6Check acl1(V6ADDR_1, 1);
|
|
@@ -336,25 +431,90 @@ TEST(Ipv6Check, V6StringConstructor) {
|
|
|
EXPECT_THROW(DerivedV6Check("::1/0"), isc::OutOfRange);
|
|
|
EXPECT_THROW(DerivedV6Check("::1/129"), isc::OutOfRange);
|
|
|
EXPECT_THROW(DerivedV6Check("::1/24/3"), isc::InvalidParameter);
|
|
|
- EXPECT_THROW(DerivedV6Check("2001:0db8::dead:beef/ww"), isc::InvalidParameter);
|
|
|
- EXPECT_THROW(DerivedV6Check("2xx1:0db8::dead:beef/32"), isc::InvalidParameter);
|
|
|
+ EXPECT_THROW(DerivedV6Check("2001:0db8::abcd/ww"), isc::InvalidParameter);
|
|
|
+ EXPECT_THROW(DerivedV6Check("2xx1:0db8::abcd/32"), isc::InvalidParameter);
|
|
|
}
|
|
|
|
|
|
+TEST(Ipv6Check, V6CopyConstructor) {
|
|
|
+ DerivedV6Check acl1(string(V6ADDR_2_STRING) + string("/52"));
|
|
|
+ DerivedV6Check acl2(acl1);
|
|
|
|
|
|
+ vector<uint8_t> acl1_address = acl1.getAddress();
|
|
|
+ vector<uint8_t> acl2_address = acl1.getAddress();
|
|
|
+ EXPECT_EQ(sizeof(V6ADDR_1), acl1_address.size());
|
|
|
+ EXPECT_EQ(acl1_address.size(), acl2_address.size());
|
|
|
+ EXPECT_TRUE(equal(acl1_address.begin(), acl1_address.end(),
|
|
|
+ acl2_address.begin()));
|
|
|
|
|
|
-// Check that the comparison works - note that "matches" just calls the
|
|
|
-// internal compare() code.
|
|
|
-//
|
|
|
-// Note that addresses passed to the class are expected to be in network-
|
|
|
-// byte order. Therefore for the comparisons to work as expected, we must
|
|
|
-// convert the values to network-byte order first.
|
|
|
+ EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
|
|
|
+
|
|
|
+ vector<uint8_t> acl1_netmask = acl1.getNetmask();
|
|
|
+ vector<uint8_t> acl2_netmask = acl1.getNetmask();
|
|
|
+ EXPECT_EQ(sizeof(V6ADDR_1), acl1_netmask.size());
|
|
|
+ EXPECT_EQ(acl1_netmask.size(), acl2_netmask.size());
|
|
|
+ EXPECT_TRUE(equal(acl1_netmask.begin(), acl1_netmask.end(),
|
|
|
+ acl2_netmask.begin()));
|
|
|
+
|
|
|
+ EXPECT_EQ(acl1.getInverse(), acl2.getInverse());
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Ipv6Check, V6AssignmentOperator) {
|
|
|
+ DerivedV6Check acl1(string(V6ADDR_2_STRING) + string("/52"));
|
|
|
+ DerivedV6Check acl2(string(V6ADDR_1_STRING) + string("/48"));
|
|
|
+
|
|
|
+ acl2 = acl1;
|
|
|
+
|
|
|
+ vector<uint8_t> acl1_address = acl1.getAddress();
|
|
|
+ vector<uint8_t> acl2_address = acl2.getAddress();
|
|
|
+ EXPECT_EQ(sizeof(V6ADDR_1), acl1_address.size());
|
|
|
+ EXPECT_EQ(acl1_address.size(), acl2_address.size());
|
|
|
+ EXPECT_TRUE(equal(acl1_address.begin(), acl1_address.end(),
|
|
|
+ acl2_address.begin()));
|
|
|
+
|
|
|
+ EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
|
|
|
+
|
|
|
+ vector<uint8_t> acl1_netmask = acl1.getNetmask();
|
|
|
+ vector<uint8_t> acl2_netmask = acl2.getNetmask();
|
|
|
+ EXPECT_EQ(sizeof(V6ADDR_1), acl1_netmask.size());
|
|
|
+ EXPECT_EQ(acl1_netmask.size(), acl2_netmask.size());
|
|
|
+ EXPECT_TRUE(equal(acl1_netmask.begin(), acl1_netmask.end(),
|
|
|
+ acl2_netmask.begin()));
|
|
|
+
|
|
|
+ EXPECT_EQ(acl1.getInverse(), acl2.getInverse());
|
|
|
+}
|
|
|
+
|
|
|
+TEST(Ipv6Check, V6Clone) {
|
|
|
+ DerivedV6Check acl1(string(V6ADDR_2_STRING) + string("/52"));
|
|
|
+ boost::scoped_ptr<DerivedV6Check> acl2(
|
|
|
+ static_cast<DerivedV6Check*>(acl1.clone()));
|
|
|
+
|
|
|
+ vector<uint8_t> acl1_address = acl1.getAddress();
|
|
|
+ vector<uint8_t> acl2_address = acl2->getAddress();
|
|
|
+ EXPECT_EQ(sizeof(V6ADDR_1), acl1_address.size());
|
|
|
+ EXPECT_EQ(acl1_address.size(), acl2_address.size());
|
|
|
+ EXPECT_TRUE(equal(acl1_address.begin(), acl1_address.end(),
|
|
|
+ acl2_address.begin()));
|
|
|
+
|
|
|
+ EXPECT_EQ(acl1.getMasksize(), acl2->getMasksize());
|
|
|
+
|
|
|
+ vector<uint8_t> acl1_netmask = acl1.getNetmask();
|
|
|
+ vector<uint8_t> acl2_netmask = acl2->getNetmask();
|
|
|
+ EXPECT_EQ(sizeof(V6ADDR_1), acl1_netmask.size());
|
|
|
+ EXPECT_EQ(acl1_netmask.size(), acl2_netmask.size());
|
|
|
+ EXPECT_TRUE(equal(acl1_netmask.begin(), acl1_netmask.end(),
|
|
|
+ acl2_netmask.begin()));
|
|
|
+
|
|
|
+ EXPECT_EQ(acl1.getInverse(), acl2->getInverse());
|
|
|
+}
|
|
|
|
|
|
TEST(Ipv6Check, V6Compare) {
|
|
|
// Set up some data. The constant doesn't depend on the template parameter,
|
|
|
// so use a type name that's short.
|
|
|
vector<uint8_t> v6addr_2(V6ADDR_2, V6ADDR_2 + DerivedV6Check::IPV6_SIZE);
|
|
|
- vector<uint8_t> v6addr_2_48(V6ADDR_2_48, V6ADDR_2_48 + DerivedV6Check::IPV6_SIZE);
|
|
|
- vector<uint8_t> v6addr_2_52(V6ADDR_2_52, V6ADDR_2_52 + DerivedV6Check::IPV6_SIZE);
|
|
|
+ vector<uint8_t> v6addr_2_48(V6ADDR_2_48,
|
|
|
+ V6ADDR_2_48 + DerivedV6Check::IPV6_SIZE);
|
|
|
+ vector<uint8_t> v6addr_2_52(V6ADDR_2_52,
|
|
|
+ V6ADDR_2_52 + DerivedV6Check::IPV6_SIZE);
|
|
|
vector<uint8_t> v6addr_3(V6ADDR_3, V6ADDR_3 + DerivedV6Check::IPV6_SIZE);
|
|
|
|
|
|
// Exact address - match if given address matches stored address.
|
|
@@ -385,3 +545,83 @@ TEST(Ipv6Check, V6Compare) {
|
|
|
EXPECT_TRUE(acl4.matches(v6addr_2_48));
|
|
|
EXPECT_TRUE(acl4.matches(v6addr_3));
|
|
|
}
|
|
|
+
|
|
|
+// *** IP Tests ***
|
|
|
+
|
|
|
+// Provide specializations for a simple joint struct holding both an
|
|
|
+// IPV4 address and an IPV6 address
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ bool isv4;
|
|
|
+ uint32_t v4addr;
|
|
|
+ uint8_t v6addr[16];
|
|
|
+} GeneralAddress;
|
|
|
+
|
|
|
+namespace isc {
|
|
|
+namespace acl {
|
|
|
+template <>
|
|
|
+bool Ipv4Check<GeneralAddress>::matches(const GeneralAddress& addr) const {
|
|
|
+ return (addr.isv4 ? compare(addr.v4addr) : false);
|
|
|
+}
|
|
|
+
|
|
|
+template <>
|
|
|
+bool Ipv6Check<GeneralAddress>::matches(const GeneralAddress& addr) const {
|
|
|
+ return (addr.isv4 ? false : compare(addr.v6addr));
|
|
|
+}
|
|
|
+} // namespace acl
|
|
|
+} // namespace isc
|
|
|
+
|
|
|
+TEST(IpCheck, V4Test) {
|
|
|
+ IpCheck<GeneralAddress> acl("192.168.132.255/16");
|
|
|
+ //c0 a8 84 ff
|
|
|
+
|
|
|
+ GeneralAddress test;
|
|
|
+ test.isv4 = true;
|
|
|
+ test.v4addr = htonl(0xc0a884ff);
|
|
|
+ EXPECT_TRUE(acl.matches(test));
|
|
|
+
|
|
|
+ test.v4addr = htonl(0xc0a884ee); // Correct to 24 bits
|
|
|
+ EXPECT_TRUE(acl.matches(test));
|
|
|
+
|
|
|
+ test.v4addr = htonl(0xc0a8ffee); // Correct to 16 bits
|
|
|
+ EXPECT_TRUE(acl.matches(test));
|
|
|
+
|
|
|
+ test.v4addr = htonl(0xc000ffee); // Incorrect
|
|
|
+ EXPECT_FALSE(acl.matches(test));
|
|
|
+
|
|
|
+ test.isv4 = false;
|
|
|
+ test.v4addr = htonl(0xc0a884ff); // Correct IPV4 address
|
|
|
+ EXPECT_FALSE(acl.matches(test));
|
|
|
+
|
|
|
+ // Quick check for negative match
|
|
|
+ IpCheck<GeneralAddress> acl2("192.168.132.255/16", true);
|
|
|
+ test.isv4 = true;
|
|
|
+ test.v4addr = htonl(0xc0a884ff);
|
|
|
+ EXPECT_FALSE(acl.matches(test));
|
|
|
+}
|
|
|
+
|
|
|
+TEST(IpCheck, V6Test) {
|
|
|
+ IpCheck<GeneralAddress> acl(string(V6ADDR_2_STRING) + string("/52"));
|
|
|
+
|
|
|
+ GeneralAddress test;
|
|
|
+ test.isv4 = false;
|
|
|
+ copy(V6ADDR_2, V6ADDR_2 + sizeof(V6ADDR_2), test.v6addr);
|
|
|
+ EXPECT_TRUE(acl.matches(test));
|
|
|
+
|
|
|
+ copy(V6ADDR_2, V6ADDR_2_52 + sizeof(V6ADDR_2_52), test.v6addr);
|
|
|
+ EXPECT_TRUE(acl.matches(test));
|
|
|
+
|
|
|
+ copy(V6ADDR_2, V6ADDR_2_48 + sizeof(V6ADDR_2_48), test.v6addr);
|
|
|
+ EXPECT_FALSE(acl.matches(test));
|
|
|
+
|
|
|
+ test.isv4 = true;
|
|
|
+ copy(V6ADDR_2, V6ADDR_2 + sizeof(V6ADDR_2), test.v6addr);
|
|
|
+ // Correct V6 address
|
|
|
+ EXPECT_FALSE(acl.matches(test));
|
|
|
+
|
|
|
+ // Quick check for negative match
|
|
|
+ IpCheck<GeneralAddress> acl2(string(V6ADDR_2_STRING) + string("/52"), true);
|
|
|
+ test.isv4 = false;
|
|
|
+ copy(V6ADDR_2, V6ADDR_2 + sizeof(V6ADDR_2), test.v6addr);
|
|
|
+ EXPECT_FALSE(acl.matches(test));
|
|
|
+}
|