mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[2312] Changes to the code as a result of review.
This commit is contained in:
@@ -99,9 +99,12 @@ OptionCustom::createBuffers() {
|
||||
// Proceed to the next data field.
|
||||
data += data_size;
|
||||
}
|
||||
} else {
|
||||
// If option definition type is not a 'record' than definition
|
||||
// type itself indicates what type of data is being held there.
|
||||
} else if (data_type != OPT_EMPTY_TYPE) {
|
||||
// If data_type value is other than OPT_RECORD_TYPE, our option is
|
||||
// empty (have no data at all) or it comprises one or more
|
||||
// data fields of the same type. The type of those fields
|
||||
// is held in the data_type variable so let's use it to determine
|
||||
// a size of buffers.
|
||||
int data_size = OptionDataTypeUtil::getDataTypeLen(data_type);
|
||||
// The check below will fail if the input buffer is too short
|
||||
// for the data size being held by this option.
|
||||
@@ -122,7 +125,9 @@ OptionCustom::createBuffers() {
|
||||
assert(data_size > 0);
|
||||
// Get equal chunks of data and store as collection of buffers.
|
||||
// Truncate any remaining part which length is not divisible by
|
||||
// data_size.
|
||||
// data_size. Note that it is ok to truncate the data if and only
|
||||
// if the data buffer is long enough to keep at least one value.
|
||||
// This has been checked above already.
|
||||
do {
|
||||
buffers.push_back(OptionBuffer(data, data + data_size));
|
||||
data += data_size;
|
||||
@@ -134,9 +139,9 @@ OptionCustom::createBuffers() {
|
||||
if (data_size == 0) {
|
||||
data_size = std::distance(data, data_.end());
|
||||
}
|
||||
if (data_size > 0 && data_type != OPT_EMPTY_TYPE) {
|
||||
if (data_size > 0) {
|
||||
buffers.push_back(OptionBuffer(data, data + data_size));
|
||||
} else if (data_type != OPT_EMPTY_TYPE) {
|
||||
} else {
|
||||
isc_throw(OutOfRange, "option buffer truncated");
|
||||
}
|
||||
}
|
||||
@@ -148,57 +153,49 @@ OptionCustom::createBuffers() {
|
||||
std::string
|
||||
OptionCustom::dataFieldToText(const OptionDataType data_type,
|
||||
const uint32_t index) const {
|
||||
std::ostringstream tmp;
|
||||
std::ostringstream text;
|
||||
|
||||
// Get the value of the data field.
|
||||
switch (data_type) {
|
||||
case OPT_BINARY_TYPE:
|
||||
tmp << util::encode::encodeHex(readBinary(index));
|
||||
text << util::encode::encodeHex(readBinary(index));
|
||||
break;
|
||||
case OPT_BOOLEAN_TYPE:
|
||||
tmp << (readBoolean(index) ? "true" : "false");
|
||||
text << (readBoolean(index) ? "true" : "false");
|
||||
break;
|
||||
case OPT_INT8_TYPE:
|
||||
tmp << readInteger<int8_t>(index);
|
||||
text << readInteger<int8_t>(index);
|
||||
break;
|
||||
case OPT_INT16_TYPE:
|
||||
tmp << readInteger<int16_t>(index);
|
||||
text << readInteger<int16_t>(index);
|
||||
break;
|
||||
case OPT_INT32_TYPE:
|
||||
tmp << readInteger<int32_t>(index);
|
||||
text << readInteger<int32_t>(index);
|
||||
break;
|
||||
case OPT_UINT8_TYPE:
|
||||
tmp << readInteger<uint8_t>(index);
|
||||
text << readInteger<uint8_t>(index);
|
||||
break;
|
||||
case OPT_UINT16_TYPE:
|
||||
tmp << readInteger<uint16_t>(index);
|
||||
text << readInteger<uint16_t>(index);
|
||||
break;
|
||||
case OPT_UINT32_TYPE:
|
||||
tmp << readInteger<uint32_t>(index);
|
||||
text << readInteger<uint32_t>(index);
|
||||
break;
|
||||
case OPT_IPV4_ADDRESS_TYPE:
|
||||
case OPT_IPV6_ADDRESS_TYPE:
|
||||
{
|
||||
asiolink::IOAddress address("127.0.0.1");
|
||||
readAddress(index, address);
|
||||
tmp << address.toText();
|
||||
break;
|
||||
}
|
||||
text << readAddress(index).toText();
|
||||
break;
|
||||
case OPT_STRING_TYPE:
|
||||
{
|
||||
std::string s;
|
||||
readString(index, s);
|
||||
tmp << s;
|
||||
break;
|
||||
}
|
||||
text << readString(index);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
// Append data field type in brackets.
|
||||
tmp << " ( " << OptionDataTypeUtil::getDataTypeName(data_type) << " ) ";
|
||||
text << " ( " << OptionDataTypeUtil::getDataTypeName(data_type) << " ) ";
|
||||
|
||||
return (tmp.str());
|
||||
return (text.str());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -214,7 +211,12 @@ OptionCustom::pack4(isc::util::OutputBuffer& buf) {
|
||||
// Write data from buffers.
|
||||
for (std::vector<OptionBuffer>::const_iterator it = buffers_.begin();
|
||||
it != buffers_.end(); ++it) {
|
||||
buf.writeData(&(*it)[0], it->size());
|
||||
// In theory the createBuffers function should have taken
|
||||
// care that there are no empty buffers added to the
|
||||
// collection but it is almost always good to make sure.
|
||||
if (it->size() > 0) {
|
||||
buf.writeData(&(*it)[0], it->size());
|
||||
}
|
||||
}
|
||||
|
||||
// Write suboptions.
|
||||
@@ -235,17 +237,17 @@ OptionCustom::pack6(isc::util::OutputBuffer& buf) {
|
||||
LibDHCP::packOptions(buf, options_);
|
||||
}
|
||||
|
||||
void
|
||||
OptionCustom::readAddress(const uint32_t index, asiolink::IOAddress& address) const {
|
||||
asiolink::IOAddress
|
||||
OptionCustom::readAddress(const uint32_t index) const {
|
||||
checkIndex(index);
|
||||
|
||||
// The address being read can be either IPv4 or IPv6. The decision
|
||||
// is made based on the buffer length. If it holds 4 bytes it is IPv4
|
||||
// address, if it holds 16 bytes it is IPv6.
|
||||
if (buffers_[index].size() == asiolink::V4ADDRESS_LEN) {
|
||||
OptionDataTypeUtil::readAddress(buffers_[index], AF_INET, address);
|
||||
return (OptionDataTypeUtil::readAddress(buffers_[index], AF_INET));
|
||||
} else if (buffers_[index].size() == asiolink::V6ADDRESS_LEN) {
|
||||
OptionDataTypeUtil::readAddress(buffers_[index], AF_INET6, address);
|
||||
return (OptionDataTypeUtil::readAddress(buffers_[index], AF_INET6));
|
||||
} else {
|
||||
isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
|
||||
<< " IP address. Invalid buffer length " << buffers_[index].size());
|
||||
@@ -264,10 +266,10 @@ OptionCustom::readBoolean(const uint32_t index) const {
|
||||
return (OptionDataTypeUtil::readBool(buffers_[index]));
|
||||
}
|
||||
|
||||
void
|
||||
OptionCustom::readString(const uint32_t index, std::string& value) const {
|
||||
std::string
|
||||
OptionCustom::readString(const uint32_t index) const {
|
||||
checkIndex(index);
|
||||
OptionDataTypeUtil::readString(buffers_[index], value);
|
||||
return (OptionDataTypeUtil::readString(buffers_[index]));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -310,7 +312,7 @@ void OptionCustom::setData(const OptionBufferConstIter first,
|
||||
createBuffers();
|
||||
}
|
||||
|
||||
std::string OptionCustom::toText(int indent /* = 0 */ ) {
|
||||
std::string OptionCustom::toText(int indent) {
|
||||
std::stringstream tmp;
|
||||
|
||||
for (int i = 0; i < indent; ++i)
|
||||
|
@@ -40,6 +40,12 @@ public:
|
||||
|
||||
/// @brief Constructor, used for options to be sent.
|
||||
///
|
||||
/// This constructor creates an instance of an option from the whole
|
||||
/// supplied buffer. This constructor is mainly used to create an
|
||||
/// instances of options to be stored in outgoing DHCP packets.
|
||||
/// The buffer used to create the instance of an option can be
|
||||
/// created from the option data specified in server's configuration.
|
||||
///
|
||||
/// @param def option definition.
|
||||
/// @param u specifies universe (V4 or V6).
|
||||
/// @param data content of the option.
|
||||
@@ -51,6 +57,13 @@ public:
|
||||
|
||||
/// @brief Constructor, used for received options.
|
||||
///
|
||||
/// This constructor creates an instance an option from the portion
|
||||
/// of the buffer specified by iterators. This is mainly useful when
|
||||
/// parsing received packets. Such packets are represented by a single
|
||||
/// buffer holding option data and all sub options. Methods that are
|
||||
/// parsing a packet, supply relevant portions of the packet buffer
|
||||
/// to this constructor to create option instances out of it.
|
||||
///
|
||||
/// @param def option definition.
|
||||
/// @param u specifies universe (V4 or V6).
|
||||
/// @param first iterator to the first element that should be copied.
|
||||
@@ -71,10 +84,10 @@ public:
|
||||
/// @brief Read a buffer as IP address.
|
||||
///
|
||||
/// @param index buffer index.
|
||||
/// @param [out] address read IP address.
|
||||
///
|
||||
/// @return IP address read from a buffer.
|
||||
/// @throw isc::OutOfRange if index is out of range.
|
||||
void readAddress(const uint32_t index, asiolink::IOAddress& address) const;
|
||||
asiolink::IOAddress readAddress(const uint32_t index) const;
|
||||
|
||||
/// @brief Read a buffer as binary data.
|
||||
///
|
||||
@@ -140,10 +153,10 @@ public:
|
||||
/// @brief Read a buffer as string value.
|
||||
///
|
||||
/// @param index buffer index.
|
||||
/// @param [out] value read string value.
|
||||
///
|
||||
/// @return string value read from buffer.
|
||||
/// @throw isc::OutOfRange if index is out of range.
|
||||
void readString(const uint32_t index, std::string& value) const;
|
||||
std::string readString(const uint32_t index) const;
|
||||
|
||||
/// @brief Parses received buffer.
|
||||
///
|
||||
|
@@ -48,6 +48,10 @@ OptionDataTypeUtil::OptionDataTypeUtil() {
|
||||
data_type_names_[OPT_STRING_TYPE] = "string";
|
||||
data_type_names_[OPT_FQDN_TYPE] = "fqdn";
|
||||
data_type_names_[OPT_RECORD_TYPE] = "record";
|
||||
// The "unknown" data type is declared here so as
|
||||
// it can be returned by reference by a getDataTypeName
|
||||
// function it no other type is suitable. Other than that
|
||||
// this is unused.
|
||||
data_type_names_[OPT_UNKNOWN_TYPE] = "unknown";
|
||||
}
|
||||
|
||||
@@ -73,16 +77,21 @@ OptionDataTypeUtil::getDataTypeLen(const OptionDataType data_type) {
|
||||
case OPT_INT8_TYPE:
|
||||
case OPT_UINT8_TYPE:
|
||||
return (1);
|
||||
|
||||
case OPT_INT16_TYPE:
|
||||
case OPT_UINT16_TYPE:
|
||||
return (2);
|
||||
|
||||
case OPT_INT32_TYPE:
|
||||
case OPT_UINT32_TYPE:
|
||||
return (4);
|
||||
|
||||
case OPT_IPV4_ADDRESS_TYPE:
|
||||
return (asiolink::V4ADDRESS_LEN);
|
||||
|
||||
case OPT_IPV6_ADDRESS_TYPE:
|
||||
return (asiolink::V6ADDRESS_LEN);
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
@@ -110,23 +119,22 @@ OptionDataTypeUtil::instance() {
|
||||
return (instance);
|
||||
}
|
||||
|
||||
void
|
||||
asiolink::IOAddress
|
||||
OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf,
|
||||
const short family,
|
||||
asiolink::IOAddress& address) {
|
||||
const short family) {
|
||||
using namespace isc::asiolink;
|
||||
if (family == AF_INET) {
|
||||
if (buf.size() < V4ADDRESS_LEN) {
|
||||
isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
|
||||
<< " IPv4 address. Invalid buffer size: " << buf.size());
|
||||
}
|
||||
address = IOAddress::fromBytes(AF_INET, &buf[0]);
|
||||
} else if (buf.size() == V6ADDRESS_LEN) {
|
||||
return (IOAddress::fromBytes(AF_INET, &buf[0]));
|
||||
} else if (family == AF_INET6) {
|
||||
if (buf.size() < V6ADDRESS_LEN) {
|
||||
isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
|
||||
<< " IPv6 address. Invalid buffer size: " << buf.size());
|
||||
}
|
||||
address = IOAddress::fromBytes(AF_INET6, &buf[0]);
|
||||
return (IOAddress::fromBytes(AF_INET6, &buf[0]));
|
||||
} else {
|
||||
isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
|
||||
"IP address. Invalid family: " << family);
|
||||
@@ -136,6 +144,9 @@ OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf,
|
||||
void
|
||||
OptionDataTypeUtil::writeAddress(const asiolink::IOAddress& address,
|
||||
std::vector<uint8_t>& buf) {
|
||||
// @todo There is a ticket 2396 submitted, which adds the
|
||||
// functionality to return a buffer representation of
|
||||
// IOAddress. If so, this function can be simplified.
|
||||
if (address.getAddress().is_v4()) {
|
||||
asio::ip::address_v4::bytes_type addr_bytes =
|
||||
address.getAddress().to_v4().to_bytes();
|
||||
@@ -192,28 +203,23 @@ OptionDataTypeUtil::readBool(const std::vector<uint8_t>& buf) {
|
||||
void
|
||||
OptionDataTypeUtil::writeBool(const bool value,
|
||||
std::vector<uint8_t>& buf) {
|
||||
if (value) {
|
||||
buf.push_back(static_cast<uint8_t>(1));
|
||||
} else {
|
||||
buf.push_back(static_cast<uint8_t>(0));
|
||||
}
|
||||
buf.push_back(static_cast<uint8_t>(value ? 1 : 0));
|
||||
}
|
||||
|
||||
void
|
||||
OptionDataTypeUtil::readString(const std::vector<uint8_t>& buf,
|
||||
std::string& value) {
|
||||
value.insert(value.end(), buf.begin(), buf.end());
|
||||
std::string
|
||||
OptionDataTypeUtil::readString(const std::vector<uint8_t>& buf) {
|
||||
std::string value;
|
||||
if (buf.size() > 0) {
|
||||
value.insert(value.end(), buf.begin(), buf.end());
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
void
|
||||
OptionDataTypeUtil::writeString(const std::string& value,
|
||||
std::vector<uint8_t>& buf) {
|
||||
if (value.size() > 0) {
|
||||
// Increase the size of the storage by the size of the string.
|
||||
buf.resize(buf.size() + value.size());
|
||||
// Assuming that the string is already UTF8 encoded.
|
||||
std::copy_backward(value.c_str(), value.c_str() + value.size(),
|
||||
buf.end());
|
||||
buf.insert(buf.end(), value.begin(), value.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -41,6 +41,13 @@ public:
|
||||
|
||||
|
||||
/// @brief Data types of DHCP option fields.
|
||||
///
|
||||
/// @warning The order of data types matters: OPT_UNKNOWN_TYPE
|
||||
/// must always be the last position. Also, OPT_RECORD_TYPE
|
||||
/// must be at last but one position. This is because some
|
||||
/// functions perform sanity checks on data type values using
|
||||
/// '>' operators, assuming that all values beyond the
|
||||
/// OPT_RECORD_TYPE are invalid.
|
||||
enum OptionDataType {
|
||||
OPT_EMPTY_TYPE,
|
||||
OPT_BINARY_TYPE,
|
||||
@@ -175,6 +182,16 @@ struct OptionDataTypeTraits<std::string> {
|
||||
};
|
||||
|
||||
/// @brief Utility class for option data types.
|
||||
///
|
||||
/// This class provides a set of utility functions to operate on
|
||||
/// supported DHCP option data types. It includes conversion
|
||||
/// between enumerator values representing data types and data
|
||||
/// type names. It also includes a set of functions that write
|
||||
/// data into option buffers and read data from option buffers.
|
||||
/// The data being written and read are converted from/to actual
|
||||
/// data types.
|
||||
/// @note This is a singleton class but it can be accessed via
|
||||
/// static methods only.
|
||||
class OptionDataTypeUtil {
|
||||
public:
|
||||
|
||||
@@ -212,19 +229,19 @@ public:
|
||||
///
|
||||
/// @param buf input buffer.
|
||||
/// @param family address family: AF_INET or AF_INET6.
|
||||
/// @param [out] address being read.
|
||||
static void readAddress(const std::vector<uint8_t>& buf,
|
||||
const short family,
|
||||
asiolink::IOAddress& address);
|
||||
///
|
||||
/// @return address being read.
|
||||
static asiolink::IOAddress readAddress(const std::vector<uint8_t>& buf,
|
||||
const short family);
|
||||
|
||||
/// @brief Write IPv4 or IPv6 address into a buffer.
|
||||
/// @brief Append IPv4 or IPv6 address to a buffer.
|
||||
///
|
||||
/// @param address IPv4 or IPv6 address.
|
||||
/// @param [out] buf output buffer.
|
||||
static void writeAddress(const asiolink::IOAddress& address,
|
||||
std::vector<uint8_t>& buf);
|
||||
|
||||
/// @brief Write hex-encoded binary values into a buffer.
|
||||
/// @brief Append hex-encoded binary values to a buffer.
|
||||
///
|
||||
/// @param hex_str string representing a binary value encoded
|
||||
/// with hexadecimal digits (without 0x prefix).
|
||||
@@ -238,7 +255,7 @@ public:
|
||||
/// @return boolean value read from a buffer.
|
||||
static bool readBool(const std::vector<uint8_t>& buf);
|
||||
|
||||
/// @brief Write boolean value into a buffer.
|
||||
/// @brief Append boolean value into a buffer.
|
||||
///
|
||||
/// The bool value is encoded in a buffer in such a way that
|
||||
/// "1" means "true" and "0" means "false".
|
||||
@@ -256,7 +273,7 @@ public:
|
||||
static T readInt(const std::vector<uint8_t>& buf) {
|
||||
if (!OptionDataTypeTraits<T>::integer_type) {
|
||||
isc_throw(isc::dhcp::InvalidDataType, "specified data type to be returned"
|
||||
" by readInteger is not supported integer type");
|
||||
" by readInteger is unsupported integer type");
|
||||
}
|
||||
|
||||
assert(buf.size() == OptionDataTypeTraits<T>::len);
|
||||
@@ -266,9 +283,13 @@ public:
|
||||
value = *(buf.begin());
|
||||
break;
|
||||
case 2:
|
||||
// Calling readUint16 works either for unsigned
|
||||
// or signed types.
|
||||
value = isc::util::readUint16(&(*buf.begin()));
|
||||
break;
|
||||
case 4:
|
||||
// Calling readUint32 works either for unsigned
|
||||
// or signed types.
|
||||
value = isc::util::readUint32(&(*buf.begin()));
|
||||
break;
|
||||
default:
|
||||
@@ -280,7 +301,7 @@ public:
|
||||
return (value);
|
||||
}
|
||||
|
||||
/// @brief Write integer or unsigned integer value into a buffer.
|
||||
/// @brief Append integer or unsigned integer value to a buffer.
|
||||
///
|
||||
/// @param value an integer value to be written into a buffer.
|
||||
/// @param [out] buf output buffer.
|
||||
@@ -314,9 +335,9 @@ public:
|
||||
/// @brief Read string value from a buffer.
|
||||
///
|
||||
/// @param buf input buffer.
|
||||
/// @param [out] value string value being read.
|
||||
static void readString(const std::vector<uint8_t>& buf,
|
||||
std::string& value);
|
||||
///
|
||||
/// @return string value being read.
|
||||
static std::string readString(const std::vector<uint8_t>& buf);
|
||||
|
||||
/// @brief Write UTF8-encoded string into a buffer.
|
||||
///
|
||||
|
@@ -350,8 +350,8 @@ OptionDefinition::writeToBuffer(const std::string& value,
|
||||
case OPT_IPV6_ADDRESS_TYPE:
|
||||
{
|
||||
asiolink::IOAddress address(value);
|
||||
if (!address.getAddress().is_v4() &&
|
||||
!address.getAddress().is_v6()) {
|
||||
if (address.getFamily() != AF_INET &&
|
||||
address.getFamily() != AF_INET6) {
|
||||
isc_throw(BadDataTypeCast, "provided address " << address.toText()
|
||||
<< " is not a valid "
|
||||
<< (address.getAddress().is_v4() ? "IPv4" : "IPv6")
|
||||
|
@@ -278,7 +278,7 @@ TEST_F(OptionCustomTest, ipv4AddressData) {
|
||||
|
||||
IOAddress address("127.0.0.1");
|
||||
// Read IPv4 address from using index 0.
|
||||
ASSERT_NO_THROW(option->readAddress(0, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(0));
|
||||
|
||||
EXPECT_EQ("192.168.100.50", address.toText());
|
||||
}
|
||||
@@ -306,7 +306,7 @@ TEST_F(OptionCustomTest, ipv6AddressData) {
|
||||
// IPv6 address.
|
||||
IOAddress address("::1");
|
||||
// Read an address from buffer #0.
|
||||
ASSERT_NO_THROW(option->readAddress(0, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(0));
|
||||
|
||||
EXPECT_EQ("2001:db8:1::100", address.toText());
|
||||
}
|
||||
@@ -333,7 +333,7 @@ TEST_F(OptionCustomTest, stringData) {
|
||||
// Custom option should now comprise single string value that
|
||||
// can be accessed using index 0.
|
||||
std::string value;
|
||||
ASSERT_NO_THROW(option->readString(0, value));
|
||||
ASSERT_NO_THROW(value = option->readString(0));
|
||||
|
||||
EXPECT_EQ("hello world!", value);
|
||||
}
|
||||
@@ -494,7 +494,7 @@ TEST_F(OptionCustomTest, ipv4AddressDataArray) {
|
||||
// We expect 3 IPv4 addresses being stored in the option.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
IOAddress address("10.10.10.10");
|
||||
ASSERT_NO_THROW(option->readAddress(i, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(i));
|
||||
EXPECT_EQ(addresses[i].toText(), address.toText());
|
||||
}
|
||||
}
|
||||
@@ -529,7 +529,7 @@ TEST_F(OptionCustomTest, ipv6AddressDataArray) {
|
||||
// We expect 3 IPv6 addresses being stored in the option.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
IOAddress address("fe80::4");
|
||||
ASSERT_NO_THROW(option->readAddress(i, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(i));
|
||||
EXPECT_EQ(addresses[i].toText(), address.toText());
|
||||
}
|
||||
}
|
||||
@@ -580,17 +580,17 @@ TEST_F(OptionCustomTest, recordData) {
|
||||
|
||||
// Verify value in the field 2.
|
||||
IOAddress value2("127.0.0.1");
|
||||
ASSERT_NO_THROW(option->readAddress(2, value2));
|
||||
ASSERT_NO_THROW(value2 = option->readAddress(2));
|
||||
EXPECT_EQ("192.168.0.1", value2.toText());
|
||||
|
||||
// Verify value in the field 3.
|
||||
IOAddress value3("::1");
|
||||
ASSERT_NO_THROW(option->readAddress(3, value3));
|
||||
ASSERT_NO_THROW(value3 = option->readAddress(3));
|
||||
EXPECT_EQ("2001:db8:1::1", value3.toText());
|
||||
|
||||
// Verify value in the field 4.
|
||||
std::string value4;
|
||||
ASSERT_NO_THROW(option->readString(4, value4));
|
||||
ASSERT_NO_THROW(value4 = option->readString(4));
|
||||
EXPECT_EQ("ABCD", value4);
|
||||
}
|
||||
|
||||
@@ -740,7 +740,7 @@ TEST_F(OptionCustomTest, unpack) {
|
||||
// We expect 3 IPv4 addresses being stored in the option.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
IOAddress address("10.10.10.10");
|
||||
ASSERT_NO_THROW(option->readAddress(i, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(i));
|
||||
EXPECT_EQ(addresses[i].toText(), address.toText());
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ TEST_F(OptionCustomTest, unpack) {
|
||||
// Verify that the addresses have been overwritten.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
IOAddress address("10.10.10.10");
|
||||
ASSERT_NO_THROW(option->readAddress(i, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(i));
|
||||
EXPECT_EQ(addresses[i].toText(), address.toText());
|
||||
}
|
||||
}
|
||||
@@ -802,7 +802,7 @@ TEST_F(OptionCustomTest, setData) {
|
||||
// We expect 3 IPv6 addresses being stored in the option.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
IOAddress address("fe80::4");
|
||||
ASSERT_NO_THROW(option->readAddress(i, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(i));
|
||||
EXPECT_EQ(addresses[i].toText(), address.toText());
|
||||
}
|
||||
|
||||
@@ -828,7 +828,7 @@ TEST_F(OptionCustomTest, setData) {
|
||||
// Check that it has been replaced.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
IOAddress address("10.10.10.10");
|
||||
ASSERT_NO_THROW(option->readAddress(i, address));
|
||||
ASSERT_NO_THROW(address = option->readAddress(i));
|
||||
EXPECT_EQ(addresses[i].toText(), address.toText());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user