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
450
Issues
450
List
Boards
Labels
Service Desk
Milestones
Merge Requests
75
Merge Requests
75
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
741fe7bc
Commit
741fe7bc
authored
Jan 08, 2013
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Plain Diff
[master] Merge branch 'trac2315'
Conflicts: src/bin/dhcp4/config_parser.cc src/bin/dhcp6/config_parser.cc
parents
856d60a9
b7892222
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
652 additions
and
96 deletions
+652
-96
src/bin/dhcp4/config_parser.cc
src/bin/dhcp4/config_parser.cc
+6
-4
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp4/tests/config_parser_unittest.cc
+20
-18
src/bin/dhcp6/config_parser.cc
src/bin/dhcp6/config_parser.cc
+6
-5
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/dhcp6_srv.cc
+3
-3
src/bin/dhcp6/tests/config_parser_unittest.cc
src/bin/dhcp6/tests/config_parser_unittest.cc
+18
-18
src/lib/dhcp/libdhcp++.cc
src/lib/dhcp/libdhcp++.cc
+28
-0
src/lib/dhcp/libdhcp++.h
src/lib/dhcp/libdhcp++.h
+15
-0
src/lib/dhcp/option_definition.h
src/lib/dhcp/option_definition.h
+12
-1
src/lib/dhcp/tests/libdhcp++_unittest.cc
src/lib/dhcp/tests/libdhcp++_unittest.cc
+60
-0
src/lib/dhcpsrv/cfgmgr.cc
src/lib/dhcpsrv/cfgmgr.cc
+84
-1
src/lib/dhcpsrv/cfgmgr.h
src/lib/dhcpsrv/cfgmgr.h
+62
-1
src/lib/dhcpsrv/subnet.cc
src/lib/dhcpsrv/subnet.cc
+53
-4
src/lib/dhcpsrv/subnet.h
src/lib/dhcpsrv/subnet.h
+35
-12
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
+162
-1
src/lib/dhcpsrv/tests/subnet_unittest.cc
src/lib/dhcpsrv/tests/subnet_unittest.cc
+88
-28
No files found.
src/bin/dhcp4/config_parser.cc
View file @
741fe7bc
...
...
@@ -1117,8 +1117,8 @@ private:
subnet_
->
addPool4
(
*
it
);
}
const
Subnet
::
OptionContainer
&
options
=
subnet_
->
getOptions
(
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
Subnet
::
OptionContainerPtr
options
=
subnet_
->
getOptionDescriptors
(
"dhcp4"
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Add subnet specific options.
BOOST_FOREACH
(
Subnet
::
OptionDescriptor
desc
,
options_
)
{
...
...
@@ -1127,7 +1127,7 @@ private:
LOG_WARN
(
dhcp4_logger
,
DHCP4_CONFIG_OPTION_DUPLICATE
)
.
arg
(
desc
.
option
->
getType
()).
arg
(
addr
.
toText
());
}
subnet_
->
addOption
(
desc
.
option
);
subnet_
->
addOption
(
desc
.
option
,
false
,
"dhcp4"
);
}
// Check all global options and add them to the subnet object if
...
...
@@ -1137,6 +1137,8 @@ private:
BOOST_FOREACH
(
Subnet
::
OptionDescriptor
desc
,
option_defaults
)
{
// Get all options specified locally in the subnet and having
// code equal to global option's code.
Subnet
::
OptionContainerPtr
options
=
subnet_
->
getOptionDescriptors
(
"dhcp4"
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
Subnet
::
OptionContainerTypeRange
range
=
idx
.
equal_range
(
desc
.
option
->
getType
());
// @todo: In the future we will be searching for options using either
// an option code or namespace. Currently we have only the option
...
...
@@ -1147,7 +1149,7 @@ private:
// want to issue a warning about dropping the configuration of
// a global option if one already exsists.
if
(
std
::
distance
(
range
.
first
,
range
.
second
)
==
0
)
{
subnet_
->
addOption
(
desc
.
option
);
subnet_
->
addOption
(
desc
.
option
,
false
,
"dhcp4"
);
}
}
}
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
741fe7bc
...
...
@@ -471,11 +471,11 @@ TEST_F(Dhcp4ParserTest, optionDataDefaults) {
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.200"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp4"
);
ASSERT_EQ
(
2
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -542,11 +542,11 @@ TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.24"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp4"
);
ASSERT_EQ
(
2
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -609,11 +609,11 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
Subnet4Ptr
subnet1
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.100"
));
ASSERT_TRUE
(
subnet1
);
const
Subnet
::
OptionContainer
&
options1
=
subnet1
->
getOptions
(
);
ASSERT_EQ
(
1
,
options1
.
size
());
Subnet
::
OptionContainerPtr
options1
=
subnet1
->
getOptionDescriptors
(
"dhcp4"
);
ASSERT_EQ
(
1
,
options1
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx1
=
options1
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx1
=
options1
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -633,10 +633,10 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
// Test another subnet in the same way.
Subnet4Ptr
subnet2
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.3.102"
));
ASSERT_TRUE
(
subnet2
);
const
Subnet
::
OptionContainer
&
options2
=
subnet2
->
getOptions
(
);
ASSERT_EQ
(
1
,
options2
.
size
());
Subnet
::
OptionContainerPtr
options2
=
subnet2
->
getOptionDescriptors
(
"dhcp4"
);
ASSERT_EQ
(
1
,
options2
->
size
());
const
Subnet
::
OptionContainerTypeIndex
&
idx2
=
options2
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx2
=
options2
->
get
<
1
>
();
std
::
pair
<
Subnet
::
OptionContainerTypeIndex
::
const_iterator
,
Subnet
::
OptionContainerTypeIndex
::
const_iterator
>
range2
=
idx2
.
equal_range
(
23
);
...
...
@@ -718,11 +718,11 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.5"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp4"
);
ASSERT_EQ
(
1
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -761,11 +761,13 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.5"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
();
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp4"
);
ASSERT_TRUE
(
options
);
ASSERT_EQ
(
1
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
src/bin/dhcp6/config_parser.cc
View file @
741fe7bc
...
...
@@ -1151,9 +1151,8 @@ private:
subnet_
->
addPool6
(
*
it
);
}
// Get the options search index.
const
Subnet
::
OptionContainer
&
options
=
subnet_
->
getOptions
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
Subnet
::
OptionContainerPtr
options
=
subnet_
->
getOptionDescriptors
(
"dhcp6"
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Add subnet specific options.
BOOST_FOREACH
(
Subnet
::
OptionDescriptor
desc
,
options_
)
{
...
...
@@ -1162,7 +1161,7 @@ private:
LOG_WARN
(
dhcp6_logger
,
DHCP6_CONFIG_OPTION_DUPLICATE
)
.
arg
(
desc
.
option
->
getType
()).
arg
(
addr
.
toText
());
}
subnet_
->
addOption
(
desc
.
option
);
subnet_
->
addOption
(
desc
.
option
,
false
,
"dhcp6"
);
}
// Check all global options and add them to the subnet object if
...
...
@@ -1172,6 +1171,8 @@ private:
BOOST_FOREACH
(
Subnet
::
OptionDescriptor
desc
,
option_defaults
)
{
// Get all options specified locally in the subnet and having
// code equal to global option's code.
Subnet
::
OptionContainerPtr
options
=
subnet_
->
getOptionDescriptors
(
"dhcp6"
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
Subnet
::
OptionContainerTypeRange
range
=
idx
.
equal_range
(
desc
.
option
->
getType
());
// @todo: In the future we will be searching for options using either
// an option code or namespace. Currently we have only the option
...
...
@@ -1182,7 +1183,7 @@ private:
// want to issue a warning about dropping the configuration of
// a global option if one already exsists.
if
(
std
::
distance
(
range
.
first
,
range
.
second
)
==
0
)
{
subnet_
->
addOption
(
desc
.
option
);
subnet_
->
addOption
(
desc
.
option
,
false
,
"dhcp6"
);
}
}
}
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
741fe7bc
// Copyright (C) 2011-201
2
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-201
3
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
...
...
@@ -340,8 +340,8 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer)
// Get the list of options that client requested.
const
std
::
vector
<
uint16_t
>&
requested_opts
=
option_oro
->
getValues
();
// Get the list of options configured for a subnet.
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp6"
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Try to match requested options with those configured for a subnet.
// If match is found, append configured option to the answer message.
BOOST_FOREACH
(
uint16_t
opt
,
requested_opts
)
{
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
741fe7bc
...
...
@@ -463,11 +463,11 @@ TEST_F(Dhcp6ParserTest, optionDataDefaults) {
Subnet6Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet6
(
IOAddress
(
"2001:db8:1::5"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp6"
);
ASSERT_EQ
(
2
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -541,11 +541,11 @@ TEST_F(Dhcp6ParserTest, optionDataInSingleSubnet) {
Subnet6Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet6
(
IOAddress
(
"2001:db8:1::5"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp6"
);
ASSERT_EQ
(
2
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -609,11 +609,11 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
Subnet6Ptr
subnet1
=
CfgMgr
::
instance
().
getSubnet6
(
IOAddress
(
"2001:db8:1::5"
));
ASSERT_TRUE
(
subnet1
);
const
Subnet
::
OptionContainer
&
options1
=
subnet1
->
getOptions
(
);
ASSERT_EQ
(
1
,
options1
.
size
());
Subnet
::
OptionContainerPtr
options1
=
subnet1
->
getOptionDescriptors
(
"dhcp6"
);
ASSERT_EQ
(
1
,
options1
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx1
=
options1
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx1
=
options1
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -633,10 +633,10 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
// Test another subnet in the same way.
Subnet6Ptr
subnet2
=
CfgMgr
::
instance
().
getSubnet6
(
IOAddress
(
"2001:db8:2::4"
));
ASSERT_TRUE
(
subnet2
);
const
Subnet
::
OptionContainer
&
options2
=
subnet2
->
getOptions
(
);
ASSERT_EQ
(
1
,
options2
.
size
());
Subnet
::
OptionContainerPtr
options2
=
subnet2
->
getOptionDescriptors
(
"dhcp6"
);
ASSERT_EQ
(
1
,
options2
->
size
());
const
Subnet
::
OptionContainerTypeIndex
&
idx2
=
options2
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx2
=
options2
->
get
<
1
>
();
std
::
pair
<
Subnet
::
OptionContainerTypeIndex
::
const_iterator
,
Subnet
::
OptionContainerTypeIndex
::
const_iterator
>
range2
=
idx2
.
equal_range
(
101
);
...
...
@@ -727,11 +727,11 @@ TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
Subnet6Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet6
(
IOAddress
(
"2001:db8:1::5"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp6"
);
ASSERT_EQ
(
1
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
@@ -769,11 +769,11 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
Subnet6Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet6
(
IOAddress
(
"2001:db8:1::5"
));
ASSERT_TRUE
(
subnet
);
const
Subnet
::
OptionContainer
&
options
=
subnet
->
getOptions
(
);
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainerPtr
options
=
subnet
->
getOptionDescriptors
(
"dhcp6"
);
ASSERT_EQ
(
1
,
options
->
size
());
// Get the search index. Index #1 is to search using option code.
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
->
get
<
1
>
();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
...
...
src/lib/dhcp/libdhcp++.cc
View file @
741fe7bc
...
...
@@ -74,6 +74,34 @@ LibDHCP::getOptionDef(const Option::Universe u, const uint16_t code) {
return
(
OptionDefinitionPtr
());
}
bool
LibDHCP
::
isStandardOption
(
const
Option
::
Universe
u
,
const
uint16_t
code
)
{
if
(
u
==
Option
::
V6
)
{
if
(
code
<
79
&&
code
!=
10
&&
code
!=
35
)
{
return
(
true
);
}
}
else
if
(
u
==
Option
::
V4
)
{
if
(
!
(
code
==
84
||
code
==
96
||
(
code
>
101
&&
code
<
112
)
||
code
==
115
||
code
==
126
||
code
==
127
||
(
code
>
146
&&
code
<
150
)
||
(
code
>
177
&&
code
<
208
)
||
(
code
>
213
&&
code
<
220
)
||
(
code
>
221
&&
code
<
224
)))
{
return
(
true
);
}
}
return
(
false
);
}
OptionPtr
LibDHCP
::
optionFactory
(
Option
::
Universe
u
,
uint16_t
type
,
...
...
src/lib/dhcp/libdhcp++.h
View file @
741fe7bc
...
...
@@ -55,6 +55,21 @@ public:
static
OptionDefinitionPtr
getOptionDef
(
const
Option
::
Universe
u
,
const
uint16_t
code
);
/// @brief Check if the specified option is a standard option.
///
/// @param u universe (V4 or V6)
/// @param code option code.
///
/// @return true if the specified option is a standard option.
/// @todo We arleady create option definitions for the subset if
/// standard options. We are aiming that this function checks
/// the presence of the standard option definition and if it finds
/// it, then the true value is returned. However, at this point
/// this is not doable because some of the definitions (for less
/// important options) are not created yet.
static
bool
isStandardOption
(
const
Option
::
Universe
u
,
const
uint16_t
code
);
/// @brief Factory function to create instance of option.
///
/// Factory method creates instance of specified option. The option
...
...
src/lib/dhcp/option_definition.h
View file @
741fe7bc
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012
-2013
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
...
...
@@ -42,6 +42,14 @@ public:
isc
::
Exception
(
file
,
line
,
what
)
{
};
};
/// @brief Exception to be thrown when the particular option definition
/// duplicates existing option definition.
class
DuplicateOptionDefinition
:
public
Exception
{
public:
DuplicateOptionDefinition
(
const
char
*
file
,
size_t
line
,
const
char
*
what
)
:
isc
::
Exception
(
file
,
line
,
what
)
{
};
};
/// @brief Forward declaration to OptionDefinition.
class
OptionDefinition
;
...
...
@@ -492,6 +500,9 @@ typedef boost::multi_index_container<
>
>
OptionDefContainer
;
/// Pointer to an option definition container.
typedef
boost
::
shared_ptr
<
OptionDefContainer
>
OptionDefContainerPtr
;
/// Type of the index #1 - option type.
typedef
OptionDefContainer
::
nth_index
<
1
>::
type
OptionDefContainerTypeIndex
;
/// Pair of iterators to represent the range of options definitions
...
...
src/lib/dhcp/tests/libdhcp++_unittest.cc
View file @
741fe7bc
...
...
@@ -453,6 +453,66 @@ TEST_F(LibDhcpTest, unpackOptions4) {
EXPECT_TRUE
(
x
==
options
.
end
());
// option 2 not found
}
TEST_F
(
LibDhcpTest
,
isStandardOption4
)
{
// Get all option codes that are not occupied by standard options.
const
uint16_t
unassigned_codes
[]
=
{
84
,
96
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
,
110
,
111
,
115
,
126
,
127
,
147
,
148
,
149
,
178
,
179
,
180
,
181
,
182
,
183
,
184
,
185
,
186
,
187
,
188
,
189
,
190
,
191
,
192
,
193
,
194
,
195
,
196
,
197
,
198
,
199
,
200
,
201
,
202
,
203
,
204
,
205
,
206
,
207
,
214
,
215
,
216
,
217
,
218
,
219
,
222
,
223
};
const
size_t
unassigned_num
=
sizeof
(
unassigned_codes
)
/
sizeof
(
unassigned_codes
[
0
]);
// Try all possible option codes.
for
(
size_t
i
=
0
;
i
<
256
;
++
i
)
{
// Some ranges of option codes are unassigned and thus the isStandardOption
// should return false for them.
bool
check_unassigned
=
false
;
// Check the array of unassigned options to find out whether option code
// is assigned to standard option or unassigned.
for
(
size_t
j
=
0
;
j
<
unassigned_num
;
++
j
)
{
// If option code is found within the array of unassigned options
// we the isStandardOption function should return false.
if
(
unassigned_codes
[
j
]
==
i
)
{
check_unassigned
=
true
;
EXPECT_FALSE
(
LibDHCP
::
isStandardOption
(
Option
::
V4
,
unassigned_codes
[
j
]))
<<
"Test failed for option code "
<<
unassigned_codes
[
j
];
break
;
}
}
// If the option code belongs to the standard option then the
// isStandardOption should return true.
if
(
!
check_unassigned
)
{
EXPECT_TRUE
(
LibDHCP
::
isStandardOption
(
Option
::
V4
,
i
))
<<
"Test failed for the option code "
<<
i
;
}
}
}
TEST_F
(
LibDhcpTest
,
isStandardOption6
)
{
// All option codes in the range from 0 to 78 (except 10 and 35)
// identify the standard options.
for
(
uint16_t
code
=
0
;
code
<
79
;
++
code
)
{
if
(
code
!=
10
&&
code
!=
35
)
{
EXPECT_TRUE
(
LibDHCP
::
isStandardOption
(
Option
::
V6
,
code
))
<<
"Test failed for option code "
<<
code
;
}
}
// Check the option codes 10 and 35. They are unassigned.
EXPECT_FALSE
(
LibDHCP
::
isStandardOption
(
Option
::
V6
,
10
));
EXPECT_FALSE
(
LibDHCP
::
isStandardOption
(
Option
::
V6
,
35
));
// Check a range of option codes above 78. Those are option codes
// identifying non-standard options.
for
(
uint16_t
code
=
79
;
code
<
512
;
++
code
)
{
EXPECT_FALSE
(
LibDHCP
::
isStandardOption
(
Option
::
V6
,
code
))
<<
"Test failed for option code "
<<
code
;
}
}
TEST_F
(
LibDhcpTest
,
stdOptionDefs4
)
{
// Create a buffer that holds dummy option data.
...
...
src/lib/dhcpsrv/cfgmgr.cc
View file @
741fe7bc
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012
-2013
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
...
...
@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <asiolink/io_address.h>
#include <dhcp/libdhcp++.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dhcpsrv_log.h>
...
...
@@ -28,6 +29,84 @@ CfgMgr::instance() {
return
(
cfg_mgr
);
}
void
CfgMgr
::
addOptionDef
(
const
OptionDefinitionPtr
&
def
,
const
std
::
string
&
option_space
)
{
// @todo we need better validation of the provided option space name here.
// This will be implemented when #2313 is merged.
if
(
option_space
.
empty
())
{
isc_throw
(
BadValue
,
"option space name must not be empty"
);
}
else
if
(
!
def
)
{
// Option definition must point to a valid object.
isc_throw
(
MalformedOptionDefinition
,
"option definition must not be NULL"
);
}
else
if
(
getOptionDef
(
option_space
,
def
->
getCode
()))
{
// Option definition must not be overriden.
isc_throw
(
DuplicateOptionDefinition
,
"option definition already added"
<<
" to option space "
<<
option_space
);
}
else
if
((
option_space
==
"dhcp4"
&&
LibDHCP
::
isStandardOption
(
Option
::
V4
,
def
->
getCode
()))
||
(
option_space
==
"dhcp6"
&&
LibDHCP
::
isStandardOption
(
Option
::
V6
,
def
->
getCode
())))
{
// We must not override standard (assigned) option. The standard options
// belong to dhcp4 or dhcp6 option space.
isc_throw
(
BadValue
,
"unable to override definition of option '"
<<
def
->
getCode
()
<<
"' in standard option space '"
<<
option_space
<<
"'."
);
}
// Get existing option definitions for the option space.
OptionDefContainerPtr
defs
=
getOptionDefs
(
option_space
);
// getOptionDefs always returns a valid pointer to
// the container. Let's make an assert to make sure.
assert
(
defs
);
// Actually add the new definition.
defs
->
push_back
(
def
);
option_def_spaces_
[
option_space
]
=
defs
;
}
OptionDefContainerPtr
CfgMgr
::
getOptionDefs
(
const
std
::
string
&
option_space
)
const
{
// @todo Validate the option space once the #2313 is implemented.
// Get all option definitions for the particular option space.
const
OptionDefsMap
::
const_iterator
&
defs
=
option_def_spaces_
.
find
(
option_space
);
// If there are no option definitions for the particular option space
// then return empty container.
if
(
defs
==
option_def_spaces_
.
end
())
{
return
(
OptionDefContainerPtr
(
new
OptionDefContainer
()));
}
// If option definitions found, return them.
return
(
defs
->
second
);
}
OptionDefinitionPtr
CfgMgr
::
getOptionDef
(
const
std
::
string
&
option_space
,
const
uint16_t
option_code
)
const
{
// @todo Validate the option space once the #2313 is implemented.
// Get a reference to option definitions for a particular option space.
OptionDefContainerPtr
defs
=
getOptionDefs
(
option_space
);
// If there are no matching option definitions then return the empty pointer.
if
(
!
defs
||
defs
->
empty
())
{
return
(
OptionDefinitionPtr
());
}
// If there are some option definitions for a particular option space
// use an option code to get the one we want.
const
OptionDefContainerTypeIndex
&
idx
=
defs
->
get
<
1
>
();
const
OptionDefContainerTypeRange
&
range
=
idx
.
equal_range
(
option_code
);
// If there is no definition that matches option code, return empty pointer.
if
(
std
::
distance
(
range
.
first
,
range
.
second
)
==
0
)
{
return
(
OptionDefinitionPtr
());
}
// If there is more than one definition matching an option code, return
// the first one. This should not happen because we check for duplicates
// when addOptionDef is called.
return
(
*
range
.
first
);
}
Subnet6Ptr
CfgMgr
::
getSubnet6
(
const
isc
::
asiolink
::
IOAddress
&
hint
)
{
...
...
@@ -119,6 +198,10 @@ void CfgMgr::addSubnet4(const Subnet4Ptr& subnet) {
subnets4_
.
push_back
(
subnet
);
}
void
CfgMgr
::
deleteOptionDefs
()
{
option_def_spaces_
.
clear
();
}
void
CfgMgr
::
deleteSubnets4
()
{
LOG_DEBUG
(
dhcpsrv_logger
,
DHCPSRV_DBG_TRACE
,
DHCPSRV_CFGMGR_DELETE_SUBNET4
);
subnets4_
.
clear
();
...
...
src/lib/dhcpsrv/cfgmgr.h
View file @
741fe7bc
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012
-2013
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
...
...
@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp/option.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/subnet.h>
#include <util/buffer.h>
...
...
@@ -77,6 +78,41 @@ public:
/// accessing it.
static
CfgMgr
&
instance
();
/// @brief Add new option definition.
///
/// @param def option definition to be added.
/// @param option_space name of the option space to add definition to.
///
/// @throw isc::dhcp::DuplicateOptionDefinition when the particular
/// option definition already exists.
/// @throw isc::dhcp::MalformedOptionDefinition when the pointer to
/// an option definition is NULL.
/// @throw isc::BadValue when the option space name is empty or
/// when trying to override the standard option (in dhcp4 or dhcp6
/// option space).
void
addOptionDef
(
const
OptionDefinitionPtr
&
def
,
const
std
::
string
&
option_space
);
/// @brief Return option definitions for particular option space.
///
/// @param option_space option space.
///
/// @return pointer to the collection of option definitions for
/// the particular option space. The option collection is empty
/// if no option exists for the option space specified.
OptionDefContainerPtr
getOptionDefs
(
const
std
::
string
&
option_space
)
const
;
/// @brief Return option definition for a particular option space and code.
///
/// @param option_space option space.
/// @param option_code option code.
///
/// @return an option definition or NULL pointer if option definition
/// has not been found.
OptionDefinitionPtr
getOptionDef
(
const
std
::
string
&
option_space
,
const
uint16_t
option_code
)
const
;
/// @brief get IPv6 subnet by address
///
/// Finds a matching subnet, based on an address. This can be used
...
...
@@ -86,6 +122,8 @@ public:
/// (for directly connected clients)
///
/// @param hint an address that belongs to a searched subnet
///
/// @return a subnet object
Subnet6Ptr
getSubnet6
(
const
isc
::
asiolink
::
IOAddress
&
hint
);
/// @brief get IPv6 subnet by interface-id
...
...
@@ -93,12 +131,19 @@ public:
/// Another possibility to find a subnet is based on interface-id.