summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarcin Siodelski <marcin@isc.org>2012-11-30 13:28:28 +0100
committerMarcin Siodelski <marcin@isc.org>2012-11-30 13:28:28 +0100
commitac111116c588c5b611e1363d4fe11c7ee8f4e495 (patch)
treeb02a8ff873c79efbe62cd4835a9d6668c5d957da /src
parent[2491] Support for custom option to hold FQDN. (diff)
downloadkea-ac111116c588c5b611e1363d4fe11c7ee8f4e495.tar.xz
kea-ac111116c588c5b611e1363d4fe11c7ee8f4e495.zip
[2491] Test that appropriate std options are returned.
Diffstat (limited to 'src')
-rw-r--r--src/lib/dhcp/libdhcp++.cc2
-rw-r--r--src/lib/dhcp/option_definition.cc76
-rw-r--r--src/lib/dhcp/tests/libdhcp++_unittest.cc164
-rw-r--r--src/lib/dhcp/tests/option_definition_unittest.cc3
4 files changed, 190 insertions, 55 deletions
diff --git a/src/lib/dhcp/libdhcp++.cc b/src/lib/dhcp/libdhcp++.cc
index e3477a3d5b..e8d3f17d87 100644
--- a/src/lib/dhcp/libdhcp++.cc
+++ b/src/lib/dhcp/libdhcp++.cc
@@ -356,7 +356,7 @@ LibDHCP::initStdOptionDefs6() {
case D6O_GEOCONF_CIVIC:
definition->addRecordField(OPT_UINT8_TYPE);
definition->addRecordField(OPT_UINT16_TYPE);
- definition->addRecordField(OPT_STRING_TYPE);
+ definition->addRecordField(OPT_BINARY_TYPE);
break;
case D6O_REMOTE_ID:
definition->addRecordField(OPT_UINT32_TYPE);
diff --git a/src/lib/dhcp/option_definition.cc b/src/lib/dhcp/option_definition.cc
index 58d0c4bae8..1d1d75bbd2 100644
--- a/src/lib/dhcp/option_definition.cc
+++ b/src/lib/dhcp/option_definition.cc
@@ -19,6 +19,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int.h>
#include <dhcp/option6_int_array.h>
+#include <dhcp/option_custom.h>
#include <dhcp/option_definition.h>
#include <util/encode/hex.h>
@@ -78,53 +79,64 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
OptionBufferConstIter begin,
OptionBufferConstIter end) const {
validate();
-
+
try {
- if (type_ == OPT_BINARY_TYPE) {
+ switch(type_) {
+ case OPT_EMPTY_TYPE:
+ return (factoryEmpty(u, type));
+
+ case OPT_BINARY_TYPE:
return (factoryGeneric(u, type, begin, end));
- } else if (type_ == OPT_IPV6_ADDRESS_TYPE && array_type_) {
- return (factoryAddrList6(type, begin, end));
+ case OPT_UINT8_TYPE:
+ return (array_type_ ? factoryGeneric(u, type, begin, end) :
+ factoryInteger<uint8_t>(u, type, begin, end));;
- } else if (type_ == OPT_IPV4_ADDRESS_TYPE && array_type_) {
- return (factoryAddrList4(type, begin, end));
+ case OPT_INT8_TYPE:
+ return (array_type_ ? factoryGeneric(u, type, begin, end) :
+ factoryInteger<int8_t>(u, type, begin, end));
- } else if (type_ == OPT_EMPTY_TYPE) {
- return (factoryEmpty(u, type));
+ case OPT_UINT16_TYPE:
+ return (array_type_ ? factoryIntegerArray<uint16_t>(type, begin, end) :
+ factoryInteger<uint16_t>(u, type, begin, end));
- } else if (u == Option::V6 &&
- code_ == D6O_IA_NA &&
- haveIA6Format()) {
- return (factoryIA6(type, begin, end));
+ case OPT_INT16_TYPE:
+ return (array_type_ ? factoryIntegerArray<uint16_t>(type, begin, end) :
+ factoryInteger<int16_t>(u, type, begin, end));
- } else if (u == Option::V6 &&
- code_ == D6O_IAADDR &&
- haveIAAddr6Format()) {
- return (factoryIAAddr6(type, begin, end));
+ case OPT_UINT32_TYPE:
+ return (array_type_ ? factoryIntegerArray<uint32_t>(type, begin, end) :
+ factoryInteger<uint32_t>(u, type, begin, end));
- } else if (type_ == OPT_UINT8_TYPE) {
- if (array_type_) {
- return (factoryGeneric(u, type, begin, end));
- } else {
- return (factoryInteger<uint8_t>(u, type, begin, end));
- }
+ case OPT_INT32_TYPE:
+ return (array_type_ ? factoryIntegerArray<uint32_t>(type, begin, end) :
+ factoryInteger<int32_t>(u, type, begin, end));
- } else if (type_ == OPT_UINT16_TYPE) {
+ case OPT_IPV4_ADDRESS_TYPE:
if (array_type_) {
- return (factoryIntegerArray<uint16_t>(type, begin, end));
- } else {
- return (factoryInteger<uint16_t>(u, type, begin, end));
+ return (factoryAddrList4(type, begin, end));
}
+ break;
- } else if (type_ == OPT_UINT32_TYPE) {
+ case OPT_IPV6_ADDRESS_TYPE:
if (array_type_) {
- return (factoryIntegerArray<uint32_t>(type, begin, end));
- } else {
- return (factoryInteger<uint32_t>(u, type, begin, end));
+ return (factoryAddrList6(type, begin, end));
+ }
+ break;
+
+ default:
+ if (u == Option::V6 &&
+ (code_ == D6O_IA_NA || code_ == D6O_IA_PD) &&
+ haveIA6Format()) {
+ return (factoryIA6(type, begin, end));
+
+ } else if (u == Option::V6 &&
+ code_ == D6O_IAADDR &&
+ haveIAAddr6Format()) {
+ return (factoryIAAddr6(type, begin, end));
}
-
}
- return (factoryGeneric(u, type, begin, end));
+ return (OptionPtr(new OptionCustom(*this, u, begin, end)));
} catch (const Exception& ex) {
isc_throw(InvalidOptionValue, ex.what());
diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc
index 7fcd3b7a32..d65d4a8b0b 100644
--- a/src/lib/dhcp/tests/libdhcp++_unittest.cc
+++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc
@@ -22,6 +22,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int.h>
#include <dhcp/option6_int_array.h>
+#include <dhcp/option_custom.h>
#include <util/buffer.h>
#include <gtest/gtest.h>
@@ -90,13 +91,15 @@ public:
ASSERT_NO_THROW(def->validate());
OptionPtr option;
// Create the option.
- ASSERT_NO_THROW(option = def->optionFactory(Option::V6, code, buf));
+ ASSERT_NO_THROW(option = def->optionFactory(Option::V6, code, buf))
+ << "Option creation failed to option code " << code;
// Make sure it is not NULL.
ASSERT_TRUE(option);
// And the actual object type is the one that we expect.
// Note that for many options there are dedicated classes
// derived from Option class to represent them.
- EXPECT_TRUE(typeid(*option) == expected_type);
+ EXPECT_TRUE(typeid(*option) == expected_type)
+ << "Invalid class returned for option code " << code;
}
};
@@ -399,29 +402,148 @@ TEST_F(LibDhcpTest, unpackOptions4) {
// This test have to be extended once all option definitions are
// created.
TEST_F(LibDhcpTest, stdOptionDefs6) {
- LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, OptionBuffer(14, 1),
- typeid(Option));
- LibDhcpTest::testStdOptionDefs6(D6O_SERVERID, OptionBuffer(14, 1),
- typeid(Option));
- LibDhcpTest::testStdOptionDefs6(D6O_IA_NA, OptionBuffer(12, 1),
- typeid(Option6IA));
- LibDhcpTest::testStdOptionDefs6(D6O_IA_TA, OptionBuffer(4, 1),
+
+ // Create a buffer that holds dummy option data.
+ // It will be used to create most of the options.
+ std::vector<uint8_t> buf(48, 1);
+
+ // Prepare buffer holding an array of FQDNs.
+ const char data[] = {
+ 8, 109, 121, 100, 111, 109, 97, 105, 110, // "mydomain"
+ 7, 101, 120, 97, 109, 112, 108, 101, // "example"
+ 3, 99, 111, 109, // "com"
+ 0,
+ 7, 101, 120, 97, 109, 112, 108, 101, // "example"
+ 3, 99, 111, 109, // "com"
+ 0
+ };
+ // Initialize a vector with the FQDN data.
+ std::vector<uint8_t> fqdn_buf(data, data + sizeof(data));
+
+ // The CLIENT_FQDN holds a uint8_t value and FQDN. We have
+ // to add the uint8_t value to it and then append the buffer
+ // holding some valid FQDN.
+ std::vector<uint8_t> client_fqdn_buf(1);
+ client_fqdn_buf.insert(client_fqdn_buf.end(), fqdn_buf.begin(),
+ fqdn_buf.end());
+
+ // The actual test starts here for all supported option codes.
+ LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_SERVERID, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_IA_NA, buf, typeid(Option6IA));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_IA_TA, buf,
typeid(Option6Int<uint32_t>));
- LibDhcpTest::testStdOptionDefs6(D6O_IAADDR, OptionBuffer(24, 1),
- typeid(Option6IAAddr));
- LibDhcpTest::testStdOptionDefs6(D6O_ORO, OptionBuffer(10, 1),
+
+ LibDhcpTest::testStdOptionDefs6(D6O_IAADDR, buf, typeid(Option6IAAddr));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_ORO, buf,
typeid(Option6IntArray<uint16_t>));
- LibDhcpTest::testStdOptionDefs6(D6O_PREFERENCE, OptionBuffer(1, 1),
+
+ LibDhcpTest::testStdOptionDefs6(D6O_PREFERENCE, buf,
typeid(Option6Int<uint8_t>));
- LibDhcpTest::testStdOptionDefs6(D6O_ELAPSED_TIME, OptionBuffer(2, 1),
+
+ LibDhcpTest::testStdOptionDefs6(D6O_ELAPSED_TIME, buf,
typeid(Option6Int<uint16_t>));
- LibDhcpTest::testStdOptionDefs6(D6O_RELAY_MSG, OptionBuffer(30, 1),
- typeid(Option));
- LibDhcpTest::testStdOptionDefs6(D6O_STATUS_CODE, OptionBuffer(10, 1),
- typeid(Option));
- LibDhcpTest::testStdOptionDefs6(D6O_RAPID_COMMIT, OptionBuffer(),
- typeid(Option));
- LibDhcpTest::testStdOptionDefs6(D6O_NAME_SERVERS, OptionBuffer(32, 1),
+
+ LibDhcpTest::testStdOptionDefs6(D6O_RELAY_MSG, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_STATUS_CODE, buf, typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_RAPID_COMMIT, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_USER_CLASS, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_CLASS, buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_OPTS, buf, typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_INTERFACE_ID, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_RECONF_MSG, buf,
+ typeid(Option6Int<uint8_t>));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_RECONF_ACCEPT, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_SIP_SERVERS_DNS, fqdn_buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_SIP_SERVERS_ADDR, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NAME_SERVERS, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_DOMAIN_SEARCH, fqdn_buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_IA_PD, buf, typeid(Option6IA));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_IAPREFIX, buf, typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NIS_SERVERS, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NISP_SERVERS, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NIS_DOMAIN_NAME, fqdn_buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NISP_DOMAIN_NAME, fqdn_buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_SNTP_SERVERS, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_INFORMATION_REFRESH_TIME,
+ buf, typeid(Option6Int<uint32_t>));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_BCMCS_SERVER_D, fqdn_buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_BCMCS_SERVER_A, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_GEOCONF_CIVIC, buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_REMOTE_ID, buf, typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_SUBSCRIBER_ID, buf,typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_CLIENT_FQDN, client_fqdn_buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_PANA_AGENT, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_PANA_AGENT, buf,
+ typeid(Option6AddrLst));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NEW_POSIX_TIMEZONE, buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_NEW_TZDB_TIMEZONE, buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_ERO, buf,
+ typeid(Option6IntArray<uint16_t>));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_LQ_QUERY, buf, typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_CLIENT_DATA, buf, typeid(Option));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_CLT_TIME, buf,
+ typeid(Option6Int<uint32_t>));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_LQ_RELAY_DATA, buf,
+ typeid(OptionCustom));
+
+ LibDhcpTest::testStdOptionDefs6(D6O_LQ_CLIENT_LINK, buf,
typeid(Option6AddrLst));
}
diff --git a/src/lib/dhcp/tests/option_definition_unittest.cc b/src/lib/dhcp/tests/option_definition_unittest.cc
index 20c87d6203..91b822c3cd 100644
--- a/src/lib/dhcp/tests/option_definition_unittest.cc
+++ b/src/lib/dhcp/tests/option_definition_unittest.cc
@@ -23,6 +23,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int.h>
#include <dhcp/option6_int_array.h>
+#include <dhcp/option_custom.h>
#include <dhcp/option_definition.h>
#include <exceptions/exceptions.h>
@@ -883,7 +884,7 @@ TEST_F(OptionDefinitionTest, utf8StringTokenized) {
option_v6 = opt_def.optionFactory(Option::V6, opt_code, values);
);
ASSERT_TRUE(option_v6);
- ASSERT_TRUE(typeid(*option_v6) == typeid(Option));
+ ASSERT_TRUE(typeid(*option_v6) == typeid(OptionCustom));
std::vector<uint8_t> data = option_v6->getData();
std::vector<uint8_t> ref_data(values[0].c_str(), values[0].c_str()
+ values[0].length());