#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;
buf.writeUint32(value_);
break;
default:
- isc_throw(isc::BadValue, "");
+ isc_throw(dhcp::InvalidDataType, "non-numeric type");
}
}
if (distance(begin, end) < sizeof(T)) {
isc_throw(OutOfRange, "Option " << type_ << " truncated");
}
- switch (sizeof(T)) {
+ switch (OptionDataTypes<T>::len) {
case 1:
value_ = *begin;
break;
value_ = isc::util::readUint32( &(*begin) );
break;
default:
- isc_throw(isc::BadValue, "");
+ isc_throw(dhcp::InvalidDataType, "non-numeric type");
}
LibDHCP::unpackOptions6(OptionBuffer(begin, end), options_);
--- /dev/null
+// 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_ */