diff --git a/include/dhcpv6.h b/include/dhcpv6.h index e45ddd2..b9ac2e3 100644 --- a/include/dhcpv6.h +++ b/include/dhcpv6.h @@ -276,7 +276,19 @@ public: /** * The type used to store the User Class option. */ - typedef std::vector user_class_type; + //typedef std::vector user_class_type; + struct user_class_type { + typedef std::vector data_type; + data_type data; + + user_class_type(const data_type &data = data_type()) + : data(data) + { + + } + + static user_class_type from_option(const option &opt); + }; /** * The type used to store the Vendor Class option. @@ -861,46 +873,6 @@ private: throw option_not_found(); return option->to(); } - - template - void class_option_data2option(InputIterator start, InputIterator end, - std::vector& buffer, size_t start_index = 0) - { - size_t index = start_index; - while(start != end) { - buffer.resize(buffer.size() + sizeof(uint16_t) + start->size()); - *(uint16_t*)&buffer[index] = Endian::host_to_be(start->size()); - index += sizeof(uint16_t); - std::copy(start->begin(), start->end(), buffer.begin() + index); - index += start->size(); - - start++; - } - } - - template - OutputType option2class_option_data(const uint8_t *ptr, uint32_t total_sz) const - { - typedef typename OutputType::value_type value_type; - OutputType output; - size_t index = 0; - while(index + 2 < total_sz) { - uint16_t size = Endian::be_to_host( - *(const uint16_t*)(ptr + index) - ); - index += sizeof(uint16_t); - if(index + size > total_sz) - throw option_not_found(); - output.push_back( - value_type(ptr + index, ptr + index + size) - ); - index += size; - } - if(index != total_sz) - throw option_not_found(); - return output; - } - uint8_t header_data[4]; uint32_t options_size; diff --git a/src/dhcpv6.cpp b/src/dhcpv6.cpp index 6c2f4f9..2918209 100644 --- a/src/dhcpv6.cpp +++ b/src/dhcpv6.cpp @@ -201,12 +201,7 @@ bool DHCPv6::has_rapid_commit() const { } DHCPv6::user_class_type DHCPv6::user_class() const { - const option *opt = safe_search_option( - USER_CLASS, sizeof(uint16_t) - ); - return option2class_option_data( - opt->data_ptr(), opt->data_size() - ); + return search_and_convert(USER_CLASS); } DHCPv6::vendor_class_type DHCPv6::vendor_class() const { @@ -364,10 +359,10 @@ void DHCPv6::rapid_commit() { } void DHCPv6::user_class(const user_class_type &value) { - typedef user_class_type::const_iterator iterator; + typedef user_class_type::data_type::const_iterator iterator; std::vector buffer; - class_option_data2option(value.begin(), value.end(), buffer); + Internals::class_option_data2option(value.data.begin(), value.data.end(), buffer); add_option( option(USER_CLASS, buffer.begin(), buffer.end()) ); @@ -378,7 +373,7 @@ void DHCPv6::vendor_class(const vendor_class_type &value) { sizeof(uint32_t) ); *(uint32_t*)&buffer[0] = Endian::host_to_be(value.enterprise_number); - class_option_data2option( + Internals::class_option_data2option( value.vendor_class_data.begin(), value.vendor_class_data.end(), buffer, @@ -638,4 +633,15 @@ DHCPv6::duid_type DHCPv6::duid_type::from_option(const option &opt) ) ); } + +DHCPv6::user_class_type DHCPv6::user_class_type::from_option(const option &opt) +{ + if(opt.data_size() < sizeof(uint16_t)) + throw malformed_option(); + user_class_type output; + output.data = Internals::option2class_option_data( + opt.data_ptr(), opt.data_size() + ); + return output; +} } // namespace Tins diff --git a/tests/src/dhcpv6.cpp b/tests/src/dhcpv6.cpp index 1d65e07..f7d0791 100644 --- a/tests/src/dhcpv6.cpp +++ b/tests/src/dhcpv6.cpp @@ -202,16 +202,16 @@ TEST_F(DHCPv6Test, UserClass) { DHCPv6::class_option_data_type user_data; user_data.push_back(22); user_data.push_back(176); - data.push_back(user_data); + data.data.push_back(user_data); user_data.push_back(99); user_data.push_back(231); - data.push_back(user_data); + data.data.push_back(user_data); dhcp.user_class(data); output = dhcp.user_class(); - EXPECT_EQ(data, output); + EXPECT_EQ(data.data, output.data); } TEST_F(DHCPv6Test, VendorClass) {