A Discrete-Event Network Simulator
API
nms-p2p-nix.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, GTech Systems, Inc.
3  * Copyright (c) 2021 NITK Surathkal: Extended to handle IPv6
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: Alfred Park <park@gtech-systems.com>
19  * Modified By: Josh Pelkey <jpelkey@gatech.edu> (ported to ns-3)
20  * Modified By: Ameya Deshpande <ameyanrd@outlook.com> (IPv6 extensions)
21  * Tommaso Pecorella <tommaso.pecorella@unifi.it> (IPv6 extensions)
22  */
23 /*
24  * DARPA NMS Campus Network Model
25  *
26  * This topology replicates the original NMS Campus Network model
27  * with the exception of chord links (which were never utilized in the
28  * original model)
29  * Link Bandwidths and Delays may not be the same as the original
30  * specifications
31  *
32  * The fundamental unit of the NMS model consists of a campus network. The
33  * campus network topology can been seen in the model manual.
34  *
35  * The number of hosts (default 42) is variable. Finally, an arbitrary
36  * number of these campus networks can be connected together (default 2)
37  * to make very large simulations.
38  */
39 
40 #include "ns3/applications-module.h"
41 #include "ns3/core-module.h"
42 #include "ns3/internet-module.h"
43 #include "ns3/network-module.h"
44 #include "ns3/nix-vector-helper.h"
45 #include "ns3/onoff-application.h"
46 #include "ns3/packet-sink.h"
47 #include "ns3/point-to-point-module.h"
48 #include "ns3/simulator.h"
49 
50 #include <chrono>
51 #include <sstream>
52 
53 using namespace ns3;
54 
55 NS_LOG_COMPONENT_DEFINE("CampusNetworkModel");
56 
57 void
59 {
61 }
62 
67 template <typename T>
68 class Array2D
69 {
70  public:
76  Array2D(const size_t x, const size_t y)
77  : p(new T*[x]),
78  m_xMax(x)
79  {
80  for (size_t i = 0; i < m_xMax; i++)
81  {
82  p[i] = new T[y];
83  }
84  }
85 
87  {
88  for (size_t i = 0; i < m_xMax; i++)
89  {
90  delete[] p[i];
91  }
92  delete[] p;
93  p = nullptr;
94  }
95 
101  T* operator[](const size_t i)
102  {
103  return p[i];
104  }
105 
106  private:
107  T** p;
108  const size_t m_xMax;
109 };
110 
115 template <typename T>
116 class Array3D
117 {
118  public:
125  Array3D(const size_t x, const size_t y, const size_t z)
126  : p(new Array2D<T>*[x]),
127  m_xMax(x)
128  {
129  for (size_t i = 0; i < m_xMax; i++)
130  {
131  p[i] = new Array2D<T>(y, z);
132  }
133  }
134 
136  {
137  for (size_t i = 0; i < m_xMax; i++)
138  {
139  delete p[i];
140  p[i] = nullptr;
141  }
142  delete[] p;
143  p = nullptr;
144  }
145 
151  Array2D<T>& operator[](const size_t i)
152  {
153  return *(p[i]);
154  }
155 
156  private:
158  const size_t m_xMax;
159 };
160 
161 int
162 main(int argc, char* argv[])
163 {
164  auto t0 = std::chrono::steady_clock::now();
165 
166  std::cout << " ==== DARPA NMS CAMPUS NETWORK SIMULATION ====" << std::endl;
167  // LogComponentEnable ("OnOffApplication", LOG_LEVEL_INFO);
168 
169  int nCN = 2;
170  int nLANClients = 42;
171  bool nix = true;
172  bool useIpv6 = false;
173 
174  CommandLine cmd(__FILE__);
175  cmd.AddValue("useIPv6", "Use IPv6 instead of IPv4", useIpv6);
176  cmd.AddValue("CN", "Number of total CNs [2]", nCN);
177  cmd.AddValue("LAN", "Number of nodes per LAN [42]", nLANClients);
178  cmd.AddValue("NIX", "Toggle nix-vector routing", nix);
179  cmd.Parse(argc, argv);
180 
181  if (useIpv6 && !nix)
182  {
183  std::cout << "This script can work in IPv6 only by using NIX" << std::endl;
184  return 1;
185  }
186  if (nCN < 2)
187  {
188  std::cout << "Number of total CNs (" << nCN << ") lower than minimum of 2" << std::endl;
189  return 1;
190  }
191 
192  std::cout << "Number of CNs: " << nCN << ", LAN nodes: " << nLANClients << std::endl;
193 
194  Array2D<NodeContainer> nodes_net0(nCN, 3);
195  Array2D<NodeContainer> nodes_net1(nCN, 6);
196  auto nodes_netLR = new NodeContainer[nCN];
197  Array2D<NodeContainer> nodes_net2(nCN, 14);
198  Array3D<NodeContainer> nodes_net2LAN(nCN, 7, nLANClients);
199  Array2D<NodeContainer> nodes_net3(nCN, 9);
200  Array3D<NodeContainer> nodes_net3LAN(nCN, 5, nLANClients);
201 
202  PointToPointHelper p2p_2gb200ms;
203  PointToPointHelper p2p_1gb5ms;
204  PointToPointHelper p2p_100mb1ms;
206  Array3D<Address> ifs2LanRemoteAddress(nCN, 7, nLANClients);
207  Array3D<Address> ifs3LanRemoteAddress(nCN, 5, nLANClients);
208 
209  Ipv4AddressHelper addressHelperv4;
210  Ipv6AddressHelper addressHelperv6;
211  std::ostringstream oss;
212  p2p_1gb5ms.SetDeviceAttribute("DataRate", StringValue("1Gbps"));
213  p2p_1gb5ms.SetChannelAttribute("Delay", StringValue("5ms"));
214  p2p_2gb200ms.SetDeviceAttribute("DataRate", StringValue("2Gbps"));
215  p2p_2gb200ms.SetChannelAttribute("Delay", StringValue("200ms"));
216  p2p_100mb1ms.SetDeviceAttribute("DataRate", StringValue("100Mbps"));
217  p2p_100mb1ms.SetChannelAttribute("Delay", StringValue("1ms"));
218 
219  // Setup NixVector Routing
220  if (nix)
221  {
222  if (!useIpv6)
223  {
225  stack.SetRoutingHelper(nixRouting); // has effect on the next Install ()
226  }
227  else
228  {
230  stack.SetRoutingHelper(nixRouting); // has effect on the next Install ()
231  }
232  }
233 
234  // Create Campus Networks
235  for (int z = 0; z < nCN; ++z)
236  {
237  std::cout << "Creating Campus Network " << z << ":" << std::endl;
238  // Create Net0
239  std::cout << " SubNet [ 0";
240  for (int i = 0; i < 3; ++i)
241  {
242  nodes_net0[z][i].Create(1);
243  stack.Install(nodes_net0[z][i]);
244  }
245  nodes_net0[z][0].Add(nodes_net0[z][1].Get(0));
246  nodes_net0[z][1].Add(nodes_net0[z][2].Get(0));
247  nodes_net0[z][2].Add(nodes_net0[z][0].Get(0));
248  NetDeviceContainer ndc0[3];
249  for (int i = 0; i < 3; ++i)
250  {
251  ndc0[i] = p2p_1gb5ms.Install(nodes_net0[z][i]);
252  }
253  // Create Net1
254  std::cout << " 1";
255  for (int i = 0; i < 6; ++i)
256  {
257  nodes_net1[z][i].Create(1);
258  stack.Install(nodes_net1[z][i]);
259  }
260  nodes_net1[z][0].Add(nodes_net1[z][1].Get(0));
261  nodes_net1[z][2].Add(nodes_net1[z][0].Get(0));
262  nodes_net1[z][3].Add(nodes_net1[z][0].Get(0));
263  nodes_net1[z][4].Add(nodes_net1[z][1].Get(0));
264  nodes_net1[z][5].Add(nodes_net1[z][1].Get(0));
265  NetDeviceContainer ndc1[6];
266  for (int i = 0; i < 6; ++i)
267  {
268  if (i == 1)
269  {
270  continue;
271  }
272  ndc1[i] = p2p_1gb5ms.Install(nodes_net1[z][i]);
273  }
274  // Connect Net0 <-> Net1
275  NodeContainer net0_1;
276  net0_1.Add(nodes_net0[z][2].Get(0));
277  net0_1.Add(nodes_net1[z][0].Get(0));
278  NetDeviceContainer ndc0_1;
279  ndc0_1 = p2p_1gb5ms.Install(net0_1);
280  oss.str("");
281  if (!useIpv6)
282  {
283  oss << 10 + z << ".1.252.0";
284  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
285  addressHelperv4.Assign(ndc0_1);
286  }
287  else
288  {
289  oss << 2001 + z << ":1:252::";
290  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
291  addressHelperv6.Assign(ndc0_1);
292  }
293  // Create Net2
294  std::cout << " 2";
295  for (int i = 0; i < 14; ++i)
296  {
297  nodes_net2[z][i].Create(1);
298  stack.Install(nodes_net2[z][i]);
299  }
300  nodes_net2[z][0].Add(nodes_net2[z][1].Get(0));
301  nodes_net2[z][2].Add(nodes_net2[z][0].Get(0));
302  nodes_net2[z][1].Add(nodes_net2[z][3].Get(0));
303  nodes_net2[z][3].Add(nodes_net2[z][2].Get(0));
304  nodes_net2[z][4].Add(nodes_net2[z][2].Get(0));
305  nodes_net2[z][5].Add(nodes_net2[z][3].Get(0));
306  nodes_net2[z][6].Add(nodes_net2[z][5].Get(0));
307  nodes_net2[z][7].Add(nodes_net2[z][2].Get(0));
308  nodes_net2[z][8].Add(nodes_net2[z][3].Get(0));
309  nodes_net2[z][9].Add(nodes_net2[z][4].Get(0));
310  nodes_net2[z][10].Add(nodes_net2[z][5].Get(0));
311  nodes_net2[z][11].Add(nodes_net2[z][6].Get(0));
312  nodes_net2[z][12].Add(nodes_net2[z][6].Get(0));
313  nodes_net2[z][13].Add(nodes_net2[z][6].Get(0));
314  NetDeviceContainer ndc2[14];
315  for (int i = 0; i < 14; ++i)
316  {
317  ndc2[i] = p2p_1gb5ms.Install(nodes_net2[z][i]);
318  }
319  Array2D<NetDeviceContainer> ndc2LAN(7, nLANClients);
320  for (int i = 0; i < 7; ++i)
321  {
322  oss.str("");
323  if (!useIpv6)
324  {
325  oss << 10 + z << ".4." << 15 + i << ".0";
326  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
327  }
328  else
329  {
330  oss << 2001 + z << ":4:" << 15 + i << "::";
331  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
332  }
333  for (int j = 0; j < nLANClients; ++j)
334  {
335  nodes_net2LAN[z][i][j].Create(1);
336  stack.Install(nodes_net2LAN[z][i][j]);
337  nodes_net2LAN[z][i][j].Add(nodes_net2[z][i + 7].Get(0));
338  ndc2LAN[i][j] = p2p_100mb1ms.Install(nodes_net2LAN[z][i][j]);
339  if (!useIpv6)
340  {
341  ifs2LanRemoteAddress[z][i][j] =
342  InetSocketAddress(addressHelperv4.Assign(ndc2LAN[i][j]).GetAddress(0),
343  9999);
344  }
345  else
346  {
347  ifs2LanRemoteAddress[z][i][j] =
348  Inet6SocketAddress(addressHelperv6.Assign(ndc2LAN[i][j]).GetAddress(0, 1),
349  9999);
350  }
351  }
352  }
353  // Create Net3
354  std::cout << " 3 ]" << std::endl;
355  for (int i = 0; i < 9; ++i)
356  {
357  nodes_net3[z][i].Create(1);
358  stack.Install(nodes_net3[z][i]);
359  }
360  nodes_net3[z][0].Add(nodes_net3[z][1].Get(0));
361  nodes_net3[z][1].Add(nodes_net3[z][2].Get(0));
362  nodes_net3[z][2].Add(nodes_net3[z][3].Get(0));
363  nodes_net3[z][3].Add(nodes_net3[z][1].Get(0));
364  nodes_net3[z][4].Add(nodes_net3[z][0].Get(0));
365  nodes_net3[z][5].Add(nodes_net3[z][0].Get(0));
366  nodes_net3[z][6].Add(nodes_net3[z][2].Get(0));
367  nodes_net3[z][7].Add(nodes_net3[z][3].Get(0));
368  nodes_net3[z][8].Add(nodes_net3[z][3].Get(0));
369  NetDeviceContainer ndc3[9];
370  for (int i = 0; i < 9; ++i)
371  {
372  ndc3[i] = p2p_1gb5ms.Install(nodes_net3[z][i]);
373  }
374  Array2D<NetDeviceContainer> ndc3LAN(5, nLANClients);
375  for (int i = 0; i < 5; ++i)
376  {
377  oss.str("");
378  if (!useIpv6)
379  {
380  oss << 10 + z << ".5." << 10 + i << ".0";
381  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
382  }
383  else
384  {
385  oss << 2001 + z << ":5:" << 10 + i << "::";
386  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
387  }
388  for (int j = 0; j < nLANClients; ++j)
389  {
390  nodes_net3LAN[z][i][j].Create(1);
391  stack.Install(nodes_net3LAN[z][i][j]);
392  nodes_net3LAN[z][i][j].Add(nodes_net3[z][i + 4].Get(0));
393  ndc3LAN[i][j] = p2p_100mb1ms.Install(nodes_net3LAN[z][i][j]);
394  if (!useIpv6)
395  {
396  ifs3LanRemoteAddress[z][i][j] =
397  InetSocketAddress(addressHelperv4.Assign(ndc3LAN[i][j]).GetAddress(0),
398  9999);
399  }
400  else
401  {
402  ifs3LanRemoteAddress[z][i][j] =
403  Inet6SocketAddress(addressHelperv6.Assign(ndc3LAN[i][j]).GetAddress(0, 1),
404  9999);
405  }
406  }
407  }
408  std::cout << " Connecting Subnets..." << std::endl;
409  // Create Lone Routers (Node 4 & 5)
410  nodes_netLR[z].Create(2);
411  stack.Install(nodes_netLR[z]);
412  NetDeviceContainer ndcLR;
413  ndcLR = p2p_1gb5ms.Install(nodes_netLR[z]);
414  // Connect Net2/Net3 through Lone Routers to Net0
415  NodeContainer net0_4;
416  NodeContainer net0_5;
417  NodeContainer net2_4a;
418  NodeContainer net2_4b;
419  NodeContainer net3_5a;
420  NodeContainer net3_5b;
421  net0_4.Add(nodes_netLR[z].Get(0));
422  net0_4.Add(nodes_net0[z][0].Get(0));
423  net0_5.Add(nodes_netLR[z].Get(1));
424  net0_5.Add(nodes_net0[z][1].Get(0));
425  net2_4a.Add(nodes_netLR[z].Get(0));
426  net2_4a.Add(nodes_net2[z][0].Get(0));
427  net2_4b.Add(nodes_netLR[z].Get(1));
428  net2_4b.Add(nodes_net2[z][1].Get(0));
429  net3_5a.Add(nodes_netLR[z].Get(1));
430  net3_5a.Add(nodes_net3[z][0].Get(0));
431  net3_5b.Add(nodes_netLR[z].Get(1));
432  net3_5b.Add(nodes_net3[z][1].Get(0));
433  NetDeviceContainer ndc0_4;
434  NetDeviceContainer ndc0_5;
435  NetDeviceContainer ndc2_4a;
436  NetDeviceContainer ndc2_4b;
437  NetDeviceContainer ndc3_5a;
438  NetDeviceContainer ndc3_5b;
439  ndc0_4 = p2p_1gb5ms.Install(net0_4);
440  ndc0_5 = p2p_1gb5ms.Install(net0_5);
441  ndc2_4a = p2p_1gb5ms.Install(net2_4a);
442  ndc2_4b = p2p_1gb5ms.Install(net2_4b);
443  ndc3_5a = p2p_1gb5ms.Install(net3_5a);
444  ndc3_5b = p2p_1gb5ms.Install(net3_5b);
445 
446  // Assign IP addresses
447 
448  if (!useIpv6)
449  {
450  // ndc0_4
451  oss.str("");
452  oss << 10 + z << ".1.253.0";
453  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
454  addressHelperv4.Assign(ndc0_4);
455  // ndc0_5
456  oss.str("");
457  oss << 10 + z << ".1.254.0";
458  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
459  addressHelperv4.Assign(ndc0_5);
460  // ndc2_4a
461  oss.str("");
462  oss << 10 + z << ".4.253.0";
463  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
464  addressHelperv4.Assign(ndc2_4a);
465  // ndc2_4b
466  oss.str("");
467  oss << 10 + z << ".4.254.0";
468  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
469  addressHelperv4.Assign(ndc2_4b);
470  // ndc3_5a
471  oss.str("");
472  oss << 10 + z << ".5.253.0";
473  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
474  addressHelperv4.Assign(ndc3_5a);
475  // ndc3_5b
476  oss.str("");
477  oss << 10 + z << ".5.254.0";
478  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
479  addressHelperv4.Assign(ndc3_5b);
480  }
481  else
482  {
483  // ndc0_4
484  oss.str("");
485  oss << 2001 + z << ":1:253::";
486  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
487  addressHelperv6.Assign(ndc0_4);
488  // ndc0_5
489  oss.str("");
490  oss << 2001 + z << ":1:254::";
491  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
492  addressHelperv6.Assign(ndc0_5);
493  // ndc2_4a
494  oss.str("");
495  oss << 2001 + z << ":4:253::";
496  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
497  addressHelperv6.Assign(ndc2_4a);
498  // ndc2_4b
499  oss.str("");
500  oss << 2001 + z << ":4:254::";
501  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
502  addressHelperv6.Assign(ndc2_4b);
503  // ndc3_5a
504  oss.str("");
505  oss << 2001 + z << ":5:253::";
506  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
507  addressHelperv6.Assign(ndc3_5a);
508  // ndc3_5b
509  oss.str("");
510  oss << 2001 + z << ":5:254::";
511  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
512  addressHelperv6.Assign(ndc3_5b);
513  }
514 
515  std::cout << " Assigning IP addresses..." << std::endl;
516  for (int i = 0; i < 3; ++i)
517  {
518  oss.str("");
519  if (!useIpv6)
520  {
521  oss << 10 + z << ".1." << 1 + i << ".0";
522  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
523  addressHelperv4.Assign(ndc0[i]);
524  }
525  else
526  {
527  oss << 2001 + z << ":1:" << 1 + i << "::";
528  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
529  addressHelperv6.Assign(ndc0[i]);
530  }
531  }
532  for (int i = 0; i < 6; ++i)
533  {
534  if (i == 1)
535  {
536  continue;
537  }
538  oss.str("");
539  if (!useIpv6)
540  {
541  oss << 10 + z << ".2." << 1 + i << ".0";
542  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
543  addressHelperv4.Assign(ndc1[i]);
544  }
545  else
546  {
547  oss << 2001 + z << ":2:" << 1 + i << "::";
548  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
549  addressHelperv6.Assign(ndc1[i]);
550  }
551  }
552  oss.str("");
553  if (!useIpv6)
554  {
555  oss << 10 + z << ".3.1.0";
556  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
557  addressHelperv4.Assign(ndcLR);
558  }
559  else
560  {
561  oss << 2001 + z << ":3:1::";
562  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
563  addressHelperv6.Assign(ndcLR);
564  }
565  for (int i = 0; i < 14; ++i)
566  {
567  oss.str("");
568  if (!useIpv6)
569  {
570  oss << 10 + z << ".4." << 1 + i << ".0";
571  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
572  addressHelperv4.Assign(ndc2[i]);
573  }
574  else
575  {
576  oss << 2001 + z << ":4:" << 1 + i << "::";
577  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
578  addressHelperv6.Assign(ndc2[i]);
579  }
580  }
581  for (int i = 0; i < 9; ++i)
582  {
583  oss.str("");
584  if (!useIpv6)
585  {
586  oss << 10 + z << ".5." << 1 + i << ".0";
587  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
588  addressHelperv4.Assign(ndc3[i]);
589  }
590  else
591  {
592  oss << 2001 + z << ":5:" << 1 + i << "::";
593  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
594  addressHelperv6.Assign(ndc3[i]);
595  }
596  }
597  }
598  // Create Ring Links
599  if (nCN > 1)
600  {
601  std::cout << "Forming Ring Topology..." << std::endl;
602  auto nodes_ring = new NodeContainer[nCN];
603  for (int z = 0; z < nCN - 1; ++z)
604  {
605  nodes_ring[z].Add(nodes_net0[z][0].Get(0));
606  nodes_ring[z].Add(nodes_net0[z + 1][0].Get(0));
607  }
608  nodes_ring[nCN - 1].Add(nodes_net0[nCN - 1][0].Get(0));
609  nodes_ring[nCN - 1].Add(nodes_net0[0][0].Get(0));
610  auto ndc_ring = new NetDeviceContainer[nCN];
611  for (int z = 0; z < nCN; ++z)
612  {
613  ndc_ring[z] = p2p_2gb200ms.Install(nodes_ring[z]);
614  oss.str("");
615  if (!useIpv6)
616  {
617  oss << "254.1." << z + 1 << ".0";
618  addressHelperv4.SetBase(oss.str().c_str(), "255.255.255.0");
619  addressHelperv4.Assign(ndc_ring[z]);
620  }
621  else
622  {
623  oss << "254:1:" << z + 1 << "::";
624  addressHelperv6.SetBase(oss.str().c_str(), Ipv6Prefix(64));
625  addressHelperv6.Assign(ndc_ring[z]);
626  }
627  }
628  delete[] ndc_ring;
629  delete[] nodes_ring;
630  }
631 
632  // Create Traffic Flows
633  std::cout << "Creating TCP Traffic Flows:" << std::endl;
634  Config::SetDefault("ns3::OnOffApplication::MaxBytes", UintegerValue(500000));
635  Config::SetDefault("ns3::OnOffApplication::OnTime",
636  StringValue("ns3::ConstantRandomVariable[Constant=1.0]"));
637  Config::SetDefault("ns3::OnOffApplication::OffTime",
638  StringValue("ns3::ConstantRandomVariable[Constant=0.0]"));
639  Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(512));
640 
641  Ptr<UniformRandomVariable> urng = CreateObject<UniformRandomVariable>();
642  int r1;
643  double r2;
644 
645  Address sinkAddress;
646  if (!useIpv6)
647  {
648  sinkAddress = InetSocketAddress(Ipv4Address::GetAny(), 9999);
649  }
650  else
651  {
652  sinkAddress = Inet6SocketAddress(Ipv6Address::GetAny(), 9999);
653  }
654 
655  for (int z = 0; z < nCN; ++z)
656  {
657  int x = z + 1;
658  if (z == nCN - 1)
659  {
660  x = 0;
661  }
662  // Subnet 2 LANs
663  std::cout << " Campus Network " << z << " Flows [ Net2 ";
664  for (int i = 0; i < 7; ++i)
665  {
666  for (int j = 0; j < nLANClients; ++j)
667  {
668  // Sinks
669  PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkAddress);
670  ApplicationContainer sinkApp = sinkHelper.Install(nodes_net2LAN[z][i][j].Get(0));
671  sinkApp.Start(Seconds(0.0));
672  // Sources
673  r1 = 2 + (int)(4 * urng->GetValue());
674  r2 = 10 * urng->GetValue();
675  OnOffHelper client("ns3::TcpSocketFactory", Address());
676  AddressValue remoteAddress(ifs2LanRemoteAddress[z][i][j]);
677  client.SetAttribute("Remote", remoteAddress);
678  ApplicationContainer clientApp;
679  clientApp.Add(client.Install(nodes_net1[x][r1].Get(0)));
680  clientApp.Start(Seconds(r2));
681  }
682  }
683  // Subnet 3 LANs
684  std::cout << "Net3 ]" << std::endl;
685  for (int i = 0; i < 5; ++i)
686  {
687  for (int j = 0; j < nLANClients; ++j)
688  {
689  // Sinks
690  PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkAddress);
691  ApplicationContainer sinkApp = sinkHelper.Install(nodes_net3LAN[z][i][j].Get(0));
692  sinkApp.Start(Seconds(0.0));
693  // Sources
694  r1 = 2 + (int)(4 * urng->GetValue());
695  r2 = 10 * urng->GetValue();
696  OnOffHelper client("ns3::TcpSocketFactory", Address());
697  AddressValue remoteAddress(ifs3LanRemoteAddress[z][i][j]);
698  client.SetAttribute("Remote", remoteAddress);
699  ApplicationContainer clientApp;
700  clientApp.Add(client.Install(nodes_net1[x][r1].Get(0)));
701  clientApp.Start(Seconds(r2));
702  }
703  }
704  }
705 
706  std::cout << "Created " << NodeList::GetNNodes() << " nodes." << std::endl;
707  auto routingStart = std::chrono::steady_clock::now();
708 
709  if (nix)
710  {
711  // Calculate routing tables
712  std::cout << "Using Nix-vectors..." << std::endl;
713  }
714  else
715  {
716  // Calculate routing tables
717  std::cout << "Populating Global Static Routing Tables..." << std::endl;
719  }
720 
721  auto routingEnd = std::chrono::steady_clock::now();
722  std::cout
723  << "Routing tables population took "
724  << std::chrono::duration_cast<std::chrono::milliseconds>(routingEnd - routingStart).count()
725  << "ms" << std::endl;
726 
728  std::cout << "Running simulator..." << std::endl;
729  auto t1 = std::chrono::steady_clock::now();
730  Simulator::Stop(Seconds(100.0));
731  Simulator::Run();
732  auto t2 = std::chrono::steady_clock::now();
733  std::cout << "Simulator finished." << std::endl;
735 
736  auto d1 = std::chrono::duration_cast<std::chrono::seconds>(t1 - t0);
737  auto d2 = std::chrono::duration_cast<std::chrono::seconds>(t2 - t1);
738 
739  std::cout << "-----" << std::endl << "Runtime Stats:" << std::endl;
740  std::cout << "Simulator init time: " << d1.count() << "s" << std::endl;
741  std::cout << "Simulator run time: " << d2.count() << "s" << std::endl;
742  std::cout << "Total elapsed time: " << (d1 + d2).count() << "s" << std::endl;
743 
744  delete[] nodes_netLR;
745  return 0;
746 }
2D array used in nix-vector-routing example "nms-p2p-nix.cc"
Definition: nms-p2p-nix.cc:69
Array2D(const size_t x, const size_t y)
Constructor.
Definition: nms-p2p-nix.cc:76
const size_t m_xMax
maximum number of rows
Definition: nms-p2p-nix.cc:108
T * operator[](const size_t i)
Accessor operator.
Definition: nms-p2p-nix.cc:101
T ** p
Stored elements.
Definition: nms-p2p-nix.cc:107
3D array used in nix-vector-routing example "nms-p2p-nix.cc"
Definition: nms-p2p-nix.cc:117
Array3D(const size_t x, const size_t y, const size_t z)
Constructor.
Definition: nms-p2p-nix.cc:125
Array2D< T > & operator[](const size_t i)
Accessor operator.
Definition: nms-p2p-nix.cc:151
const size_t m_xMax
maximum number of rows
Definition: nms-p2p-nix.cc:158
Array2D< T > ** p
Stored elements.
Definition: nms-p2p-nix.cc:157
a polymophic address class
Definition: address.h:101
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.
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
Parse command-line arguments.
Definition: command-line.h:232
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...
static Ipv4Address GetAny()
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
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.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
holds a vector of ns3::NetDevice pointers
Helper class that adds Nix-vector routing to nodes.
keep track of a set of node pointers.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
static uint32_t GetNNodes()
Definition: node-list.cc:258
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
stack
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:40
void Progress()
Definition: nms-p2p-nix.cc:58