]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#464,!238] New unit-test implemented for vendor opts processing
authorTomek Mrugalski <tomasz@isc.org>
Fri, 15 Feb 2019 14:54:18 +0000 (15:54 +0100)
committerTomek Mrugalski <tomasz@isc.org>
Tue, 19 Feb 2019 11:15:37 +0000 (12:15 +0100)
src/bin/dhcp4/tests/vendor_opts_unittest.cc
src/lib/dhcp/tests/pkt_captures.h
src/lib/dhcp/tests/pkt_captures4.cc

index 583b5fc4c392caa29702eaf75aa1217b96ef096d..f05301170894f3328995e848b3206c4fed4cd3e7 100644 (file)
@@ -28,6 +28,7 @@
 #include <dhcp/tests/iface_mgr_test_config.h>
 #include <dhcp/option_int_array.h>
 #include <dhcp/option_int.h>
+#include <dhcp/option_string.h>
 #include <dhcp/option_vendor.h>
 #include <dhcp/tests/pkt_captures.h>
 #include <dhcp/docsis3_option_defs.h>
@@ -432,8 +433,6 @@ TEST_F(VendorOptsTest, docsisClientClassification) {
     ASSERT_NO_THROW(dis1 = PktCaptures::captureRelayedDiscover());
     ASSERT_NO_THROW(dis1->unpack());
 
-    std::cout << dis1->toText() << std::endl;
-
     srv.classifyPacket(dis1);
 
     EXPECT_TRUE(dis1->inClass(srv.VENDOR_CLASS_PREFIX + "docsis3.0:"));
@@ -451,6 +450,80 @@ TEST_F(VendorOptsTest, docsisClientClassification) {
     EXPECT_FALSE(dis2->inClass(srv.VENDOR_CLASS_PREFIX + "docsis3.0:"));
 }
 
+// Checks that it's possible to have a vivso (125) option in the response
+// only. Once specific client (Genexis) sends only vendor-class info and
+// expects the server to include vivso in the response.
+TEST_F(VendorOptsTest, vendorInResponseOnly) {
+    IfaceMgrTestConfig test_config(true);
+    IfaceMgr::instance().openSockets4();
+    Dhcp4Client client;
+
+    // The config defines custom vendor 125 suboption 2 that conveys a TFTP URL.
+    // The client doesn't send vendor 125 option, so normal vendor option
+    // processing is impossible. However, since there's a class defined that
+    // matches client's packets and that class inserts vivso in the response,
+    // Kea should be able to figure out the vendor-id and then also insert
+    // suboption 2 with the TFTP URL.
+    string config =
+        "{"
+        "    \"interfaces-config\": {"
+        "        \"interfaces\": [ \"*\" ]"
+        "    },"
+        "    \"rebind-timer\": 2000, "
+        "    \"renew-timer\": 1000, "
+        "    \"option-def\": ["
+        "        {"
+        "            \"name\": \"tftp\","
+        "            \"code\": 2,"
+        "            \"space\": \"vendor-25167\","
+        "            \"type\": \"string\""
+        "        }"
+        "    ],"
+        "    \"client-classes\": ["
+        "    {"
+        "        \"name\": \"cpe_genexis\","
+        "        \"test\": \"substring(option[60].hex,0,7) == 'HMC1000'\","
+        "        \"option-data\": ["
+        "        {"
+        "            \"name\": \"vivso-suboptions\","
+        "            \"data\": \"25167\""
+        "        },"
+        "        {"
+        "            \"name\": \"tftp\","
+        "            \"space\": \"vendor-25167\","
+        "            \"data\": \"tftp://192.0.2.1/genexis/HMC1000.v1.3.0-R.img\","
+        "            \"always-send\": true"
+        "        } ]"
+        "    } ],"
+        "\"subnet4\": [ { "
+        "    \"pools\": [ { \"pool\": \"192.0.2.0/25\" } ],"
+        "    \"subnet\": \"192.0.2.0/24\", "
+        "    \"rebind-timer\": 2000, "
+        "    \"renew-timer\": 1000, "
+        "    \"valid-lifetime\": 4000,"
+        "    \"interface\": \"eth0\" "
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    EXPECT_NO_THROW(configure(config, *client.getServer()));
+
+    // A a vendor-class identifier (this matches what Genexis hardware sends)
+    OptionPtr vopt(new OptionString(Option::V4, DHO_VENDOR_CLASS_IDENTIFIER,
+                                    "HMC1000.v1.3.0-R,Element-P1090,genexis.eu"));
+    client.addExtraOption(vopt);
+
+    // Let's check whether the server is not able to process this packet
+    // and raises an exception so the response is empty.
+    EXPECT_NO_THROW(client.doDiscover());
+    ASSERT_TRUE(client.getContext().response_);
+
+    OptionPtr rsp = client.getContext().response_->getOption(DHO_VENDOR_ENCAPSULATED_OPTIONS);
+    ASSERT_TRUE(rsp);
+    EXPECT_EQ("HMC1000.v1.3.0-R,Element-P1090,genexis.eu",
+              rsp->toText());
+}
+
+
 // Verifies last resort option 43 is backward compatible
 TEST_F(VendorOptsTest, option43LastResort) {
     IfaceMgrTestConfig test_config(true);
index 2f8ce420bef2098caa6eb5538f5b9ca990e96d78..5ac899758b17b1e01e5bd14e9fe01c642a29456a 100644 (file)
@@ -47,6 +47,13 @@ public:
     /// @return relayed DISCOVER
     static isc::dhcp::Pkt4Ptr discoverWithTruncatedVIVSO();
 
+    /// @brief returns captured DISCOVER from Genexis hardware.
+    ///
+    /// This device in uncommon, because it doesn't send VIVSO in Dicover, but
+    /// expects one in Offer.
+    /// @return DISCOVER.
+    static isc::dhcp::Pkt4Ptr discoverGenexis();
+
     // see pkt_captures6.cc for descriptions
     // The descriptions are too large and too closely related to the
     // code, so it is kept in .cc rather than traditionally in .h
index 75596384b71f6fea6d2894c6d73bd62a26bba36b..3982c535c40efdc96b5faef7d04a46d28109b3e1 100644 (file)
@@ -282,6 +282,53 @@ Bootstrap   Protocol    (Discover)
     return (packetFromCapture(hex_string));
 }
 
+Pkt4Ptr PktCaptures::discoverGenexis() {
+
+/* Bootstrap Protocol (Discover)
+    Message type: Boot Request (1)
+    Hardware type: Ethernet (0x01)
+    Hardware address length: 6
+    Hops: 0
+    Transaction ID: 0x946a5b5a
+    Seconds elapsed: 0
+    Bootp flags: 0x8000, Broadcast flag (Broadcast)
+    Client IP address: 0.0.0.0
+    Your (client) IP address: 0.0.0.0
+    Next server IP address: 0.0.0.0
+    Relay agent IP address: 0.0.0.0
+    Client MAC address: GenexisB_6a:1a:93 (00:0f:94:6a:1a:93)
+    Client hardware address padding: 00000000000000000000
+    Server host name not given
+    Boot file name not given
+    Magic cookie: DHCP
+    Option: (53) DHCP Message Type (Discover)
+    Option: (60) Vendor class identifier (HMC1000.v1.3.0-R,Element-P1090,genexis.eu)
+    Option: (51) IP Address Lease Time
+    Option: (55) Parameter Request List
+    Option: (255) End
+    Padding: 000000000000000000000000000000000000000000000000... */
+
+    string hex_string =
+        "01010600946a5b5a0000800000000000000000000000000000000000000f946a1a9300"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000638253633501013c29"
+        "484d43313030302e76312e332e302d522c456c656d656e742d50313039302c67656e65"
+        "7869732e65753304ffffffff37040103067dff00000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000";
+    return (packetFromCapture(hex_string));
+}
+
 }; // end of isc::dhcp::test namespace
 }; // end of isc::dhcp namespace
 }; // end of isc namespace