From: Marcin Siodelski Date: Thu, 19 Nov 2015 13:46:39 +0000 (+0100) Subject: [4093] Implemented Option::toHexString method. X-Git-Tag: trac4204_base~1^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d6a66ecfb33bc5eb78b4b49267fe0c1944d2116;p=thirdparty%2Fkea.git [4093] Implemented Option::toHexString method. --- diff --git a/src/lib/dhcp/option.cc b/src/lib/dhcp/option.cc index 063884ad34..92bbfd7afa 100644 --- a/src/lib/dhcp/option.cc +++ b/src/lib/dhcp/option.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -219,6 +220,40 @@ Option::toString() { return (toText(0)); } +std::string +Option::toHexString(const bool include_header) { + OutputBuffer buf(len()); + try { + // If the option is too long, exception will be thrown. We allow + // for this exception to propagate to not mask this error. + pack(buf); + + } catch (const std::exception &ex) { + isc_throw(OutOfRange, "unable to obtain hexadecimal representation" + " of option " << getType() << ": " << ex.what()); + } + const uint8_t* option_data = static_cast(buf.getData()); + std::vector option_vec; + + // Exclude header. + if (!include_header) { + if (buf.getLength() > getHeaderLen()) { + option_vec.assign(option_data + getHeaderLen(), + option_data + buf.getLength()); + } + + } else { + option_vec.assign(option_data, option_data + buf.getLength()); + } + + // Return hexadecimal representation prepended with 0x or empty string + // if option has no payload and the header fields are excluded. + std::ostringstream s; + if (!option_vec.empty()) { + s << "0x" << encode::encodeHex(option_vec); + } + return (s.str()); +} std::string Option::headerToText(const int indent, const std::string& type_name) { diff --git a/src/lib/dhcp/option.h b/src/lib/dhcp/option.h index 3d1e9c18a2..0cda90e84e 100644 --- a/src/lib/dhcp/option.h +++ b/src/lib/dhcp/option.h @@ -216,6 +216,14 @@ public: /// @return string that represents the value of the option. virtual std::string toString(); + /// @brief Returns string containing hexadecimal representation of option. + /// + /// @param include_header Boolean flag which indicates if the output should + /// also contain header fields. The default is that it shouldn't. + /// + /// @return String containing hexadecimal representation of the option. + virtual std::string toHexString(const bool include_header = false); + /// Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6) /// /// @return option type diff --git a/src/lib/dhcp/tests/option_unittest.cc b/src/lib/dhcp/tests/option_unittest.cc index 6b24b300fc..519783e52a 100644 --- a/src/lib/dhcp/tests/option_unittest.cc +++ b/src/lib/dhcp/tests/option_unittest.cc @@ -236,6 +236,38 @@ TEST_F(OptionTest, v4_toText) { EXPECT_EQ("type=253, len=003: 00:0f:ff", opt.toText()); } +// Test converting option to the hexadecimal representation. +TEST_F(OptionTest, v4_toHexString) { + std::vector payload; + for (unsigned int i = 0; i < 16; ++i) { + payload.push_back(static_cast(i)); + } + Option opt(Option::V4, 122, payload); + EXPECT_EQ("0x000102030405060708090A0B0C0D0E0F", opt.toHexString()); + EXPECT_EQ("0x7A10000102030405060708090A0B0C0D0E0F", + opt.toHexString(true)); + + // Test empty option. + Option opt_empty(Option::V4, 65, std::vector()); + EXPECT_TRUE(opt_empty.toHexString().empty()); + EXPECT_EQ("0x4100", opt_empty.toHexString(true)); + + // Test too long option. We can't simply create such option by + // providing a long payload, because class constructor would not + // accept it. Instead we'll add two long sub options after we + // create an option instance. + Option opt_too_long(Option::V4, 33); + // Both suboptions have payloads of 150 bytes. + std::vector long_payload(150, 1); + OptionPtr sub1(new Option(Option::V4, 100, long_payload)); + OptionPtr sub2(new Option(Option::V4, 101, long_payload)); + opt_too_long.addOption(sub1); + opt_too_long.addOption(sub2); + + // The toHexString() should throw exception. + EXPECT_THROW(opt_too_long.toHexString(), isc::OutOfRange); +} + // Tests simple constructor TEST_F(OptionTest, v6_basic) { @@ -446,6 +478,22 @@ TEST_F(OptionTest, v6_toText) { EXPECT_EQ("type=00258, len=00003: 00:0f:ff", opt->toText()); } +// Test converting option to the hexadecimal representation. +TEST_F(OptionTest, v6_toHexString) { + std::vector payload; + for (unsigned int i = 0; i < 16; ++i) { + payload.push_back(static_cast(i)); + } + Option opt(Option::V6, 12202, payload); + EXPECT_EQ("0x000102030405060708090A0B0C0D0E0F", opt.toHexString()); + EXPECT_EQ("0x2FAA0010000102030405060708090A0B0C0D0E0F", + opt.toHexString(true)); + + // Test empty option. + Option opt_empty(Option::V6, 65000, std::vector()); + EXPECT_TRUE(opt_empty.toHexString().empty()); + EXPECT_EQ("0xFDE80000", opt_empty.toHexString(true)); +} TEST_F(OptionTest, getUintX) {