2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 05:55:28 +00:00

[trac998] Replaced "netmask" terminology with "prefix"

This commit is contained in:
Stephen Morris
2011-06-22 16:26:20 +01:00
parent 6c5a9b252b
commit df5bad72ac
2 changed files with 165 additions and 154 deletions

View File

@@ -38,36 +38,35 @@ namespace acl {
// Free functions
/// \brief Convert mask size to mask
/// \brief Convert prefix length to mask
///
/// Given a mask size and a data type, return a value of that data type with the
/// most significant "masksize" bits set. For example, if the data type is an
/// uint8_t and the masksize is 3, the function would return a uint8_t holding
/// the binary value 11100000.
/// Given a prefix length and a data type, return a value of that data type
/// with the most significant "prefix length" bits set. For example, if the
/// data type is an uint8_t and the p[refix length is 3, the function would
/// return a uint8_t holding the binary value 11100000. This value is used as
/// a mask in the address checks.
///
/// The function is templated on the data type of the mask.
///
/// \param masksize Size of the mask. This must be between 0 and 8*sizeof(T).
/// An out of range exception is thrown if this is not the case.
/// \param prefixlen number of bits to be set in the mask. This must be
/// between 0 and 8*sizeof(T).
///
/// \return Value with the most significant "masksize" bits set.
/// \return Value with the most significant "prefixlen" bits set.
///
/// \exception OutOfRange prefixlen is too large for the data type.
template <typename T>
T createNetmask(size_t masksize) {
T createNetmask(size_t prefixlen) {
if (masksize == 0) {
// Although a mask size of zero is invalid for the IP ACL check
// specification, it simplifies logic elsewhere if this function is
// allowed to handle a mask size of 0.
if (prefixlen == 0) {
return (0);
} else if (masksize <= 8 * sizeof(T)) {
} else if (prefixlen <= 8 * sizeof(T)) {
// In the following discussion:
//
// w is the width of the data type T in bits.
// m is the value of masksize, the number of most signifcant bits we
// m is the value of prefixlen, the number of most signifcant bits we
// want to set.
// ** is exponentiation (i.e. 2**n is 2 raised to the power of n).
//
@@ -79,87 +78,89 @@ T createNetmask(size_t masksize) {
// w-m bits set and the most significant m bits clear. The 1's
// complement of this value gives is the result we want.
//
// Final note: at this point in the logic, m is non-zero, so w-m < m.
// Final note: at this point in the logic, m is non-zero, so w-m < w.
// This means 1<<(w-m) will fit into a variable of width w bits. In
// other words, in the expression below, no term will cause an integer
// overflow.
return (~((1 << (8 * sizeof(T) - masksize)) - 1));
return (~((1 << (8 * sizeof(T) - prefixlen)) - 1));
}
// Mask size is too large. (Note that masksize is unsigned, so can't be
// Mask size is too large. (Note that prefixlen is unsigned, so can't be
// negative.)
isc_throw(isc::OutOfRange, "masksize argument must be between 0 and " <<
isc_throw(isc::OutOfRange, "prefixlen argument must be between 0 and " <<
8 * sizeof(T));
}
/// \brief Split IP Address
/// \brief Split IP Address Prefix
///
/// Splits an IP address (given in the form of "xxxxxx/n" or "xxxxx" into a
/// string representing the IP address and a number giving the size of the
/// network mask in bits. (In the latter case, the size of the network mask is
/// equal to the width of the data type holding the address.) An exception will
/// be thrown if the string format is invalid or if the network mask size is not
/// an integer.
/// Splits an IP address prefix (given in the form of "xxxxxx/n" or "xxxxx" into
/// a string representing the IP address and a number giving the length of the
/// prefix. (In the latter case, the prefix is equal in length to the width in
/// width in bits of the data type holding the address.) An exception will
/// be thrown if the string format is invalid or if the prefix length is
/// invalid.
///
/// N.B. This function does NOT check that the address component is a valid IP
/// address; this is done elsewhere in the address parsing process.
///
/// \param addrmask Address and/or address/mask. The string should be passed
/// \param addrmask Address or address prefix. The string should be passed
/// without leading or trailing spaces.
///
/// \return Pair of (string, int) holding the address string and the mask
/// size value. The second element is -1 if no mask was given.
/// \return Pair of (string, int) holding the address string and the prefix
/// length. The second element is -1 if no prefix was given.
///
/// \exception InvalidParameter Address prefix not of the expected syntax
std::pair<std::string, int>
splitIPAddress(const std::string& addrmask) {
splitIPAddress(const std::string& prefix) {
// Set the default value for the mask size
int masksize = -1;
// Set the default value for the prefix length. As the type of the address
// is not known at the point this function is called, the maximum
// allowable value is also not known. And the value of 0 is reserved for
// a "match any address" match.
int prefixlen = -1;
// Split string into its components. As the tokenising code ignores
// leading, trailing nd consecutive delimiters, be strict here and ensures
// leading, trailing and consecutive delimiters, be strict here and ensure
// that the string contains at most 0 or 1 slashes.
if (std::count(addrmask.begin(), addrmask.end(), '/') > 1) {
isc_throw(isc::InvalidParameter, "address/masksize of " <<
addrmask << " is not valid");
if (std::count(prefix.begin(), prefix.end(), '/') > 1) {
isc_throw(isc::InvalidParameter, "address prefix of " << prefix <<
" is not valid");
}
std::vector<std::string> components = isc::util::str::tokens(addrmask, "/");
std::vector<std::string> components = isc::util::str::tokens(prefix, "/");
if (components.size() == 2) {
// There appears to be a mask, try converting it to a number.
// There appears to be a prefix length, try converting it to a number.
try {
masksize = boost::lexical_cast<int>(components[1]);
prefixlen = boost::lexical_cast<int>(components[1]);
} catch (boost::bad_lexical_cast&) {
isc_throw(isc::InvalidParameter,
"mask size specified in address/masksize " << addrmask <<
" is not valid");
isc_throw(isc::InvalidParameter, "prefix length of " << prefix <<
" is not valid");
}
// Ensure that it is positive - a mask size of zero is not a valid
// value.
if (masksize <= 0) {
isc_throw(isc::OutOfRange,
"mask size specified in address/masksize " << addrmask <<
" must be a positive number");
// Ensure that it is positive or zero (a prefix length of zero implies
// an unconditional match)
if (prefixlen < 0) {
isc_throw(isc::InvalidParameter,
"prefix length specified in address prefix of " <<
prefix << " must not be negative");
}
} else if (components.size() > 2) {
isc_throw(isc::InvalidParameter, "address/masksize of " <<
addrmask << " is not valid");
isc_throw(isc::InvalidParameter, "address prefix of " << prefix <<
" is not valid");
}
return (std::make_pair(components[0], masksize));
return (std::make_pair(components[0], prefixlen));
}
/// \brief IP Check
///
/// This class performs a match between an IP address specified in an ACL
/// (IP address, network mask and a flag indicating whether the check should
/// be for a match or for a non-match) and a given IP address. The check
/// works for both IPV4 and IPV6 addresses.
/// This class performs a match between an IP address prefix specified in an ACL
/// and a given IP address. The check works for both IPV4 and IPV6 addresses.
///
/// The class is templated on the type of a context structure passed to the
/// matches() method, and a template specialisation for that method must be
@@ -186,80 +187,78 @@ public:
///
/// Constructs an empty IPCheck object. The address family returned will
/// be zero.
IPCheck() : address_(), netmask_(), masksize_(0), inverse_(false),
IPCheck() : address_(), mask_(), prefixlen_(0), inverse_(false),
family_(0), straddr_()
{
std::fill(address_.word, address_.word + IPV6_SIZE32, 0);
std::fill(netmask_.word, netmask_.word + IPV6_SIZE32, 0);
std::fill(mask_.word, mask_.word + IPV6_SIZE32, 0);
}
/// \brief IPV4 Constructor
///
/// Constructs an IPCheck object from a network address given as a
/// 32-bit value in network byte order.
/// 32-bit value in network byte order and a prefix length.
///
/// \param address IP address to check for (as an address in network-byte
/// order).
/// \param mask The network mask specified as an integer between 1 and
/// 32. This determines the number of bits in the mask to check.
/// An exception will be thrown if the number is not within these
/// bounds.
/// \param prefixlen The prefix length specified as an integer between 0 and
/// 32. This determines the number of bits of the address to check.
/// (A value of zero imples match all IPV4 addresses.)
/// \param inverse If false (the default), matches() returns true if the
/// condition matches. If true, matches() returns true if the
/// condition does not match.
IPCheck(uint32_t address, int masksize = 8 * sizeof(uint32_t),
IPCheck(uint32_t address, int prefixlen = 8 * sizeof(uint32_t),
bool inverse = false):
address_(), netmask_(), masksize_(masksize), inverse_(inverse),
address_(), mask_(), prefixlen_(prefixlen), inverse_(inverse),
family_(AF_INET), straddr_()
{
address_.word[0] = address;
std::fill(address_.word + 1, address_.word + IPV6_SIZE32, 0);
std::fill(netmask_.word, netmask_.word + IPV6_SIZE32, 0);
setNetmask(masksize_);
std::fill(mask_.word, mask_.word + IPV6_SIZE32, 0);
setMask(prefixlen_);
}
/// \brief IPV6 Constructor
///
/// Constructs an IPv6 Check object from a network address given as a
/// 16-byte array in network-byte order.
/// 16-byte array in network-byte order and a prefix length.
///
/// \param address IP address to check for (as an address in network-byte
/// order).
/// \param mask The network mask specified as an integer between 1 and
/// 128 This determines the number of bits in the mask to check.
/// An exception will be thrown if the number is not within these
/// bounds.
/// \param inverse If false (the default), matches() returns true if the
/// condition matches. If true, matches() returns true if the
/// condition does not match.
IPCheck(const uint8_t* address, int masksize = 8 * IPV6_SIZE8,
IPCheck(const uint8_t* address, int prefixlen = 8 * IPV6_SIZE8,
bool inverse = false):
address_(), netmask_(), masksize_(masksize), inverse_(inverse),
address_(), mask_(), prefixlen_(prefixlen), inverse_(inverse),
family_(AF_INET6), straddr_()
{
std::copy(address, address + IPV6_SIZE8, address_.byte);
std::fill(netmask_.word, netmask_.word + IPV6_SIZE32, 0);
setNetmask(masksize_);
std::fill(mask_.word, mask_.word + IPV6_SIZE32, 0);
setMask(prefixlen_);
}
/// \brief String Constructor
///
/// Constructs an IP Check object from a network address and size of mask
/// given as a string of the form <ip-address>/n".
/// Constructs an IP Check object from an address or address prefix in the
/// form <ip-address>/n".
///
/// \param address IP address and netmask in the form "<ip-address>/n"
/// \param address IP address and mask in the form "<ip-address>/n"
/// (where the "/n" part is optional and should be valid for the
/// address).
/// address). If "n" is specified as zero, the match is for any
/// address in that address family.
/// \param inverse If false (the default), matches() returns true if the
/// condition matches. If true, matches() returns true if the
/// condition does not match.
IPCheck(const std::string& address, bool inverse = false) :
address_(), netmask_(), masksize_(0), inverse_(inverse),
address_(), mask_(), prefixlen_(0), inverse_(inverse),
family_(0), straddr_(address)
{
// Initialize.
std::fill(address_.word, address_.word + IPV6_SIZE32, 0);
std::fill(netmask_.word, netmask_.word + IPV6_SIZE32, 0);
std::fill(mask_.word, mask_.word + IPV6_SIZE32, 0);
// Split the address into address part and mask.
std::pair<std::string, int> result = splitIPAddress(address);
@@ -275,26 +274,26 @@ public:
int status = inet_pton(AF_INET, result.first.c_str(),
address_.word);
if (status == 0) {
isc_throw(isc::InvalidParameter, "address/masksize of " <<
address << " is not valid IP address");
isc_throw(isc::InvalidParameter, "address of " <<
result.first << " is a not valid IP address");
}
}
// All done, so set the network mask.
setNetmask(result.second);
// All done, so set the mask used in checking.
setMask(result.second);
}
/// \brief Copy constructor
///
/// \param other Object from which the copy is being constructed.
IPCheck(const IPCheck<Context>& other) : address_(), netmask_(),
masksize_(other.masksize_), inverse_(other.inverse_),
IPCheck(const IPCheck<Context>& other) : address_(), mask_(),
prefixlen_(other.prefixlen_), inverse_(other.inverse_),
family_(other.family_), straddr_(other.straddr_)
{
std::copy(other.address_.word, other.address_.word + IPV6_SIZE32,
address_.word);
std::copy(other.netmask_.word, other.netmask_.word + IPV6_SIZE32,
netmask_.word);
std::copy(other.mask_.word, other.mask_.word + IPV6_SIZE32,
mask_.word);
}
/// \brief Assignment operator
@@ -307,9 +306,9 @@ public:
Check<Context>::operator=(other);
std::copy(other.address_.word, other.address_.word + IPV6_SIZE32,
address_.word);
std::copy(other.netmask_.word, other.netmask_.word + IPV6_SIZE32,
netmask_.word);
masksize_ = other.masksize_;
std::copy(other.mask_.word, other.mask_.word + IPV6_SIZE32,
mask_.word);
prefixlen_ = other.prefixlen_;
inverse_ = other.inverse_;
family_ = other.family_;
straddr_ = other.straddr_;
@@ -350,7 +349,7 @@ public:
/// \return Network mask applied to match
std::vector<uint8_t> getNetmask() const {
return (std::vector<uint8_t>(netmask_.byte, netmask_.byte + IPV6_SIZE8));
return (std::vector<uint8_t>(mask_.byte, mask_.byte + IPV6_SIZE8));
}
/// \return String passed to constructor
@@ -358,9 +357,9 @@ public:
return (straddr_);
}
/// \return Mask size given to constructor
size_t getMasksize() const {
return (masksize_);
/// \return Prefix length of the match
size_t getPrefixlen() const {
return (prefixlen_);
}
/// \return Address family
@@ -394,30 +393,36 @@ private:
/// \return true if the address matches, false if it does not.
virtual bool compare(const uint8_t* testaddr) const {
// To check that the address given matches the stored network address
// and netmask, we check the simple condition that:
//
// address_given & netmask_ == stored_address & netmask_
//
// The result is checked for all bytes for which there are bits set in
// the network mask. We stop at the first non-match (or when we run
// out of bits in the network mask). (Note that the network mask
// represents a contiguous set of bits. As such, as soon as we find
// a netmask byte of zeroes, we have run past the part of the address
// where we need to match.
//
// We can optimise further by casting to a 32-bit array and checking
// 32 bits at a time.
if (prefixlen_ != 0) {
bool match = true;
for (int i = 0; match && (i < IPV6_SIZE8) && (netmask_.byte[i] != 0);
++i) {
match = ((testaddr[i] & netmask_.byte[i]) ==
(address_.byte[i] & netmask_.byte[i]));
// To check that the address given matches the stored network
// address and mask, we check the simple condition that:
//
// address_given & mask_ == stored_address & mask_
//
// The result is checked for all bytes for which there are bits set
// in the mask. We stop at the first non-match (or when we run
// out of bits in the mask). (Note that the mask represents a
// contiguous set of bits. As such, as soon as we find a mask byte
// of zeroes, we have run past the part of the address where we need
// to match.
//
// We can optimise further by casting to a 32-bit array and checking
// 32 bits at a time.
bool match = true;
for (int i = 0; match && (i < IPV6_SIZE8) && (mask_.byte[i] != 0);
++i) {
match = ((testaddr[i] & mask_.byte[i]) ==
(address_.byte[i] & mask_.byte[i]));
}
// As with the V4 check, return the XOR with the inverse flag.
return (match != inverse_);
}
// As with the V4 check, return the XOR with the inverse flag.
return (match != inverse_);
// A prefix length of 0 is an unconditional match.
return (true);
}
/// \brief Comparison
@@ -429,23 +434,29 @@ private:
///
/// \return true if the address matches, false if it does not.
virtual bool compare(const uint32_t testaddr) const {
return (((testaddr & netmask_.word[0]) ==
(address_.word[0] & netmask_.word[0])) != inverse_);
if (prefixlen_ != 0) {
return (((testaddr & mask_.word[0]) ==
(address_.word[0] & mask_.word[0])) != inverse_);
}
// A prefix length of 0 is an unconditional match.
return (true);
}
/// \brief Set Network Mask
/// \brief Set Mask
///
/// Sets up the network mask from the mask size. This involves setting
/// an individual mask in each byte of the network mask.
/// Sets up the mask from the prefix length. This involves setting
/// an individual mask in each byte of the mask array.
///
/// The actual allowed value of the mask size depends on the address
/// The actual allowed value of the prefix length depends on the address
/// family.
///
/// \param requested Requested mask size. If negative, the maximum for
/// the address family is assumed. (A negative value will arise
/// if the string constructor was used and no mask size was given.)
void setNetmask(int requested) {
/// \param requested Requested prefix length size. If negative, the
/// maximum for the address family is assumed. (A negative value
/// will arise if the string constructor was used and no mask size
/// was given.)
void setMask(int requested) {
// Set the maximum mask size allowed.
int maxmask = 8 * ((family_ == AF_INET) ? sizeof(uint32_t) : IPV6_SIZE8);
@@ -454,35 +465,35 @@ private:
}
// Validate that the mask is valid.
if ((requested >= 1) && (requested <= maxmask)) {
masksize_ = requested;
if (requested <= maxmask) {
prefixlen_ = requested;
// The netmask array was initialized to zero in the constructor,
// The mask array was initialized to zero in the constructor,
// but as an addition check, assert that this is so.
assert(std::find_if(netmask_.word, netmask_.word + IPV6_SIZE32,
assert(std::find_if(mask_.word, mask_.word + IPV6_SIZE32,
std::bind1st(std::not_equal_to<uint32_t>(), 0)) ==
netmask_.word + IPV6_SIZE32);
mask_.word + IPV6_SIZE32);
// Loop, setting the bits in the set of mask bytes until all the
// specified bits have been used up. As both IPV4 and IPV6
// addresses are stored in network-byte order, this works in
// both cases.
size_t bits_left = masksize_; // Bits remaining to set
size_t bits_left = prefixlen_; // Bits remaining to set
int i = -1;
while (bits_left > 0) {
if (bits_left >= 8) {
netmask_.byte[++i] = ~0; // All bits set
mask_.byte[++i] = ~0; // All bits set
bits_left -= 8;
} else if (bits_left > 0) {
netmask_.byte[++i] = createNetmask<uint8_t>(bits_left);
mask_.byte[++i] = createNetmask<uint8_t>(bits_left);
bits_left = 0;
}
}
} else {
isc_throw(isc::OutOfRange,
"mask size of " << masksize_ << " is invalid " <<
"mask size of " << prefixlen_ << " is invalid " <<
"for the givem address");
}
}
@@ -490,8 +501,8 @@ private:
// Member variables
AddressData address_; ///< Address in binary form
AddressData netmask_; ///< Network mask
size_t masksize_; ///< Mask size passed to constructor
AddressData mask_; ///< Address mask
size_t prefixlen_; ///< Mask size passed to constructor
bool inverse_; ///< Test for equality or inequality
int family_; ///< Address family
std::string straddr_; ///< Copy of constructor address string

View File

@@ -136,11 +136,14 @@ TEST(IPFunctionCheck, SplitIPAddress) {
EXPECT_EQ(string("2001:db8::"), result.first);
EXPECT_EQ(128, result.second);
EXPECT_THROW(splitIPAddress("192.0.2.43/-1"), isc::OutOfRange);
result = splitIPAddress("192.0.2.1/0");
EXPECT_EQ(string("192.0.2.1"), result.first);
EXPECT_EQ(0, result.second);
EXPECT_THROW(splitIPAddress("192.0.2.43/-1"), isc::InvalidParameter);
EXPECT_THROW(splitIPAddress("192.0.2.43//1"), isc::InvalidParameter);
EXPECT_THROW(splitIPAddress("192.0.2.43/1/"), isc::InvalidParameter);
EXPECT_THROW(splitIPAddress("/192.0.2.43/1"), isc::InvalidParameter);
EXPECT_THROW(splitIPAddress("2001:db8::/0"), isc::OutOfRange);
EXPECT_THROW(splitIPAddress("2001:db8::/xxxx"), isc::InvalidParameter);
EXPECT_THROW(splitIPAddress("2001:db8::/32/s"), isc::InvalidParameter);
}
@@ -178,18 +181,17 @@ TEST(IPCheck, V4ConstructorMask) {
GeneralAddress netmask1(htonl(0x80000000)); // Expected mask
vector<uint8_t> stored1 = acl1.getNetmask();
EXPECT_TRUE(netmask1.equals(stored1));
EXPECT_EQ(1, acl1.getMasksize());
EXPECT_EQ(1, acl1.getPrefixlen());
// Different check
IPCheck<GeneralAddress> acl2(1, 24);
GeneralAddress netmask2(htonl(0xffffff00));
vector<uint8_t> stored2 = acl2.getNetmask();
EXPECT_TRUE(netmask2.equals(stored2));
EXPECT_EQ(24, acl2.getMasksize());
EXPECT_EQ(24, acl2.getPrefixlen());
// ... and some invalid network masks
GeneralAddress dummy;
EXPECT_THROW(IPCheck<GeneralAddress>(1, 0), isc::OutOfRange);
EXPECT_THROW(IPCheck<GeneralAddress>(1, 33), isc::OutOfRange);
EXPECT_THROW(IPCheck<GeneralAddress>(dummy.v6addr, 129), isc::OutOfRange);
}
@@ -209,7 +211,7 @@ TEST(IPCheck, V4ConstructorInverse) {
TEST(IPCheck, V4StringConstructor) {
// Constructor with no mask given
IPCheck<GeneralAddress> acl1("192.0.2.255");
EXPECT_EQ(32, acl1.getMasksize());
EXPECT_EQ(32, acl1.getPrefixlen());
vector<uint8_t> stored1 = acl1.getAddress();
GeneralAddress expected1(htonl(0xc00002ff));
@@ -217,14 +219,13 @@ TEST(IPCheck, V4StringConstructor) {
// Constructor with valid mask given
IPCheck<GeneralAddress> acl2("192.0.2.0/24");
EXPECT_EQ(24, acl2.getMasksize());
EXPECT_EQ(24, acl2.getPrefixlen());
vector<uint8_t> stored2 = acl2.getAddress();
GeneralAddress expected2(htonl(0xc0000200));
EXPECT_TRUE(expected2.equals(stored2));
// Invalid masks
EXPECT_THROW(IPCheck<GeneralAddress>("192.0.2.0/0"), isc::OutOfRange);
EXPECT_THROW(IPCheck<GeneralAddress>("192.0.2.0/33"), isc::OutOfRange);
EXPECT_THROW(IPCheck<GeneralAddress>("192.0.2.0/24/3"),
isc::InvalidParameter);
@@ -238,7 +239,7 @@ TEST(IPCheck, V4CopyConstructor) {
IPCheck<GeneralAddress> acl1("192.0.2.1/24", true);
IPCheck<GeneralAddress> acl2(acl1);
EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
EXPECT_EQ(acl1.getPrefixlen(), acl2.getPrefixlen());
EXPECT_EQ(acl1.getInverse(), acl2.getInverse());
EXPECT_EQ(acl1.getFamily(), acl2.getFamily());
EXPECT_EQ(acl1.getStringAddress(), acl2.getStringAddress());
@@ -259,7 +260,7 @@ TEST(IPCheck, V4AssignmentOperator) {
IPCheck<GeneralAddress> acl2("192.0.2.128/25", false);
acl2 = acl1;
EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
EXPECT_EQ(acl1.getPrefixlen(), acl2.getPrefixlen());
EXPECT_EQ(acl1.getInverse(), acl2.getInverse());
EXPECT_EQ(acl1.getFamily(), acl2.getFamily());
EXPECT_EQ(acl1.getStringAddress(), acl2.getStringAddress());
@@ -413,7 +414,6 @@ TEST(IPCheck, V6ConstructorMask) {
EXPECT_TRUE(equal(stored.begin(), stored.end(), MASK_128));
// ... and some invalid network masks
EXPECT_THROW(IPCheck<GeneralAddress>(V6ADDR_1, 0), isc::OutOfRange);
EXPECT_THROW(IPCheck<GeneralAddress>(V6ADDR_1, 129), isc::OutOfRange);
}
@@ -432,20 +432,20 @@ TEST(IPCheck, V6ConstructorInverse) {
TEST(IPCheck, V6StringConstructor) {
IPCheck<GeneralAddress> acl1(V6ADDR_1_STRING);
vector<uint8_t> address = acl1.getAddress();
EXPECT_EQ(128, acl1.getMasksize());
EXPECT_EQ(128, acl1.getPrefixlen());
EXPECT_TRUE(equal(address.begin(), address.end(), V6ADDR_1));
IPCheck<GeneralAddress> acl2(string(V6ADDR_2_STRING) + string("/48"));
address = acl2.getAddress();
EXPECT_EQ(48, acl2.getMasksize());
EXPECT_EQ(48, acl2.getPrefixlen());
EXPECT_TRUE(equal(address.begin(), address.end(), V6ADDR_2));
IPCheck<GeneralAddress> acl3("::1");
address = acl3.getAddress();
EXPECT_EQ(128, acl3.getMasksize());
EXPECT_EQ(128, acl3.getPrefixlen());
EXPECT_TRUE(equal(address.begin(), address.end(), V6ADDR_3));
EXPECT_THROW(IPCheck<GeneralAddress>("::1/0"), isc::OutOfRange);
EXPECT_NO_THROW(IPCheck<GeneralAddress>("::1/0"));
EXPECT_THROW(IPCheck<GeneralAddress>("::1/129"), isc::OutOfRange);
EXPECT_THROW(IPCheck<GeneralAddress>("::1/24/3"), isc::InvalidParameter);
EXPECT_THROW(IPCheck<GeneralAddress>("2001:0db8::abcd/ww"),
@@ -465,7 +465,7 @@ TEST(IPCheck, V6CopyConstructor) {
EXPECT_TRUE(equal(acl1_address.begin(), acl1_address.end(),
acl2_address.begin()));
EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
EXPECT_EQ(acl1.getPrefixlen(), acl2.getPrefixlen());
vector<uint8_t> acl1_netmask = acl1.getNetmask();
vector<uint8_t> acl2_netmask = acl1.getNetmask();
@@ -490,7 +490,7 @@ TEST(IPCheck, V6AssignmentOperator) {
EXPECT_TRUE(equal(acl1_address.begin(), acl1_address.end(),
acl2_address.begin()));
EXPECT_EQ(acl1.getMasksize(), acl2.getMasksize());
EXPECT_EQ(acl1.getPrefixlen(), acl2.getPrefixlen());
vector<uint8_t> acl1_netmask = acl1.getNetmask();
vector<uint8_t> acl2_netmask = acl2.getNetmask();