From f5f56e1a1c4d9e9496fcb9d81131066a964ccd23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 14:15:43 +0200 Subject: Adding upstream version 2.4.1. Signed-off-by: Daniel Baumann --- src/lib/dhcp/tests/pkt4_unittest.cc | 1529 +++++++++++++++++++++++++++++++++++ 1 file changed, 1529 insertions(+) create mode 100644 src/lib/dhcp/tests/pkt4_unittest.cc (limited to 'src/lib/dhcp/tests/pkt4_unittest.cc') diff --git a/src/lib/dhcp/tests/pkt4_unittest.cc b/src/lib/dhcp/tests/pkt4_unittest.cc new file mode 100644 index 0000000..70bc624 --- /dev/null +++ b/src/lib/dhcp/tests/pkt4_unittest.cc @@ -0,0 +1,1529 @@ +// Copyright (C) 2011-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace std; +using namespace isc; +using namespace isc::asiolink; +using namespace isc::dhcp; +using namespace isc::util; +// Don't import the entire boost namespace. It will unexpectedly hide uint8_t +// for some systems. +using boost::scoped_ptr; + +namespace { + +/// V4 Options being used for pack/unpack testing. +/// For test simplicity, all selected options have +/// variable length data so as there are no restrictions +/// on a length of their data. +static uint8_t v4_opts[] = { + 53, 1, 2, // Message Type (required to not throw exception during unpack) + 12, 3, 0, 1, 2, // Hostname + 14, 3, 10, 11, 12, // Merit Dump File + 60, 3, 20, 21, 22, // Class Id + 128, 3, 30, 31, 32, // Vendor specific + 254, 3, 40, 41, 42, // Reserved +}; + +// Sample data +const uint8_t dummyOp = BOOTREQUEST; +const uint8_t dummyHtype = 6; +const uint8_t dummyHlen = 6; +const uint8_t dummyHops = 13; +const uint32_t dummyTransid = 0x12345678; +const uint16_t dummySecs = 42; +const uint16_t dummyFlags = BOOTP_BROADCAST; + +const IOAddress dummyCiaddr("192.0.2.1"); +const IOAddress dummyYiaddr("1.2.3.4"); +const IOAddress dummySiaddr("192.0.2.255"); +const IOAddress dummyGiaddr("255.255.255.255"); + +// a dummy MAC address +const uint8_t dummyMacAddr[] = {0, 1, 2, 3, 4, 5}; + +// A dummy MAC address, padded with 0s +const uint8_t dummyChaddr[16] = {0, 1, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + +// Let's use some creative test content here (128 chars + \0) +const uint8_t dummyFile[] = "Lorem ipsum dolor sit amet, consectetur " + "adipiscing elit. Proin mollis placerat metus, at " + "lacinia orci ornare vitae. Mauris amet."; + +// Yet another type of test content (64 chars + \0) +const uint8_t dummySname[] = "Lorem ipsum dolor sit amet, consectetur " + "adipiscing elit posuere."; + +BOOST_STATIC_ASSERT(sizeof(dummyFile) == Pkt4::MAX_FILE_LEN + 1); +BOOST_STATIC_ASSERT(sizeof(dummySname) == Pkt4::MAX_SNAME_LEN + 1); + + +class Pkt4Test : public ::testing::Test { +public: + Pkt4Test() { + } + + /// @brief Generates test packet. + /// + /// Allocates and generates test packet, with all fixed fields set to non-zero + /// values. Content is not always reasonable. + /// + /// See generateTestPacket2() function that returns exactly the same packet in + /// on-wire format. + /// + /// @return pointer to allocated Pkt4 object. + Pkt4Ptr generateTestPacket1() { + + boost::shared_ptr pkt(new Pkt4(DHCPDISCOVER, dummyTransid)); + + vector vectorMacAddr(dummyMacAddr, dummyMacAddr + + sizeof(dummyMacAddr)); + + // hwType = 6(ETHERNET), hlen = 6(MAC address len) + pkt->setHWAddr(dummyHtype, dummyHlen, vectorMacAddr); + pkt->setHops(dummyHops); // 13 relays. Wow! + // Transaction-id is already set. + pkt->setSecs(dummySecs); + pkt->setFlags(dummyFlags); // all flags set + pkt->setCiaddr(dummyCiaddr); + pkt->setYiaddr(dummyYiaddr); + pkt->setSiaddr(dummySiaddr); + pkt->setGiaddr(dummyGiaddr); + // Chaddr already set with setHWAddr(). + pkt->setSname(dummySname, 64); + pkt->setFile(dummyFile, 128); + + return (pkt); + } + + /// @brief Generates test packet. + /// + /// Allocates and generates on-wire buffer that represents test packet, with all + /// fixed fields set to non-zero values. Content is not always reasonable. + /// + /// See generateTestPacket1() function that returns exactly the same packet as + /// Pkt4 object. + /// + /// @return pointer to allocated Pkt4 object + // Returns a vector containing a DHCPv4 packet header. + vector generateTestPacket2() { + + // That is only part of the header. It contains all "short" fields, + // larger fields are constructed separately. + uint8_t hdr[] = { + 1, 6, 6, 13, // op, htype, hlen, hops, + 0x12, 0x34, 0x56, 0x78, // transaction-id + 0, 42, 0x80, 0x00, // 42 secs, BROADCAST flags + 192, 0, 2, 1, // ciaddr + 1, 2, 3, 4, // yiaddr + 192, 0, 2, 255, // siaddr + 255, 255, 255, 255, // giaddr + }; + + // Initialize the vector with the header fields defined above. + vector buf(hdr, hdr + sizeof(hdr)); + + // Append the large header fields. + copy(dummyChaddr, dummyChaddr + Pkt4::MAX_CHADDR_LEN, back_inserter(buf)); + copy(dummySname, dummySname + Pkt4::MAX_SNAME_LEN, back_inserter(buf)); + copy(dummyFile, dummyFile + Pkt4::MAX_FILE_LEN, back_inserter(buf)); + + // Should now have all the header, so check. The "static_cast" is used + // to get round an odd bug whereby the linker appears not to find the + // definition of DHCPV4_PKT_HDR_LEN if it appears within an EXPECT_EQ(). + EXPECT_EQ(static_cast(Pkt4::DHCPV4_PKT_HDR_LEN), buf.size()); + + return (buf); + } + + /// @brief Verify that the options are correct after parsing. + /// + /// @param pkt A packet holding parsed options. + void verifyParsedOptions(const Pkt4Ptr& pkt) { + EXPECT_TRUE(pkt->getOption(12)); + EXPECT_TRUE(pkt->getOption(60)); + EXPECT_TRUE(pkt->getOption(14)); + EXPECT_TRUE(pkt->getOption(128)); + EXPECT_TRUE(pkt->getOption(254)); + + // Verify the packet type is correct. + ASSERT_EQ(DHCPOFFER, pkt->getType()); + + // First option after message type starts at 3. + uint8_t *opt_data_ptr = v4_opts + 3; + + // Option 12 is represented by the OptionString class so let's do + // the appropriate conversion. + boost::shared_ptr