To implement NAMO (Neighbor-Aware Multipath Opportunistic) routing in ns3, we need to create a new routing protocol. That protocol requires a good understanding of ns3s routing architecture, the ability to extend it with a custom routing protocol and also that have to support the features of NAMO. The following steps will guide on how to implement NAMO in ns3:
Step-by-step to implement NAMO in ns3
Step 1: Set Up ns3 Environment
- Download ns-3: Download ns3.
- Install ns-3: Follow the installation instructions for operating system.
- Familiarize yourself with ns-3 basics: Understand how to create nodes, set up channels, and run basic simulations.
Step 2: Create a Custom Routing Protocol
To implement NAMO in ns3,we need to create a custom routing protocol class. This involves extending the Ipv4RoutingProtocol class and implementing the necessary methods.
Create NAMO Routing Protocol Header File
Create a header file namo-routing-protocol.h:
#ifndef NAMO_ROUTING_PROTOCOL_H
#define NAMO_ROUTING_PROTOCOL_H
#include “ns3/ipv4-routing-protocol.h”
#include “ns3/node.h”
#include “ns3/ipv4.h”
#include “ns3/ipv4-routing-table-entry.h”
#include “ns3/timer.h”
#include “ns3/random-variable-stream.h”
#include <map>
#include <vector>
namespace ns3 {
class NamoRoutingProtocol : public Ipv4RoutingProtocol
{
public:
static TypeId GetTypeId(void);
NamoRoutingProtocol();
virtual ~NamoRoutingProtocol();
// Inherited from Ipv4RoutingProtocol
virtual Ptr<Ipv4Route> RouteOutput(Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) override;
virtual bool RouteInput(Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) override;
virtual void NotifyInterfaceUp(uint32_t interface) override;
virtual void NotifyInterfaceDown(uint32_t interface) override;
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override;
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override;
virtual void SetIpv4(Ptr<Ipv4> ipv4) override;
virtual void PrintRoutingTable(Ptr<OutputStreamWrapper> stream, Time::Unit unit = Time::S) const override;
private:
Ptr<Ipv4> m_ipv4;
std::map<Ipv4Address, Ipv4RoutingTableEntry> m_routingTable;
Timer m_helloTimer;
void SendHello();
void ReceiveHello(Ptr<Socket> socket);
void ScheduleHello();
};
} // namespace ns3
#endif // NAMO_ROUTING_PROTOCOL_H
Implement NAMO Routing Protocol Source File
Create a source file namo-routing-protocol.cc:
#include “namo-routing-protocol.h”
#include “ns3/log.h”
#include “ns3/ipv4-l3-protocol.h”
#include “ns3/packet.h”
#include “ns3/socket-factory.h”
#include “ns3/udp-socket-factory.h”
#include “ns3/trace-source-accessor.h”
#include “ns3/mobility-module.h”
#include “ns3/ipv4-address.h”
#include “ns3/simulator.h”
#include “ns3/ipv4.h”
#include “ns3/ipv4-static-routing.h”
#include “ns3/ipv4-static-routing-helper.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE(“NamoRoutingProtocol”);
NS_OBJECT_ENSURE_REGISTERED(NamoRoutingProtocol);
TypeId NamoRoutingProtocol::GetTypeId(void)
{
static TypeId tid = TypeId(“ns3::NamoRoutingProtocol”)
.SetParent<Ipv4RoutingProtocol>()
.SetGroupName(“Internet”)
.AddConstructor<NamoRoutingProtocol>();
return tid;
}
NamoRoutingProtocol::NamoRoutingProtocol()
{
NS_LOG_FUNCTION(this);
m_helloTimer.SetFunction(&NamoRoutingProtocol::SendHello, this);
}
NamoRoutingProtocol::~NamoRoutingProtocol()
{
NS_LOG_FUNCTION(this);
}
void NamoRoutingProtocol::SetIpv4(Ptr<Ipv4> ipv4)
{
NS_LOG_FUNCTION(this << ipv4);
m_ipv4 = ipv4;
}
void NamoRoutingProtocol::NotifyInterfaceUp(uint32_t interface)
{
NS_LOG_FUNCTION(this << interface);
ScheduleHello();
}
void NamoRoutingProtocol::NotifyInterfaceDown(uint32_t interface)
{
NS_LOG_FUNCTION(this << interface);
}
void NamoRoutingProtocol::NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
{
NS_LOG_FUNCTION(this << interface << address);
}
void NamoRoutingProtocol::NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
{
NS_LOG_FUNCTION(this << interface << address);
}
void NamoRoutingProtocol::SendHello()
{
NS_LOG_FUNCTION(this);
Ptr<Packet> packet = Create<Packet>(100); // Placeholder for Hello packet
// Broadcast the Hello packet on all interfaces
for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); ++i)
{
for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); ++j)
{
Ipv4Address addr = m_ipv4->GetAddress(i, j).GetLocal();
if (addr == Ipv4Address::GetLoopback())
{
continue;
}
Ptr<Socket>socket=Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
socket->SetAllowBroadcast(true);
socket->Connect(InetSocketAddress(Ipv4Address::GetBroadcast(), 9));
socket->Send(packet);
}
}
ScheduleHello();
}
void NamoRoutingProtocol::ReceiveHello(Ptr<Socket> socket)
{
NS_LOG_FUNCTION(this << socket);
Ptr<Packet> packet;
Address sourceAddress;
while ((packet = socket->RecvFrom(sourceAddress)))
{
InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom(sourceAddress);
Ipv4Address sender = inetSourceAddr.GetIpv4();
NS_LOG_INFO(“Received Hello from ” << sender);
// Add the sender to the routing table
Ipv4RoutingTableEntry rtEntry;
if (!m_routingTable.count(sender))
{
m_routingTable[sender] = rtEntry;
}
}
}
void NamoRoutingProtocol::ScheduleHello()
{
NS_LOG_FUNCTION(this);
m_helloTimer.Schedule(Seconds(1.0));
}
Ptr<Ipv4Route> NamoRoutingProtocol::RouteOutput(Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
{
NS_LOG_FUNCTION(this << p << header << oif);
Ptr<Ipv4Route> route = Create<Ipv4Route>();
route->SetDestination(header.GetDestination());
if (m_routingTable.count(header.GetDestination()))
{
route->SetGateway(m_routingTable[header.GetDestination()].GetGateway());
route->SetSource(m_ipv4->GetAddress(1, 0).GetLocal());
route->SetOutputDevice(m_ipv4->GetNetDevice(1));
sockerr = Socket::ERROR_NOTERROR;
return route;
}
sockerr = Socket::ERROR_NOROUTETOHOST;
return 0;
}
bool NamoRoutingProtocol::RouteInput(Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
{
NS_LOG_FUNCTION(this << p << header << idev);
if (m_routingTable.count(header.GetDestination()))
{
Ptr<Ipv4Route> route = Create<Ipv4Route>();
route->SetDestination(header.GetDestination());
route->SetGateway(m_routingTable[header.GetDestination()].GetGateway());
route->SetSource(m_ipv4->GetAddress(1, 0).GetLocal());
route->SetOutputDevice(m_ipv4->GetNetDevice(1));
ucb(route, p, header);
return true;
}
return false;
void NamoRoutingProtocol::PrintRoutingTable(Ptr<OutputStreamWrapper> stream, Time::Unit unit) const
{
NS_LOG_FUNCTION(this << stream << unit);
*stream->GetStream() << “Routing table:\n”;
for (const auto &entry : m_routingTable)
{
*stream->GetStream() << entry.first << ” -> ” << entry.second.GetGateway() << “\n”;
}
}
} // namespace ns3
Step 3: Integrate NAMO with ns-3
We need to modify the simulation script to use this custom routing protocol, to integrate the NAMO routing protocol with ns3.
Example Simulation Script
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/internet-module.h”
#include “ns3/point-to-point-module.h”
#include “ns3/mobility-module.h”
#include “namo-routing-protocol.h”
using namespace ns3;
NS_LOG_COMPONENT_DEFINE(“NamoSimulation”);
int main(int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse(argc, argv);
// Create nodes
NodeContainer nodes;
nodes.Create(5);
// Set up point-to-point connections
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute(“DataRate”, StringValue(“5Mbps”));
pointToPoint.SetChannelAttribute(“Delay”, StringValue(“2ms”));
NetDeviceContainer devices;
for (uint32_t i = 0; i < nodes.GetN() – 1; ++i)
{
devices.Add(pointToPoint.Install(nodes.Get(i), nodes.Get(i + 1)));
}
// Install internet stack
InternetStackHelper stack;
Ptr<NamoRoutingProtocol> namo = CreateObject<NamoRoutingProtocol>();
stack.SetRoutingHelper(namo); // Has effect on the next Install ()
stack.Install(nodes);
// Assign IP addresses
Ipv4AddressHelper address;
address.SetBase(“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer interfaces = address.Assign(devices);
// Set up applications
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(nodes.Get(nodes.GetN() – 1));
serverApps.Start(Seconds(1.0));
serverApps.Stop(Seconds(10.0));
UdpEchoClientHelper echoClient(interfaces.GetAddress(nodes.GetN() – 1), 9);
echoClient.SetAttribute(“MaxPackets”, UintegerValue(10));
echoClient.SetAttribute(“Interval”, TimeValue(Seconds(1.0)));
echoClient.SetAttribute(“PacketSize”, UintegerValue(1024));
ApplicationContainer clientApps = echoClient.Install(nodes.Get(0));
clientApps.Start(Seconds(2.0));
clientApps.Stop(Seconds(10.0));
// Enable tracing
pointToPoint.EnablePcapAll(“namo”);
Simulator::Run();
Simulator::Destroy();
return 0;
}
At last, We had clearly know about how to implement NAMO (Neighbor-Aware Multipath Opportunistic) routing with an example script and how to extend it with custom routing protocol in a ns3 environment.
NAMO in ns3, along with our team’s implementation support, is supported by us. Keep in contact with us for the results of your networking performance analysis. Send us the required project details.