diff options
Diffstat (limited to 'src/lib/dhcp/tests/iface_mgr_test_config.cc')
-rw-r--r-- | src/lib/dhcp/tests/iface_mgr_test_config.cc | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/lib/dhcp/tests/iface_mgr_test_config.cc b/src/lib/dhcp/tests/iface_mgr_test_config.cc new file mode 100644 index 0000000..bd5d207 --- /dev/null +++ b/src/lib/dhcp/tests/iface_mgr_test_config.cc @@ -0,0 +1,207 @@ +// Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dhcp/pkt_filter.h> +#include <dhcp/pkt_filter_inet.h> +#include <dhcp/pkt_filter_inet6.h> +#include <dhcp/tests/iface_mgr_test_config.h> +#include <dhcp/tests/pkt_filter_test_stub.h> +#include <dhcp/tests/pkt_filter6_test_stub.h> + +#include <boost/foreach.hpp> + +using namespace isc::asiolink; + +namespace isc { +namespace dhcp { +namespace test { + +IfaceMgrTestConfig::IfaceMgrTestConfig(const bool default_config) { + IfaceMgr::instance().setTestMode(true); + IfaceMgr::instance().closeSockets(); + IfaceMgr::instance().clearIfaces(); + IfaceMgr::instance().getPacketQueueMgr4()->destroyPacketQueue(); + IfaceMgr::instance().getPacketQueueMgr6()->destroyPacketQueue(); + packet_filter4_ = PktFilterPtr(new PktFilterTestStub()); + packet_filter6_ = PktFilter6Ptr(new PktFilter6TestStub()); + IfaceMgr::instance().setPacketFilter(packet_filter4_); + IfaceMgr::instance().setPacketFilter(packet_filter6_); + + // Create default set of fake interfaces: lo, eth0, eth1 and eth1961. + if (default_config) { + createIfaces(); + } +} + +IfaceMgrTestConfig::~IfaceMgrTestConfig() { + IfaceMgr::instance().stopDHCPReceiver(); + IfaceMgr::instance().closeSockets(); + IfaceMgr::instance().getPacketQueueMgr4()->destroyPacketQueue(); + IfaceMgr::instance().getPacketQueueMgr6()->destroyPacketQueue(); + IfaceMgr::instance().clearIfaces(); + IfaceMgr::instance().setPacketFilter(PktFilterPtr(new PktFilterInet())); + IfaceMgr::instance().setPacketFilter(PktFilter6Ptr(new PktFilterInet6())); + IfaceMgr::instance().setTestMode(false); + IfaceMgr::instance().detectIfaces(); +} + +void +IfaceMgrTestConfig::addAddress(const std::string& iface_name, + const IOAddress& address) { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (!iface) { + isc_throw(isc::BadValue, "interface '" << iface_name + << "' doesn't exist"); + } + iface->addAddress(address); +} + +void +IfaceMgrTestConfig::addIface(const IfacePtr& iface) { + IfaceMgr::instance().addInterface(iface); +} + +void +IfaceMgrTestConfig::addIface(const std::string& name, const int ifindex) { + IfaceMgr::instance().addInterface(createIface(name, ifindex)); +} + +IfacePtr +IfaceMgrTestConfig::createIface(const std::string &name, const int ifindex) { + IfacePtr iface(new Iface(name, ifindex)); + if (name == "lo") { + iface->flag_loopback_ = true; + // Don't open sockets on the loopback interface. + iface->inactive4_ = true; + iface->inactive6_ = true; + } else { + iface->inactive4_ = false; + iface->inactive6_ = false; + } + iface->flag_multicast_ = true; + // On BSD systems, the SO_BINDTODEVICE option is not supported. + // Therefore the IfaceMgr will throw an exception on attempt to + // open sockets on more than one broadcast-capable interface at + // the same time. In order to prevent this error, we mark all + // interfaces broadcast-incapable for unit testing. + iface->flag_broadcast_ = false; + iface->flag_up_ = true; + iface->flag_running_ = true; + + // Set MAC address to 08:08:08:08:08:08. + std::vector<uint8_t> mac_vec(6, 8); + iface->setMac(&mac_vec[0], mac_vec.size()); + iface->setHWType(HTYPE_ETHER); + + return (iface); +} + +void +IfaceMgrTestConfig::createIfaces() { + // local loopback + addIface("lo", LO_INDEX); + addAddress("lo", IOAddress("127.0.0.1")); + addAddress("lo", IOAddress("::1")); + // eth0 + addIface("eth0", ETH0_INDEX); + addAddress("eth0", IOAddress("10.0.0.1")); + addAddress("eth0", IOAddress("fe80::3a60:77ff:fed5:cdef")); + addAddress("eth0", IOAddress("2001:db8:1::1")); + // eth1 + addIface("eth1", ETH1_INDEX); + addAddress("eth1", IOAddress("192.0.2.3")); + addAddress("eth1", IOAddress("192.0.2.5")); + addAddress("eth1", IOAddress("fe80::3a60:77ff:fed5:abcd")); + // eth1961 + addIface("eth1961", ETH1961_INDEX); + addAddress("eth1961", IOAddress("198.51.100.1")); + addAddress("eth1961", IOAddress("fe80::3a60:77ff:fed5:9876")); +} + +void +IfaceMgrTestConfig::setDirectResponse(const bool direct_resp) { + boost::shared_ptr<PktFilterTestStub> stub = + boost::dynamic_pointer_cast<PktFilterTestStub>(getPacketFilter4()); + if (!stub) { + isc_throw(isc::Unexpected, "unable to set direct response capability for" + " test packet filter - current packet filter is not" + " of a PktFilterTestStub"); + } + stub->direct_response_supported_ = direct_resp; +} + +void +IfaceMgrTestConfig::setIfaceFlags(const std::string& name, + const FlagLoopback& loopback, + const FlagUp& up, + const FlagRunning& running, + const FlagInactive4& inactive4, + const FlagInactive6& inactive6) { + IfacePtr iface = IfaceMgr::instance().getIface(name); + if (iface == NULL) { + isc_throw(isc::BadValue, "interface '" << name << "' doesn't exist"); + } + iface->flag_loopback_ = loopback.flag_; + iface->flag_up_ = up.flag_; + iface->flag_running_ = running.flag_; + iface->inactive4_ = inactive4.flag_; + iface->inactive6_ = inactive6.flag_; +} + +bool +IfaceMgrTestConfig::socketOpen(const std::string& iface_name, + const int family) const { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (iface == NULL) { + isc_throw(Unexpected, "No such interface '" << iface_name << "'"); + } + + BOOST_FOREACH(SocketInfo sock, iface->getSockets()) { + if (sock.family_ == family) { + return (true); + } + } + return (false); +} + +bool +IfaceMgrTestConfig::socketOpen(const std::string& iface_name, + const std::string& address) const { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (!iface) { + isc_throw(Unexpected, "No such interface '" << iface_name << "'"); + } + + BOOST_FOREACH(SocketInfo sock, iface->getSockets()) { + if ((sock.family_ == AF_INET) && + (sock.addr_ == IOAddress(address))) { + return (true); + } + } + return (false); +} + +bool +IfaceMgrTestConfig::unicastOpen(const std::string& iface_name) const { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (!iface) { + isc_throw(Unexpected, "No such interface '" << iface_name << "'"); + } + + BOOST_FOREACH(SocketInfo sock, iface->getSockets()) { + if ((!sock.addr_.isV6LinkLocal()) && + (!sock.addr_.isV6Multicast())) { + return (true); + } + } + return (false); +} + +} +} +} |