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++)
115 template <
typename T>
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++)
162 main(
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;
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;
410 nodes_netLR[z].Create(2);
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)
673 r1 = 2 + (int)(4 * urng->
GetValue());
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)
694 r1 = 2 + (int)(4 * urng->
GetValue());
700 clientApp.
Add(
client.Install(nodes_net1[
x][r1].Get(0)));
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;
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();
732 auto t2 = std::chrono::steady_clock::now();
733 std::cout <<
"Simulator finished." << std::endl;
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.
const size_t m_xMax
maximum number of rows
T * operator[](const size_t i)
Accessor operator.
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.
Array2D< T > & operator[](const size_t i)
Accessor operator.
const size_t m_xMax
maximum number of rows
Array2D< T > ** p
Stored elements.
a polymophic address class
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.
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.
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()
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)
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static void Run()
Run the simulation.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
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.