Commit c6e8dd84 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[1228] LibDHCP::unpackOptions4 implemented (+tests)

parent 7d25b201
......@@ -84,6 +84,37 @@ LibDHCP::unpackOptions6(const boost::shared_array<uint8_t> buf,
return (offset);
}
void
LibDHCP::unpackOptions4(const std::vector<uint8_t>& buf,
isc::dhcp::Option::Option6Collection& options) {
size_t offset = 0;
// 2 - header of DHCPv4 option
while (offset + 2 <= buf.size()) {
uint8_t opt_type = buf[offset++];
uint8_t opt_len = buf[offset++];
if (offset + opt_len > buf.size() ) {
isc_throw(OutOfRange, "Option parse failed. Tried to parse "
<< offset + opt_len << " bytes from " << buf.size()
<< "-byte long buffer.");
}
boost::shared_ptr<Option> opt;
switch(opt_type) {
default:
/// TODO: Is this intermediate object really necessary here?
vector<uint8_t> tmpVec(&buf[offset], &buf[offset] + opt_len);
opt = boost::shared_ptr<Option>(new Option(Option::V4,
opt_type,
tmpVec));
}
options.insert(pair<int, boost::shared_ptr<Option> >(opt_type, opt));
offset += opt_len;
}
}
unsigned int
LibDHCP::packOptions6(boost::shared_array<uint8_t> data,
unsigned int data_len,
......
......@@ -58,6 +58,9 @@ public:
packOptions(isc::util::OutputBuffer& buf,
const isc::dhcp::Option::Option6Collection& options);
static void
unpackOptions4(const std::vector<uint8_t>& buf,
isc::dhcp::Option::Option6Collection& options);
///
/// Parses provided buffer and creates Option objects.
///
......
......@@ -15,16 +15,16 @@
#include <config.h>
#include <iostream>
#include <sstream>
#include <arpa/inet.h>
#include <gtest/gtest.h>
#include "dhcp/libdhcp.h"
#include <util/buffer.h>
#include <dhcp/libdhcp.h>
#include "config.h"
using namespace std;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::util;
namespace {
class LibDhcpTest : public ::testing::Test {
......@@ -134,14 +134,101 @@ TEST(LibDhcpTest, unpackOptions6) {
EXPECT_TRUE(x == options.end()); // option 32000 not found
}
static uint8_t v4Opts[] = {
12, 3, 0, 1, 2,
13, 3, 10, 11, 12,
14, 3, 20, 21, 22,
254, 3, 30, 31, 32,
128, 3, 40, 41, 42
};
TEST(LibDhcpTest, packOptions4) {
// TODO
ASSERT_TRUE(false);
vector<uint8_t> payload[5];
for (int i = 0; i < 5; i++) {
payload[i].resize(3);
payload[i][0] = i*10;
payload[i][1] = i*10+1;
payload[i][2] = i*10+2;
}
boost::shared_ptr<Option> opt1(new Option(Option::V4, 12, payload[0]));
boost::shared_ptr<Option> opt2(new Option(Option::V4, 13, payload[1]));
boost::shared_ptr<Option> opt3(new Option(Option::V4, 14, payload[2]));
boost::shared_ptr<Option> opt4(new Option(Option::V4,254, payload[3]));
boost::shared_ptr<Option> opt5(new Option(Option::V4,128, payload[4]));
isc::dhcp::Option::Option6Collection opts; // list of options
opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt1));
opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt2));
opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt3));
opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt4));
opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt5));
vector<uint8_t> expVect(v4Opts, v4Opts + sizeof(v4Opts));
OutputBuffer buf(100);
EXPECT_NO_THROW (
LibDHCP::packOptions(buf, opts);
);
ASSERT_EQ(buf.getLength(), sizeof(v4Opts));
EXPECT_EQ(0, memcmp(v4Opts, buf.getData(), sizeof(v4Opts)));
}
TEST(LibDhcpTest, unpackOptions4) {
// TODO
ASSERT_TRUE(false);
vector<uint8_t> packed(v4Opts, v4Opts + sizeof(v4Opts));
isc::dhcp::Option::Option6Collection options; // list of options
ASSERT_NO_THROW(
LibDHCP::unpackOptions4(packed, options);
);
isc::dhcp::Option::Option6Collection::const_iterator x = options.find(12);
ASSERT_FALSE(x == options.end()); // option 1 should exist
EXPECT_EQ(12, x->second->getType()); // this should be option 12
ASSERT_EQ(3, x->second->getData().size()); // it should be of length 3
EXPECT_EQ(5, x->second->len()); // total option length 5
EXPECT_EQ(0, memcmp(&x->second->getData()[0], v4Opts+2, 3)); // data len=3
x = options.find(13);
ASSERT_FALSE(x == options.end()); // option 1 should exist
EXPECT_EQ(13, x->second->getType()); // this should be option 13
ASSERT_EQ(3, x->second->getData().size()); // it should be of length 3
EXPECT_EQ(5, x->second->len()); // total option length 5
EXPECT_EQ(0, memcmp(&x->second->getData()[0], v4Opts+7, 3)); // data len=3
x = options.find(14);
ASSERT_FALSE(x == options.end()); // option 3 should exist
EXPECT_EQ(14, x->second->getType()); // this should be option 14
ASSERT_EQ(3, x->second->getData().size()); // it should be of length 3
EXPECT_EQ(5, x->second->len()); // total option length 5
EXPECT_EQ(0, memcmp(&x->second->getData()[0], v4Opts+12, 3)); // data len=3
x = options.find(254);
ASSERT_FALSE(x == options.end()); // option 3 should exist
EXPECT_EQ(254, x->second->getType()); // this should be option 254
ASSERT_EQ(3, x->second->getData().size()); // it should be of length 3
EXPECT_EQ(5, x->second->len()); // total option length 5
EXPECT_EQ(0, memcmp(&x->second->getData()[0], v4Opts+17, 3)); // data len=3
x = options.find(128);
ASSERT_FALSE(x == options.end()); // option 3 should exist
EXPECT_EQ(128, x->second->getType()); // this should be option 254
ASSERT_EQ(3, x->second->getData().size()); // it should be of length 3
EXPECT_EQ(5, x->second->len()); // total option length 5
EXPECT_EQ(0, memcmp(&x->second->getData()[0], v4Opts+22, 3)); // data len=3
x = options.find(0);
EXPECT_TRUE(x == options.end()); // option 0 not found
x = options.find(1);
EXPECT_TRUE(x == options.end()); // option 1 not found
x = options.find(2);
EXPECT_TRUE(x == options.end()); // option 2 not found
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment