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:
@@ -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) {
|
||||
|
@@ -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.
|
||||
|
@@ -32,7 +32,17 @@ OptionCustom::OptionCustom(const OptionDefinition& def,
|
||||
const OptionBuffer& data)
|
||||
: Option(u, def.getCode(), data.begin(), data.end()),
|
||||
definition_(def) {
|
||||
// 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,
|
||||
|
@@ -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());
|
||||
|
@@ -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.
|
||||
///
|
||||
|
Reference in New Issue
Block a user