From: Marcin Siodelski Date: Mon, 13 Jan 2014 17:18:46 +0000 (+0100) Subject: [3279] Implemented a Dhcpv4Srv function which checks server identifier. X-Git-Tag: bind10-1.2.0beta1-release~141^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eb73d9223bbb17aed86eabaf29e62f9e18ac089d;p=thirdparty%2Fkea.git [3279] Implemented a Dhcpv4Srv function which checks server identifier. --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 39dde03388..bb568a8148 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -1525,6 +1525,34 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) { return (subnet); } +bool +Dhcpv4Srv::acceptServerId(const Pkt4Ptr& pkt) const { + // This function is meant to be called internally by the server class, so + // we rely on the caller to sanity check the pointer and we don't check + // it here. + + // Check if server identifier option is present. If it is not present + // we accept the message because it is targetted to all servers. + // Note that we don't check cases that server identifier is mandatory + // but not present. This is meant to be sanity checked in other + // functions. + OptionPtr option = pkt->getOption(DHO_DHCP_SERVER_IDENTIFIER); + if (!option) { + return (true); + } + // Server identifier is present. Let's convert it to 4-byte address + // and try to match with server identifiers used by the server. + Option4AddrLstPtr option_addrs = + boost::dynamic_pointer_cast(option); + Option4AddrLst::AddressContainer addrs = option_addrs->getAddresses(); + + if (addrs.size() != 1) { + return (false); + } + + return (IfaceMgr::instance().hasOpenSocket(addrs[0])); +} + void Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) { OptionPtr server_id = pkt->getOption(DHO_DHCP_SERVER_IDENTIFIER); diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h index 324ba4fa0d..04e622babe 100644 --- a/src/bin/dhcp4/dhcp4_srv.h +++ b/src/bin/dhcp4/dhcp4_srv.h @@ -167,6 +167,21 @@ public: protected: + /// @brief Verifies if the server id belongs to our server. + /// + /// This function checks if the server identifier carried in the specified + /// DHCPv4 message belongs to this server. If the server identifier option + /// is absent or the value carried by this option is equal to one of the + /// server identifiers used by the server, the true is returned. If the + /// server identifier option is present, but it doesn't match any server + /// identifier used by this server, the false value is returned. + /// + /// @param pkt DHCPv4 message which server identifier is to be checked. + /// + /// @return true, if the server identifier is absent or matches one of the + /// server identifiers that the server is using; false otherwise. + bool acceptServerId(const Pkt4Ptr& pkt) const; + /// @brief verifies if specified packet meets RFC requirements /// /// Checks if mandatory option is really there, that forbidden option diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 5142c70c06..2871c903d3 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -1031,6 +1031,52 @@ TEST_F(Dhcpv4SrvFakeIfaceTest, RenewBasic) { EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); } +// This test verifies that the logic which matches server identifier in the +// received message with server identifiers used by a server works correctly: +// - a message with no server identifier is accepted, +// - a message with a server identifier which matches one of the server +// identifiers used by a server is accepted, +// - a message with a server identifier which doesn't match any server +// identifier used by a server, is not accepted. +TEST_F(Dhcpv4SrvFakeIfaceTest, acceptServerId) { + NakedDhcpv4Srv srv(0); + + Pkt4Ptr pkt(new Pkt4(DHCPREQUEST, 1234)); + // If no server identifier option is present, the message is always + // accepted. + EXPECT_TRUE(srv.acceptServerId(pkt)); + + // Add a server identifier option which doesn't match server ids being + // used by the server. The accepted server ids are the IPv4 addresses + // configured on the interfaces. The 10.1.2.3 is not configured on + // any interface. + OptionPtr other_serverid(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER, + IOAddress("10.1.2.3"))); + pkt->addOption(other_serverid); + EXPECT_FALSE(srv.acceptServerId(pkt)); + + // Remove the server identifier. + ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER)); + + // Add a server id being an IPv4 address configured on eth0 interface. + // A DHCPv4 message holding this server identifier should be accepted. + OptionPtr eth0_serverid(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER, + IOAddress("192.0.3.1"))); + ASSERT_NO_THROW(pkt->addOption(eth0_serverid)); + EXPECT_TRUE(srv.acceptServerId(pkt)); + + // Remove the server identifier. + ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER)); + + // Add a server id being an IPv4 address configured on eth1 interface. + // A DHCPv4 message holding this server identifier should be accepted. + OptionPtr eth1_serverid(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER, + IOAddress("10.0.0.1"))); + ASSERT_NO_THROW(pkt->addOption(eth1_serverid)); + EXPECT_TRUE(srv.acceptServerId(pkt)); + +} + // @todo: Implement tests for rejecting renewals // This test verifies if the sanityCheck() really checks options presence. diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.h b/src/bin/dhcp4/tests/dhcp4_test_utils.h index ebb6300a5d..65ae312329 100644 --- a/src/bin/dhcp4/tests/dhcp4_test_utils.h +++ b/src/bin/dhcp4/tests/dhcp4_test_utils.h @@ -438,6 +438,7 @@ public: using Dhcpv4Srv::processClientName; using Dhcpv4Srv::computeDhcid; using Dhcpv4Srv::createNameChangeRequests; + using Dhcpv4Srv::acceptServerId; using Dhcpv4Srv::sanityCheck; using Dhcpv4Srv::srvidToString; using Dhcpv4Srv::unpackOptions;