Browse Source

[master] Finishing merge of trac5277 (bootp parameters)

Francis Dupont 7 years ago
parent
commit
d0d611d0e7

+ 4 - 0
doc/examples/kea4/shared-network.json

@@ -72,6 +72,8 @@
                     "id": 1,
                     "id": 1,
                     "match-client-id": true,
                     "match-client-id": true,
                     "next-server": "0.0.0.0",
                     "next-server": "0.0.0.0",
+                    "server-hostname": "",
+                    "boot-file-name": "",
                     "option-data": [ ],
                     "option-data": [ ],
                     "pools": [ ],
                     "pools": [ ],
                     "rebind-timer": 20,
                     "rebind-timer": 20,
@@ -91,6 +93,8 @@
                     "id": 2,
                     "id": 2,
                     "match-client-id": true,
                     "match-client-id": true,
                     "next-server": "0.0.0.0",
                     "next-server": "0.0.0.0",
+                    "server-hostname": "",
+                    "boot-file-name": "",
                     "option-data": [ ],
                     "option-data": [ ],
                     "pools": [ ],
                     "pools": [ ],
                     "rebind-timer": 20,
                     "rebind-timer": 20,

+ 12 - 2
doc/guide/dhcp4-srv.xml

@@ -2645,14 +2645,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
       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.
       it was not defined at all, i.e. use the global value.
       </para>
       </para>
+      <para>
+      The <command>server-hostname</command> (that conveys a server hostname,
+      can be up to 64 bytes long and will be sent in the sname field) and
+      <command>boot-file-name</command> (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 as <command>next-server</command>.
+      </para>
 
 
 <screen>
 <screen>
 "Dhcp4": {
 "Dhcp4": {
-    <userinput>"next-server": "192.0.2.123"</userinput>,
+    <userinput>"next-server": "192.0.2.123",
+    "boot-file-name": "/dev/null"</userinput>,
     ...,
     ...,
     "subnet4": [
     "subnet4": [
         {
         {
-            <userinput>"next-server": "192.0.2.234"</userinput>,
+            <userinput>"next-server": "192.0.2.234",
+            "server-hostname": "some-name.example.org",
+            "boot-file-name": "bootfile.efi"</userinput>,
             ...
             ...
         }
         }
     ]
     ]

+ 24 - 23
src/bin/dhcp4/dhcp4_lexer.cc

@@ -1592,8 +1592,8 @@ static const flex_int16_t yy_rule_linenum[158] =
      1128, 1137, 1146, 1155, 1164, 1173, 1182, 1191, 1200, 1209,
      1128, 1137, 1146, 1155, 1164, 1173, 1182, 1191, 1200, 1209,
      1219, 1229, 1239, 1249, 1259, 1269, 1279, 1289, 1299, 1308,
      1219, 1229, 1239, 1249, 1259, 1269, 1279, 1289, 1299, 1308,
      1317, 1326, 1335, 1344, 1353, 1364, 1375, 1388, 1399, 1412,
      1317, 1326, 1335, 1344, 1353, 1364, 1375, 1388, 1399, 1412,
-     1510, 1515, 1520, 1525, 1526, 1527, 1528, 1529, 1530, 1532,
-     1550, 1563, 1568, 1572, 1574, 1576, 1578
+     1511, 1516, 1521, 1526, 1527, 1528, 1529, 1530, 1531, 1533,
+     1551, 1564, 1569, 1573, 1575, 1577, 1579
     } ;
     } ;
 
 
 /* The intent behind this definition is that it'll catch
 /* The intent behind this definition is that it'll catch
@@ -3788,6 +3788,7 @@ YY_RULE_SETUP
         case '"':
         case '"':
             /* impossible condition */
             /* impossible condition */
             driver.error(driver.loc_, "Bad quote in \"" + raw + "\"");
             driver.error(driver.loc_, "Bad quote in \"" + raw + "\"");
+            break;
         case '\\':
         case '\\':
             ++pos;
             ++pos;
             if (pos >= len) {
             if (pos >= len) {
@@ -3873,7 +3874,7 @@ YY_RULE_SETUP
 case 141:
 case 141:
 /* rule 141 can match eol */
 /* rule 141 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1510 "dhcp4_lexer.ll"
+#line 1511 "dhcp4_lexer.ll"
 {
 {
     /* Bad string with a forbidden control character inside */
     /* Bad string with a forbidden control character inside */
     driver.error(driver.loc_, "Invalid control in " + std::string(yytext));
     driver.error(driver.loc_, "Invalid control in " + std::string(yytext));
@@ -3882,7 +3883,7 @@ YY_RULE_SETUP
 case 142:
 case 142:
 /* rule 142 can match eol */
 /* rule 142 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1515 "dhcp4_lexer.ll"
+#line 1516 "dhcp4_lexer.ll"
 {
 {
     /* Bad string with a bad escape inside */
     /* Bad string with a bad escape inside */
     driver.error(driver.loc_, "Bad escape in " + std::string(yytext));
     driver.error(driver.loc_, "Bad escape in " + std::string(yytext));
@@ -3890,7 +3891,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 143:
 case 143:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1520 "dhcp4_lexer.ll"
+#line 1521 "dhcp4_lexer.ll"
 {
 {
     /* Bad string with an open escape at the end */
     /* Bad string with an open escape at the end */
     driver.error(driver.loc_, "Overflow escape in " + std::string(yytext));
     driver.error(driver.loc_, "Overflow escape in " + std::string(yytext));
@@ -3898,37 +3899,37 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 144:
 case 144:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1525 "dhcp4_lexer.ll"
+#line 1526 "dhcp4_lexer.ll"
 { return isc::dhcp::Dhcp4Parser::make_LSQUARE_BRACKET(driver.loc_); }
 { return isc::dhcp::Dhcp4Parser::make_LSQUARE_BRACKET(driver.loc_); }
 	YY_BREAK
 	YY_BREAK
 case 145:
 case 145:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1526 "dhcp4_lexer.ll"
+#line 1527 "dhcp4_lexer.ll"
 { return isc::dhcp::Dhcp4Parser::make_RSQUARE_BRACKET(driver.loc_); }
 { return isc::dhcp::Dhcp4Parser::make_RSQUARE_BRACKET(driver.loc_); }
 	YY_BREAK
 	YY_BREAK
 case 146:
 case 146:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1527 "dhcp4_lexer.ll"
+#line 1528 "dhcp4_lexer.ll"
 { return isc::dhcp::Dhcp4Parser::make_LCURLY_BRACKET(driver.loc_); }
 { return isc::dhcp::Dhcp4Parser::make_LCURLY_BRACKET(driver.loc_); }
 	YY_BREAK
 	YY_BREAK
 case 147:
 case 147:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1528 "dhcp4_lexer.ll"
+#line 1529 "dhcp4_lexer.ll"
 { return isc::dhcp::Dhcp4Parser::make_RCURLY_BRACKET(driver.loc_); }
 { return isc::dhcp::Dhcp4Parser::make_RCURLY_BRACKET(driver.loc_); }
 	YY_BREAK
 	YY_BREAK
 case 148:
 case 148:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1529 "dhcp4_lexer.ll"
+#line 1530 "dhcp4_lexer.ll"
 { return isc::dhcp::Dhcp4Parser::make_COMMA(driver.loc_); }
 { return isc::dhcp::Dhcp4Parser::make_COMMA(driver.loc_); }
 	YY_BREAK
 	YY_BREAK
 case 149:
 case 149:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1530 "dhcp4_lexer.ll"
+#line 1531 "dhcp4_lexer.ll"
 { return isc::dhcp::Dhcp4Parser::make_COLON(driver.loc_); }
 { return isc::dhcp::Dhcp4Parser::make_COLON(driver.loc_); }
 	YY_BREAK
 	YY_BREAK
 case 150:
 case 150:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1532 "dhcp4_lexer.ll"
+#line 1533 "dhcp4_lexer.ll"
 {
 {
     /* An integer was found. */
     /* An integer was found. */
     std::string tmp(yytext);
     std::string tmp(yytext);
@@ -3949,7 +3950,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 151:
 case 151:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1550 "dhcp4_lexer.ll"
+#line 1551 "dhcp4_lexer.ll"
 {
 {
     /* A floating point was found. */
     /* A floating point was found. */
     std::string tmp(yytext);
     std::string tmp(yytext);
@@ -3965,7 +3966,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 152:
 case 152:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1563 "dhcp4_lexer.ll"
+#line 1564 "dhcp4_lexer.ll"
 {
 {
     string tmp(yytext);
     string tmp(yytext);
     return isc::dhcp::Dhcp4Parser::make_BOOLEAN(tmp == "true", driver.loc_);
     return isc::dhcp::Dhcp4Parser::make_BOOLEAN(tmp == "true", driver.loc_);
@@ -3973,33 +3974,33 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 153:
 case 153:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1568 "dhcp4_lexer.ll"
+#line 1569 "dhcp4_lexer.ll"
 {
 {
    return isc::dhcp::Dhcp4Parser::make_NULL_TYPE(driver.loc_);
    return isc::dhcp::Dhcp4Parser::make_NULL_TYPE(driver.loc_);
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 154:
 case 154:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1572 "dhcp4_lexer.ll"
+#line 1573 "dhcp4_lexer.ll"
 driver.error (driver.loc_, "JSON true reserved keyword is lower case only");
 driver.error (driver.loc_, "JSON true reserved keyword is lower case only");
 	YY_BREAK
 	YY_BREAK
 case 155:
 case 155:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1574 "dhcp4_lexer.ll"
+#line 1575 "dhcp4_lexer.ll"
 driver.error (driver.loc_, "JSON false reserved keyword is lower case only");
 driver.error (driver.loc_, "JSON false reserved keyword is lower case only");
 	YY_BREAK
 	YY_BREAK
 case 156:
 case 156:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1576 "dhcp4_lexer.ll"
+#line 1577 "dhcp4_lexer.ll"
 driver.error (driver.loc_, "JSON null reserved keyword is lower case only");
 driver.error (driver.loc_, "JSON null reserved keyword is lower case only");
 	YY_BREAK
 	YY_BREAK
 case 157:
 case 157:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1578 "dhcp4_lexer.ll"
+#line 1579 "dhcp4_lexer.ll"
 driver.error (driver.loc_, "Invalid character: " + std::string(yytext));
 driver.error (driver.loc_, "Invalid character: " + std::string(yytext));
 	YY_BREAK
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(INITIAL):
-#line 1580 "dhcp4_lexer.ll"
+#line 1581 "dhcp4_lexer.ll"
 {
 {
     if (driver.states_.empty()) {
     if (driver.states_.empty()) {
         return isc::dhcp::Dhcp4Parser::make_END(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_END(driver.loc_);
@@ -4025,10 +4026,10 @@ case YY_STATE_EOF(INITIAL):
 	YY_BREAK
 	YY_BREAK
 case 158:
 case 158:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 1603 "dhcp4_lexer.ll"
+#line 1604 "dhcp4_lexer.ll"
 ECHO;
 ECHO;
 	YY_BREAK
 	YY_BREAK
-#line 4031 "dhcp4_lexer.cc"
+#line 4032 "dhcp4_lexer.cc"
 
 
 	case YY_END_OF_BUFFER:
 	case YY_END_OF_BUFFER:
 		{
 		{
@@ -5133,7 +5134,7 @@ void yyfree (void * ptr )
 
 
 /* %ok-for-header */
 /* %ok-for-header */
 
 
-#line 1603 "dhcp4_lexer.ll"
+#line 1604 "dhcp4_lexer.ll"
 
 
 
 
 using namespace isc::dhcp;
 using namespace isc::dhcp;

+ 17 - 15
src/bin/dhcp4/dhcp4_lexer.ll

@@ -442,7 +442,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_VALID_LIFETIME(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_VALID_LIFETIME(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("valid-lifetime", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("valid-lifetime", driver.loc_);
@@ -453,7 +453,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_RENEW_TIMER(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_RENEW_TIMER(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("renew-timer", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("renew-timer", driver.loc_);
@@ -464,7 +464,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_REBIND_TIMER(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_REBIND_TIMER(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("rebind-timer", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("rebind-timer", driver.loc_);
@@ -492,10 +492,10 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 
 
 \"shared-networks\" {
 \"shared-networks\" {
     switch (driver.ctx_) {
     switch (driver.ctx_) {
-    case Parser4Context::DHCP4:
-        return Dhcp4Parser::make_SHARED_NETWORKS(driver.loc_);
+    case isc::dhcp::Parser4Context::DHCP4:
+        return isc::dhcp::Dhcp4Parser::make_SHARED_NETWORKS(driver.loc_);
     default:
     default:
-        return Dhcp4Parser::make_STRING("shared-networks", driver.loc_);
+        return isc::dhcp::Dhcp4Parser::make_STRING("shared-networks", driver.loc_);
     }
     }
 }
 }
 
 
@@ -513,11 +513,11 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
     case isc::dhcp::Parser4Context::POOLS:
     case isc::dhcp::Parser4Context::POOLS:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASS:
     case isc::dhcp::Parser4Context::CLIENT_CLASS:
-    case Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_OPTION_DATA(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_OPTION_DATA(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("option-data", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("option-data", driver.loc_);
@@ -532,7 +532,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     case isc::dhcp::Parser4Context::OPTION_DATA:
     case isc::dhcp::Parser4Context::OPTION_DATA:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASS:
     case isc::dhcp::Parser4Context::CLIENT_CLASS:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
     case isc::dhcp::Parser4Context::LOGGERS:
     case isc::dhcp::Parser4Context::LOGGERS:
         return isc::dhcp::Dhcp4Parser::make_NAME(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_NAME(driver.loc_);
     default:
     default:
@@ -598,7 +598,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 \"interface\" {
 \"interface\" {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_INTERFACE(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_INTERFACE(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("interface", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("interface", driver.loc_);
@@ -791,8 +791,8 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 \"client-class\" {
 \"client-class\" {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
-    case Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_CLIENT_CLASS(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_CLIENT_CLASS(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("client-class", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("client-class", driver.loc_);
@@ -926,7 +926,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 \"relay\" {
 \"relay\" {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_RELAY(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_RELAY(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("relay", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("relay", driver.loc_);
@@ -1352,8 +1352,6 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 \"echo-client-id\" {
 \"echo-client-id\" {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
-    case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_ECHO_CLIENT_ID(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_ECHO_CLIENT_ID(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("echo-client-id", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("echo-client-id", driver.loc_);
@@ -1364,7 +1362,7 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
-    case Parser4Context::SHARED_NETWORK:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_MATCH_CLIENT_ID(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_MATCH_CLIENT_ID(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("match-client-id", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("match-client-id", driver.loc_);
@@ -1375,9 +1373,9 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
-    case Parser4Context::SHARED_NETWORK:
         return isc::dhcp::Dhcp4Parser::make_NEXT_SERVER(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_NEXT_SERVER(driver.loc_);
     default:
     default:
         return isc::dhcp::Dhcp4Parser::make_STRING("next-server", driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_STRING("next-server", driver.loc_);
@@ -1386,7 +1384,9 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 
 
 \"server-hostname\" {
 \"server-hostname\" {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
+    case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
         return isc::dhcp::Dhcp4Parser::make_SERVER_HOSTNAME(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_SERVER_HOSTNAME(driver.loc_);
@@ -1397,7 +1397,9 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
 
 
 \"boot-file-name\" {
 \"boot-file-name\" {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
+    case isc::dhcp::Parser4Context::DHCP4:
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::SUBNET4:
+    case isc::dhcp::Parser4Context::SHARED_NETWORK:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::RESERVATIONS:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
         return isc::dhcp::Dhcp4Parser::make_BOOT_FILE_NAME(driver.loc_);
         return isc::dhcp::Dhcp4Parser::make_BOOT_FILE_NAME(driver.loc_);

+ 6 - 0
src/bin/dhcp4/dhcp4_parser.yy

@@ -430,6 +430,8 @@ global_param: valid_lifetime
             | echo_client_id
             | echo_client_id
             | match_client_id
             | match_client_id
             | next_server
             | next_server
+            | server_hostname
+            | boot_file_name
             | unknown_map_entry
             | unknown_map_entry
             ;
             ;
 
 
@@ -912,6 +914,8 @@ subnet4_param: valid_lifetime
              | relay
              | relay
              | match_client_id
              | match_client_id
              | next_server
              | next_server
+             | server_hostname
+             | boot_file_name
              | subnet_4o6_interface
              | subnet_4o6_interface
              | subnet_4o6_interface_id
              | subnet_4o6_interface_id
              | subnet_4o6_subnet
              | subnet_4o6_subnet
@@ -1039,6 +1043,8 @@ shared_network_param: name
                     | option_data_list
                     | option_data_list
                     | match_client_id
                     | match_client_id
                     | next_server
                     | next_server
+                    | server_hostname
+                    | boot_file_name
                     | relay
                     | relay
                     | reservation_mode
                     | reservation_mode
                     | client_class
                     | client_class

+ 22 - 0
src/bin/dhcp4/dhcp4_srv.cc

@@ -2214,6 +2214,28 @@ Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) {
         if (!subnet_next_server.isV4Zero()) {
         if (!subnet_next_server.isV4Zero()) {
             response->setSiaddr(subnet_next_server);
             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<const uint8_t*>(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<const uint8_t*>(filename.c_str()),
+                              filename.size());
+        }
     }
     }
 
 
     // Step 2: Try to set the values based on classes.
     // Step 2: Try to set the values based on classes.

+ 3 - 1
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 == "dhcp4o6-port") ||
                  (config_pair.first == "echo-client-id") ||
                  (config_pair.first == "echo-client-id") ||
                  (config_pair.first == "match-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;
                 continue;
             }
             }
 
 

+ 1 - 1
src/bin/dhcp4/location.hh

@@ -1,4 +1,4 @@
-// Generated 201709252348
+// Generated 201710011747
 // A Bison parser, made by GNU Bison 3.0.4.
 // A Bison parser, made by GNU Bison 3.0.4.
 
 
 // Locations for Bison parsers in C++
 // Locations for Bison parsers in C++

+ 1 - 1
src/bin/dhcp4/position.hh

@@ -1,4 +1,4 @@
-// Generated 201709252348
+// Generated 201710011747
 // A Bison parser, made by GNU Bison 3.0.4.
 // A Bison parser, made by GNU Bison 3.0.4.
 
 
 // Positions for Bison parsers in C++
 // Positions for Bison parsers in C++

+ 1 - 1
src/bin/dhcp4/stack.hh

@@ -1,4 +1,4 @@
-// Generated 201709252348
+// Generated 201710011747
 // A Bison parser, made by GNU Bison 3.0.4.
 // A Bison parser, made by GNU Bison 3.0.4.
 
 
 // Stack handling for Bison parsers in C++
 // Stack handling for Bison parsers in C++

+ 71 - 4
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.
 /// @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) {
 TEST_F(Dhcp4ParserTest, nextServerGlobal) {
 
 
     string config = "{ " + genIfaceConfig() + "," +
     string config = "{ " + genIfaceConfig() + "," +
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
         "\"next-server\": \"1.2.3.4\", "
         "\"next-server\": \"1.2.3.4\", "
+        "\"server-hostname\": \"foo\", "
+        "\"boot-file-name\": \"bar\", "
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
@@ -1135,10 +1137,12 @@ TEST_F(Dhcp4ParserTest, nextServerGlobal) {
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
     ASSERT_TRUE(subnet);
     ASSERT_TRUE(subnet);
     EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText());
     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) {
 TEST_F(Dhcp4ParserTest, nextServerSubnet) {
 
 
     string config = "{ " + genIfaceConfig() + "," +
     string config = "{ " + genIfaceConfig() + "," +
@@ -1147,6 +1151,8 @@ TEST_F(Dhcp4ParserTest, nextServerSubnet) {
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"next-server\": \"1.2.3.4\", "
         "    \"next-server\": \"1.2.3.4\", "
+        "    \"server-hostname\": \"foo\", "
+        "    \"boot-file-name\": \"bar\", "
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
         "\"valid-lifetime\": 4000 }";
 
 
@@ -1166,6 +1172,8 @@ TEST_F(Dhcp4ParserTest, nextServerSubnet) {
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
     ASSERT_TRUE(subnet);
     ASSERT_TRUE(subnet);
     EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText());
     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
 // Test checks several negative scenarios for next-server configuration: bogus
@@ -1209,12 +1217,43 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
         "\"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;
     ConstElementPtr json1;
     ASSERT_NO_THROW(json1 = parseDHCP4(config_bogus1));
     ASSERT_NO_THROW(json1 = parseDHCP4(config_bogus1));
     ConstElementPtr json2;
     ConstElementPtr json2;
     ASSERT_NO_THROW(json2 = parseDHCP4(config_bogus2));
     ASSERT_NO_THROW(json2 = parseDHCP4(config_bogus2));
     ConstElementPtr json3;
     ConstElementPtr json3;
     ASSERT_NO_THROW(json3 = parseDHCP4(config_bogus3));
     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
     // check if returned status is always a failure
     ConstElementPtr status;
     ConstElementPtr status;
@@ -1233,6 +1272,18 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
     EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json3));
     EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json3));
     checkResult(status, 0);
     checkResult(status, 0);
     EXPECT_FALSE(errorContainsPosition(status, "<string>"));
     EXPECT_FALSE(errorContainsPosition(status, "<string>"));
+
+    CfgMgr::instance().clear();
+
+    EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json4));
+    checkResult(status, 1);
+    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+
+    CfgMgr::instance().clear();
+
+    EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json5));
+    checkResult(status, 1);
+    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 }
 }
 
 
 // Checks if the next-server defined as global value is overridden by subnet
 // Checks if the next-server defined as global value is overridden by subnet
@@ -1243,9 +1294,13 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) {
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
         "\"next-server\": \"192.0.0.1\", "
         "\"next-server\": \"192.0.0.1\", "
+        "\"server-hostname\": \"nohost\","
+        "\"boot-file-name\": \"nofile\","        
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"next-server\": \"1.2.3.4\", "
         "    \"next-server\": \"1.2.3.4\", "
+        "    \"server-hostname\": \"some-name.example.org\","
+        "    \"boot-file-name\": \"bootfile.efi\","
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
         "\"valid-lifetime\": 4000 }";
 
 
@@ -1265,6 +1320,8 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) {
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
     ASSERT_TRUE(subnet);
     ASSERT_TRUE(subnet);
     EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText());
     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
 // Check whether it is possible to configure echo-client-id
@@ -5289,6 +5346,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
         "    \"interface\": \"eth0\",\n"
         "    \"interface\": \"eth0\",\n"
         "    \"match-client-id\": false,\n"
         "    \"match-client-id\": false,\n"
         "    \"next-server\": \"1.2.3.4\",\n"
         "    \"next-server\": \"1.2.3.4\",\n"
+        "    \"server-hostname\": \"foo\",\n"
+        "    \"boot-file-name\": \"bar\",\n"
         "    \"relay\": {\n"
         "    \"relay\": {\n"
         "        \"ip-address\": \"5.6.7.8\"\n"
         "        \"ip-address\": \"5.6.7.8\"\n"
         "    },\n"
         "    },\n"
@@ -5309,6 +5368,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
         "        \"valid-lifetime\": 400,\n"
         "        \"valid-lifetime\": 400,\n"
         "        \"match-client-id\": true,\n"
         "        \"match-client-id\": true,\n"
         "        \"next-server\": \"11.22.33.44\",\n"
         "        \"next-server\": \"11.22.33.44\",\n"
+        "        \"server-hostname\": \"some-name.example.org\",\n"
+        "        \"boot-file-name\": \"bootfile.efi\",\n"
         "        \"relay\": {\n"
         "        \"relay\": {\n"
         "            \"ip-address\": \"55.66.77.88\"\n"
         "            \"ip-address\": \"55.66.77.88\"\n"
         "        },\n"
         "        },\n"
@@ -5359,6 +5420,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
     EXPECT_EQ("eth0", s->getIface());
     EXPECT_EQ("eth0", s->getIface());
     EXPECT_FALSE(s->getMatchClientId());
     EXPECT_FALSE(s->getMatchClientId());
     EXPECT_EQ(IOAddress("1.2.3.4"), s->getSiaddr());
     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(IOAddress("5.6.7.8"), s->getRelayInfo().addr_);
     EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode());
     EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode());
 
 
@@ -5372,6 +5435,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
     EXPECT_EQ("eth0", s->getIface());
     EXPECT_EQ("eth0", s->getIface());
     EXPECT_TRUE(s->getMatchClientId());
     EXPECT_TRUE(s->getMatchClientId());
     EXPECT_EQ(IOAddress("11.22.33.44"), s->getSiaddr());
     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(IOAddress("55.66.77.88"), s->getRelayInfo().addr_);
     EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode());
     EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode());
 
 
@@ -5389,6 +5454,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
     EXPECT_EQ("", s->getIface());
     EXPECT_EQ("", s->getIface());
     EXPECT_TRUE(s->getMatchClientId());
     EXPECT_TRUE(s->getMatchClientId());
     EXPECT_EQ(IOAddress("0.0.0.0"), s->getSiaddr());
     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(IOAddress("0.0.0.0"), s->getRelayInfo().addr_);
     EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
     EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
 }
 }

+ 27 - 1
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

@@ -1337,7 +1337,7 @@ TEST_F(Dhcpv4SrvTest, siaddr) {
 // Checks if the next-server defined as global value is overridden by subnet
 // 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
 // specific value and returned in server messages. There's also similar test for
 // checking parser only configuration, see Dhcp4ParserTest.nextServerOverride in
 // 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) {
 TEST_F(Dhcpv4SrvTest, nextServerOverride) {
     IfaceMgrTestConfig test_config(true);
     IfaceMgrTestConfig test_config(true);
     IfaceMgr::instance().openSockets4();
     IfaceMgr::instance().openSockets4();
@@ -1352,9 +1352,13 @@ TEST_F(Dhcpv4SrvTest, nextServerOverride) {
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
         "\"next-server\": \"192.0.0.1\", "
         "\"next-server\": \"192.0.0.1\", "
+        "\"server-hostname\": \"nohost\", "
+        "\"boot-file-name\": \"nofile\", "
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\":  \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"pools\": [ { \"pool\":  \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"next-server\": \"1.2.3.4\", "
         "    \"next-server\": \"1.2.3.4\", "
+        "    \"server-hostname\": \"some-name.example.org\", "
+        "    \"boot-file-name\": \"bootfile.efi\", "
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
         "\"valid-lifetime\": 4000 }";
 
 
@@ -1382,6 +1386,16 @@ TEST_F(Dhcpv4SrvTest, nextServerOverride) {
     EXPECT_EQ(DHCPOFFER, offer->getType());
     EXPECT_EQ(DHCPOFFER, offer->getType());
 
 
     EXPECT_EQ("1.2.3.4", offer->getSiaddr().toText());
     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
 // Checks if the next-server defined as global value is used in responses
@@ -1402,6 +1416,8 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) {
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
         "\"next-server\": \"192.0.0.1\", "
         "\"next-server\": \"192.0.0.1\", "
+        "\"server-hostname\": \"some-name.example.org\", "
+        "\"boot-file-name\": \"bootfile.efi\", "
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
@@ -1431,6 +1447,16 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) {
     EXPECT_EQ(DHCPOFFER, offer->getType());
     EXPECT_EQ(DHCPOFFER, offer->getType());
 
 
     EXPECT_EQ("192.0.0.1", offer->getSiaddr().toText());
     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
 // Checks if server is able to handle a relayed traffic from DOCSIS3.0 modems

+ 2 - 0
src/bin/dhcp4/tests/dora_unittest.cc

@@ -278,6 +278,8 @@ const char* DORA_CONFIGS[] = {
         "},"
         "},"
         "\"valid-lifetime\": 600,"
         "\"valid-lifetime\": 600,"
         "\"next-server\": \"10.0.0.1\","
         "\"next-server\": \"10.0.0.1\","
+        "\"server-hostname\": \"nohost\","
+        "\"boot-file-name\": \"nofile\","
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"subnet\": \"10.0.0.0/24\", "
         "    \"subnet\": \"10.0.0.0/24\", "
         "    \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
         "    \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"

+ 120 - 0
src/bin/dhcp4/tests/get_config_unittest.cc

@@ -223,12 +223,14 @@ const char* EXTRACTED_CONFIGS[] = {
 "    }\n",
 "    }\n",
     // CONFIGURATION 6
     // CONFIGURATION 6
 "{\n"
 "{\n"
+"        \"boot-file-name\": \"bar\",\n"
 "        \"interfaces-config\": {\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
 "        },\n"
 "        \"next-server\": \"1.2.3.4\",\n"
 "        \"next-server\": \"1.2.3.4\",\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
 "        \"renew-timer\": 1000,\n"
+"        \"server-hostname\": \"foo\",\n"
 "        \"subnet4\": [\n"
 "        \"subnet4\": [\n"
 "            {\n"
 "            {\n"
 "                \"pools\": [\n"
 "                \"pools\": [\n"
@@ -250,12 +252,14 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"renew-timer\": 1000,\n"
 "        \"subnet4\": [\n"
 "        \"subnet4\": [\n"
 "            {\n"
 "            {\n"
+"                \"boot-file-name\": \"bar\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"pools\": [\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                    {\n"
 "                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
 "                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
 "                    }\n"
 "                    }\n"
 "                ],\n"
 "                ],\n"
+"                \"server-hostname\": \"foo\",\n"
 "                \"subnet\": \"192.0.2.0/24\"\n"
 "                \"subnet\": \"192.0.2.0/24\"\n"
 "            }\n"
 "            }\n"
 "        ],\n"
 "        ],\n"
@@ -263,20 +267,24 @@ const char* EXTRACTED_CONFIGS[] = {
 "    }\n",
 "    }\n",
     // CONFIGURATION 8
     // CONFIGURATION 8
 "{\n"
 "{\n"
+"        \"boot-file-name\": \"nofile\",\n"
 "        \"interfaces-config\": {\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
 "        },\n"
 "        \"next-server\": \"192.0.0.1\",\n"
 "        \"next-server\": \"192.0.0.1\",\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
 "        \"renew-timer\": 1000,\n"
+"        \"server-hostname\": \"nohost\",\n"
 "        \"subnet4\": [\n"
 "        \"subnet4\": [\n"
 "            {\n"
 "            {\n"
+"                \"boot-file-name\": \"bootfile.efi\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"pools\": [\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                    {\n"
 "                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
 "                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
 "                    }\n"
 "                    }\n"
 "                ],\n"
 "                ],\n"
+"                \"server-hostname\": \"some-name.example.org\",\n"
 "                \"subnet\": \"192.0.2.0/24\"\n"
 "                \"subnet\": \"192.0.2.0/24\"\n"
 "            }\n"
 "            }\n"
 "        ],\n"
 "        ],\n"
@@ -1670,6 +1678,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1687,6 +1696,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 900,\n"
 "                \"renew-timer\": 900,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -1738,6 +1748,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1755,6 +1766,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -1806,6 +1818,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1823,6 +1836,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -1874,6 +1888,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1891,6 +1906,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -1898,6 +1914,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 2,\n"
 "                \"id\": 2,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1915,6 +1932,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -1922,6 +1940,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 3,\n"
 "                \"id\": 3,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1939,6 +1958,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -1946,6 +1966,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 4,\n"
 "                \"id\": 4,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -1963,6 +1984,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2014,6 +2036,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1024,\n"
 "                \"id\": 1024,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2031,6 +2054,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -2038,6 +2062,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 100,\n"
 "                \"id\": 100,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2055,6 +2080,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -2062,6 +2088,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2079,6 +2106,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -2086,6 +2114,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 34,\n"
 "                \"id\": 34,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2103,6 +2132,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2154,6 +2184,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"bar\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
@@ -2171,6 +2202,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"foo\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2222,6 +2254,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"bar\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
@@ -2239,6 +2272,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"foo\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2290,6 +2324,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"bootfile.efi\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"next-server\": \"1.2.3.4\",\n"
@@ -2307,6 +2342,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"some-name.example.org\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2358,6 +2394,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2375,6 +2412,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2426,6 +2464,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2443,6 +2482,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2494,6 +2534,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2511,6 +2552,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -2518,6 +2560,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 2,\n"
 "                \"id\": 2,\n"
 "                \"match-client-id\": false,\n"
 "                \"match-client-id\": false,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2535,6 +2578,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2586,6 +2630,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": false,\n"
 "                \"match-client-id\": false,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2603,6 +2648,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -2610,6 +2656,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 2,\n"
 "                \"id\": 2,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2627,6 +2674,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2678,6 +2726,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2695,6 +2744,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1,\n"
 "                \"renew-timer\": 1,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4\n"
 "                \"valid-lifetime\": 4\n"
 "            }\n"
 "            }\n"
@@ -2746,6 +2796,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2767,6 +2818,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -2774,6 +2826,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 2,\n"
 "                \"id\": 2,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2795,6 +2848,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -2846,6 +2900,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -2863,6 +2918,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -3311,6 +3367,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3328,6 +3385,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -3379,6 +3437,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3413,6 +3472,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -3491,6 +3551,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3508,6 +3569,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -3691,6 +3753,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3708,6 +3771,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 3000\n"
 "                \"valid-lifetime\": 3000\n"
 "            }\n"
 "            }\n"
@@ -3768,6 +3832,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3802,6 +3867,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -3853,6 +3919,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3879,6 +3946,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -3886,6 +3954,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 2,\n"
 "                \"id\": 2,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3912,6 +3981,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -3963,6 +4033,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -3997,6 +4068,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -4048,6 +4120,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4087,6 +4160,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -4346,6 +4420,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4363,6 +4438,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 3000\n"
 "                \"valid-lifetime\": 3000\n"
 "            }\n"
 "            }\n"
@@ -4429,6 +4505,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4446,6 +4523,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -4516,6 +4594,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4533,6 +4612,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -4670,6 +4750,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4687,6 +4768,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -4738,6 +4820,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4755,6 +4838,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1,\n"
 "                \"renew-timer\": 1,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4\n"
 "                \"valid-lifetime\": 4\n"
 "            }\n"
 "            }\n"
@@ -4806,6 +4890,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 123,\n"
 "                \"id\": 123,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4823,6 +4908,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -4830,6 +4916,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 234,\n"
 "                \"id\": 234,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4902,6 +4989,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"server-hostname\": \"\"\n"
 "                        \"server-hostname\": \"\"\n"
 "                    }\n"
 "                    }\n"
 "                ],\n"
 "                ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -4909,6 +4997,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 542,\n"
 "                \"id\": 542,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -4974,6 +5063,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"server-hostname\": \"\"\n"
 "                        \"server-hostname\": \"\"\n"
 "                    }\n"
 "                    }\n"
 "                ],\n"
 "                ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5035,6 +5125,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 234,\n"
 "                \"id\": 234,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5072,6 +5163,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"server-hostname\": \"\"\n"
 "                        \"server-hostname\": \"\"\n"
 "                    }\n"
 "                    }\n"
 "                ],\n"
 "                ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5123,6 +5215,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5140,6 +5233,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -5147,6 +5241,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 2,\n"
 "                \"id\": 2,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5164,6 +5259,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"out-of-pool\",\n"
 "                \"reservation-mode\": \"out-of-pool\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -5171,6 +5267,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 3,\n"
 "                \"id\": 3,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5188,6 +5285,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"disabled\",\n"
 "                \"reservation-mode\": \"disabled\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            },\n"
 "            },\n"
@@ -5195,6 +5293,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 4,\n"
 "                \"id\": 4,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5212,6 +5311,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5435,6 +5535,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5452,6 +5553,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5503,6 +5605,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"2001:db8::123/45\",\n"
 "                \"4o6-subnet\": \"2001:db8::123/45\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5520,6 +5623,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5571,6 +5675,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"ethX\",\n"
 "                \"4o6-interface\": \"ethX\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5588,6 +5693,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5639,6 +5745,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"ethX\",\n"
 "                \"4o6-interface\": \"ethX\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"2001:db8::543/21\",\n"
 "                \"4o6-subnet\": \"2001:db8::543/21\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5656,6 +5763,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5707,6 +5815,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"vlan123\",\n"
 "                \"4o6-interface-id\": \"vlan123\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5724,6 +5833,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5801,6 +5911,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5818,6 +5929,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5869,6 +5981,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5886,6 +5999,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -5937,6 +6051,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -5955,6 +6070,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -6006,6 +6122,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -6028,6 +6145,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"
@@ -6079,6 +6197,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
+"                \"boot-file-name\": \"\",\n"
 "                \"id\": 1,\n"
 "                \"id\": 1,\n"
 "                \"match-client-id\": true,\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"next-server\": \"0.0.0.0\",\n"
@@ -6101,6 +6220,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservation-mode\": \"all\",\n"
 "                \"reservations\": [ ],\n"
 "                \"reservations\": [ ],\n"
+"                \"server-hostname\": \"\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"valid-lifetime\": 4000\n"
 "                \"valid-lifetime\": 4000\n"
 "            }\n"
 "            }\n"

+ 2 - 0
src/bin/dhcp4/tests/inform_unittest.cc

@@ -109,6 +109,8 @@ const char* INFORM_CONFIGS[] = {
         "},"
         "},"
         "\"valid-lifetime\": 600,"
         "\"valid-lifetime\": 600,"
         "\"next-server\": \"10.0.0.1\","
         "\"next-server\": \"10.0.0.1\","
+        "\"server-hostname\": \"nohost\","
+        "\"server-hostname\": \"nofile\","
         "\"subnet4\": [ { "
         "\"subnet4\": [ { "
         "    \"subnet\": \"192.0.2.0/24\", "
         "    \"subnet\": \"192.0.2.0/24\", "
         "    \"reservations\": [ "
         "    \"reservations\": [ "

+ 26 - 0
src/lib/dhcpsrv/parsers/dhcp_parsers.cc

@@ -622,6 +622,32 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
                   << next_server << "(" << pos << ")");
                   << 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
     // Get interface name. If it is defined, then the subnet is available
     // directly over specified network interface.
     // directly over specified network interface.
     std::string iface = getString(params, "interface");
     std::string iface = getString(params, "interface");

+ 5 - 1
src/lib/dhcpsrv/parsers/simple_parser4.cc

@@ -63,7 +63,9 @@ const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
     { "dhcp4o6-port",             Element::integer, "0" },
     { "dhcp4o6-port",             Element::integer, "0" },
     { "echo-client-id",           Element::boolean, "true" },
     { "echo-client-id",           Element::boolean, "true" },
     { "match-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.
 /// @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
 /// This list is also used for inheriting from global to shared networks
 /// and from shared networks to subnets within it.
 /// and from shared networks to subnets within it.
 const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
 const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
+    "boot-file-name",
     "client-class",
     "client-class",
     "interface",
     "interface",
     "match-client-id",
     "match-client-id",
@@ -126,6 +129,7 @@ const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
     "relay",
     "relay",
     "renew-timer",
     "renew-timer",
     "reservation-mode",
     "reservation-mode",
+    "server-hostname",
     "valid-lifetime"
     "valid-lifetime"
 };
 };
 
 

+ 21 - 0
src/lib/dhcpsrv/subnet.cc

@@ -239,6 +239,21 @@ isc::asiolink::IOAddress Subnet4::getSiaddr() const {
     return (siaddr_);
     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 {
 const PoolCollection& Subnet::getPools(Lease::Type type) const {
     // check if the type is valid (and throw if it isn't)
     // check if the type is valid (and throw if it isn't)
     checkType(type);
     checkType(type);
@@ -574,6 +589,12 @@ Subnet4::toElement() const {
     // Set next-server
     // Set next-server
     map->set("next-server", Element::create(getSiaddr().toText()));
     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
     // Set pools
     const PoolCollection& pools = getPools(Lease::TYPE_V4);
     const PoolCollection& pools = getPools(Lease::TYPE_V4);
     ElementPtr pool_list = Element::createList();
     ElementPtr pool_list = Element::createList();

+ 26 - 0
src/lib/dhcpsrv/subnet.h

@@ -457,6 +457,26 @@ public:
     /// @return siaddr value
     /// @return siaddr value
     isc::asiolink::IOAddress getSiaddr() const;
     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.
     /// @brief Returns DHCP4o6 configuration parameters.
     ///
     ///
     /// This structure is always available. If the 4o6 is not enabled, its
     /// This structure is always available. If the 4o6 is not enabled, its
@@ -497,6 +517,12 @@ private:
     /// @brief siaddr value for this subnet
     /// @brief siaddr value for this subnet
     isc::asiolink::IOAddress siaddr_;
     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
     /// @brief All the information related to DHCP4o6
     Cfg4o6 dhcp4o6_;
     Cfg4o6 dhcp4o6_;
 };
 };

+ 8 - 0
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc

@@ -752,6 +752,8 @@ TEST(CfgSubnets4Test, unparseSubnet) {
         "    \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
         "    \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
         "    \"match-client-id\": true,\n"
         "    \"match-client-id\": true,\n"
         "    \"next-server\": \"0.0.0.0\",\n"
         "    \"next-server\": \"0.0.0.0\",\n"
+        "    \"server-hostname\": \"\",\n"
+        "    \"boot-file-name\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"valid-lifetime\": 3,\n"
         "    \"valid-lifetime\": 3,\n"
@@ -769,6 +771,8 @@ TEST(CfgSubnets4Test, unparseSubnet) {
         "    \"interface\": \"lo\",\n"
         "    \"interface\": \"lo\",\n"
         "    \"match-client-id\": true,\n"
         "    \"match-client-id\": true,\n"
         "    \"next-server\": \"0.0.0.0\",\n"
         "    \"next-server\": \"0.0.0.0\",\n"
+        "    \"server-hostname\": \"\",\n"
+        "    \"boot-file-name\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"valid-lifetime\": 3,\n"
         "    \"valid-lifetime\": 3,\n"
@@ -785,6 +789,8 @@ TEST(CfgSubnets4Test, unparseSubnet) {
         "    \"interface\": \"eth1\",\n"
         "    \"interface\": \"eth1\",\n"
         "    \"match-client-id\": true,\n"
         "    \"match-client-id\": true,\n"
         "    \"next-server\": \"0.0.0.0\",\n"
         "    \"next-server\": \"0.0.0.0\",\n"
+        "    \"server-hostname\": \"\",\n"
+        "    \"boot-file-name\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"valid-lifetime\": 3,\n"
         "    \"valid-lifetime\": 3,\n"
@@ -819,6 +825,8 @@ TEST(CfgSubnets4Test, unparsePool) {
         "    \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
         "    \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
         "    \"match-client-id\": true,\n"
         "    \"match-client-id\": true,\n"
         "    \"next-server\": \"0.0.0.0\",\n"
         "    \"next-server\": \"0.0.0.0\",\n"
+        "    \"server-hostname\": \"\",\n"
+        "    \"boot-file-name\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"valid-lifetime\": 3,\n"
         "    \"valid-lifetime\": 3,\n"

+ 4 - 0
src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc

@@ -49,6 +49,8 @@ public:
                 "            \"valid-lifetime\": 300,"
                 "            \"valid-lifetime\": 300,"
                 "            \"match-client-id\": false,"
                 "            \"match-client-id\": false,"
                 "            \"next-server\": \"\","
                 "            \"next-server\": \"\","
+                "            \"server-hostname\": \"\","
+                "            \"boot-file-name\": \"\","
                 "            \"client-class\": \"\","
                 "            \"client-class\": \"\","
                 "            \"reservation-mode\": \"all\","
                 "            \"reservation-mode\": \"all\","
                 "            \"4o6-interface\": \"\","
                 "            \"4o6-interface\": \"\","
@@ -67,6 +69,8 @@ public:
                 "            \"valid-lifetime\": 30,"
                 "            \"valid-lifetime\": 30,"
                 "            \"match-client-id\": false,"
                 "            \"match-client-id\": false,"
                 "            \"next-server\": \"\","
                 "            \"next-server\": \"\","
+                "            \"server-hostname\": \"\","
+                "            \"boot-file-name\": \"\","
                 "            \"client-class\": \"\","
                 "            \"client-class\": \"\","
                 "            \"reservation-mode\": \"all\","
                 "            \"reservation-mode\": \"all\","
                 "            \"4o6-interface\": \"\","
                 "            \"4o6-interface\": \"\","

+ 4 - 0
src/lib/dhcpsrv/tests/shared_network_unittest.cc

@@ -222,6 +222,8 @@ TEST(SharedNetwork4Test, unparse) {
         "        \"id\": 1,\n"
         "        \"id\": 1,\n"
         "        \"match-client-id\": true,\n"
         "        \"match-client-id\": true,\n"
         "        \"next-server\": \"0.0.0.0\",\n"
         "        \"next-server\": \"0.0.0.0\",\n"
+        "        \"server-hostname\": \"\",\n"
+        "        \"boot-file-name\": \"\",\n"
         "        \"option-data\": [ ],\n"
         "        \"option-data\": [ ],\n"
         "        \"pools\": [ ],\n"
         "        \"pools\": [ ],\n"
         "        \"rebind-timer\": 20,\n"
         "        \"rebind-timer\": 20,\n"
@@ -240,6 +242,8 @@ TEST(SharedNetwork4Test, unparse) {
         "        \"id\": 2,\n"
         "        \"id\": 2,\n"
         "        \"match-client-id\": true,\n"
         "        \"match-client-id\": true,\n"
         "        \"next-server\": \"0.0.0.0\",\n"
         "        \"next-server\": \"0.0.0.0\",\n"
+        "        \"server-hostname\": \"\",\n"
+        "        \"boot-file-name\": \"\",\n"
         "        \"option-data\": [ ],\n"
         "        \"option-data\": [ ],\n"
         "        \"pools\": [ ],\n"
         "        \"pools\": [ ],\n"
         "        \"rebind-timer\": 20,\n"
         "        \"rebind-timer\": 20,\n"

+ 28 - 0
src/lib/dhcpsrv/tests/subnet_unittest.cc

@@ -116,6 +116,34 @@ TEST(Subnet4Test, siaddr) {
         BadValue);
         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.
 // Checks if the match-client-id flag can be set and retrieved.
 TEST(Subnet4Test, matchClientId) {
 TEST(Subnet4Test, matchClientId) {
     Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);
     Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);