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
31c8d5e0
Commit
31c8d5e0
authored
Oct 05, 2012
by
Marcin Siodelski
Browse files
[2304] Added Option6IntArray option type and unit tests.
parent
273e195e
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/Makefile.am
View file @
31c8d5e0
...
...
@@ -28,6 +28,7 @@ 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
+=
option6_int_array.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/option6_int.h
View file @
31c8d5e0
...
...
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef OPTION_INT
6
_H_
#define OPTION_INT
6
_H_
#ifndef OPTION
6
_INT_H_
#define OPTION
6
_INT_H_
#include
<stdint.h>
#include
<limits>
...
...
@@ -144,10 +144,10 @@ public:
private:
T
value_
;
T
value_
;
///< Value cabveyed by the option.
};
}
// isc::dhcp namespace
}
// isc namespace
#endif
/* OPTION_I
A
_H_ */
#endif
/* OPTION
6
_I
NT
_H_ */
src/lib/dhcp/option6_int_array.h
0 → 100644
View file @
31c8d5e0
// 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 OPTION6_INT_ARRAY_H_
#define OPTION6_INT_ARRAY_H_
#include
<stdint.h>
#include
<limits>
#include
<util/io_utilities.h>
#include
"dhcp/libdhcp++.h"
#include
"dhcp/option.h"
#include
"dhcp/option_data_types.h"
namespace
isc
{
namespace
dhcp
{
/// This template class represents DHCPv6 option with array of
/// integer values. The type of the elements in the array can be
/// any of the following:
/// - uint8_t,
/// - uint16_t,
/// - uint32_t,
/// - int8_t,
/// - int16_t,
/// - int32_t.
///
/// @param T data field type (see above).
template
<
typename
T
>
class
Option6IntArray
:
public
Option
{
public:
typedef
std
::
vector
<
T
>
ValuesCollection
;
/// @brief Constructor.
///
/// @param type option type.
/// @param value option value.
Option6IntArray
(
uint16_t
type
,
const
ValuesCollection
&
values
)
:
Option
(
Option
::
V6
,
type
),
values_
(
values
)
{
if
(
!
OptionDataTypes
<
T
>::
valid
)
{
isc_throw
(
dhcp
::
InvalidDataType
,
"non-numeric type"
);
}
}
/// @brief Constructor.
///
/// This constructor creates option from a buffer. This construtor
/// may throw exception if \ref unpack function throws during buffer
/// parsing.
///
/// @param type option type.
/// @param begin iterator to first byte of option data.
/// @param end iterator to end of option data (first byte after option end).
///
/// @todo mention here what it throws.
Option6IntArray
(
uint16_t
type
,
OptionBufferConstIter
begin
,
OptionBufferConstIter
end
)
:
Option
(
Option
::
V6
,
type
)
{
if
(
!
OptionDataTypes
<
T
>::
valid
)
{
isc_throw
(
dhcp
::
InvalidDataType
,
"non-numeric type"
);
}
unpack
(
begin
,
end
);
}
/// Writes option in wire-format to buf, returns pointer to first unused
/// byte after stored option.
///
/// @param [out] buf buffer (option will be stored here)
///
/// @throw isc::BadValue if invalid option type has been provided.
void
pack
(
isc
::
util
::
OutputBuffer
&
buf
)
{
buf
.
writeUint16
(
type_
);
buf
.
writeUint16
(
len
()
-
OPTION6_HDR_LEN
);
for
(
int
i
=
0
;
i
<
values_
.
size
();
++
i
)
{
switch
(
OptionDataTypes
<
T
>::
len
)
{
case
1
:
buf
.
writeUint8
(
values_
[
i
]);
break
;
case
2
:
buf
.
writeUint16
(
values_
[
i
]);
break
;
case
4
:
buf
.
writeUint32
(
values_
[
i
]);
break
;
default:
isc_throw
(
dhcp
::
InvalidDataType
,
"non-numeric type"
);
}
}
}
/// @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
)
!=
0
)
{
isc_throw
(
OutOfRange
,
"Option "
<<
type_
<<
" truncated"
);
}
values_
.
clear
();
while
(
begin
!=
end
)
{
switch
(
OptionDataTypes
<
T
>::
len
)
{
case
1
:
values_
.
push_back
(
*
begin
);
break
;
case
2
:
values_
.
push_back
(
isc
::
util
::
readUint16
(
&
(
*
begin
)));
break
;
case
4
:
values_
.
push_back
(
isc
::
util
::
readUint32
(
&
(
*
begin
)));
break
;
default:
isc_throw
(
dhcp
::
InvalidDataType
,
"non-numeric type"
);
}
begin
+=
sizeof
(
T
);
}
LibDHCP
::
unpackOptions6
(
OptionBuffer
(
begin
,
end
),
options_
);
}
/// @brief Returns collection of values.
///
/// @return collection of values.
const
ValuesCollection
&
getValues
()
const
{
return
values_
;
}
/// @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
+
values_
.
size
()
*
sizeof
(
T
);
// length of all suboptions
for
(
Option
::
OptionCollection
::
iterator
it
=
options_
.
begin
();
it
!=
options_
.
end
();
++
it
)
{
length
+=
(
*
it
).
second
->
len
();
}
return
(
length
);
}
private:
ValuesCollection
values_
;
};
}
// isc::dhcp namespace
}
// isc namespace
#endif
/* OPTION6_INT_ARRAY_H_ */
src/lib/dhcp/option_data_types.h
View file @
31c8d5e0
...
...
@@ -15,6 +15,7 @@
#ifndef OPTION_DATA_TYPES_H_
#define OPTION_DATA_TYPES_H_
#include
<stdint.h>
#include
<exceptions/exceptions.h>
namespace
isc
{
...
...
src/lib/dhcp/option_definition.cc
View file @
31c8d5e0
...
...
@@ -18,6 +18,7 @@
#include
"dhcp/option6_ia.h"
#include
"dhcp/option6_iaaddr.h"
#include
"dhcp/option6_int.h"
#include
"dhcp/option6_int_array.h"
using
namespace
std
;
using
namespace
isc
::
util
;
...
...
src/lib/dhcp/option_definition.h
View file @
31c8d5e0
...
...
@@ -15,7 +15,9 @@
#ifndef OPTION_DEFINITION_H_
#define OPTION_DEFINITION_H_
#include
"dhcp/option_data_types.h"
#include
"dhcp/option6_int.h"
#include
"dhcp/option6_int_array.h"
#include
"dhcp/option.h"
namespace
isc
{
...
...
@@ -258,7 +260,7 @@ public:
///
/// @param u universe (V6 or V4).
/// @param type option type.
/// @param buf option buffer
(must be empty)
.
/// @param buf option buffer.
/// @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
)
{
...
...
@@ -266,7 +268,25 @@ public:
isc_throw
(
isc
::
OutOfRange
,
"provided option buffer is too large, expected: "
<<
sizeof
(
T
)
<<
" bytes"
);
}
OptionPtr
option
(
new
Option6Int
<
T
>
(
type
,
buf
.
begin
(),
buf
.
begin
()
+
buf
.
size
()));
OptionPtr
option
(
new
Option6Int
<
T
>
(
type
,
buf
.
begin
(),
buf
.
end
()));
return
(
option
);
}
/// @brief Factory function to create option with array of integer values.
///
/// @param u universe (V6 or V4).
/// @param type option type.
/// @param buf option buffer.
/// @param T type of the data field (must be one of the uintX_t or intX_t).
template
<
typename
T
>
static
OptionPtr
factoryIntegerArray
(
Option
::
Universe
,
uint16_t
type
,
const
OptionBuffer
&
buf
)
{
if
(
buf
.
size
()
==
0
)
{
isc_throw
(
isc
::
OutOfRange
,
"option buffer length must be greater than zero"
);
}
else
if
(
buf
.
size
()
%
OptionDataTypes
<
T
>::
len
!=
0
)
{
isc_throw
(
isc
::
OutOfRange
,
"option buffer length must be multiple of "
<<
OptionDataTypes
<
T
>::
len
<<
" bytes"
);
}
OptionPtr
option
(
new
Option6IntArray
<
T
>
(
type
,
buf
.
begin
(),
buf
.
end
()));
return
(
option
);
}
...
...
src/lib/dhcp/tests/option_definition_unittest.cc
View file @
31c8d5e0
...
...
@@ -29,6 +29,7 @@
#include
"dhcp/option6_ia.h"
#include
"dhcp/option6_iaaddr.h"
#include
"dhcp/option6_int.h"
#include
"dhcp/option6_int_array.h"
#include
"dhcp/option_definition.h"
using
namespace
std
;
...
...
@@ -319,7 +320,7 @@ TEST_F(OptionDefinitionTest, factoryIAAddr6) {
EXPECT_EQ
(
0x04050607
,
option_cast_v6
->
getValid
());
}
TEST_F
(
OptionDefinitionTest
,
factoryInteger
Negativ
e
)
{
TEST_F
(
OptionDefinitionTest
,
factoryInteger
InvalidTyp
e
)
{
EXPECT_THROW
(
OptionDefinition
::
factoryInteger
<
bool
>
(
Option
::
V6
,
D6O_PREFERENCE
,
OptionBuffer
(
1
)),
isc
::
dhcp
::
InvalidDataType
...
...
@@ -408,4 +409,84 @@ TEST_F(OptionDefinitionTest, factoryInteger32) {
// @todo Add more cases for DHCPv4
}
TEST_F
(
OptionDefinitionTest
,
factoryInteger16Array
)
{
Option
::
Factory
*
f
=
OptionDefinition
::
factoryIntegerArray
<
uint16_t
>
;
OptionPtr
option_v6
;
// Provided buffer size must be greater than zero. Check if we
// get exception if we provide zero-length buffer.
EXPECT_THROW
(
option_v6
=
f
(
Option
::
V6
,
79
,
OptionBuffer
()),
isc
::
OutOfRange
);
// Buffer length must be multiple of data type size.
EXPECT_THROW
(
option_v6
=
f
(
Option
::
V6
,
79
,
OptionBuffer
(
5
)),
isc
::
OutOfRange
);
// Positive scenario, initiate the buffer with length being
// multiple of uint16_t size.
// buffer elements will be: 0x112233.
OptionBuffer
buf
(
6
);
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
buf
[
i
]
=
i
/
2
;
}
// Constructor should succeed because buffer has correct size.
EXPECT_NO_THROW
(
option_v6
=
f
(
Option
::
V6
,
79
,
buf
);
);
boost
::
shared_ptr
<
Option6IntArray
<
uint16_t
>
>
option_cast_v6
=
boost
::
static_pointer_cast
<
Option6IntArray
<
uint16_t
>
>
(
option_v6
);
// Get the values from the initiated options and validate.
Option6IntArray
<
uint16_t
>::
ValuesCollection
values
=
option_cast_v6
->
getValues
();
for
(
int
i
=
0
;
i
<
values
.
size
();
++
i
)
{
// Expected value is calculated using on the same pattern
// as the one we used to initiate buffer:
// for i=0, expected = 0x00, for i = 1, expected == 0x11 etc.
uint16_t
expected
=
(
i
<<
8
)
|
i
;
EXPECT_EQ
(
expected
,
values
[
i
]);
}
}
TEST_F
(
OptionDefinitionTest
,
factoryInteger32Array
)
{
Option
::
Factory
*
f
=
OptionDefinition
::
factoryIntegerArray
<
uint32_t
>
;
const
uint16_t
opt_code
=
80
;
OptionPtr
option_v6
;
// Provided buffer size must be greater than zero. Check if we
// get exception if we provide zero-length buffer.
EXPECT_THROW
(
option_v6
=
f
(
Option
::
V6
,
opt_code
,
OptionBuffer
()),
isc
::
OutOfRange
);
// Buffer length must be multiple of data type size.
EXPECT_THROW
(
option_v6
=
f
(
Option
::
V6
,
opt_code
,
OptionBuffer
(
5
)),
isc
::
OutOfRange
);
// Positive scenario, initiate the buffer with length being
// multiple of uint16_t size.
// buffer elements will be: 0x111122223333.
OptionBuffer
buf
(
12
);
for
(
int
i
=
0
;
i
<
buf
.
size
();
++
i
)
{
buf
[
i
]
=
i
/
4
;
}
// Constructor should succeed because buffer has correct size.
EXPECT_NO_THROW
(
option_v6
=
f
(
Option
::
V6
,
opt_code
,
buf
);
);
boost
::
shared_ptr
<
Option6IntArray
<
uint32_t
>
>
option_cast_v6
=
boost
::
static_pointer_cast
<
Option6IntArray
<
uint32_t
>
>
(
option_v6
);
// Get the values from the initiated options and validate.
Option6IntArray
<
uint32_t
>::
ValuesCollection
values
=
option_cast_v6
->
getValues
();
for
(
int
i
=
0
;
i
<
values
.
size
();
++
i
)
{
// Expected value is calculated using on the same pattern
// as the one we used to initiate buffer:
// for i=0, expected = 0x0000, for i = 1, expected == 0x1111 etc.
uint32_t
expected
=
0x01010101
*
i
;
EXPECT_EQ
(
expected
,
values
[
i
]);
}
}
}
// anonymous namespace
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