Commit b2d0a03b authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2304] Checking data types specified for Option6Int.

parent 3c35688d
......@@ -21,6 +21,7 @@ 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_data_types.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
......
......@@ -18,36 +18,68 @@
#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 single value.
/// This value is of integer type and 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 OptionInt6: public Option {
class Option6Int: public Option {
public:
OptionInt6(uint16_t type, T value)
/// @brief Constructor.
///
/// @param type option type.
/// @param value option value.
Option6Int(uint16_t type, T value)
: Option(Option::V6, type), value_(value) {
if (!OptionDataTypes<T>::valid) {
isc_throw(dhcp::InvalidDataType, "non-numeric type");
}
}
OptionInt6(uint16_t type, OptionBufferConstIter begin,
/// @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.
Option6Int(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 buf buffer (option will be stored here)
/// @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) {
if (!std::numeric_limits<T>::is_integer) {
isc_throw(isc::BadValue, "");
}
buf.writeUint16(type_);
buf.writeUint16(len() - OPTION6_HDR_LEN);
switch (sizeof(T)) {
switch (OptionDataTypes<T>::len) {
case 1:
buf.writeUint8(value_);
break;
......@@ -58,7 +90,7 @@ public:
buf.writeUint32(value_);
break;
default:
isc_throw(isc::BadValue, "");
isc_throw(dhcp::InvalidDataType, "non-numeric type");
}
}
......@@ -73,7 +105,7 @@ public:
if (distance(begin, end) < sizeof(T)) {
isc_throw(OutOfRange, "Option " << type_ << " truncated");
}
switch (sizeof(T)) {
switch (OptionDataTypes<T>::len) {
case 1:
value_ = *begin;
break;
......@@ -84,7 +116,7 @@ public:
value_ = isc::util::readUint32( &(*begin) );
break;
default:
isc_throw(isc::BadValue, "");
isc_throw(dhcp::InvalidDataType, "non-numeric type");
}
LibDHCP::unpackOptions6(OptionBuffer(begin, end), options_);
......
// 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_DATA_TYPES_H_
#define OPTION_DATA_TYPES_H_
#include <exceptions/exceptions.h>
namespace isc {
namespace dhcp {
/// @brief Exception to be thrown when invalid type specified as template parameter.
class InvalidDataType : public Exception {
public:
InvalidDataType(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief Numeric data types supported by DHCP option defintions.
template<typename T>
struct OptionDataTypes {
static const bool valid = false;
static const int len = 0;
};
template<>
struct OptionDataTypes<int8_t> {
static const bool valid = true;
static const int len = 1;
};
template<>
struct OptionDataTypes<int16_t> {
static const bool valid = true;
static const int len = 2;
};
template<>
struct OptionDataTypes<int32_t> {
static const bool valid = true;
static const int len = 4;
};
template<>
struct OptionDataTypes<uint8_t> {
static const bool valid = true;
static const int len = 1;
};
template<>
struct OptionDataTypes<uint16_t> {
static const bool valid = true;
static const int len = 2;
};
template<>
struct OptionDataTypes<uint32_t> {
static const bool valid = true;
static const int len = 4;
};
} // isc::dhcp namespace
} // isc namespace
#endif /* OPTION_DATA_TYPES_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment