lengyijun
12/29/2018 - 6:22 AM

my.cc

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
 * Author: Valerio Sartini <valesar@gmail.com>
 *
 * This program conducts a simple experiment: It builds up a topology based on
 * either Inet or Orbis trace files. A random node is then chosen, and all the
 * other nodes will send a packet to it. The TTL is measured and reported as an histogram.
 *
 */

#include <ctime>
#include <sstream>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-nix-vector-helper.h"
#include "ns3/csma-module.h"
#include "ns3/topology-read-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TopologyCreationExperiment");

int main (int argc, char *argv[])
{

  std::string format ("Inet");
  std::string input ("src/topology-read/examples/Inet_small_toposample.txt");

  // Set up command line parameters used to control the experiment.
  CommandLine cmd;
  cmd.AddValue ("format", "Format to use for data input [Orbis|Inet|Rocketfuel].",
                format);
  cmd.AddValue ("input", "Name of the input file.",
                input);
  cmd.Parse (argc, argv);


  // ------------------------------------------------------------
  // -- Read topology data.
  // --------------------------------------------

  // Pick a topology reader based in the requested format.
  TopologyReaderHelper topoHelp;
  topoHelp.SetFileName (input);
  topoHelp.SetFileType (format);
  Ptr<TopologyReader> inFile = topoHelp.GetTopologyReader ();

  NodeContainer nodes;

  if (inFile != 0)
    {
      nodes = inFile->Read ();
    }

  if (inFile->LinksSize () == 0)
    {
      NS_LOG_ERROR ("Problems reading the topology file. Failing.");
      return -1;
    }

  // ------------------------------------------------------------
  // -- Create nodes and network stacks
  // --------------------------------------------
  // NS_LOG_INFO ("creating internet stack");
  InternetStackHelper stack;

  // Setup NixVector Routing
  // Ipv4NixVectorHelper nixRouting;
  // stack.SetRoutingHelper (nixRouting);  // has effect on the next Install ()
  stack.Install (nodes);

  NS_LOG_INFO ("creating node containers");
  NodeContainer* nc = new NodeContainer[nodes.GetN()];
  NetDeviceContainer* nd=new NetDeviceContainer[nodes.GetN()];
  TopologyReader::ConstLinksIterator iter;
  std::vector<std::vector<int>> array(nodes.GetN());

  unsigned int i;
  for(i=0;i<nodes.GetN();i++){
    nc[i].Add(nodes.Get(i));
  }

  for ( iter = inFile->LinksBegin (); iter != inFile->LinksEnd (); iter++ )
    {
      int from= std::stoi (iter->GetFromNodeName());
      int to=std::stoi(iter->GetToNodeName());

      nc[from].Add(iter->GetToNode());
      nc[to].Add(iter->GetFromNode());

      array[to].push_back(from);
      array[from].push_back(to);
    }

  CsmaHelper csma;
  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));

  NS_LOG_INFO ("creating ip4 addresses");
  Ipv4AddressHelper address;
  address.SetBase ("10.0.0.0", "255.255.255.0");

  NS_LOG_INFO ("creating net device containers");
  for(i=0;i<nodes.GetN();i++){
    nd[i] = csma.Install (nc[i]); 
    address.Assign (nd[i]);
    address.NewNetwork ();
  }

  Ipv4Address multicastSource ("10.0.0.1");
  Ipv4Address multicastGroup ("225.1.2.4");
 
  Ipv4StaticRoutingHelper multicast;

  std::vector<int>::iterator veciter;
  std::vector<int>::iterator veciter1;

  NS_LOG_INFO ("Loop Begin");

  //start at 1 , not 0
  for(i=1;i<nodes.GetN();i++){
    Ptr<Node> multicastRouter =nodes.Get (i);  // The node in question
    for(unsigned int j=0;j<multicastRouter->GetNDevices();j++)
    {
      Ptr<NetDevice> inputIf =multicastRouter->GetDevice(j);
      NetDeviceContainer outputDevices;  // A container of output NetDevices
      NS_LOG_INFO ("Small Loop Begin");
      for(unsigned int k=0;k<multicastRouter->GetNDevices();k++){
        if( k!=j ){
          outputDevices.Add (multicastRouter->GetDevice(k));  
        }
      }
      NS_LOG_INFO ("Small Loop End");
      multicast.AddMulticastRoute (multicastRouter, multicastSource,  multicastGroup, inputIf, outputDevices); 
    }
  }
  NS_LOG_INFO ("Loop End");

  Ptr<Node> sender = nodes.Get (0);
  Ptr<NetDevice> senderIf = nd[0].Get (0);  //maybe??
  multicast.SetDefaultMulticastRoute (sender, senderIf);

  NS_LOG_INFO ("Create Applications.");

  uint16_t multicastPort = 9;   // Discard port (RFC 863)

  // Configure a multicast packet generator that generates a packet
  // every few seconds
  OnOffHelper onoff ("ns3::UdpSocketFactory", 
                     Address (InetSocketAddress (multicastGroup, multicastPort)));
  onoff.SetConstantRate (DataRate ("255b/s"));
  onoff.SetAttribute ("PacketSize", UintegerValue (128));

  ApplicationContainer srcC = onoff.Install (nc[0].Get (0));

  //
  // Tell the application when to start and stop.
  //
  srcC.Start (Seconds (1.));
  srcC.Stop (Seconds (10.));

  // Create an optional packet sink to receive these packets
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
                         InetSocketAddress (Ipv4Address::GetAny (), multicastPort));

  ApplicationContainer sinkC = sink.Install (nc[1].Get (0)); // Node n4
  // Start the sink
  sinkC.Start (Seconds (1.0));
  sinkC.Stop (Seconds (10.0));

  NS_LOG_INFO ("Configure Tracing.");
  //
  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
  // Ascii trace output will be sent to the file "csma-multicast.tr"
  //
  AsciiTraceHelper ascii;
  csma.EnableAsciiAll (ascii.CreateFileStream ("my.tr"));

  // Also configure some tcpdump traces; each interface will be traced.
  // The output files will be named:
  //     csma-multicast-<nodeId>-<interfaceId>.pcap
  // and can be read by the "tcpdump -r" command (use "-tt" option to
  // display timestamps correctly)
  csma.EnablePcapAll ("csma-multicast", false);
  NS_LOG_INFO ("Run Simulation.");
  Simulator::Run ();
  Simulator::Destroy ();

  delete[] nd;
  delete[] nc;

  NS_LOG_INFO ("Done.");

  return 0;
}