]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3211] Incoming IAPREFIX is now parsed properly.
authorTomek Mrugalski <tomasz@isc.org>
Fri, 25 Oct 2013 12:53:56 +0000 (14:53 +0200)
committerTomek Mrugalski <tomasz@isc.org>
Fri, 25 Oct 2013 12:53:56 +0000 (14:53 +0200)
ChangeLog
src/lib/dhcp/option_definition.cc
src/lib/dhcp/option_definition.h
src/lib/dhcp/std_option_defs.h
src/lib/dhcp/tests/libdhcp++_unittest.cc

index e5e0e5f8e1398cb73bf7dbe8872bb02ddfd5d78d..0eb01b36b803452959046f2093ae6bd330b46175 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+7XX.   [bug]           tomek
+       libdhcp++: Incoming IAPREFIX option is now parsed properly.
+       (Trac #3211, git ABCD)
+
 700.   [func]          tomek,marcin
        b10-dhcp4,b10-dhcp6: Support for vendor options has been added. It
        is now possible to configure vendor options. Server is able to
index 952c758e3aeb2eae4c6eebd5b5e6d97299d918a8..be1a5e7890955f5997fbc9ac4de248b6c4d36f12 100644 (file)
@@ -19,6 +19,7 @@
 #include <dhcp/option6_addrlst.h>
 #include <dhcp/option6_ia.h>
 #include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
 #include <dhcp/option6_client_fqdn.h>
 #include <dhcp/option_custom.h>
 #include <dhcp/option_definition.h>
@@ -360,6 +361,16 @@ OptionDefinition::haveIAAddr6Format() const {
     return (haveIAx6Format(OPT_IPV6_ADDRESS_TYPE));
 }
 
+bool
+OptionDefinition::haveIAPrefix6Format() const {
+    return (haveType(OPT_RECORD_TYPE) &&
+            record_fields_.size() == 4 &&
+            record_fields_[0] == OPT_UINT32_TYPE &&
+            record_fields_[1] == OPT_UINT32_TYPE &&
+            record_fields_[2] == OPT_UINT8_TYPE &&
+            record_fields_[3] == OPT_IPV6_ADDRESS_TYPE);
+}
+
 bool
 OptionDefinition::haveFqdn4Format() const {
     return (haveType(OPT_RECORD_TYPE) &&
@@ -570,6 +581,20 @@ OptionDefinition::factoryIAAddr6(uint16_t type,
     return (option);
 }
 
+OptionPtr
+OptionDefinition::factoryIAPrefix6(uint16_t type,
+                                 OptionBufferConstIter begin,
+                                 OptionBufferConstIter end) {
+    if (std::distance(begin, end) < Option6IAPrefix::OPTION6_IAPREFIX_LEN) {
+        isc_throw(isc::OutOfRange,
+                  "input option buffer has invalid size, expected at least "
+                  << Option6IAPrefix::OPTION6_IAPREFIX_LEN << " bytes");
+    }
+    boost::shared_ptr<Option6IAPrefix> option(new Option6IAPrefix(type, begin,
+                                                                  end));
+    return (option);
+}
+
 OptionPtr
 OptionDefinition::factorySpecialFormatOption(Option::Universe u,
                                              OptionBufferConstIter begin,
@@ -593,15 +618,15 @@ OptionDefinition::factorySpecialFormatOption(Option::Universe u,
             // option only for the same reasons as described in
             // for IA_NA and IA_PD above.
             return (factoryIAAddr6(getCode(), begin, end));
+        } else if (getCode() == D6O_IAPREFIX && haveIAPrefix6Format()) {
+            return (factoryIAPrefix6(getCode(), begin, end));
         } else if (getCode() == D6O_CLIENT_FQDN && haveClientFqdnFormat()) {
             // FQDN option requires special processing. Thus, there is
             // a specialized class to handle it.
             return (OptionPtr(new Option6ClientFqdn(begin, end)));
-
         } else if (getCode() == D6O_VENDOR_OPTS && haveVendor6Format()) {
             // Vendor-Specific Information.
             return (OptionPtr(new OptionVendor(Option::V6, begin, end)));
-
         }
     } else {
         if ((getCode() == DHO_FQDN) && haveFqdn4Format()) {
index 7db32fa43a75bd85c1347772e8cb003a6c53a594..8f2d3671ce45df8a9ee362bf3dcb37acba3d4b12 100644 (file)
@@ -276,6 +276,11 @@ public:
     /// @return true if specified format is IAADDR option format.
     bool haveIAAddr6Format() const;
 
+    /// @brief Check if specified format is IAPREFIX option format.
+    ///
+    /// @return true if specified format is IAPREFIX option format.
+    bool haveIAPrefix6Format() const;
+
     /// @brief Check if specified format is OPTION_CLIENT_FQDN option format.
     ///
     /// @return true of specified format is OPTION_CLIENT_FQDN option format,
@@ -466,6 +471,19 @@ public:
                                     OptionBufferConstIter begin,
                                     OptionBufferConstIter end);
 
+    /// @brief Factory for IAPREFIX-type of option.
+    ///
+    /// @param type option type.
+    /// @param begin iterator pointing to the beginning of the buffer.
+    /// @param end iterator pointing to the end of the buffer.
+    ///
+    /// @throw isc::OutOfRange if provided option buffer is too short or
+    /// too long. Expected size is 25 bytes.
+    /// @throw isc::BadValue if specified universe value is not V6.
+    static OptionPtr factoryIAPrefix6(uint16_t type,
+                                      OptionBufferConstIter begin,
+                                      OptionBufferConstIter end);
+
     /// @brief Factory function to create option with integer value.
     ///
     /// @param u universe (V4 or V6).
index c330ff677c11fb8b12471dccbcde104db06da115..9f6455338fc8a55ab6a025745fac44d8746405d0 100644 (file)
@@ -220,7 +220,7 @@ RECORD_DECL(IA_NA_RECORDS, OPT_UINT32_TYPE, OPT_UINT32_TYPE, OPT_UINT32_TYPE);
 RECORD_DECL(IA_PD_RECORDS, OPT_UINT32_TYPE, OPT_UINT32_TYPE, OPT_UINT32_TYPE);
 // ia-prefix
 RECORD_DECL(IA_PREFIX_RECORDS, OPT_UINT32_TYPE, OPT_UINT32_TYPE,
-            OPT_UINT8_TYPE, OPT_IPV6_ADDRESS_TYPE, OPT_BINARY_TYPE);
+            OPT_UINT8_TYPE, OPT_IPV6_ADDRESS_TYPE);
 // lq-query
 RECORD_DECL(LQ_QUERY_RECORDS, OPT_UINT8_TYPE, OPT_IPV6_ADDRESS_TYPE);
 // lq-relay-data
index 9b1cadf9b01b5a2eef9664b0e1979a9bc971e548..92f7baf92059e20a69f930954c71a9e5c3d8da2f 100644 (file)
@@ -23,6 +23,7 @@
 #include <dhcp/option6_client_fqdn.h>
 #include <dhcp/option6_ia.h>
 #include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
 #include <dhcp/option_custom.h>
 #include <dhcp/option_int.h>
 #include <dhcp/option_int_array.h>
@@ -1043,8 +1044,8 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
     LibDhcpTest::testStdOptionDefs6(D6O_IA_PD, begin, end,
                                     typeid(Option6IA));
 
-    LibDhcpTest::testStdOptionDefs6(D6O_IAPREFIX, begin, end,
-                                    typeid(OptionCustom));
+    LibDhcpTest::testStdOptionDefs6(D6O_IAPREFIX, begin, begin + 25,
+                                    typeid(Option6IAPrefix));
 
     LibDhcpTest::testStdOptionDefs6(D6O_NIS_SERVERS, begin, end,
                                     typeid(Option6AddrLst));