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 
38 using 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 
100 public:
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 ();
122  NS_TEST_ASSERT_MSG_EQ (availableData, m_receivedPacket->GetSize (),
123  "availableData should be equal to the size of packet received.");
125 }
126 
127 void
129 {
130  Address realTo = InetSocketAddress (to, 1234);
131  socket->SendTo (Create<Packet> (123), 0, realTo);
132 }
133 
134 void
136 {
137  Address realTo = Inet6SocketAddress (to, 1234);
138  socket->SendTo (Create<Packet> (123), 0, realTo);
139 }
140 
141 void
143 {
144  m_receivedPacket = Create<Packet> ();
145  Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), delay,
146  &NixVectorRoutingTest::DoSendDatav4, this, socket, to);
147 }
148 
149 void
151 {
152  m_receivedPacket = Create<Packet> ();
153  Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), delay,
154  &NixVectorRoutingTest::DoSendDatav6, this, socket, to);
155 }
156 
157 void
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;
208  NetDeviceContainer dAdB;
209  NetDeviceContainer dBdC;
210  NetDeviceContainer dCdDst;
211  NetDeviceContainer dAdC;
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 {
373 public:
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(NodeContainer other)
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< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
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 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:103
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:1244
stack
Definition: first.py:41
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
static NixVectorRoutingTestSuite g_nixVectorRoutingTestSuite
Static variable for test initialization.
Definition: nix-test.cc:381