Skip to content
GitLab
Menu
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
afad9d6d
Commit
afad9d6d
authored
Nov 04, 2015
by
Marcin Siodelski
Browse files
[4106] Throw exception of the packet sent over IPC is invalid.
parent
e42ed520
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcpsrv/dhcp4o6_ipc.cc
View file @
afad9d6d
...
...
@@ -139,22 +139,48 @@ Pkt6Ptr Dhcp4o6IpcBase::receive() {
OptionVendorPtr
vendor
=
boost
::
dynamic_pointer_cast
<
OptionVendor
>
(
pkt
->
getOption
(
D6O_VENDOR_OPTS
));
if
(
!
vendor
||
vendor
->
getVendorId
()
!=
ENTERPRISE_ID_ISC
)
{
return
(
Pkt6Ptr
());
// Vendor option must exist.
if
(
!
vendor
)
{
isc_throw
(
Dhcp4o6IpcError
,
"option "
<<
D6O_VENDOR_OPTS
<<
" not present in the DHCP4o6 message sent between the "
" servers"
);
}
// The vendor option must require appropriate enterprise-id.
if
(
vendor
->
getVendorId
()
!=
ENTERPRISE_ID_ISC
)
{
isc_throw
(
Dhcp4o6IpcError
,
"option "
<<
D6O_VENDOR_OPTS
<<
" in the DHCP4o6 message contains invalid enterprise-id '"
<<
vendor
->
getVendorId
()
<<
"'. Expected enterprise-id '"
<<
ENTERPRISE_ID_ISC
<<
"'"
);
}
OptionStringPtr
ifname
=
boost
::
dynamic_pointer_cast
<
OptionString
>
(
vendor
->
getOption
(
ISC_V6_4O6_INTERFACE
));
// The option carrying interface name is required.
OptionStringPtr
ifname
=
boost
::
dynamic_pointer_cast
<
OptionString
>
(
vendor
->
getOption
(
ISC_V6_4O6_INTERFACE
));
if
(
!
ifname
)
{
return
(
Pkt6Ptr
());
isc_throw
(
Dhcp4o6IpcError
,
"option "
<<
D6O_VENDOR_OPTS
<<
" doesn't contain the "
<<
ISC_V6_4O6_INTERFACE
<<
" option required in the DHCP4o6 message sent"
" between Kea servers"
);
}
// Check if this interface is present in the system.
IfacePtr
iface
=
IfaceMgr
::
instance
().
getIface
(
ifname
->
getValue
());
if
(
!
iface
)
{
return
(
Pkt6Ptr
());
isc_throw
(
Dhcp4o6IpcError
,
"option "
<<
ISC_V6_4O6_INTERFACE
<<
" sent in the DHCP4o6 message contains non-existing"
" interface name '"
<<
ifname
->
getValue
()
<<
"'"
);
}
// Get the option holding source IPv6 address.
OptionCustomPtr
srcs
=
boost
::
dynamic_pointer_cast
<
OptionCustom
>
(
vendor
->
getOption
(
ISC_V6_4O6_SRC_ADDRESS
));
if
(
!
srcs
)
{
return
(
Pkt6Ptr
());
isc_throw
(
Dhcp4o6IpcError
,
"option "
<<
D6O_VENDOR_OPTS
<<
" doesn't contain the "
<<
ISC_V6_4O6_SRC_ADDRESS
<<
" option required in the DHCP4o6 message sent"
" between Kea servers"
);
}
// Update the packet and return it
...
...
@@ -180,11 +206,11 @@ void Dhcp4o6IpcBase::send(const Pkt6Ptr& pkt) {
OptionVendorPtr
vendor
(
new
OptionVendor
(
Option
::
V6
,
ENTERPRISE_ID_ISC
));
// Push interface name and source address in it
vendor
->
addOption
(
OptionPtr
(
new
OptionString
(
Option
::
V6
,
ISC_V6_4O6_INTERFACE
,
pkt
->
getIface
())));
vendor
->
addOption
(
OptionPtr
(
new
Option6AddrLst
(
ISC_V6_4O6_SRC_ADDRESS
,
pkt
->
getRemoteAddr
())));
vendor
->
addOption
(
Option
String
Ptr
(
new
OptionString
(
Option
::
V6
,
ISC_V6_4O6_INTERFACE
,
pkt
->
getIface
())));
vendor
->
addOption
(
Option
6AddrLst
Ptr
(
new
Option6AddrLst
(
ISC_V6_4O6_SRC_ADDRESS
,
pkt
->
getRemoteAddr
())));
pkt
->
addOption
(
vendor
);
// Get packet content
...
...
src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc
View file @
afad9d6d
...
...
@@ -17,6 +17,9 @@
#include <dhcp/option_vendor.h>
#include <dhcp/pkt6.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp/option6_addrlst.h>
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcpsrv/dhcp4o6_ipc.h>
#include <boost/bind.hpp>
#include <gtest/gtest.h>
...
...
@@ -164,6 +167,11 @@ protected:
void
testSendReceive
(
const
uint16_t
iterations_num
,
const
int
src
,
const
int
dest
);
/// @brief Tests that error is reported when invalid message is received.
///
/// @param pkt Pointer to the invalid message.
void
testReceiveError
(
const
Pkt6Ptr
&
pkt
);
private:
/// @brief Holds the fake configuration of the interfaces.
...
...
@@ -269,6 +277,32 @@ Dhcp4o6IpcBaseTest::testSendReceive(const uint16_t iterations_num,
}
}
void
Dhcp4o6IpcBaseTest
::
testReceiveError
(
const
Pkt6Ptr
&
pkt
)
{
TestIpc
ipc_src
(
TEST_PORT
,
ENDPOINT_TYPE_V6
);
TestIpc
ipc_dest
(
TEST_PORT
,
ENDPOINT_TYPE_V4
);
// Open the IPC on both ends.
ASSERT_NO_THROW
(
ipc_src
.
open
());
ASSERT_NO_THROW
(
ipc_dest
.
open
());
pkt
->
setIface
(
"eth0"
);
pkt
->
setRemoteAddr
(
IOAddress
(
"2001:db8:1::1"
));
pkt
->
addOption
(
createDHCPv4MsgOption
(
ENDPOINT_TYPE_V6
));
OutputBuffer
&
buf
=
pkt
->
getBuffer
();
buf
.
clear
();
ASSERT_NO_THROW
(
pkt
->
pack
());
ASSERT_NE
(
-
1
,
::
send
(
ipc_src
.
getSocketFd
(),
buf
.
getData
(),
buf
.
getLength
(),
0
));
// Call receive with a timeout. The data should appear on the socket
// within this time.
ASSERT_THROW
(
IfaceMgr
::
instance
().
receive6
(
1
,
0
),
Dhcp4o6IpcError
);
}
// This test verifies that the IPC can transmit messages between the
// DHCPv6 and DHCPv4 server.
TEST_F
(
Dhcp4o6IpcBaseTest
,
send4To6
)
{
...
...
@@ -339,4 +373,78 @@ TEST_F(Dhcp4o6IpcBaseTest, openError) {
}
// This test verifies that receiving packet over the IPC fails when there
// is no vendor option present.
TEST_F
(
Dhcp4o6IpcBaseTest
,
receiveWithoutVendorOption
)
{
Pkt6Ptr
pkt
(
new
Pkt6
(
DHCPV6_DHCPV4_QUERY
,
0
));
testReceiveError
(
pkt
);
}
// This test verifies that receving packet over the IPC fails when the
// enterprise ID carried in the vendor option is invalid.
TEST_F
(
Dhcp4o6IpcBaseTest
,
receiveInvalidEnterpriseId
)
{
Pkt6Ptr
pkt
(
new
Pkt6
(
DHCPV6_DHCPV4_QUERY
,
0
));
OptionVendorPtr
option_vendor
(
new
OptionVendor
(
Option
::
V6
,
1
));
option_vendor
->
addOption
(
OptionStringPtr
(
new
OptionString
(
Option
::
V6
,
ISC_V6_4O6_INTERFACE
,
"eth0"
)));
option_vendor
->
addOption
(
Option6AddrLstPtr
(
new
Option6AddrLst
(
ISC_V6_4O6_SRC_ADDRESS
,
IOAddress
(
"2001:db8:1::1"
)))
);
pkt
->
addOption
(
option_vendor
);
testReceiveError
(
pkt
);
}
// This test verifies that receiving pakcet over the IPC fails when the
// interface option is not present.
TEST_F
(
Dhcp4o6IpcBaseTest
,
receiveWithoutInterfaceOption
)
{
Pkt6Ptr
pkt
(
new
Pkt6
(
DHCPV6_DHCPV4_QUERY
,
0
));
OptionVendorPtr
option_vendor
(
new
OptionVendor
(
Option
::
V6
,
ENTERPRISE_ID_ISC
));
option_vendor
->
addOption
(
Option6AddrLstPtr
(
new
Option6AddrLst
(
ISC_V6_4O6_SRC_ADDRESS
,
IOAddress
(
"2001:db8:1::1"
)))
);
pkt
->
addOption
(
option_vendor
);
testReceiveError
(
pkt
);
}
// This test verifies that receiving packet over the IPC fails when the
// interface which name is carried in the option is not present in the
// system.
TEST_F
(
Dhcp4o6IpcBaseTest
,
receiveWithInvalidInterface
)
{
Pkt6Ptr
pkt
(
new
Pkt6
(
DHCPV6_DHCPV4_QUERY
,
0
));
OptionVendorPtr
option_vendor
(
new
OptionVendor
(
Option
::
V6
,
ENTERPRISE_ID_ISC
));
option_vendor
->
addOption
(
OptionStringPtr
(
new
OptionString
(
Option
::
V6
,
ISC_V6_4O6_INTERFACE
,
"ethX"
)));
option_vendor
->
addOption
(
Option6AddrLstPtr
(
new
Option6AddrLst
(
ISC_V6_4O6_SRC_ADDRESS
,
IOAddress
(
"2001:db8:1::1"
)))
);
pkt
->
addOption
(
option_vendor
);
testReceiveError
(
pkt
);
}
// This test verifies that receving packet over the IPC fails when the
// source address option is not present.
TEST_F
(
Dhcp4o6IpcBaseTest
,
receiveWithoutSourceAddressOption
)
{
Pkt6Ptr
pkt
(
new
Pkt6
(
DHCPV6_DHCPV4_QUERY
,
0
));
OptionVendorPtr
option_vendor
(
new
OptionVendor
(
Option
::
V6
,
ENTERPRISE_ID_ISC
));
option_vendor
->
addOption
(
OptionStringPtr
(
new
OptionString
(
Option
::
V6
,
ISC_V6_4O6_INTERFACE
,
"eth0"
)));
pkt
->
addOption
(
option_vendor
);
testReceiveError
(
pkt
);
}
}
// end of anonymous namespace
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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