#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>
}
OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
-
- // @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);
+ OptionDefinitionPtr status_code_def =
+ LibDHCP::getOptionDef(Option::V6, D6O_STATUS_CODE);
+ assert(status_code_def);
+
+ 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) {
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.
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,
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());
/// @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.
///