Commit eb73d922 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3279] Implemented a Dhcpv4Srv function which checks server identifier.

parent 779a2309
// 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<Option4AddrLst>(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);
......
......@@ -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
......
// 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.
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment