Ping a real pc from a ns3 node

115 views
Skip to first unread message

Kevin Woschny

unread,
Oct 5, 2023, 6:16:37 AM10/5/23
to ns-3-users
Hi all,
I am trying to ping a remote IP from a ns-3 node using the fdnetdevice. I used the "fd-emu-ping.cc" as a starting point.

   Node1                Node0
+------------+         +-------------------------------+
I I I EmuFdNetDevice I 192.168.0.172------------------------ remote
+------------+         +-------------------------------+  
 I  CSMA I          I             CSMA            I
+------------+         +-------------------------------+
  10.1.1.2                        10.1.1.1
         I                                    I
         ==================
I can ping 8.8.8.8 from node0, but not from Node1. 
node1 and node0 can ping each other.
My computer is 192.168.0.171 and my gateway is 192.168.0.1
What do I have to change so that Node1 can ping remote?

This is my source code.

#include "ns3/abort.h"
#include "ns3/core-module.h"
#include "ns3/fd-net-device-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/internet-module.h"
#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE("PingEmulation");

static void
PingRtt(std::string context, uint16_t seqNo, Time rtt)
{
    NS_LOG_UNCOND("Received " << seqNo << " Response with RTT = " << rtt);
}

int
main(int argc, char* argv[])
{
    NS_LOG_INFO("Ping Emulation Example");

    std::string deviceName("enp6s0");
    std::string remote("8.8.8.8");
    std::string localAddress("192.168.0.172");
    std::string localGateway("192.168.0.1");
    std::string emuMode("raw");


 
    Ipv4Address remoteIp(remote.c_str());
    Ipv4Address localIp(localAddress.c_str());
    NS_ABORT_MSG_IF(localIp == "1.2.3.4",
                    "You must change the local IP address before running this example");

    Ipv4Mask localMask("255.255.255.0");

    //
    // Since we are using a real piece of hardware we need to use the realtime
    // simulator.
    //
    GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl"));
    GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));


    NS_LOG_INFO("Create Node");
    Ptr<Node> node0 = CreateObject<Node>();
    Ptr<Node> node1 = CreateObject<Node>();
    NodeContainer endpointNodes (node0, node1);
   
   
    CsmaHelper csma;
    csma.SetChannelAttribute("DataRate", DataRateValue(5000000));
    csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
   
    NetDeviceContainer devicesC = csma.Install(endpointNodes);

    NS_LOG_INFO("Add Internet Stack");
    InternetStackHelper stack;
    stack.Install(endpointNodes);
   
    Ipv4AddressHelper addressesC;
    addressesC.SetBase("10.1.1.0", "255.255.255.0");
    Ipv4InterfaceContainer interfacesC = addressesC.Assign(devicesC);

    NS_LOG_INFO("Create Device");

    FdNetDeviceHelper* helper = nullptr;


    EmuFdNetDeviceHelper* raw = new EmuFdNetDeviceHelper;
    raw->SetDeviceName(deviceName);
    helper = raw;
   
    NetDeviceContainer devices = helper->Install(node0);
    Ptr<NetDevice> device = devices.Get(0);
    device->SetAttribute("Address", Mac48AddressValue(Mac48Address::Allocate()));
   
    NetDeviceContainer devices1 = helper->Install(node1);
    Ptr<NetDevice> device1 = devices1.Get(0);
    device1->SetAttribute("Address", Mac48AddressValue(Mac48Address::Allocate()));
   

    NS_LOG_INFO("Create IPv4 Interface");
   
    Ptr<Ipv4> ipv4 = node0->GetObject<Ipv4>();
    uint32_t interface = ipv4->AddInterface(device);
    Ipv4InterfaceAddress address = Ipv4InterfaceAddress(localIp, localMask);
    ipv4->AddAddress(interface, address);
    ipv4->SetMetric(interface, 1);
    ipv4->SetUp(interface);

   
    Ipv4Address gateway(localGateway.c_str());
   
    Ipv4StaticRoutingHelper ipv4RoutingHelper;
    Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting(ipv4);
    staticRouting->SetDefaultRoute(gateway, interface);
   
   
    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
   

 
    // ping application
    NS_LOG_INFO("Create Ping Application");
    Ptr<Ping> app = CreateObject<Ping>();
    app->SetAttribute("Destination", AddressValue(remoteIp));
    app->SetAttribute("VerboseMode", EnumValue(Ping::VerboseMode::VERBOSE));
    node1->AddApplication(app);
    app->SetStartTime(Seconds(1.0));
    app->SetStopTime(Seconds(22.0));

    Names::Add("app", app);

    //
    // Hook a trace to print something when the response comes back.
    //
    Config::Connect("/Names/app/Rtt", MakeCallback(&PingRtt));

    //
    // Enable a promiscuous pcap trace to see what is coming and going on our device.
    //
    helper->EnablePcap(emuMode + "-emu-ping", device, true);

 
    // emulation.
    NS_LOG_INFO("Run Emulation in " << emuMode << " mode.");
    Simulator::Stop(Seconds(23.0));
    Simulator::Run();
    Simulator::Destroy();
    delete helper;
    NS_LOG_INFO("Done.");

    return 0;
}




Tom Henderson

unread,
Oct 5, 2023, 11:02:56 AM10/5/23
to ns-3-...@googlegroups.com, Kevin Woschny
i think the issue is that you cannot use Ipv4GlobalRouting::PopulateRoutingTables() and expect that node1's tables learn about the remote, because IPv4GlobalRouting only knows about the simulated links, and not the external links.

Instead, you should add a static default route to node 1 that sets the next hop to 10.1.1.1.

- Tom
--
Posting to this group should follow these guidelines https://www.nsnam.org/wiki/Ns-3-users-guidelines-for-posting
---
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ns-3-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ns-3-users/abfee6fd-28ff-4c40-8997-3e4fa1e826c8n%40googlegroups.com.


Kevin Woschny

unread,
Oct 5, 2023, 3:30:40 PM10/5/23
to ns-3-users
Hi,

i added IP forwarding to node0 

    ipv4->SetForwarding (interface, true);

and used static routing in node0

    staticRouting->SetDefaultRoute(gateway, interface);
    staticRouting->AddHostRouteTo(Ipv4Address("10.1.1.2"),Ipv4Address("10.1.1.2"),1,1);

and also in node1 

    staticRoutingNode1->SetDefaultRoute(Ipv4Address("10.1.1.1"), 1);

but i get the same result like befor. Node1 can just ping node0 and not the remote ip.

My edited source code

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

//     Node1                         Node0
//+------------+         +-------------------------------+                                                pc                                  gateway                          
// I               I         I   EmuFdNetDevice   I  192.168.0.172------ 192.168.0.171 ------------------ 192.168.0.1
// +------------+         +-------------------------------+  
// I  CSMA  I         I             CSMA              I
// +------------+         +-------------------------------+
//   10.1.1.2                            10.1.1.1
//     I                                                I
//     =======================


#include "ns3/abort.h"
#include "ns3/core-module.h"
#include "ns3/fd-net-device-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/internet-module.h"
#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE("PingEmulation");

static void
PingRtt(std::string context, uint16_t seqNo, Time rtt)
{
    NS_LOG_UNCOND("Received " << seqNo << " Response with RTT = " << rtt);
}

int
main(int argc, char* argv[])
{
    NS_LOG_INFO("Ping Emulation Example");

    std::string deviceName("enp6s0");
    std::string remote("8.8.8.8");
    std::string localAddress("192.168.0.172");
    std::string localGateway("192.168.0.1");
    std::string emuMode("raw");


 
    Ipv4Address remoteIp(remote.c_str());
    Ipv4Address localIp(localAddress.c_str());  
    Ptr<Ipv4> ipv4Node1 = node1->GetObject<Ipv4>();

    Ptr<Ipv4> ipv4 = node0->GetObject<Ipv4>();
   
    uint32_t interface = ipv4->AddInterface(device);
    Ipv4InterfaceAddress address = Ipv4InterfaceAddress(localIp, localMask);
    ipv4->AddAddress(interface, address);
    ipv4->SetMetric(interface, 1);
    ipv4->SetForwarding (interface, true);

    ipv4->SetUp(interface);

   
    Ipv4Address gateway(localGateway.c_str());
   
    Ipv4StaticRoutingHelper ipv4RoutingHelper;
    Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting(ipv4);
    staticRouting->SetDefaultRoute(gateway, interface);
    staticRouting->AddHostRouteTo(Ipv4Address("10.1.1.2"),Ipv4Address("10.1.1.2"),1,1);
   
    Ptr<Ipv4StaticRouting> staticRoutingNode1 = ipv4RoutingHelper.GetStaticRouting(ipv4Node1);
    staticRoutingNode1->SetDefaultRoute(Ipv4Address("10.1.1.1"), 1);
   
   
   

   
   
    //Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

Tom Henderson

unread,
Oct 8, 2023, 6:17:07 PM10/8/23
to ns-3-...@googlegroups.com
I gave your program a try.  I see the pings leaving node0 with source address 10.1.1.2 to 8.8.8.8.  I think that the problem is that 8.8.8.8 has no route back to 10.1.1.2 (and this is probably going through a NAT so there is not mapping in the NAT for that source address).

- Tom
Reply all
Reply to author
Forward
0 new messages