Parcourir la source

[2304] Checking data types specified for Option6Int.

Marcin Siodelski il y a 12 ans
Parent
commit
b2d0a03b1e
3 fichiers modifiés avec 121 ajouts et 11 suppressions
  1. 1 0
      src/lib/dhcp/Makefile.am
  2. 43 11
      src/lib/dhcp/option6_int.h
  3. 77 0
      src/lib/dhcp/option_data_types.h

+ 1 - 0
src/lib/dhcp/Makefile.am

@@ -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

+ 43 - 11
src/lib/dhcp/option6_int.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_);

+ 77 - 0
src/lib/dhcp/option_data_types.h

@@ -0,0 +1,77 @@
+// 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_ */