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
Adam Osuchowski
Kea
Commits
7b920501
Commit
7b920501
authored
Jan 27, 2015
by
Tomek Mrugalski
🛰
Browse files
[3552] Patch by Adam Kalmus (with minor clean-ups)
parent
82847177
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/pkt.cc
View file @
7b920501
...
...
@@ -180,6 +180,16 @@ Pkt::getMAC(uint32_t hw_addr_src) {
}
// Method 5: From remote-id option inserted by a relay
if
(
hw_addr_src
&
HWAddr
::
HWADDR_SOURCE_REMOTE_ID
)
{
mac
=
getMACFromRemoteIdRelayOption
();
if
(
mac
)
{
return
(
mac
);
}
else
if
(
hw_addr_src
==
HWAddr
::
HWADDR_SOURCE_REMOTE_ID
)
{
// If the only source allowed is remote-id option then we can skip
// the other methods.
return
(
HWAddrPtr
());
}
}
// Method 6: From subscriber-id option inserted by a relay
...
...
src/lib/dhcp/pkt.h
View file @
7b920501
...
...
@@ -492,8 +492,7 @@ protected:
/// @return hardware address (or NULL)
virtual
HWAddrPtr
getMACFromIPv6RelayOpt
()
=
0
;
/// @brief Attempts to obtain MAC address from DUID-LL or DUID-LLT
/// @brief Attempts to obtain MAC address from DUID-LL or DUID-LLT.
///
/// This method is called from getMAC(HWADDR_SOURCE_DUID) and should not be
/// called directly. It will attempt to extract MAC address information
...
...
@@ -507,6 +506,20 @@ protected:
/// @return hardware address (or NULL)
virtual
HWAddrPtr
getMACFromDUID
()
=
0
;
/// @brief Attempts to obtain MAC address from remote-id relay option.
///
/// This method is called from getMAC(HWADDR_SOURCE_REMOTE_ID) and should not be
/// called directly. It will attempt to extract MAC address information
/// from remote-id option inserted by a relay agent closest to the client.
/// If this method fails, it will return NULL.
///
/// @note This is a pure virtual method and must be implemented in
/// the derived classes. The @c Pkt6 class have respective implementation.
/// This method is not applicable to DHCPv4.
///
/// @return hardware address (or NULL)
virtual
HWAddrPtr
getMACFromRemoteIdRelayOption
()
=
0
;
/// @brief Attempts to convert IPv6 address into MAC.
///
/// Utility method that attempts to convert link-local IPv6 address to the
...
...
src/lib/dhcp/pkt4.h
View file @
7b920501
// Copyright (C) 2011-201
4
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-201
5
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
...
...
@@ -447,6 +447,16 @@ protected:
return
(
HWAddrPtr
());
}
/// @brief No-op
///
/// This method returns hardware address extracted from remote-id relay option.
/// Currently it is a no-op, it always returns NULL.
///
/// @return always NULL
virtual
HWAddrPtr
getMACFromRemoteIdRelayOption
(){
return
(
HWAddrPtr
());
}
/// local HW address (dst if receiving packet, src if sending packet)
HWAddrPtr
local_hwaddr_
;
...
...
src/lib/dhcp/pkt6.cc
View file @
7b920501
...
...
@@ -22,6 +22,7 @@
#include <util/io_utilities.h>
#include <exceptions/exceptions.h>
#include <dhcp/duid.h>
#include <dhcp/iface_mgr.h>
#include <iostream>
#include <sstream>
...
...
@@ -615,7 +616,7 @@ Pkt6::getMACFromIPv6RelayOpt() {
if
(
opt
)
{
const
OptionBuffer
data
=
opt
->
getData
();
if
(
data
.
size
()
<
3
)
{
// This client link address option is tru
c
nated. It's supposed to be
// This client link address option is trun
c
ated. It's supposed to be
// 2 bytes of link-layer type followed by link-layer address.
return
(
HWAddrPtr
());
}
...
...
@@ -683,5 +684,39 @@ Pkt6::getMACFromDocsisCMTS() {
}
}
HWAddrPtr
Pkt6
::
getMACFromRemoteIdRelayOption
()
{
if
(
relay_info_
.
empty
())
{
// This is a direct message
return
(
HWAddrPtr
());
}
// Get remote-id option from a relay agent closest to the client
OptionPtr
opt
=
getAnyRelayOption
(
D6O_REMOTE_ID
,
RELAY_GET_FIRST
);
if
(
opt
)
{
const
OptionBuffer
data
=
opt
->
getData
();
if
(
data
.
size
()
<
5
)
{
// This remote-id option is truncated. It's supposed to be
// 4 bytes of enterprise-number followed by remote-id.
return
(
HWAddrPtr
());
}
// Let's get the interface this packet was received on. We need it to get
// the hardware type.
Iface
*
iface
=
IfaceMgr
::
instance
().
getIface
(
iface_
);
uint16_t
hwtype
=
0
;
// not specified
// If we get the interface HW type, great! If not, let's not panic.
if
(
iface
)
{
hwtype
=
iface
->
getHWType
();
}
// Skip the initial 4 bytes which are enterprise-number.
return
(
HWAddrPtr
(
new
HWAddr
(
&
data
[
0
]
+
4
,
data
.
size
()
-
4
,
hwtype
)));
}
else
{
return
(
HWAddrPtr
());
}
}
}
// end of isc::dhcp namespace
}
// end of isc namespace
src/lib/dhcp/pkt6.h
View file @
7b920501
...
...
@@ -342,6 +342,16 @@ protected:
/// @return hardware address (if DOCSIS suboption 1026 is present)
virtual
HWAddrPtr
getMACFromDocsisCMTS
();
/// @brief Attempts to obtain MAC address from remote-id relay option.
///
/// This method is called from getMAC(HWADDR_SOURCE_REMOTE_ID) and should not be
/// called directly. It will attempt to extract MAC address information
/// from remote-id option inserted by a relay agent closest to the client.
/// If this method fails, it will return NULL.
///
/// @return hardware address (or NULL)
virtual
HWAddrPtr
getMACFromRemoteIdRelayOption
();
/// @brief Builds on wire packet for TCP transmission.
///
/// @todo This function is not implemented yet.
...
...
src/lib/dhcp/tests/pkt6_unittest.cc
100644 → 100755
View file @
7b920501
...
...
@@ -1242,4 +1242,56 @@ TEST_F(Pkt6Test, getMAC_DOCSIS_CMTS) {
EXPECT_FALSE
(
pkt
->
getMAC
(
HWAddr
::
HWADDR_SOURCE_DOCSIS_CMTS
));
}
// Test checks whether getMACFromRemoteIdRelayOption() returns the hardware (MAC)
// address properly from a relayed message.
TEST_F
(
Pkt6Test
,
getMACFromRemoteIdRelayOption
)
{
// Create a solicit message.
Pkt6
pkt
(
DHCPV6_SOLICIT
,
1234
);
// This should fail as the message is't relayed yet.
EXPECT_FALSE
(
pkt
.
getMAC
(
HWAddr
::
HWADDR_SOURCE_REMOTE_ID
));
// Let's get the first interface
Iface
*
iface
=
IfaceMgr
::
instance
().
getIface
(
1
);
ASSERT_TRUE
(
iface
);
// and set source interface data properly. getMACFromIPv6LinkLocal attempts
// to use source interface to obtain hardware type
pkt
.
setIface
(
iface
->
getName
());
pkt
.
setIndex
(
iface
->
getIndex
());
// Generate option data with randomly picked enterprise number and MAC address
const
uint8_t
opt_data
[]
=
{
1
,
2
,
3
,
4
,
// enterprise-number
0xa
,
0xb
,
0xc
,
0xd
,
0xe
,
0xf
// MAC
};
// Create option with number 37 (remote-id relay agent option)
OptionPtr
relay_opt
(
new
Option
(
Option
::
V6
,
D6O_REMOTE_ID
,
OptionBuffer
(
opt_data
,
opt_data
+
sizeof
(
opt_data
))));
// First simulate relaying message without adding remote-id option
Pkt6
::
RelayInfo
info
;
pkt
.
addRelayInfo
(
info
);
ASSERT_EQ
(
1
,
pkt
.
relay_info_
.
size
());
// This should fail as the remote-id option isn't there
EXPECT_FALSE
(
pkt
.
getMAC
(
HWAddr
::
HWADDR_SOURCE_REMOTE_ID
));
// Now add this option to the relayed message
info
.
options_
.
insert
(
make_pair
(
relay_opt
->
getType
(),
relay_opt
));
pkt
.
addRelayInfo
(
info
);
ASSERT_EQ
(
2
,
pkt
.
relay_info_
.
size
());
// This should work now
HWAddrPtr
mac
=
pkt
.
getMAC
(
HWAddr
::
HWADDR_SOURCE_REMOTE_ID
);
ASSERT_TRUE
(
mac
);
stringstream
tmp
;
tmp
<<
"hwtype="
<<
(
int
)
iface
->
getHWType
()
<<
" 0a:0b:0c:0d:0e:0f"
;
EXPECT_EQ
(
tmp
.
str
(),
mac
->
toText
(
true
));
}
}
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