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
f643dc9f
Commit
f643dc9f
authored
Dec 16, 2014
by
Tomek Mrugalski
🛰
Browse files
[3554] Configurable MAC sources implemented.
parent
88f088fa
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/dhcp6.spec
View file @
f643dc9f
...
...
@@ -422,6 +422,21 @@
} ]
}
},
{ "item_name": "mac-sources",
"item_type": "list",
"item_optional": true,
"item_default": [ "any" ],
"item_description": "Lists MAC/hardware address acquisition sources",
"list_item_spec":
{
"item_name": "source",
"item_type": "string",
"item_optional": true,
"item_default": "any"
}
} ,
{ "item_name": "dhcp-ddns",
"item_type": "map",
"item_optional": false,
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
f643dc9f
...
...
@@ -1253,10 +1253,18 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
hostname
=
fqdn
->
getDomainName
();
}
// Attempt to get MAC address using any of available mechanisms.
// It's ok if there response is NULL. Hardware address is optional in Lease6
/// @todo: Make this configurable after trac 3554 is done.
HWAddrPtr
hwaddr
=
query
->
getMAC
(
Pkt
::
HWADDR_SOURCE_ANY
);
// Attempt to get MAC address using configured mechanisms.
// It's ok if there response is NULL. Hardware address is optional in Lease6.
std
::
vector
<
uint32_t
>
mac_sources
=
CfgMgr
::
instance
().
getCurrentCfg
()
->
getMACSources
();
HWAddrPtr
hwaddr
;
for
(
std
::
vector
<
uint32_t
>::
const_iterator
it
=
mac_sources
.
begin
();
it
!=
mac_sources
.
end
();
++
it
)
{
hwaddr
=
query
->
getMAC
(
*
it
);
if
(
hwaddr
)
{
break
;
}
}
// Use allocation engine to pick a lease for this client. Allocation engine
// will try to honour the hint, but it is just a hint - some other address
...
...
src/bin/dhcp6/json_config_parser.cc
View file @
f643dc9f
...
...
@@ -613,6 +613,9 @@ namespace dhcp {
parser
=
new
HooksLibrariesParser
(
config_id
);
}
else
if
(
config_id
.
compare
(
"dhcp-ddns"
)
==
0
)
{
parser
=
new
D2ClientConfigParser
(
config_id
);
}
else
if
(
config_id
.
compare
(
"mac-sources"
)
==
0
)
{
parser
=
new
MACSourcesListConfigParser
(
config_id
,
globalContext
());
}
else
{
isc_throw
(
DhcpConfigError
,
"unsupported global configuration parameter: "
...
...
src/bin/dhcp6/json_config_parser.h
View file @
f643dc9f
...
...
@@ -15,9 +15,6 @@
#ifndef DHCP6_CONFIG_PARSER_H
#define DHCP6_CONFIG_PARSER_H
/// @todo: This header file and its .cc counterpart are very similar between
/// DHCPv4 and DHCPv6. They should be merged. See ticket #2355.
#include
<cc/data.h>
#include
<dhcpsrv/parsers/dhcp_parsers.h>
#include
<exceptions/exceptions.h>
...
...
src/lib/dhcp/pkt.cc
View file @
f643dc9f
...
...
@@ -20,6 +20,16 @@
namespace
isc
{
namespace
dhcp
{
const
uint32_t
Pkt
::
HWADDR_SOURCE_ANY
=
0xffffffff
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_UNKNOWN
=
0x00000000
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_RAW
=
0x00000001
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_DUID
=
0x00000002
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_IPV6_LINK_LOCAL
=
0x00000004
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
=
0x00000008
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_REMOTE_ID
=
0x00000010
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_SUBSCRIBER_ID
=
0x00000020
;
const
uint32_t
Pkt
::
HWADDR_SOURCE_DOCSIS
=
0x00000040
;
Pkt
::
Pkt
(
uint32_t
transid
,
const
isc
::
asiolink
::
IOAddress
&
local_addr
,
const
isc
::
asiolink
::
IOAddress
&
remote_addr
,
uint16_t
local_port
,
uint16_t
remote_port
)
...
...
@@ -223,6 +233,34 @@ Pkt::getMACFromIPv6(const isc::asiolink::IOAddress& addr) {
return
(
HWAddrPtr
(
new
HWAddr
(
bin
,
hwtype
)));
}
uint16_t
Pkt
::
MACSourceFromText
(
const
std
::
string
&
name
)
{
struct
{
const
char
*
name
;
uint32_t
type
;
}
sources
[]
=
{
{
"any"
,
Pkt
::
HWADDR_SOURCE_ANY
},
{
"raw"
,
Pkt
::
HWADDR_SOURCE_RAW
},
{
"duid"
,
Pkt
::
HWADDR_SOURCE_DUID
},
{
"ipv6-link-local"
,
Pkt
::
HWADDR_SOURCE_IPV6_LINK_LOCAL
},
{
"client-link-addr-option"
,
Pkt
::
HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
},
{
"rfc6939"
,
Pkt
::
HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
},
{
"remote-id"
,
Pkt
::
HWADDR_SOURCE_REMOTE_ID
},
{
"rfc4649"
,
Pkt
::
HWADDR_SOURCE_REMOTE_ID
},
{
"subscriber-id"
,
Pkt
::
HWADDR_SOURCE_SUBSCRIBER_ID
},
{
"rfc4580"
,
Pkt
::
HWADDR_SOURCE_SUBSCRIBER_ID
},
{
"docsis"
,
Pkt
::
HWADDR_SOURCE_DOCSIS
}
};
for
(
int
i
=
0
;
i
<
sizeof
(
sources
)
/
sizeof
(
sources
[
0
]);
++
i
)
{
if
(
name
.
compare
(
sources
[
i
].
name
))
{
return
(
sources
[
i
].
type
);
}
}
isc_throw
(
BadValue
,
"Can't convert '"
<<
name
<<
"' to any known MAC source."
);
}
};
};
src/lib/dhcp/pkt.h
View file @
f643dc9f
...
...
@@ -44,51 +44,63 @@ public:
///
/// @brief The list covers all possible MAC/hw address sources.
///
/// @note The uncommented ones are currently supported. When you implement
/// a new method, please uncomment appropriate line here.
///
/// @{
/// Not really a type, only used in getMAC() calls.
static
const
uint32_t
HWADDR_SOURCE_ANY
=
0xffff
;
static
const
uint32_t
HWADDR_SOURCE_ANY
;
/// Used when actual origin is not known, e.g. when reading from a
/// lease database that didn't store that information.
static
const
uint32_t
HWADDR_SOURCE_UNKNOWN
=
0x0000
;
static
const
uint32_t
HWADDR_SOURCE_UNKNOWN
;
/// Obtained first hand from raw socket (100% reliable).
static
const
uint32_t
HWADDR_SOURCE_RAW
=
0x0001
;
static
const
uint32_t
HWADDR_SOURCE_RAW
;
/// Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client
/// can send fake DUID).
//
static const uint32_t HWADDR_SOURCE_DUID
= 0x0002
;
static
const
uint32_t
HWADDR_SOURCE_DUID
;
/// Extracted from IPv6 link-local address. Not 100% reliable, as the
/// client can use different IID other than EUI-64, e.g. Windows supports
/// RFC4941 and uses random values instead of EUI-64.
static
const
uint32_t
HWADDR_SOURCE_IPV6_LINK_LOCAL
=
0x0004
;
static
const
uint32_t
HWADDR_SOURCE_IPV6_LINK_LOCAL
;
/// Get it from RFC6939 option. (A relay agent can insert client link layer
/// address option). Note that a skilled attacker can fake that by sending
/// his request relayed, so the legitimate relay will think it's a second
/// relay.
static
const
uint32_t
HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
=
0x0008
;
static
const
uint32_t
HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
;
/// A relay can insert remote-id. In some deployments it contains a MAC
/// address (RFC4649).
//
static const uint32_t HWADDR_SOURCE_REMOTE_ID
= 0x0010
;
static
const
uint32_t
HWADDR_SOURCE_REMOTE_ID
;
/// A relay can insert a subscriber-id option. In some deployments it
/// contains a MAC address (RFC4580).
//
static const uint32_t HWADDR_SOURCE_SUBSCRIBER_ID
= 0x0020
;
static
const
uint32_t
HWADDR_SOURCE_SUBSCRIBER_ID
;
/// A CMTS (acting as DHCP relay agent) that supports DOCSIS standard
/// can insert DOCSIS options that contain client's MAC address.
/// Client in this context would be a cable modem.
//
static const uint32_t HWADDR_SOURCE_DOCSIS
_OPTIONS = 0x0040
;
static
const
uint32_t
HWADDR_SOURCE_DOCSIS
;
/// @}
/// @brief Attempts to convert known hardware address sources to uint32_t
///
/// Supported strings are: any => 0xffffffff
/// raw => 0x00000001
/// duid => 0x00000002
/// ipv6-link-local 0x00000004
/// client-link-addr-option, rfc6939 => 0x00000008
/// remote-id, rfc4649 => 0x00000010
/// subscriber-id, rfc4580 => 0x00000020
/// docsis => 0x00000040
///
/// @throw BadValue if specified string is unknown
/// @return bitmask version of a given method
static
uint16_t
MACSourceFromText
(
const
std
::
string
&
name
);
protected:
/// @brief Constructor.
...
...
src/lib/dhcpsrv/parsers/dhcp_parsers.cc
View file @
f643dc9f
...
...
@@ -187,6 +187,7 @@ InterfaceListConfigParser(const std::string& param_name,
void
InterfaceListConfigParser
::
build
(
ConstElementPtr
value
)
{
CfgIface
cfg_iface
;
BOOST_FOREACH
(
ConstElementPtr
iface
,
value
->
listValue
())
{
std
::
string
iface_name
=
iface
->
stringValue
();
try
{
...
...
@@ -206,6 +207,45 @@ InterfaceListConfigParser::commit() {
// Nothing to do.
}
// ******************** MACSourcesListConfigParser *************************
MACSourcesListConfigParser
::
MACSourcesListConfigParser
(
const
std
::
string
&
param_name
,
ParserContextPtr
global_context
)
:
param_name_
(
param_name
),
global_context_
(
global_context
)
{
if
(
param_name_
!=
"mac-sources"
)
{
isc_throw
(
BadValue
,
"Internal error. MAC sources configuration "
"parser called for the wrong parameter: "
<<
param_name
);
}
}
void
MACSourcesListConfigParser
::
build
(
ConstElementPtr
value
)
{
CfgIface
cfg_iface
;
uint32_t
source
=
0
;
// By default, there's only one source defined: ANY.
// If user specified anything, we need to get rid of that default.
CfgMgr
::
instance
().
getStagingCfg
()
->
clearMACSources
();
BOOST_FOREACH
(
ConstElementPtr
source_elem
,
value
->
listValue
())
{
std
::
string
source_str
=
source_elem
->
stringValue
();
try
{
source
=
Pkt
::
MACSourceFromText
(
source_str
);
CfgMgr
::
instance
().
getStagingCfg
()
->
addMACSource
(
source
);
}
catch
(
const
std
::
exception
&
ex
)
{
isc_throw
(
DhcpConfigError
,
"Failed to convert '"
<<
source_str
<<
"' to any recognized MAC source:"
<<
ex
.
what
()
<<
" ("
<<
value
->
getPosition
()
<<
")"
);
}
}
}
void
MACSourcesListConfigParser
::
commit
()
{
// Nothing to do.
}
// ******************** HooksLibrariesParser *************************
HooksLibrariesParser
::
HooksLibrariesParser
(
const
std
::
string
&
param_name
)
...
...
src/lib/dhcpsrv/parsers/dhcp_parsers.h
View file @
f643dc9f
...
...
@@ -382,12 +382,10 @@ private:
/// @brief parser for interface list definition
///
/// This parser handles Dhcp4/interface entr
y
.
/// This parser handles Dhcp4/interface
s and Dhcp6/interfaces
entr
ies
.
/// It contains a list of network interfaces that the server listens on.
/// In particular, it can contain an entry called "all" or "any" that
/// designates all interfaces.
///
/// It is useful for parsing Dhcp4/interface parameter.
class
InterfaceListConfigParser
:
public
DhcpConfigParser
{
public:
...
...
@@ -422,6 +420,48 @@ private:
ParserContextPtr
global_context_
;
};
/// @brief parser for MAC/hardware aquisition sources
///
/// This parser handles Dhcp6/mac-sources entry.
/// It contains a list of MAC/hardware aquisition source, i.e. methods how
/// MAC address can possibly by obtained in DHCPv6. For a currently supported
/// methods, see @ref isc::dhcp::Pkt::getMAC.
class
MACSourcesListConfigParser
:
public
DhcpConfigParser
{
public:
/// @brief constructor
///
/// As this is a dedicated parser, it must be used to parse
/// "mac-sources" parameter only. All other types will throw exception.
///
/// @param param_name name of the configuration parameter being parsed
/// @param global_context Global parser context.
/// @throw BadValue if supplied parameter name is not "mac-sources"
MACSourcesListConfigParser
(
const
std
::
string
&
param_name
,
ParserContextPtr
global_context
);
/// @brief parses parameters value
///
/// Parses configuration entry (list of sources) and adds each element
/// to the sources list.
///
/// @param value pointer to the content of parsed values
virtual
void
build
(
isc
::
data
::
ConstElementPtr
value
);
/// @brief Does nothing.
virtual
void
commit
();
private:
// Parsed parameter name
std
::
string
param_name_
;
/// Global parser context.
ParserContextPtr
global_context_
;
};
/// @brief Parser for hooks library list
///
/// This parser handles the list of hooks libraries. This is an optional list,
...
...
@@ -1172,4 +1212,3 @@ typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
};
// end of isc namespace
#endif // DHCP_PARSERS_H
src/lib/dhcpsrv/srv_config.cc
View file @
f643dc9f
...
...
@@ -16,6 +16,7 @@
#include
<dhcpsrv/srv_config.h>
#include
<log/logger_manager.h>
#include
<log/logger_specification.h>
#include
<dhcp/pkt.h>
// Needed for HWADDR_SOURCE_*
#include
<list>
#include
<sstream>
...
...
@@ -28,12 +29,18 @@ SrvConfig::SrvConfig()
:
sequence_
(
0
),
cfg_option_def_
(
new
CfgOptionDef
()),
cfg_option_
(
new
CfgOption
()),
cfg_subnets4_
(
new
CfgSubnets4
()),
cfg_subnets6_
(
new
CfgSubnets6
()),
cfg_hosts_
(
new
CfgHosts
())
{
// By default, use any hardware source that is available.
mac_sources_
.
push_back
(
Pkt
::
HWADDR_SOURCE_ANY
);
}
SrvConfig
::
SrvConfig
(
const
uint32_t
sequence
)
:
sequence_
(
sequence
),
cfg_option_def_
(
new
CfgOptionDef
()),
cfg_option_
(
new
CfgOption
()),
cfg_subnets4_
(
new
CfgSubnets4
()),
cfg_subnets6_
(
new
CfgSubnets6
()),
cfg_hosts_
(
new
CfgHosts
())
{
// By default, use any hardware source that is available.
mac_sources_
.
push_back
(
Pkt
::
HWADDR_SOURCE_ANY
);
}
std
::
string
...
...
src/lib/dhcpsrv/srv_config.h
View file @
f643dc9f
...
...
@@ -235,6 +235,28 @@ public:
return
(
cfg_hosts_
);
}
/// @brief Adds additional MAC/hardware address aquisition.
///
/// @param source MAC source (see constants in Pkt::HWADDR_SOURCE_*)
///
/// Specified source is being added to the mac_sources_ array.
void
addMACSource
(
uint32_t
source
)
{
mac_sources_
.
push_back
(
source
);
}
/// @brief Provides access to the configure MAC/Hardware address sources.
///
/// @note The const reference returned is only valid as long as the
/// object that returned it.
const
std
::
vector
<
uint32_t
>&
getMACSources
()
const
{
return
mac_sources_
;
}
/// @brief Removes any configured MAC/Hardware address sources.
void
clearMACSources
()
{
mac_sources_
.
clear
();
}
//@}
/// @brief Copies the currnet configuration to a new configuration.
...
...
@@ -310,6 +332,7 @@ public:
//@}
private:
/// @brief Sequence number identifying the configuration.
...
...
@@ -348,6 +371,8 @@ private:
/// reservations for different IPv4 and IPv6 subnets.
CfgHostsPtr
cfg_hosts_
;
/// @brief A list of configured MAC sources.
std
::
vector
<
uint32_t
>
mac_sources_
;
};
/// @name Pointers to the @c SrvConfig object.
...
...
src/lib/dhcpsrv/tests/Makefile.am
View file @
f643dc9f
...
...
@@ -120,7 +120,8 @@ if USE_CLANGPP
libdhcpsrv_unittests_CXXFLAGS
+=
-Wno-unused-variable
-Wno-unused-parameter
endif
libdhcpsrv_unittests_LDADD
=
$(top_builddir)
/src/lib/dhcpsrv/libkea-dhcpsrv.la
libdhcpsrv_unittests_LDADD
=
$(top_builddir)
/src/lib/dhcp/libkea-dhcp++.la
libdhcpsrv_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcpsrv/libkea-dhcpsrv.la
libdhcpsrv_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
libdhcpsrv_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcp/tests/libdhcptest.la
libdhcpsrv_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcp/libkea-dhcp++.la
...
...
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