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

[2491] Create Status Code option using an option definition.

This commit is contained in:
Marcin Siodelski
2012-12-03 16:55:16 +01:00
parent a0662ae560
commit 372f3a19f5
5 changed files with 41 additions and 14 deletions

View File

@@ -24,6 +24,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int_array.h>
#include <dhcp/option_custom.h>
#include <dhcp/pkt6.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/dhcp6_srv.h>
@@ -348,13 +349,18 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer)
}
OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
OptionDefinitionPtr status_code_def =
LibDHCP::getOptionDef(Option::V6, D6O_STATUS_CODE);
assert(status_code_def);
// @todo: Implement Option6_StatusCode and rewrite this code here
vector<uint8_t> data(text.c_str(), text.c_str() + text.length());
data.insert(data.begin(), static_cast<uint8_t>(code % 256));
data.insert(data.begin(), static_cast<uint8_t>(code >> 8));
OptionPtr status(new Option(Option::V6, D6O_STATUS_CODE, data));
return (status);
boost::shared_ptr<OptionCustom> option_status =
boost::dynamic_pointer_cast<
OptionCustom>(status_code_def->optionFactory(Option::V6, D6O_STATUS_CODE));
assert(option_status);
option_status->writeInteger<uint16_t>(code, 0);
option_status->writeString(text, 1);
return (option_status);
}
Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {

View File

@@ -801,12 +801,23 @@ TEST_F(Dhcpv6SrvTest, StatusCode) {
ASSERT_NO_THROW( srv.reset(new NakedDhcpv6Srv(0)) );
// a dummy content for client-id
uint8_t expected[] = {0x0, 0x3, 0x41, 0x42, 0x43, 0x44, 0x45};
OptionBuffer exp(expected, expected + sizeof(expected));
uint8_t expected[] = {
0x0, 0xD, // option code = 14
0x0, 0x7, // option length = 7
0x0, 0x3, // status code = 3
0x41, 0x42, 0x43, 0x44, 0x45 // string value ABCDE
};
// Create the option.
OptionPtr status = srv->createStatusCode(3, "ABCDE");
EXPECT_TRUE(status->getData() == exp);
// Allocate an output buffer. We will store the option
// in wire format here.
OutputBuffer buf(sizeof(expected));
// Prepare the wire format.
ASSERT_NO_THROW(status->pack(buf));
// Check that the option buffer has valid length (option header + data).
ASSERT_EQ(sizeof(expected), buf.getLength());
// Verify the contents of the option.
EXPECT_EQ(0, memcmp(expected, buf.getData(), sizeof(expected)));
}
// This test verifies if the selectSubnet() method works as expected.

View File

@@ -32,7 +32,17 @@ OptionCustom::OptionCustom(const OptionDefinition& def,
const OptionBuffer& data)
: Option(u, def.getCode(), data.begin(), data.end()),
definition_(def) {
createBuffers(data_);
// It is possible that no data is provided if an option
// is being created on a server side. In such case a bunch
// of buffers with default values is first created and then
// the values are replaced using writeXXX functions. Thus
// we need to detect that no data has been specified and
// take a different code path.
if (!data_.empty()) {
createBuffers(data_);
} else {
createBuffers();
}
}
OptionCustom::OptionCustom(const OptionDefinition& def,

View File

@@ -136,7 +136,7 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
return (factoryIAAddr6(type, begin, end));
}
}
return (OptionPtr(new OptionCustom(*this, u, begin, end)));
return (OptionPtr(new OptionCustom(*this, u, OptionBuffer(begin, end))));
} catch (const Exception& ex) {
isc_throw(InvalidOptionValue, ex.what());

View File

@@ -246,7 +246,7 @@ public:
/// @throw MalformedOptionDefinition if option definition is invalid.
/// @throw InvalidOptionValue if data for the option is invalid.
OptionPtr optionFactory(Option::Universe u, uint16_t type,
const OptionBuffer& buf) const;
const OptionBuffer& buf = OptionBuffer()) const;
/// @brief Option factory.
///