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
Sebastian Schrader
Kea
Commits
fad91c5b
Commit
fad91c5b
authored
Jul 14, 2014
by
Marcin Siodelski
Browse files
[3390] Initial implementation of the dhcp4 test client.
parent
fa9570d1
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/tests/Makefile.am
View file @
fad91c5b
...
...
@@ -88,6 +88,7 @@ dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
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
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
0 → 100644
View file @
fad91c5b
// 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
<dhcp/dhcp4.h>
#include
<dhcp4/tests/dhcp4_client.h>
#include
<cstdlib>
namespace
isc
{
namespace
dhcp
{
namespace
test
{
Dhcp4Client
::
Dhcp4Client
()
:
curr_transid_
(
0
),
dest_addr_
(
"255.255.255.255"
),
hwaddr_
(
generateHWAddr
()),
relay_addr_
(
"10.0.0.2"
),
srv_
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
(
new
NakedDhcpv4Srv
(
0
))),
use_relay_
(
false
)
{
}
Dhcp4Client
::
Dhcp4Client
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>&
srv
)
:
curr_transid_
(
0
),
dest_addr_
(
"255.255.255.255"
),
hwaddr_
(
generateHWAddr
()),
relay_addr_
(
"10.0.0.2"
),
srv_
(
srv
),
use_relay_
(
false
)
{
}
Pkt4Ptr
Dhcp4Client
::
createMsg
(
const
uint8_t
msg_type
)
{
Pkt4Ptr
msg
(
new
Pkt4
(
msg_type
,
curr_transid_
++
));
msg
->
setHWAddr
(
hwaddr_
);
return
(
msg
);
}
void
Dhcp4Client
::
doInform
()
{
context_
.
query_
=
createMsg
(
DHCPINFORM
);
sendMsg
(
context_
.
query_
);
context_
.
response_
=
receiveOneMsg
();
}
HWAddrPtr
Dhcp4Client
::
generateHWAddr
(
const
uint8_t
htype
)
const
{
if
(
htype
!=
HTYPE_ETHER
)
{
isc_throw
(
isc
::
NotImplemented
,
"The harware address type "
<<
static_cast
<
int
>
(
htype
)
<<
" is currently not supported"
);
}
std
::
vector
<
uint8_t
>
hwaddr
;
// Generate ethernet hardware address by assigning random byte values.
for
(
int
i
=
0
;
i
<
HWAddr
::
ETHERNET_HWADDR_LEN
;
++
i
)
{
hwaddr
.
push_back
(
static_cast
<
uint8_t
>
(
rand
()
%
255
));
}
return
(
HWAddrPtr
(
new
HWAddr
(
hwaddr
,
htype
)));
}
void
Dhcp4Client
::
modifyHWAddr
()
{
if
(
!
hwaddr_
)
{
hwaddr_
=
generateHWAddr
();
return
;
}
// Modify the HW address by adding 1 to its last byte.
++
hwaddr_
->
hwaddr_
[
hwaddr_
->
hwaddr_
.
size
()
-
1
];
}
Pkt4Ptr
Dhcp4Client
::
receiveOneMsg
()
{
// Return empty pointer if server hasn't responded.
if
(
srv_
->
fake_sent_
.
empty
())
{
return
(
Pkt4Ptr
());
}
Pkt4Ptr
msg
=
srv_
->
fake_sent_
.
front
();
srv_
->
fake_sent_
.
pop_front
();
return
(
msg
);
}
void
Dhcp4Client
::
sendMsg
(
const
Pkt4Ptr
&
msg
)
{
srv_
->
shutdown_
=
false
;
if
(
use_relay_
)
{
msg
->
setGiaddr
(
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
->
setLocalAddr
(
dest_addr_
);
msg_copy
->
setIface
(
"eth0"
);
srv_
->
fakeReceive
(
msg_copy
);
srv_
->
run
();
}
}
// end of namespace isc::dhcp::test
}
// end of namespace isc::dhcp
}
// end of namespace isc
src/bin/dhcp4/tests/dhcp4_client.h
0 → 100644
View file @
fad91c5b
// 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.
#ifndef DHCP4_CLIENT_H
#define DHCP4_CLIENT_H
#include
<asiolink/io_address.h>
#include
<dhcp/hwaddr.h>
#include
<dhcp/pkt4.h>
#include
<dhcp4/tests/dhcp4_test_utils.h>
#include
<boost/noncopyable.hpp>
#include
<boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
namespace
test
{
/// @brief DHCPv4 client used for unit testing.
///
/// This class implements a DHCPv4 "client" which interoperates with the
/// @c NakedDhcpv4Srv class. It calls @c NakedDhcpv4Srv::fakeRecive to
/// deliver client messages to the server for processing. The server places
/// the response in the @c NakedDhcpv4Srv::fake_sent_ container. The client
/// pops messages from this container which simulates reception of the
/// response from the server.
///
/// The client maintains the leases it acquired from the server
///
/// The client exposes a set of functions which simulate different exchange
/// types between the client and the server. It also provides the access to
/// the objects encapsulating responses from the server so as it is possible
/// to verify from the unit test that the server's response is correct.
class
Dhcp4Client
:
public
boost
::
noncopyable
{
public:
/// @brief Holds the DHCPv4 messages taking part in transaction between
/// the client and the server.
struct
Context
{
/// @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_
;
};
/// @brief Creates a new client.
Dhcp4Client
();
/// @brief Creates a new client that communicates with a specified server.
///
/// @param srv An instance of the DHCPv4 server to be used.
Dhcp4Client
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>&
srv
);
/// @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).
///
/// @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
();
/// @brief Generates a hardware address used by the client.
///
/// It assiges random values to the bytes of the harware address.
///
/// @param htype hardware address type. Currently the only type
/// supported is ethernet hardware address.
///
/// @return Pointer to the generated hardware address.
HWAddrPtr
generateHWAddr
(
const
uint8_t
htype
=
HTYPE_ETHER
)
const
;
/// @brief Returns HW address used by the client.
HWAddrPtr
getHWAddress
()
const
;
/// @brief Returns current context.
const
Context
&
getContext
()
const
{
return
(
context_
);
}
/// @brief Returns the server that the client is communicating with.
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
getServer
()
const
{
return
(
srv_
);
}
/// @brief Modifies the client's HW address (adds one to it).
///
/// The HW address should be modified to test negative scenarios when the
/// client acquires a lease and tries to renew it with a different HW
/// address. The server should detect the HW address mismatch and react
/// accordingly.
///
/// The HW address modification affects the value returned by the
/// @c Dhcp4Client::getHWAddress.
void
modifyHWAddr
();
/// @brief Sets destination address for the messages being sent by the
/// client.
///
/// By default, the client uses broadcast address 255.255.255.255 to
/// communicate with the server. In certain cases it may be desired
/// that different address is used. This function sets the new address
/// for all future exchanges with the server.
///
/// @param dest_addr New destination address.
void
setDestAddress
(
const
asiolink
::
IOAddress
&
dest_addr
)
{
dest_addr_
=
dest_addr
;
}
/// @brief Simulate sending messages through a relay.
///
/// @param use Parameter which 'true' value indicates that client should
/// simulate sending messages via relay.
/// @param relay_addr Relay address
void
useRelay
(
const
bool
use
=
true
,
const
asiolink
::
IOAddress
&
relay_addr
=
asiolink
::
IOAddress
(
"10.0.0.2"
))
{
use_relay_
=
use
;
relay_addr_
=
relay_addr
;
}
private:
/// @brief Creates client's side DHCP message.
///
/// @param msg_type Type of the message to be created.
/// @return An instance of the message created.
Pkt4Ptr
createMsg
(
const
uint8_t
msg_type
);
/// @brief Simulates reception of the message from the server.
///
/// @return Received message.
Pkt4Ptr
receiveOneMsg
();
/// @brief Simulates sending a message to the server.
///
/// This function instantly triggers processing of the message by the
/// server. The server's response can be gathered by invoking the
/// @c receiveOneMsg function.
///
/// @param msg Message to be sent.
void
sendMsg
(
const
Pkt4Ptr
&
msg
);
/// @brief Current context (sent and received message).
Context
context_
;
/// @biref Current transaction id (altered on each send).
uint32_t
curr_transid_
;
/// @brief Currently use destination address.
asiolink
::
IOAddress
dest_addr_
;
/// @brief Current hardware address of the client.
HWAddrPtr
hwaddr_
;
/// @brief Relay address to use.
asiolink
::
IOAddress
relay_addr_
;
/// @brief Pointer to the server that the client is communicating with.
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
srv_
;
/// @brief Enable relaying messages to the server.
bool
use_relay_
;
};
}
// end of namespace isc::dhcp::test
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // DHCP4_CLIENT
src/bin/dhcp4/tests/dhcp4_test_utils.h
View file @
fad91c5b
...
...
@@ -204,6 +204,7 @@ public:
using
Dhcpv4Srv
::
acceptMessageType
;
using
Dhcpv4Srv
::
selectSubnet
;
using
Dhcpv4Srv
::
VENDOR_CLASS_PREFIX
;
using
Dhcpv4Srv
::
shutdown_
;
};
class
Dhcpv4SrvTest
:
public
::
testing
::
Test
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment