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"
80 for (
size_t i = 0; i <
m_xMax; i++)
88 for (
size_t i = 0; i <
m_xMax; i++)
125 Array3D(
const size_t x,
const size_t y,
const size_t z)
129 for (
size_t i = 0; i <
m_xMax; i++)
137 for (
size_t i = 0; i <
m_xMax; i++)
162main(
int argc,
char* argv[])
164 auto t0 = std::chrono::steady_clock::now();
166 std::cout <<
" ==== DARPA NMS CAMPUS NETWORK SIMULATION ====" << std::endl;
170 int nLANClients = 42;
172 bool useIpv6 =
false;
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);
183 std::cout <<
"This script can work in IPv6 only by using NIX" << std::endl;
188 std::cout <<
"Number of total CNs (" << nCN <<
") lower than minimum of 2" << std::endl;
192 std::cout <<
"Number of CNs: " << nCN <<
", LAN nodes: " << nLANClients << std::endl;
211 std::ostringstream oss;
225 stack.SetRoutingHelper(nixRouting);
230 stack.SetRoutingHelper(nixRouting);
235 for (
int z = 0; z < nCN; ++z)
237 std::cout <<
"Creating Campus Network " << z <<
":" << std::endl;
239 std::cout <<
" SubNet [ 0";
240 for (
int i = 0; i < 3; ++i)
242 nodes_net0[z][i].Create(1);
243 stack.Install(nodes_net0[z][i]);
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));
249 for (
int i = 0; i < 3; ++i)
251 ndc0[i] = p2p_1gb5ms.
Install(nodes_net0[z][i]);
255 for (
int i = 0; i < 6; ++i)
257 nodes_net1[z][i].Create(1);
258 stack.Install(nodes_net1[z][i]);
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));
266 for (
int i = 0; i < 6; ++i)
272 ndc1[i] = p2p_1gb5ms.
Install(nodes_net1[z][i]);
276 net0_1.
Add(nodes_net0[z][2].Get(0));
277 net0_1.
Add(nodes_net1[z][0].Get(0));
279 ndc0_1 = p2p_1gb5ms.
Install(net0_1);
283 oss << 10 + z <<
".1.252.0";
284 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
285 addressHelperv4.
Assign(ndc0_1);
289 oss << 2001 + z <<
":1:252::";
291 addressHelperv6.
Assign(ndc0_1);
295 for (
int i = 0; i < 14; ++i)
297 nodes_net2[z][i].Create(1);
298 stack.Install(nodes_net2[z][i]);
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));
315 for (
int i = 0; i < 14; ++i)
317 ndc2[i] = p2p_1gb5ms.
Install(nodes_net2[z][i]);
320 for (
int i = 0; i < 7; ++i)
325 oss << 10 + z <<
".4." << 15 + i <<
".0";
326 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
330 oss << 2001 + z <<
":4:" << 15 + i <<
"::";
333 for (
int j = 0; j < nLANClients; ++j)
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]);
341 ifs2LanRemoteAddress[z][i][j] =
347 ifs2LanRemoteAddress[z][i][j] =
354 std::cout <<
" 3 ]" << std::endl;
355 for (
int i = 0; i < 9; ++i)
357 nodes_net3[z][i].Create(1);
358 stack.Install(nodes_net3[z][i]);
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));
370 for (
int i = 0; i < 9; ++i)
372 ndc3[i] = p2p_1gb5ms.
Install(nodes_net3[z][i]);
375 for (
int i = 0; i < 5; ++i)
380 oss << 10 + z <<
".5." << 10 + i <<
".0";
381 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
385 oss << 2001 + z <<
":5:" << 10 + i <<
"::";
388 for (
int j = 0; j < nLANClients; ++j)
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]);
396 ifs3LanRemoteAddress[z][i][j] =
402 ifs3LanRemoteAddress[z][i][j] =
408 std::cout <<
" Connecting Subnets..." << std::endl;
411 stack.Install(nodes_netLR[z]);
413 ndcLR = p2p_1gb5ms.
Install(nodes_netLR[z]);
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));
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);
452 oss << 10 + z <<
".1.253.0";
453 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
454 addressHelperv4.
Assign(ndc0_4);
457 oss << 10 + z <<
".1.254.0";
458 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
459 addressHelperv4.
Assign(ndc0_5);
462 oss << 10 + z <<
".4.253.0";
463 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
464 addressHelperv4.
Assign(ndc2_4a);
467 oss << 10 + z <<
".4.254.0";
468 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
469 addressHelperv4.
Assign(ndc2_4b);
472 oss << 10 + z <<
".5.253.0";
473 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
474 addressHelperv4.
Assign(ndc3_5a);
477 oss << 10 + z <<
".5.254.0";
478 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
479 addressHelperv4.
Assign(ndc3_5b);
485 oss << 2001 + z <<
":1:253::";
487 addressHelperv6.
Assign(ndc0_4);
490 oss << 2001 + z <<
":1:254::";
492 addressHelperv6.
Assign(ndc0_5);
495 oss << 2001 + z <<
":4:253::";
497 addressHelperv6.
Assign(ndc2_4a);
500 oss << 2001 + z <<
":4:254::";
502 addressHelperv6.
Assign(ndc2_4b);
505 oss << 2001 + z <<
":5:253::";
507 addressHelperv6.
Assign(ndc3_5a);
510 oss << 2001 + z <<
":5:254::";
512 addressHelperv6.
Assign(ndc3_5b);
515 std::cout <<
" Assigning IP addresses..." << std::endl;
516 for (
int i = 0; i < 3; ++i)
521 oss << 10 + z <<
".1." << 1 + i <<
".0";
522 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
523 addressHelperv4.
Assign(ndc0[i]);
527 oss << 2001 + z <<
":1:" << 1 + i <<
"::";
529 addressHelperv6.
Assign(ndc0[i]);
532 for (
int i = 0; i < 6; ++i)
541 oss << 10 + z <<
".2." << 1 + i <<
".0";
542 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
543 addressHelperv4.
Assign(ndc1[i]);
547 oss << 2001 + z <<
":2:" << 1 + i <<
"::";
549 addressHelperv6.
Assign(ndc1[i]);
555 oss << 10 + z <<
".3.1.0";
556 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
557 addressHelperv4.
Assign(ndcLR);
561 oss << 2001 + z <<
":3:1::";
563 addressHelperv6.
Assign(ndcLR);
565 for (
int i = 0; i < 14; ++i)
570 oss << 10 + z <<
".4." << 1 + i <<
".0";
571 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
572 addressHelperv4.
Assign(ndc2[i]);
576 oss << 2001 + z <<
":4:" << 1 + i <<
"::";
578 addressHelperv6.
Assign(ndc2[i]);
581 for (
int i = 0; i < 9; ++i)
586 oss << 10 + z <<
".5." << 1 + i <<
".0";
587 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
588 addressHelperv4.
Assign(ndc3[i]);
592 oss << 2001 + z <<
":5:" << 1 + i <<
"::";
594 addressHelperv6.
Assign(ndc3[i]);
601 std::cout <<
"Forming Ring Topology..." << std::endl;
603 for (
int z = 0; z < nCN - 1; ++z)
605 nodes_ring[z].
Add(nodes_net0[z][0].Get(0));
606 nodes_ring[z].
Add(nodes_net0[z + 1][0].Get(0));
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));
611 for (
int z = 0; z < nCN; ++z)
613 ndc_ring[z] = p2p_2gb200ms.
Install(nodes_ring[z]);
617 oss <<
"254.1." << z + 1 <<
".0";
618 addressHelperv4.
SetBase(oss.str().c_str(),
"255.255.255.0");
619 addressHelperv4.
Assign(ndc_ring[z]);
623 oss <<
"254:1:" << z + 1 <<
"::";
625 addressHelperv6.
Assign(ndc_ring[z]);
633 std::cout <<
"Creating TCP Traffic Flows:" << std::endl;
636 StringValue(
"ns3::ConstantRandomVariable[Constant=1.0]"));
638 StringValue(
"ns3::ConstantRandomVariable[Constant=0.0]"));
655 for (
int z = 0; z < nCN; ++z)
663 std::cout <<
" Campus Network " << z <<
" Flows [ Net2 ";
664 for (
int i = 0; i < 7; ++i)
666 for (
int j = 0; j < nLANClients; ++j)
676 AddressValue remoteAddress(ifs2LanRemoteAddress[z][i][j]);
677 client.SetAttribute(
"Remote", remoteAddress);
679 clientApp.
Add(client.Install(nodes_net1[x][r1].Get(0)));
684 std::cout <<
"Net3 ]" << std::endl;
685 for (
int i = 0; i < 5; ++i)
687 for (
int j = 0; j < nLANClients; ++j)
697 AddressValue remoteAddress(ifs3LanRemoteAddress[z][i][j]);
698 client.SetAttribute(
"Remote", remoteAddress);
700 clientApp.
Add(client.Install(nodes_net1[x][r1].Get(0)));
706 std::cout <<
"Created " << NodeList::GetNNodes() <<
" nodes." << std::endl;
707 auto routingStart = std::chrono::steady_clock::now();
712 std::cout <<
"Using Nix-vectors..." << std::endl;
717 std::cout <<
"Populating Global Static Routing Tables..." << std::endl;
718 Ipv4GlobalRoutingHelper::PopulateRoutingTables();
721 auto routingEnd = std::chrono::steady_clock::now();
723 <<
"Routing tables population took "
724 << std::chrono::duration_cast<std::chrono::milliseconds>(routingEnd - routingStart).count()
725 <<
"ms" << std::endl;
728 std::cout <<
"Running simulator..." << std::endl;
729 auto t1 = std::chrono::steady_clock::now();
730 Simulator::Stop(
Seconds(100.0));
732 auto t2 = std::chrono::steady_clock::now();
733 std::cout <<
"Simulator finished." << std::endl;
734 Simulator::Destroy();
736 auto d1 = std::chrono::duration_cast<std::chrono::seconds>(t1 - t0);
737 auto d2 = std::chrono::duration_cast<std::chrono::seconds>(t2 - t1);
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;
744 delete[] nodes_netLR;
2D array used in nix-vector-routing example "nms-p2p-nix.cc"
Array2D(const size_t x, const size_t y)
Constructor.
T * operator[](const size_t i)
Accessor operator.
const size_t m_xMax
maximum number of rows
3D array used in nix-vector-routing example "nms-p2p-nix.cc"
Array3D(const size_t x, const size_t y, const size_t z)
Constructor.
const size_t m_xMax
maximum number of rows
Array2D< T > ** p
Stored elements.
Array2D< T > & operator[](const size_t i)
Accessor operator.
a polymophic address class
AttributeValue implementation for Address.
holds a vector of ns3::Application pointers.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the 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.
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...
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.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Describes an IPv6 prefix.
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 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.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
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)
Hold variables of type string.
Hold an unsigned integer type.
void SetDefault(std::string name, const AttributeValue &value)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.