Commit 65097a0a authored by Shawn Routhier's avatar Shawn Routhier
Browse files

[trac3576] Add PXE options

Add the options used by PXE
rfc4578 (dhcpv4)
93 Client_System (arch type)
94 Client NDI (network Interface id)
97 UUID/GUID client machine option def

rfc5970 (dhcpv6)
59 BOOTFILE_URL
60 BOOTFILE_PARAM
61 CLIENT_ARCH_TYPE
62 NII

Option 60 requires a special class in order to process the length & string tuples

As some unreleated tests used option 59 as an undefined option they needed to be
updated to use another option.
parent dde7523e
......@@ -1085,7 +1085,9 @@ It is merely echoed by the server
<row><entry>client-last-transaction-time</entry><entry>91</entry><entry>uint32</entry><entry>false</entry><entry>false</entry></row>
<row><entry>associated-ip</entry><entry>92</entry><entry>ipv4-address</entry><entry>true</entry><entry>false</entry></row>
-->
<row><entry>subnet-selection</entry><entry>118</entry><entry>ipv4-address</entry><entry>false</entry><entry>false</entry></row>
<row><entry>client-system</entry><entry>93</entry><entry>uint16</entry><entry>true</entry><entry>false</entry></row>
<row><entry>client-ndi</entry><entry>94</entry><entry>record</entry><entry>false</entry><entry>false</entry></row>
<row><entry>uuid-guid</entry><entry>97</entry><entry>record</entry><entry>false</entry><entry>false</entry></row>
<row><entry>domain-search</entry><entry>119</entry><entry>binary</entry><entry>false</entry><entry>false</entry></row>
<row><entry>vivco-suboptions</entry><entry>124</entry><entry>binary</entry><entry>false</entry><entry>false</entry></row>
<row><entry>vivso-suboptions</entry><entry>125</entry><entry>binary</entry><entry>false</entry><entry>false</entry></row>
......
......@@ -954,6 +954,10 @@ temporarily override a list of interface names and listen on all interfaces.
<row><entry>clt-time</entry><entry>46</entry><entry>uint32</entry><entry>false</entry></row>
<row><entry>lq-relay-data</entry><entry>47</entry><entry>record</entry><entry>false</entry></row>
<row><entry>lq-client-link</entry><entry>48</entry><entry>ipv6-address</entry><entry>true</entry></row>
<row><entry>bootfile-url</entry><entry>59</entry><entry>string</entry><entry>false</entry></row>
<row><entry>bootfile-param</entry><entry>60</entry><entry>binary</entry><entry>false</entry></row>
<row><entry>client-arch-type</entry><entry>61</entry><entry>uint16</entry><entry>true</entry></row>
<row><entry>nii</entry><entry>62</entry><entry>record</entry><entry>false</entry></row>
<row><entry>erp-local-domain-name</entry><entry>65</entry><entry>fqdn</entry><entry>false</entry></row>
<row><entry>rsoo</entry><entry>66</entry><entry>empty</entry><entry>false</entry></row>
<row><entry>client-linklayer-addr</entry><entry>79</entry><entry>binary</entry><entry>false</entry></row>
......
......@@ -2067,15 +2067,15 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
/// @todo The option 59 is a standard DHCPv6 option. However, at this point
/// @todo The option 63 is a standard DHCPv6 option. However, at this point
/// there is no definition for this option in libdhcp++, so it should be
/// allowed to define it from the configuration interface. This test will
/// have to be removed once definitions for remaining standard options are
/// created.
config =
"{ \"option-def\": [ {"
" \"name\": \"boot-file-name\","
" \"code\": 59,"
" \"name\": \"geolocation\","
" \"code\": 63,"
" \"type\": \"string\","
" \"array\": False,"
" \"record-types\": \"\","
......@@ -2092,12 +2092,12 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
checkResult(status, 0);
def = CfgMgr::instance().getStagingCfg()->
getCfgOptionDef()->get("dhcp6", 59);
getCfgOptionDef()->get("dhcp6", 63);
ASSERT_TRUE(def);
// Check the option data.
EXPECT_EQ("boot-file-name", def->getName());
EXPECT_EQ(59, def->getCode());
EXPECT_EQ("geolocation", def->getName());
EXPECT_EQ(63, def->getCode());
EXPECT_EQ(OPT_STRING_TYPE, def->getType());
EXPECT_FALSE(def->getArrayType());
}
......
......@@ -41,6 +41,7 @@ libkea_dhcp___la_SOURCES += option.cc option.h
libkea_dhcp___la_SOURCES += option_custom.cc option_custom.h
libkea_dhcp___la_SOURCES += option_data_types.cc option_data_types.h
libkea_dhcp___la_SOURCES += option_definition.cc option_definition.h
libkea_dhcp___la_SOURCES += option_opaque_data_tuples.cc option_opqaue_data_tuples.h
libkea_dhcp___la_SOURCES += option_space.cc option_space.h
libkea_dhcp___la_SOURCES += option_string.cc option_string.h
libkea_dhcp___la_SOURCES += protocol_util.cc protocol_util.h
......
......@@ -165,11 +165,11 @@ enum DHCPOptionType {
DHO_AUTHENTICATE = 90, /* RFC3118, was 210 */
DHO_CLIENT_LAST_TRANSACTION_TIME = 91,
DHO_ASSOCIATED_IP = 92,
// DHO_SYSTEM = 93,
// DHO_NDI = 94,
DHO_SYSTEM = 93, /* RFC4578 */
DHO_NDI = 94, /* RFC4578 */
// DHO_LDAP = 95,
// 96 is removed/unassigned
// DHO_UUID_GUID = 97,
DHO_UUID_GUID = 97, /* RFC4578 */
// DHO_USER_AUTH = 98,
// DHO_GEOCONF_CIVIC = 99,
// DHO_PCODE = 100,
......
......@@ -82,10 +82,10 @@
//#define D6O_NTP_SERVER 56 /* RFC5908 */
//#define D6O_V6_ACCESS_DOMAIN 57 /* RFC5986 */
//#define D6O_SIP_UA_CS_LIST 58 /* RFC6011 */
//#define D6O_BOOTFILE_URL 59 /* RFC5970 */
//#define D6O_BOOTFILE_PARAM 60 /* RFC5970 */
//#define D6O_CLIENT_ARCH_TYPE 61 /* RFC5970 */
//#define D6O_NII 62 /* RFC5970 */
#define D6O_BOOTFILE_URL 59 /* RFC5970 */
#define D6O_BOOTFILE_PARAM 60 /* RFC5970 */
#define D6O_CLIENT_ARCH_TYPE 61 /* RFC5970 */
#define D6O_NII 62 /* RFC5970 */
//#define D6O_GEOLOCATION 63 /* RFC6225 */
//#define D6O_AFTR_NAME 64 /* RFC6334 */
#define D6O_ERP_LOCAL_DOMAIN_NAME 65 /* RFC6440 */
......
......@@ -27,6 +27,7 @@
#include <dhcp/option_definition.h>
#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>
......@@ -436,6 +437,11 @@ OptionDefinition::haveStatusCodeFormat() const {
(record_fields_[1] == OPT_STRING_TYPE));
}
bool
OptionDefinition::haveOpaqueDataTuplesFormat() const {
return (getType() == OPT_BINARY_TYPE);
}
bool
OptionDefinition::convertToBool(const std::string& value_str) const {
// Case insensitve check that the input is one of: "true" or "false".
......@@ -696,6 +702,9 @@ OptionDefinition::factorySpecialFormatOption(Option::Universe u,
} else if (getCode() == D6O_STATUS_CODE && haveStatusCodeFormat()) {
// Status Code (option code 13)
return (OptionPtr(new Option6StatusCode(begin, end)));
} else if (getCode() == D6O_BOOTFILE_PARAM && haveOpaqueDataTuplesFormat()) {
// Bootfile params (option code 60)
return (OptionPtr(new OptionOpaqueDataTuples(Option::V6, getCode(), begin, end)));
}
} else {
if ((getCode() == DHO_FQDN) && haveFqdn4Format()) {
......
......@@ -370,6 +370,11 @@ public:
/// @return true if option has the format of DHCPv6 Status code option.
bool haveStatusCodeFormat() const;
/// @brief Check if the option has format of OpaqueDataTuples type options.
///
/// @return true if option has the format of OpaqueDataTuples type options.
bool haveOpaqueDataTuplesFormat() const;
/// @brief Option factory.
///
/// This function creates an instance of DHCP option using
......
......@@ -72,6 +72,13 @@ RECORD_DECL(FQDN_RECORDS, OPT_UINT8_TYPE, OPT_UINT8_TYPE, OPT_UINT8_TYPE,
// Opaque data is represented here by the binary data field.
RECORD_DECL(VIVCO_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE);
// RFC4578 (PXE) record fields
//
// Three 1 byte fileds to describe a network interface: type, major and minor
RECORD_DECL(CLIENT_NDI_RECORDS, OPT_UINT8_TYPE, OPT_UINT8_TYPE, OPT_UINT8_TYPE);
// A client identifer: a 1 byte type field followed by opaque data depending on the type
RECORD_DECL(UUID_GUID_RECORDS, OPT_UINT8_TYPE, OPT_BINARY_TYPE);
/// @brief Definitions of standard DHCPv4 options.
const OptionDefParams OPTION_DEF_PARAMS4[] = {
{ "subnet-mask", DHO_SUBNET_MASK, OPT_IPV4_ADDRESS_TYPE, false, NO_RECORD_DEF, "" },
......@@ -188,6 +195,9 @@ const OptionDefParams OPTION_DEF_PARAMS4[] = {
{ "client-last-transaction-time", DHO_CLIENT_LAST_TRANSACTION_TIME,
OPT_UINT32_TYPE, false, NO_RECORD_DEF, "" },
{ "associated-ip", DHO_ASSOCIATED_IP, OPT_IPV4_ADDRESS_TYPE, true, NO_RECORD_DEF, "" },
{ "client-system", DHO_SYSTEM, OPT_UINT16_TYPE, true, NO_RECORD_DEF, "" },
{ "client-ndi", DHO_NDI, OPT_RECORD_TYPE, false, RECORD_DEF(CLIENT_NDI_RECORDS), "" },
{ "uuid-guid", DHO_UUID_GUID, OPT_RECORD_TYPE, false, RECORD_DEF(UUID_GUID_RECORDS), "" },
{ "subnet-selection", DHO_SUBNET_SELECTION,
OPT_IPV4_ADDRESS_TYPE, false, NO_RECORD_DEF, "" },
// The following options need a special encoding of data
......@@ -240,6 +250,11 @@ RECORD_DECL(VENDOR_CLASS_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE);
RECORD_DECL(SIGNATURE_RECORDS, OPT_UINT8_TYPE, OPT_UINT8_TYPE,
OPT_BINARY_TYPE);
// RFC5970 (PXE) Class record fields
//
// Three 1 byte fileds to describe a network interface: type, major and minor
RECORD_DECL(CLIENT_NII_RECORDS, OPT_UINT8_TYPE, OPT_UINT8_TYPE, OPT_UINT8_TYPE);
/// Standard DHCPv6 option definitions.
///
/// @warning in this array, the initializers are provided for all
......@@ -329,6 +344,10 @@ const OptionDefParams OPTION_DEF_PARAMS6[] = {
RECORD_DEF(LQ_RELAY_DATA_RECORDS), "" },
{ "lq-client-link", D6O_LQ_CLIENT_LINK, OPT_IPV6_ADDRESS_TYPE, true,
NO_RECORD_DEF, "" },
{ "bootfile-url", D6O_BOOTFILE_URL, OPT_STRING_TYPE, false, NO_RECORD_DEF, "" },
{ "bootfile-param", D6O_BOOTFILE_PARAM, OPT_BINARY_TYPE, false, NO_RECORD_DEF, "" },
{ "client-arch-type", D6O_CLIENT_ARCH_TYPE, OPT_UINT16_TYPE, true, NO_RECORD_DEF, "" },
{ "nii", D6O_NII, OPT_RECORD_TYPE, false, RECORD_DEF(CLIENT_NII_RECORDS), "" },
{ "erp-local-domain-name", D6O_ERP_LOCAL_DOMAIN_NAME, OPT_FQDN_TYPE, false,
NO_RECORD_DEF, "" },
{ "rsoo", D6O_RSOO, OPT_EMPTY_TYPE, false, NO_RECORD_DEF, "rsoo-opts" },
......
......@@ -51,7 +51,6 @@ libdhcp___unittests_SOURCES += hwaddr_unittest.cc
libdhcp___unittests_SOURCES += iface_mgr_unittest.cc
libdhcp___unittests_SOURCES += iface_mgr_test_config.cc iface_mgr_test_config.h
libdhcp___unittests_SOURCES += libdhcp++_unittest.cc
libdhcp___unittests_SOURCES += opaque_data_tuple_unittest.cc
libdhcp___unittests_SOURCES += option4_addrlst_unittest.cc
libdhcp___unittests_SOURCES += option4_client_fqdn_unittest.cc
libdhcp___unittests_SOURCES += option6_addrlst_unittest.cc
......@@ -65,6 +64,7 @@ libdhcp___unittests_SOURCES += option_int_array_unittest.cc
libdhcp___unittests_SOURCES += option_data_types_unittest.cc
libdhcp___unittests_SOURCES += option_definition_unittest.cc
libdhcp___unittests_SOURCES += option_custom_unittest.cc
libdhcp___unittests_SOURCES += option_opaque_data_tuples_unittest.cc
libdhcp___unittests_SOURCES += option_unittest.cc
libdhcp___unittests_SOURCES += option_space_unittest.cc
libdhcp___unittests_SOURCES += option_string_unittest.cc
......
......@@ -29,6 +29,7 @@
#include <dhcp/option_custom.h>
#include <dhcp/option_int.h>
#include <dhcp/option_int_array.h>
#include <dhcp/option_opaque_data_tuples.h>
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcp/option_vendor_class.h>
......@@ -941,6 +942,15 @@ TEST_F(LibDhcpTest, stdOptionDefs4) {
LibDhcpTest::testStdOptionDefs4(DHO_SUBNET_SELECTION, begin, end,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs4(DHO_SYSTEM, begin, end,
typeid(OptionIntArray<uint16_t>));
LibDhcpTest::testStdOptionDefs4(DHO_NDI, begin, begin + 3,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs4(DHO_UUID_GUID, begin, begin + 17,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs4(DHO_DOMAIN_SEARCH, begin, end,
typeid(Option));
......@@ -1016,6 +1026,13 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
std::vector<uint8_t> vclass_buf(vclass_data,
vclass_data + sizeof(vclass_data));;
// Initialize test buffer for Bootfile Param option.
const char bparam_data[] = {
0x00, 0x01, 0x02
};
std::vector<uint8_t> bparam_buf(bparam_data,
bparam_data + sizeof(bparam_data));;
// The actual test starts here for all supported option codes.
LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, begin, end,
typeid(Option));
......@@ -1161,6 +1178,19 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
LibDhcpTest::testStdOptionDefs6(D6O_LQ_CLIENT_LINK, begin, end,
typeid(Option6AddrLst));
LibDhcpTest::testStdOptionDefs6(D6O_BOOTFILE_URL, begin, end,
typeid(OptionString));
LibDhcpTest::testStdOptionDefs6(D6O_BOOTFILE_PARAM, bparam_buf.begin(),
bparam_buf.end(),
typeid(OptionOpaqueDataTuples));
LibDhcpTest::testStdOptionDefs6(D6O_CLIENT_ARCH_TYPE, begin, end,
typeid(OptionIntArray<uint16_t>));
LibDhcpTest::testStdOptionDefs6(D6O_NII, begin, begin + 3,
typeid(OptionCustom));
LibDhcpTest::testStdOptionDefs6(D6O_RSOO, begin, end,
typeid(OptionCustom),
"rsoo-opts");
......
......@@ -231,9 +231,9 @@ TEST(CfgOptionDefTest, overrideStdOptionDef) {
def.reset(new OptionDefinition("sntp-servers", D6O_SNTP_SERVERS,
"ipv4-address"));
EXPECT_THROW(cfg.add(def, DHCP6_OPTION_SPACE), isc::BadValue);
// There is no definition for option 59 in libdhcp++ yet, so it should
// There is no definition for option 63 in libdhcp++ yet, so it should
// be possible provide a custom definition.
def.reset(new OptionDefinition("bootfile-url", 59, "uint32"));
def.reset(new OptionDefinition("geolocation", 63, "uint32"));
EXPECT_NO_THROW(cfg.add(def, DHCP6_OPTION_SPACE));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment