From: Francis Dupont Date: Sat, 9 Mar 2019 18:24:07 +0000 (+0100) Subject: [519-dhcp-server-response-an-empty-rai-field] Added the bad RAI case X-Git-Tag: Kea-1.6.0-beta~394 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3563396d2227e48e96a5d65587406d8d1868db5;p=thirdparty%2Fkea.git [519-dhcp-server-response-an-empty-rai-field] Added the bad RAI case --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 0ef7832e03..40bbe2ca29 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -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); } diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 201fe3df37..638aefca65 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -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); diff --git a/src/lib/dhcp/tests/pkt_captures.h b/src/lib/dhcp/tests/pkt_captures.h index 56a3aaf10f..9e93ef04bf 100644 --- a/src/lib/dhcp/tests/pkt_captures.h +++ b/src/lib/dhcp/tests/pkt_captures.h @@ -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. diff --git a/src/lib/dhcp/tests/pkt_captures4.cc b/src/lib/dhcp/tests/pkt_captures4.cc index 53836bea86..018506ed43 100644 --- a/src/lib/dhcp/tests/pkt_captures4.cc +++ b/src/lib/dhcp/tests/pkt_captures4.cc @@ -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