Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Osuchowski
Kea
Commits
741fe7bc
Commit
741fe7bc
authored
Jan 08, 2013
by
Marcin Siodelski
Browse files
[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
src/bin/dhcp4/config_parser.cc
View file @
741fe7bc
...
...
@@ -1117,8 +1117,8 @@ private:
subnet_
->
addPool4
(
*
it
);
}
const
Subnet
::
OptionContainer
&
options
=
subnet_
->
getOption
s
(
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
Subnet
::
OptionContainer
Ptr
options
=
subnet_
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options1
.
size
());
Subnet
::
OptionContainer
Ptr
options1
=
subnet1
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options2
.
size
());
Subnet
::
OptionContainer
Ptr
options2
=
subnet2
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
const
Subnet
::
OptionContainerTypeIndex
&
idx
=
options
.
get
<
1
>
();
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
2
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options1
.
size
());
Subnet
::
OptionContainer
Ptr
options1
=
subnet1
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options2
.
size
());
Subnet
::
OptionContainer
Ptr
options2
=
subnet2
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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
->
getOption
s
(
);
ASSERT_EQ
(
1
,
options
.
size
());
Subnet
::
OptionContainer
Ptr
options
=
subnet
->
getOption
Descriptors
(
"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.
///
/// @param interface_id content of interface-id option returned by a relay
///