NS3 node talks to Mininet host

 

[tap-csma2.cc] (put this file under scratch)

/* -*- 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

 */

 

#include <iostream>

#include <fstream>

#include "ns3/core-module.h"

#include "ns3/network-module.h"

#include "ns3/wifi-module.h"

#include "ns3/csma-module.h"

#include "ns3/internet-module.h"

#include "ns3/ipv4-global-routing-helper.h"

#include "ns3/tap-bridge-module.h"

#include "ns3/applications-module.h"

 

using namespace ns3;

 

NS_LOG_COMPONENT_DEFINE ("TapCsma2Example");

 

void SendStuff (Ptr<Socket> sock, Ipv4Address dstaddr, uint16_t port)

{

  std::cout << "SendStuff () called ..." << std::endl;

  Ptr<Packet> p = Create<Packet> (reinterpret_cast<uint8_t const *> ("I am long 20 bytes!"), 20);

  //p->AddPaddingAtEnd (100);

  sock->SendTo (p, 0, InetSocketAddress (dstaddr,port));

  return;

}

 

int

main (int argc, char *argv[])

{

 

  std::string mode = "UseLocal";

  CommandLine cmd (__FILE__);

  std::string remote ("10.1.1.10");

  cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);

 

  cmd.Parse (argc, argv);

 

  //std::cout << "remote=" << remote << std::endl;

  Ipv4Address remoteIp (remote.c_str ());

 

  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));

  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));

 

  NodeContainer nodes;

  nodes.Create (4);

 

  CsmaHelper csma;

  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));

  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));

 

  NetDeviceContainer devices = csma.Install (nodes);

 

  InternetStackHelper stack;

stack.Install (nodes);

 

  Ipv4AddressHelper addresses;

  addresses.SetBase ("10.1.1.0", "255.255.255.0");

 

  Ipv4InterfaceContainer interfaces = addresses.Assign (devices);

 

  TapBridgeHelper tapBridge;

  tapBridge.SetAttribute ("Mode", StringValue (mode));

  tapBridge.SetAttribute ("DeviceName", StringValue ("mytap"));

  tapBridge.Install (nodes.Get (0), devices.Get (0));

 

  csma.EnablePcapAll ("tap-csma", false);

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

 

  Ptr<Socket> srcSocket = Socket::CreateSocket (nodes.Get(1), TypeId::LookupByName ("ns3::UdpSocketFactory"));

  srcSocket->Bind ();

  srcSocket->BindToNetDevice (devices.Get(1));

  Ipv4Address dstAddr = remoteIp;

  uint16_t dstPort = 9999;

  for (uint32_t i = 0; i < 500; i++) {

      Simulator::Schedule (Seconds (1 + i * 0.5), &SendStuff, srcSocket, dstAddr, dstPort);

  }

 

  Simulator::Stop (Seconds (600.));

  Simulator::Run ();

  Simulator::Destroy ();

}

 

[test-tap-csma.py]

#!/usr/bin/python

from mininet.net import Mininet

from mininet.node import Controller

from mininet.cli import CLI

from mininet.link import Intf

from mininet.log import setLogLevel, info

 

def myNetwork():

 

    net = Mininet( topo=None, build=False)

 

    info( '*** Adding controller\n' )

    net.addController(name='c0')

 

    info( '*** Add switches\n')

    s1 = net.addSwitch('s1')

    Intf( 'mytap', node=s1 )

 

    info( '*** Add hosts\n')

    h1 = net.addHost('h1', ip='10.1.1.10')

    h2 = net.addHost('h2', ip='10.1.1.11')

 

    info( '*** Add links\n')

    net.addLink(h1, s1)

    net.addLink(h2, s1)

 

    info( '*** Starting network\n')

    net.start()

    #h1.cmdPrint('dhclient '+h1.defaultIntf().name)

    CLI(net)

    net.stop()

 

if __name__ == '__main__':

    setLogLevel( 'info' )

    myNetwork()

 

[receive.py]  (h1 will receive the data sent from NS3 node)

import socket

 

HOST = '0.0.0.0'

PORT = 9999

 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind((HOST, PORT))

 

print('server start at: %s:%s' % (HOST, PORT))

print('wait for connection...')

 

while True:

    data, addr = s.recvfrom(1024)

    print 'recvfrom ' + str(addr) + ': ' + data

 

[Execution]

Open one terminal

 

Open another terminal

 

type xterm h1 to open another terminal for mininet host h1

 

Execute “python receive.py” to receive the data sent from NS3 node.

----------------------------------------------------------------------------------

Extension: when the mininet host receive the packets, the mininet host will send packets back to ns3 host.

 

[tap-csma2.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

 */

 

#include <iostream>

#include <fstream>

#include "ns3/core-module.h"

#include "ns3/network-module.h"

#include "ns3/wifi-module.h"

#include "ns3/csma-module.h"

#include "ns3/internet-module.h"

#include "ns3/ipv4-global-routing-helper.h"

#include "ns3/tap-bridge-module.h"

#include "ns3/applications-module.h"

 

using namespace ns3;

 

NS_LOG_COMPONENT_DEFINE ("TapCsma2Example");

 

void SendStuff (Ptr<Socket> sock, Ipv4Address dstaddr, uint16_t port)

{

  std::cout << "SendStuff () called ..." << std::endl;

  Ptr<Packet> p = Create<Packet> (reinterpret_cast<uint8_t const *> ("I am long 20 bytes!"), 20);

  //p->AddPaddingAtEnd (100);

  sock->SendTo (p, 0, InetSocketAddress (dstaddr,port));

  return;

}

 

void ReceivePacket (Ptr<Socket> socket)

{

  //Ptr<Packet> packet = socket->Recv ();

  //std::cout << "Received one packet!" << std::endl;

  Ptr<Packet> packet;

  uint32_t nodeIdr=socket->GetNode()->GetId();

  while ((packet = socket->Recv ()))

  {

    uint8_t buf[1300];

    packet->CopyData(buf , packet->GetSize());

    std::cout<<"Data, "<<buf<< ", SimulatorTime, "<<Simulator::Now().GetSeconds()<<" NodeIDR "<<nodeIdr<<std::endl;

  }

}

 

int

main (int argc, char *argv[])

{

 

  std::string mode = "UseLocal";

  CommandLine cmd (__FILE__);

  std::string remote ("10.1.1.10");

  cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);

 

  cmd.Parse (argc, argv);

 

  //std::cout << "remote=" << remote << std::endl;

  Ipv4Address remoteIp (remote.c_str ());

 

  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));

  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));

 

  NodeContainer nodes;

  nodes.Create (4);

 

  CsmaHelper csma;

  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));

  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));

 

  NetDeviceContainer devices = csma.Install (nodes);

 

  InternetStackHelper stack;

stack.Install (nodes);

 

  Ipv4AddressHelper addresses;

  addresses.SetBase ("10.1.1.0", "255.255.255.0");

 

  Ipv4InterfaceContainer interfaces = addresses.Assign (devices);

 

  TapBridgeHelper tapBridge;

  tapBridge.SetAttribute ("Mode", StringValue (mode));

  tapBridge.SetAttribute ("DeviceName", StringValue ("mytap"));

  tapBridge.Install (nodes.Get (0), devices.Get (0));

 

  csma.EnablePcapAll ("tap-csma", false);

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

 

  Ptr<Socket> srcSocket = Socket::CreateSocket (nodes.Get(1), TypeId::LookupByName ("ns3::UdpSocketFactory"));

  InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 4477);

  srcSocket->Bind (local);

  srcSocket->BindToNetDevice (devices.Get(1));

  Ipv4Address dstAddr = remoteIp;

  uint16_t dstPort = 9999;

  srcSocket->SetRecvCallback (MakeCallback (&ReceivePacket));

 

  for (uint32_t i = 0; i < 500; i++) {

      Simulator::Schedule (Seconds (1 + i * 0.5), &SendStuff, srcSocket, dstAddr, dstPort);

  }

 

  Simulator::Stop (Seconds (600.));

  Simulator::Run ();

  Simulator::Destroy ();

}

 

[receive2.py]

import socket

 

HOST = '0.0.0.0'

PORT = 9999

 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind((HOST, PORT))

 

print('server start at: %s:%s' % (HOST, PORT))

print('wait for connection...')

 

while True:

    data, addr = s.recvfrom(1024)

    print 'recvfrom ' + str(addr) + ': ' + data

    sent = s.sendto(data, addr)

Execution

 

 

 

Extension: In NS3, there is a wifi station node (n5). It will send it received signal strength to mininet host.

 

(tap-csma3.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

 */

 

// Default Network Topology

//

//   Wifi 10.1.3.0

//                 AP

//  *    *    *    *

//  |    |    |    |    10.1.2.0  

// n7   n6   n5    n0 --------------n1   n2   n3  n4  

//                                  |    |    |   |  

//                                 ================

//                                  LAN 10.1.1.0

 

#include <iostream>

#include <fstream>

#include "ns3/core-module.h"

#include "ns3/point-to-point-module.h"

#include "ns3/network-module.h"

#include "ns3/wifi-module.h"

#include "ns3/csma-module.h"

#include "ns3/internet-module.h"

#include "ns3/ipv4-global-routing-helper.h"

#include "ns3/tap-bridge-module.h"

#include "ns3/applications-module.h"

#include "ns3/yans-wifi-helper.h"

#include "ns3/ssid.h"

#include "ns3/mobility-module.h"

 

using namespace ns3;

 

double signal_wifi0; //signal strength for n5 (wifi station 0)

 

NS_LOG_COMPONENT_DEFINE ("TapCsma2Example");

 

 

 

uint32_t

ContextToNodeId (std::string context)

{

  std::string sub = context.substr (10);

  uint32_t pos = sub.find ("/Device");

  return atoi (sub.substr (0, pos).c_str ());

}

 

void

TracePacketReception (std::string context, Ptr<const Packet> p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)

{

 std::cout << "TracePacketReception: " << Simulator::Now ().As (Time::S)

                                 << " node=" << ContextToNodeId (context)

                                 << " signal=" << signalNoise.signal << std::endl;

 

 if (ContextToNodeId (context) == 5)

   signal_wifi0 = signalNoise.signal;

}

 

void SendStuff (Ptr<Socket> sock, Ipv4Address dstaddr, uint16_t port)

{

  std::cout << "SendStuff () called ..." << std::endl;

  std::ostringstream msg; msg << signal_wifi0 << '\0';

  Ptr<Packet> p = Create<Packet> ((uint8_t*) msg.str().c_str(), msg.str().length());

  //p->AddPaddingAtEnd (100);

  sock->SendTo (p, 0, InetSocketAddress (dstaddr,port));

  return;

}

 

void ReceivePacket (Ptr<Socket> socket)

{

  //Ptr<Packet> packet = socket->Recv ();

  //std::cout << "Received one packet!" << std::endl;

  Ptr<Packet> packet;

  uint32_t nodeIdr=socket->GetNode()->GetId();

  while ((packet = socket->Recv ()))

  {

    uint8_t buf[1300];

    packet->CopyData(buf , packet->GetSize());

    std::cout<<"Data, "<<buf<< ", SimulatorTime, "<<Simulator::Now().GetSeconds()<<" NodeIDR "<<nodeIdr<<std::endl;

  }

}

 

int

main (int argc, char *argv[])

{

  std::string mode = "UseLocal";

  CommandLine cmd (__FILE__);

  std::string remote ("10.1.1.10");

  cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);

 

 

  cmd.Parse (argc, argv);

 

  //std::cout << "remote=" << remote << std::endl;

  Ipv4Address remoteIp (remote.c_str ());

 

  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));

  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));

 

  NodeContainer p2pNodes;

  p2pNodes.Create (2);

 

  PointToPointHelper pointToPoint;

  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));

  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

 

  NetDeviceContainer p2pDevices;

  p2pDevices = pointToPoint.Install (p2pNodes);

 

  NodeContainer nodes;

  nodes.Add (p2pNodes.Get (1));

  nodes.Create (3);

 

  CsmaHelper csma;

  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));

  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));

 

  NetDeviceContainer devices = csma.Install (nodes);

 

  NodeContainer wifiStaNodes;

  wifiStaNodes.Create (3);

  NodeContainer wifiApNode = p2pNodes.Get (0);

 

  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();

  YansWifiPhyHelper phy;

  phy.SetChannel (channel.Create ());

 

  WifiHelper wifi;

  wifi.SetRemoteStationManager ("ns3::AarfWifiManager");

 

  WifiMacHelper mac;

  Ssid ssid = Ssid ("ns-3-ssid");

  mac.SetType ("ns3::StaWifiMac",

               "Ssid", SsidValue (ssid),

               "ActiveProbing", BooleanValue (false));

 

  NetDeviceContainer staDevices;

  staDevices = wifi.Install (phy, mac, wifiStaNodes);

 

  mac.SetType ("ns3::ApWifiMac",

               "Ssid", SsidValue (ssid));

 

  NetDeviceContainer apDevices;

  apDevices = wifi.Install (phy, mac, wifiApNode);

 

  MobilityHelper mobility;

 

  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",

                                 "MinX", DoubleValue (0.0),

                                 "MinY", DoubleValue (0.0),

                                 "DeltaX", DoubleValue (5.0),

                                 "DeltaY", DoubleValue (10.0),

                                 "GridWidth", UintegerValue (3),

                                 "LayoutType", StringValue ("RowFirst"));

 

  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",

                             "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));

  mobility.Install (wifiStaNodes);

 

  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");

  mobility.Install (wifiApNode);

 

 

 

  InternetStackHelper stack;

  stack.Install (nodes);

  stack.Install (wifiApNode);

  stack.Install (wifiStaNodes);

 

  Ipv4AddressHelper addresses;

  addresses.SetBase ("10.1.2.0", "255.255.255.0");

  Ipv4InterfaceContainer p2pInterfaces;

  p2pInterfaces = addresses.Assign (p2pDevices);

 

  addresses.SetBase ("10.1.1.0", "255.255.255.0");

  Ipv4InterfaceContainer interfaces = addresses.Assign (devices);

 

  addresses.SetBase ("10.1.3.0", "255.255.255.0");

  addresses.Assign (apDevices);

  addresses.Assign (staDevices);

 

  TapBridgeHelper tapBridge;

  tapBridge.SetAttribute ("Mode", StringValue (mode));

  tapBridge.SetAttribute ("DeviceName", StringValue ("mytap"));

  tapBridge.Install (nodes.Get (3), devices.Get (3));

 

  csma.EnablePcapAll ("tap-csma", false);

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

 

  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx", MakeCallback (&TracePacketReception));

 

  Ptr<Socket> srcSocket = Socket::CreateSocket (wifiStaNodes.Get(0), TypeId::LookupByName ("ns3::UdpSocketFactory"));

  InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 4477);

  srcSocket->Bind (local);

  srcSocket->BindToNetDevice (staDevices.Get(0));

  Ipv4Address dstAddr = remoteIp;

  uint16_t dstPort = 9999;

  srcSocket->SetRecvCallback (MakeCallback (&ReceivePacket));

 

  for (uint32_t i = 0; i < 500; i++) {

      Simulator::Schedule (Seconds (1 + i * 0.5), &SendStuff, srcSocket, dstAddr, dstPort);

  }

 

  Simulator::Stop (Seconds (600.));

  Simulator::Run ();

  Simulator::Destroy ();

}

Execution

 

 

Back to NS3 Learning Guide

Last Modified: 2022/10/22 done

 

[reference]

https://pastebin.com/vSuhxgdi

 

[Author]

Dr. Chih-Heng Ke

Department of Computer Science and Information Engineering, National Quemoy University, Kinmen, Taiwan

Email: smallko@gmail.com