From: Tomek Mrugalski Date: Fri, 25 Oct 2013 12:53:56 +0000 (+0200) Subject: [3211] Incoming IAPREFIX is now parsed properly. X-Git-Tag: bind10-1.2.0beta1-release~102^2~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fab2fd65c02fe2e215a004b094916c449f6d994c;p=thirdparty%2Fkea.git [3211] Incoming IAPREFIX is now parsed properly. --- diff --git a/ChangeLog b/ChangeLog index e5e0e5f8e1..0eb01b36b8 100644 --- 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 diff --git a/src/lib/dhcp/option_definition.cc b/src/lib/dhcp/option_definition.cc index 952c758e3a..be1a5e7890 100644 --- a/src/lib/dhcp/option_definition.cc +++ b/src/lib/dhcp/option_definition.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -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 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()) { diff --git a/src/lib/dhcp/option_definition.h b/src/lib/dhcp/option_definition.h index 7db32fa43a..8f2d3671ce 100644 --- a/src/lib/dhcp/option_definition.h +++ b/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). diff --git a/src/lib/dhcp/std_option_defs.h b/src/lib/dhcp/std_option_defs.h index c330ff677c..9f6455338f 100644 --- a/src/lib/dhcp/std_option_defs.h +++ b/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 diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc index 9b1cadf9b0..92f7baf920 100644 --- a/src/lib/dhcp/tests/libdhcp++_unittest.cc +++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -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));