Browse Source

[3211] Incoming IAPREFIX is now parsed properly.

Tomek Mrugalski 11 years ago
parent
commit
fab2fd65c0

+ 4 - 0
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

+ 27 - 2
src/lib/dhcp/option_definition.cc

@@ -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>
@@ -361,6 +362,16 @@ OptionDefinition::haveIAAddr6Format() const {
 }
 
 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) &&
             record_fields_.size() == 4 &&
@@ -571,6 +582,20 @@ OptionDefinition::factoryIAAddr6(uint16_t type,
 }
 
 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,
                                              OptionBufferConstIter end,
@@ -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()) {

+ 18 - 0
src/lib/dhcp/option_definition.h

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

+ 1 - 1
src/lib/dhcp/std_option_defs.h

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

+ 3 - 2
src/lib/dhcp/tests/libdhcp++_unittest.cc

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