Commit c3d50f87 authored by Marcin Siodelski's avatar Marcin Siodelski

[3699] Added trace messages to the CfgHosts class.

parent e366ba78
/dhcpsrv_messages.cc
/dhcpsrv_messages.h
/hosts_messages.cc
/hosts_messages.h
/s-messages
......@@ -35,19 +35,22 @@ EXTRA_DIST += parsers/host_reservation_parser.h
EXTRA_DIST += parsers/host_reservations_list_parser.h
# Define rule to build logging source files from message file
dhcpsrv_messages.h dhcpsrv_messages.cc: s-messages
dhcpsrv_messages.h dhcpsrv_messages.cc hosts_messages.h hosts_messages.cc: s-messages
s-messages: dhcpsrv_messages.mes
s-messages: dhcpsrv_messages.mes hosts_messages.mes
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/dhcpsrv_messages.mes
touch $@
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/hosts_messages.mes
touch $@
# Tell Automake that the dhcpsrv_messages.{cc,h} source files are created in the
# build process, so it must create these before doing anything else. Although
# they are a dependency of the library (so will be created from the message file
# anyway), there is no guarantee as to exactly _when_ in the build they will be
# Tell Automake that the {dhcpsrv,hosts}_messages.{cc,h} source files are created
# in the build process, so it must create these before doing anything else.
# Although they are a dependency of the library (so will be created from the message
# file anyway), there is no guarantee as to exactly _when_ in the build they will be
# created. As the .h file is included in other sources file (so must be
# present when they are compiled), the safest option is to create it first.
BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
BUILT_SOURCES += hosts_messages.h hosts_messages.cc
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
......@@ -56,7 +59,8 @@ BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
# Make sure the generated files are deleted in a "clean" operation
CLEANFILES = *.gcno *.gcda dhcpsrv_messages.h dhcpsrv_messages.cc s-messages
CLEANFILES = *.gcno *.gcda dhcpsrv_messages.h dhcpsrv_messages.cc
CLEANFILES += hosts_messages.h hosts_messages.cc s-messages
# Remove CSV files created by the CSVLeaseFile6 and CSVLeaseFile4 unit tests.
CLEANFILES += *.csv
......@@ -84,6 +88,7 @@ libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES += host.cc host.h
libkea_dhcpsrv_la_SOURCES += host_container.h
libkea_dhcpsrv_la_SOURCES += host_mgr.cc host_mgr.h
libkea_dhcpsrv_la_SOURCES += hosts_log.cc hosts_log.h
libkea_dhcpsrv_la_SOURCES += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_file_loader.h
......@@ -125,6 +130,7 @@ libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.h
nodist_libkea_dhcpsrv_la_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
nodist_libkea_dhcpsrv_la_SOURCES += hosts_messages.h hosts_messages.cc
libkea_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS)
libkea_dhcpsrv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
......@@ -154,6 +160,7 @@ endif
# The message file should be in the distribution
EXTRA_DIST += dhcpsrv_messages.mes
EXTRA_DIST += hosts_messages.mes
# Distribute backend documentation
# Database schema creation script moved to src/bin/admin
......
......@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/cfg_hosts.h>
#include <dhcpsrv/hosts_log.h>
#include <exceptions/exceptions.h>
#include <ostream>
......@@ -23,6 +24,8 @@ namespace dhcp {
ConstHostCollection
CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
// Do not issue logging message here because it will be logged by
// the getAllInternal method.
ConstHostCollection collection;
getAllInternal<ConstHostCollection>(hwaddr, duid, collection);
return (collection);
......@@ -30,6 +33,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
HostCollection
CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) {
// Do not issue logging message here because it will be logged by
// the getAllInternal method.
HostCollection collection;
getAllInternal<HostCollection>(hwaddr, duid, collection);
return (collection);
......@@ -37,6 +42,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) {
ConstHostCollection
CfgHosts::getAll4(const IOAddress& address) const {
// Do not issue logging message here because it will be logged by
// the getAllInternal4 method.
ConstHostCollection collection;
getAllInternal4<ConstHostCollection>(address, collection);
return (collection);
......@@ -44,6 +51,8 @@ CfgHosts::getAll4(const IOAddress& address) const {
HostCollection
CfgHosts::getAll4(const IOAddress& address) {
// Do not issue logging message here because it will be logged by
// the getAllInternal4 method.
HostCollection collection;
getAllInternal4<HostCollection>(address, collection);
return (collection);
......@@ -51,6 +60,8 @@ CfgHosts::getAll4(const IOAddress& address) {
ConstHostCollection
CfgHosts::getAll6(const IOAddress& address) const {
// Do not issue logging message here because it will be logged by
// the getAllInternal6 method.
ConstHostCollection collection;
getAllInternal6<ConstHostCollection>(address, collection);
return (collection);
......@@ -58,6 +69,8 @@ CfgHosts::getAll6(const IOAddress& address) const {
HostCollection
CfgHosts::getAll6(const IOAddress& address) {
// Do not issue logging message here because it will be logged by
// the getAllInternal6 method.
HostCollection collection;
getAllInternal6<HostCollection>(address, collection);
return (collection);
......@@ -68,6 +81,8 @@ void
CfgHosts::getAllInternal(const std::vector<uint8_t>& identifier,
const Host::IdentifierType& identifier_type,
Storage& storage) const {
// HOST_RESRV_GET_ALL_IDENTIFIER
// Use the identifier and identifier type as a composite key.
const HostContainerIndex0& idx = hosts_.get<0>();
boost::tuple<const std::vector<uint8_t>, const Host::IdentifierType> t =
......@@ -84,6 +99,10 @@ template<typename Storage>
void
CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_HWADDR_DUID)
.arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)")
.arg(duid ? duid->toText() : "(no-duid)");
// Get hosts using HW address.
if (hwaddr) {
getAllInternal<Storage>(hwaddr->hwaddr_, Host::IDENT_HWADDR, storage);
......@@ -97,6 +116,9 @@ CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
template<typename Storage>
void
CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_ADDRESS4)
.arg(address.toText());
// Must not specify address other than IPv4.
if (!address.isV4()) {
isc_throw(BadHostAddress, "must specify an IPv4 address when searching"
......@@ -115,6 +137,9 @@ CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
template<typename Storage>
void
CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_ADDRESS6)
.arg(address.toText());
// Must not specify address other than IPv6.
if (!address.isV6()) {
isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
......@@ -134,6 +159,7 @@ CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const {
ConstHostPtr
CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) const {
// Do not log here because getHostInternal logs.
// The false value indicates that it is an IPv4 subnet.
return (getHostInternal(subnet_id, false, hwaddr, duid));
}
......@@ -141,12 +167,16 @@ CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
HostPtr
CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) {
// Do not log here because getHostInternal logs.
// The false value indicates that it is an IPv4 subnet.
return (getHostInternal(subnet_id, false, hwaddr, duid));
}
ConstHostPtr
CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4)
.arg(subnet_id).arg(address.toText());
ConstHostCollection hosts = getAll4(address);
for (ConstHostCollection::const_iterator host = hosts.begin();
host != hosts.end(); ++host) {
......@@ -161,6 +191,7 @@ CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
ConstHostPtr
CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) const {
// Do not log here because getHostInternal logs.
// The true value indicates that it is an IPv6 subnet.
return (getHostInternal(subnet_id, true, hwaddr, duid));
}
......@@ -168,6 +199,7 @@ CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
HostPtr
CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) {
// Do not log here because getHostInternal logs.
// The true value indicates that it is an IPv6 subnet.
return (getHostInternal(subnet_id, true, hwaddr, duid));
}
......@@ -186,12 +218,29 @@ CfgHosts::get6(const IOAddress&, const uint8_t) {
ConstHostPtr
CfgHosts::get6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const {
ConstHostCollection storage;
getAllInternal6(subnet_id, address, storage);
// Do not log here because getHostInternal6 logs.
return (getHostInternal6<ConstHostPtr, ConstHostCollection>(subnet_id, address));
}
HostPtr
CfgHosts::get6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) {
// Do not log here because getHostInternal6 logs.
return (getHostInternal6<HostPtr, HostCollection>(subnet_id, address));
}
template<typename ReturnType, typename Storage>
ReturnType
CfgHosts::getHostInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6)
.arg(subnet_id).arg(address.toText());
Storage storage;
getAllInternal6<Storage>(subnet_id, address, storage);
switch (storage.size()) {
case 0:
return (ConstHostPtr());
return (HostPtr());
case 1:
return (*storage.begin());
default:
......@@ -200,6 +249,7 @@ CfgHosts::get6(const SubnetID& subnet_id,
<< subnet_id << "' and using the address '"
<< address.toText() << "'");
}
}
template<typename Storage>
......@@ -207,6 +257,9 @@ void
CfgHosts::getAllInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& address,
Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6)
.arg(subnet_id).arg(address.toText());
// Must not specify address other than IPv6.
if (!address.isV6()) {
isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
......@@ -227,26 +280,15 @@ CfgHosts::getAllInternal6(const SubnetID& subnet_id,
}
}
HostPtr
CfgHosts::get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) {
HostCollection storage;
getAllInternal6<HostCollection>(subnet_id, address, storage);
switch (storage.size()) {
case 0:
return (HostPtr());
case 1:
return (*storage.begin());
default:
isc_throw(DuplicateHost, "more than one reservation found"
" for the host belonging to the subnet with id '"
<< subnet_id << "' and using the address '"
<< address.toText() << "'");
}
}
HostPtr
CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID)
.arg(subnet6 ? "IPv6" : "IPv4")
.arg(subnet_id)
.arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)")
.arg(duid ? duid->toText() : "(no-duid)");
// Get all hosts for the HW address and DUID. This may return multiple hosts
// for different subnets, but the number of hosts returned should be low
// because one host presumably doesn't show up in many subnets.
......@@ -290,11 +332,15 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
void
CfgHosts::add(const HostPtr& host) {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_ADD_HOST)
.arg(host ? host->toText() : "(no-host)");
// Sanity check that the host is non-null.
if (!host) {
isc_throw(BadValue, "specified host object must not be NULL when it"
" is added to the configuration");
}
// At least one subnet ID must be non-zero
if (host->getIPv4SubnetID() == 0 && host->getIPv6SubnetID() == 0) {
isc_throw(BadValue, "must not use both IPv4 and IPv6 subnet ids of"
......@@ -308,7 +354,6 @@ CfgHosts::add(const HostPtr& host) {
void
CfgHosts::add4(const HostPtr& host) {
/// @todo This may need further sanity checks.
HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid();
......@@ -316,7 +361,7 @@ CfgHosts::add4(const HostPtr& host) {
// There should be at least one resource reserved: hostname, IPv4
// address, IPv6 address or prefix.
if (host->getHostname().empty() &&
(host->getIPv4Reservation() == IOAddress("0.0.0.0")) &&
(host->getIPv4Reservation().isV4Zero()) &&
(!host->hasIPv6Reservation())) {
std::ostringstream s;
if (hwaddr) {
......@@ -357,7 +402,6 @@ CfgHosts::add4(const HostPtr& host) {
void
CfgHosts::add6(const HostPtr& host) {
/// @todo This may need further sanity checks.
HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid();
......
......@@ -339,6 +339,23 @@ private:
const HWAddrPtr& hwaddr,
const DuidPtr& duid) const;
/// @brief Returns the @c Host object holding reservation for the IPv6
/// address and connected to the specific subnet.
///
/// This private method is called by the public @c get6 method variants.
///
/// @param subnet_id IPv6 subnet identifier.
/// @param address IPv6 address.
/// @tparam ReturnType One of @c HostPtr or @c ConstHostPtr
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
///
/// @return Pointer to the found host, or NULL if no host found.
/// @throw isc::dhcp::DuplicateHost if method found more than one matching
/// @c Host object.
template<typename ReturnType, typename Storage>
ReturnType getHostInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& adddress) const;
/// @brief Adds a new host to the v4 collection.
///
/// This is an internal method called by public @ref add.
......
......@@ -268,5 +268,61 @@ Host::getIdentifierAsText() const {
return (txt);
}
std::string
Host::toText() const {
std::ostringstream s;
// Add HW address or DUID.
s << getIdentifierAsText();
// Add IPv4 subnet id if exists (non-zero).
if (ipv4_subnet_id_) {
s << " ipv4_subnet_id=" << ipv4_subnet_id_;
}
// Add IPv6 subnet id if exists (non-zero).
if (ipv6_subnet_id_) {
s << " ipv6_subnet_id=" << ipv6_subnet_id_;
}
// Add hostname.
s << " hostname=" << (hostname_.empty() ? "(empty)" : hostname_);
// Add IPv4 reservation.
s << " ipv4_reservation=" << (ipv4_reservation_.isV4Zero() ? "(no)" :
ipv4_reservation_.toText());
if (ipv6_reservations_.empty()) {
s << " ipv6_reservations=(none)";
} else {
// Add all IPv6 reservations.
for (IPv6ResrvIterator resrv = ipv6_reservations_.begin();
resrv != ipv6_reservations_.end(); ++resrv) {
s << " ipv6_reservation"
<< std::distance(ipv6_reservations_.begin(), resrv)
<< "=" << resrv->second.toText();
}
}
// Add DHCPv4 client classes.
for (ClientClasses::const_iterator cclass = dhcp4_client_classes_.begin();
cclass != dhcp4_client_classes_.end(); ++cclass) {
s << " dhcp4_class"
<< std::distance(dhcp4_client_classes_.begin(), cclass)
<< "=" << *cclass;
}
// Add DHCPv6 client classes.
for (ClientClasses::const_iterator cclass = dhcp6_client_classes_.begin();
cclass != dhcp6_client_classes_.end(); ++cclass) {
s << " dhcp6_class"
<< std::distance(dhcp6_client_classes_.begin(), cclass)
<< "=" << *cclass;
}
return (s.str());
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -417,6 +417,9 @@ public:
return (dhcp6_client_classes_);
}
/// @brief Returns information about the host in the textual format.
std::string toText() const;
private:
/// @brief Adds new client class for DHCPv4 or DHCPv6.
......
// Copyright (C) 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
/// @file Defines the logger used by the @c isc::dhcp::HostMgr
#include "dhcpsrv/hosts_log.h"
namespace isc {
namespace dhcp {
isc::log::Logger hosts_logger("hosts");
} // namespace dhcp
} // namespace isc
// Copyright (C) 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef HOSTS_LOG_H
#define HOSTS_LOG_H
#include <dhcpsrv/hosts_messages.h>
#include <log/macros.h>
namespace isc {
namespace dhcp {
///@{
/// \brief Logging levels for the host reservations management.
///
/// Defines the levels used to output debug messages during the host
/// reservations management, i.e. retrieving and adding host reservations.
/// Note that higher numbers equate to more verbose(and detailed) output.
/// @brief Traces normal operations
///
/// An example of the normal operation is the call to one of the functions
/// which retrieve the reservations or add new reservation.
const int HOSTS_DBG_TRACE = DBGLVL_TRACE_BASIC;
/// @brief Records the results of the lookups
///
/// Messages logged at this level will typically contain summary of the
/// data retrieved.
const int HOSTS_DBG_RESULTS = DBGLVL_TRACE_BASIC_DATA;
/// @brief Record detailed traces
///
/// Messages logged at this level will log detailed tracing information.
const int HOSTS_DBG_TRACE_DETAIL = DBGLVL_TRACE_DETAIL;
/// @brief Records detailed results of lookups.
///
/// Messages logged at this level will contain detailed results.
const int HOSTS_DBG_TRACE_DETAIL_DATA = DBGLVL_TRACE_DETAIL_DATA;
///@}
/// @brief Logger for the @c HostMgr and the code it calls.
///
/// Define the logger used to log messages in @c HostMgr and the code it
/// calls to manage host reservations.
extern isc::log::Logger hosts_logger;
} // namespace dhcp
} // namespace isc
#endif // HOSTS_LOG_H
# Copyright (C) 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
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
$NAMESPACE isc::dhcp
% HOSTS_CFG_ADD_HOST add the host for reservations: %1
This debug message is issued when new host (with reservations) is added to
the server's configuration. The argument describes the host and its
reservations in detail.
% HOSTS_CFG_GET_ALL_ADDRESS4 get all hosts with reservations for IPv4 address %1
This debug message is issued when retrieving all hosts, holding the
reservation for the specific IPv4 address, from the configuration. The
argument specifies the IPv4 address used to search the hosts.
% HOSTS_CFG_GET_ALL_ADDRESS6 get all hosts with reservations for IPv6 address %1
This debug message is issued when retrieving all hosts, holding the
reservation for the specific IPv6 address, from the configuration.
The argument specifies the IPv6 address used to search the hosts.
% HOSTS_CFG_GET_ALL_HWADDR_DUID get all hosts with reservations for HWADDR %1 and DUID %2
This debug message is issued when retrieving reservations for all hosts
using specific HW address or DUID. The arguments specify the HW address and
DUID respectively. The argument specify the HW address and DUID respectively.
% HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6 get all hosts with reservations for subnet id %1 and IPv6 address %2
This debug message is issued when retrieving all hosts connected to
the specific subnet and having the specific IPv6 address reserved.
The arguments specify subnet id and IPv6 address respectively.
% HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4 get one host with reservation for subnet id %1 and IPv4 address %2
This debug message is issued when retrieving a host connected to the
specific subnet and having the specific IPv4 address reserved. The
arguments specify subnet id and IPv4 address respectively.
% HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6 get one host with reservation for subnet id %1 and including IPv6 address %2
This debug message is issued when retrieveing a host connected to the
specific subnet and having the specific IPv6 address reserved. The
arguments specify subnet id and IPv6 address respectively.
% HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID get one host with %1 reservation for subnet id %2, HWADDR %3, DUID %4
This debug message is issued when retrieving the host holding IPv4 or
IPv6 reservations, which is connected to the specific subnet and is
identified by the specific HW address or DUID. The first argument
identifies if the IPv4 or IPv6 reservation is desired.
......@@ -524,4 +524,77 @@ TEST(HostTest, getIdentifierAsText) {
host2.getIdentifierAsText());
}
// This test checks that Host object is correctly described in the
// textual format using the toText method.
TEST(HostTest, toText) {
boost::scoped_ptr<Host> host;
ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"),
"myhost.example.com")));
// Add 4 reservations: 2 for NAs, 2 for PDs.
ASSERT_NO_THROW(
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::cafe")));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:1::"), 64));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:2::"), 64));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::1")));
);
// Make sure that the output is correct,
EXPECT_EQ("hwaddr=01:02:03:04:05:06 ipv4_subnet_id=1 ipv6_subnet_id=2"
" hostname=myhost.example.com"
" ipv4_reservation=192.0.2.3"
" ipv6_reservation0=2001:db8:1::cafe"
" ipv6_reservation1=2001:db8:1::1"
" ipv6_reservation2=2001:db8:1:1::/64"
" ipv6_reservation3=2001:db8:1:2::/64",
host->toText());
// Reset some of the data and make sure that the output is affected.
host->setHostname("");
host->removeIPv4Reservation();
host->setIPv4SubnetID(0);
EXPECT_EQ("hwaddr=01:02:03:04:05:06 ipv6_subnet_id=2"
" hostname=(empty) ipv4_reservation=(no)"
" ipv6_reservation0=2001:db8:1::cafe"
" ipv6_reservation1=2001:db8:1::1"
" ipv6_reservation2=2001:db8:1:1::/64"
" ipv6_reservation3=2001:db8:1:2::/64",
host->toText());
// Create host identified by DUID, instead of HWADDR, with a very
// basic configuration.
ASSERT_NO_THROW(host.reset(new Host("11:12:13:14:15", "duid",
SubnetID(0), SubnetID(0),
IOAddress::IPV4_ZERO_ADDRESS(),
"myhost")));
EXPECT_EQ("duid=11:12:13:14:15 hostname=myhost ipv4_reservation=(no)"
" ipv6_reservations=(none)", host->toText());
// Add some classes.
host->addClientClass4("modem");
host->addClientClass4("router");
EXPECT_EQ("duid=11:12:13:14:15 hostname=myhost ipv4_reservation=(no)"
" ipv6_reservations=(none)"
" dhcp4_class0=modem dhcp4_class1=router",
host->toText());
host->addClientClass6("hub");
host->addClientClass6("device");
EXPECT_EQ("duid=11:12:13:14:15 hostname=myhost ipv4_reservation=(no)"
" ipv6_reservations=(none)"
" dhcp4_class0=modem dhcp4_class1=router"
" dhcp6_class0=device dhcp6_class1=hub",
host->toText());
}
} // end of anonymous namespace
Markdown is supported
0% or