Dhcpv4Srv::Dhcpv4Srv(uint16_t server_port, uint16_t client_port,
const bool use_bcast, const bool direct_response_desired)
: io_service_(new IOService()), shutdown_(true), alloc_engine_(),
- server_port_(server_port), use_bcast_(use_bcast),
+ use_bcast_(use_bcast), server_port_(server_port),
client_port_(client_port),
network_state_(new NetworkState(NetworkState::DHCPv4)),
cb_control_(new CBControlDHCPv4()) {
response->setIface(query->getIface());
}
- response->setLocalPort(DHCP4_SERVER_PORT);
+ if (server_port_) {
+ response->setLocalPort(server_port_);
+ } else {
+ response->setLocalPort(DHCP4_SERVER_PORT);
+ }
}
void
/// @return Option that contains netmask information
static OptionPtr getNetmaskOption(const Subnet4Ptr& subnet);
- /// UDP port number on which server listens.
- uint16_t server_port_;
-
/// Should broadcast be enabled on sockets (if true).
bool use_bcast_;
protected:
+ /// UDP port number on which server listens.
+ uint16_t server_port_;
+
/// UDP port number to which server sends responses.
uint16_t client_port_;
// Clear remote address.
resp->setRemoteAddr(IOAddress("0.0.0.0"));
- // Set the client port.
+ // Set the client and server ports.
srv_.client_port_ = 1234;
+ srv_.server_port_ = 2345;
ASSERT_NO_THROW(srv_.adjustIfaceData(ex));
// Remote port was enforced to the client port.
EXPECT_EQ(srv_.client_port_, resp->getRemotePort());
+
+ // Local port was enforced to the server port.
+ EXPECT_EQ(srv_.server_port_, resp->getLocalPort());
}
// This test verifies that the remote port is adjusted when
EXPECT_EQ(srv.client_port_, offer->getRemotePort());
}
+// Checks if server port can be overridden in packets being sent.
+TEST_F(Dhcpv4SrvTest, portsServerPort) {
+ IfaceMgrTestConfig test_config(true);
+ IfaceMgr::instance().openSockets4();
+
+ // Do not use DHCP4_SERVER_PORT here as 0 means don't open sockets.
+ NakedDhcpv4Srv srv(0);
+ EXPECT_EQ(0, srv.server_port_);
+
+ // Use of the captured DHCPDISCOVER packet requires that
+ // subnet 10.254.226.0/24 is in use, because this packet
+ // contains the giaddr which belongs to this subnet and
+ // this giaddr is used to select the subnet
+ configure(CONFIGS[0]);
+ srv.server_port_ = 1234;
+
+ // Let's create a relayed DISCOVER. This particular relayed DISCOVER has
+ // added option 82 (relay agent info) with 3 suboptions. The server
+ // is supposed to echo it back in its response.
+ Pkt4Ptr dis;
+ ASSERT_NO_THROW(dis = PktCaptures::captureRelayedDiscover());
+
+ // Simulate that we have received that traffic
+ srv.fakeReceive(dis);
+
+ // Server will now process to run its normal loop, but instead of calling
+ // IfaceMgr::receive4(), it will read all packets from the list set by
+ // fakeReceive()
+ // In particular, it should call registered buffer4_receive callback.
+ srv.run();
+
+ // Check that the server did send a response
+ ASSERT_EQ(1, srv.fake_sent_.size());
+
+ // Make sure that we received a response
+ Pkt4Ptr offer = srv.fake_sent_.front();
+ ASSERT_TRUE(offer);
+
+ // Get Relay Agent Info from query...
+ EXPECT_EQ(srv.server_port_, offer->getLocalPort());
+}
+
/// @todo Implement tests for subnetSelect See tests in dhcp6_srv_unittest.cc:
/// selectSubnetAddr, selectSubnetIface, selectSubnetRelayLinkaddr,
/// selectSubnetRelayInterfaceId. Note that the concept of interface-id is not
using Dhcpv4Srv::VENDOR_CLASS_PREFIX;
using Dhcpv4Srv::shutdown_;
using Dhcpv4Srv::alloc_engine_;
+ using Dhcpv4Srv::server_port_;
using Dhcpv4Srv::client_port_;
};
rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
}
- rsp->setLocalPort(DHCP6_SERVER_PORT);
+ if (server_port_) {
+ rsp->setLocalPort(server_port_);
+ } else {
+ rsp->setLocalPort(DHCP6_SERVER_PORT);
+ }
rsp->setIndex(query->getIndex());
rsp->setIface(query->getIface());
/// @return true if option has been requested in the ORO.
bool requestedInORO(const Pkt6Ptr& query, const uint16_t code) const;
+protected:
/// UDP port number on which server listens.
uint16_t server_port_;
-protected:
/// UDP port number to which server sends all responses.
uint16_t client_port_;
Kea
kea-dhcp6
DHCPv6 server in Kea
-2011-2018
+2011-2019
Internet Systems Consortium, Inc. ("ISC")
kea-dhcp6
-v
config-file
-p
server-port-number
+-P
+client-port-number
DESCRIPTION
===========
Server port number (1-65535) on which the server listens. This is
useful for testing purposes only.
+``-P``
+ Client port number (1-65535) to which the server responds. This is
+ useful for testing purposes only.
+
DOCUMENTATION
=============
<info>
<productname>ISC Kea</productname>
- <date>Aug 28, 2019</date>
- <edition>1.6.0</edition>
+ <date>Oct 11, 2019</date>
+ <edition>1.7.1</edition>
<author>
<contrib>The Kea software has been written by a number of
engineers working for ISC: Tomek Mrugalski, Stephen Morris, Marcin
<arg choice="opt" rep="norepeat"><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-t <replaceable class="parameter">config-file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-p <replaceable class="parameter">server-port-number</replaceable></option></arg>
+ <arg choice="opt" rep="norepeat"><option>-P <replaceable class="parameter">client-port-number</replaceable></option></arg>
</cmdsynopsis>
</refsynopsisdiv>
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-P</option></term>
+ <listitem><para>
+ Client port number (1-65535) to which the server responds.
+ This is useful for testing purposes only.
+ </para></listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
EXPECT_EQ(srv.client_port_, adv->getRemotePort());
}
+// Checks if server responses are sent to the proper port.
+TEST_F(Dhcpv6SrvTest, portsServerPort) {
+
+ // Create the test server in test mode.
+ NakedDhcpv6Srv srv(0);
+
+ // Enforce a specific server port value.
+ EXPECT_EQ(0, srv.server_port_);
+ srv.server_port_ = 1234;
+
+ // Let's create a simple SOLICIT
+ Pkt6Ptr sol = PktCaptures::captureSimpleSolicit();
+
+ // Simulate that we have received that traffic
+ srv.fakeReceive(sol);
+
+ // Server will now process to run its normal loop, but instead of calling
+ // IfaceMgr::receive6(), it will read all packets from the list set by
+ // fakeReceive()
+ srv.run();
+
+ // Get Advertise...
+ ASSERT_FALSE(srv.fake_sent_.empty());
+ Pkt6Ptr adv = srv.fake_sent_.front();
+ ASSERT_TRUE(adv);
+
+ // Verify the local port: it must be the server port.
+ EXPECT_EQ(srv.server_port_, adv->getLocalPort());
+}
+
// Checks if server responses are sent to the proper port.
TEST_F(Dhcpv6SrvTest, portsDirectTraffic) {
using Dhcpv6Srv::name_change_reqs_;
using Dhcpv6Srv::VENDOR_CLASS_PREFIX;
using Dhcpv6Srv::initContext;
+ using Dhcpv6Srv::server_port_;
using Dhcpv6Srv::client_port_;
/// @brief packets we pretend to receive