Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Kea
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
416
Issues
416
List
Boards
Labels
Service Desk
Milestones
Merge Requests
66
Merge Requests
66
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
Kea
Commits
50de7df4
Commit
50de7df4
authored
May 22, 2014
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Plain Diff
[master] Merge branch 'trac3246'
Conflicts: src/bin/dhcp6/tests/Makefile.am
parents
b8ce9d26
dc9a9575
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
341 additions
and
55 deletions
+341
-55
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/dhcp6_srv.cc
+4
-4
src/bin/dhcp6/tests/Makefile.am
src/bin/dhcp6/tests/Makefile.am
+1
-0
src/bin/dhcp6/tests/dhcp6_client.cc
src/bin/dhcp6/tests/dhcp6_client.cc
+15
-3
src/bin/dhcp6/tests/dhcp6_client.h
src/bin/dhcp6/tests/dhcp6_client.h
+24
-1
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
+6
-2
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/bin/dhcp6/tests/dhcp6_test_utils.h
+7
-2
src/bin/dhcp6/tests/rebind_unittest.cc
src/bin/dhcp6/tests/rebind_unittest.cc
+0
-19
src/bin/dhcp6/tests/sarr_unittest.cc
src/bin/dhcp6/tests/sarr_unittest.cc
+124
-0
src/lib/dhcp/option6_iaprefix.cc
src/lib/dhcp/option6_iaprefix.cc
+29
-2
src/lib/dhcp/option6_iaprefix.h
src/lib/dhcp/option6_iaprefix.h
+42
-3
src/lib/dhcp/tests/option6_iaprefix_unittest.cc
src/lib/dhcp/tests/option6_iaprefix_unittest.cc
+89
-19
No files found.
src/bin/dhcp6/dhcp6_srv.cc
View file @
50de7df4
...
...
@@ -1365,16 +1365,16 @@ Dhcpv6Srv::assignIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
// Check if the client sent us a hint in his IA_PD. Clients may send an
// address in their IA_NA options as a suggestion (e.g. the last address
// they used before).
boost
::
shared_ptr
<
Option6IAPrefix
>
hint
O
pt
=
boost
::
shared_ptr
<
Option6IAPrefix
>
hint
_o
pt
=
boost
::
dynamic_pointer_cast
<
Option6IAPrefix
>
(
ia
->
getOption
(
D6O_IAPREFIX
));
IOAddress
hint
(
"::"
);
if
(
hint
O
pt
)
{
hint
=
hint
O
pt
->
getAddress
();
if
(
hint
_o
pt
)
{
hint
=
hint
_o
pt
->
getAddress
();
}
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_DETAIL
,
DHCP6_PROCESS_IA_PD_REQUEST
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
).
arg
(
ia
->
getIAID
())
.
arg
(
hint
O
pt
?
hint
.
toText
()
:
"(no hint)"
);
.
arg
(
hint
_o
pt
?
hint
.
toText
()
:
"(no hint)"
);
// "Fake" allocation is processing of SOLICIT message. We pretend to do an
// allocation, but we do not put the lease in the database. That is ok,
...
...
src/bin/dhcp6/tests/Makefile.am
View file @
50de7df4
...
...
@@ -85,6 +85,7 @@ dhcp6_unittests_SOURCES += ctrl_dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES
+=
wireshark.cc
dhcp6_unittests_SOURCES
+=
dhcp6_client.cc dhcp6_client.h
dhcp6_unittests_SOURCES
+=
rebind_unittest.cc
dhcp6_unittests_SOURCES
+=
sarr_unittest.cc
dhcp6_unittests_SOURCES
+=
../json_config_parser.cc ../json_config_parser.h
dhcp6_unittests_SOURCES
+=
config_parser_unittest.cc
...
...
src/bin/dhcp6/tests/dhcp6_client.cc
View file @
50de7df4
...
...
@@ -39,7 +39,8 @@ Dhcp6Client::Dhcp6Client() :
srv_
(
boost
::
shared_ptr
<
NakedDhcpv6Srv
>
(
new
NakedDhcpv6Srv
(
0
))),
use_na_
(
false
),
use_pd_
(
false
),
use_relay_
(
false
)
{
use_relay_
(
false
),
prefix_hint_
()
{
}
Dhcp6Client
::
Dhcp6Client
(
boost
::
shared_ptr
<
NakedDhcpv6Srv
>&
srv
)
:
...
...
@@ -234,8 +235,11 @@ Dhcp6Client::doSolicit() {
1234
)));
}
if
(
use_pd_
)
{
context_
.
query_
->
addOption
(
Option6IAPtr
(
new
Option6IA
(
D6O_IA_PD
,
5678
)));
Option6IAPtr
ia
(
new
Option6IA
(
D6O_IA_PD
,
5678
));
if
(
prefix_hint_
)
{
ia
->
addOption
(
prefix_hint_
);
}
context_
.
query_
->
addOption
(
ia
);
}
sendMsg
(
context_
.
query_
);
context_
.
response_
=
receiveOneMsg
();
...
...
@@ -358,6 +362,14 @@ Dhcp6Client::sendMsg(const Pkt6Ptr& msg) {
srv_
->
run
();
}
void
Dhcp6Client
::
useHint
(
const
uint32_t
pref_lft
,
const
uint32_t
valid_lft
,
const
uint8_t
len
,
const
std
::
string
&
prefix
)
{
prefix_hint_
.
reset
(
new
Option6IAPrefix
(
D6O_IAPREFIX
,
asiolink
::
IOAddress
(
prefix
),
len
,
pref_lft
,
valid_lft
));
}
}
// end of namespace isc::dhcp::test
}
// end of namespace isc::dhcp
...
...
src/bin/dhcp6/tests/dhcp6_client.h
View file @
50de7df4
...
...
@@ -26,7 +26,6 @@ namespace isc {
namespace
dhcp
{
namespace
test
{
/// @brief DHCPv6 client used for unit testing.
///
/// This class implements a DHCPv6 "client" which interoperates with the
...
...
@@ -76,6 +75,11 @@ public:
/// Currently it simply contains the collection of leases acquired.
struct
Configuration
{
std
::
vector
<
LeaseInfo
>
leases_
;
/// @brief Clears configuration.
void
clear
()
{
leases_
.
clear
();
}
};
/// @brief Holds the DHCPv6 messages taking part in transaction between
...
...
@@ -175,6 +179,13 @@ public:
/// @todo Perform sanity checks on returned messages.
void
doRequest
();
/// @brief Removes the stateful configuration obtained from the server.
///
/// It removes all leases held by the client.
void
clearConfig
()
{
config_
.
clear
();
}
/// @brief Simulates aging of leases by the specified number of seconds.
///
/// This function moves back the time of acquired leases by the specified
...
...
@@ -250,6 +261,15 @@ public:
dest_addr_
=
dest_addr
;
}
/// @brief Sets a prefix hint to be sent to a server.
///
/// @param pref_lft Preferred lifetime.
/// @param valid_lft Valid lifetime.
/// @param len Prefix length.
/// @param prefix Prefix for which the client has a preference.
void
useHint
(
const
uint32_t
pref_lft
,
const
uint32_t
valid_lft
,
const
uint8_t
len
,
const
std
::
string
&
prefix
);
/// @brief Place IA_NA options to request address assignment.
///
/// This function configures the client to place IA_NA options in its
...
...
@@ -383,6 +403,9 @@ private:
bool
use_na_
;
///< Enable address assignment.
bool
use_pd_
;
///< Enable prefix delegation.
bool
use_relay_
;
///< Enable relaying messages to the server.
/// @brief Pointer to the option holding a prefix hint.
Option6IAPrefixPtr
prefix_hint_
;
};
}
// end of namespace isc::dhcp::test
...
...
src/bin/dhcp6/tests/dhcp6_test_utils.cc
View file @
50de7df4
...
...
@@ -590,18 +590,22 @@ Dhcpv6SrvTest::testReleaseReject(Lease::Type type, const IOAddress& addr) {
void
Dhcpv6SrvTest
::
configure
(
const
std
::
string
&
config
)
{
configure
(
config
,
srv_
);
}
void
Dhcpv6SrvTest
::
configure
(
const
std
::
string
&
config
,
NakedDhcpv6Srv
&
srv
)
{
ElementPtr
json
=
data
::
Element
::
fromJSON
(
config
);
ConstElementPtr
status
;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv
_
,
json
));
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv
,
json
));
ASSERT_TRUE
(
status
);
int
rcode
;
ConstElementPtr
comment
=
config
::
parseAnswer
(
rcode
,
status
);
ASSERT_EQ
(
0
,
rcode
);
}
// Generate IA_NA option with specified parameters
boost
::
shared_ptr
<
Option6IA
>
NakedDhcpv6SrvTest
::
generateIA
(
uint16_t
type
,
uint32_t
iaid
,
uint32_t
t1
,
...
...
src/bin/dhcp6/tests/dhcp6_test_utils.h
View file @
50de7df4
...
...
@@ -354,8 +354,13 @@ public:
/// @brief Runs DHCPv6 configuration from the JSON string.
///
/// @param config String holding server configuration in JSON format.
void
configure
(
const
std
::
string
&
config
);
void
configure
(
const
std
::
string
&
config
);
/// @brief Configure the DHCPv6 server using the JSON string.
///
/// @param config String holding server configuration in JSON format.
/// @param srv Server to be configured.
void
configure
(
const
std
::
string
&
config
,
NakedDhcpv6Srv
&
srv
);
/// @brief Checks that server response (ADVERTISE or REPLY) contains proper
/// IA_NA option
...
...
src/bin/dhcp6/tests/rebind_unittest.cc
View file @
50de7df4
...
...
@@ -208,12 +208,6 @@ public:
iface_mgr_test_config_
(
true
)
{
}
/// @brief Configure the DHCPv6 server using the JSON string.
///
/// @param config New configuration in JSON format.
/// @param srv Server to be configured.
void
configure
(
const
std
::
string
&
config
,
NakedDhcpv6Srv
&
srv
);
/// @brief Make 4-way exchange to obtain a lease.
///
/// @param config_index Index of the configuration held in @c REBIND_CONFIGS
...
...
@@ -229,19 +223,6 @@ public:
};
void
RebindTest
::
configure
(
const
std
::
string
&
config
,
NakedDhcpv6Srv
&
srv
)
{
ElementPtr
json
=
Element
::
fromJSON
(
config
);
ConstElementPtr
status
;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv
,
json
));
ASSERT_TRUE
(
status
);
int
rcode
;
ConstElementPtr
comment
=
config
::
parseAnswer
(
rcode
,
status
);
ASSERT_EQ
(
0
,
rcode
);
}
void
RebindTest
::
requestLease
(
const
int
config_index
,
const
int
subnets_num
,
Dhcp6Client
&
client
)
{
...
...
src/bin/dhcp6/tests/sarr_unittest.cc
0 → 100644
View file @
50de7df4
// 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 <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/tests/dhcp6_client.h>
using
namespace
isc
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
dhcp
::
test
;
using
namespace
isc
::
test
;
namespace
{
/// @brief Set of JSON configurations used by the SARR unit tests.
///
/// - Configuration 0:
/// - one subnet used on eth0 interface
/// - prefixes of length 64, delegated from the pool: 2001:db8:3::/48
const
char
*
CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet6
\"
: [ { "
"
\"
pd-pools
\"
: ["
" {
\"
prefix
\"
:
\"
2001:db8:3::
\"
, "
"
\"
prefix-len
\"
: 48, "
"
\"
delegated-len
\"
: 64"
" } ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
, "
"
\"
interface-id
\"
:
\"\"
,"
"
\"
interface
\"
:
\"
eth0
\"
"
" } ],"
"
\"
valid-lifetime
\"
: 4000 }"
};
/// @brief Test fixture class for testing 4-way exchange: Solicit-Advertise,
/// Request-Reply.
class
SARRTest
:
public
Dhcpv6SrvTest
{
public:
/// @brief Constructor.
///
/// Sets up fake interfaces.
SARRTest
()
:
Dhcpv6SrvTest
(),
iface_mgr_test_config_
(
true
)
{
}
/// @brief Interface Manager's fake configuration control.
IfaceMgrTestConfig
iface_mgr_test_config_
;
};
/// Check that server processes correctly a prefix hint sent by the client.
/// This test checks that the server doesn't allocate colliding prefixes
/// as a result of receiving hints from two clients which set the
/// non-significant bytes of the prefix in their hints. The server should zero
/// the non-significant bytes of the hint and allocate the prefix of the
/// correct (configured) length.
TEST_F
(
SARRTest
,
directClientPrefixHint
)
{
Dhcp6Client
client
;
// Configure client to request IA_PD.
client
.
usePD
();
configure
(
CONFIGS
[
0
],
*
client
.
getServer
());
// Make sure we ended-up having expected number of subnets configured.
const
Subnet6Collection
*
subnets
=
CfgMgr
::
instance
().
getSubnets6
();
ASSERT_EQ
(
1
,
subnets
->
size
());
// Append IAPREFIX option to the client's message.
ASSERT_NO_THROW
(
client
.
useHint
(
100
,
200
,
64
,
"2001:db8:3:33::33"
));
// Perform 4-way exchange.
ASSERT_NO_THROW
(
client
.
doSARR
());
// Server should have assigned a prefix.
ASSERT_EQ
(
1
,
client
.
getLeaseNum
());
Lease6
lease_client
=
client
.
getLease
(
0
);
// The server should correctly deal with the least significant bytes
// of the hint being set. It should set them to zero and use the
// valid portion of the hint.
EXPECT_EQ
(
"2001:db8:3:33::"
,
lease_client
.
addr_
.
toText
());
// Server ignores other parts of the IAPREFIX option.
EXPECT_EQ
(
64
,
lease_client
.
prefixlen_
);
EXPECT_EQ
(
3000
,
lease_client
.
preferred_lft_
);
EXPECT_EQ
(
4000
,
lease_client
.
valid_lft_
);
Lease6Ptr
lease_server
=
checkLease
(
lease_client
);
// Check that the server recorded the lease.
ASSERT_TRUE
(
lease_server
);
// Remove existing lease and modify the DUID of the client to simulate
// the case that different client is trying to get the prefix.
client
.
clearConfig
();
client
.
modifyDUID
();
// Use the hint with some least significant bytes set.
ASSERT_NO_THROW
(
client
.
useHint
(
100
,
200
,
64
,
"2001:db8:3:33::34"
));
ASSERT_NO_THROW
(
client
.
doSARR
());
// Server should assign a lease.
ASSERT_EQ
(
1
,
client
.
getLeaseNum
());
lease_client
=
client
.
getLease
(
0
);
// The hint collides with the existing lease, so the server should not
// assign for the second client.
EXPECT_NE
(
"2001:db8:3:33::"
,
lease_client
.
addr_
.
toText
());
EXPECT_NE
(
"2001:db8:3:33::34"
,
lease_client
.
addr_
.
toText
());
// Check that the assigned prefix belongs to the pool.
(
*
subnets
)[
0
]
->
inPool
(
Lease
::
TYPE_PD
,
lease_client
.
addr_
);
EXPECT_EQ
(
64
,
lease_client
.
prefixlen_
);
EXPECT_EQ
(
3000
,
lease_client
.
preferred_lft_
);
EXPECT_EQ
(
4000
,
lease_client
.
valid_lft_
);
lease_server
=
checkLease
(
lease_client
);
ASSERT_TRUE
(
lease_server
);
}
}
// end of anonymous namespace
src/lib/dhcp/option6_iaprefix.cc
View file @
50de7df4
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2013
-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
...
...
@@ -86,7 +86,9 @@ void Option6IAPrefix::unpack(OptionBuffer::const_iterator begin,
begin
+=
sizeof
(
uint8_t
);
// 16 bytes: IPv6 address
addr_
=
IOAddress
::
fromBytes
(
AF_INET6
,
&
(
*
begin
));
OptionBuffer
address_with_mask
;
mask
(
begin
,
begin
+
V6ADDRESS_LEN
,
prefix_len_
,
address_with_mask
);
addr_
=
IOAddress
::
fromBytes
(
AF_INET6
,
&
(
*
address_with_mask
.
begin
()));
begin
+=
V6ADDRESS_LEN
;
// unpack encapsulated options (the only defined so far is PD_EXCLUDE)
...
...
@@ -122,5 +124,30 @@ uint16_t Option6IAPrefix::len() {
return
(
length
);
}
void
Option6IAPrefix
::
mask
(
OptionBuffer
::
const_iterator
begin
,
OptionBuffer
::
const_iterator
end
,
const
uint8_t
len
,
OptionBuffer
&
output_address
)
{
output_address
.
resize
(
16
,
0
);
if
(
len
>=
128
)
{
std
::
copy
(
begin
,
end
,
output_address
.
begin
());
}
else
if
(
len
>
0
)
{
// All the bits that represent whole octets of the prefix are copied with
// no change.
std
::
copy
(
begin
,
begin
+
static_cast
<
uint8_t
>
(
len
/
8
),
output_address
.
begin
());
// The remaining significant bits of the last octet have to be left unchanged,
// but the remaining bits of this octet must be set to zero. The number of
// significant bits is calculated as a reminder from the devision of the
// prefix length by 8 (by size of the octet). The number of bits to be set
// to zero is therefore calculated as: 8 - (len % 8).
// Next, the mask is created by shifting the 0xFF by the number of bits
// to be set to 0. By performing logical AND of this mask with the original
// value of the last octet we get the final value for the new octet.
output_address
[
len
/
8
]
=
(
*
(
begin
+
len
/
8
)
&
(
0xFF
<<
(
8
-
(
len
%
8
))));
}
}
}
// end of namespace isc::dhcp
}
// end of namespace isc
src/lib/dhcp/option6_iaprefix.h
View file @
50de7df4
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2013
-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
...
...
@@ -33,9 +33,29 @@ namespace dhcp {
/// a prefix length) 2 methods are used: getAddress() and getLength(). Although
/// using getAddress() to obtain base prefix is somewhat counter-intuitive at
/// first, it becomes obvious when one realizes that an address is a special
/// case of a prefix with /128. It makes everyone's li
k
e much easier, because
/// case of a prefix with /128. It makes everyone's li
f
e much easier, because
/// the base prefix doubles as a regular address in many cases, e.g. when
/// searching for a lease.
///
/// When searching for a prefix in the database or simply comparing two prefixes
/// for equality, it is important that only the significant parts of the
/// prefixes are compared. It is possible that the client or a server sends a
/// prefix which has non-significant bits (beyond prefix length) set. The
/// server or client receiving such a prefix should be liberal and not discard
/// this prefix. It should rather ignore the non-significant bits. Therefore
/// the unpack() function, which parses the prefix from the wire, always sets
/// the non-significant bits to 0 so as two prefixes received on the wire can
/// be compared without additional processing.
///
/// @todo Currently, the constructor which creates the option from the textual
/// format doesn't set non-significant bits to 0. This is because it is assumed
/// that the prefixes from the string are created locally (not received over the
/// wire) and should be validated before the option is created. If we wanted
/// to set non-significant bits to 0 when the prefix is created from the textual
/// format it would have some peformance implications, because the option would
/// need to be turned into wire format, appropriate bits set to 0 and then
/// option would need to be created again from the wire format. We may consider
/// doing it if we find a use case where it is required.
class
Option6IAPrefix
:
public
Option6IAAddr
{
public:
...
...
@@ -74,6 +94,11 @@ public:
/// @brief Parses received buffer.
///
/// This function calls the @c Option6IAPrefix::mask function to set the
/// non-significant bits of the prefix (bits beyond the length of the
/// prefix) to zero. See the @c Option6IAPrefix class documentation for
/// details why it is done.
///
/// @throw OutOfRange when buffer is shorter than 25 bytes
///
/// @param begin iterator to first byte of option data
...
...
@@ -100,7 +125,21 @@ public:
/// returns data length (data length + DHCPv4/DHCPv6 option header)
virtual
uint16_t
len
();
protected:
private:
/// @brief Apply mask of the specific length to the IPv6 address.
///
/// @param begin Iterator pointing to the buffer holding IPv6 address.
/// @param end Iterator pointing to the end of the buffer holding IPv6
/// address.
/// @param len Length of the mask to be applied.
/// @param [out] output_address Reference to the buffer where the address
/// with a mask applied is output.
void
mask
(
OptionBuffer
::
const_iterator
begin
,
OptionBuffer
::
const_iterator
end
,
const
uint8_t
len
,
OptionBuffer
&
output_address
);
uint8_t
prefix_len_
;
};
...
...
src/lib/dhcp/tests/option6_iaprefix_unittest.cc
View file @
50de7df4
// Copyright (C) 2011-201
3
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-201
4
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
...
...
@@ -36,7 +36,7 @@ using namespace isc::asiolink;
namespace
{
class
Option6IAPrefixTest
:
public
::
testing
::
Test
{
public:
Option6IAPrefixTest
()
:
buf_
(
255
),
out
B
uf_
(
255
)
{
Option6IAPrefixTest
()
:
buf_
(
255
),
out
_b
uf_
(
255
)
{
for
(
int
i
=
0
;
i
<
255
;
i
++
)
{
buf_
[
i
]
=
255
-
i
;
}
...
...
@@ -45,7 +45,7 @@ public:
/// @brief creates on-wire representation of IAPREFIX option
///
/// buf_ field is set up to have IAPREFIX with preferred=1000,
/// valid=3000000000 and prefix bei
gn 2001:db8:1:
:dead:beef/77
/// valid=3000000000 and prefix bei
ng 2001:db8:1:0:afaf:0
:dead:beef/77
void
setExampleBuffer
()
{
for
(
int
i
=
0
;
i
<
255
;
i
++
)
{
buf_
[
i
]
=
0
;
...
...
@@ -69,10 +69,12 @@ public:
buf_
[
12
]
=
0xb8
;
buf_
[
13
]
=
0x00
;
buf_
[
14
]
=
0x01
;
buf_
[
17
]
=
0xaf
;
buf_
[
18
]
=
0xaf
;
buf_
[
21
]
=
0xde
;
buf_
[
22
]
=
0xad
;
buf_
[
23
]
=
0xbe
;
buf_
[
24
]
=
0xef
;
// 2001:db8:1::dead:beef
buf_
[
24
]
=
0xef
;
// 2001:db8:1:
0:afaf:0
:dead:beef
}
...
...
@@ -82,15 +84,22 @@ public:
///
/// @param opt IAPREFIX option being tested
/// @param expected_type expected option type
void
checkOption
(
Option6IAPrefix
&
opt
,
uint16_t
expected_type
)
{
/// @param expected_length Expected length of the prefix.
/// @param expected_address Expected prefix value in the textual format.
void
checkOption
(
Option6IAPrefix
&
opt
,
const
uint16_t
expected_type
,
const
uint8_t
expected_length
,
const
std
::
string
&
expected_address
)
{
// Check if all fields have expected values
EXPECT_EQ
(
Option
::
V6
,
opt
.
getUniverse
());
EXPECT_EQ
(
expected_type
,
opt
.
getType
());
EXPECT_EQ
(
"2001:db8:1::dead:beef"
,
opt
.
getAddress
().
toText
());
EXPECT_EQ
(
expected_address
,
opt
.
getAddress
().
toText
());
EXPECT_EQ
(
1000
,
opt
.
getPreferred
());
EXPECT_EQ
(
3000000000U
,
opt
.
getValid
());
EXPECT_EQ
(
77
,
opt
.
getLength
());
// uint8_t is often represented as a character type (char). Convert it
// to integer so as it is logged as a numeric value instead.
EXPECT_EQ
(
static_cast
<
int
>
(
expected_length
),
static_cast
<
int
>
(
opt
.
getLength
()));
// 4 bytes header + 25 bytes content
EXPECT_EQ
(
Option
::
OPTION6_HDR_LEN
+
Option6IAPrefix
::
OPTION6_IAPREFIX_LEN
,
...
...
@@ -105,7 +114,7 @@ public:
/// @param expected_type expected option type
void
checkOutputBuffer
(
uint16_t
expected_type
)
{
// Check if pack worked properly:
const
uint8_t
*
out
=
(
const
uint8_t
*
)
outBuf_
.
getData
(
);
const
uint8_t
*
out
=
static_cast
<
const
uint8_t
*>
(
out_buf_
.
getData
()
);
// - if option type is correct
EXPECT_EQ
(
expected_type
,
out
[
0
]
*
256
+
out
[
1
]);
...
...
@@ -118,11 +127,12 @@ public:
}
OptionBuffer
buf_
;
OutputBuffer
out
B
uf_
;
OutputBuffer
out
_b
uf_
;
};
// Tests if receiving option can be parsed correctly
TEST_F
(
Option6IAPrefixTest
,
basic
)
{
// Tests if a received option is parsed correctly. For the prefix length between
// 0 and 128 the non-significant bits should be set to 0.
TEST_F
(
Option6IAPrefixTest
,
parseShort
)
{
setExampleBuffer
();
...
...
@@ -133,17 +143,75 @@ TEST_F(Option6IAPrefixTest, basic) {
ASSERT_TRUE
(
opt
);
// Pack this option
opt
->
pack
(
out
B
uf_
);
EXPECT_EQ
(
29
,
out
B
uf_
.
getLength
());
opt
->
pack
(
out
_b
uf_
);
EXPECT_EQ
(
29
,
out
_b
uf_
.
getLength
());
checkOption
(
*
opt
,
D6O_IAPREFIX
);
// The non-significant bits (above 77) of the received prefix should be
// set to zero.
checkOption
(
*
opt
,
D6O_IAPREFIX
,
77
,
"2001:db8:1:0:afa8::"
);
// Set non-significant bits in the reference buffer to 0, so as the buffer
// can be directly compared with the option buffer.
buf_
[
18
]
=
0xa8
;
buf_
.
insert
(
buf_
.
begin
()
+
19
,
5
,
0
);
checkOutputBuffer
(
D6O_IAPREFIX
);
// Check that option can be disposed safely
EXPECT_NO_THROW
(
opt
.
reset
());
}
// Tests if a received option holding prefix of 128 bits is parsed correctly.
TEST_F
(
Option6IAPrefixTest
,
parseLong
)
{
setExampleBuffer
();
// Set prefix length to the maximal value.
buf_
[
8
]
=
128
;
// Create an option (unpack content)
boost
::
scoped_ptr
<
Option6IAPrefix
>
opt
;
ASSERT_NO_THROW
(
opt
.
reset
(
new
Option6IAPrefix
(
D6O_IAPREFIX
,
buf_
.
begin
(),
buf_
.
begin
()
+
25
)));
ASSERT_TRUE
(
opt
);
// Pack this option
opt
->
pack
(
out_buf_
);
EXPECT_EQ
(
29
,
out_buf_
.
getLength
());
checkOption
(
*
opt
,
D6O_IAPREFIX
,
128
,
"2001:db8:1:0:afaf:0:dead:beef"
);
checkOutputBuffer
(
D6O_IAPREFIX
);
// Check that option can be disposed safely
EXPECT_NO_THROW
(
opt
.
reset
());
}
// Check that the prefix having length of zero is represented as a "::".
TEST_F
(
Option6IAPrefixTest
,
parseZero
)
{
setExampleBuffer
();
// Set prefix length to 0.
buf_
[
8
]
=
0
;
// Create an option (unpack content)
boost
::
scoped_ptr
<
Option6IAPrefix
>
opt
;
ASSERT_NO_THROW
(
opt
.
reset
(
new
Option6IAPrefix
(
D6O_IAPREFIX
,
buf_
.
begin
(),
buf_
.
begin
()
+
25
)));
ASSERT_TRUE
(
opt
);
// Pack this option
opt
->
pack
(
out_buf_
);
EXPECT_EQ
(
29
,
out_buf_
.
getLength
());
checkOption
(
*
opt
,
D6O_IAPREFIX
,
0
,
"::"
);
// Fill the address in the reference buffer with zeros.
buf_
.
insert
(
buf_
.
begin
()
+
9
,
16
,
0
);
checkOutputBuffer
(
D6O_IAPREFIX
);
// Check that option can be disposed safely
EXPECT_NO_THROW
(
opt
.
reset
());
}
// Checks whether a new option can be built correctly
TEST_F
(
Option6IAPrefixTest
,
build
)
{
...
...
@@ -151,14 +219,15 @@ TEST_F(Option6IAPrefixTest, build) {
setExampleBuffer
();
ASSERT_NO_THROW
(
opt
.
reset
(
new
Option6IAPrefix
(
12345
,
IOAddress
(
"2001:db8:1::dead:beef"
),
77
,
1000
,
3000000000u
)));
IOAddress
(
"2001:db8:1:0:afaf:0:dead:beef"
),
77
,
1000
,
3000000000u
)));
ASSERT_TRUE
(
opt
);
checkOption
(
*
opt
,
12345
);
checkOption
(
*
opt
,
12345
,
77
,
"2001:db8:1:0:afaf:0:dead:beef"
);
// Check if we can build it properly
EXPECT_NO_THROW
(
opt
->
pack
(
out
B
uf_
));
EXPECT_EQ
(
29
,
out
B
uf_
.
getLength
());
EXPECT_NO_THROW
(
opt
->
pack
(
out
_b
uf_
));
EXPECT_EQ
(
29
,
out
_b
uf_
.
getLength
());
checkOutputBuffer
(
12345
);
// Check that option can be disposed safely
...
...
@@ -181,7 +250,8 @@ TEST_F(Option6IAPrefixTest, negative) {
BadValue
);
// Prefix length can't be larger than 128
EXPECT_THROW
(
Option6IAPrefix
(
12345
,
IOAddress
(
"192.0.2.1"
),
255
,
1000
,
2000
),
EXPECT_THROW
(
Option6IAPrefix
(
12345
,
IOAddress
(
"192.0.2.1"
),
255
,
1000
,
2000
),