Commit 20784067 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3316] Use OptionVendorClass to encapsulate DHCPv6 option 16.

parent ce6bedc1
......@@ -1759,8 +1759,8 @@ TEST_F(Dhcpv6SrvTest, cableLabsShortVendorClass) {
Pkt6Ptr adv = srv.fake_sent_.front();
ASSERT_TRUE(adv);
// This is sent back to relay, so port is 547
EXPECT_EQ(DHCP6_SERVER_PORT, adv->getRemotePort());
// This is sent back to client, so port is 546
EXPECT_EQ(DHCP6_CLIENT_PORT, adv->getRemotePort());
}
......
......@@ -28,6 +28,7 @@
#include <dhcp/option_space.h>
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcp/option_vendor_class.h>
#include <util/encode/hex.h>
#include <util/strutil.h>
#include <boost/algorithm/string/classification.hpp>
......@@ -399,6 +400,14 @@ OptionDefinition::haveVendor6Format() const {
return (getType() == OPT_UINT32_TYPE && !getEncapsulatedSpace().empty());
}
bool
OptionDefinition::haveVendorClass6Format() const {
return (haveType(OPT_RECORD_TYPE) &&
(record_fields_.size() == 2) &&
(record_fields_[0] == OPT_UINT32_TYPE) &&
(record_fields_[1] == OPT_BINARY_TYPE));
}
bool
OptionDefinition::convertToBool(const std::string& value_str) const {
// Case insensitve check that the input is one of: "true" or "false".
......@@ -653,6 +662,9 @@ OptionDefinition::factorySpecialFormatOption(Option::Universe u,
} else if (getCode() == D6O_VENDOR_OPTS && haveVendor6Format()) {
// Vendor-Specific Information.
return (OptionPtr(new OptionVendor(Option::V6, begin, end)));
} else if (getCode() == D6O_VENDOR_CLASS && haveVendorClass6Format()) {
// Vendor Class.
return (OptionPtr(new OptionVendorClass(Option::V6, begin, end)));
}
} else {
if ((getCode() == DHO_FQDN) && haveFqdn4Format()) {
......
......@@ -324,6 +324,11 @@ public:
/// Vendor-Specific Information %Option.
bool haveVendor6Format() const;
/// @brief Check if the option has format of DHCPv6 Vendor Class option.
///
/// @return true if option has the format of DHCPv6 Vendor Class option.
bool haveVendorClass6Format() const;
/// @brief Option factory.
///
/// This function creates an instance of DHCP option using
......
......@@ -230,8 +230,7 @@ RECORD_DECL(REMOTE_ID_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE);
// status-code
RECORD_DECL(STATUS_CODE_RECORDS, OPT_UINT16_TYPE, OPT_STRING_TYPE);
// vendor-class
RECORD_DECL(VENDOR_CLASS_RECORDS, OPT_UINT32_TYPE, OPT_UINT16_TYPE,
OPT_STRING_TYPE);
RECORD_DECL(VENDOR_CLASS_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE);
/// Standard DHCPv6 option definitions.
///
......
......@@ -29,6 +29,7 @@
#include <dhcp/option_int_array.h>
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcp/option_vendor_class.h>
#include <util/buffer.h>
#include <util/encode/hex.h>
......@@ -981,6 +982,14 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
client_fqdn_buf.insert(client_fqdn_buf.end(), fqdn_buf.begin(),
fqdn_buf.end());
// Initialize test buffer for Vendor Class option.
const char vclass_data[] = {
0x00, 0x01, 0x02, 0x03,
0x00, 0x01, 0x02
};
std::vector<uint8_t> vclass_buf(vclass_data,
vclass_data + sizeof(vclass_data));;
// The actual test starts here for all supported option codes.
LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, begin, end,
typeid(Option));
......@@ -1018,8 +1027,9 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
LibDhcpTest::testStdOptionDefs6(D6O_USER_CLASS, begin, end,
typeid(Option));
LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_CLASS, begin, end,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_CLASS, vclass_buf.begin(),
vclass_buf.end(),
typeid(OptionVendorClass));
LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_OPTS, begin, end,
typeid(OptionVendor),
......@@ -1148,22 +1158,18 @@ TEST_F(LibDhcpTest, vendorClass6) {
// Option vendor-class should be there
ASSERT_FALSE(options.find(D6O_VENDOR_CLASS) == options.end());
// It should be of type OptionCustom
boost::shared_ptr<OptionCustom> vclass =
boost::dynamic_pointer_cast<OptionCustom> (options.begin()->second);
// It should be of type OptionVendorClass
boost::shared_ptr<OptionVendorClass> vclass =
boost::dynamic_pointer_cast<OptionVendorClass>(options.begin()->second);
ASSERT_TRUE(vclass);
// Let's investigate if the option content is correct
// 3 fields expected: vendor-id, data-len and data
ASSERT_EQ(3, vclass->getDataFieldsNum());
EXPECT_EQ(4491, vclass->readInteger<uint32_t>
(VENDOR_CLASS_ENTERPRISE_ID_INDEX)); // vendor-id=4491
EXPECT_EQ(10, vclass->readInteger<uint16_t>
(VENDOR_CLASS_DATA_LEN_INDEX)); // data len = 10
EXPECT_EQ("eRouter1.0", vclass->readString
(VENDOR_CLASS_STRING_INDEX)); // data="eRouter1.0"
EXPECT_EQ(4491, vclass->getVendorId());
EXPECT_EQ(20, vclass->len());
ASSERT_EQ(1, vclass->getTuplesNum());
EXPECT_EQ("eRouter1.0", vclass->getTuple(0).getText());
}
} // end of anonymous space
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment