A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-raw-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Hajime Tazaki
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Hajime Tazaki <tazaki@sfc.wide.ad.jp>
7 */
8/*
9 * This is the test code for ipv4-raw-socket-impl.cc.
10 */
11
12#include "ns3/arp-l3-protocol.h"
13#include "ns3/boolean.h"
14#include "ns3/core-module.h"
15#include "ns3/error-model.h"
16#include "ns3/icmpv4-l4-protocol.h"
17#include "ns3/inet-socket-address.h"
18#include "ns3/internet-stack-helper.h"
19#include "ns3/ipv4-address-helper.h"
20#include "ns3/ipv4-global-routing-helper.h"
21#include "ns3/ipv4-l3-protocol.h"
22#include "ns3/ipv4-list-routing.h"
23#include "ns3/ipv4-raw-socket-factory.h"
24#include "ns3/ipv4-static-routing.h"
25#include "ns3/log.h"
26#include "ns3/node.h"
27#include "ns3/point-to-point-helper.h"
28#include "ns3/simple-channel.h"
29#include "ns3/simple-net-device-helper.h"
30#include "ns3/simple-net-device.h"
31#include "ns3/simulator.h"
32#include "ns3/socket-factory.h"
33#include "ns3/socket.h"
34#include "ns3/test.h"
35#ifdef __WIN32__
36#include "ns3/win32-internet.h"
37#else
38#include <netinet/in.h>
39#include <sys/socket.h>
40#endif
41
42#include <limits>
43#include <string>
44#include <sys/types.h>
45
46using namespace ns3;
47
48NS_LOG_COMPONENT_DEFINE("ipv4-raw-fragmentation-test");
49
50/**
51 * @ingroup internet-test
52 *
53 * @brief IPv4 Raw Socket Fragmentation Test
54 * Configuration : Two sockets. 1 sender, 1 receiver
55 * Sender socket sends packets in two epochs.
56 * In the first epoch, it sends payload of sizes {500, 1000, 5000, 10000,
57 * 20000, 40000, 60000}.
58 * In the second epoch, it sends payload of sizes {5000, 10000, 20000,
59 * 40000, 60000}. These are payloads of size greater than the MTU of
60 * the link.
61 * In the first epoch, there is no loss model.
62 * In the second epoch, the second fragment of the packet sent is dropped.
63 *
64 * Expected behaviour: In the first epoch: Receiver should receive only 1 packet and the size of
65 * the payload received should be equal to the size of the payload sent.
66 * No packets should have been dropped.
67 * In the second epoch: Receiver should not receive any packet. Only 1 packet
68 * should have been dropped at the physical layer.
69 */
71{
72 public:
74 void DoRun() override;
75
76 private:
77 /**
78 * @brief Send data to the receiver
79 * @param s The sending socket.
80 * @param sz Size of the packet.
81 */
83
84 /**
85 * @brief Receive callback
86 * @param s The receiving socket.
87 */
88 void RxCallback(Ptr<Socket> s);
89
90 /**
91 * @brief Packet dropped callback at Phy Rx.
92 * @param p Dropped packet.
93 */
95
96 uint32_t m_rxCount{0}; //!< Received packet count
97 uint32_t m_rxPayloadSize{0}; //!< Received packet size
98 uint32_t m_droppedFragments{0}; //!< Number of dropped fragments
99};
100
102 : TestCase("IPv4 raw fragmentation, fragment‑loss test")
103{
104}
105
106void
108{
109 Ptr<Packet> p = s->Recv();
110 Ipv4Header h;
111 if (p->PeekHeader(h))
112 {
113 p->RemoveHeader(h);
114 }
115 m_rxCount++;
116 m_rxPayloadSize = p->GetSize();
117 NS_LOG_DEBUG("Receiver got " << m_rxPayloadSize << " bytes");
118}
119
120void
125
126void
128{
129 Address realTo = InetSocketAddress(Ipv4Address("10.0.1.1"), 0);
130 Ptr<Packet> p = Create<Packet>(size);
131 socket->SendTo(p, 0, realTo);
132 NS_LOG_DEBUG("Sender sent " << p->GetSize() << " bytes to 10.0.1.1");
133}
134
135void
137{
138 Ptr<Node> rxNode = CreateObject<Node>();
139 Ptr<Node> txNode = CreateObject<Node>();
140
141 NodeContainer nodes(rxNode, txNode);
142
143 SimpleNetDeviceHelper helperChannel;
144 helperChannel.SetNetDevicePointToPointMode(true);
145 NetDeviceContainer net = helperChannel.Install(nodes);
146
147 net.Get(1)->SetMtu(1000);
148
149 InternetStackHelper internet;
150 internet.Install(nodes);
151
152 Ptr<Ipv4> ipv4;
153 uint32_t netdev_idx;
154 Ipv4InterfaceAddress ipv4Addr;
155
156 ipv4 = rxNode->GetObject<Ipv4>();
157 netdev_idx = ipv4->AddInterface(net.Get(0));
158 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.1.1"), Ipv4Mask(0xffff0000U));
159 ipv4->AddAddress(netdev_idx, ipv4Addr);
160 ipv4->SetUp(netdev_idx);
161
162 ipv4 = txNode->GetObject<Ipv4>();
163 netdev_idx = ipv4->AddInterface(net.Get(1));
164 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.1.2"), Ipv4Mask(0xffff0000U));
165 ipv4->AddAddress(netdev_idx, ipv4Addr);
166 ipv4->SetUp(netdev_idx);
167
168 net.Get(0)->TraceConnectWithoutContext(
169 "PhyRxDrop",
171
172 Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<Ipv4RawSocketFactory>();
173 Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket();
174 rxSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 0));
175 rxSocket->SetRecvCallback(MakeCallback(&Ipv4RawFragmentationTest::RxCallback, this));
176
177 Ptr<SocketFactory> txSocketFactory = txNode->GetObject<Ipv4RawSocketFactory>();
178 Ptr<Socket> txSocket = txSocketFactory->CreateSocket();
179
180 // Contains both Fragmentable and Non-fragmentable payload sizes
181 std::vector<uint32_t> payloadSizes = {500, 1000, 5000, 10000, 20000, 40000, 60000};
182
183 for (auto sentPayloadSize : payloadSizes)
184 {
185 m_rxCount = 0;
187 m_rxPayloadSize = 0;
190 this,
191 txSocket,
192 sentPayloadSize);
194
195 NS_TEST_EXPECT_MSG_EQ(m_rxCount, 1, "Packet should be reassembled and be delivered");
197 sentPayloadSize,
198 "Reassembled payload size must match the payload size sent");
199 NS_TEST_EXPECT_MSG_EQ(m_droppedFragments, 0, "No fragment must have been dropped");
200 }
201
202 std::vector<uint32_t> fragmentablePayloadSizes = {5000, 10000, 20000, 40000, 60000};
203
204 for (auto sentPayloadSize : fragmentablePayloadSizes)
205 {
206 m_rxCount = 0;
209 errModel->SetList({1});
210
211 net.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue(errModel));
212
215 this,
216 txSocket,
217 sentPayloadSize);
219
220 NS_TEST_EXPECT_MSG_EQ(m_rxCount, 0, "Packet must not have been delivered");
221
222 NS_TEST_EXPECT_MSG_EQ(m_droppedFragments, 1, "One fragment must have been dropped");
223 }
225}
226
227/**
228 * @ingroup internet-test
229 *
230 * @brief IPv4 RAW Socket Test
231 */
233{
234 Ptr<Packet> m_receivedPacket; //!< Received packet (1).
235 Ptr<Packet> m_receivedPacket2; //!< Received packet (2).
236
237 /**
238 * @brief Send data.
239 * @param socket The sending socket.
240 * @param to Destination address.
241 */
242 void DoSendData(Ptr<Socket> socket, std::string to);
243 /**
244 * @brief Send data.
245 * @param socket The sending socket.
246 * @param to Destination address.
247 */
248 void SendData(Ptr<Socket> socket, std::string to);
249 /**
250 * @brief Send data.
251 * @param socket The sending socket.
252 * @param to Destination address.
253 */
254 void DoSendData_IpHdr(Ptr<Socket> socket, std::string to);
255 /**
256 * @brief Send data.
257 * @param socket The sending socket.
258 * @param to Destination address.
259 */
260 void SendData_IpHdr(Ptr<Socket> socket, std::string to);
261
262 public:
263 void DoRun() override;
265
266 /**
267 * @brief Receive data.
268 * @param socket The receiving socket.
269 * @param packet The received packet.
270 * @param from The sender.
271 */
272 void ReceivePacket(Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
273 /**
274 * @brief Receive data.
275 * @param socket The receiving socket.
276 * @param packet The received packet.
277 * @param from The sender.
278 */
279 void ReceivePacket2(Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
280 /**
281 * @brief Receive data.
282 * @param socket The receiving socket.
283 */
284 void ReceivePkt(Ptr<Socket> socket);
285 /**
286 * @brief Receive data.
287 * @param socket The receiving socket.
288 */
289 void ReceivePkt2(Ptr<Socket> socket);
290};
291
293 : TestCase("IPv4 Raw socket implementation")
294{
295}
296
297void
299{
300 m_receivedPacket = packet;
301}
302
303void
305{
306 m_receivedPacket2 = packet;
307}
308
309void
311{
312 uint32_t availableData;
313 availableData = socket->GetRxAvailable();
314 m_receivedPacket = socket->Recv(2, MSG_PEEK);
315 NS_TEST_ASSERT_MSG_EQ(m_receivedPacket->GetSize(), 2, "ReceivedPacket size is not equal to 2");
316 m_receivedPacket = socket->Recv(std::numeric_limits<uint32_t>::max(), 0);
317 NS_TEST_ASSERT_MSG_EQ(availableData,
319 "Received packet size is not equal to Rx buffer size");
320}
321
322void
324{
325 uint32_t availableData;
326 availableData = socket->GetRxAvailable();
327 m_receivedPacket2 = socket->Recv(2, MSG_PEEK);
328 NS_TEST_ASSERT_MSG_EQ(m_receivedPacket2->GetSize(), 2, "ReceivedPacket size is not equal to 2");
329 m_receivedPacket2 = socket->Recv(std::numeric_limits<uint32_t>::max(), 0);
330 NS_TEST_ASSERT_MSG_EQ(availableData,
332 "Received packet size is not equal to Rx buffer size");
333}
334
335void
337{
338 Address realTo = InetSocketAddress(Ipv4Address(to.c_str()), 0);
339 NS_TEST_EXPECT_MSG_EQ(socket->SendTo(Create<Packet>(123), 0, realTo), 123, to);
340}
341
342void
344{
347 Simulator::ScheduleWithContext(socket->GetNode()->GetId(),
348 Seconds(0),
350 this,
351 socket,
352 to);
354}
355
356void
358{
359 Address realTo = InetSocketAddress(Ipv4Address(to.c_str()), 0);
360 socket->SetAttribute("IpHeaderInclude", BooleanValue(true));
362 Ipv4Header ipHeader;
363 ipHeader.SetSource(Ipv4Address("10.0.0.2"));
364 ipHeader.SetDestination(Ipv4Address(to.c_str()));
365 ipHeader.SetProtocol(0);
366 ipHeader.SetPayloadSize(p->GetSize());
367 ipHeader.SetTtl(255);
368 p->AddHeader(ipHeader);
369
370 NS_TEST_EXPECT_MSG_EQ(socket->SendTo(p, 0, realTo), 143, to);
371 socket->SetAttribute("IpHeaderInclude", BooleanValue(false));
372}
373
374void
376{
379 Simulator::ScheduleWithContext(socket->GetNode()->GetId(),
380 Seconds(0),
382 this,
383 socket,
384 to);
386}
387
388void
390{
391 // Create topology
392
393 // Receiver Node
394 Ptr<Node> rxNode = CreateObject<Node>();
395 // Sender Node
396 Ptr<Node> txNode = CreateObject<Node>();
397
398 NodeContainer nodes(rxNode, txNode);
399
400 SimpleNetDeviceHelper helperChannel1;
401 helperChannel1.SetNetDevicePointToPointMode(true);
402 NetDeviceContainer net1 = helperChannel1.Install(nodes);
403
404 SimpleNetDeviceHelper helperChannel2;
405 helperChannel2.SetNetDevicePointToPointMode(true);
406 NetDeviceContainer net2 = helperChannel2.Install(nodes);
407
408 InternetStackHelper internet;
409 internet.Install(nodes);
410
411 Ptr<Ipv4> ipv4;
412 uint32_t netdev_idx;
413 Ipv4InterfaceAddress ipv4Addr;
414
415 // Receiver Node
416 ipv4 = rxNode->GetObject<Ipv4>();
417 netdev_idx = ipv4->AddInterface(net1.Get(0));
418 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.0.1"), Ipv4Mask(0xffff0000U));
419 ipv4->AddAddress(netdev_idx, ipv4Addr);
420 ipv4->SetUp(netdev_idx);
421
422 netdev_idx = ipv4->AddInterface(net2.Get(0));
423 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.1.1"), Ipv4Mask(0xffff0000U));
424 ipv4->AddAddress(netdev_idx, ipv4Addr);
425 ipv4->SetUp(netdev_idx);
426
427 // Sender Node
428 ipv4 = txNode->GetObject<Ipv4>();
429 netdev_idx = ipv4->AddInterface(net1.Get(1));
430 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.0.2"), Ipv4Mask(0xffff0000U));
431 ipv4->AddAddress(netdev_idx, ipv4Addr);
432 ipv4->SetUp(netdev_idx);
433
434 netdev_idx = ipv4->AddInterface(net2.Get(1));
435 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.1.2"), Ipv4Mask(0xffff0000U));
436 ipv4->AddAddress(netdev_idx, ipv4Addr);
437 ipv4->SetUp(netdev_idx);
438
439 // Create the IPv4 Raw sockets
440 Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<Ipv4RawSocketFactory>();
441 Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket();
442 NS_TEST_EXPECT_MSG_EQ(rxSocket->Bind(InetSocketAddress(Ipv4Address("0.0.0.0"), 0)),
443 0,
444 "trivial");
445 rxSocket->SetRecvCallback(MakeCallback(&Ipv4RawSocketImplTest::ReceivePkt, this));
446
447 Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket();
448 rxSocket2->SetRecvCallback(MakeCallback(&Ipv4RawSocketImplTest::ReceivePkt2, this));
449 NS_TEST_EXPECT_MSG_EQ(rxSocket2->Bind(InetSocketAddress(Ipv4Address("10.0.1.1"), 0)),
450 0,
451 "trivial");
452
453 Ptr<SocketFactory> txSocketFactory = txNode->GetObject<Ipv4RawSocketFactory>();
454 Ptr<Socket> txSocket = txSocketFactory->CreateSocket();
455
456 // ------ Now the tests ------------
457
458 // Unicast test
459 SendData(txSocket, "10.0.0.1");
460 NS_TEST_EXPECT_MSG_EQ(m_receivedPacket->GetSize(), 143, "recv: 10.0.0.1");
462 0,
463 "second interface should not receive it");
464
467
468 // Unicast w/ header test
469 SendData_IpHdr(txSocket, "10.0.0.1");
470 NS_TEST_EXPECT_MSG_EQ(m_receivedPacket->GetSize(), 143, "recv(hdrincl): 10.0.0.1");
472 0,
473 "second interface should not receive it");
474
477
478#if 0
479 // Simple broadcast test
480
481 SendData (txSocket, "255.255.255.255");
482 NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 143, "recv: 255.255.255.255");
483 NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second socket should not receive it (it is bound specifically to the second interface's address");
484
487#endif
488
489 // Simple Link-local multicast test
490
491 txSocket->Bind(InetSocketAddress(Ipv4Address("10.0.0.2"), 0));
492 SendData(txSocket, "224.0.0.9");
493 NS_TEST_EXPECT_MSG_EQ(m_receivedPacket->GetSize(), 143, "recv: 224.0.0.9");
495 0,
496 "second socket should not receive it (it is bound specifically to the "
497 "second interface's address");
498
501
502#if 0
503 // Broadcast test with multiple receiving sockets
504
505 // When receiving broadcast packets, all sockets sockets bound to
506 // the address/port should receive a copy of the same packet -- if
507 // the socket address matches.
508 rxSocket2->Dispose ();
509 rxSocket2 = rxSocketFactory->CreateSocket ();
510 rxSocket2->SetRecvCallback (MakeCallback (&Ipv4RawSocketImplTest::ReceivePkt2, this));
511 NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 0)), 0, "trivial");
512
513 SendData (txSocket, "255.255.255.255");
514 NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 143, "recv: 255.255.255.255");
515 NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 143, "recv: 255.255.255.255");
516#endif
517
518 m_receivedPacket = nullptr;
519 m_receivedPacket2 = nullptr;
520
521 // Simple getpeername tests
522
523 Address peerAddress;
524 int err = txSocket->GetPeerName(peerAddress);
525 NS_TEST_EXPECT_MSG_EQ(err, -1, "socket GetPeerName() should fail when socket is not connected");
526 NS_TEST_EXPECT_MSG_EQ(txSocket->GetErrno(),
528 "socket error code should be ERROR_NOTCONN");
529
530 InetSocketAddress peer("10.0.0.1", 1234);
531 err = txSocket->Connect(peer);
532 NS_TEST_EXPECT_MSG_EQ(err, 0, "socket Connect() should succeed");
533
534 err = txSocket->GetPeerName(peerAddress);
535 NS_TEST_EXPECT_MSG_EQ(err, 0, "socket GetPeerName() should succeed when socket is connected");
536 peer.SetPort(0);
537 NS_TEST_EXPECT_MSG_EQ(peerAddress,
538 peer,
539 "address from socket GetPeerName() should equal the connected address");
540
542}
543
544/**
545 * @ingroup internet-test
546 *
547 * @brief IPv4 RAW Socket TestSuite
548 */
550{
551 public:
553 : TestSuite("ipv4-raw", Type::UNIT)
554 {
555 AddTestCase(new Ipv4RawSocketImplTest, TestCase::Duration::QUICK);
556 AddTestCase(new Ipv4RawFragmentationTest, TestCase::Duration::QUICK);
557 }
558};
559
560static Ipv4RawTestSuite g_ipv4rawTestSuite; //!< Static variable for test initialization
IPv4 Raw Socket Fragmentation Test Configuration : Two sockets.
uint32_t m_droppedFragments
Number of dropped fragments.
void DoRun() override
Implementation to actually run this TestCase.
void RxCallback(Ptr< Socket > s)
Receive callback.
uint32_t m_rxCount
Received packet count.
uint32_t m_rxPayloadSize
Received packet size.
void SendPacket(Ptr< Socket > s, uint32_t sz)
Send data to the receiver.
void PhyRxDropCallback(Ptr< const Packet > p)
Packet dropped callback at Phy Rx.
IPv4 RAW Socket Test.
void SendData_IpHdr(Ptr< Socket > socket, std::string to)
Send data.
void ReceivePkt(Ptr< Socket > socket)
Receive data.
Ptr< Packet > m_receivedPacket
Received packet (1).
void DoRun() override
Implementation to actually run this TestCase.
Ptr< Packet > m_receivedPacket2
Received packet (2).
void SendData(Ptr< Socket > socket, std::string to)
Send data.
void DoSendData(Ptr< Socket > socket, std::string to)
Send data.
void DoSendData_IpHdr(Ptr< Socket > socket, std::string to)
Send data.
void ReceivePacket2(Ptr< Socket > socket, Ptr< Packet > packet, const Address &from)
Receive data.
void ReceivePkt2(Ptr< Socket > socket)
Receive data.
void ReceivePacket(Ptr< Socket > socket, Ptr< Packet > packet, const Address &from)
Receive data.
IPv4 RAW Socket TestSuite.
a polymophic address class
Definition address.h:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
an Inet address class
void SetPort(uint16_t port)
aggregate IP/TCP/UDP functionality to existing Nodes.
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetAny()
Packet header for IPv4.
Definition ipv4-header.h:23
void SetDestination(Ipv4Address destination)
void SetPayloadSize(uint16_t size)
void SetTtl(uint8_t ttl)
void SetProtocol(uint8_t num)
void SetSource(Ipv4Address source)
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
API to create RAW socket instances.
holds a vector of ns3::NetDevice pointers
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.
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
void RemoveAllByteTags()
Remove all byte tags stored in this packet.
Definition packet.cc:382
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
build a set of SimpleNetDevice objects
void SetNetDevicePointToPointMode(bool pointToPointMode)
SimpleNetDevice is Broadcast capable and ARP needing.
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:578
static void Run()
Run the simulation.
Definition simulator.cc:167
@ ERROR_NOTCONN
Definition socket.h:76
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
static constexpr auto UNIT
Definition test.h:1291
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:439
#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:134
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
static Ipv4RawTestSuite g_ipv4rawTestSuite
Static variable for test initialization.
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:684