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
f3da5ed9
Commit
f3da5ed9
authored
Nov 26, 2012
by
Marcin Siodelski
Browse files
[2312] Added functions to read data of different types from buffer.
parent
f957fa65
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/option_data_types.cc
View file @
f3da5ed9
...
...
@@ -18,6 +18,52 @@
namespace
isc
{
namespace
dhcp
{
void
OptionDataTypeUtil
::
readAddress
(
const
std
::
vector
<
uint8_t
>&
buf
,
const
short
family
,
asiolink
::
IOAddress
&
address
)
{
using
namespace
isc
::
asiolink
;
if
(
family
==
AF_INET
)
{
if
(
buf
.
size
()
<
V4ADDRESS_LEN
)
{
isc_throw
(
BadDataTypeCast
,
"unavle to read data from the buffer as"
<<
" IPv4 address. Invalid buffer size: "
<<
buf
.
size
());
}
address
=
IOAddress
::
from_bytes
(
AF_INET
,
&
buf
[
0
]);
}
else
if
(
buf
.
size
()
==
V6ADDRESS_LEN
)
{
if
(
buf
.
size
()
<
V6ADDRESS_LEN
)
{
isc_throw
(
BadDataTypeCast
,
"unavle to read data from the buffer as"
<<
" IPv6 address. Invalid buffer size: "
<<
buf
.
size
());
}
address
=
IOAddress
::
from_bytes
(
AF_INET6
,
&
buf
[
0
]);
}
else
{
isc_throw
(
BadDataTypeCast
,
"unable to read data from the buffer as"
"IP address. Invalid family: "
<<
family
);
}
}
void
OptionDataTypeUtil
::
writeAddress
(
const
asiolink
::
IOAddress
&
address
,
std
::
vector
<
uint8_t
>&
buf
)
{
if
(
address
.
getAddress
().
is_v4
())
{
asio
::
ip
::
address_v4
::
bytes_type
addr_bytes
=
address
.
getAddress
().
to_v4
().
to_bytes
();
// Increase the buffer size by the size of IPv4 address.
buf
.
resize
(
buf
.
size
()
+
addr_bytes
.
size
());
std
::
copy_backward
(
addr_bytes
.
begin
(),
addr_bytes
.
end
(),
buf
.
end
());
}
else
if
(
address
.
getAddress
().
is_v6
())
{
asio
::
ip
::
address_v6
::
bytes_type
addr_bytes
=
address
.
getAddress
().
to_v6
().
to_bytes
();
// Incresase the buffer size by the size of IPv6 address.
buf
.
resize
(
buf
.
size
()
+
addr_bytes
.
size
());
std
::
copy_backward
(
addr_bytes
.
begin
(),
addr_bytes
.
end
(),
buf
.
end
());
}
else
{
isc_throw
(
BadDataTypeCast
,
"the address "
<<
address
.
toText
()
<<
" is neither valid IPv4 not IPv6 address."
);
}
}
void
OptionDataTypeUtil
::
writeBinary
(
const
std
::
string
&
hex_str
,
std
::
vector
<
uint8_t
>&
buf
)
{
...
...
@@ -36,6 +82,21 @@ OptionDataTypeUtil::writeBinary(const std::string& hex_str,
buf
.
insert
(
buf
.
end
(),
binary
.
begin
(),
binary
.
end
());
}
bool
OptionDataTypeUtil
::
readBool
(
const
std
::
vector
<
uint8_t
>&
buf
)
{
if
(
buf
.
size
()
<
1
)
{
isc_throw
(
BadDataTypeCast
,
"unable to read the buffer as boolean"
<<
" value. Invalid buffer size "
<<
buf
.
size
());
}
if
(
buf
[
0
]
==
1
)
{
return
(
true
);
}
else
if
(
buf
[
0
]
==
0
)
{
return
(
false
);
}
isc_throw
(
BadDataTypeCast
,
"unable to read the buffer as boolean"
<<
" value. Inavlid value "
<<
static_cast
<
int
>
(
buf
[
0
]));
}
void
OptionDataTypeUtil
::
writeBool
(
const
bool
value
,
std
::
vector
<
uint8_t
>&
buf
)
{
...
...
@@ -47,26 +108,9 @@ OptionDataTypeUtil::writeBool(const bool value,
}
void
OptionDataTypeUtil
::
writeAddress
(
const
asiolink
::
IOAddress
&
address
,
std
::
vector
<
uint8_t
>&
buf
)
{
if
(
address
.
getAddress
().
is_v4
())
{
asio
::
ip
::
address_v4
::
bytes_type
addr_bytes
=
address
.
getAddress
().
to_v4
().
to_bytes
();
// Increase the buffer size by the size of IPv4 address.
buf
.
resize
(
buf
.
size
()
+
addr_bytes
.
size
());
std
::
copy_backward
(
addr_bytes
.
begin
(),
addr_bytes
.
end
(),
buf
.
end
());
}
else
if
(
address
.
getAddress
().
is_v6
())
{
asio
::
ip
::
address_v6
::
bytes_type
addr_bytes
=
address
.
getAddress
().
to_v6
().
to_bytes
();
// Incresase the buffer size by the size of IPv6 address.
buf
.
resize
(
buf
.
size
()
+
addr_bytes
.
size
());
std
::
copy_backward
(
addr_bytes
.
begin
(),
addr_bytes
.
end
(),
buf
.
end
());
}
else
{
isc_throw
(
BadDataTypeCast
,
"the address "
<<
address
.
toText
()
<<
" is neither valid IPv4 not IPv6 address."
);
}
OptionDataTypeUtil
::
readString
(
const
std
::
vector
<
uint8_t
>&
buf
,
std
::
string
&
value
)
{
value
.
insert
(
value
.
end
(),
buf
.
begin
(),
buf
.
end
());
}
void
...
...
src/lib/dhcp/option_data_types.h
View file @
f3da5ed9
...
...
@@ -177,6 +177,16 @@ struct OptionDataTypeTraits<std::string> {
/// @brief Utility class to write/read data to/from a buffer.
class
OptionDataTypeUtil
{
public:
/// @brief Read IPv4 or IPv6 addres from a buffer.
///
/// @param buf input buffer.
/// @param family address family: AF_INET or AF_INET6.
/// @param [out] address being read.
static
void
readAddress
(
const
std
::
vector
<
uint8_t
>&
buf
,
const
short
family
,
asiolink
::
IOAddress
&
address
);
/// @brief Write IPv4 or IPv6 address into a buffer.
///
/// @param address IPv4 or IPv6 address.
...
...
@@ -190,7 +200,13 @@ public:
/// with hexadecimal digits (without 0x prefix).
/// @param [out] output buffer.
static
void
writeBinary
(
const
std
::
string
&
hex_str
,
std
::
vector
<
uint8_t
>&
buf
);
std
::
vector
<
uint8_t
>&
buf
);
/// @brief Read boolean value from a buffer.
///
/// @param buf input buffer.
/// @return boolean value read from a buffer.
static
bool
readBool
(
const
std
::
vector
<
uint8_t
>&
buf
);
/// @brief Write boolean value into a buffer.
///
...
...
@@ -201,6 +217,39 @@ public:
/// @param [out] buf output buffer.
static
void
writeBool
(
const
bool
value
,
std
::
vector
<
uint8_t
>&
buf
);
/// @brief Read integer value from a buffer.
///
/// @param buf input buffer.
/// @tparam integer type of the returned value.
/// @return integer value being read.
template
<
typename
T
>
T
readInt
(
const
std
::
vector
<
uint8_t
>&
buf
)
{
if
(
!
OptionDataTypeTraits
<
T
>::
integer_type
)
{
isc_throw
(
isc
::
dhcp
::
InvalidDataType
,
"specified data type to be returned"
" by readInteger is not supported integer type"
);
}
assert
(
buf
.
size
()
==
OptionDataTypeTraits
<
T
>::
len
);
T
value
;
switch
(
OptionDataTypeTraits
<
T
>::
len
)
{
case
1
:
value
=
*
(
buf
.
begin
());
break
;
case
2
:
value
=
isc
::
util
::
readUint16
(
&
(
*
buf
.
begin
()));
break
;
case
4
:
value
=
isc
::
util
::
readUint32
(
&
(
*
buf
.
begin
()));
break
;
default:
// This should not happen because we made checks on data types
// but it does not hurt to keep throw statement here.
isc_throw
(
isc
::
dhcp
::
InvalidDataType
,
"invalid size of the data type to be read as integer."
);
}
return
(
value
);
}
/// @brief Write integer or unsiged integer value into a buffer.
///
/// @param value an integer value to be written into a buffer.
...
...
@@ -232,6 +281,13 @@ public:
}
}
/// @brief Read string value from a buffer.
///
/// @param buf input buffer.
/// @param [out] value string value being read.
void
readString
(
const
std
::
vector
<
uint8_t
>&
buf
,
std
::
string
&
value
);
/// @brief Write utf8-encoded string into a buffer.
///
/// @param value string value to be written into a buffer.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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