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
3c35688d
Commit
3c35688d
authored
Oct 03, 2012
by
Marcin Siodelski
Browse files
[2304] Added basic implementation of OptionDefinition class and unit tests.
parent
f5811cdf
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/Makefile.am
View file @
3c35688d
...
...
@@ -21,10 +21,12 @@ libb10_dhcp___la_SOURCES += iface_mgr_linux.cc
libb10_dhcp___la_SOURCES
+=
iface_mgr_bsd.cc
libb10_dhcp___la_SOURCES
+=
iface_mgr_sun.cc
libb10_dhcp___la_SOURCES
+=
option.cc option.h
libb10_dhcp___la_SOURCES
+=
option_definition.cc option_definition.h
libb10_dhcp___la_SOURCES
+=
option6_ia.cc option6_ia.h
libb10_dhcp___la_SOURCES
+=
option6_iaaddr.cc option6_iaaddr.h
libb10_dhcp___la_SOURCES
+=
option6_addrlst.cc option6_addrlst.h
libb10_dhcp___la_SOURCES
+=
option4_addrlst.cc option4_addrlst.h
libb10_dhcp___la_SOURCES
+=
option6_int.h
libb10_dhcp___la_SOURCES
+=
dhcp6.h dhcp4.h
libb10_dhcp___la_SOURCES
+=
pkt6.cc pkt6.h
libb10_dhcp___la_SOURCES
+=
pkt4.cc pkt4.h
...
...
src/lib/dhcp/option4_addrlst.h
View file @
3c35688d
...
...
@@ -20,6 +20,7 @@
#include
<vector>
#include
<boost/shared_ptr.hpp>
#include
<boost/shared_array.hpp>
#include
<asiolink/io_address.h>
#include
<util/buffer.h>
#include
<dhcp/option.h>
...
...
src/lib/dhcp/option6_int.h
0 → 100644
View file @
3c35688d
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef OPTION_INT6_H_
#define OPTION_INT6_H_
#include
<stdint.h>
#include
<limits>
#include
<util/io_utilities.h>
#include
"dhcp/option.h"
namespace
isc
{
namespace
dhcp
{
template
<
typename
T
>
class
OptionInt6
:
public
Option
{
public:
OptionInt6
(
uint16_t
type
,
T
value
)
:
Option
(
Option
::
V6
,
type
),
value_
(
value
)
{
}
OptionInt6
(
uint16_t
type
,
OptionBufferConstIter
begin
,
OptionBufferConstIter
end
)
:
Option
(
Option
::
V6
,
type
)
{
unpack
(
begin
,
end
);
}
/// Writes option in wire-format to buf, returns pointer to first unused
/// byte after stored option.
///
/// @param buf buffer (option will be stored here)
void
pack
(
isc
::
util
::
OutputBuffer
&
buf
)
{
if
(
!
std
::
numeric_limits
<
T
>::
is_integer
)
{
isc_throw
(
isc
::
BadValue
,
""
);
}
buf
.
writeUint16
(
type_
);
buf
.
writeUint16
(
len
()
-
OPTION6_HDR_LEN
);
switch
(
sizeof
(
T
))
{
case
1
:
buf
.
writeUint8
(
value_
);
break
;
case
2
:
buf
.
writeUint16
(
value_
);
break
;
case
4
:
buf
.
writeUint32
(
value_
);
break
;
default:
isc_throw
(
isc
::
BadValue
,
""
);
}
}
/// @brief Parses received buffer
///
/// Parses received buffer and returns offset to the first unused byte after
/// parsed option.
///
/// @param begin iterator to first byte of option data
/// @param end iterator to end of option data (first byte after option end)
virtual
void
unpack
(
OptionBufferConstIter
begin
,
OptionBufferConstIter
end
)
{
if
(
distance
(
begin
,
end
)
<
sizeof
(
T
))
{
isc_throw
(
OutOfRange
,
"Option "
<<
type_
<<
" truncated"
);
}
switch
(
sizeof
(
T
))
{
case
1
:
value_
=
*
begin
;
break
;
case
2
:
value_
=
isc
::
util
::
readUint16
(
&
(
*
begin
)
);
break
;
case
4
:
value_
=
isc
::
util
::
readUint32
(
&
(
*
begin
)
);
break
;
default:
isc_throw
(
isc
::
BadValue
,
""
);
}
LibDHCP
::
unpackOptions6
(
OptionBuffer
(
begin
,
end
),
options_
);
}
void
setValue
(
T
value
)
{
value_
=
value
;
}
T
getValue
()
const
{
return
value_
;
}
/// @brief returns complete length of option
///
/// Returns length of this option, including option header and suboptions
///
/// @return length of this option
virtual
uint16_t
len
()
{
uint16_t
length
=
OPTION6_HDR_LEN
+
sizeof
(
T
);
// length of all suboptions
for
(
Option
::
OptionCollection
::
iterator
it
=
options_
.
begin
();
it
!=
options_
.
end
();
++
it
)
{
length
+=
(
*
it
).
second
->
len
();
}
return
(
length
);
}
private:
T
value_
;
};
}
// isc::dhcp namespace
}
// isc namespace
#endif
/* OPTION_IA_H_ */
src/lib/dhcp/option_definition.cc
0 → 100644
View file @
3c35688d
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
"dhcp/option_definition.h"
#include
"dhcp/option4_addrlst.h"
#include
"dhcp/option6_addrlst.h"
#include
"dhcp/option6_int.h"
using
namespace
std
;
using
namespace
isc
::
util
;
namespace
isc
{
namespace
dhcp
{
OptionDefinition
::
DataTypeUtil
::
DataTypeUtil
()
{
data_types_
[
"empty"
]
=
EMPTY_TYPE
;
data_types_
[
"boolean"
]
=
BOOLEAN_TYPE
;
data_types_
[
"int8"
]
=
INT8_TYPE
;
data_types_
[
"int16"
]
=
INT16_TYPE
;
data_types_
[
"int32"
]
=
INT32_TYPE
;
data_types_
[
"uint8"
]
=
UINT8_TYPE
;
data_types_
[
"uint16"
]
=
UINT16_TYPE
;
data_types_
[
"uint32"
]
=
UINT32_TYPE
;
data_types_
[
"ipv4-address"
]
=
IPV4_ADDRESS_TYPE
;
data_types_
[
"ipv6-address"
]
=
IPV6_ADDRESS_TYPE
;
data_types_
[
"string"
]
=
STRING_TYPE
;
data_types_
[
"fqdn"
]
=
FQDN_TYPE
;
data_types_
[
"record"
]
=
RECORD_TYPE
;
}
OptionDefinition
::
DataType
OptionDefinition
::
DataTypeUtil
::
getDataType
(
const
std
::
string
&
data_type
)
{
std
::
map
<
std
::
string
,
DataType
>::
const_iterator
data_type_it
=
data_types_
.
find
(
data_type
);
if
(
data_type_it
!=
data_types_
.
end
())
{
return
(
data_type_it
->
second
);
}
return
UNKNOWN_TYPE
;
}
OptionDefinition
::
OptionDefinition
(
const
std
::
string
&
name
,
const
uint16_t
code
,
const
std
::
string
&
type
,
const
bool
array_type
/* = false */
)
:
name_
(
name
),
code_
(
code
),
type_
(
UNKNOWN_TYPE
),
array_type_
(
array_type
)
{
// Data type is held as enum value by this class.
// Use the provided option type string to get the
// corresponding enum value.
type_
=
DataTypeUtil
::
instance
().
getDataType
(
type
);
}
OptionDefinition
::
OptionDefinition
(
const
std
::
string
&
name
,
const
uint16_t
code
,
const
DataType
type
,
const
bool
array_type
/* = false */
)
:
name_
(
name
),
code_
(
code
),
type_
(
type
),
array_type_
(
array_type
)
{
}
void
OptionDefinition
::
addRecordField
(
const
std
::
string
&
data_type_name
)
{
DataType
data_type
=
DataTypeUtil
::
instance
().
getDataType
(
data_type_name
);
addRecordField
(
data_type
);
}
void
OptionDefinition
::
addRecordField
(
const
DataType
data_type
)
{
if
(
type_
!=
RECORD_TYPE
)
{
isc_throw
(
isc
::
InvalidOperation
,
"'record' option type must be used"
" to add data fields to the record"
);
}
if
(
data_type
>=
UNKNOWN_TYPE
)
{
isc_throw
(
isc
::
BadValue
,
"attempted to add invalid data type to the record"
);
}
record_fields_
.
push_back
(
data_type
);
}
Option
::
Factory
*
OptionDefinition
::
getFactory
()
const
{
return
(
OptionDefinition
::
factoryEmpty
);
}
void
OptionDefinition
::
sanityCheckUniverse
(
const
Option
::
Universe
expected_universe
,
const
Option
::
Universe
actual_universe
)
{
if
(
expected_universe
!=
actual_universe
)
{
isc_throw
(
isc
::
BadValue
,
"invalid universe specified for the option"
);
}
}
void
OptionDefinition
::
validate
()
const
{
if
(
type_
>=
UNKNOWN_TYPE
)
{
isc_throw
(
isc
::
OutOfRange
,
"option type value "
<<
type_
<<
" is out of range"
);
}
}
OptionPtr
OptionDefinition
::
factoryAddrList4
(
Option
::
Universe
u
,
uint16_t
type
,
const
OptionBuffer
&
buf
)
{
sanityCheckUniverse
(
u
,
Option
::
V4
);
boost
::
shared_ptr
<
Option4AddrLst
>
option
(
new
Option4AddrLst
(
type
,
buf
.
begin
(),
buf
.
begin
()
+
buf
.
size
()));
return
(
option
);
}
OptionPtr
OptionDefinition
::
factoryAddrList6
(
Option
::
Universe
u
,
uint16_t
type
,
const
OptionBuffer
&
buf
)
{
sanityCheckUniverse
(
u
,
Option
::
V6
);
boost
::
shared_ptr
<
Option6AddrLst
>
option
(
new
Option6AddrLst
(
type
,
buf
.
begin
(),
buf
.
begin
()
+
buf
.
size
()));
return
(
option
);
}
OptionPtr
OptionDefinition
::
factoryEmpty
(
Option
::
Universe
u
,
uint16_t
type
,
const
OptionBuffer
&
buf
)
{
if
(
buf
.
size
()
>
0
)
{
isc_throw
(
isc
::
BadValue
,
"input option buffer must be empty"
" when creating empty option instance"
);
}
OptionPtr
option
(
new
Option
(
u
,
type
));
return
(
option
);
}
}
// end of isc::dhcp namespace
}
// end of isc namespace
src/lib/dhcp/option_definition.h
0 → 100644
View file @
3c35688d
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef OPTION_DEFINITION_H_
#define OPTION_DEFINITION_H_
#include
"dhcp/option6_int.h"
#include
"dhcp/option.h"
namespace
isc
{
namespace
dhcp
{
/// @brief Base class representing DHCP option definitions.
///
/// This is a base class representing DHCP options definitions.
/// The definition describes the format of the option. In particular
/// it defines:
/// - option name,
/// - option code,
/// - data fields order and their types,
/// - sub options space that the particular option encapsulates.
///
/// The option type specifies the data type(s) which option conveys.
/// If it is to convey single value the option type points to the
/// data type of this value. For example, DHCPv6 option 8 comprises
/// 2-byte option code, 2-byte option length and 2-byte field that
/// carries uint16 value (http://ietf.org/rfc/rfc3315.txt).
/// In such case option type is defined as "uint16". In case when
/// the particular option has more complex structure the option type
/// may be defined as "array", "record" or even "array of records".
/// Array types should be used when the option contains multiple
/// data fields of the same type laid successively. For example,
/// DHCPv6 option 6 includes multiple fields holding uint16 codes
/// of requested DHCPv6 options (http://ietf.org/rfc/rfc3315.txt).
/// Such option can be represented with this class by setting
/// option type to "uint16" and array indicator (array_type) to true.
/// The number of elements in the array is unlimited (actually it is
/// limited by the maximal DHCPv6 option length).
/// Should option comprise data fields of different types the "record"
/// option type is used. In such cases the data field types within the
/// record are specified using \ref OptionDefinition::AddRecordField.
/// When OptionDefinition object has been sucessfully created it
/// can be queried to return the appropriate option factory function
/// for the specified option format. There is a number of "standard"
/// factory functions that cover well known (common) formats.
/// If the particular format does not match any common format the generic
/// factory function is returned.
///
/// The following data type strings are supported:
/// - "empty" - option does not contain data fields
/// - "boolean"
/// - "int8"
/// - "int16"
/// - "int32"
/// - "uint8"
/// - "uint16"
/// - "uint32"
/// - "ipv4-address" - IPv4 Address
/// - "ipv6-address" - IPV6 Address
/// - "string"
/// - "fqdn" - fully qualified name
/// - "record" - set of data fields of different types
///
/// @todo Extend the comment to describe "generic factories".
/// @todo Extend this class to use custom namespaces.
class
OptionDefinition
{
public:
/// Data types of DHCP option fields.
enum
DataType
{
EMPTY_TYPE
=
0
,
BOOLEAN_TYPE
=
1
,
INT8_TYPE
=
2
,
INT16_TYPE
=
3
,
INT32_TYPE
=
4
,
UINT8_TYPE
=
5
,
UINT16_TYPE
=
6
,
UINT32_TYPE
=
7
,
IPV4_ADDRESS_TYPE
=
8
,
IPV6_ADDRESS_TYPE
=
9
,
STRING_TYPE
=
10
,
FQDN_TYPE
=
11
,
RECORD_TYPE
=
12
,
UNKNOWN_TYPE
=
RECORD_TYPE
+
1
};
/// List of fields within the record.
typedef
std
::
vector
<
DataType
>
RecordFieldsCollection
;
/// Iterator for record data fields.
typedef
std
::
vector
<
DataType
>::
iterator
RecordFieldsCollectionIter
;
private:
/// @brief Utility class for operations on DataTypes.
class
DataTypeUtil
{
public:
/// @brief Return sole instance of this class.
///
/// @return instance of this class.
static
DataTypeUtil
&
instance
()
{
static
DataTypeUtil
instance
;
return
(
instance
);
}
/// @brief Convert type given as string value to option data type.
///
/// @param data_type_name data type string.
///
/// @return option data type.
DataType
getDataType
(
const
std
::
string
&
data_type_name
);
private:
/// @brief Constructor.
///
/// Constructor initializes the internal data structures, e.g.
/// mapping between data type name and the corresponding enum.
DataTypeUtil
();
/// Map of data types, maps name of the type to enum value.
std
::
map
<
std
::
string
,
DataType
>
data_types_
;
};
public:
/// @brief Constructor.
///
/// @param name option name.
/// @param code option code.
/// @param type option data type as string.
/// @param array_type array indicator, if true it indicates that
/// option fields are the array.
OptionDefinition
(
const
std
::
string
&
name
,
const
uint16_t
code
,
const
std
::
string
&
type
,
const
bool
array_type
=
false
);
/// @brief Constructor.
///
/// @param name option name.
/// @param code option code.
/// @param type option data type.
/// @param array_type array indicator, if true it indicates that
/// option fields are the array.
OptionDefinition
(
const
std
::
string
&
name
,
const
uint16_t
code
,
const
DataType
type
,
const
bool
array_type
=
false
);
/// @brief Adds data field to the record.
///
/// @param data_type_name name of the data type for the field.
///
/// @throw isc::InvalidOperation if option type is not set to RECORD_TYPE.
/// @throw isc::BadValue if specified invalid data type.
void
addRecordField
(
const
std
::
string
&
data_type_name
);
/// @brief Adds data field to the record.
///
/// @param data_type data type for the field.
///
/// @throw isc::InvalidOperation if option type is not set to RECORD_TYPE.
/// @throw isc::BadValue if specified invalid data type.
void
addRecordField
(
const
DataType
data_type
);
/// @brief Return array type indicator.
///
/// The method returns the bool value to indicate wheter
/// option is single value or array of values.
///
/// @return true if option comprises an array of values.
bool
getArrayType
()
const
{
return
(
array_type_
);
}
/// @brief Return option code.
///
/// @return option code.
uint16_t
getCode
()
const
{
return
(
code_
);
}
/// @brief Return factory function for the given definition.
///
/// @return pointer to factory function.
Option
::
Factory
*
getFactory
()
const
;
/// @brief Return option name.
///
/// @return option name.
const
std
::
string
&
getName
()
const
{
return
(
name_
);
}
/// @brief Return list of record fields.
///
/// @return list of record fields.
const
RecordFieldsCollection
&
getRecordFields
()
const
{
return
(
record_fields_
);
}
/// @brief Return option data type.
///
/// @return option data type.
DataType
getType
()
const
{
return
(
type_
);
};
/// @brief Factory to create option with address list.
///
/// @param u universe (must be V4).
/// @param type option type.
/// @param buf option buffer with a list of IPv4 addresses.
static
OptionPtr
factoryAddrList4
(
Option
::
Universe
u
,
uint16_t
type
,
const
OptionBuffer
&
buf
);
/// @brief Factory to create option with address list.
///
/// @param u universe (must be V6).
/// @param type option type.
/// @param buf option buffer with a list of IPv6 addresses.
static
OptionPtr
factoryAddrList6
(
Option
::
Universe
u
,
uint16_t
type
,
const
OptionBuffer
&
buf
);
/// @brief Empty option factory.
///
/// @param u universe (V6 or V4).
/// @param type option type.
/// @param buf option buffer (must be empty).
static
OptionPtr
factoryEmpty
(
Option
::
Universe
u
,
uint16_t
type
,
const
OptionBuffer
&
buf
);
/// @brief Factory function to create option with integer value.
///
/// @param u universe (V6 or V4).
/// @param type option type.
/// @param buf option buffer (must be empty).
/// @param T type of the data field (must be one of the uintX_t or intX_t).
template
<
typename
T
>
static
OptionPtr
factoryInteger
(
Option
::
Universe
,
uint16_t
type
,
const
OptionBuffer
&
buf
)
{
if
(
buf
.
size
()
>
sizeof
(
T
))
{
isc_throw
(
isc
::
OutOfRange
,
"provided option buffer is too large, expected: "
<<
sizeof
(
T
)
<<
" bytes"
);
}
OptionPtr
option
(
new
OptionInt6
<
T
>
(
type
,
buf
.
begin
(),
buf
.
begin
()
+
buf
.
size
()));
return
(
option
);
}
private:
/// @brief Sanity check universe value.
///
/// @param expected_universe expected universe value.
/// @param actual_universe actual universe value.
///
/// @throw isc::BadValue if expected universe and actual universe don't match.
static
inline
void
sanityCheckUniverse
(
const
Option
::
Universe
expected_universe
,
const
Option
::
Universe
actual_universe
);
/// @brief Check if the option definition is valid.
///
/// @todo: list exceptions it throws.
void
validate
()
const
;
/// Option name.
std
::
string
name_
;
/// Option code.
uint16_t
code_
;
/// Option data type.
DataType
type_
;
/// Indicates wheter option is a single value or array.
bool
array_type_
;
/// Collection of data fields within the record.
RecordFieldsCollection
record_fields_
;
};
}
// namespace isc::dhcp
}
// namespace isc
#endif
src/lib/dhcp/tests/Makefile.am
View file @
3c35688d
...
...
@@ -33,6 +33,7 @@ libdhcp___unittests_SOURCES += option6_ia_unittest.cc
libdhcp___unittests_SOURCES
+=
option6_addrlst_unittest.cc
libdhcp___unittests_SOURCES
+=
option4_addrlst_unittest.cc
libdhcp___unittests_SOURCES
+=
option_unittest.cc
libdhcp___unittests_SOURCES
+=
option_definition_unittest.cc
libdhcp___unittests_SOURCES
+=
pkt6_unittest.cc
libdhcp___unittests_SOURCES
+=
pkt4_unittest.cc
...
...
src/lib/dhcp/tests/option_definition_unittest.cc
0 → 100644
View file @
3c35688d
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
<config.h>
#include
<iostream>
#include
<sstream>
#include
<gtest/gtest.h>
#include
<boost/shared_ptr.hpp>
#include
<boost/pointer_cast.hpp>
#include
<exceptions/exceptions.h>
#include
<asiolink/io_address.h>
#include
"dhcp/dhcp4.h"
#include
"dhcp/dhcp6.h"
#include
"dhcp/option4_addrlst.h"
#include
"dhcp/option6_addrlst.h"
#include
"dhcp/option6_int.h"
#include
"dhcp/option_definition.h"
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
util
;
namespace
{
class
OptionDefinitionTest
:
public
::
testing
::
Test
{