#include <dhcp/option6_iaaddr.h>
#include <dhcp/option_definition.h>
#include <dhcp/option_int_array.h>
-#include <dhcp/option_space.h>
#include <dhcp/std_option_defs.h>
#include <dhcp/docsis3_option_defs.h>
#include <exceptions/exceptions.h>
using namespace isc::dhcp;
using namespace isc::util;
+namespace isc {
+namespace dhcp {
+
+namespace {
+
+const OptionDefParamsEncapsulation OPTION_DEF_PARAMS[] = {
+ { STANDARD_V4_OPTION_DEFINITIONS, STANDARD_V4_OPTION_DEFINITIONS_SIZE, DHCP4_OPTION_SPACE },
+ { STANDARD_V6_OPTION_DEFINITIONS, STANDARD_V6_OPTION_DEFINITIONS_SIZE, DHCP6_OPTION_SPACE },
+ { DOCSIS3_V4_DEFS, DOCSIS3_V4_DEFS_SIZE, DOCSIS3_V4_OPTION_SPACE },
+ { DOCSIS3_V6_DEFS, DOCSIS3_V6_DEFS_SIZE, DOCSIS3_V6_OPTION_SPACE },
+ { ISC_V6_OPTION_DEFINITIONS, ISC_V6_OPTION_DEFINITIONS_SIZE, ISC_V6_OPTION_SPACE },
+ { MAPE_V6_OPTION_DEFINITIONS, MAPE_V6_OPTION_DEFINITIONS_SIZE, MAPE_V6_OPTION_SPACE },
+ { MAPT_V6_OPTION_DEFINITIONS, MAPT_V6_OPTION_DEFINITIONS_SIZE, MAPT_V6_OPTION_SPACE },
+ { LW_V6_OPTION_DEFINITIONS, LW_V6_OPTION_DEFINITIONS_SIZE, LW_V6_OPTION_SPACE },
+ { V4V6_RULE_OPTION_DEFINITIONS, V4V6_RULE_OPTION_DEFINITIONS_SIZE, V4V6_RULE_OPTION_SPACE },
+ { V4V6_BIND_OPTION_DEFINITIONS, V4V6_BIND_OPTION_DEFINITIONS_SIZE, V4V6_BIND_OPTION_SPACE },
+ { LAST_RESORT_V4_OPTION_DEFINITIONS, LAST_RESORT_V4_OPTION_DEFINITIONS_SIZE, LAST_RESORT_V4_OPTION_SPACE },
+ { NULL, 0, "" }
+};
+
+} // namespace
+
+} // namespace dhcp
+} // namespace isc
+
// static array with factories for options
std::map<unsigned short, Option::Factory*> LibDHCP::v4factories_;
// static array with factories for options
std::map<unsigned short, Option::Factory*> LibDHCP::v6factories_;
-// Static container with DHCPv4 option definitions.
-OptionDefContainerPtr LibDHCP::v4option_defs_(new OptionDefContainer());
-
-// Static container with DHCPv6 option definitions.
-OptionDefContainerPtr LibDHCP::v6option_defs_(new OptionDefContainer());
-
// Static container with option definitions grouped by option space.
OptionDefContainers LibDHCP::option_defs_;
-// Static container with vendor option definitions for DHCPv4.
-VendorOptionDefContainers LibDHCP::vendor4_defs_;
-
-// Static container with vendor option definitions for DHCPv6.
-VendorOptionDefContainers LibDHCP::vendor6_defs_;
-
-// Static container with last resort option definitions for DHCPv4.
-OptionDefContainerPtr LibDHCP::lastresort_defs_(new OptionDefContainer());
-
// Static container with option definitions created in runtime.
StagedValue<OptionDefSpaceContainer> LibDHCP::runtime_option_defs_;
LibDHCP::getOptionDefs(const std::string& space) {
// If any of the containers is not initialized, it means that we haven't
// initialized option definitions at all.
- if (v4option_defs_->empty()) {
- initStdOptionDefs4();
- initVendorOptsDocsis4();
- initStdOptionDefs6();
- initVendorOptsDocsis6();
- initLastResortOptionDefs();
- }
-
- if (space == DHCP4_OPTION_SPACE) {
- return (v4option_defs_);
-
- } else if (space == DHCP6_OPTION_SPACE) {
- return (v6option_defs_);
+ if (option_defs_.end() == option_defs_.find(space)) {
+ initStdOptionDefs(space);
}
OptionDefContainers::const_iterator container = option_defs_.find(space);
return (null_option_def_container_);
}
-const OptionDefContainerPtr&
-LibDHCP::getVendorOption4Defs(const uint32_t vendor_id) {
-
- if (vendor_id == VENDOR_ID_CABLE_LABS &&
- vendor4_defs_.find(VENDOR_ID_CABLE_LABS) == vendor4_defs_.end()) {
- initVendorOptsDocsis4();
- }
-
- VendorOptionDefContainers::const_iterator def = vendor4_defs_.find(vendor_id);
- if (def == vendor4_defs_.end()) {
- // No such vendor-id space
- return (null_option_def_container_);
- }
- return (def->second);
-}
-
-const OptionDefContainerPtr&
-LibDHCP::getVendorOption6Defs(const uint32_t vendor_id) {
-
- if (vendor_id == VENDOR_ID_CABLE_LABS &&
- vendor6_defs_.find(VENDOR_ID_CABLE_LABS) == vendor6_defs_.end()) {
- initVendorOptsDocsis6();
- }
-
- if (vendor_id == ENTERPRISE_ID_ISC &&
- vendor6_defs_.find(ENTERPRISE_ID_ISC) == vendor6_defs_.end()) {
- initVendorOptsIsc6();
- }
-
- VendorOptionDefContainers::const_iterator def = vendor6_defs_.find(vendor_id);
- if (def == vendor6_defs_.end()) {
- // No such vendor-id space
- return (null_option_def_container_);
+const OptionDefContainerPtr
+LibDHCP::getVendorOptionDefs(const Option::Universe u, const uint32_t vendor_id) {
+ if (Option::V4 == u) {
+ if (VENDOR_ID_CABLE_LABS == vendor_id) {
+ return getOptionDefs(DOCSIS3_V4_OPTION_SPACE);
+ }
+ } else if (Option::V6 == u) {
+ if (VENDOR_ID_CABLE_LABS == vendor_id) {
+ return getOptionDefs(DOCSIS3_V6_OPTION_SPACE);
+ } else if (ENTERPRISE_ID_ISC == vendor_id) {
+ return getOptionDefs(ISC_V6_OPTION_SPACE);
+ }
}
- return (def->second);
+ return (null_option_def_container_);
}
OptionDefinitionPtr
OptionDefinitionPtr
LibDHCP::getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id,
const std::string& name) {
- OptionDefContainerPtr defs = (u == Option::V4 ? getVendorOption4Defs(vendor_id) :
- getVendorOption6Defs(vendor_id));
+ const OptionDefContainerPtr option_defs_ptr = getVendorOptionDefs(u, vendor_id);
- if (!defs) {
+ if (!option_defs_ptr) {
return (OptionDefinitionPtr());
}
- const OptionDefContainerNameIndex& idx = defs->get<2>();
+ const OptionDefContainerNameIndex& idx = option_defs_ptr->get<2>();
const OptionDefContainerNameRange& range = idx.equal_range(name);
if (range.first != range.second) {
return (*range.first);
OptionDefinitionPtr
LibDHCP::getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id,
const uint16_t code) {
- OptionDefContainerPtr defs = (u == Option::V4 ? getVendorOption4Defs(vendor_id) :
- getVendorOption6Defs(vendor_id));
+ const OptionDefContainerPtr option_defs_ptr = getVendorOptionDefs(u, vendor_id);
- if (!defs) {
+ if (!option_defs_ptr) {
// Weird universe or unknown vendor_id. We don't care. No definitions
// one way or another
// What is it anyway?
return (OptionDefinitionPtr());
}
- const OptionDefContainerTypeIndex& idx = defs->get<1>();
+ const OptionDefContainerTypeIndex& idx = option_defs_ptr->get<1>();
const OptionDefContainerTypeRange& range = idx.equal_range(code);
if (range.first != range.second) {
return (*range.first);
OptionDefContainerPtr
LibDHCP::getLastResortOptionDefs(const std::string& space) {
if (space == DHCP4_OPTION_SPACE) {
- return (lastresort_defs_);
+ return getOptionDefs(LAST_RESORT_V4_OPTION_SPACE);
}
return (null_option_def_container_);
}
size_t length = buf.size();
// Get the list of option definitions for this particular vendor-id
- const OptionDefContainerPtr& option_defs = LibDHCP::getVendorOption6Defs(vendor_id);
+ const OptionDefContainerPtr option_defs_ptr =
+ LibDHCP::getVendorOptionDefs(Option::V6, vendor_id);
// Get the search index #1. It allows to search for option definitions
// using option code. If there's no such vendor-id space, we're out of luck
// anyway.
const OptionDefContainerTypeIndex* idx = NULL;
- if (option_defs) {
- idx = &(option_defs->get<1>());
+ if (option_defs_ptr) {
+ idx = &(option_defs_ptr->get<1>());
}
// The buffer being read comprises a set of options, each starting with
size_t offset = 0;
// Get the list of standard option definitions.
- const OptionDefContainerPtr& option_defs = LibDHCP::getVendorOption4Defs(vendor_id);
+ const OptionDefContainerPtr option_defs_ptr =
+ LibDHCP::getVendorOptionDefs(Option::V4, vendor_id);
// Get the search index #1. It allows to search for option definitions
// using option code.
const OptionDefContainerTypeIndex* idx = NULL;
- if (option_defs) {
- idx = &(option_defs->get<1>());
+ if (option_defs_ptr) {
+ idx = &(option_defs_ptr->get<1>());
}
// The buffer being read comprises a set of options, each starting with
options.insert(std::make_pair(opt_type, opt));
offset += opt_len;
- } // end of data-chunk
+ } // end of data-chunk
break; // end of the vendor block.
}
return;
}
-void
-LibDHCP::initStdOptionDefs4() {
- initOptionSpace(v4option_defs_, STANDARD_V4_OPTION_DEFINITIONS,
- STANDARD_V4_OPTION_DEFINITIONS_SIZE);
-}
-
-void
-LibDHCP::initStdOptionDefs6() {
- initOptionSpace(v6option_defs_, STANDARD_V6_OPTION_DEFINITIONS,
- STANDARD_V6_OPTION_DEFINITIONS_SIZE);
- initOptionSpace(option_defs_[MAPE_V6_OPTION_SPACE], MAPE_V6_OPTION_DEFINITIONS,
- MAPE_V6_OPTION_DEFINITIONS_SIZE);
- initOptionSpace(option_defs_[MAPT_V6_OPTION_SPACE], MAPT_V6_OPTION_DEFINITIONS,
- MAPT_V6_OPTION_DEFINITIONS_SIZE);
- initOptionSpace(option_defs_[LW_V6_OPTION_SPACE], LW_V6_OPTION_DEFINITIONS,
- LW_V6_OPTION_DEFINITIONS_SIZE);
- initOptionSpace(option_defs_[V4V6_RULE_OPTION_SPACE], V4V6_RULE_OPTION_DEFINITIONS,
- V4V6_RULE_OPTION_DEFINITIONS_SIZE);
- initOptionSpace(option_defs_[V4V6_BIND_OPTION_SPACE], V4V6_BIND_OPTION_DEFINITIONS,
- V4V6_BIND_OPTION_DEFINITIONS_SIZE);
-}
-
-void
-LibDHCP::initLastResortOptionDefs() {
- initOptionSpace(lastresort_defs_, LAST_RESORT_V4_OPTION_DEFINITIONS,
- LAST_RESORT_V4_OPTION_DEFINITIONS_SIZE);
-}
-
-void
-LibDHCP::initVendorOptsDocsis4() {
- initOptionSpace(vendor4_defs_[VENDOR_ID_CABLE_LABS], DOCSIS3_V4_DEFS,
- DOCSIS3_V4_DEFS_SIZE);
-}
-
-void
-LibDHCP::initVendorOptsDocsis6() {
- initOptionSpace(vendor6_defs_[VENDOR_ID_CABLE_LABS], DOCSIS3_V6_DEFS,
- DOCSIS3_V6_DEFS_SIZE);
-}
-
-void
-LibDHCP::initVendorOptsIsc6() {
- initOptionSpace(vendor6_defs_[ENTERPRISE_ID_ISC], ISC_V6_OPTION_DEFINITIONS,
- ISC_V6_OPTION_DEFINITIONS_SIZE);
+void LibDHCP::initStdOptionDefs(const std::string &space) {
+ if (option_defs_.end() == option_defs_.find(space)) {
+ option_defs_[space] = OptionDefContainerPtr(new OptionDefContainer);
+ for (int i = 0; OPTION_DEF_PARAMS[i].optionDefParams; i++) {
+ if (space == OPTION_DEF_PARAMS[i].space) {
+ initOptionSpace(option_defs_[space], OPTION_DEF_PARAMS[i].optionDefParams, OPTION_DEF_PARAMS[i].size);
+ break;
+ }
+ }
+ }
}
uint32_t
#include <dhcp/option_definition.h>
#include <dhcp/option_space_container.h>
+#include <dhcp/option_space.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#include <util/buffer.h>
uint16_t type,
Option::Factory * factory);
- /// @brief Returns v4 option definitions for a given vendor
+ /// @brief Returns option definitions for given universe and vendor
///
+ /// @param u option universe
/// @param vendor_id enterprise-id of a given vendor
- /// @return a container for a given vendor (or NULL if no option
- /// definitions are defined)
- static const OptionDefContainerPtr&
- getVendorOption4Defs(const uint32_t vendor_id);
-
- /// @brief Returns v6 option definitions for a given vendor
///
- /// @param vendor_id enterprise-id of a given vendor
/// @return a container for a given vendor (or NULL if no option
/// definitions are defined)
- static const OptionDefContainerPtr&
- getVendorOption6Defs(const uint32_t vendor_id);
+ static const OptionDefContainerPtr
+ getVendorOptionDefs(Option::Universe u, const uint32_t vendor_id);
/// @brief Parses provided buffer as DHCPv6 vendor options and creates
/// Option objects.
private:
- /// Initialize standard DHCPv4 option definitions.
+ /// Initialize DHCP option definitions.
///
- /// The method creates option definitions for all DHCPv4 options.
- /// Currently this function is not implemented.
+ /// The method creates option definitions for all DHCP options.
///
/// @throw std::bad alloc if system went out of memory.
/// @throw MalformedOptionDefinition if any of the definitions
/// are incorrect. This is programming error.
- static void initStdOptionDefs4();
-
- /// Initialize standard DHCPv6 option definitions.
- ///
- /// The method creates option definitions for all DHCPv6 options.
- ///
- /// @throw std::bad_alloc if system went out of memory.
- /// @throw MalformedOptionDefinition if any of the definitions
- /// is incorrect. This is a programming error.
- static void initStdOptionDefs6();
-
- /// Initialize last resort DHCPv4 option definitions.
- static void initLastResortOptionDefs();
-
- /// Initialize DOCSIS DHCPv4 option definitions.
- static void initVendorOptsDocsis4();
-
- /// Initialize DOCSIS DHCPv6 option definitions.
- static void initVendorOptsDocsis6();
-
- /// Initialize private DHCPv6 option definitions.
- static void initVendorOptsIsc6();
+ static void initStdOptionDefs(const std::string& space);
/// pointers to factories that produce DHCPv6 options
static FactoryMap v4factories_;
/// pointers to factories that produce DHCPv6 options
static FactoryMap v6factories_;
- /// Container with DHCPv4 option definitions.
- static OptionDefContainerPtr v4option_defs_;
-
- /// Container with DHCPv6 option definitions.
- static OptionDefContainerPtr v6option_defs_;
/// Container that holds option definitions for various option spaces.
static OptionDefContainers option_defs_;
- /// Container for v4 vendor option definitions
- static VendorOptionDefContainers vendor4_defs_;
-
- /// Container for v6 vendor option definitions
- static VendorOptionDefContainers vendor6_defs_;
-
- /// Container with DHCPv4 last resort option definitions.
- static OptionDefContainerPtr lastresort_defs_;
-
/// Container for additional option definitions created in runtime.
static util::StagedValue<OptionDefSpaceContainer> runtime_option_defs_;
};
#include <dhcp/option_int.h>
#include <dhcp/option_int_array.h>
#include <dhcp/option_opaque_data_tuples.h>
-#include <dhcp/option_space.h>
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcp/option_vendor_class.h>
EXPECT_NO_THROW ({
LibDHCP::unpackOptions6(OptionBuffer(buf.begin(), buf.begin() + sizeof(v6packed)),
- "dhcp6", options);
+ DHCP6_OPTION_SPACE, options);
});
EXPECT_EQ(options.size(), 6); // there should be 5 options
list<uint16_t> deferred;
ASSERT_NO_THROW(
- LibDHCP::unpackOptions4(v4packed, "dhcp4", options, deferred);
+ LibDHCP::unpackOptions4(v4packed, DHCP4_OPTION_SPACE, options, deferred);
);
isc::dhcp::OptionCollection::const_iterator x = options.find(12);
// This test checks if the definition of the DHCPv6 vendor option can
// be searched by option name.
TEST_F(LibDhcpTest, getVendorOptionDefByName6) {
- const OptionDefContainerPtr& defs =
- LibDHCP::getVendorOption6Defs(VENDOR_ID_CABLE_LABS);
+ const OptionDefContainerPtr defs =
+ LibDHCP::getVendorOptionDefs(Option::V6, VENDOR_ID_CABLE_LABS);
ASSERT_TRUE(defs);
for (OptionDefContainer::const_iterator def = defs->begin();
def != defs->end(); ++def) {
// This test checks if the definition of the DHCPv4 vendor option can
// be searched by option name.
TEST_F(LibDhcpTest, getVendorOptionDefByName4) {
- const OptionDefContainerPtr& defs =
- LibDHCP::getVendorOption4Defs(VENDOR_ID_CABLE_LABS);
+ const OptionDefContainerPtr defs =
+ LibDHCP::getVendorOptionDefs(Option::V4, VENDOR_ID_CABLE_LABS);
ASSERT_TRUE(defs);
for (OptionDefContainer::const_iterator def = defs->begin();
def != defs->end(); ++def) {
isc::util::encode::decodeHex(vendor_class_hex, bin);
ASSERT_NO_THROW ({
- LibDHCP::unpackOptions6(bin, "dhcp6", options);
+ LibDHCP::unpackOptions6(bin, DHCP6_OPTION_SPACE, options);
});
EXPECT_EQ(options.size(), 1); // There should be 1 option.
OptionBuffer buf(mape_bin);
- size_t parsed;
+ size_t parsed = 0;
EXPECT_NO_THROW (parsed = LibDHCP::unpackOptions6(buf, "dhcp6", options));
EXPECT_EQ(mape_bin.size(), parsed);
EXPECT_EQ("type=00093, len=00004: 8 (uint8) len=6,psid=63 (psid)", portparam->toText());
}
-} // end of anonymous space
+} // end of anonymous space