Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
852fb7c1
Commit
852fb7c1
authored
Jul 15, 2014
by
Marcin Siodelski
Browse files
[3390] Implemented tests for DHCPINFORM processing.
parent
fad91c5b
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/tests/Makefile.am
View file @
852fb7c1
...
...
@@ -89,6 +89,7 @@ dhcp4_unittests_SOURCES += config_parser_unittest.cc
dhcp4_unittests_SOURCES
+=
fqdn_unittest.cc
dhcp4_unittests_SOURCES
+=
marker_file.cc
dhcp4_unittests_SOURCES
+=
dhcp4_client.cc dhcp4_client.h
dhcp4_unittests_SOURCES
+=
inform_unittest.cc
if
CONFIG_BACKEND_BUNDY
# For Bundy backend, we only need to run the usual tests. There are no
...
...
src/bin/dhcp4/tests/dhcp4_client.cc
View file @
852fb7c1
...
...
@@ -13,30 +13,92 @@
// PERFORMANCE OF THIS SOFTWARE.
#include
<dhcp/dhcp4.h>
#include
<dhcp/option.h>
#include
<dhcp/option_int_array.h>
#include
<dhcpsrv/lease.h>
#include
<dhcp4/tests/dhcp4_client.h>
#include
<boost/pointer_cast.hpp>
#include
<cstdlib>
namespace
isc
{
namespace
dhcp
{
namespace
test
{
Dhcp4Client
::
Configuration
::
Configuration
()
:
routers_
(),
dns_servers_
(),
serverid_
(
"0.0.0.0"
)
{
reset
();
}
void
Dhcp4Client
::
Configuration
::
reset
()
{
routers_
.
clear
();
dns_servers_
.
clear
();
serverid_
=
asiolink
::
IOAddress
(
"0.0.0.0"
);
}
Dhcp4Client
::
Dhcp4Client
()
:
config_
(),
curr_transid_
(
0
),
dest_addr_
(
"255.255.255.255"
),
hwaddr_
(
generateHWAddr
()),
relay_addr_
(
"10.0.0.2"
),
relay_addr_
(
"192.0.2.2"
),
requested_options_
(),
server_facing_relay_addr_
(
"10.0.0.2"
),
srv_
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
(
new
NakedDhcpv4Srv
(
0
))),
use_relay_
(
false
)
{
}
Dhcp4Client
::
Dhcp4Client
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>&
srv
)
:
config_
(),
curr_transid_
(
0
),
dest_addr_
(
"255.255.255.255"
),
hwaddr_
(
generateHWAddr
()),
relay_addr_
(
"10.0.0.2"
),
relay_addr_
(
"192.0.2.2"
),
requested_options_
(),
server_facing_relay_addr_
(
"10.0.0.2"
),
srv_
(
srv
),
use_relay_
(
false
)
{
}
void
Dhcp4Client
::
applyConfiguration
()
{
Pkt4Ptr
resp
=
context_
.
response_
;
if
(
!
resp
)
{
return
;
}
config_
.
reset
();
Option4AddrLstPtr
opt_routers
=
boost
::
dynamic_pointer_cast
<
Option4AddrLst
>
(
resp
->
getOption
(
DHO_ROUTERS
));
if
(
opt_routers
)
{
config_
.
routers_
=
opt_routers
->
getAddresses
();
}
Option4AddrLstPtr
opt_dns_servers
=
boost
::
dynamic_pointer_cast
<
Option4AddrLst
>
(
resp
->
getOption
(
DHO_DOMAIN_NAME_SERVERS
));
if
(
opt_dns_servers
)
{
config_
.
dns_servers_
=
opt_dns_servers
->
getAddresses
();
}
OptionCustomPtr
opt_serverid
=
boost
::
dynamic_pointer_cast
<
OptionCustom
>
(
resp
->
getOption
(
DHO_DHCP_SERVER_IDENTIFIER
));
if
(
opt_serverid
)
{
config_
.
serverid_
=
opt_serverid
->
readAddress
();
}
/// @todo Other possible configuration.
}
void
Dhcp4Client
::
createLease
(
const
asiolink
::
IOAddress
&
addr
,
const
uint32_t
valid_lft
)
{
Lease4
lease
(
addr
,
&
hwaddr_
->
hwaddr_
[
0
],
hwaddr_
->
hwaddr_
.
size
(),
0
,
0
,
valid_lft
,
valid_lft
/
2
,
valid_lft
,
time
(
NULL
),
false
,
false
,
""
);
config_
.
lease_
=
lease
;
}
Pkt4Ptr
Dhcp4Client
::
createMsg
(
const
uint8_t
msg_type
)
{
Pkt4Ptr
msg
(
new
Pkt4
(
msg_type
,
curr_transid_
++
));
...
...
@@ -45,10 +107,39 @@ Dhcp4Client::createMsg(const uint8_t msg_type) {
}
void
Dhcp4Client
::
doInform
()
{
Dhcp4Client
::
doInform
(
const
bool
set_ciaddr
)
{
context_
.
query_
=
createMsg
(
DHCPINFORM
);
// Request options if any.
if
(
!
requested_options_
.
empty
())
{
// Include Parameter Request List if at least one option code
// has been specified to be requested.
OptionUint8ArrayPtr
prl
(
new
OptionUint8Array
(
Option
::
V4
,
DHO_DHCP_PARAMETER_REQUEST_LIST
));
for
(
std
::
set
<
uint8_t
>::
const_iterator
opt
=
requested_options_
.
begin
();
opt
!=
requested_options_
.
end
();
++
opt
)
{
prl
->
addValue
(
*
opt
);
}
context_
.
query_
->
addOption
(
prl
);
}
// The client sending a DHCPINFORM message has an IP address obtained
// by some other means, e.g. static configuration. The lease which we
// are using here is most likely set by the createLease method.
if
(
set_ciaddr
)
{
context_
.
query_
->
setCiaddr
(
config_
.
lease_
.
addr_
);
}
context_
.
query_
->
setLocalAddr
(
config_
.
lease_
.
addr_
);
// Send the message to the server.
sendMsg
(
context_
.
query_
);
// Expect response. If there is no response, return.
context_
.
response_
=
receiveOneMsg
();
if
(
!
context_
.
response_
)
{
return
;
}
// If DHCPACK has been returned by the server, use the returned
// configuration.
if
(
context_
.
response_
->
getType
()
==
DHCPACK
)
{
applyConfiguration
();
}
}
HWAddrPtr
...
...
@@ -76,6 +167,23 @@ Dhcp4Client::modifyHWAddr() {
++
hwaddr_
->
hwaddr_
[
hwaddr_
->
hwaddr_
.
size
()
-
1
];
}
void
Dhcp4Client
::
requestOption
(
const
uint8_t
option
)
{
if
(
option
!=
0
)
{
requested_options_
.
insert
(
option
);
}
}
void
Dhcp4Client
::
requestOptions
(
const
uint8_t
option1
,
const
uint8_t
option2
,
const
uint8_t
option3
)
{
requested_options_
.
clear
();
requestOption
(
option1
);
requestOption
(
option2
);
requestOption
(
option3
);
}
Pkt4Ptr
Dhcp4Client
::
receiveOneMsg
()
{
// Return empty pointer if server hasn't responded.
...
...
@@ -84,21 +192,35 @@ Dhcp4Client::receiveOneMsg() {
}
Pkt4Ptr
msg
=
srv_
->
fake_sent_
.
front
();
srv_
->
fake_sent_
.
pop_front
();
return
(
msg
);
// Copy the original message to simulate reception over the wire.
msg
->
pack
();
Pkt4Ptr
msg_copy
(
new
Pkt4
(
static_cast
<
const
uint8_t
*>
(
msg
->
getBuffer
().
getData
()),
msg
->
getBuffer
().
getLength
()));
msg_copy
->
setRemoteAddr
(
msg
->
getLocalAddr
());
msg_copy
->
setLocalAddr
(
msg
->
getRemoteAddr
());
msg_copy
->
setIface
(
msg
->
getIface
());
msg_copy
->
unpack
();
return
(
msg_copy
);
}
void
Dhcp4Client
::
sendMsg
(
const
Pkt4Ptr
&
msg
)
{
srv_
->
shutdown_
=
false
;
if
(
use_relay_
)
{
msg
->
setHops
(
1
);
msg
->
setGiaddr
(
relay_addr_
);
msg
->
setLocalAddr
(
server_facing_relay_addr_
);
}
// Repack the message to simulate wire-data parsing.
msg
->
pack
();
Pkt4Ptr
msg_copy
(
new
Pkt4
(
static_cast
<
const
uint8_t
*>
(
msg
->
getBuffer
().
getData
()),
msg
->
getBuffer
().
getLength
()));
msg_copy
->
setRemoteAddr
(
asiolink
::
IOAddress
(
"0.0.0.0"
));
msg_copy
->
setRemoteAddr
(
msg
->
getLocalAddr
(
));
msg_copy
->
setLocalAddr
(
dest_addr_
);
msg_copy
->
setIface
(
"eth0"
);
srv_
->
fakeReceive
(
msg_copy
);
...
...
src/bin/dhcp4/tests/dhcp4_client.h
View file @
852fb7c1
...
...
@@ -21,6 +21,7 @@
#include
<dhcp4/tests/dhcp4_test_utils.h>
#include
<boost/noncopyable.hpp>
#include
<boost/shared_ptr.hpp>
#include
<set>
namespace
isc
{
namespace
dhcp
{
...
...
@@ -50,7 +51,21 @@ public:
/// @brief Holds the last sent message from the client to the server.
Pkt4Ptr
query_
;
/// @brief Holds the last sent message by the server to the client.
Pkt4Ptr
response_
;
};
Pkt4Ptr
response_
;
};
/// @brief Holds the configuration of the client received from the
/// DHCP server.
struct
Configuration
{
Option4AddrLst
::
AddressContainer
routers_
;
Option4AddrLst
::
AddressContainer
dns_servers_
;
Lease4
lease_
;
asiolink
::
IOAddress
serverid_
;
Configuration
();
void
reset
();
};
/// @brief Creates a new client.
Dhcp4Client
();
...
...
@@ -60,15 +75,35 @@ public:
/// @param srv An instance of the DHCPv4 server to be used.
Dhcp4Client
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>&
srv
);
/// @brief Creates a lease for the client using the specified address
/// and valid lifetime.
///
/// This method creates the lease using the specified address and
/// valid lease lifetime. The client will use this lease in any
/// future communication with the DHCP server. One of the use cases
/// for this method is to pre-configure the client with the explicitly
/// given address before it sends the DHCPINFORM to the DHCP server.
/// The client will inject the leased address into the ciaddr field
/// of the DHCPINFORM message.
///
/// @param addr Lease address.
/// @param valid_lft Valid lifetime.
void
createLease
(
const
asiolink
::
IOAddress
&
addr
,
const
uint32_t
valid_lft
);
/// @brief Sends DHCPINFORM message to the server and receives response.
///
/// This function simulates sending the DHCPINFORM message to the server
/// and receiving server's response (if any).
///
/// @param set_ciaddr Indicates if the ciaddr should be set for an
/// outgoing message and defaults to true. Note, that the RFC2131 mandates
/// setting the ciaddr for DHCPINFORM but the server may still want to
/// respond if the ciaddr is not set.
///
/// @throw This function doesn't thrown exceptions on its own, but it calls
/// functions that are not exception safe, so it may emit an exception if
/// an error occurs.
void
doInform
();
void
doInform
(
const
bool
set_ciaddr
=
true
);
/// @brief Generates a hardware address used by the client.
///
...
...
@@ -104,6 +139,33 @@ public:
/// @c Dhcp4Client::getHWAddress.
void
modifyHWAddr
();
/// @brief Specify an option to be requested by a client.
///
/// This function adds option code to the collection of option
/// codes to be requested by a client.
///
/// @param option Option code to be requested. The value of 0 is
/// ignored and the function is no-op.
void
requestOption
(
const
uint8_t
option
);
/// @brief Specifies options to be requested by the client.
///
/// This function configures the client to request options having
/// specified codes using Parameter Request List option. The default
/// value of 0 specify that the option is not requested.
///
/// If there are options specified to be requested before the function
/// is called, the new option codes override previously specified ones.
/// In order to clear the list of requested options call
/// @c requestOptions(0).
///
/// @param option1 First option to be requested.
/// @param option2 Second option to be requested (optional).
/// @param option3 Third option to be requested (optional).
void
requestOptions
(
const
uint8_t
option1
,
const
uint8_t
option2
=
0
,
const
uint8_t
option3
=
0
);
/// @brief Sets destination address for the messages being sent by the
/// client.
///
...
...
@@ -124,13 +186,22 @@ public:
/// @param relay_addr Relay address
void
useRelay
(
const
bool
use
=
true
,
const
asiolink
::
IOAddress
&
relay_addr
=
asiolink
::
IOAddress
(
"192.0.2.2"
),
const
asiolink
::
IOAddress
&
sf_relay_addr
=
asiolink
::
IOAddress
(
"10.0.0.2"
))
{
use_relay_
=
use
;
relay_addr_
=
relay_addr
;
server_facing_relay_addr_
=
sf_relay_addr
;
}
/// @brief Current client's configuration obtained from the server.
Configuration
config_
;
private:
/// @brief Stores configuration received from the server.
void
applyConfiguration
();
/// @brief Creates client's side DHCP message.
///
/// @param msg_type Type of the message to be created.
...
...
@@ -166,6 +237,12 @@ private:
/// @brief Relay address to use.
asiolink
::
IOAddress
relay_addr_
;
/// @brief Collection of options codes to be requested by the client.
std
::
set
<
uint8_t
>
requested_options_
;
/// @brief Address of the relay interface connected to the server.
asiolink
::
IOAddress
server_facing_relay_addr_
;
/// @brief Pointer to the server that the client is communicating with.
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
srv_
;
...
...
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
View file @
852fb7c1
...
...
@@ -480,20 +480,6 @@ TEST_F(Dhcpv4SrvTest, processDecline) {
EXPECT_NO_THROW
(
srv
.
processDecline
(
pkt
));
}
TEST_F
(
Dhcpv4SrvTest
,
processInform
)
{
NakedDhcpv4Srv
srv
;
Pkt4Ptr
pkt
(
new
Pkt4
(
DHCPINFORM
,
1234
));
// Should not throw
EXPECT_NO_THROW
(
srv
.
processInform
(
pkt
));
// Should return something
EXPECT_TRUE
(
srv
.
processInform
(
pkt
));
// @todo Implement more reasonable tests before starting
// work on processSomething() method.
}
TEST_F
(
Dhcpv4SrvTest
,
serverReceivedPacketName
)
{
// Check all possible packet types
for
(
int
itype
=
0
;
itype
<
256
;
++
itype
)
{
...
...
@@ -3587,6 +3573,7 @@ TEST_F(Dhcpv4SrvTest, acceptDirectRequest) {
// message is considered malformed and the accept() function should
// return false.
pkt
->
setGiaddr
(
IOAddress
(
"192.0.10.1"
));
pkt
->
setRemoteAddr
(
IOAddress
(
"0.0.0.0"
));
pkt
->
setLocalAddr
(
IOAddress
(
"192.0.2.3"
));
pkt
->
setIface
(
"eth1"
);
EXPECT_FALSE
(
srv
.
accept
(
pkt
));
...
...
@@ -3621,6 +3608,20 @@ TEST_F(Dhcpv4SrvTest, acceptDirectRequest) {
pkt
->
setLocalAddr
(
IOAddress
(
"10.0.0.1"
));
EXPECT_TRUE
(
srv
.
accept
(
pkt
));
// For the DHCPINFORM the ciaddr should be set or at least the source
// address.
pkt
->
setType
(
DHCPINFORM
);
pkt
->
setRemoteAddr
(
IOAddress
(
"10.0.0.101"
));
EXPECT_TRUE
(
srv
.
accept
(
pkt
));
// When neither ciaddr nor source addres is present, the packet should
// be dropped.
pkt
->
setRemoteAddr
(
IOAddress
(
"0.0.0.0"
));
EXPECT_FALSE
(
srv
.
accept
(
pkt
));
// When ciaddr is set, the packet should be accepted.
pkt
->
setCiaddr
(
IOAddress
(
"10.0.0.1"
));
EXPECT_TRUE
(
srv
.
accept
(
pkt
));
}
// This test checks that the server rejects a message with invalid type.
...
...
src/bin/dhcp4/tests/dhcp4_test_utils.cc
View file @
852fb7c1
...
...
@@ -563,16 +563,22 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
void
Dhcpv4SrvTest
::
configure
(
const
std
::
string
&
config
)
{
configure
(
config
,
srv_
);
}
void
Dhcpv4SrvTest
::
configure
(
const
std
::
string
&
config
,
NakedDhcpv4Srv
&
srv
)
{
ElementPtr
json
=
Element
::
fromJSON
(
config
);
ConstElementPtr
status
;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
srv
_
,
json
));
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
srv
,
json
));
ASSERT_TRUE
(
status
);
int
rcode
;
ConstElementPtr
comment
=
config
::
parseAnswer
(
rcode
,
status
);
ASSERT_EQ
(
0
,
rcode
);
}
}
};
// end of isc::dhcp::test namespace
...
...
src/bin/dhcp4/tests/dhcp4_test_utils.h
View file @
852fb7c1
...
...
@@ -407,6 +407,12 @@ public:
/// @param config String holding server configuration in JSON format.
void
configure
(
const
std
::
string
&
config
);
/// @brief Configure specified DHCP server using JSON string.
///
/// @param config String holding server configuration in JSON format.
/// @param srv Instance of the server to be configured.
void
configure
(
const
std
::
string
&
config
,
NakedDhcpv4Srv
&
srv
);
/// @brief This function cleans up after the test.
virtual
void
TearDown
();
...
...
src/bin/dhcp4/tests/inform_unittest.cc
0 → 100644
View file @
852fb7c1
// Copyright (C) 2014 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.
#include
<config.h>
#include
<asiolink/io_address.h>
#include
<cc/data.h>
#include
<dhcp/dhcp4.h>
#include
<dhcp/tests/iface_mgr_test_config.h>
#include
<dhcp4/tests/dhcp4_test_utils.h>
#include
<dhcp4/tests/dhcp4_client.h>
using
namespace
isc
;
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
data
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
dhcp
::
test
;
namespace
{
/// @brief Set of JSON configurations used throughout the Rebind tests.
///
/// - Configuration 0:
/// - Used for testing direct traffic
/// - 1 subnet: 10.0.0.0/24
/// - 1 pool: 10.0.0.10-10.0.0.100
/// - Router option present: 10.0.0.200 and 10.0.0.201
/// - Domain Name Server option present: 10.0.0.202, 10.0.0.203.
///
/// - Configuration 1:
/// - Use for testing relayed messages
/// - 1 subnet: 192.0.2.0/24
/// - Router option present: 192.0.2.200 and 192.0.2.201
/// - Domain Name Server option present: 192.0.2.202, 192.0.2.203.
const
char
*
INFORM_CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
10.0.0.0/24
\"
, "
"
\"
pool
\"
: [
\"
10.0.0.10-10.0.0.100
\"
],"
"
\"
option-data
\"
: [ {"
"
\"
name
\"
:
\"
routers
\"
,"
"
\"
code
\"
: 3,"
"
\"
data
\"
:
\"
10.0.0.200,10.0.0.201
\"
,"
"
\"
csv-format
\"
: true,"
"
\"
space
\"
:
\"
dhcp4
\"
"
" },"
" {"
"
\"
name
\"
:
\"
domain-name-servers
\"
,"
"
\"
code
\"
: 6,"
"
\"
data
\"
:
\"
10.0.0.202,10.0.0.203
\"
,"
"
\"
csv-format
\"
: true,"
"
\"
space
\"
:
\"
dhcp4
\"
"
" } ]"
" } ]"
"}"
,
// Configuration 1
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
, "
"
\"
option-data
\"
: [ {"
"
\"
name
\"
:
\"
routers
\"
,"
"
\"
code
\"
: 3,"
"
\"
data
\"
:
\"
192.0.2.200,192.0.2.201
\"
,"
"
\"
csv-format
\"
: true,"
"
\"
space
\"
:
\"
dhcp4
\"
"
" },"
" {"
"
\"
name
\"
:
\"
domain-name-servers
\"
,"
"
\"
code
\"
: 6,"
"
\"
data
\"
:
\"
192.0.2.202,192.0.2.203
\"
,"
"
\"
csv-format
\"
: true,"
"
\"
space
\"
:
\"
dhcp4
\"
"
" } ]"
" } ]"
"}"
};
/// @brief Test fixture class for testing DHCPINFORM.
class
InformTest
:
public
Dhcpv4SrvTest
{
public:
/// @brief Constructor.
///
/// Sets up fake interfaces.
InformTest
()
:
Dhcpv4SrvTest
(),
iface_mgr_test_config_
(
true
)
{
IfaceMgr
::
instance
().
openSockets4
();
}
/// @brief Interface Manager's fake configuration control.
IfaceMgrTestConfig
iface_mgr_test_config_
;
};
// Test that directly connected client's DHCPINFORM message is processed and
// DHCPACK message is sent back.
TEST_F
(
InformTest
,
directClientBroadcast
)
{
Dhcp4Client
client
;
// Configure DHCP server.
configure
(
INFORM_CONFIGS
[
0
],
*
client
.
getServer
());
// Request some configuration when DHCPINFORM is sent.
client
.
requestOptions
(
DHO_DOMAIN_NAME_SERVERS
,
DHO_ROUTERS
);
// Preconfigure the client with the IP address.
client
.
createLease
(
IOAddress
(
"10.0.0.56"
),
600
);
// Send DHCPINFORM message to the server.
client
.
doInform
();
// ASSERT_NO_THROW(client.doInform());
// Make sure that the server responded.
ASSERT_TRUE
(
client
.
getContext
().
response_
);
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
// Make sure that the server has responded with DHCPACK.
ASSERT_EQ
(
DHCPACK
,
static_cast
<
int
>
(
resp
->
getType
()));
// Response should have been unicast to the ciaddr.
EXPECT_EQ
(
IOAddress
(
"10.0.0.56"
),
resp
->
getLocalAddr
());
// Response must not be relayed.
EXPECT_FALSE
(
resp
->
isRelayed
());
// Make sure that the server id is present.
EXPECT_EQ
(
"10.0.0.1"
,
client
.
config_
.
serverid_
.
toText
());
// Make sure that the Routers option has been received.
ASSERT_EQ
(
2
,
client
.
config_
.
routers_
.
size
());
EXPECT_EQ
(
"10.0.0.200"
,
client
.
config_
.
routers_
[
0
].
toText
());
EXPECT_EQ
(
"10.0.0.201"
,
client
.
config_
.
routers_
[
1
].
toText
());
// Make sure that the DNS Servers option has been received.
ASSERT_EQ
(
2
,
client
.
config_
.
dns_servers_
.
size
());
EXPECT_EQ
(
"10.0.0.202"
,
client
.
config_
.
dns_servers_
[
0
].
toText
());
EXPECT_EQ
(
"10.0.0.203"
,
client
.
config_
.
dns_servers_
[
1
].
toText
());
// Check that we can send another DHCPINFORM message using
// different ciaddr and we will get the configuration.
client
.
createLease
(
IOAddress
(
"10.0.0.12"
),
600
);
// This time do not request DNS Servers option and it should not
// be returned.
client
.
requestOptions
(
DHO_ROUTERS
);
// Send DHCPINFORM.
ASSERT_NO_THROW
(
client
.
doInform
());
ASSERT_TRUE
(
client
.
getContext
().
response_
);
resp
=
client
.
getContext
().
response_
;
// Make sure that the server has responded with DHCPACK.
ASSERT_EQ
(
DHCPACK
,
static_cast
<
int
>
(
resp
->
getType
()));
// Response should have been unicast to the ciaddr.
EXPECT_EQ
(
IOAddress
(
"10.0.0.12"
),
resp
->
getLocalAddr
());
// Response must not be relayed.
EXPECT_FALSE
(
resp
->
isRelayed
());
// Make sure that the server id is present.
EXPECT_EQ
(
"10.0.0.1"
,
client
.
config_
.
serverid_
.
toText
());
// Make sure that the Routers option has been received.
ASSERT_EQ
(
2
,
client
.
config_
.
routers_
.
size
());
EXPECT_EQ
(
"10.0.0.200"
,
client
.
config_
.
routers_
[
0
].
toText
());
EXPECT_EQ
(
"10.0.0.201"
,
client
.
config_
.
routers_
[
1
].
toText
());
// Make sure that the DNS Servers option has been received.
ASSERT_TRUE
(
client
.
config_
.
dns_servers_
.
empty
());
}
// This test checks that the server drops DHCPINFORM message when the
// source address and ciaddr is 0.
TEST_F
(
InformTest
,
directClientBroadcastNoAddress
)
{
Dhcp4Client
client
;
// Configure DHCP server.
configure
(
INFORM_CONFIGS
[
0
],
*
client
.
getServer
());
// Request some configuration when DHCPINFORM is sent.
client
.
requestOptions
(
DHO_DOMAIN_NAME_SERVERS
,
DHO_ROUTERS
);
// Send DHCPINFORM message to the server.
ASSERT_NO_THROW
(
client
.
doInform
());
// Make sure that the server dropped the message.
ASSERT_FALSE
(
client
.
getContext
().
response_
);
}