A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-fragmentation-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Universita' di Firenze, Italy
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
18 */
19/**
20 * This is the test code for ipv4-l3protocol.cc (only the fragmentation and reassembly part).
21 */
22
23#include "ns3/arp-l3-protocol.h"
24#include "ns3/boolean.h"
25#include "ns3/config.h"
26#include "ns3/error-channel.h"
27#include "ns3/icmpv4-l4-protocol.h"
28#include "ns3/inet-socket-address.h"
29#include "ns3/internet-stack-helper.h"
30#include "ns3/ipv4-l3-protocol.h"
31#include "ns3/ipv4-list-routing.h"
32#include "ns3/ipv4-raw-socket-factory.h"
33#include "ns3/ipv4-static-routing.h"
34#include "ns3/log.h"
35#include "ns3/node.h"
36#include "ns3/simple-net-device-helper.h"
37#include "ns3/simple-net-device.h"
38#include "ns3/simulator.h"
39#include "ns3/socket-factory.h"
40#include "ns3/socket.h"
41#include "ns3/test.h"
42#include "ns3/udp-l4-protocol.h"
43#include "ns3/udp-socket-factory.h"
44#include "ns3/udp-socket.h"
45#include "ns3/uinteger.h"
46
47#ifdef __WIN32__
48#include "ns3/win32-internet.h"
49#else
50#include <netinet/in.h>
51#endif
52
53#include <limits>
54#include <string>
55
56using namespace ns3;
57
58class UdpSocketImpl;
59
60/**
61 * \ingroup internet-test
62 *
63 * \brief Tag used in IPv4 Fragmentation Test
64 */
65class IPv4TestTag : public Tag
66{
67 private:
68 uint64_t token; //!< Token carried by the tag.
69 public:
70 /**
71 * \brief Get the type ID.
72 * \return the object TypeId
73 */
75 {
76 static TypeId tid =
77 TypeId("ns3::IPv4TestTag").SetParent<Tag>().AddConstructor<IPv4TestTag>();
78 return tid;
79 }
80
81 TypeId GetInstanceTypeId() const override
82 {
83 return GetTypeId();
84 }
85
86 uint32_t GetSerializedSize() const override
87 {
88 return sizeof(token);
89 }
90
91 void Serialize(TagBuffer buffer) const override
92 {
93 buffer.WriteU64(token);
94 }
95
96 void Deserialize(TagBuffer buffer) override
97 {
98 token = buffer.ReadU64();
99 }
100
101 void Print(std::ostream& os) const override
102 {
103 os << "token=" << token;
104 }
105
106 /**
107 * \brief Set the token.
108 * \param token The token.
109 */
110 void SetToken(uint64_t token)
111 {
112 this->token = token;
113 }
114
115 /**
116 * \brief Get the token.
117 * \returns The token.
118 */
119 uint64_t GetToken() const
120 {
121 return token;
122 }
123};
124
125/**
126 * \ingroup internet-test
127 *
128 * \brief IPv4 Fragmentation Test
129 */
131{
132 Ptr<Packet> m_sentPacketClient; //!< Packet sent by client.
133 Ptr<Packet> m_receivedPacketClient; //!< Packet received by client.
134 Ptr<Packet> m_receivedPacketServer; //!< Packet received by server.
135
136 Ptr<Socket> m_socketServer; //!< Server socket.
137 Ptr<Socket> m_socketClient; //!< Client socket.
138 uint32_t m_dataSize; //!< Data size.
139 uint8_t* m_data; //!< Data.
140 uint32_t m_size; //!< packet size.
141 uint8_t m_icmpType; //!< ICMP type.
142 bool m_broadcast; //!< broadcast packets
143
144 public:
145 void DoRun() override;
146 /**
147 * Constructor
148 * \param broadcast send broadcast packets (true) or unicast packets (false)
149 */
150 Ipv4FragmentationTest(bool broadcast);
151 ~Ipv4FragmentationTest() override;
152
153 // server part
154
155 /**
156 * \brief Start the server.
157 * \param ServerNode The server.
158 */
159 void StartServer(Ptr<Node> ServerNode);
160 /**
161 * \brief Handle incoming packets.
162 * \param socket The receiving socket.
163 */
164 void HandleReadServer(Ptr<Socket> socket);
165
166 // client part
167
168 /**
169 * \brief Start the client.
170 * \param ClientNode The client.
171 */
172 void StartClient(Ptr<Node> ClientNode);
173 /**
174 * \brief Handle incoming packets.
175 * \param socket The receiving socket.
176 */
177 void HandleReadClient(Ptr<Socket> socket);
178 /**
179 * \brief Handle incoming ICMP packets.
180 * \param icmpSource The ICMP sender.
181 * \param icmpTtl The ICMP TTL.
182 * \param icmpType The ICMP Type.
183 * \param icmpCode The ICMP Code.
184 * \param icmpInfo The ICMP Info.
185 */
186 void HandleReadIcmpClient(Ipv4Address icmpSource,
187 uint8_t icmpTtl,
188 uint8_t icmpType,
189 uint8_t icmpCode,
190 uint32_t icmpInfo);
191
192 /**
193 * \brief Set the packet fill.
194 * \param fill The fill.
195 * \param fillSize The fill size.
196 * \param dataSize The packet size.
197 */
198 void SetFill(uint8_t* fill, uint32_t fillSize, uint32_t dataSize);
199
200 /**
201 * \brief Send a packet.
202 * \returns The sent packet.
203 */
205};
206
208 : TestCase(std::string("Verify the IPv4 layer 3 protocol fragmentation and reassembly: ") +
209 (broadcast ? "broadcast" : "unicast"))
210{
211 m_socketServer = nullptr;
212 m_data = nullptr;
213 m_dataSize = 0;
214 m_size = 0;
215 m_icmpType = 0;
216 m_broadcast = broadcast;
217}
218
220{
221 if (m_data)
222 {
223 delete[] m_data;
224 }
225 m_data = nullptr;
226 m_dataSize = 0;
227}
228
229void
231{
232 if (!m_socketServer)
233 {
234 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
235 m_socketServer = Socket::CreateSocket(ServerNode, tid);
237 m_socketServer->Bind(local);
238 Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket>(m_socketServer);
239 if (udpSocket)
240 {
241 // equivalent to setsockopt (MCAST_JOIN_GROUP)
242 udpSocket->MulticastJoinGroup(0, Ipv4Address("10.0.0.1"));
243 }
244 }
245
247}
248
249void
251{
252 Ptr<Packet> packet;
253 Address from;
254 while ((packet = socket->RecvFrom(from)))
255 {
257 {
258 m_receivedPacketServer = packet->Copy();
259 }
260 }
261}
262
263void
265{
266 if (!m_socketClient)
267 {
268 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
269 m_socketClient = Socket::CreateSocket(ClientNode, tid);
273 m_socketClient->SetAttribute("IcmpCallback", cbValue);
275 }
276
278}
279
280void
282{
283 Ptr<Packet> packet;
284 Address from;
285 while ((packet = socket->RecvFrom(from)))
286 {
288 {
289 m_receivedPacketClient = packet->Copy();
290 }
291 }
292}
293
294void
296 uint8_t icmpTtl,
297 uint8_t icmpType,
298 uint8_t icmpCode,
299 uint32_t icmpInfo)
300{
301 m_icmpType = icmpType;
302}
303
304void
305Ipv4FragmentationTest::SetFill(uint8_t* fill, uint32_t fillSize, uint32_t dataSize)
306{
307 if (dataSize != m_dataSize)
308 {
309 delete[] m_data;
310 m_data = new uint8_t[dataSize];
311 m_dataSize = dataSize;
312 }
313
314 if (fillSize >= dataSize)
315 {
316 memcpy(m_data, fill, dataSize);
317 return;
318 }
319
320 uint32_t filled = 0;
321 while (filled + fillSize < dataSize)
322 {
323 memcpy(&m_data[filled], fill, fillSize);
324 filled += fillSize;
325 }
326
327 memcpy(&m_data[filled], fill, dataSize - filled);
328
329 m_size = dataSize;
330}
331
334{
335 Ptr<Packet> p;
336 if (m_dataSize)
337 {
338 p = Create<Packet>(m_data, m_dataSize);
339 }
340 else
341 {
342 p = Create<Packet>(m_size);
343 }
344 IPv4TestTag tag;
345 tag.SetToken(42);
346 p->AddPacketTag(tag);
347 p->AddByteTag(tag);
348
349 if (m_broadcast)
350 {
351 Address address;
352 m_socketClient->GetPeerName(address);
355 m_socketClient->SendTo(p, 0, saddress);
356 }
357 else
358 {
360 }
361
362 return p;
363}
364
365void
367{
368 // set the arp cache to something quite high
369 // we shouldn't need because the NetDevice used doesn't need arp, but still
370 Config::SetDefault("ns3::ArpCache::PendingQueueSize", UintegerValue(100));
371
372 // Create topology
373
374 // Receiver Node
375 Ptr<Node> serverNode = CreateObject<Node>();
376 // Sender Node
377 Ptr<Node> clientNode = CreateObject<Node>();
378
379 NodeContainer nodes(serverNode, clientNode);
380
381 Ptr<ErrorChannel> channel = CreateObject<ErrorChannel>();
382 channel->SetJumpingTime(Seconds(0.5));
383
384 SimpleNetDeviceHelper helperChannel;
385 helperChannel.SetNetDevicePointToPointMode(true);
386 NetDeviceContainer net = helperChannel.Install(nodes, channel);
387
388 InternetStackHelper internet;
389 internet.Install(nodes);
390
391 Ptr<Ipv4> ipv4;
392 uint32_t netdev_idx;
393 Ipv4InterfaceAddress ipv4Addr;
394
395 // Receiver Node
396 ipv4 = serverNode->GetObject<Ipv4>();
397 netdev_idx = ipv4->AddInterface(net.Get(0));
398 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.0.1"), Ipv4Mask(0xffff0000U));
399 ipv4->AddAddress(netdev_idx, ipv4Addr);
400 ipv4->SetUp(netdev_idx);
401 Ptr<BinaryErrorModel> serverDevErrorModel = CreateObject<BinaryErrorModel>();
402 Ptr<SimpleNetDevice> serverDev = DynamicCast<SimpleNetDevice>(net.Get(0));
403 serverDevErrorModel->Disable();
404 serverDev->SetMtu(1500);
405 serverDev->SetReceiveErrorModel(serverDevErrorModel);
406 StartServer(serverNode);
407
408 // Sender Node
409 ipv4 = clientNode->GetObject<Ipv4>();
410 netdev_idx = ipv4->AddInterface(net.Get(1));
411 ipv4Addr = Ipv4InterfaceAddress(Ipv4Address("10.0.0.2"), Ipv4Mask(0xffff0000U));
412 ipv4->AddAddress(netdev_idx, ipv4Addr);
413 ipv4->SetUp(netdev_idx);
414 Ptr<BinaryErrorModel> clientDevErrorModel = CreateObject<BinaryErrorModel>();
415 Ptr<SimpleNetDevice> clientDev = DynamicCast<SimpleNetDevice>(net.Get(1));
416 clientDevErrorModel->Disable();
417 clientDev->SetMtu(1500);
418 clientDev->SetReceiveErrorModel(clientDevErrorModel);
419 StartClient(clientNode);
420
421 // some small packets, some rather big ones
422 uint32_t packetSizes[5] = {1000, 2000, 5000, 10000, 65000};
423
424 // using the alphabet
425 uint8_t fillData[78];
426 for (uint32_t k = 48; k <= 125; k++)
427 {
428 fillData[k - 48] = k;
429 }
430
431 // First test: normal channel, no errors, no delays
432 for (int i = 0; i < 5; i++)
433 {
434 uint32_t packetSize = packetSizes[i];
435
436 SetFill(fillData, 78, packetSize);
437
438 m_receivedPacketServer = Create<Packet>();
440 Seconds(0),
442 this);
444
445 uint8_t recvBuffer[65000];
446
447 uint16_t recvSize = m_receivedPacketServer->GetSize();
448
449 NS_TEST_EXPECT_MSG_EQ(recvSize, packetSizes[i], "Packet size not correct");
450
451 m_receivedPacketServer->CopyData(recvBuffer, 65000);
453 0,
454 "Packet content differs");
455 }
456
457 // Second test: normal channel, no errors, delays each 2 packets.
458 // Each other fragment will arrive out-of-order.
459 // The packets should be received correctly since reassembly will reorder the fragments.
460 channel->SetJumpingMode(true);
461 for (int i = 0; i < 5; i++)
462 {
463 uint32_t packetSize = packetSizes[i];
464
465 SetFill(fillData, 78, packetSize);
466
467 m_receivedPacketServer = Create<Packet>();
469 Seconds(0),
471 this);
473
474 uint8_t recvBuffer[65000];
475
476 uint16_t recvSize = m_receivedPacketServer->GetSize();
477
478 NS_TEST_EXPECT_MSG_EQ(recvSize, packetSizes[i], "Packet size not correct");
479
480 m_receivedPacketServer->CopyData(recvBuffer, 65000);
482 0,
483 "Packet content differs");
484 }
485 channel->SetJumpingMode(false);
486
487 // Third test: normal channel, some errors, no delays.
488 // The reassembly procedure should fire a timeout after 30 seconds (as specified in the RFCs).
489 // Upon the timeout, the fragments received so far are discarded and an ICMP should be sent back
490 // to the sender (if the first fragment has been received).
491 // In this test case the first fragment is received, so we do expect an ICMP.
492 // Client -> Server : errors enabled
493 // Server -> Client : errors disabled (we want to have back the ICMP)
494 clientDevErrorModel->Disable();
495 serverDevErrorModel->Enable();
496 for (int i = 1; i < 5; i++)
497 {
498 uint32_t packetSize = packetSizes[i];
499
500 SetFill(fillData, 78, packetSize);
501
502 // reset the model, we want to receive the very first fragment.
503 serverDevErrorModel->Reset();
504
505 m_receivedPacketServer = Create<Packet>();
506 m_icmpType = 0;
508 Seconds(0),
510 this);
512
513 uint16_t recvSize = m_receivedPacketServer->GetSize();
514
515 NS_TEST_EXPECT_MSG_EQ((recvSize == 0), true, "Server got a packet, something wrong");
517 true,
518 "Client did not receive ICMP::TIME_EXCEEDED");
519 }
520
521 // Fourth test: normal channel, no errors, no delays.
522 // We check tags
523 clientDevErrorModel->Disable();
524 serverDevErrorModel->Disable();
525 for (int i = 0; i < 5; i++)
526 {
527 uint32_t packetSize = packetSizes[i];
528
529 SetFill(fillData, 78, packetSize);
530
531 m_receivedPacketServer = Create<Packet>();
533 Seconds(0),
535 this);
537
538 IPv4TestTag packetTag;
539 bool found = m_receivedPacketServer->PeekPacketTag(packetTag);
540
541 NS_TEST_EXPECT_MSG_EQ(found, true, "PacketTag not found");
542 NS_TEST_EXPECT_MSG_EQ(packetTag.GetToken(), 42, "PacketTag value not correct");
543
545
546 uint32_t end = 0;
547 uint32_t tagStart = 0;
548 uint32_t tagEnd = 0;
549 while (iter.HasNext())
550 {
551 ByteTagIterator::Item item = iter.Next();
553 "ns3::IPv4TestTag",
554 "ByteTag name not correct");
555 tagStart = item.GetStart();
556 tagEnd = item.GetEnd();
557 if (end == 0)
558 {
559 NS_TEST_EXPECT_MSG_EQ(tagStart, 0, "First ByteTag Start not correct");
560 }
561 if (end != 0)
562 {
563 NS_TEST_EXPECT_MSG_EQ(tagStart, end, "ByteTag End not correct");
564 }
565 end = tagEnd;
566 IPv4TestTag* byteTag = dynamic_cast<IPv4TestTag*>(item.GetTypeId().GetConstructor()());
567 NS_TEST_EXPECT_MSG_NE(byteTag, 0, "ByteTag not found");
568 item.GetTag(*byteTag);
569 NS_TEST_EXPECT_MSG_EQ(byteTag->GetToken(), 42, "ByteTag value not correct");
570 delete byteTag;
571 }
573 }
574
576}
577
578/**
579 * \ingroup internet-test
580 *
581 * \brief IPv4 Fragmentation TestSuite
582 */
584{
585 public:
587};
588
590 : TestSuite("ipv4-fragmentation", Type::UNIT)
591{
592 AddTestCase(new Ipv4FragmentationTest(false), TestCase::Duration::QUICK);
593 AddTestCase(new Ipv4FragmentationTest(true), TestCase::Duration::QUICK);
594}
595
597 g_ipv4fragmentationTestSuite; //!< Static variable for test initialization
Tag used in IPv4 Fragmentation Test.
static TypeId GetTypeId()
Get the type ID.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
uint32_t GetSerializedSize() const override
void SetToken(uint64_t token)
Set the token.
void Deserialize(TagBuffer buffer) override
uint64_t token
Token carried by the tag.
void Serialize(TagBuffer buffer) const override
uint64_t GetToken() const
Get the token.
void Print(std::ostream &os) const override
IPv4 Fragmentation Test.
Ptr< Packet > m_receivedPacketClient
Packet received by client.
Ptr< Packet > m_receivedPacketServer
Packet received by server.
Ptr< Packet > m_sentPacketClient
Packet sent by client.
Ptr< Packet > SendClient()
Send a packet.
Ptr< Socket > m_socketServer
Server socket.
void StartClient(Ptr< Node > ClientNode)
Start the client.
Ptr< Socket > m_socketClient
Client socket.
void StartServer(Ptr< Node > ServerNode)
Start the server.
void HandleReadIcmpClient(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Handle incoming ICMP packets.
void HandleReadClient(Ptr< Socket > socket)
Handle incoming packets.
Ipv4FragmentationTest(bool broadcast)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
void HandleReadServer(Ptr< Socket > socket)
Handle incoming packets.
void SetFill(uint8_t *fill, uint32_t fillSize, uint32_t dataSize)
Set the packet fill.
bool m_broadcast
broadcast packets
IPv4 Fragmentation TestSuite.
a polymophic address class
Definition: address.h:101
Identifies a byte tag and a set of bytes within a packet to which the tag applies.
Definition: packet.h:63
uint32_t GetEnd() const
The index is an offset from the start of the packet.
Definition: packet.cc:48
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition: packet.cc:54
uint32_t GetStart() const
The index is an offset from the start of the packet.
Definition: packet.cc:42
TypeId GetTypeId() const
Definition: packet.cc:36
Iterator over the set of byte tags in a packet.
Definition: packet.h:56
bool HasNext() const
Definition: packet.cc:72
AttributeValue implementation for Callback.
Definition: callback.h:808
an Inet address class
void SetIpv4(Ipv4Address address)
static bool IsMatchingType(const Address &address)
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
aggregate IP/TCP/UDP functionality to existing Nodes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetBroadcast()
static Ipv4Address GetAny()
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
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 GetId() const
Definition: node.cc:117
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:983
ByteTagIterator GetByteTagIterator() const
Returns an iterator over the set of byte tags included in this packet.
Definition: packet.cc:937
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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 void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:588
static void Run()
Run the simulation.
Definition: simulator.cc:178
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
virtual int GetPeerName(Address &address) const =0
Get the peer address of a connected socket.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual Ptr< Node > GetNode() const =0
Return the node this socket is associated with.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
read and write tag data
Definition: tag-buffer.h:52
void WriteU64(uint64_t v)
Definition: tag-buffer.cc:104
uint64_t ReadU64()
Definition: tag-buffer.cc:139
tag a set of bytes in a packet
Definition: tag.h:39
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:836
Callback< ObjectBase * > GetConstructor() const
Get the constructor callback.
Definition: type-id.cc:1085
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
std::string GetName() const
Get the name.
Definition: type-id.cc:992
A sockets interface to UDP.
Hold an unsigned integer type.
Definition: uinteger.h:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
Definition: test.h:667
#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:252
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
static Ipv4FragmentationTestSuite g_ipv4fragmentationTestSuite
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:706
STL namespace.
static const uint32_t packetSize
Packet size generated at the AP.