To implement Layer 3 (L3) protocols in ns3, it requires a module for handling the specific Layer 3 functionalities, such as routing and addressing. For that, we may create a custom module or we can use the existing modules in ns3.
The stages given below will guide how to create a simple custom Layer 3 protocol using custom routing protocol in ns3.
Step-by-Step Guide to Implementing a Custom Layer 3 Protocol in ns-3
- Set Up Your Environment
Ensure that ns3 is installed on the system.
- Create a New ns-3 Module
Create a new module for the custom L3 protocol in the src directory from the ns3 installation. This involves creating the necessary directory structure and files.
cd ns3.xx
cd src
mkdir -p custom-l3-protocol/model
mkdir -p custom-l3-protocol/helper
3. Create the Custom L3 Protocol Header File
Create the custom L3 protocol header file custom-l3-routing-protocol.h in the model directory.
#ifndef CUSTOM_L3_ROUTING_PROTOCOL_H
#define CUSTOM_L3_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 CustomL3RoutingProtocol : public Ipv4RoutingProtocol
{
public:
static TypeId GetTypeId (void);
CustomL3RoutingProtocol ();
virtual ~CustomL3RoutingProtocol ();
// 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 /* CUSTOM_L3_ROUTING_PROTOCOL_H */
4. Create the Custom L3 Protocol Source File
Create the custom L3 protocol source file custom-l3-routing-protocol.cc in the model directory.
#include “custom-l3-routing-protocol.h”
#include “ns3/log.h”
#include “ns3/ipv4-route.h”
#include “ns3/simulator.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“CustomL3RoutingProtocol”);
NS_OBJECT_ENSURE_REGISTERED (CustomL3RoutingProtocol);
TypeId
CustomL3RoutingProtocol::GetTypeId (void)
{
static TypeId tid = TypeId (“ns3::CustomL3RoutingProtocol”)
.SetParent<Ipv4RoutingProtocol> ()
.SetGroupName(“Internet”)
.AddConstructor<CustomL3RoutingProtocol> ();
return tid;
}
CustomL3RoutingProtocol::CustomL3RoutingProtocol ()
{
}
CustomL3RoutingProtocol::~CustomL3RoutingProtocol ()
{
}
void
CustomL3RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
{
m_ipv4 = ipv4;
}
Ptr<NetDevice>
CustomL3RoutingProtocol::GetNetDevice (uint32_t interface)
{
return m_ipv4->GetNetDevice (interface);
}
Ptr<MobilityModel>
CustomL3RoutingProtocol::GetMobilityModel (Ptr<NetDevice> netDevice)
{
return netDevice->GetNode ()->GetObject<MobilityModel> ();
}
Ipv4Address
CustomL3RoutingProtocol::GetNextHop (Ipv4Address dest)
{
if (m_routingTable.find(dest) != m_routingTable.end())
{
return m_routingTable[dest].GetGateway();
}
return Ipv4Address::GetBroadcast ();
}
Ptr<Ipv4Route>
CustomL3RoutingProtocol::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
CustomL3RoutingProtocol::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
CustomL3RoutingProtocol::NotifyInterfaceUp (uint32_t interface)
{
}
void
CustomL3RoutingProtocol::NotifyInterfaceDown (uint32_t interface)
{
}
void
CustomL3RoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
}
void
CustomL3RoutingProtocol::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
}
void
CustomL3RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
{
*stream->GetStream () << “Custom L3 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
5. Define Custom L3 Protocol Helper
Create the custom L3 protocol helper header file custom-l3-routing-helper.h in the helper directory.
#ifndef CUSTOM_L3_ROUTING_HELPER_H
#define CUSTOM_L3_ROUTING_HELPER_H
#include “ns3/node-container.h”
#include “ns3/custom-l3-routing-protocol.h”
namespace ns3 {
class CustomL3RoutingHelper : public Ipv4RoutingHelper
{
public:
CustomL3RoutingHelper ();
virtual ~CustomL3RoutingHelper ();
CustomL3RoutingHelper* Copy (void) const;
virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
};
} // namespace ns3
#endif /* CUSTOM_L3_ROUTING_HELPER_H */
Create the custom L3 protocol helper source file custom-l3-routing-helper.cc in the helper directory.
#include “custom-l3-routing-helper.h”
#include “ns3/node.h”
#include “ns3/log.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“CustomL3RoutingHelper”);
CustomL3RoutingHelper::CustomL3RoutingHelper ()
{
}
CustomL3RoutingHelper::~CustomL3RoutingHelper ()
{
}
CustomL3RoutingHelper*
CustomL3RoutingHelper::Copy (void) const
{
return new CustomL3RoutingHelper (*this);
}
Ptr<Ipv4RoutingProtocol>
CustomL3RoutingHelper::Create (Ptr<Node> node) const
{
Ptr<CustomL3RoutingProtocol> protocol = CreateObject<CustomL3RoutingProtocol> ();
node->AggregateObject (protocol);
return protocol;
}
} // namespace ns3
6. Update CMakeLists.txt
Add the new custom L3 protocol module to the ns-3 build system. Edit src/CMakeLists.txt and add the following line:
add_subdirectory (custom-l3-protocol)
Create src/custom-l3-protocol/CMakeLists.txt with the following content:
ns3_add_library (custom-l3-protocol
model/custom-l3-routing-protocol.cc
helper/custom-l3-routing-helper.cc
)
target_link_libraries (custom-l3-protocol)
7. Set Up the Network Topology
Create a simulation script in the scratch directory to use the custom L3 protocol.
#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/custom-l3-routing-helper.h”
using namespace ns3;
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
// Create nodes
NodeContainer nodes;
nodes.Create (4);
// Set up point-to-point links
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));
pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes.Get (0), nodes.Get (1));
devices = pointToPoint.Install (nodes.Get (1), nodes.Get (2));
devices = pointToPoint.Install (nodes.Get (2), nodes.Get (3));
// Install the internet stack on nodes
InternetStackHelper stack;
CustomL3RoutingHelper customRouting;
stack.SetRoutingHelper (customRouting);
stack.Install (nodes);
// Assign IP addresses to the devices
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer if1 = address.Assign (devices.Get (0));
address.SetBase (“10.1.2.0”, “255.255.255.0”);
Ipv4InterfaceContainer if2 = address.Assign (devices.Get (1));
address.SetBase (“10.1.3.0”, “255.255.255.0”);
Ipv4InterfaceContainer if3 = address.Assign (devices.Get (2));
// Set up applications (e.g., a UDP echo server and client)
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (3));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (if3.GetAddress (1), 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
pointToPoint.EnablePcapAll (“custom-l3-protocol-simulation”);
// Run the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
8. Build and Run the Simulation
After writing your script, you need to build and run it.
./waf build
./waf –run scratch/custom-l3-protocol-simulation
9. Analyze the Results
After running the simulation, we can analyze the results using the generated pcap files (custom-l3-protocol-simulation-0-0.pcap, etc.).
Complete Example Script for Custom L3 Protocol
Here’s a complete example script for reference:
#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/custom-l3-routing-helper.h”
using namespace ns3;
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
// Create nodes
NodeContainer nodes;
nodes.Create (4);
// Set up point-to-point links
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));
pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes.Get (0), nodes.Get (1));
devices = pointToPoint.Install (nodes.Get (1), nodes.Get (2));
devices = pointToPoint.Install (nodes.Get (2), nodes.Get (3));
// Install the internet stack on nodes
InternetStackHelper stack;
CustomL3RoutingHelper customRouting;
stack.SetRoutingHelper (customRouting);
stack.Install (nodes);
// Assign IP addresses to the devices
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer if1 = address.Assign (devices.Get (0));
address.SetBase (“10.1.2.0”, “255.255.255.0”);
Ipv4InterfaceContainer if2 = address.Assign (devices.Get (1));
address.SetBase (“10.1.3.0”, “255.255.255.0”);
Ipv4InterfaceContainer if3 = address.Assign (devices.Get (2));
// Set up applications (e.g., a UDP echo server and client)
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (3));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (if3.GetAddress (1), 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
pointToPoint.EnablePcapAll (“custom-l3-protocol-simulation”);
// Run the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
Finally, we have implemented the simple custom Layer3 protocol using custom routing protocol in ns3 environment by creating a new module to handle Layer 3 functionalities.
Ns3simulation.com are highly skilled programmers who provide customized outcomes for Layer 3 (L3) protocols in ns3tool.