A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
dhcp6-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 NITK Surathkal
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Kavya Bhat <kavyabhat@gmail.com>
7 *
8 */
9
10#include "ns3/data-rate.h"
11#include "ns3/dhcp6-helper.h"
12#include "ns3/internet-stack-helper.h"
13#include "ns3/ipv6-address-helper.h"
14#include "ns3/radvd-helper.h"
15#include "ns3/simple-net-device-helper.h"
16#include "ns3/simulator.h"
17#include "ns3/test.h"
18#include "ns3/trace-helper.h"
19
20using namespace ns3;
21
22/**
23 * @ingroup dhcp6
24 * @defgroup dhcp6-test DHCPv6 module tests
25 */
26
27/**
28 * @ingroup dhcp6-test
29 * @ingroup tests
30 *
31 * @brief DHCPv6 header tests
32 */
33class Dhcp6TestCase : public TestCase
34{
35 public:
37 ~Dhcp6TestCase() override;
38
39 /**
40 * Triggered by an address lease on a client.
41 * @param context The test name.
42 * @param newAddress The leased address.
43 */
44 void LeaseObtained(std::string context, const Ipv6Address& newAddress);
45
46 private:
47 void DoRun() override;
48 Ipv6Address m_leasedAddress[2]; //!< Address given to the nodes
49};
50
52 : TestCase("Dhcp6 test case ")
53{
54}
55
59
60void
61Dhcp6TestCase::LeaseObtained(std::string context, const Ipv6Address& newAddress)
62{
63 uint8_t numericalContext = std::stoi(context, nullptr, 10);
64
65 if (numericalContext >= 0 && numericalContext < std::size(m_leasedAddress))
66 {
67 m_leasedAddress[numericalContext] = newAddress;
68 }
69}
70
71void
73{
74 NodeContainer nonRouterNodes;
75 nonRouterNodes.Create(3);
77 NodeContainer all(nonRouterNodes, router);
78
79 SimpleNetDeviceHelper simpleNetDevice;
80 simpleNetDevice.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
81 simpleNetDevice.SetDeviceAttribute("DataRate", DataRateValue(DataRate("5Mbps")));
82 NetDeviceContainer devices = simpleNetDevice.Install(all); // all nodes
83
84 InternetStackHelper internetv6;
85 internetv6.Install(all);
86
88 ipv6.SetBase(Ipv6Address("2001:cafe::"), Ipv6Prefix(64));
89 NetDeviceContainer nonRouterDevices;
90 nonRouterDevices.Add(devices.Get(0)); // The server node, S0.
91 nonRouterDevices.Add(devices.Get(1)); // The first client node, N0.
92 nonRouterDevices.Add(devices.Get(2)); // The second client node, N1.
93 Ipv6InterfaceContainer i = ipv6.AssignWithoutAddress(nonRouterDevices);
94
95 NetDeviceContainer routerDevice;
96 routerDevice.Add(devices.Get(3)); // CSMA interface of the node R0.
97 Ipv6InterfaceContainer r1 = ipv6.Assign(routerDevice);
98 r1.SetForwarding(0, true);
99
100 RadvdHelper radvdHelper;
101
102 /* Set up unsolicited RAs */
103 radvdHelper.AddAnnouncedPrefix(r1.GetInterfaceIndex(0), Ipv6Address("2001:cafe::1"), 64);
104 radvdHelper.GetRadvdInterface(r1.GetInterfaceIndex(0))->SetManagedFlag(true);
105
106 Dhcp6Helper dhcp6Helper;
107
108 dhcp6Helper.SetServerAttribute("RenewTime", StringValue("10s"));
109 dhcp6Helper.SetServerAttribute("RebindTime", StringValue("16s"));
110 dhcp6Helper.SetServerAttribute("PreferredLifetime", StringValue("18s"));
111 dhcp6Helper.SetServerAttribute("ValidLifetime", StringValue("20s"));
112
113 // DHCPv6 clients
114 NodeContainer nodes = NodeContainer(nonRouterNodes.Get(1), nonRouterNodes.Get(2));
115 ApplicationContainer dhcpClients = dhcp6Helper.InstallDhcp6Client(nodes);
116 dhcpClients.Start(Seconds(1.0));
117 dhcpClients.Stop(Seconds(20.0));
118
119 // DHCPv6 server
120 NetDeviceContainer serverNetDevices;
121 serverNetDevices.Add(nonRouterDevices.Get(0));
122 ApplicationContainer dhcpServerApp = dhcp6Helper.InstallDhcp6Server(serverNetDevices);
123
124 Ptr<Dhcp6Server> server = DynamicCast<Dhcp6Server>(dhcpServerApp.Get(0));
125 server->AddSubnet(Ipv6Address("2001:cafe::"),
126 Ipv6Prefix(64),
127 Ipv6Address("2001:cafe::42:1"),
128 Ipv6Address("2001:cafe::42:ffff"));
129
130 dhcpServerApp.Start(Seconds(0.0));
131 dhcpServerApp.Stop(Seconds(20.0));
132
133 ApplicationContainer radvdApps = radvdHelper.Install(router);
134 radvdApps.Start(Seconds(1.0));
135 radvdApps.Stop(Seconds(20.0));
136
137 dhcpClients.Get(0)->TraceConnect("NewLease",
138 "0",
140 dhcpClients.Get(1)->TraceConnect("NewLease",
141 "1",
143
146
147 // Validate that the client nodes have three addresses on each interface -
148 // link-local, autoconfigured, and leased from DHCPv6 server.
149 Ptr<Ipv6> ipv6_client1 = nonRouterNodes.Get(1)->GetObject<Ipv6>();
150 Ptr<Ipv6L3Protocol> l3_client1 = ipv6_client1->GetObject<Ipv6L3Protocol>();
151 int32_t ifIndex_client1 = ipv6_client1->GetInterfaceForDevice(nonRouterDevices.Get(1));
152
153 NS_TEST_ASSERT_MSG_EQ(l3_client1->GetNAddresses(ifIndex_client1),
154 3,
155 "Incorrect number of addresses.");
156
157 Ptr<Ipv6> ipv6_client2 = nonRouterNodes.Get(2)->GetObject<Ipv6>();
158 Ptr<Ipv6L3Protocol> l3_client2 = ipv6_client2->GetObject<Ipv6L3Protocol>();
159 int32_t ifIndex_client2 = ipv6_client2->GetInterfaceForDevice(nonRouterDevices.Get(2));
160 NS_TEST_ASSERT_MSG_EQ(l3_client2->GetNAddresses(ifIndex_client2),
161 3,
162 "Incorrect number of addresses.");
163
165}
166
167/**
168 * @ingroup dhcp6-test
169 * @ingroup tests
170 *
171 * @brief DHCPv6 DUID tests
172 */
174{
175 public:
177 ~Dhcp6DuidTestCase() override;
178
179 private:
180 void DoRun() override;
181};
182
184 : TestCase("Dhcp6 DUID test case ")
185{
186}
187
191
192void
194{
196 nodes.Create(2);
197
198 SimpleNetDeviceHelper simpleNetDevice;
199 simpleNetDevice.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
200 simpleNetDevice.SetDeviceAttribute("DataRate", DataRateValue(DataRate("5Mbps")));
201 NetDeviceContainer devices = simpleNetDevice.Install(nodes);
202
203 InternetStackHelper internetv6;
204 internetv6.Install(nodes);
205
207 ipv6.SetBase(Ipv6Address("2001:cafe::"), Ipv6Prefix(64));
209
210 Dhcp6Helper dhcp6Helper;
211 ApplicationContainer dhcpClients = dhcp6Helper.InstallDhcp6Client(nodes);
212
213 // DUID-LL
214 {
215 Duid duidTest;
216 duidTest.InitializeLL(nodes.Get(1));
217 std::ostringstream buffer;
218 buffer << duidTest;
219 NS_TEST_ASSERT_MSG_EQ(duidTest.GetSerializedSize(), 10, "Unexpected DUID-LL length.");
220 std::string reference{"DUID-LL HWtype: 1 Identifier: 0x000000000002"};
221 NS_TEST_ASSERT_MSG_EQ(buffer.str(), reference, "Unexpected DUID-LL.");
222 }
223
224 // DUID-LLT
225 {
226 Duid duidTest;
227 duidTest.InitializeLLT(nodes.Get(1));
228 std::ostringstream buffer;
229 buffer << duidTest;
230 NS_TEST_ASSERT_MSG_EQ(duidTest.GetSerializedSize(), 14, "Unexpected DUID-LLT length.");
231 std::string reference{"DUID-LLT HWtype: 1 Time: 0 Identifier: 0x000000000002"};
232 NS_TEST_ASSERT_MSG_EQ(buffer.str(), reference, "Unexpected DUID-LLT.");
233 }
234
235 // DUID-EN
236 {
237 Duid duidTest;
238 std::vector<uint8_t> identifier(32);
239 std::iota(identifier.begin(), identifier.end(), 0);
240
241 duidTest.InitializeEN(0xf00dcafe, identifier);
242 std::ostringstream buffer;
243 buffer << duidTest;
244 NS_TEST_ASSERT_MSG_EQ(duidTest.GetSerializedSize(), 38, "Unexpected DUID-EN length.");
245 std::string reference{"DUID-EN EnNumber: 0xf00dcafe Identifier: "
246 "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"};
247 NS_TEST_ASSERT_MSG_EQ(buffer.str(), reference, "Unexpected DUID-EN.");
248 }
249
250 // DUID-UUID
251 {
252 Duid duidTest;
253 std::vector<uint8_t> identifier(16);
254 std::iota(identifier.begin(), identifier.end(), 0);
255
256 duidTest.InitializeUUID(identifier);
257 std::ostringstream buffer;
258 buffer << duidTest;
259 NS_TEST_ASSERT_MSG_EQ(duidTest.GetSerializedSize(), 18, "Unexpected DUID-UUID length.");
260 std::string reference{"DUID-UUID UUID: 0x000102030405060708090a0b0c0d0e0f"};
261 NS_TEST_ASSERT_MSG_EQ(buffer.str(), reference, "Unexpected DUID-UUID.");
262 }
263
265}
266
267/**
268 * @ingroup dhcp6-test
269 * @ingroup tests
270 *
271 * @brief DHCPv6 TestSuite
272 */
274{
275 public:
277};
278
285
286static Dhcp6TestSuite dhcp6TestSuite; //!< Static variable for test initialization
DHCPv6 DUID tests.
~Dhcp6DuidTestCase() override
void DoRun() override
Implementation to actually run this TestCase.
DHCPv6 header tests.
Definition dhcp6-test.cc:34
void DoRun() override
Implementation to actually run this TestCase.
Definition dhcp6-test.cc:72
~Dhcp6TestCase() override
Definition dhcp6-test.cc:56
Ipv6Address m_leasedAddress[2]
Address given to the nodes.
Definition dhcp6-test.cc:48
void LeaseObtained(std::string context, const Ipv6Address &newAddress)
Triggered by an address lease on a client.
Definition dhcp6-test.cc:61
DHCPv6 TestSuite.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
Class for representing data rates.
Definition data-rate.h:78
AttributeValue implementation for DataRate.
Definition data-rate.h:252
The helper class used to configure and install DHCPv6 applications on nodes.
void SetServerAttribute(std::string name, const AttributeValue &value)
Set DHCPv6 server attributes.
ApplicationContainer InstallDhcp6Client(NodeContainer clientNodes) const
Install DHCPv6 client on a set of nodes.
ApplicationContainer InstallDhcp6Server(NetDeviceContainer netDevices)
Install DHCPv6 server on a node / NetDevice.
Implements the unique identifier for DHCPv6.
Definition dhcp6-duid.h:27
void InitializeLL(Ptr< Node > node)
Initialize the DUID-LL for a client or server.
Definition dhcp6-duid.cc:53
void InitializeEN(uint32_t enNumber, const std::vector< uint8_t > &identifier)
Initialize the DUID-EN for a client or server.
void InitializeUUID(const std::vector< uint8_t > &uuid)
Initialize the DUID-EN for a client or server.
uint32_t GetSerializedSize() const
Get the DUID serialized size.
void InitializeLLT(Ptr< Node > node)
Initialize the DUID-LLT for a client or server.
Definition dhcp6-duid.cc:74
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Helper class to auto-assign global IPv6 unicast addresses.
Ipv6InterfaceContainer AssignWithoutAddress(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer but do not assign any IPv6 addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Describes an IPv6 address.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
Keep track of a set of IPv6 interfaces.
void SetForwarding(uint32_t i, bool state)
Set the state of the stack (act as a router or as an host) for the specified index.
uint32_t GetInterfaceIndex(uint32_t i) const
Get the interface index for the specified node index.
IPv6 layer implementation.
Describes an IPv6 prefix.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:518
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
Radvd application helper.
void AddAnnouncedPrefix(uint32_t interface, const Ipv6Address &prefix, uint32_t prefixLength, bool slaac=true)
Add a new prefix to be announced through an interface.
Ptr< RadvdInterface > GetRadvdInterface(uint32_t interface)
Get the low-level RadvdInterface specification for an interface.
build a set of SimpleNetDevice objects
void SetChannelAttribute(std::string n1, const AttributeValue &v1)
void SetDeviceAttribute(std::string n1, const AttributeValue &v1)
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
Hold variables of type string.
Definition string.h:45
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
AttributeValue implementation for Time.
Definition nstime.h:1375
static Dhcp6TestSuite dhcp6TestSuite
Static variable for test initialization.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:690
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:133
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1290
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605