A Discrete-Event Network Simulator
API
nix-test.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2021 NITK Surathkal
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Ameya Deshpande <ameyanrd@outlook.com>
19 */
20
21#include "ns3/test.h"
22#include "ns3/socket-factory.h"
23#include "ns3/udp-socket-factory.h"
24#include "ns3/simulator.h"
25#include "ns3/socket.h"
26
27#include "ns3/internet-stack-helper.h"
28#include "ns3/ipv4-address-helper.h"
29#include "ns3/ipv4-l3-protocol.h"
30#include "ns3/icmpv4-l4-protocol.h"
31#include "ns3/ipv6-address-helper.h"
32#include "ns3/ipv6-l3-protocol.h"
33#include "ns3/icmpv6-l4-protocol.h"
34#include "ns3/udp-l4-protocol.h"
35#include "ns3/simple-net-device-helper.h"
36#include "ns3/nix-vector-helper.h"
37
38using namespace ns3;
67{
69
75 void DoSendDatav4 (Ptr<Socket> socket, Ipv4Address to);
76
82 void DoSendDatav6 (Ptr<Socket> socket, Ipv6Address to);
83
90 void SendData (Time delay, Ptr<Socket> socket, Ipv4Address to);
91
98 void SendData (Time delay, Ptr<Socket> socket, Ipv6Address to);
99
100public:
101 virtual void DoRun (void);
103
108 void ReceivePkt (Ptr<Socket> socket);
109
110 std::vector<uint32_t> m_receivedPacketSizes;
111};
112
114 : TestCase ("three router, two path test")
115{
116}
117
119{
120 [[maybe_unused]] uint32_t availableData = socket->GetRxAvailable ();
123 "availableData should be equal to the size of packet received.");
125}
126
127void
129{
130 Address realTo = InetSocketAddress (to, 1234);
131 socket->SendTo (Create<Packet> (123), 0, realTo);
132}
133
134void
136{
137 Address realTo = Inet6SocketAddress (to, 1234);
138 socket->SendTo (Create<Packet> (123), 0, realTo);
139}
140
141void
143{
144 m_receivedPacket = Create<Packet> ();
145 Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), delay,
146 &NixVectorRoutingTest::DoSendDatav4, this, socket, to);
147}
148
149void
151{
152 m_receivedPacket = Create<Packet> ();
153 Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), delay,
154 &NixVectorRoutingTest::DoSendDatav6, this, socket, to);
155}
156
157void
159{
160 // Create topology
161 NodeContainer nSrcnA;
162 NodeContainer nAnB;
163 NodeContainer nBnC;
164 NodeContainer nCnDst;
165 NodeContainer nAnC;
166
167 nSrcnA.Create (2);
168
169 nAnB.Add (nSrcnA.Get (1));
170 nAnB.Create (1);
171
172 nBnC.Add (nAnB.Get (1));
173 nBnC.Create (1);
174
175 nCnDst.Add (nBnC.Get (1));
176 nCnDst.Create (1);
177
178 nAnC.Add (nAnB.Get (0));
179 nAnC.Add (nCnDst.Get (0));
180
181 SimpleNetDeviceHelper devHelper;
182 devHelper.SetNetDevicePointToPointMode (true);
183
184 NodeContainer allNodes = NodeContainer (nSrcnA, nBnC, nCnDst.Get (1));
185
186 std::ostringstream stringStream1v4;
187 Ptr<OutputStreamWrapper> routingStream1v4 = Create<OutputStreamWrapper> (&stringStream1v4);
188 std::ostringstream stringStream1v6;
189 Ptr<OutputStreamWrapper> routingStream1v6 = Create<OutputStreamWrapper> (&stringStream1v6);
190 std::ostringstream stringStream2v4;
191 Ptr<OutputStreamWrapper> cacheStreamv4 = Create<OutputStreamWrapper> (&stringStream2v4);
192 std::ostringstream stringStream2v6;
193 Ptr<OutputStreamWrapper> cacheStreamv6 = Create<OutputStreamWrapper> (&stringStream2v6);
194 std::ostringstream stringStream3v4;
195 Ptr<OutputStreamWrapper> routingStream3v4 = Create<OutputStreamWrapper> (&stringStream3v4);
196 std::ostringstream stringStream3v6;
197 Ptr<OutputStreamWrapper> routingStream3v6 = Create<OutputStreamWrapper> (&stringStream3v6);
198
199 // NixHelper to install nix-vector routing on all nodes
200 Ipv4NixVectorHelper ipv4NixRouting;
201 Ipv6NixVectorHelper ipv6NixRouting;
203 stack.SetRoutingHelper (ipv4NixRouting); // has effect on the next Install ()
204 stack.SetRoutingHelper (ipv6NixRouting); // has effect on the next Install ()
205 stack.Install (allNodes);
206
207 NetDeviceContainer dSrcdA;
210 NetDeviceContainer dCdDst;
212 dSrcdA = devHelper.Install (nSrcnA);
213 dAdB = devHelper.Install (nAnB);
214 dBdC = devHelper.Install (nBnC);
215 dCdDst = devHelper.Install (nCnDst);
216 dAdC = devHelper.Install (nAnC);
217
218 Ipv4AddressHelper aSrcaAv4;
219 aSrcaAv4.SetBase ("10.1.0.0", "255.255.255.0");
220 Ipv4AddressHelper aAaBv4;
221 aAaBv4.SetBase ("10.1.1.0", "255.255.255.0");
222 Ipv4AddressHelper aBaCv4;
223 aBaCv4.SetBase ("10.1.2.0", "255.255.255.0");
224 Ipv4AddressHelper aCaDstv4;
225 aCaDstv4.SetBase ("10.1.3.0", "255.255.255.0");
226 Ipv4AddressHelper aAaCv4;
227 aAaCv4.SetBase ("10.1.4.0", "255.255.255.0");
228
229 Ipv6AddressHelper aSrcaAv6;
230 aSrcaAv6.SetBase (Ipv6Address ("2001:0::"), Ipv6Prefix (64));
231 Ipv6AddressHelper aAaBv6;
232 aAaBv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
233 Ipv6AddressHelper aBaCv6;
234 aBaCv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
235 Ipv6AddressHelper aCaDstv6;
236 aCaDstv6.SetBase (Ipv6Address ("2001:3::"), Ipv6Prefix (64));
237 Ipv6AddressHelper aAaCv6;
238 aAaCv6.SetBase (Ipv6Address ("2001:4::"), Ipv6Prefix (64));
239
240 aSrcaAv4.Assign (dSrcdA);
241 aAaBv4.Assign (dAdB);
242 aBaCv4.Assign (dBdC);
243 Ipv4InterfaceContainer iCiDstv4 = aCaDstv4.Assign (dCdDst);
244 Ipv4InterfaceContainer iAiCv4 = aAaCv4.Assign (dAdC);
245
246 aSrcaAv6.Assign (dSrcdA);
247 aAaBv6.Assign (dAdB);
248 aBaCv6.Assign (dBdC);
249 Ipv6InterfaceContainer iCiDstv6 = aCaDstv6.Assign (dCdDst);
250 Ipv6InterfaceContainer iAiCv6 = aAaCv6.Assign (dAdC);
251
252 // Create the UDP sockets
253 Ptr<SocketFactory> rxSocketFactory = nCnDst.Get (1)->GetObject<UdpSocketFactory> ();
254 Ptr<Socket> rxSocketv4 = rxSocketFactory->CreateSocket ();
255 Ptr<Socket> rxSocketv6 = rxSocketFactory->CreateSocket ();
256 NS_TEST_EXPECT_MSG_EQ (rxSocketv4->Bind (InetSocketAddress (iCiDstv4.GetAddress (1), 1234)), 0, "trivial");
257 NS_TEST_EXPECT_MSG_EQ (rxSocketv6->Bind (Inet6SocketAddress (iCiDstv6.GetAddress (1, 1), 1234)), 0, "trivial");
258 rxSocketv4->SetRecvCallback (MakeCallback (&NixVectorRoutingTest::ReceivePkt, this));
260
261 Ptr<SocketFactory> txSocketFactory = nSrcnA.Get (0)->GetObject<UdpSocketFactory> ();
262 Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
263 txSocket->SetAllowBroadcast (true);
264
265 SendData (Seconds (2), txSocket, Ipv4Address ("10.1.3.2"));
266 SendData (Seconds (2), txSocket, Ipv6Address ("2001:3::200:ff:fe00:8"));
267
268 ipv4NixRouting.PrintRoutingPathAt (Seconds (3), nSrcnA.Get (0), iCiDstv4.GetAddress (1), routingStream1v4);
269 ipv6NixRouting.PrintRoutingPathAt (Seconds (3), nSrcnA.Get (0), iCiDstv6.GetAddress (1, 1), routingStream1v6);
270
271 // Set the IPv4 nA interface on nA - nC channel down.
272 Ptr<Ipv4> ipv4 = nAnC.Get (0)->GetObject<Ipv4> ();
273 int32_t ifIndex = ipv4->GetInterfaceForDevice (dAdC.Get (0));
274 Simulator::Schedule (Seconds (5), &Ipv4::SetDown, ipv4, ifIndex);
275
276 // Set the IPv6 nA interface on nA - nC channel down.
277 Ptr<Ipv6> ipv6 = nAnC.Get (0)->GetObject<Ipv6> ();
278 ifIndex = ipv6->GetInterfaceForDevice (dAdC.Get (0));
279 Simulator::Schedule (Seconds (5), &Ipv6::SetDown, ipv6, ifIndex);
280
281 ipv4NixRouting.PrintRoutingTableAllAt (Seconds (7), cacheStreamv4);
282 ipv6NixRouting.PrintRoutingTableAllAt (Seconds (7), cacheStreamv6);
283
284 SendData (Seconds (8), txSocket, Ipv4Address ("10.1.3.2"));
285 SendData (Seconds (8), txSocket, Ipv6Address ("2001:3::200:ff:fe00:8"));
286
287 ipv4NixRouting.PrintRoutingPathAt (Seconds (9), nSrcnA.Get (0), iCiDstv4.GetAddress (1), routingStream3v4);
288 ipv6NixRouting.PrintRoutingPathAt (Seconds (9), nSrcnA.Get (0), iCiDstv6.GetAddress (1, 1), routingStream3v6);
289
290 // Set the IPv4 nC interface on nB - nC channel down.
291 ipv4 = nBnC.Get (1)->GetObject<Ipv4> ();
292 ifIndex = ipv4->GetInterfaceForDevice (dBdC.Get (1));
293 Simulator::Schedule (Seconds (10), &Ipv4::SetDown, ipv4, ifIndex);
294
295 // Set the IPv6 nC interface on nB - nC channel down.
296 ipv6 = nBnC.Get (1)->GetObject<Ipv6> ();
297 ifIndex = ipv6->GetInterfaceForDevice (dBdC.Get (1));
298 Simulator::Schedule (Seconds (10), &Ipv6::SetDown, ipv6, ifIndex);
299
300 SendData (Seconds (11), txSocket, Ipv4Address ("10.1.3.2"));
301 SendData (Seconds (11), txSocket, Ipv6Address ("2001:3::200:ff:fe00:8"));
302
303 Simulator::Stop (Seconds (66));
304 Simulator::Run ();
305
306 // ------ Now the tests ------------
307
308 // Test the Routing
309 NS_TEST_EXPECT_MSG_EQ (m_receivedPacketSizes[0], 123, "IPv4 Nix-Vector Routing should work.");
310 NS_TEST_EXPECT_MSG_EQ (m_receivedPacketSizes[1], 123, "IPv6 Nix-Vector Routing should work.");
311 NS_TEST_EXPECT_MSG_EQ (m_receivedPacketSizes.size (), 4, "IPv4 and IPv6 Nix-Vector Routing should have received only 1 packet.");
312
313 // Test the Path
314 const std::string p_nSrcnAnCnDstv4 = "Time: +3s, Nix Routing\n"
315 "Route path from Node 0 to Node 4, Nix Vector: 01001 (5 bits left)\n"
316 "10.1.0.1 (Node 0) ----> 10.1.0.2 (Node 1)\n"
317 "10.1.4.1 (Node 1) ----> 10.1.4.2 (Node 3)\n"
318 "10.1.3.1 (Node 3) ----> 10.1.3.2 (Node 4)\n\n";
319 NS_TEST_EXPECT_MSG_EQ (stringStream1v4.str (), p_nSrcnAnCnDstv4, "Routing Path is incorrect.");
320
321 const std::string p_nSrcnAnCnDstv6 = "Time: +3s, Nix Routing\n"
322 "Route path from Node 0 to Node 4, Nix Vector: 01001 (5 bits left)\n"
323 "2001::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)\n"
324 "fe80::200:ff:fe00:9 (Node 1) ----> fe80::200:ff:fe00:a (Node 3)\n"
325 "fe80::200:ff:fe00:7 (Node 3) ----> 2001:3::200:ff:fe00:8 (Node 4)\n\n";
326 NS_TEST_EXPECT_MSG_EQ (stringStream1v6.str (), p_nSrcnAnCnDstv6, "Routing Path is incorrect.");
327
328 const std::string p_nSrcnAnBnCnDstv4 = "Time: +9s, Nix Routing\n"
329 "Route path from Node 0 to Node 4, Nix Vector: 0111 (4 bits left)\n"
330 "10.1.0.1 (Node 0) ----> 10.1.0.2 (Node 1)\n"
331 "10.1.1.1 (Node 1) ----> 10.1.1.2 (Node 2)\n"
332 "10.1.2.1 (Node 2) ----> 10.1.2.2 (Node 3)\n"
333 "10.1.3.1 (Node 3) ----> 10.1.3.2 (Node 4)\n\n";
334 NS_TEST_EXPECT_MSG_EQ (stringStream3v4.str (), p_nSrcnAnBnCnDstv4, "Routing Path is incorrect.");
335
336 const std::string p_nSrcnAnBnCnDstv6 = "Time: +9s, Nix Routing\n"
337 "Route path from Node 0 to Node 4, Nix Vector: 0111 (4 bits left)\n"
338 "2001::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)\n"
339 "fe80::200:ff:fe00:3 (Node 1) ----> fe80::200:ff:fe00:4 (Node 2)\n"
340 "fe80::200:ff:fe00:5 (Node 2) ----> fe80::200:ff:fe00:6 (Node 3)\n"
341 "fe80::200:ff:fe00:7 (Node 3) ----> 2001:3::200:ff:fe00:8 (Node 4)\n\n";
342 NS_TEST_EXPECT_MSG_EQ (stringStream3v6.str (), p_nSrcnAnBnCnDstv6, "Routing Path is incorrect.");
343
344 const std::string emptyCaches = "Node: 0, Time: +7s, Local time: +7s, Nix Routing\n"
345 "NixCache:\n"
346 "IpRouteCache:\n\n"
347 "Node: 1, Time: +7s, Local time: +7s, Nix Routing\n"
348 "NixCache:\n"
349 "IpRouteCache:\n\n"
350 "Node: 2, Time: +7s, Local time: +7s, Nix Routing\n"
351 "NixCache:\n"
352 "IpRouteCache:\n\n"
353 "Node: 3, Time: +7s, Local time: +7s, Nix Routing\n"
354 "NixCache:\n"
355 "IpRouteCache:\n\n"
356 "Node: 4, Time: +7s, Local time: +7s, Nix Routing\n"
357 "NixCache:\n"
358 "IpRouteCache:\n\n";
359 NS_TEST_EXPECT_MSG_EQ (stringStream2v4.str (), emptyCaches, "The caches should have been empty.");
360 NS_TEST_EXPECT_MSG_EQ (stringStream2v6.str (), emptyCaches, "The caches should have been empty.");
361
362 Simulator::Destroy ();
363}
364
372{
373public:
374 NixVectorRoutingTestSuite () : TestSuite ("nix-vector-routing", UNIT)
375 {
376 AddTestCase (new NixVectorRoutingTest (), TestCase::QUICK);
377 }
378};
379
#define max(a, b)
Definition: 80211b.c:43
The topology is of the form:
Definition: nix-test.cc:67
void DoSendDatav4(Ptr< Socket > socket, Ipv4Address to)
Send data immediately after being called.
Definition: nix-test.cc:128
std::vector< uint32_t > m_receivedPacketSizes
Received packet sizes.
Definition: nix-test.cc:110
Ptr< Packet > m_receivedPacket
Received packet.
Definition: nix-test.cc:68
virtual void DoRun(void)
Implementation to actually run this TestCase.
Definition: nix-test.cc:158
void ReceivePkt(Ptr< Socket > socket)
Receive data.
Definition: nix-test.cc:118
void DoSendDatav6(Ptr< Socket > socket, Ipv6Address to)
Send data immediately after being called.
Definition: nix-test.cc:135
void SendData(Time delay, Ptr< Socket > socket, Ipv4Address to)
Schedules the DoSendData () function to send the data.
Definition: nix-test.cc:142
IPv4 Nix-Vector Routing TestSuite.
Definition: nix-test.cc:372
a polymophic address class
Definition: address.h:91
An Inet6 address class.
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class to auto-assign global IPv6 unicast 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.
Definition: ipv6-address.h:50
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
Keep track of a set of IPv6 interfaces.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
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.
Helper class that adds Nix-vector routing to nodes.
void PrintRoutingPathAt(Time printTime, Ptr< Node > source, IpAddress dest, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the routing path for a source and destination at a particular time.
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.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t GetId(void) const
Definition: node.cc:109
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
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...
virtual Ptr< Node > GetNode(void) const =0
Return the node this socket is associated with.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual uint32_t GetRxAvailable(void) const =0
Return number of bytes which can be returned from one or multiple calls to Recv.
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
API to create UDP socket instances.
#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:141
#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:240
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
stack
Definition: first.py:37
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:661
static NixVectorRoutingTestSuite g_nixVectorRoutingTestSuite
Static variable for test initialization.
Definition: nix-test.cc:381