|
@@ -20,16 +20,17 @@
|
|
|
#include <boost/static_assert.hpp>
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
#include <boost/shared_array.hpp>
|
|
|
-
|
|
|
-#include "io_address.h"
|
|
|
-#include "dhcp/pkt4.h"
|
|
|
-#include "dhcp/dhcp4.h"
|
|
|
-#include "exceptions/exceptions.h"
|
|
|
+#include <util/buffer.h>
|
|
|
+#include <asiolink/io_address.h>
|
|
|
+#include <dhcp/pkt4.h>
|
|
|
+#include <dhcp/dhcp4.h>
|
|
|
+#include <exceptions/exceptions.h>
|
|
|
|
|
|
using namespace std;
|
|
|
using namespace isc;
|
|
|
using namespace isc::asiolink;
|
|
|
using namespace isc::dhcp;
|
|
|
+using namespace isc::util;
|
|
|
using namespace boost;
|
|
|
|
|
|
namespace {
|
|
@@ -433,19 +434,127 @@ TEST(Pkt4Test, file) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+static uint8_t v4Opts[] = {
|
|
|
+ 12, 3, 0, 1, 2,
|
|
|
+ 13, 3, 10, 11, 12,
|
|
|
+ 14, 3, 20, 21, 22,
|
|
|
+ 128, 3, 30, 31, 32,
|
|
|
+ 254, 3, 40, 41, 42
|
|
|
+};
|
|
|
+
|
|
|
TEST(Pkt4Test, options) {
|
|
|
- // TODO
|
|
|
- ASSERT_TRUE(false);
|
|
|
-}
|
|
|
+ Pkt4* pkt = new Pkt4(DHCPOFFER, 0);
|
|
|
+
|
|
|
+ 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> opt5(new Option(Option::V4,128, payload[3]));
|
|
|
+ boost::shared_ptr<Option> opt4(new Option(Option::V4,254, payload[4]));
|
|
|
+
|
|
|
+ pkt->addOption(opt1);
|
|
|
+ pkt->addOption(opt2);
|
|
|
+ pkt->addOption(opt3);
|
|
|
+ pkt->addOption(opt4);
|
|
|
+ pkt->addOption(opt5);
|
|
|
+
|
|
|
+ EXPECT_TRUE(pkt->getOption(12));
|
|
|
+ EXPECT_TRUE(pkt->getOption(13));
|
|
|
+ EXPECT_TRUE(pkt->getOption(14));
|
|
|
+ EXPECT_TRUE(pkt->getOption(128));
|
|
|
+ EXPECT_TRUE(pkt->getOption(254));
|
|
|
+ EXPECT_FALSE(pkt->getOption(127)); // no such option
|
|
|
+
|
|
|
+ // options are unique in DHCPv4. It should not be possible
|
|
|
+ // to add more than one option of the same type.
|
|
|
+ EXPECT_THROW(
|
|
|
+ pkt->addOption(opt1),
|
|
|
+ BadValue
|
|
|
+ );
|
|
|
|
|
|
-TEST(Pkt4Test, packOptions) {
|
|
|
- // TODO
|
|
|
- ASSERT_TRUE(false);
|
|
|
+ EXPECT_NO_THROW(
|
|
|
+ pkt->pack();
|
|
|
+ );
|
|
|
+
|
|
|
+ OutputBuffer& buf = pkt->getBuffer();
|
|
|
+ // check that all options are stored, they should take sizeof(v4Opts)
|
|
|
+ ASSERT_EQ(static_cast<size_t>(Pkt4::DHCPV4_PKT_HDR_LEN) + sizeof(v4Opts),
|
|
|
+ buf.getLength());
|
|
|
+
|
|
|
+ // that that this extra data actually contain our options
|
|
|
+ const uint8_t* ptr = static_cast<const uint8_t*>(buf.getData());
|
|
|
+ ptr += Pkt4::DHCPV4_PKT_HDR_LEN; // rewind to end of fixed part
|
|
|
+ EXPECT_EQ(0, memcmp(ptr, v4Opts, sizeof(v4Opts)));
|
|
|
+
|
|
|
+ EXPECT_NO_THROW(
|
|
|
+ delete pkt;
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
TEST(Pkt4Test, unpackOptions) {
|
|
|
- // TODO
|
|
|
- ASSERT_TRUE(false);
|
|
|
+
|
|
|
+ vector<uint8_t> expectedFormat = generateTestPacket2();
|
|
|
+
|
|
|
+ for (int i=0; i < sizeof(v4Opts); i++) {
|
|
|
+ expectedFormat.push_back(v4Opts[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // now expectedFormat contains fixed format and 5 options
|
|
|
+
|
|
|
+ shared_ptr<Pkt4> pkt(new Pkt4(&expectedFormat[0],
|
|
|
+ expectedFormat.size()));
|
|
|
+
|
|
|
+ EXPECT_NO_THROW(
|
|
|
+ pkt->unpack()
|
|
|
+ );
|
|
|
+
|
|
|
+ EXPECT_TRUE(pkt->getOption(12));
|
|
|
+ EXPECT_TRUE(pkt->getOption(13));
|
|
|
+ EXPECT_TRUE(pkt->getOption(14));
|
|
|
+ EXPECT_TRUE(pkt->getOption(128));
|
|
|
+ EXPECT_TRUE(pkt->getOption(254));
|
|
|
+
|
|
|
+ shared_ptr<Option> x = pkt->getOption(12);
|
|
|
+ ASSERT_TRUE(x); // option 1 should exist
|
|
|
+ EXPECT_EQ(12, x->getType()); // this should be option 12
|
|
|
+ ASSERT_EQ(3, x->getData().size()); // it should be of length 3
|
|
|
+ EXPECT_EQ(5, x->len()); // total option length 5
|
|
|
+ EXPECT_EQ(0, memcmp(&x->getData()[0], v4Opts+2, 3)); // data len=3
|
|
|
+
|
|
|
+ x = pkt->getOption(13);
|
|
|
+ ASSERT_TRUE(x); // option 13 should exist
|
|
|
+ EXPECT_EQ(13, x->getType()); // this should be option 13
|
|
|
+ ASSERT_EQ(3, x->getData().size()); // it should be of length 3
|
|
|
+ EXPECT_EQ(5, x->len()); // total option length 5
|
|
|
+ EXPECT_EQ(0, memcmp(&x->getData()[0], v4Opts+7, 3)); // data len=3
|
|
|
+
|
|
|
+ x = pkt->getOption(14);
|
|
|
+ ASSERT_TRUE(x); // option 14 should exist
|
|
|
+ EXPECT_EQ(14, x->getType()); // this should be option 14
|
|
|
+ ASSERT_EQ(3, x->getData().size()); // it should be of length 3
|
|
|
+ EXPECT_EQ(5, x->len()); // total option length 5
|
|
|
+ EXPECT_EQ(0, memcmp(&x->getData()[0], v4Opts+12, 3)); // data len=3
|
|
|
+
|
|
|
+ x = pkt->getOption(128);
|
|
|
+ ASSERT_TRUE(x); // option 3 should exist
|
|
|
+ EXPECT_EQ(128, x->getType()); // this should be option 254
|
|
|
+ ASSERT_EQ(3, x->getData().size()); // it should be of length 3
|
|
|
+ EXPECT_EQ(5, x->len()); // total option length 5
|
|
|
+ EXPECT_EQ(0, memcmp(&x->getData()[0], v4Opts+17, 3)); // data len=3
|
|
|
+
|
|
|
+ x = pkt->getOption(254);
|
|
|
+ ASSERT_TRUE(x); // option 3 should exist
|
|
|
+ EXPECT_EQ(254, x->getType()); // this should be option 254
|
|
|
+ ASSERT_EQ(3, x->getData().size()); // it should be of length 3
|
|
|
+ EXPECT_EQ(5, x->len()); // total option length 5
|
|
|
+ EXPECT_EQ(0, memcmp(&x->getData()[0], v4Opts+22, 3)); // data len=3
|
|
|
}
|
|
|
|
|
|
} // end of anonymous namespace
|