]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[519-dhcp-server-response-an-empty-rai-field] Added the bad RAI case 519-dhcp-server-response-an-empty-rai-field
authorFrancis Dupont <fdupont@isc.org>
Sat, 9 Mar 2019 18:24:07 +0000 (19:24 +0100)
committerFrancis Dupont <fdupont@isc.org>
Tue, 12 Mar 2019 08:59:39 +0000 (04:59 -0400)
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/lib/dhcp/tests/pkt_captures.h
src/lib/dhcp/tests/pkt_captures4.cc

index 0ef7832e0326cda7015afa65372ab9c3a205ef12..40bbe2ca293c7b66c48981032cc215574ada7e98 100644 (file)
@@ -285,8 +285,9 @@ Dhcpv4Exchange::copyDefaultOptions() {
     }
 
     // If this packet is relayed, we want to copy Relay Agent Info option
+    // when it is not empty.
     OptionPtr rai = query_->getOption(DHO_DHCP_AGENT_OPTIONS);
-    if (rai) {
+    if (rai && (rai->len() > Option::OPTION4_HDR_LEN)) {
         resp_->addOption(rai);
     }
 
index 201fe3df37b82cdb54af38596b0f3d3f6ae78a16..638aefca655957f34532cb82d9c7f5ebcaa68910 100644 (file)
@@ -1509,6 +1509,53 @@ TEST_F(Dhcpv4SrvTest, relayAgentInfoEcho) {
     EXPECT_TRUE(rai_response->equals(rai_query));
 }
 
+// Checks if received bad relay agent info option is not echoed back
+// to the client
+TEST_F(Dhcpv4SrvTest, badRelayAgentInfoEcho) {
+    IfaceMgrTestConfig test_config(true);
+    IfaceMgr::instance().openSockets4();
+
+    NakedDhcpv4Srv srv(0);
+
+    // Use of the captured DHCPDISCOVER packet requires that
+    // subnet 10.254.226.0/24 is in use, because this packet
+    // contains the giaddr which belongs to this subnet and
+    // this giaddr is used to select the subnet
+    configure(CONFIGS[0]);
+
+    // Let's create a relayed DISCOVER. This particular relayed DISCOVER has
+    // added option 82 (relay agent info) with a sub-option which does not
+    // fit in the option. Unpacking it gave an empty option which is
+    // supposed to not be  echoed back in its response.
+    Pkt4Ptr dis;
+    ASSERT_NO_THROW(dis = PktCaptures::captureBadRelayedDiscover());
+
+    // Simulate that we have received that traffic
+    srv.fakeReceive(dis);
+
+    // Server will now process to run its normal loop, but instead of calling
+    // IfaceMgr::receive4(), it will read all packets from the list set by
+    // fakeReceive()
+    // In particular, it should call registered buffer4_receive callback.
+    srv.run();
+
+    // Check that the server did send a response
+    ASSERT_EQ(1, srv.fake_sent_.size());
+
+    // Make sure that we received a response
+    Pkt4Ptr offer = srv.fake_sent_.front();
+    ASSERT_TRUE(offer);
+
+    // Get Relay Agent Info from query...
+    OptionPtr rai_query = dis->getOption(DHO_DHCP_AGENT_OPTIONS);
+    ASSERT_TRUE(rai_query);
+    ASSERT_EQ(2, rai_query->len());
+
+    // Get Relay Agent Info from response...
+    OptionPtr rai_response = offer->getOption(DHO_DHCP_AGENT_OPTIONS);
+    ASSERT_FALSE(rai_response);
+}
+
 // Checks if client port can be overridden in packets being sent.
 TEST_F(Dhcpv4SrvTest, portsClientPort) {
     IfaceMgrTestConfig test_config(true);
index 56a3aaf10f2952648c827371d3de032f78574682..9e93ef04bfad9676a72a8e265df9d770b208ec59 100644 (file)
@@ -33,6 +33,14 @@ public:
     /// @return relayed DISCOVER
     static isc::dhcp::Pkt4Ptr captureRelayedDiscover2();
 
+    /// @brief returns captured DISCOVER that went through a relay
+    ///
+    /// See method code for a detailed explanation. This is a discover from
+    /// a buggy relay device with a bad suboption.
+    ///
+    /// @return relayed DISCOVER
+    static isc::dhcp::Pkt4Ptr captureBadRelayedDiscover();
+
     /// @brief returns captured DISCOVER that contains a valid VIVSO option
     ///
     /// See method code for a detailed explanation.
index 53836bea863f1dae1fc3c5c3d525b18f0a0dc49f..018506ed43f185bf3b6f34081c0009fab7582f6c 100644 (file)
@@ -178,6 +178,59 @@ Bootstrap Protocol
     return (packetFromCapture(hex_string));
 }
 
+Pkt4Ptr PktCaptures::captureBadRelayedDiscover() {
+
+/* Modified packet 1 with a bad RAI.
+
+Bootstrap Protocol
+    Message type: Boot Request (1)
+    Hardware type: Ethernet
+    Hardware address length: 6
+    Hops: 1
+    Transaction ID: 0x5d05478d
+    Seconds elapsed: 0
+    Bootp flags: 0x0000 (Unicast)
+    Client IP address: 0.0.0.0 (0.0.0.0)
+    Your (client) IP address: 0.0.0.0 (0.0.0.0)
+    Next server IP address: 0.0.0.0 (0.0.0.0)
+    Relay agent IP address: 10.254.226.1 (10.254.226.1)
+    Client MAC address: Netgear_b8:15:14 (20:e5:2a:b8:15:14)
+    Client hardware address padding: 00000000000000000000
+    Server host name not given
+    Boot file name not given
+    Magic cookie: DHCP
+    Option: (53) DHCP Message Type
+    Option: (55) Parameter Request List
+    Option: (60) Vendor class identifier (docsis3.0)
+    Option: (125) V-I Vendor-specific Information
+      - suboption 1 (Option Request): requesting option 2
+      - suboption 5 (Modem Caps): 117 bytes
+    Option: (43) Vendor-Specific Information (CableLabs)
+    Option: (61) Client identifier
+    Option: (57) Maximum DHCP Message Size
+    Option: (82) Agent Information Option */
+
+    string hex_string =
+        "010106015d05478d000000000000000000000000000000000afee20120e52ab8151400"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000638253633501013707"
+        "0102030407067d3c0a646f63736973332e303a7d7f0000118b7a010102057501010102"
+        "010303010104010105010106010107010f0801100901030a01010b01180c01010d0200"
+        "400e0200100f010110040000000211010014010015013f160101170101180104190104"
+        "1a01041b01201c01021d01081e01201f01102001102101022201012301002401002501"
+        "01260200ff2701012b59020345434d030b45434d3a45524f55544552040d3242523232"
+        "39553430303434430504312e3034060856312e33332e30330707322e332e3052320806"
+        "30303039354209094347333030304443520a074e657467656172fe01083d0fff2ab815"
+        "140003000120e52ab81514390205dc52205141000102030405060708090a0b0c0d0e0f"
+        "101112131415161718191a1b1c1d";
+
+    return (packetFromCapture(hex_string));
+}
+
 Pkt4Ptr PktCaptures::discoverWithValidVIVSO() {
 /* DISCOVER that contains a valid VIVSO option 125
 User    Datagram    Protocol,   Src Port:   67, Dst Port:   67