NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
Overall ndnSIM documentation

Examples

Note

!!! This page only shows up examples of how to config topology and perform basic operations in ndnSIM (an example equivalent to “Hello, world1”) !!! These are **NOT** examples of real experimentations (just like “Hello, world!” is not a real program).

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

Simple scenario

The first example (ndn-simple.cc) shows very basics of ndnSIM. In the simulated topology there are 3 nodes, connected with point-to-point links, one NDN consumer, and one NDN producer:

Consumer is simulated using ConsumerCbr reference application and generates Interests towards the producer with frequency of 10 Interests per second (see ndnSIM applications).

Producer is simulated using Producer class, which is used to satisfy all incoming Interests with virtual payload data (1024 bytes).

FIB on every node is populated using default routes (see ndnSIM helpers).

The following code represents all that is necessary to run such a simple scenario

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// ndn-simple.cc
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/ndnSIM-module.h"

using namespace ns3;

int 
main (int argc, char *argv[])
{
  // setting default parameters for PointToPoint links and channels
  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
  Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("10ms"));
  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));

  // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
  CommandLine cmd;
  cmd.Parse (argc, argv);

  // Creating nodes
  NodeContainer nodes;
  nodes.Create (3);

  // Connecting nodes using two links
  PointToPointHelper p2p;
  p2p.Install (nodes.Get (0), nodes.Get (1));
  p2p.Install (nodes.Get (1), nodes.Get (2));

  // Install NDN stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetDefaultRoutes (true);
  ndnHelper.InstallAll ();

  // Installing applications

  // Consumer
  ndn::AppHelper consumerHelper ("ns3::ndn::ConsumerCbr");
  // Consumer will request /prefix/0, /prefix/1, ...
  consumerHelper.SetPrefix ("/prefix");
  consumerHelper.SetAttribute ("Frequency", StringValue ("10")); // 10 interests a second
  consumerHelper.Install (nodes.Get (0)); // first node

  // Producer
  ndn::AppHelper producerHelper ("ns3::ndn::Producer");
  // Producer will reply to all requests starting with /prefix
  producerHelper.SetPrefix ("/prefix");
  producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));
  producerHelper.Install (nodes.Get (2)); // last node

  Simulator::Stop (Seconds (20.0));

  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

If this code is placed into scratch/ndn-simple.cc and NS-3 is compiled in debug mode, you can run and see progress of the simulation using the following command (in optimized mode nothing will be printed out):

NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-simple

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

9-node grid example

This scenario (ndn-grid.cc) simulates a grid topology, which is constructed using PointToPointLayout NS-3 module

FIB is populated using GlobalRoutingHelper (see ndnSIM helpers).

Consumer is simulated using ConsumerCbr reference application and generates Interests towards the producer with frequency of 100 interests per second (see ndnSIM applications).

Producer is simulated using Producer class, which is used to satisfy all incoming Interests with virtual payload data (1024 bytes).

The following code represents all that is necessary to run such a simple scenario

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// ndn-grid.cc
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/point-to-point-layout-module.h"
#include "ns3/ndnSIM-module.h"

using namespace ns3;
int
main (int argc, char *argv[])
{
  // Setting default parameters for PointToPoint links and channels
  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
  Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("10ms"));
  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("10"));

  // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
  CommandLine cmd;
  cmd.Parse (argc, argv);

  // Creating 3x3 topology
  PointToPointHelper p2p;
  PointToPointGridHelper grid (3, 3, p2p);
  grid.BoundingBox(100,100,200,200);

  // Install NDN stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
  ndnHelper.InstallAll ();

  // Installing global routing interface on all nodes
  ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
  ndnGlobalRoutingHelper.InstallAll ();

  // Getting containers for the consumer/producer
  Ptr<Node> producer = grid.GetNode (2, 2);
  NodeContainer consumerNodes;
  consumerNodes.Add (grid.GetNode (0,0));

  // Install NDN applications
  std::string prefix = "/prefix";

  ndn::AppHelper consumerHelper ("ns3::ndn::ConsumerCbr");
  consumerHelper.SetPrefix (prefix);
  consumerHelper.SetAttribute ("Frequency", StringValue ("100")); // 100 interests a second
  consumerHelper.Install (consumerNodes);

  ndn::AppHelper producerHelper ("ns3::ndn::Producer");
  producerHelper.SetPrefix (prefix);
  producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));
  producerHelper.Install (producer);

  // Add /prefix origins to ndn::GlobalRouter
  ndnGlobalRoutingHelper.AddOrigins (prefix, producer);

  // Calculate and install FIBs
  ndn::GlobalRoutingHelper::CalculateRoutes ();

  Simulator::Stop (Seconds (20.0));

  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

If this code is placed into scratch/ndn-grid.cc and NS-3 is compiled in debug mode, you can run and see progress of the simulation using the following command (in optimized mode nothing will be printed out):

NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-grid

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

9-node grid example using topology plugin

Instead of defining topology directly as in Simple scenario or using specialized helpers as in 9-node grid example, ndnSIM provides experimental extended versions of TopologyReader classes: AnnotatedTopologyReader and RocketfuelWeightsReader.

While RocketfuelWeightsReader is a specialized version intended to be used with Rocketfuel topology and link weights files (examples will be provided later), AnnotatedTopologyReader is a more general-use class that uses simple user-readable format.

AnnotatedTopologyReader expects the following format:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# topo-grid-3x3.txt

# any empty lines and lines starting with '#' symbol is ignored
#
# The file should contain exactly two sections: router and link, each starting with the corresponding keyword
#
# router section defines topology nodes and their relative positions (e.g., to use in visualizer)
router

# each line in this section represents one router and should have the following data
# node  comment     yPos    xPos
Node0   NA          3       1
Node1   NA          3       2
Node2   NA          3       3
Node3   NA          2       1
Node4   NA          2       2
Node5   NA          2       3
Node6   NA          1       1
Node7   NA          1       2
Node8   NA          1       3
# Note that `node` can be any string. It is possible to access to the node by name using Names::Find, see examples.

# link section defines point-to-point links between nodes and characteristics of these links
link

# Each line should be in the following format (only first two are required, the rest can be omitted)
# srcNode   dstNode     bandwidth   metric  delay   queue
# bandwidth: link bandwidth
# metric: routing metric
# delay:  link delay
# queue:  MaxPackets for transmission queue on the link (both directions)
Node0       Node1       1Mbps       1       10ms    10
Node0       Node3       1Mbps       1       10ms    10
Node1       Node2       1Mbps       1       10ms    10
Node1       Node4       1Mbps       1       10ms    10
Node2       Node5       1Mbps       1       10ms    10
Node3       Node4       1Mbps       1       10ms    10
Node3       Node6       1Mbps       1       10ms    10
Node4       Node5       1Mbps       1       10ms    10
Node4       Node7       1Mbps       1       10ms    10
Node5       Node8       1Mbps       1       10ms    10
Node6       Node7       1Mbps       1       10ms    10
Node7       Node8       1Mbps       1       10ms    10

This scenario (ndn-grid-topo-plugin.cc) duplicates the functionality of 9-node grid example but with the use of AnnotatedTopologyReader.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// ndn-grid-topo-plugin.cc
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"

using namespace ns3;

int
main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);

  AnnotatedTopologyReader topologyReader ("", 25);
  topologyReader.SetFileName ("src/ndnSIM/examples/topologies/topo-grid-3x3.txt");
  topologyReader.Read ();

  // Install NDN stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
  ndnHelper.InstallAll ();

  // Installing global routing interface on all nodes
  ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
  ndnGlobalRoutingHelper.InstallAll ();

  // Getting containers for the consumer/producer
  Ptr<Node> producer = Names::Find<Node> ("Node8");
  NodeContainer consumerNodes;
  consumerNodes.Add (Names::Find<Node> ("Node0"));

  // Install NDN applications
  std::string prefix = "/prefix";

  ndn::AppHelper consumerHelper ("ns3::ndn::ConsumerCbr");
  consumerHelper.SetPrefix (prefix);
  consumerHelper.SetAttribute ("Frequency", StringValue ("100")); // 100 interests a second
  consumerHelper.Install (consumerNodes);

  ndn::AppHelper producerHelper ("ns3::ndn::Producer");
  producerHelper.SetPrefix (prefix);
  producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));
  producerHelper.Install (producer);

  // Add /prefix origins to ndn::GlobalRouter
  ndnGlobalRoutingHelper.AddOrigins (prefix, producer);

  // Calculate and install FIBs
  ndn::GlobalRoutingHelper::CalculateRoutes ();

  Simulator::Stop (Seconds (20.0));

  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

As you can see, scenario code became more compact and more readable.

AnnotatedTopologyReader provides two ways to access topology nodes. First, you can use the method AnnotatedTopologyReader::GetNodes() which returns NodeContainer.

Alternatively, nodes can be accessed by name using Names::Find<Node> (“nodename”) call, as in the above example. For this purpose,:ndnsim:AnnotatedTopologyReader automatically registers all created nodes with names specified in topology file. For more information about Names class, please refer to NS-3 documentation .

If the topology file is placed into src/ndnSIM/examples/topologies/topo-grid-3x3.txt and the code is placed into scratch/ndn-grid-topo-plugin.cc, you can run and see progress of the simulation using the following command (in optimized mode nothing will be printed out):

NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-grid-topo-plugin

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

6-node bottleneck topology

This scenario (ndn-congestion-topo-plugin.cc) can be used for congestion-related scenarios

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# topo-6-node.txt

router

# node  comment     yPos    xPos
Src1   NA        1       3
Src2   NA        3       3
Rtr1   NA        2       5
Rtr2   NA        2       7
Dst1   NA        1       9
Dst2   NA        3       9

link

# srcNode   dstNode     bandwidth   metric  delay   queue
Src1        Rtr1        10Mbps      1        10ms    20
Src2        Rtr1        10Mbps      1        10ms    20
Rtr1        Rtr2        1Mbps       1        10ms    20
Dst1        Rtr2        10Mbps      1        10ms    20
Dst2        Rtr2        10Mbps      1        10ms    20
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// ndn-congestion-topo-plugin.cc
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"

using namespace ns3;

int
main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);

  AnnotatedTopologyReader topologyReader ("", 25);
  topologyReader.SetFileName ("src/ndnSIM/examples/topologies/topo-6-node.txt");
  topologyReader.Read ();

  // Install NDN stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
  ndnHelper.SetContentStore ("ns3::ndn::cs::Lru",
                              "MaxSize", "10000");
  ndnHelper.InstallAll ();

  // Installing global routing interface on all nodes
  ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
  ndnGlobalRoutingHelper.InstallAll ();

  // Getting containers for the consumer/producer
  Ptr<Node> consumer1 = Names::Find<Node> ("Src1");
  Ptr<Node> consumer2 = Names::Find<Node> ("Src2");

  Ptr<Node> producer1 = Names::Find<Node> ("Dst1");
  Ptr<Node> producer2 = Names::Find<Node> ("Dst2");

  ndn::AppHelper consumerHelper ("ns3::ndn::ConsumerCbr");
  consumerHelper.SetAttribute ("Frequency", StringValue ("100")); // 100 interests a second

  // on the first consumer node install a Consumer application
  // that will express interests in /dst1 namespace
  consumerHelper.SetPrefix ("/dst1");
  consumerHelper.Install (consumer1);

  // on the second consumer node install a Consumer application
  // that will express interests in /dst2 namespace
  consumerHelper.SetPrefix ("/dst2");
  consumerHelper.Install (consumer2);
  
  ndn::AppHelper producerHelper ("ns3::ndn::Producer");
  producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));  

  // Register /dst1 prefix with global routing controller and
  // install producer that will satisfy Interests in /dst1 namespace
  ndnGlobalRoutingHelper.AddOrigins ("/dst1", producer1);
  producerHelper.SetPrefix ("/dst1");
  producerHelper.Install (producer1);

  // Register /dst2 prefix with global routing controller and
  // install producer that will satisfy Interests in /dst2 namespace
  ndnGlobalRoutingHelper.AddOrigins ("/dst2", producer2);
  producerHelper.SetPrefix ("/dst2");
  producerHelper.Install (producer2);

  // Calculate and install FIBs
  ndn::GlobalRoutingHelper::CalculateRoutes ();

  Simulator::Stop (Seconds (20.0));

  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

To run this scenario and see what is happening, use the following command:

NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-congestion-topo-plugin

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

11-node 2-bottleneck topology with custom forwarding strategy

To effectively use the example custom strategy, we need to make sure that FIB entries contain at least two entries. In the current version of ndnSIM, this can be accomplished using manual route configuration.

The following example illustrates how the strategy can be used in simulation scenario.

Let us first define a meaningful topology:

The corresponding topology file (topo-11-node-two-bottlenecks.txt):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# topo-11-node-two-bottlenecks.txt

router

#name   city    latitude  longitude
c1      NA      50        30
c2      NA    	30        30
c3      NA    	10        30
c4      NA    	10        40
n1      NA    	40        40
n12     NA    	30        60
n2      NA    	40        80
p1      NA    	50        90
p2      NA    	30        90
p3      NA    	10        90
p4      NA    	10        80

link

#x      y       capacity(kbps)  OSPF    Delay   MaxPackets
c1      n1      10Mbps          1       50ms    200
c2      n1      10Mbps          1       10ms    200
c3      n1      10Mbps          1       100ms   200
c4      n1      10Mbps          1       1ms     200
n1      n2      1Mbps           1176    20ms    20 
n1      n12     1Mbps           587     1ms     20
n12     n2      1Mbps           846     1ms     20
n2      p1      10Mbps          260     1ms     200
n2      p2      10Mbps          700     1ms     200
n2      p3      10Mbps          1       1ms     200
n2      p4      10Mbps          1       1ms     200

Example simulation (ndn-congestion-alt-topo-plugin.cc) scenario that utilizes CustomStrategy forwarding strategy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// ndn-congestion-alt-topo-plugin.cc

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"

using namespace ns3;

int
main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);

  AnnotatedTopologyReader topologyReader ("", 1);
  topologyReader.SetFileName ("src/ndnSIM/examples/topologies/topo-11-node-two-bottlenecks.txt");
  topologyReader.Read ();

  // Install NDN stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetForwardingStrategy ("ns3::ndn::fw::CustomStrategy");
  ndnHelper.SetContentStore ("ns3::ndn::cs::Lru",
                              "MaxSize", "1"); // ! Attention ! If set to 0, then MaxSize is infinite
  ndnHelper.InstallAll ();

  // Getting containers for the consumer/producer
  Ptr<Node> consumers[4] = { Names::Find<Node> ("c1"), Names::Find<Node> ("c2"), Names::Find<Node> ("c3"), Names::Find<Node> ("c4") };
  Ptr<Node> producers[4] = { Names::Find<Node> ("p1"), Names::Find<Node> ("p2"), Names::Find<Node> ("p3"), Names::Find<Node> ("p4") };

  if (consumers[0] == 0 || consumers[1] == 0 || consumers[2] == 0 || consumers[3] == 0 ||
      producers[0] == 0 || producers[1] == 0 || producers[2] == 0 || producers[3] == 0)
    {
      NS_FATAL_ERROR ("Error in topology: one nodes c1, c2, c3, c4, p1, p2, p3, or p4 is missing");
    }

  for (int i = 0; i < 4; i++)
    {
      std::string prefix = "/data/"+Names::FindName (producers[i]);
      
      /////////////////////////////////////////////////////////////////////////////////
      // install consumer app on consumer node c_i to request data from producer p_i //
      /////////////////////////////////////////////////////////////////////////////////

      ndn::AppHelper consumerHelper ("ns3::ndn::ConsumerCbr");
      consumerHelper.SetAttribute ("Frequency", StringValue ("10")); // 100 interests a second
      
      consumerHelper.SetPrefix (prefix);
      ApplicationContainer consumer = consumerHelper.Install (consumers[i]);
      consumer.Start (Seconds (i));    // start consumers at 0s, 1s, 2s, 3s
      consumer.Stop  (Seconds (19-i)); // stop consumers at 19s, 18s, 17s, 16s
      
      ///////////////////////////////////////////////
      // install producer app on producer node p_i //
      ///////////////////////////////////////////////
            
      ndn::AppHelper producerHelper ("ns3::ndn::Producer");
      producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));  

      // install producer that will satisfy Interests in /dst1 namespace
      producerHelper.SetPrefix (prefix);
      ApplicationContainer producer = producerHelper.Install (producers[i]);
      // when Start/Stop time is not specified, the application is running throughout the simulation
    }

  // Manually configure FIB routes
  ndn::StackHelper::AddRoute	("c1", "/data", "n1", 1); // link to n1
  ndn::StackHelper::AddRoute	("c2", "/data", "n1", 1); // link to n1
  ndn::StackHelper::AddRoute	("c3", "/data", "n1", 1); // link to n1
  ndn::StackHelper::AddRoute	("c4", "/data", "n1", 1); // link to n1

  ndn::StackHelper::AddRoute	("n1", "/data", "n2", 1); // link to n2
  ndn::StackHelper::AddRoute	("n1", "/data", "n12", 2); // link to n12

  ndn::StackHelper::AddRoute	("n12", "/data", "n2", 1); // link to n2

  ndn::StackHelper::AddRoute	("n2", "/data/p1", "p1", 1); // link to p1
  ndn::StackHelper::AddRoute	("n2", "/data/p2", "p2", 1); // link to p2
  ndn::StackHelper::AddRoute	("n2", "/data/p3", "p3", 1); // link to p3
  ndn::StackHelper::AddRoute	("n2", "/data/p4", "p4", 1); // link to p4

  // Schedule simulation time and run the simulation
  Simulator::Stop (Seconds (20.0));
  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

To run this scenario and see what is happening, use the following command:

NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-congestion-alt-topo-plugin

You can also run using visualizer module to verify that both bottleneck links are utilized:

./waf --run=ndn-congestion-alt-topo-plugin --visualize

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

3-level binary tree with packet-level trace helpers

Example of packet-level trace helpers

3-level binary tree with content store trace helper

Example of content store trace helper

3-level binary tree with application-level Interest-Data delay tracer

Example of application-level trace helper

3-node topology with Content Store respecting freshness field of ContentObjects

Content stores respecting freshness field of ContentObjects

1-node topology with custom application

Custom applications

Simple scenario with pcap dump

The following example (ndn-simple-with-pcap.cc) demonstrates how to dump all simulated traffic in pcap-formatted data, which can be used for later analysis by conventional tools, like tcpdump and wireshark.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// ndn-simple-with-pcap.cc
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/ndnSIM-module.h"

using namespace ns3;

class PcapWriter
{
public:
  PcapWriter (const std::string &file)
  {
    PcapHelper helper;
    m_pcap = helper.CreateFile (file, std::ios::out, PcapHelper::DLT_PPP);
  }

  void
  TracePacket (Ptr<const Packet> packet)
  {
    static PppHeader pppHeader;
    pppHeader.SetProtocol (0x0077);

    m_pcap->Write (Simulator::Now (), pppHeader, packet);
  }

private:
  Ptr<PcapFileWrapper> m_pcap;
};


int
main (int argc, char *argv[])
{
  // setting default parameters for PointToPoint links and channels
  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
  Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("10ms"));
  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));

  Config::SetGlobal ("ndn::WireFormat", StringValue ("1"));

  // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
  CommandLine cmd;
  cmd.Parse (argc, argv);
  
  // Creating nodes
  NodeContainer nodes;
  nodes.Create (3);

  // Connecting nodes using two links
  PointToPointHelper p2p;
  p2p.Install (nodes.Get (0), nodes.Get (1));
  p2p.Install (nodes.Get (1), nodes.Get (2));

  // Install NDN stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetDefaultRoutes (true);
  ndnHelper.InstallAll ();

  // Installing applications

  // Consumer
  ndn::AppHelper consumerHelper ("ns3::ndn::ConsumerCbr");
  // Consumer will request /prefix/0, /prefix/1, ...
  consumerHelper.SetPrefix ("/prefix");
  consumerHelper.SetAttribute ("Frequency", StringValue ("10")); // 10 interests a second
  consumerHelper.Install (nodes.Get (0)); // first node

  // Producer
  ndn::AppHelper producerHelper ("ns3::ndn::Producer");
  // Producer will reply to all requests starting with /prefix
  producerHelper.SetPrefix ("/prefix");
  producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));
  producerHelper.SetAttribute ("Signature", UintegerValue (100));
  producerHelper.SetAttribute ("KeyLocator", StringValue ("/unique/key/locator"));
  producerHelper.Install (nodes.Get (2)); // last node

  PcapWriter trace ("ndn-simple-trace.pcap");
  Config::ConnectWithoutContext ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacTx",
				 MakeCallback (&PcapWriter::TracePacket, &trace));

  Simulator::Stop (Seconds (20.0));

  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

If this code is placed into scratch/ndn-simple-with-pcap.cc and NS-3 is compiled in debug mode, you can run and see progress of the simulation using the following command (in optimized mode nothing will be printed out):

NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-simple-with-pcap

This will generate ndn-simple-trace.pcap, which can be fed to tcpdump:

tcpdump -r ndn-simple-trace.pcap

Note

If you compiled ndnSIM with examples (./waf configure --enable-examples) you can directly run the example without putting scenario into scratch/ folder.

25-node tree topology with L2Tracer

Example of packet drop tracer (L2Tracer)

3-node topology with periodic tracing of PIT

Periodic tracing of Pending Interest Table (PIT) size