To implement a custom layer 3 routed protocol in ns3, we have to create a new routing protocol which operates on the network layer. Here is a complete guide on implementing a basic layer 3 routed protocol using ns3 features.
Steps for implementing a custom layer 3 routed protocol
- Set up your environment
Make sure that ns3 is installed in the computer. If not, install it from the official ns3 website.
- Create a new ns3 module
On your ns3 installation, create a new module in the src directory for the custom layer 3 routed protocol. For this, you have to create the necessary directory structure and files.
cd ns-3.xx
cd src
mkdir -p layer3-routing-protocol/model
mkdir -p layer3-routing-protocol/helper
- Create the layer 3 routed protocol header file
In the model directory, create the header file layer3-routing-protocol.h for the layer 3 routing protocol.
#ifndef LAYER3_ROUTING_PROTOCOL_H
#define LAYER3_ROUTING_PROTOCOL_H
#include “ns3/ipv4-routing-protocol.h”
#include “ns3/ipv4-address.h”
#include “ns3/timer.h”
#include “ns3/mobility-model.h”
#include “ns3/node.h”
#include “ns3/net-device.h”
#include “ns3/ipv4.h”
#include “ns3/ipv4-routing-table-entry.h”
#include <map>
namespace ns3 {
class Layer3RoutingProtocol : public Ipv4RoutingProtocol
{
public:
static TypeId GetTypeId (void);
Layer3RoutingProtocol ();
virtual ~Layer3RoutingProtocol ();
// Inherited from Ipv4RoutingProtocol
virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
virtual bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb);
virtual void NotifyInterfaceUp (uint32_t interface);
virtual void NotifyInterfaceDown (uint32_t interface);
virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
virtual void SetIpv4 (Ptr<Ipv4> ipv4);
virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
private:
Ptr<Ipv4> m_ipv4;
std::map<Ipv4Address, Ipv4RoutingTableEntry> m_routingTable;
Ptr<NetDevice> GetNetDevice (uint32_t interface);
Ptr<MobilityModel> GetMobilityModel (Ptr<NetDevice> netDevice);
Ipv4Address GetNextHop (Ipv4Address dest);
};
} // namespace ns3
#endif /* LAYER3_ROUTING_PROTOCOL_H */
- Create the Layer 3 Routed Protocol Source File
In the model directory, create the source file layer3-routing-protocol.cc for the Layer 3 routing protocol.
#include “layer3-routing-protocol.h”
#include “ns3/log.h”
#include “ns3/ipv4-route.h”
#include “ns3/simulator.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“Layer3RoutingProtocol”);
NS_OBJECT_ENSURE_REGISTERED (Layer3RoutingProtocol);
TypeId
Layer3RoutingProtocol::GetTypeId (void)
{
static TypeId tid = TypeId (“ns3::Layer3RoutingProtocol”)
.SetParent<Ipv4RoutingProtocol> ()
.SetGroupName(“Internet”)
.AddConstructor<Layer3RoutingProtocol> ();
return tid;
}
Layer3RoutingProtocol::Layer3RoutingProtocol ()
{
}
Layer3RoutingProtocol::~Layer3RoutingProtocol ()
{
}
void
Layer3RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
{
m_ipv4 = ipv4;
}
Ptr<NetDevice>
Layer3RoutingProtocol::GetNetDevice (uint32_t interface)
{
return m_ipv4->GetNetDevice (interface);
}
Ptr<MobilityModel>
Layer3RoutingProtocol::GetMobilityModel (Ptr<NetDevice> netDevice)
{
return netDevice->GetNode ()->GetObject<MobilityModel> ();
}
Ipv4Address
Layer3RoutingProtocol::GetNextHop (Ipv4Address dest)
{
// Simplified example of next hop selection
if (m_routingTable.find(dest) != m_routingTable.end())
{
return m_routingTable[dest].GetGateway();
}
return Ipv4Address::GetBroadcast ();
}
Ptr<Ipv4Route>
Layer3RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
{
Ipv4Address dest = header.GetDestination ();
Ipv4Address nextHop = GetNextHop (dest);
if (nextHop == Ipv4Address::GetBroadcast ())
{
sockerr = Socket::ERROR_NOROUTETOHOST;
return nullptr;
}
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (dest);
route->SetGateway (nextHop);
route->SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (nextHop)));
return route;
}
bool
Layer3RoutingProtocol::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
{
Ipv4Address dest = header.GetDestination ();
Ipv4Address nextHop = GetNextHop (dest);
if (nextHop == Ipv4Address::GetBroadcast ())
{
ecb (p, header, Socket::ERROR_NOROUTETOHOST);
return false;
}
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (dest);
route->SetGateway (nextHop);
route->SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (nextHop)));
ucb (route, p, header);
return true;
}
void
Layer3RoutingProtocol::NotifyInterfaceUp (uint32_t interface)
{
}
void
Layer3RoutingProtocol::NotifyInterfaceDown (uint32_t interface)
{
}
void
Layer3RoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
}
void
Layer3RoutingProtocol::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
}
void
Layer3RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
{
*stream->GetStream () << “Layer 3 Routing Table” << std::endl;
for (auto const &entry : m_routingTable)
{
*stream->GetStream () << entry.first << ” -> ” << entry.second.GetGateway () << ” via ” << entry.second.GetInterface () << std::endl;
}
}
} // namespace ns3
- Define Layer 3 Helper
In the helper directory, create the helper header file layer3-helper.h for the layer 3.
#ifndef LAYER3_HELPER_H
#define LAYER3_HELPER_H
#include “ns3/ipv4-routing-helper.h”
#include “layer3-routing-protocol.h”
namespace ns3 {
class Layer3Helper : public Ipv4RoutingHelper
{
public:
Layer3Helper ();
virtual ~Layer3Helper ();
Layer3Helper* Copy (void) const;
virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
};
} // namespace ns3
#endif /* LAYER3_HELPER_H */
Create the Layer 3 helper source file layer3-helper.cc in the helper directory.
#include “layer3-helper.h”
#include “ns3/node.h”
#include “ns3/ipv4.h”
namespace ns3 {
Layer3Helper::Layer3Helper ()
{
}
Layer3Helper::~Layer3Helper ()
{
}
Layer3Helper*
Layer3Helper::Copy (void) const
{
return new Layer3Helper (*this);
}
Ptr<Ipv4RoutingProtocol>
Layer3Helper::Create (Ptr<Node> node) const
{
Ptr<Layer3RoutingProtocol> layer3Routing = CreateObject<Layer3RoutingProtocol> ();
node->AggregateObject (layer3Routing);
return layer3Routing;
}
} // namespace ns3
- Update CMakeLists.txt
In the ns3 build system, add a new layer 3 module. Edit src/CMakeLists.txt and add the following line:
add_subdirectory (layer3-routing-protocol)
Create src/layer3-routing-protocol/CMakeLists.txt with the following content:
ns3_add_library (layer3-routing-protocol
model/layer3-routing-protocol.cc
helper/layer3-helper.cc
)
target_link_libraries (layer3-routing-protocol)
- Set up the network topology
To use the layer 3 protocol, create a simulation script in the scratch directory.
#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/mobility-module.h”
#include “layer3-helper.h”
using namespace ns3;
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
NodeContainer nodes;
nodes.Create (10);
// Set up WiFi
WifiHelper wifi;
wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
WifiMacHelper wifiMac;
wifiMac.SetType (“ns3::AdhocWifiMac”);
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, nodes);
// Set up mobility model
MobilityHelper mobility;
Ptr<UniformRandomVariable> random = CreateObject<UniformRandomVariable> ();
mobility.SetPositionAllocator (“ns3::RandomRectanglePositionAllocator”,
“MinX”, DoubleValue (0.0),
“MinY”, DoubleValue (0.0),
“MaxX”, DoubleValue (100.0),
“MaxY”, DoubleValue (100.0));
mobility.SetMobilityModel (“ns3::RandomWaypointMobilityModel”,
“Speed”, StringValue (“ns3::ConstantRandomVariable[Constant=20.0]”),
“Pause”, StringValue (“ns3::ConstantRandomVariable[Constant=0.0]”),
“PositionAllocator”, StringValue (“ns3::RandomRectanglePositionAllocator[MinX=0.0|MinY=0.0|MaxX=100.0|MaxY=100.0]”));
mobility.Install (nodes);
// Install the internet stack on nodes
InternetStackHelper stack;
Layer3Helper layer3;
stack.SetRoutingHelper (layer3);
stack.Install (nodes);
// Assign IP addresses to the devices
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer interfaces = address.Assign (devices);
// Set up applications (e.g., a UDP echo server and client)
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (9));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress (9), 9);
echoClient.SetAttribute (“MaxPackets”, UintegerValue (1));
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
AsciiTraceHelper ascii;
wifiPhy.EnableAsciiAll (ascii.CreateFileStream (“layer3-simulation.tr”));
wifiPhy.EnablePcapAll (“layer3-simulation”);
// Run the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
- Build and run the simulation
Build and run your script after writing.
./waf build
./waf –run scratch/layer3-simulation
- Analyze the results
You can analyze the results after running the simulation, by using the generated trace files (layer3-simulation.tr and layer3-simulation-0-0.pcap).
Example script for layer 3 protocol
Below is the example script for your reference:
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/internet-module.h”
#include “ns3/wifi-module.h”
#include “ns3/mobility-module.h”
#include “ns3/applications-module.h”
#include “layer3-helper.h”
using namespace ns3;
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
NodeContainer nodes;
nodes.Create (10);
// Set up WiFi
WifiHelper wifi;
wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
WifiMacHelper wifiMac;
wifiMac.SetType (“ns3::AdhocWifiMac”);
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, nodes);
// Set up mobility model
MobilityHelper mobility;
Ptr<UniformRandomVariable> random = CreateObject<UniformRandomVariable> ();
mobility.SetPositionAllocator (“ns3::RandomRectanglePositionAllocator”,
“MinX”, DoubleValue (0.0),
“MinY”, DoubleValue (0.0),
“MaxX”, DoubleValue (100.0),
“MaxY”, DoubleValue (100.0));
mobility.SetMobilityModel (“ns3::RandomWaypointMobilityModel”,
“Speed”, StringValue (“ns3::ConstantRandomVariable[Constant=20.0]”),
“Pause”, StringValue (“ns3::ConstantRandomVariable[Constant=0.0]”),
“PositionAllocator”, StringValue (“ns3::RandomRectanglePositionAllocator[MinX=0.0|MinY=0.0|MaxX=100.0|MaxY=100.0]”));
mobility.Install (nodes);
// Install the internet stack on nodes
InternetStackHelper stack;
Layer3Helper layer3;
stack.SetRoutingHelper (layer3);
stack.Install (nodes);
// Assign IP addresses to the devices
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer interfaces = address.Assign (devices);
// Set up applications (e.g., a UDP echo server and client)
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (9));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress (9), 9);
echoClient.SetAttribute (“MaxPackets”, UintegerValue (1));
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
AsciiTraceHelper ascii;
wifiPhy.EnableAsciiAll (ascii.CreateFileStream (“layer3-simulation.tr”));
wifiPhy.EnablePcapAll (“layer3-simulation”);
// Run the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
Overall, the performance analysis for implementing a custom Layer 3 routed protocol in ns3 had been successfully executed by creating a new routing protocol which operates on the network layer. Also, we provide detailed explanation on Layer 3 routed protocol with programming help.