How to Implement ZRP protocol in ns3
To implement Zone Routing Protocol (ZRP) in ns3, we need to create a custom module since, ns3 does not natively support ZRP. It is also a well-known example for hybrid routing protocol which combines the proactive and reactive routing approaches on simulating.
The below steps will provide the instructions to implement a simplified version of ZRP.
Step-by-Step Guide to Implementing ZRP in ns-3
- Set Up Your Environment
Ensure that ns3 is installed on the system.
- Create Custom ZRP Protocol
First, create a custom protocol for ZRP. This involves creating header files and source files for ZRP.
Create ZRP Protocol Files
Create the directory structure for the custom ZRP module.
cd ns-3.xx/src
mkdir -p zrp/model
mkdir -p zrp/helper
cd zrp
3. Define ZRP Header File
Create zrp-routing-protocol.h in the model directory.
#ifndef ZRP_ROUTING_PROTOCOL_H
#define ZRP_ROUTING_PROTOCOL_H
#include “ns3/ipv4-routing-protocol.h”
#include “ns3/ipv4.h”
#include “ns3/timer.h”
#include “ns3/ipv4-address.h”
#include “ns3/ipv4-routing-table-entry.h”
#include “ns3/node-container.h”
namespace ns3 {
class ZrpRoutingProtocol : public Ipv4RoutingProtocol
{
public:
static TypeId GetTypeId (void);
ZrpRoutingProtocol ();
virtual ~ZrpRoutingProtocol ();
void Setup (Ptr<Ipv4> ipv4, NodeContainer nodes, uint32_t zoneRadius);
// 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;
NodeContainer m_nodes;
uint32_t m_zoneRadius;
std::map<Ipv4Address, Ptr<Ipv4Route>> m_routingTable;
void UpdateRoutingTable ();
Ipv4Address GetNetworkAddress (Ipv4Address ip);
void SendIarpMessages ();
void HandleIarpMessages (Ptr<Socket> socket);
void SendIerpMessages ();
void HandleIerpMessages (Ptr<Socket> socket);
};
} // namespace ns3
#endif /* ZRP_ROUTING_PROTOCOL_H */
4. Define ZRP Source File
Create zrp-routing-protocol.cc in the model directory.
#include “zrp-routing-protocol.h”
#include “ns3/log.h”
#include “ns3/ipv4-route.h”
#include “ns3/simulator.h”
#include “ns3/socket-factory.h”
#include “ns3/inet-socket-address.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“ZrpRoutingProtocol”);
NS_OBJECT_ENSURE_REGISTERED (ZrpRoutingProtocol);
TypeId
ZrpRoutingProtocol::GetTypeId (void)
{
static TypeId tid = TypeId (“ns3::ZrpRoutingProtocol”)
.SetParent<Ipv4RoutingProtocol> ()
.SetGroupName (“Internet”)
.AddConstructor<ZrpRoutingProtocol> ();
return tid;
}
ZrpRoutingProtocol::ZrpRoutingProtocol ()
{
}
ZrpRoutingProtocol::~ZrpRoutingProtocol ()
{
}
void
ZrpRoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
{
m_ipv4 = ipv4;
UpdateRoutingTable ();
}
void
ZrpRoutingProtocol::Setup (Ptr<Ipv4> ipv4, NodeContainer nodes, uint32_t zoneRadius)
{
m_ipv4 = ipv4;
m_nodes = nodes;
m_zoneRadius = zoneRadius;
UpdateRoutingTable ();
}
void
ZrpRoutingProtocol::NotifyInterfaceUp (uint32_t interface)
{
UpdateRoutingTable ();
}
void
ZrpRoutingProtocol::NotifyInterfaceDown (uint32_t interface)
{
UpdateRoutingTable ();
}
void
ZrpRoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
UpdateRoutingTable ();
}
void
ZrpRoutingProtocol::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
UpdateRoutingTable ();
}
Ptr<Ipv4Route>
ZrpRoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
{
Ipv4Address dest = header.GetDestination ();
auto it = m_routingTable.find (GetNetworkAddress (dest));
if (it != m_routingTable.end ())
{
return it->second;
}
sockerr = Socket::ERROR_NOROUTETOHOST;
return nullptr;
}
bool
ZrpRoutingProtocol::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
{
Ipv4Address dest = header.GetDestination ();
auto it = m_routingTable.find (GetNetworkAddress (dest));
if (it != m_routingTable.end ())
{
Ptr<Ipv4Route> route = it->second;
if (route->GetOutputDevice () == idev)
{
lcb (p, header, idev);
return true;
}
else
{
ucb (route, p, header);
return true;
}
}
ecb (p, header, Socket::ERROR_NOROUTETOHOST);
return false;
}
void
ZrpRoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
{
*stream->GetStream () << “ZRP Routing Table” << std::endl;
for (auto it = m_routingTable.begin (); it != m_routingTable.end (); ++it)
{
*stream->GetStream () << it->first << ” -> ” << it->second->GetGateway () << ” via ” << it->second->GetOutputDevice ()->GetIfIndex () << std::endl;
}
}
Ipv4Address
ZrpRoutingProtocol::GetNetworkAddress (Ipv4Address ip)
{
uint32_t address = ip.Get ();
if ((address & 0x80000000) == 0)
{
return Ipv4Address (address & 0xff000000); // Class A
}
else if ((address & 0xc0000000) == 0x80000000)
{
return Ipv4Address (address & 0xffff0000); // Class B
}
else
{
return Ipv4Address (address & 0xffffff00); // Class C
}
}
void
ZrpRoutingProtocol::UpdateRoutingTable ()
{
m_routingTable.clear ();
for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); ++i)
{
for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); ++j)
{
Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (i, j);
Ipv4Address netAddr = GetNetworkAddress (ifAddr.GetLocal ());
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (Ipv4Address::GetBroadcast ());
route->SetGateway (Ipv4Address (“0.0.0.0”));
route->SetOutputDevice (m_ipv4->GetNetDevice (i));
m_routingTable[netAddr] = route;
}
}
}
void
ZrpRoutingProtocol::SendIarpMessages ()
{
// Implement IARP message sending logic here
}
void
ZrpRoutingProtocol::HandleIarpMessages (Ptr<Socket> socket)
{
// Implement IARP message handling logic here
}
void
ZrpRoutingProtocol::SendIerpMessages ()
{
// Implement IERP message sending logic here
}
void
ZrpRoutingProtocol::HandleIerpMessages (Ptr<Socket> socket)
{
// Implement IERP message handling logic here
}
} // namespace ns3
5. Define ZRP Helper
Create zrp-helper.h in the helper directory.
#ifndef ZRP_HELPER_H
#define ZRP_HELPER_H
#include “ns3/ipv4-routing-helper.h”
#include “ns3/zrp-routing-protocol.h”
namespace ns3 {
class ZrpHelper : public Ipv4RoutingHelper
{
public:
ZrpHelper ();
virtual ~ZrpHelper ();
ZrpHelper* Copy (void) const;
virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
};
} // namespace ns3
#endif /* ZRP_HELPER_H */
Create zrp-helper.cc in the helper directory.
#include “zrp-helper.h”
#include “ns3/zrp-routing-protocol.h”
#include “ns3/node.h”
#include “ns3/ipv4.h”
namespace ns3 {
ZrpHelper::ZrpHelper ()
{
}
ZrpHelper::~ZrpHelper ()
{
}
ZrpHelper*
ZrpHelper::Copy (void) const
{
return new ZrpHelper (*this);
}
Ptr<Ipv4RoutingProtocol>
ZrpHelper::Create (Ptr<Node> node) const
{
Ptr<ZrpRoutingProtocol> zrpRouting = CreateObject<ZrpRoutingProtocol> ();
node->AggregateObject (zrpRouting);
return zrpRouting;
}
} // namespace ns3
6. Update CMakeLists.txt
Add the new ZRP module to the ns3 build system. Edit src/CMakeLists.txt and add the following line:
add_subdirectory (zrp)
Create src/zrp/CMakeLists.txt with the following content:
ns3_add_library (zrp
model/zrp-routing-protocol.cc
helper/zrp-helper.cc
)
target_link_libraries (zrp)
7. Set Up the Network Topology
Create a simulation script in the scratch directory to use the ZRP 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/mobility-module.h”
#include “ns3/wifi-module.h”
#include “ns3/zrp-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;
mobility.SetPositionAllocator (“ns3::GridPositionAllocator”,
“MinX”, DoubleValue (0.0),
“MinY”, DoubleValue (0.0),
“DeltaX”, DoubleValue (5.0),
“DeltaY”, DoubleValue (5.0),
“GridWidth”, UintegerValue (5),
“LayoutType”, StringValue (“RowFirst”));
mobility.SetMobilityModel (“ns3::ConstantPositionMobilityModel”);
mobility.Install (nodes);
// Install the internet stack on nodes
InternetStackHelper stack;
ZrpHelper zrp;
stack.SetRoutingHelper (zrp);
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 (“zrp-simulation.tr”));
wifiPhy.EnablePcapAll (“zrp-simulation”);
// Run the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
8. Build and Run the Simulation
After writing the script and creating the necessary files, build and run it.
./waf build
./waf –run scratch/zrp-simulation
On the conclusion, we all get to know that to implement ZRP which is hybrid routing protocol that combines routing approaches need a custom module for simulation, as it does not directly support by ns3. Implement ZRP protocol in ns3 with the help of ns3simulation.com where we provide you best guidance.