Commit 37a27e19 authored by Marcin Siodelski's avatar Marcin Siodelski

[master] Merge branch 'trac2313'

Conflicts:
	src/lib/dhcpsrv/cfgmgr.cc
	src/lib/dhcpsrv/cfgmgr.h
parents d365482e b3a9b362
......@@ -14,23 +14,23 @@ CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = libb10-dhcp++.la
libb10_dhcp___la_SOURCES =
libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h
libb10_dhcp___la_SOURCES += duid.cc duid.h
libb10_dhcp___la_SOURCES += iface_mgr.cc iface_mgr.h
libb10_dhcp___la_SOURCES += iface_mgr_bsd.cc
libb10_dhcp___la_SOURCES += iface_mgr_linux.cc
libb10_dhcp___la_SOURCES += iface_mgr_sun.cc
libb10_dhcp___la_SOURCES += libdhcp++.cc libdhcp++.h
libb10_dhcp___la_SOURCES += option.cc option.h
libb10_dhcp___la_SOURCES += option_data_types.cc option_data_types.h
libb10_dhcp___la_SOURCES += option_definition.cc option_definition.h
libb10_dhcp___la_SOURCES += option_custom.cc option_custom.h
libb10_dhcp___la_SOURCES += option4_addrlst.cc option4_addrlst.h
libb10_dhcp___la_SOURCES += option6_ia.cc option6_ia.h
libb10_dhcp___la_SOURCES += option6_iaaddr.cc option6_iaaddr.h
libb10_dhcp___la_SOURCES += option6_addrlst.cc option6_addrlst.h
libb10_dhcp___la_SOURCES += option4_addrlst.cc option4_addrlst.h
libb10_dhcp___la_SOURCES += option_int.h
libb10_dhcp___la_SOURCES += option_int_array.h
libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h
libb10_dhcp___la_SOURCES += option.cc option.h
libb10_dhcp___la_SOURCES += option_custom.cc option_custom.h
libb10_dhcp___la_SOURCES += option_data_types.cc option_data_types.h
libb10_dhcp___la_SOURCES += option_definition.cc option_definition.h
libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h
libb10_dhcp___la_SOURCES += pkt4.cc pkt4.h
libb10_dhcp___la_SOURCES += std_option_defs.h
......
......@@ -43,6 +43,7 @@ libb10_dhcpsrv_la_SOURCES += memfile_lease_mgr.cc memfile_lease_mgr.h
if HAVE_MYSQL
libb10_dhcpsrv_la_SOURCES += mysql_lease_mgr.cc mysql_lease_mgr.h
endif
libb10_dhcpsrv_la_SOURCES += option_space.cc option_space.h
libb10_dhcpsrv_la_SOURCES += pool.cc pool.h
libb10_dhcpsrv_la_SOURCES += subnet.cc subnet.h
libb10_dhcpsrv_la_SOURCES += triplet.h
......
......@@ -29,6 +29,36 @@ CfgMgr::instance() {
return (cfg_mgr);
}
void
CfgMgr::addOptionSpace4(const OptionSpacePtr& space) {
if (!space) {
isc_throw(InvalidOptionSpace,
"provided option space object is NULL.");
}
OptionSpaceCollection::iterator it = spaces4_.find(space->getName());
if (it != spaces4_.end()) {
isc_throw(InvalidOptionSpace, "option space " << space->getName()
<< " already added.");
}
spaces4_.insert(std::pair<std::string,
OptionSpacePtr>(space->getName(), space));
}
void
CfgMgr::addOptionSpace6(const OptionSpacePtr& space) {
if (!space) {
isc_throw(InvalidOptionSpace,
"provided option space object is NULL.");
}
OptionSpaceCollection::iterator it = spaces6_.find(space->getName());
if (it != spaces6_.end()) {
isc_throw(InvalidOptionSpace, "option space " << space->getName()
<< " already added.");
}
spaces6_.insert(std::pair<std::string,
OptionSpacePtr>(space->getName(), space));
}
void
CfgMgr::addOptionDef(const OptionDefinitionPtr& def,
const std::string& option_space) {
......
......@@ -18,6 +18,7 @@
#include <asiolink/io_address.h>
#include <dhcp/option.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/option_space.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/subnet.h>
#include <util/buffer.h>
......@@ -65,7 +66,6 @@ namespace dhcp {
/// Parameter inheritance is likely to be implemented in configuration handling
/// routines, so there is no storage capability in a global scope for
/// subnet-specific parameters.
///
/// @todo: Implement Subnet4 support (ticket #2237)
/// @todo: Implement option definition support
/// @todo: Implement parameter inheritance
......@@ -113,6 +113,36 @@ public:
OptionDefinitionPtr getOptionDef(const std::string& option_space,
const uint16_t option_code) const;
/// @brief Adds new DHCPv4 option space to the collection.
///
/// @param space option space to be added.
///
/// @throw isc::dhcp::InvalidOptionSpace invalid option space
/// has been specified.
void addOptionSpace4(const OptionSpacePtr& space);
/// @brief Adds new DHCPv6 option space to the collection.
///
/// @param space option space to be added.
///
/// @throw isc::dhcp::InvalidOptionSpace invalid option space
/// has been specified.
void addOptionSpace6(const OptionSpacePtr& space);
/// @brief Return option spaces for DHCPv4.
///
/// @return A collection of option spaces.
const OptionSpaceCollection& getOptionSpaces4() const {
return (spaces4_);
}
/// @brief Return option spaces for DHCPv6.
///
/// @return A collection of option spaces.
const OptionSpaceCollection& getOptionSpaces6() const {
return (spaces6_);
}
/// @brief get IPv6 subnet by address
///
/// Finds a matching subnet, based on an address. This can be used
......@@ -230,6 +260,12 @@ private:
/// The map key holds an option space name.
OptionDefsMap option_def_spaces_;
/// @brief Container for defined DHCPv6 option spaces.
OptionSpaceCollection spaces6_;
/// @brief Container for defined DHCPv4 option spaces.
OptionSpaceCollection spaces4_;
};
} // namespace isc::dhcp
......
// Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/option_space.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
namespace isc {
namespace dhcp {
OptionSpace::OptionSpace(const std::string& name, const bool vendor_space)
: name_(name), vendor_space_(vendor_space) {
// Check that provided option space name is valid.
if (!validateName(name_)) {
isc_throw(InvalidOptionSpace, "Invalid option space name "
<< name_);
}
}
bool
OptionSpace::validateName(const std::string& name) {
using namespace boost::algorithm;
// Allowed characters are: lower or upper case letters, digits,
// underscores and hyphens. Empty option spaces are not allowed.
if (all(name, boost::is_from_range('a', 'z') ||
boost::is_from_range('A', 'Z') ||
boost::is_digit() ||
boost::is_any_of("-_")) &&
!name.empty() &&
// Hyphens and underscores are not allowed at the beginning
// and at the end of the option space name.
!all(find_head(name, 1), boost::is_any_of("-_")) &&
!all(find_tail(name, 1), boost::is_any_of("-_"))) {
return (true);
}
return (false);
}
OptionSpace6::OptionSpace6(const std::string& name)
: OptionSpace(name),
enterprise_number_(0) {
}
OptionSpace6::OptionSpace6(const std::string& name,
const uint32_t enterprise_number)
: OptionSpace(name, true),
enterprise_number_(enterprise_number) {
}
void
OptionSpace6::setVendorSpace(const uint32_t enterprise_number) {
enterprise_number_ = enterprise_number;
OptionSpace::setVendorSpace();
}
} // end of isc::dhcp namespace
} // end of isc namespace
// Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef OPTION_SPACE_H
#define OPTION_SPACE_H
#include <exceptions/exceptions.h>
#include <boost/shared_ptr.hpp>
#include <map>
#include <stdint.h>
#include <string>
namespace isc {
namespace dhcp {
/// @brief Exception to be thrown when invalid option space
/// is specified.
class InvalidOptionSpace : public Exception {
public:
InvalidOptionSpace(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// OptionSpace forward declaration.
class OptionSpace;
/// A pointer to OptionSpace object.
typedef boost::shared_ptr<OptionSpace> OptionSpacePtr;
/// A collection of option spaces.
typedef std::map<std::string, OptionSpacePtr> OptionSpaceCollection;
/// @brief DHCP option space.
///
/// This class represents single option space. The option spaces are used
/// to group DHCP options having unique option codes. The special type
/// of the option space is so called "vendor specific option space".
/// It groups sub-options being sent within Vendor Encapsulated Options.
/// For DHCPv4 it is the option with code 43. The option spaces are
/// assigned to option instances represented by isc::dhcp::Option and
/// other classes derived from it. Each particular option may belong to
/// multiple option spaces.
/// This class may be used to represent any DHCPv4 option space. If the
/// option space is to group DHCPv4 Vendor Encapsulated Options then
/// "vendor space" flag must be set using \ref OptionSpace::setVendorSpace
/// or the argument passed to the constructor. In theory, this class can
/// be also used to represent non-vendor specific DHCPv6 option space
/// but this is discouraged. For DHCPv6 option spaces the OptionSpace6
/// class should be used instead.
///
/// @note this class is intended to be used to represent DHCPv4 option
/// spaces only. However, it hasn't been called OptionSpace4 (that would
/// suggest that it is specific to DHCPv4) because it can be also
/// used to represent some DHCPv6 option spaces and is a base class
/// for \ref OptionSpace6. Thus, if one declared the container as follows:
/// @code
/// std::vector<OptionSpace4> container;
/// @endcode
/// it would suggest that the container holds DHCPv4 option spaces while
/// it could hold both DHCPv4 and DHCPv6 option spaces as the OptionSpace6
/// object could be upcast to OptionSpace4. This confusion does not appear
/// when OptionSpace is used as a name for the base class.
class OptionSpace {
public:
/// @brief Constructor.
///
/// @param name option space name.
/// @param vendor_space boolean value that indicates that the object
/// describes the vendor specific option space.
///
/// @throw isc::dhcp::InvalidOptionSpace if given option space name
/// contains invalid characters or is empty. This constructor uses
/// \ref validateName function to check that the specified name is
/// correct.
OptionSpace(const std::string& name, const bool vendor_space = false);
/// @brief Return option space name.
///
/// @return option space name.
const std::string& getName() const { return (name_); }
/// @brief Mark option space as non-vendor space.
void clearVendorSpace() {
vendor_space_ = false;
}
/// @brief Check if option space is vendor specific.
///
/// @return boolean value that indicates if the object describes
/// the vendor specific option space.
bool isVendorSpace() const { return (vendor_space_); }
/// @brief Mark option space as vendor specific.
void setVendorSpace() {
vendor_space_ = true;
}
/// @brief Checks that the provided option space name is valid.
///
/// It is expected that option space name consists of upper or
/// lower case letters or digits. Also, it may contain underscores
/// or dashes. Other characters are prohibited. The empty option
/// space names are invalid.
///
/// @param name option space name to be validated.
///
/// @return true if the option space is valid, else it returns false.
static bool validateName(const std::string& name);
private:
std::string name_; ///< Holds option space name.
bool vendor_space_; ///< Is this the vendor space?
};
/// @brief DHCPv6 option space with enterprise number assigned.
///
/// This class extends the base class with the support for enterprise numbers.
/// The enterprise numbers are assigned by IANA to various organizations
/// and they are carried as uint32_t integers in DHCPv6 Vendor Specific
/// Information Options (VSIO). For more information refer to RFC3315.
/// All option spaces that group VSIO options must have enterprise number
/// set. It can be set using a constructor or \ref setVendorSpace function.
/// The extra functionality of this class (enterprise numbers) allows to
/// represent DHCPv6 vendor-specific option spaces but this class is also
/// intended to be used for all other DHCPv6 option spaces. That way all
/// DHCPv6 option spaces can be stored in the container holding OptionSpace6
/// objects. Also, it is easy to mark vendor-specific option space as non-vendor
/// specific option space (and the other way around) without a need to cast
/// between OptionSpace and OptionSpace6 types.
class OptionSpace6 : public OptionSpace {
public:
/// @brief Constructor for non-vendor-specific options.
///
/// This constructor marks option space as non-vendor specific.
///
/// @param name option space name.
///
/// @throw isc::dhcp::InvalidOptionSpace if given option space name
/// contains invalid characters or is empty. This constructor uses
/// \ref OptionSpace::validateName function to check that the specified
/// name is correct.
OptionSpace6(const std::string& name);
/// @brief Constructor for vendor-specific options.
///
/// This constructor marks option space as vendor specific and sets
/// enterprise number to a given value.
///
/// @param name option space name.
/// @param enterprise_number enterprise number.
///
/// @throw isc::dhcp::InvalidOptionSpace if given option space name
/// contains invalid characters or is empty. This constructor uses
/// \ref OptionSpace::validateName function to check that the specified
/// name is correct.
OptionSpace6(const std::string& name, const uint32_t enterprise_number);
/// @brief Return enterprise number for the option space.
///
/// @return enterprise number.
uint32_t getEnterpriseNumber() const { return (enterprise_number_); }
/// @brief Mark option space as vendor specific.
///
/// @param enterprise_number enterprise number.
void setVendorSpace(const uint32_t enterprise_number);
private:
uint32_t enterprise_number_; ///< IANA assigned enterprise number.
};
} // namespace isc::dhcp
} // namespace isc
#endif // OPTION_SPACE_H
......@@ -37,6 +37,7 @@ libdhcpsrv_unittests_SOURCES += memfile_lease_mgr_unittest.cc
if HAVE_MYSQL
libdhcpsrv_unittests_SOURCES += mysql_lease_mgr_unittest.cc
endif
libdhcpsrv_unittests_SOURCES += option_space_unittest.cc
libdhcpsrv_unittests_SOURCES += pool_unittest.cc
libdhcpsrv_unittests_SOURCES += schema_copy.h
libdhcpsrv_unittests_SOURCES += subnet_unittest.cc
......
......@@ -281,4 +281,70 @@ TEST_F(CfgMgrTest, subnet6) {
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::123")));
}
// This test verifies that new DHCPv4 option spaces can be added to
// the configuration manager and that duplicated option space is
// rejected.
TEST_F(CfgMgrTest, optionSpace4) {
CfgMgr& cfg_mgr = CfgMgr::instance();
// Create some option spaces.
OptionSpacePtr space1(new OptionSpace("isc", false));
OptionSpacePtr space2(new OptionSpace("xyz", true));
// Add option spaces with different names and expect they
// are accepted.
ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space1));
ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space2));
// Validate that the option spaces have been added correctly.
const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces4();
ASSERT_EQ(2, spaces.size());
EXPECT_FALSE(spaces.find("isc") == spaces.end());
EXPECT_FALSE(spaces.find("xyz") == spaces.end());
// Create another option space with the name that duplicates
// the existing option space.
OptionSpacePtr space3(new OptionSpace("isc", true));
// Expect that the duplicate option space is rejected.
ASSERT_THROW(
cfg_mgr.addOptionSpace4(space3), isc::dhcp::InvalidOptionSpace
);
// @todo decode if a duplicate vendor space is allowed.
}
// This test verifies that new DHCPv6 option spaces can be added to
// the configuration manager and that duplicated option space is
// rejected.
TEST_F(CfgMgrTest, optionSpace6) {
CfgMgr& cfg_mgr = CfgMgr::instance();
// Create some option spaces.
OptionSpacePtr space1(new OptionSpace("isc", false));
OptionSpacePtr space2(new OptionSpace("xyz", true));
// Add option spaces with different names and expect they
// are accepted.
ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space1));
ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space2));
// Validate that the option spaces have been added correctly.
const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces6();
ASSERT_EQ(2, spaces.size());
EXPECT_FALSE(spaces.find("isc") == spaces.end());
EXPECT_FALSE(spaces.find("xyz") == spaces.end());
// Create another option space with the name that duplicates
// the existing option space.
OptionSpacePtr space3(new OptionSpace("isc", true));
// Expect that the duplicate option space is rejected.
ASSERT_THROW(
cfg_mgr.addOptionSpace6(space3), isc::dhcp::InvalidOptionSpace
);
// @todo decide if a duplicate vendor space is allowed.
}
} // end of anonymous namespace
// Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <dhcpsrv/option_space.h>
#include <gtest/gtest.h>
using namespace isc::dhcp;
using namespace isc;
namespace {
// The purpose of this test is to verify that the constructor
// creates an object with members initialized to correct values.
TEST(OptionSpaceTest, constructor) {
// Create some option space.
OptionSpace space("isc", true);
EXPECT_EQ("isc", space.getName());
EXPECT_TRUE(space.isVendorSpace());
// Create another object with different values
// to check that the values will change.
OptionSpace space2("abc", false);
EXPECT_EQ("abc", space2.getName());
EXPECT_FALSE(space2.isVendorSpace());
// Verify that constructor throws exception if invalid
// option space name is provided.
EXPECT_THROW(OptionSpace("invalid%space.name"), InvalidOptionSpace);
}
// The purpose of this test is to verify that the vendor-space flag
// can be overriden.
TEST(OptionSpaceTest, setVendorSpace) {
OptionSpace space("isc", true);
EXPECT_EQ("isc", space.getName());
EXPECT_TRUE(space.isVendorSpace());
// Override the vendor space flag.
space.clearVendorSpace();
EXPECT_FALSE(space.isVendorSpace());
}
// The purpose of this test is to verify that the static function
// to validate the option space name works correctly.
TEST(OptionSpaceTest, validateName) {
// Positive test scenarios: letters, digits, dashes, underscores
// lower/upper case allowed.
EXPECT_TRUE(OptionSpace::validateName("abc"));
EXPECT_TRUE(OptionSpace::validateName("dash-allowed"));
EXPECT_TRUE(OptionSpace::validateName("two-dashes-allowed"));
EXPECT_TRUE(OptionSpace::validateName("underscore_allowed"));
EXPECT_TRUE(OptionSpace::validateName("underscore_three_times_allowed"));
EXPECT_TRUE(OptionSpace::validateName("digits0912"));
EXPECT_TRUE(OptionSpace::validateName("1234"));
EXPECT_TRUE(OptionSpace::validateName("UPPER_CASE_allowed"));
// Negative test scenarions: empty strings, dots, spaces are not
// allowed
EXPECT_FALSE(OptionSpace::validateName(""));
EXPECT_FALSE(OptionSpace::validateName(" "));
EXPECT_FALSE(OptionSpace::validateName(" isc "));
EXPECT_FALSE(OptionSpace::validateName("isc "));
EXPECT_FALSE(OptionSpace::validateName(" isc"));
EXPECT_FALSE(OptionSpace::validateName("isc with-space"));
// Hyphens and underscores are not allowed at the beginning
// and at the end of the option space name.
EXPECT_FALSE(OptionSpace::validateName("-isc"));
EXPECT_FALSE(OptionSpace::validateName("isc-"));
EXPECT_FALSE(OptionSpace::validateName("_isc"));
EXPECT_FALSE(OptionSpace::validateName("isc_"));
// Test other special characters
const char specials[] = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
'+', '=', '[', ']', '{', '}', ';', ':', '"', '\'',
'\\', '|', '<','>', ',', '.', '?', '~', '`' };
for (int i = 0; i < sizeof(specials); ++i) {
std::ostringstream stream;
// Concatenate valid option space name: "abc" with an invalid character.
// That way we get option space names like: "abc!", "abc$" etc. It is
// expected that the validating function fails form them.
stream << "abc" << specials[i];
EXPECT_FALSE(OptionSpace::validateName(stream.str()))
<< "Test failed for special character '" << specials[i] << "'.";
}
}
// The purpose of this test is to verify that the constructors of the
// OptionSpace6 class set the class members to correct values.
TEST(OptionSpace6Test, constructor) {
// Create some option space and do not specify enterprise number.
// In such case the vendor space flag is expected to be
// set to false.
OptionSpace6 space1("abcd");
EXPECT_EQ("abcd", space1.getName());
EXPECT_FALSE(space1.isVendorSpace());
// Create an option space and specify an enterprise number. In this
// case the vendor space flag is expected to be set to true and the
// enterprise number should be set to a desired value.
OptionSpace6 space2("abcd", 2145);
EXPECT_EQ("abcd", space2.getName());
EXPECT_TRUE(space2.isVendorSpace());
EXPECT_EQ(2145, space2.getEnterpriseNumber());
// Verify that constructors throw an exception when invalid option
// space name has been specified.
EXPECT_THROW(OptionSpace6("isc dhcp"), InvalidOptionSpace);
EXPECT_THROW(OptionSpace6("isc%dhcp", 2145), InvalidOptionSpace);
}
// The purpose of this test is to verify an option space can be marked
// vendor option space and enterprise number can be set.
TEST(OptionSpace6Test, setVendorSpace) {
OptionSpace6 space("isc");
EXPECT_EQ("isc", space.getName());
EXPECT_FALSE(space.isVendorSpace());
// Mark it vendor option space and set enterprise id.
space.setVendorSpace(1234);
EXPECT_TRUE(space.isVendorSpace());