From: Marcin Siodelski Date: Wed, 11 Mar 2015 11:06:38 +0000 (+0100) Subject: [3688] Host reservation parser doesn't allow for 0 or bcast address. X-Git-Tag: trac3764_base~12^2~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9650ed49bbb8233112b486c88cae1bebfe567fcc;p=thirdparty%2Fkea.git [3688] Host reservation parser doesn't allow for 0 or bcast address. --- diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc index 626ccfaa92..694af9e94b 100644 --- a/src/lib/dhcpsrv/host.cc +++ b/src/lib/dhcpsrv/host.cc @@ -83,15 +83,17 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len, const std::string& dhcp6_client_classes) : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id), ipv6_subnet_id_(ipv6_subnet_id), - ipv4_reservation_(asiolink::IOAddress("0.0.0.0")), + ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()), hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes), dhcp6_client_classes_(dhcp6_client_classes) { // Initialize HWAddr or DUID setIdentifier(identifier, identifier_len, identifier_type); - // Validate and set IPv4 address reservation. - setIPv4Reservation(ipv4_reservation); + if (!ipv4_reservation.isV4Zero()) { + // Validate and set IPv4 address reservation. + setIPv4Reservation(ipv4_reservation); + } } Host::Host(const std::string& identifier, const std::string& identifier_name, @@ -102,15 +104,17 @@ Host::Host(const std::string& identifier, const std::string& identifier_name, const std::string& dhcp6_client_classes) : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id), ipv6_subnet_id_(ipv6_subnet_id), - ipv4_reservation_(asiolink::IOAddress("0.0.0.0")), + ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()), hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes), dhcp6_client_classes_(dhcp6_client_classes) { // Initialize HWAddr or DUID setIdentifier(identifier, identifier_name); - // Validate and set IPv4 address reservation. - setIPv4Reservation(ipv4_reservation); + if (!ipv4_reservation.isV4Zero()) { + // Validate and set IPv4 address reservation. + setIPv4Reservation(ipv4_reservation); + } } const std::vector& @@ -172,10 +176,17 @@ Host::setIPv4Reservation(const asiolink::IOAddress& address) { if (!address.isV4()) { isc_throw(isc::BadValue, "address '" << address << "' is not a valid" " IPv4 address"); + } else if (address.isV4Zero() || address.isV4Bcast()) { + isc_throw(isc::BadValue, "must not make reservation for the '" + << address << "' address"); } ipv4_reservation_ = address; } +void +Host::removeIPv4Reservation() { + ipv4_reservation_ = asiolink::IOAddress::IPV4_ZERO_ADDRESS(); +} void Host::addReservation(const IPv6Resrv& reservation) { diff --git a/src/lib/dhcpsrv/host.h b/src/lib/dhcpsrv/host.h index 3b1b606a08..f770e31256 100644 --- a/src/lib/dhcpsrv/host.h +++ b/src/lib/dhcpsrv/host.h @@ -337,9 +337,15 @@ public: /// /// @param address Address to be reserved for the client. /// - /// @throw isc::BadValue if the provided address is not an IPv4 address. + /// @throw isc::BadValue if the provided address is not an IPv4 address, + /// is a 0 address or broadcast address. void setIPv4Reservation(const asiolink::IOAddress& address); + /// @brief Removes the IPv4 reservation. + /// + /// Sets the IPv4 reserved address to 0. + void removeIPv4Reservation(); + /// @brief Returns reserved IPv4 address. /// /// @return IPv4 address or 0.0.0.0 if no IPv4 reservation specified. diff --git a/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc b/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc index ef292dd933..5c94779f71 100644 --- a/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2015 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 @@ -249,6 +249,30 @@ TEST_F(HostReservationParserTest, malformedAddress) { EXPECT_THROW(parser.build(config_element), DhcpConfigError); } +// This test verifies that the configuration parser for host reservations +// throws an exception when zero IP address is specified. +TEST_F(HostReservationParserTest, zeroAddress) { + std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\"," + "\"ip-address\": \"0.0.0.0\" }"; + + ElementPtr config_element = Element::fromJSON(config); + + HostReservationParser4 parser(SubnetID(10)); + EXPECT_THROW(parser.build(config_element), DhcpConfigError); +} + +// This test verifies that the configuration parser for host reservations +// throws an exception when broadcast IP address is specified. +TEST_F(HostReservationParserTest, bcastAddress) { + std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\"," + "\"ip-address\": \"255.255.255.255\" }"; + + ElementPtr config_element = Element::fromJSON(config); + + HostReservationParser4 parser(SubnetID(10)); + EXPECT_THROW(parser.build(config_element), DhcpConfigError); +} + // This test verfies that the parser can parse the IPv6 reservation entry for // which hw-address is a host identifier. TEST_F(HostReservationParserTest, dhcp6HWaddr) { diff --git a/src/lib/dhcpsrv/tests/host_unittest.cc b/src/lib/dhcpsrv/tests/host_unittest.cc index f89d044515..c19c1d390c 100644 --- a/src/lib/dhcpsrv/tests/host_unittest.cc +++ b/src/lib/dhcpsrv/tests/host_unittest.cc @@ -427,9 +427,20 @@ TEST(HostTest, setValues) { EXPECT_EQ("10.0.0.1", host->getIPv4Reservation().toText()); EXPECT_EQ("other-host.example.org", host->getHostname()); + // Remove IPv4 reservation. + host->removeIPv4Reservation(); + EXPECT_EQ(IOAddress::IPV4_ZERO_ADDRESS(), host->getIPv4Reservation()); + // An IPv6 address can't be used for IPv4 reservations. EXPECT_THROW(host->setIPv4Reservation(IOAddress("2001:db8:1::1")), isc::BadValue); + // Zero address can't be set, the removeIPv4Reservation should be + // used intead. + EXPECT_THROW(host->setIPv4Reservation(IOAddress::IPV4_ZERO_ADDRESS()), + isc::BadValue); + // Broadcast address can't be set. + EXPECT_THROW(host->setIPv4Reservation(IOAddress::IPV4_BCAST_ADDRESS()), + isc::BadValue); } // Test that Host constructors initialize client classes from string.