From: Francis Dupont Date: Sun, 1 Oct 2017 21:20:38 +0000 (+0200) Subject: [5277] Extended server-hostname and boot-file-name (native for subnet4, else inherited) X-Git-Tag: Kea-1.3.0~2^2~28^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8aaf42fc5b13e06526d9ff617c03e2f1a0ae14b;p=thirdparty%2Fkea.git [5277] Extended server-hostname and boot-file-name (native for subnet4, else inherited) --- diff --git a/doc/examples/kea4/shared-network.json b/doc/examples/kea4/shared-network.json index be3babc7a0..14eceb8db9 100644 --- a/doc/examples/kea4/shared-network.json +++ b/doc/examples/kea4/shared-network.json @@ -72,6 +72,8 @@ "id": 1, "match-client-id": true, "next-server": "0.0.0.0", + "server-hostname": "", + "boot-file-name": "", "option-data": [ ], "pools": [ ], "rebind-timer": 20, @@ -91,6 +93,8 @@ "id": 2, "match-client-id": true, "next-server": "0.0.0.0", + "server-hostname": "", + "boot-file-name": "", "option-data": [ ], "pools": [ ], "rebind-timer": 20, diff --git a/doc/guide/dhcp4-srv.xml b/doc/guide/dhcp4-srv.xml index a4c450c604..e794d00c8b 100644 --- a/doc/guide/dhcp4-srv.xml +++ b/doc/guide/dhcp4-srv.xml @@ -2591,14 +2591,24 @@ It is merely echoed by the server not be sent. It may also be set to an empty string, which means the same as if it was not defined at all, i.e. use the global value. + + The server-hostname (that conveys a server hostname, + can be up to 64 bytes long and will be sent in the sname field) and + boot-file-name (that conveys the configuration file, + can be up to 128 bytes long and will be sent using file field) + directives are handled the same way than next-server. + "Dhcp4": { - "next-server": "192.0.2.123", + "next-server": "192.0.2.123", + "boot-file-name": "/dev/null", ..., "subnet4": [ { - "next-server": "192.0.2.234", + "next-server": "192.0.2.234", + "server-hostname": "some-name.example.org", + "boot-file-name": "bootfile.efi", ... } ] diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 602bf5efc8..323918ba0c 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -2165,6 +2165,28 @@ Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) { if (!subnet_next_server.isV4Zero()) { response->setSiaddr(subnet_next_server); } + + const string& sname = subnet->getSname(); + if (!sname.empty()) { + // Converting string to (const uint8_t*, size_t len) format is + // tricky. reinterpret_cast is not the most elegant solution, + // but it does avoid us making unnecessary copy. We will convert + // sname and file fields in Pkt4 to string one day and life + // will be easier. + response->setSname(reinterpret_cast(sname.c_str()), + sname.size()); + } + + const string& filename = subnet->getFilename(); + if (!filename.empty()) { + // Converting string to (const uint8_t*, size_t len) format is + // tricky. reinterpret_cast is not the most elegant solution, + // but it does avoid us making unnecessary copy. We will convert + // sname and file fields in Pkt4 to string one day and life + // will be easier. + response->setFile(reinterpret_cast(filename.c_str()), + filename.size()); + } } // Step 2: Try to set the values based on classes. diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc index b2e0704ea2..31ce8ec87b 100644 --- a/src/bin/dhcp4/json_config_parser.cc +++ b/src/bin/dhcp4/json_config_parser.cc @@ -455,7 +455,9 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set, (config_pair.first == "dhcp4o6-port") || (config_pair.first == "echo-client-id") || (config_pair.first == "match-client-id") || - (config_pair.first == "next-server")) { + (config_pair.first == "next-server") || + (config_pair.first == "server-hostname") || + (config_pair.first == "boot-file-name")) { continue; } diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index 6ac125b3ef..0cb062d867 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -1106,14 +1106,16 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) { /// @todo: implement subnet removal test as part of #3281. -// Checks if the next-server defined as global parameter is taken into -// consideration. +// Checks if the next-server and other fixed BOOTP fields defined as +// global parameter are taken into consideration. TEST_F(Dhcp4ParserTest, nextServerGlobal) { string config = "{ " + genIfaceConfig() + "," + "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " "\"next-server\": \"1.2.3.4\", " + "\"server-hostname\": \"foo\", " + "\"boot-file-name\": \"bar\", " "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," " \"subnet\": \"192.0.2.0/24\" } ]," @@ -1135,10 +1137,12 @@ TEST_F(Dhcp4ParserTest, nextServerGlobal) { getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200")); ASSERT_TRUE(subnet); EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText()); + EXPECT_EQ("foo", subnet->getSname()); + EXPECT_EQ("bar", subnet->getFilename()); } -// Checks if the next-server defined as subnet parameter is taken into -// consideration. +// Checks if the next-server and other fixed BOOTP fields defined as +// subnet parameter are taken into consideration. TEST_F(Dhcp4ParserTest, nextServerSubnet) { string config = "{ " + genIfaceConfig() + "," + @@ -1147,6 +1151,8 @@ TEST_F(Dhcp4ParserTest, nextServerSubnet) { "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," " \"next-server\": \"1.2.3.4\", " + " \"server-hostname\": \"foo\", " + " \"boot-file-name\": \"bar\", " " \"subnet\": \"192.0.2.0/24\" } ]," "\"valid-lifetime\": 4000 }"; @@ -1166,6 +1172,8 @@ TEST_F(Dhcp4ParserTest, nextServerSubnet) { getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200")); ASSERT_TRUE(subnet); EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText()); + EXPECT_EQ("foo", subnet->getSname()); + EXPECT_EQ("bar", subnet->getFilename()); } // Test checks several negative scenarios for next-server configuration: bogus @@ -1209,12 +1217,43 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) { " \"subnet\": \"192.0.2.0/24\" } ]," "\"valid-lifetime\": 4000 }"; + // Config with too large server-hostname + string bigsname(Pkt4::MAX_SNAME_LEN + 1, ' '); + string config_bogus4 = "{ " + genIfaceConfig() + "," + + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"rebind-timer\": 2000, " + " \"renew-timer\": 1000, " + " \"server-hostname\": \"" + bigsname + "\", " + + " \"subnet\": \"192.0.2.0/24\" } ]," + "\"valid-lifetime\": 4000 }"; + + // Config with too large boot-file-hostname + string bigfilename(Pkt4::MAX_FILE_LEN + 1, ' '); + string config_bogus5 = "{ " + genIfaceConfig() + "," + + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"rebind-timer\": 2000, " + " \"renew-timer\": 1000, " + " \"boot-file-name\": \"" + bigfilename + "\", " + + " \"subnet\": \"192.0.2.0/24\" } ]," + "\"valid-lifetime\": 4000 }"; + + ConstElementPtr json1; ASSERT_NO_THROW(json1 = parseDHCP4(config_bogus1)); ConstElementPtr json2; ASSERT_NO_THROW(json2 = parseDHCP4(config_bogus2)); ConstElementPtr json3; ASSERT_NO_THROW(json3 = parseDHCP4(config_bogus3)); + ConstElementPtr json4; + ASSERT_NO_THROW(json4 = parseDHCP4(config_bogus4)); + ConstElementPtr json5; + ASSERT_NO_THROW(json5 = parseDHCP4(config_bogus5)); // check if returned status is always a failure ConstElementPtr status; @@ -1233,6 +1272,18 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) { EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json3)); checkResult(status, 0); EXPECT_FALSE(errorContainsPosition(status, "")); + + CfgMgr::instance().clear(); + + EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json4)); + checkResult(status, 1); + EXPECT_TRUE(errorContainsPosition(status, "")); + + CfgMgr::instance().clear(); + + EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json5)); + checkResult(status, 1); + EXPECT_TRUE(errorContainsPosition(status, "")); } // Checks if the next-server defined as global value is overridden by subnet @@ -1243,9 +1294,13 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) { "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " "\"next-server\": \"192.0.0.1\", " + "\"server-hostname\": \"nohost\"," + "\"boot-file-name\": \"nofile\"," "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," " \"next-server\": \"1.2.3.4\", " + " \"server-hostname\": \"some-name.example.org\"," + " \"boot-file-name\": \"bootfile.efi\"," " \"subnet\": \"192.0.2.0/24\" } ]," "\"valid-lifetime\": 4000 }"; @@ -1265,6 +1320,8 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) { getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200")); ASSERT_TRUE(subnet); EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText()); + EXPECT_EQ("some-name.example.org", subnet->getSname()); + EXPECT_EQ("bootfile.efi", subnet->getFilename()); } // Check whether it is possible to configure echo-client-id @@ -5229,6 +5286,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { " \"interface\": \"eth0\",\n" " \"match-client-id\": false,\n" " \"next-server\": \"1.2.3.4\",\n" + " \"server-hostname\": \"foo\",\n" + " \"boot-file-name\": \"bar\",\n" " \"relay\": {\n" " \"ip-address\": \"5.6.7.8\"\n" " },\n" @@ -5249,6 +5308,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { " \"valid-lifetime\": 400,\n" " \"match-client-id\": true,\n" " \"next-server\": \"11.22.33.44\",\n" + " \"server-hostname\": \"some-name.example.org\",\n" + " \"boot-file-name\": \"bootfile.efi\",\n" " \"relay\": {\n" " \"ip-address\": \"55.66.77.88\"\n" " },\n" @@ -5299,6 +5360,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { EXPECT_EQ("eth0", s->getIface()); EXPECT_EQ(false, s->getMatchClientId()); EXPECT_EQ(IOAddress("1.2.3.4"), s->getSiaddr()); + EXPECT_EQ("foo", s->getSname()); + EXPECT_EQ("bar", s->getFilename()); EXPECT_EQ(IOAddress("5.6.7.8"), s->getRelayInfo().addr_); EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode()); @@ -5312,6 +5375,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { EXPECT_EQ("eth0", s->getIface()); EXPECT_EQ(true, s->getMatchClientId()); EXPECT_EQ(IOAddress("11.22.33.44"), s->getSiaddr()); + EXPECT_EQ("some-name.example.org", s->getSname()); + EXPECT_EQ("bootfile.efi", s->getFilename()); EXPECT_EQ(IOAddress("55.66.77.88"), s->getRelayInfo().addr_); EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode()); @@ -5329,6 +5394,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { EXPECT_EQ("", s->getIface()); EXPECT_EQ(true, s->getMatchClientId()); EXPECT_EQ(IOAddress("0.0.0.0"), s->getSiaddr()); + EXPECT_TRUE(s->getSname().empty()); + EXPECT_TRUE(s->getFilename().empty()); EXPECT_EQ(IOAddress("0.0.0.0"), s->getRelayInfo().addr_); EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode()); } diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 85897604b1..3871288170 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -1255,7 +1255,7 @@ TEST_F(Dhcpv4SrvTest, siaddr) { // Checks if the next-server defined as global value is overridden by subnet // specific value and returned in server messages. There's also similar test for // checking parser only configuration, see Dhcp4ParserTest.nextServerOverride in -// config_parser_unittest.cc. +// config_parser_unittest.cc. This test was extended to other BOOTP fixed fields. TEST_F(Dhcpv4SrvTest, nextServerOverride) { IfaceMgrTestConfig test_config(true); IfaceMgr::instance().openSockets4(); @@ -1270,9 +1270,13 @@ TEST_F(Dhcpv4SrvTest, nextServerOverride) { "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " "\"next-server\": \"192.0.0.1\", " + "\"server-hostname\": \"nohost\", " + "\"boot-file-name\": \"nofile\", " "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," " \"next-server\": \"1.2.3.4\", " + " \"server-hostname\": \"some-name.example.org\", " + " \"boot-file-name\": \"bootfile.efi\", " " \"subnet\": \"192.0.2.0/24\" } ]," "\"valid-lifetime\": 4000 }"; @@ -1300,6 +1304,16 @@ TEST_F(Dhcpv4SrvTest, nextServerOverride) { EXPECT_EQ(DHCPOFFER, offer->getType()); EXPECT_EQ("1.2.3.4", offer->getSiaddr().toText()); + std::string sname("some-name.example.org"); + uint8_t sname_buf[Pkt4::MAX_SNAME_LEN]; + std::memset(sname_buf, 0, Pkt4::MAX_SNAME_LEN); + std::memcpy(sname_buf, sname.c_str(), sname.size()); + EXPECT_EQ(0, std::memcmp(sname_buf, &offer->getSname()[0], Pkt4::MAX_SNAME_LEN)); + std::string filename("bootfile.efi"); + uint8_t filename_buf[Pkt4::MAX_FILE_LEN]; + std::memset(filename_buf, 0, Pkt4::MAX_FILE_LEN); + std::memcpy(filename_buf, filename.c_str(), filename.size()); + EXPECT_EQ(0, std::memcmp(filename_buf, &offer->getFile()[0], Pkt4::MAX_FILE_LEN)); } // Checks if the next-server defined as global value is used in responses @@ -1320,6 +1334,8 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) { "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " "\"next-server\": \"192.0.0.1\", " + "\"server-hostname\": \"some-name.example.org\", " + "\"boot-file-name\": \"bootfile.efi\", " "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," " \"subnet\": \"192.0.2.0/24\" } ]," @@ -1349,6 +1365,16 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) { EXPECT_EQ(DHCPOFFER, offer->getType()); EXPECT_EQ("192.0.0.1", offer->getSiaddr().toText()); + std::string sname("some-name.example.org"); + uint8_t sname_buf[Pkt4::MAX_SNAME_LEN]; + std::memset(sname_buf, 0, Pkt4::MAX_SNAME_LEN); + std::memcpy(sname_buf, sname.c_str(), sname.size()); + EXPECT_EQ(0, std::memcmp(sname_buf, &offer->getSname()[0], Pkt4::MAX_SNAME_LEN)); + std::string filename("bootfile.efi"); + uint8_t filename_buf[Pkt4::MAX_FILE_LEN]; + std::memset(filename_buf, 0, Pkt4::MAX_FILE_LEN); + std::memcpy(filename_buf, filename.c_str(), filename.size()); + EXPECT_EQ(0, std::memcmp(filename_buf, &offer->getFile()[0], Pkt4::MAX_FILE_LEN)); } // Checks if server is able to handle a relayed traffic from DOCSIS3.0 modems diff --git a/src/bin/dhcp4/tests/dora_unittest.cc b/src/bin/dhcp4/tests/dora_unittest.cc index f6a23c4f73..10261ce6dd 100644 --- a/src/bin/dhcp4/tests/dora_unittest.cc +++ b/src/bin/dhcp4/tests/dora_unittest.cc @@ -267,6 +267,8 @@ const char* DORA_CONFIGS[] = { "}," "\"valid-lifetime\": 600," "\"next-server\": \"10.0.0.1\"," + "\"server-hostname\": \"nohost\"," + "\"boot-file-name\": \"nofile\"," "\"subnet4\": [ { " " \"subnet\": \"10.0.0.0/24\", " " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]," diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc b/src/bin/dhcp4/tests/get_config_unittest.cc index 5c6cdb1635..79a5e7aac5 100644 --- a/src/bin/dhcp4/tests/get_config_unittest.cc +++ b/src/bin/dhcp4/tests/get_config_unittest.cc @@ -223,12 +223,14 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 6 "{\n" +" \"boot-file-name\": \"bar\",\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" " },\n" " \"next-server\": \"1.2.3.4\",\n" " \"rebind-timer\": 2000,\n" " \"renew-timer\": 1000,\n" +" \"server-hostname\": \"foo\",\n" " \"subnet4\": [\n" " {\n" " \"pools\": [\n" @@ -250,12 +252,14 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"subnet4\": [\n" " {\n" +" \"boot-file-name\": \"bar\",\n" " \"next-server\": \"1.2.3.4\",\n" " \"pools\": [\n" " {\n" " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" " }\n" " ],\n" +" \"server-hostname\": \"foo\",\n" " \"subnet\": \"192.0.2.0/24\"\n" " }\n" " ],\n" @@ -263,20 +267,24 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 8 "{\n" +" \"boot-file-name\": \"nofile\",\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" " },\n" " \"next-server\": \"192.0.0.1\",\n" " \"rebind-timer\": 2000,\n" " \"renew-timer\": 1000,\n" +" \"server-hostname\": \"nohost\",\n" " \"subnet4\": [\n" " {\n" +" \"boot-file-name\": \"bootfile.efi\",\n" " \"next-server\": \"1.2.3.4\",\n" " \"pools\": [\n" " {\n" " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" " }\n" " ],\n" +" \"server-hostname\": \"some-name.example.org\",\n" " \"subnet\": \"192.0.2.0/24\"\n" " }\n" " ],\n" @@ -1547,7 +1555,8 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ],\n" " \"valid-lifetime\": 4000\n" -" }\n"}; +" }\n" +}; /// @brief unparsed configurations const char* UNPARSED_CONFIGS[] = { @@ -1640,6 +1649,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1657,6 +1667,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 900,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -1708,6 +1719,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1725,6 +1737,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -1776,6 +1789,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1793,6 +1807,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -1844,6 +1859,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1861,6 +1877,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -1868,6 +1885,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 2,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1885,6 +1903,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -1892,6 +1911,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 3,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1909,6 +1929,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.4.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -1916,6 +1937,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 4,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -1933,6 +1955,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.5.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -1984,6 +2007,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1024,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2001,6 +2025,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -2008,6 +2033,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 100,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2025,6 +2051,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -2032,6 +2059,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2049,6 +2077,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.4.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -2056,6 +2085,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 34,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2073,6 +2103,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.5.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2124,6 +2155,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"bar\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"1.2.3.4\",\n" @@ -2141,6 +2173,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"foo\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2192,6 +2225,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"bar\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"1.2.3.4\",\n" @@ -2209,6 +2243,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"foo\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2260,6 +2295,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"bootfile.efi\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"1.2.3.4\",\n" @@ -2277,6 +2313,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"some-name.example.org\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2328,6 +2365,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2345,6 +2383,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2396,6 +2435,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2413,6 +2453,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2464,6 +2505,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2481,6 +2523,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -2488,6 +2531,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 2,\n" " \"match-client-id\": false,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2505,6 +2549,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2556,6 +2601,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": false,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2573,6 +2619,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -2580,6 +2627,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 2,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2597,6 +2645,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2648,6 +2697,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2665,6 +2715,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4\n" " }\n" @@ -2716,6 +2767,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2737,6 +2789,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -2744,6 +2797,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 2,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2765,6 +2819,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -2816,6 +2871,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -2833,6 +2889,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -3281,6 +3338,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3298,6 +3356,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -3349,6 +3408,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3383,6 +3443,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -3461,6 +3522,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3478,6 +3540,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -3661,6 +3724,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3678,6 +3742,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 3000\n" " }\n" @@ -3738,6 +3803,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3772,6 +3838,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -3823,6 +3890,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3849,6 +3917,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -3856,6 +3925,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 2,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3882,6 +3952,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -3933,6 +4004,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -3967,6 +4039,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -4018,6 +4091,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4057,6 +4131,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -4231,6 +4306,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4248,6 +4324,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 3000\n" " }\n" @@ -4314,6 +4391,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4331,6 +4409,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -4401,6 +4480,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4418,6 +4498,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -4555,6 +4636,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4572,6 +4654,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -4623,6 +4706,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4640,6 +4724,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4\n" " }\n" @@ -4691,6 +4776,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 123,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4708,6 +4794,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -4715,6 +4802,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 234,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4787,6 +4875,7 @@ const char* UNPARSED_CONFIGS[] = { " \"server-hostname\": \"\"\n" " }\n" " ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -4794,6 +4883,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 542,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4859,6 +4949,7 @@ const char* UNPARSED_CONFIGS[] = { " \"server-hostname\": \"\"\n" " }\n" " ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.4.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -4920,6 +5011,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 234,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -4957,6 +5049,7 @@ const char* UNPARSED_CONFIGS[] = { " \"server-hostname\": \"\"\n" " }\n" " ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5008,6 +5101,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5025,6 +5119,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -5032,6 +5127,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 2,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5049,6 +5145,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"out-of-pool\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.3.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -5056,6 +5153,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 3,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5073,6 +5171,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"disabled\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.4.0/24\",\n" " \"valid-lifetime\": 4000\n" " },\n" @@ -5080,6 +5179,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 4,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5097,6 +5197,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.5.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5320,6 +5421,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5337,6 +5439,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5388,6 +5491,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"2001:db8::123/45\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5405,6 +5509,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5456,6 +5561,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"ethX\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5473,6 +5579,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5524,6 +5631,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"ethX\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"2001:db8::543/21\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5541,6 +5649,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5592,6 +5701,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"vlan123\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5609,6 +5719,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5686,6 +5797,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5703,6 +5815,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5754,6 +5867,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5771,6 +5885,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5822,6 +5937,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5840,6 +5956,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5891,6 +6008,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5913,6 +6031,7 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" @@ -5964,6 +6083,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface\": \"\",\n" " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5986,11 +6106,13 @@ const char* UNPARSED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" " \"subnet\": \"192.0.2.0/24\",\n" " \"valid-lifetime\": 4000\n" " }\n" " ]\n" -" }\n"}; +" }\n" +}; /// @brief the number of configurations const size_t max_config_counter = sizeof(EXTRACTED_CONFIGS) / sizeof(char*); diff --git a/src/bin/dhcp4/tests/inform_unittest.cc b/src/bin/dhcp4/tests/inform_unittest.cc index b6c17b41bd..42a5cfe31b 100644 --- a/src/bin/dhcp4/tests/inform_unittest.cc +++ b/src/bin/dhcp4/tests/inform_unittest.cc @@ -109,6 +109,8 @@ const char* INFORM_CONFIGS[] = { "}," "\"valid-lifetime\": 600," "\"next-server\": \"10.0.0.1\"," + "\"server-hostname\": \"nohost\"," + "\"server-hostname\": \"nofile\"," "\"subnet4\": [ { " " \"subnet\": \"192.0.2.0/24\", " " \"reservations\": [ " diff --git a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc index cfb1dc78c3..393e1624ed 100644 --- a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc +++ b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc @@ -708,6 +708,32 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params, << next_server << "(" << pos << ")"); } + // Set server-hostname. + std::string sname = getString(params, "server-hostname"); + if (!sname.empty()) { + if (sname.length() >= Pkt4::MAX_SNAME_LEN) { + ConstElementPtr error = params->get("server-hostname"); + isc_throw(DhcpConfigError, "server-hostname must be at most " + << Pkt4::MAX_SNAME_LEN - 1 << " bytes long, it is " + << sname.length() << " (" + << error->getPosition() << ")"); + } + subnet4->setSname(sname); + } + + // Set boot-file-name. + std::string filename =getString(params, "boot-file-name"); + if (!filename.empty()) { + if (filename.length() > Pkt4::MAX_FILE_LEN) { + ConstElementPtr error = params->get("boot-file-name"); + isc_throw(DhcpConfigError, "boot-file-name must be at most " + << Pkt4::MAX_FILE_LEN - 1 << " bytes long, it is " + << filename.length() << " (" + << error->getPosition() << ")"); + } + subnet4->setFilename(filename); + } + // Get interface name. If it is defined, then the subnet is available // directly over specified network interface. std::string iface = getString(params, "interface"); diff --git a/src/lib/dhcpsrv/parsers/simple_parser4.cc b/src/lib/dhcpsrv/parsers/simple_parser4.cc index a8c47891c8..e766e96323 100644 --- a/src/lib/dhcpsrv/parsers/simple_parser4.cc +++ b/src/lib/dhcpsrv/parsers/simple_parser4.cc @@ -63,7 +63,9 @@ const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = { { "dhcp4o6-port", Element::integer, "0" }, { "echo-client-id", Element::boolean, "true" }, { "match-client-id", Element::boolean, "true" }, - { "next-server", Element::string, "0.0.0.0" } + { "next-server", Element::string, "0.0.0.0" }, + { "server-hostname", Element::string, "" }, + { "boot-file-name", Element::string, "" } }; /// @brief This table defines default values for each IPv4 subnet. @@ -118,6 +120,7 @@ const SimpleDefaults SimpleParser4::IFACE4_DEFAULTS = { /// This list is also used for inheriting from global to shared networks /// and from shared networks to subnets within it. const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = { + "boot-file-name", "client-class", "interface", "match-client-id", @@ -126,6 +129,7 @@ const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = { "relay", "renew-timer", "reservation-mode", + "server-hostname", "valid-lifetime" }; diff --git a/src/lib/dhcpsrv/subnet.cc b/src/lib/dhcpsrv/subnet.cc index e3808b4b5c..837faed171 100644 --- a/src/lib/dhcpsrv/subnet.cc +++ b/src/lib/dhcpsrv/subnet.cc @@ -239,6 +239,21 @@ isc::asiolink::IOAddress Subnet4::getSiaddr() const { return (siaddr_); } +void Subnet4::setSname(const std::string& sname) { + sname_ = sname; +} + +const std::string& Subnet4::getSname() const { + return (sname_); +} +void Subnet4::setFilename(const std::string& filename) { + filename_ = filename; +} + +const std::string& Subnet4::getFilename() const { + return (filename_); +} + const PoolCollection& Subnet::getPools(Lease::Type type) const { // check if the type is valid (and throw if it isn't) checkType(type); @@ -574,6 +589,12 @@ Subnet4::toElement() const { // Set next-server map->set("next-server", Element::create(getSiaddr().toText())); + // Set server-hostname + map->set("server-hostname", Element::create(getSname())); + + // Set boot-file-name + map->set("boot-file-name",Element::create(getFilename())); + // Set pools const PoolCollection& pools = getPools(Lease::TYPE_V4); ElementPtr pool_list = Element::createList(); diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h index 818f83cbc7..40d34a1cd4 100644 --- a/src/lib/dhcpsrv/subnet.h +++ b/src/lib/dhcpsrv/subnet.h @@ -457,6 +457,26 @@ public: /// @return siaddr value isc::asiolink::IOAddress getSiaddr() const; + /// @brief Sets server hostname for the Subnet4 + /// + /// Will be used for server hostname field (may be empty if not defined) + void setSname(const std::string& sname); + + /// @brief Returns server hostname for this subnet + /// + /// @return server hostname value + const std::string& getSname() const; + + /// @brief Sets boot file name for the Subnet4 + /// + /// Will be used for boot file name (may be empty if not defined) + void setFilename(const std::string& filename); + + /// @brief Returns boot file name for this subnet + /// + /// @return boot file name value + const std::string& getFilename() const; + /// @brief Returns DHCP4o6 configuration parameters. /// /// This structure is always available. If the 4o6 is not enabled, its @@ -497,6 +517,12 @@ private: /// @brief siaddr value for this subnet isc::asiolink::IOAddress siaddr_; + /// @brief server hostname for this subnet + std::string sname_; + + /// @brief boot file name for this subnet + std::string filename_; + /// @brief All the information related to DHCP4o6 Cfg4o6 dhcp4o6_; }; diff --git a/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc b/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc index a0664d24f4..91958fbb76 100644 --- a/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc @@ -748,6 +748,8 @@ TEST(CfgSubnets4Test, unparseSubnet) { " \"relay\": { \"ip-address\": \"0.0.0.0\" },\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" + " \"server-hostname\": \"\",\n" + " \"boot-file-name\": \"\",\n" " \"renew-timer\": 1,\n" " \"rebind-timer\": 2,\n" " \"valid-lifetime\": 3,\n" @@ -765,6 +767,8 @@ TEST(CfgSubnets4Test, unparseSubnet) { " \"interface\": \"lo\",\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" + " \"server-hostname\": \"\",\n" + " \"boot-file-name\": \"\",\n" " \"renew-timer\": 1,\n" " \"rebind-timer\": 2,\n" " \"valid-lifetime\": 3,\n" @@ -781,6 +785,8 @@ TEST(CfgSubnets4Test, unparseSubnet) { " \"interface\": \"eth1\",\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" + " \"server-hostname\": \"\",\n" + " \"boot-file-name\": \"\",\n" " \"renew-timer\": 1,\n" " \"rebind-timer\": 2,\n" " \"valid-lifetime\": 3,\n" @@ -815,6 +821,8 @@ TEST(CfgSubnets4Test, unparsePool) { " \"relay\": { \"ip-address\": \"0.0.0.0\" },\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" + " \"server-hostname\": \"\",\n" + " \"boot-file-name\": \"\",\n" " \"renew-timer\": 1,\n" " \"rebind-timer\": 2,\n" " \"valid-lifetime\": 3,\n" diff --git a/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc b/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc index d8cc6313f1..03329f87e3 100644 --- a/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc @@ -49,6 +49,8 @@ public: " \"valid-lifetime\": 300," " \"match-client-id\": false," " \"next-server\": \"\"," + " \"server-hostname\": \"\"," + " \"boot-file-name\": \"\"," " \"client-class\": \"\"," " \"reservation-mode\": \"all\"," " \"4o6-interface\": \"\"," @@ -67,6 +69,8 @@ public: " \"valid-lifetime\": 30," " \"match-client-id\": false," " \"next-server\": \"\"," + " \"server-hostname\": \"\"," + " \"boot-file-name\": \"\"," " \"client-class\": \"\"," " \"reservation-mode\": \"all\"," " \"4o6-interface\": \"\"," diff --git a/src/lib/dhcpsrv/tests/shared_network_unittest.cc b/src/lib/dhcpsrv/tests/shared_network_unittest.cc index e9bcc7c6c4..30aedd054f 100644 --- a/src/lib/dhcpsrv/tests/shared_network_unittest.cc +++ b/src/lib/dhcpsrv/tests/shared_network_unittest.cc @@ -222,6 +222,8 @@ TEST(SharedNetwork4Test, unparse) { " \"id\": 1,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" + " \"server-hostname\": \"\",\n" + " \"boot-file-name\": \"\",\n" " \"option-data\": [ ],\n" " \"pools\": [ ],\n" " \"rebind-timer\": 20,\n" @@ -240,6 +242,8 @@ TEST(SharedNetwork4Test, unparse) { " \"id\": 2,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" + " \"server-hostname\": \"\",\n" + " \"boot-file-name\": \"\",\n" " \"option-data\": [ ],\n" " \"pools\": [ ],\n" " \"rebind-timer\": 20,\n" diff --git a/src/lib/dhcpsrv/tests/subnet_unittest.cc b/src/lib/dhcpsrv/tests/subnet_unittest.cc index 8081d11c9a..34b5ddde30 100644 --- a/src/lib/dhcpsrv/tests/subnet_unittest.cc +++ b/src/lib/dhcpsrv/tests/subnet_unittest.cc @@ -110,6 +110,34 @@ TEST(Subnet4Test, siaddr) { BadValue); } +// Checks whether server-hostname field can be set and retrieved correctly. +TEST(Subnet4Test, serverHostname) { + Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000); + + // Check if the default is empty + EXPECT_TRUE(subnet.getSname().empty()); + + // Check that we can set it up + EXPECT_NO_THROW(subnet.setSname("foobar")); + + // Check that we can get it back + EXPECT_EQ("foobar", subnet.getSname()); +} + +// Checks whether boot-file-name field can be set and retrieved correctly. +TEST(Subnet4Test, bootFileName) { + Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000); + + // Check if the default is empty + EXPECT_TRUE(subnet.getFilename().empty()); + + // Check that we can set it up + EXPECT_NO_THROW(subnet.setFilename("foobar")); + + // Check that we can get it back + EXPECT_EQ("foobar", subnet.getFilename()); +} + // Checks if the match-client-id flag can be set and retrieved. TEST(Subnet4Test, matchClientId) { Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);