1 // Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, v. 2.0. If a copy of the MPL was not distributed with this 5 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 7 #ifndef PKT_FILTER_TEST_UTILS_H 8 #define PKT_FILTER_TEST_UTILS_H 9 10 #include <asiolink/io_address.h> 11 #include <dhcp/iface_mgr.h> 12 #include <dhcp/pkt_filter.h> 13 #include <gtest/gtest.h> 14 15 namespace isc { 16 namespace dhcp { 17 namespace test { 18 19 /// @brief Test fixture class for testing classes derived from PktFilter class. 20 /// 21 /// This class implements a simple algorithm checking presence of the loopback 22 /// interface and initializing its index. It assumes that the loopback interface 23 /// name is one of 'lo' or 'lo0'. If none of those interfaces is found, the 24 /// constructor will report a failure. 25 /// 26 /// @todo The interface detection algorithm should be more generic. This will 27 /// be possible once the cross-OS interface detection is implemented. 28 class PktFilterTest : public ::testing::Test { 29 public: 30 31 /// @brief Constructor 32 /// 33 /// This constructor initializes sock_info_ structure to a default value. 34 /// The socket descriptors should be set to a negative value to indicate 35 /// that no socket has been opened. Specific tests will reinitialize this 36 /// structure with the values of the open sockets. For non-negative socket 37 /// descriptors, the class destructor will close associated sockets. 38 PktFilterTest(const uint16_t port); 39 40 /// @brief Destructor 41 /// 42 /// Closes open sockets (if any). 43 virtual ~PktFilterTest(); 44 45 /// @brief Initializes DHCPv4 message used by tests. 46 void initTestMessage(); 47 48 /// @brief Detect loopback interface. 49 /// 50 /// @todo this function will be removed once cross-OS interface 51 /// detection is implemented 52 void loInit(); 53 54 /// @brief Sends a single DHCPv4 message to the loopback address. 55 /// 56 /// This function opens a datagram socket and binds it to the local loopback 57 /// address and client port. The client's port is assumed to be port_ + 1. 58 /// The send_msg_sock_ member holds the socket descriptor so as the socket 59 /// is closed automatically in the destructor. If the function succeeds to 60 /// send a DHCPv4 message, the socket is closed so as the function can be 61 /// called again within the same test. 62 /// 63 /// @param dest Destination address for the packet. 64 void sendMessage(const asiolink::IOAddress& dest = 65 asiolink::IOAddress("127.0.0.1")); 66 67 /// @brief Test that the datagram socket is opened correctly. 68 /// 69 /// This function is used by multiple tests. 70 /// 71 /// @param sock A descriptor of the open socket. 72 void testDgramSocket(const int sock) const; 73 74 /// @brief Checks if a received message matches the test_message_. 75 /// 76 /// @param rcvd_msg An instance of the message to be tested. 77 void testRcvdMessage(const Pkt4Ptr& rcvd_msg) const; 78 79 /// @brief Checks if received message has appropriate addresses and 80 /// port values set. 81 /// 82 /// @param rcvd_msg An instance of the message to be tested. 83 void testRcvdMessageAddressPort(const Pkt4Ptr& rcvd_msg) const; 84 85 std::string ifname_; ///< Loopback interface name 86 uint16_t ifindex_; ///< Loopback interface index. 87 uint16_t port_; ///< A port number used for the test. 88 isc::dhcp::SocketInfo sock_info_; ///< A structure holding socket info. 89 int send_msg_sock_; ///< Holds a descriptor of the socket used by 90 ///< sendMessage function. 91 Pkt4Ptr test_message_; ///< A DHCPv4 message used by tests. 92 93 }; 94 95 /// @brief A stub implementation of the PktFilter class. 96 /// 97 /// This class implements abstract methods of the @c isc::dhcp::PktFilter 98 /// class. It is used by unit tests, which test protected methods of the 99 /// @c isc::dhcp::test::PktFilter class. The implemented abstract methods are 100 /// no-op. 101 class PktFilterStub : public PktFilter { 102 public: 103 104 /// @brief Checks if the direct DHCPv4 response is supported. 105 /// 106 /// This function checks if the direct response capability is supported, 107 /// i.e. if the server can respond to the client which doesn't have an 108 /// address yet. For this dummy class, the true is always returned. 109 /// 110 /// @return always true. 111 virtual bool isDirectResponseSupported() const; 112 113 /// @brief Simulate opening of the socket. 114 /// 115 /// This function simulates opening a primary socket. In reality, it doesn't 116 /// open a socket but the socket descriptor returned in the SocketInfo 117 /// structure is always set to 0. 118 /// 119 /// @param iface An interface descriptor. 120 /// @param addr Address on the interface to be used to send packets. 121 /// @param port Port number to bind socket to. 122 /// @param receive_bcast A flag which indicates if socket should be 123 /// configured to receive broadcast packets (if true). 124 /// @param send_bcast A flag which indicates if the socket should be 125 /// configured to send broadcast packets (if true). 126 /// 127 /// @note All parameters are ignored. 128 /// 129 /// @return A SocketInfo structure with the socket descriptor set to 0. The 130 /// fallback socket descriptor is set to a negative value. 131 virtual SocketInfo openSocket(Iface& iface, 132 const isc::asiolink::IOAddress& addr, 133 const uint16_t port, 134 const bool receive_bcast, 135 const bool send_bcast); 136 137 /// @brief Simulate reception of the DHCPv4 message. 138 /// 139 /// @param iface An interface to be used to receive DHCPv4 message. 140 /// @param sock_info A descriptor of the primary and fallback sockets. 141 /// 142 /// @note All parameters are ignored. 143 /// 144 /// @return always a NULL object. 145 virtual Pkt4Ptr receive(Iface& iface, const SocketInfo& sock_info); 146 147 /// @brief Simulates sending a DHCPv4 message. 148 /// 149 /// This function does nothing. 150 /// 151 /// @param iface An interface to be used to send DHCPv4 message. 152 /// @param port A port used to send a message. 153 /// @param pkt A DHCPv4 to be sent. 154 /// 155 /// @note All parameters are ignored. 156 /// 157 /// @return 0. 158 virtual int send(const Iface& iface, uint16_t port, const Pkt4Ptr& pkt); 159 160 // Change the scope of the protected function so as they can be unit tested. 161 using PktFilter::openFallbackSocket; 162 163 }; 164 165 166 }; // end of isc::dhcp::test namespace 167 }; // end of isc::dhcp namespace 168 }; // end of isc namespace 169 170 #endif // PKT_FILTER_TEST_UTILS_H 171