1 // Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7 #include <config.h>
8
9 #include <dhcp/dhcp6.h>
10 #include <dhcp/option.h>
11 #include <dhcp/pkt4.h>
12 #include <dhcp/pkt6.h>
13 #include <dhcp/pkt4o6.h>
14
15 #include <boost/scoped_ptr.hpp>
16
17 #include <gtest/gtest.h>
18
19 using namespace isc::dhcp;
20
21 namespace {
22
23 /// @brief A Fixture class dedicated to testing of the Pkt4o6 class that
24 /// represents a DHCPv4-over-DHCPv6 packet.
25 class Pkt4o6Test : public ::testing::Test {
26 protected:
Pkt4o6Test()27 Pkt4o6Test() :
28 data6_(6, 0),
29 pkt6_(new Pkt6(&data6_[0], data6_.size())),
30 pkt4_(new Pkt4(DHCPDISCOVER, 0x12345678))
31 {
32 pkt4_->pack();
33 const uint8_t* cp = static_cast<const uint8_t*>(
34 pkt4_->getBuffer().getData());
35 buffer4_.assign(cp, cp + pkt4_->getBuffer().getLength());
36 }
37
38 protected:
39 // commonly used test data
40 const std::vector<uint8_t> data6_; // data for Pkt6 (content unimportant)
41 Pkt6Ptr pkt6_; // DHCPv6 message for 4o6
42 Pkt4Ptr pkt4_; // DHCPv4 message for 4o6
43 OptionBuffer buffer4_; // wire-format data buffer of pkt4_
44 };
45
46 // This test verifies that the constructors are working as expected.
TEST_F(Pkt4o6Test,construct)47 TEST_F(Pkt4o6Test, construct) {
48 // Construct 4o6 packet, unpack the data to examine it
49 boost::scoped_ptr<Pkt4o6> pkt4o6(new Pkt4o6(buffer4_, pkt6_));
50 pkt4o6->unpack();
51 // Inspect its internal to confirm it's built as expected. We also test
52 // isDhcp4o6() here.
53 EXPECT_TRUE(pkt4o6->isDhcp4o6());
54 EXPECT_EQ(pkt6_, pkt4o6->getPkt6());
55 EXPECT_EQ(DHCPDISCOVER, pkt4o6->getType());
56
57 // Same check for the other constructor. It relies on the internal
58 // behavior of Pkt4's copy constructor, so we need to first unpack pkt4.
59 pkt4_.reset(new Pkt4(&buffer4_[0], buffer4_.size()));
60 pkt4_->unpack();
61 pkt4o6.reset(new Pkt4o6(pkt4_, pkt6_));
62 EXPECT_TRUE(pkt4o6->isDhcp4o6());
63 EXPECT_EQ(pkt6_, pkt4o6->getPkt6());
64 EXPECT_EQ(DHCPDISCOVER, pkt4o6->getType());
65 }
66
67 // This test verifies that the pack() method handles the building
68 // process correctly.
TEST_F(Pkt4o6Test,pack)69 TEST_F(Pkt4o6Test, pack) {
70 // prepare unpacked DHCPv4 packet (see the note in constructor test)
71 pkt4_.reset(new Pkt4(&buffer4_[0], buffer4_.size()));
72 pkt4_->unpack();
73
74 // Construct 4o6 packet to be tested and pack the data.
75 Pkt4o6 pkt4o6(pkt4_, pkt6_);
76 pkt4o6.pack();
77
78 // The packed data should be:
79 // 4-byte DHCPv6 message header
80 // 4-byte header part of DHCPv4 message option
81 // Raw DHCPv4 message (data stored in buffer4_)
82 EXPECT_EQ(4 + 4 + buffer4_.size(),
83 pkt4o6.getPkt6()->getBuffer().getLength());
84
85 // Check the DHCPv4 message option content (Pkt4o6 class is not responsible
86 // for making it valid, so we won't examine it)
87 const uint8_t* cp = static_cast<const uint8_t*>(
88 pkt4o6.getPkt6()->getBuffer().getData());
89 EXPECT_EQ(0, cp[4]);
90 EXPECT_EQ(D6O_DHCPV4_MSG, cp[5]);
91 EXPECT_EQ((buffer4_.size() >> 8) & 0xff, cp[6]);
92 EXPECT_EQ(buffer4_.size() & 0xff, cp[7]);
93 EXPECT_EQ(0, memcmp(&cp[8], &buffer4_[0], buffer4_.size()));
94 }
95
96 // This test verifies that the flag indicating that the retrieved options
97 // should be copied is transferred between the DHCPv4 packet and the
98 // DHCPv6 packet being a member of Pkt4o6 class.
TEST_F(Pkt4o6Test,setCopyRetrievedOptions)99 TEST_F(Pkt4o6Test, setCopyRetrievedOptions) {
100 // Create Pkt4o6 and initially expect that the flag is set to false.
101 Pkt4o6 pkt4o6(pkt4_, pkt6_);
102 ASSERT_FALSE(pkt4o6.isCopyRetrievedOptions());
103 Pkt6Ptr pkt6 = pkt4o6.getPkt6();
104 ASSERT_TRUE(pkt6);
105 ASSERT_FALSE(pkt6->isCopyRetrievedOptions());
106
107 // Set the flag to true for Pkt4o6.
108 pkt4o6.setCopyRetrievedOptions(true);
109 pkt6 = pkt4o6.getPkt6();
110 ASSERT_TRUE(pkt6);
111 EXPECT_TRUE(pkt6->isCopyRetrievedOptions());
112
113 // Repeat the same test but set the flag to false.
114 pkt4o6.setCopyRetrievedOptions(false);
115 EXPECT_FALSE(pkt4o6.isCopyRetrievedOptions());
116 pkt6 = pkt4o6.getPkt6();
117 ASSERT_TRUE(pkt6);
118 EXPECT_FALSE(pkt6->isCopyRetrievedOptions());
119 }
120
121 /// @todo: Add a test that handles actual DHCP4o6 traffic capture
122 /// once we get it. We should add the capture to pkt_captures{4,6}.cc
123 }
124