Geographic Perimeter Stateless Routing (GPSR) is a routing protocol for wireless networks which utilizes the locations of routers and a packet’s destination for making packet furtherance decisions. For mobile ad hoc networks (MANETs) and vehicular ad hoc networks (VANETs), GPSR is well-suited.
In built-in routing protocol of ns3, GPSR is not included. But we can implement it by developing a custom routing protocol or we can integrate an external library or by patching which provides GPSR functionality. Here are the steps for implementing GPSR in ns-3 by creating a custom routing protocol.
Steps for implementing GPSR in ns3
- 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 GPSR protocol. For this, you have to create the necessary directory structure and files.
cd ns-3.xx
cd src
mkdir -p gpsr/model
mkdir -p gpsr/helper
- Create the GPSR header file
In the model directory, create the header file gpsr-routing-protocol.h for the GPSR routing protocol.
#ifndef GPSR_ROUTING_PROTOCOL_H
#define GPSR_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 GpsrRoutingProtocol : public Ipv4RoutingProtocol
{
public:
static TypeId GetTypeId (void);
GpsrRoutingProtocol ();
virtual ~GpsrRoutingProtocol ();
// 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 /* GPSR_ROUTING_PROTOCOL_H */
- Create the GPSR Source File
In the model directory, create the source file gpsr-routing-protocol.cc for the GPSR routing protocol.
#include “gpsr-routing-protocol.h”
#include “ns3/log.h”
#include “ns3/ipv4-route.h”
#include “ns3/simulator.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“GpsrRoutingProtocol”);
NS_OBJECT_ENSURE_REGISTERED (GpsrRoutingProtocol);
TypeId
GpsrRoutingProtocol::GetTypeId (void)
{
static TypeId tid = TypeId (“ns3::GpsrRoutingProtocol”)
.SetParent<Ipv4RoutingProtocol> ()
.SetGroupName(“Internet”)
.AddConstructor<GpsrRoutingProtocol> ();
return tid;
}
GpsrRoutingProtocol::GpsrRoutingProtocol ()
{
}
GpsrRoutingProtocol::~GpsrRoutingProtocol ()
{
}
void
GpsrRoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
{
m_ipv4 = ipv4;
}
Ptr<NetDevice>
GpsrRoutingProtocol::GetNetDevice (uint32_t interface)
{
return m_ipv4->GetNetDevice (interface);
}
Ptr<MobilityModel>
GpsrRoutingProtocol::GetMobilityModel (Ptr<NetDevice> netDevice)
{
return netDevice->GetNode ()->GetObject<MobilityModel> ();
}
Ipv4Address
GpsrRoutingProtocol::GetNextHop (Ipv4Address dest)
{
// Simplified example of next hop selection based on GPSR
Ipv4Address nextHop = Ipv4Address::GetBroadcast ();
double minDistance = std::numeric_limits<double>::max ();
Ptr<MobilityModel> destMobility = GetMobilityModel (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (dest)));
Vector destPosition = destMobility->GetPosition ();
for (auto const &entry : m_routingTable)
{
Ptr<MobilityModel> neighborMobility = GetMobilityModel (m_ipv4->GetNetDevice (entry.second.GetInterface ()));
Vector neighborPosition = neighborMobility->GetPosition ();
double distance = CalculateDistance (neighborPosition, destPosition);
if (distance < minDistance)
{
minDistance = distance;
nextHop = entry.first;
}
}
return nextHop;
}
Ptr<Ipv4Route>
GpsrRoutingProtocol::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
GpsrRoutingProtocol::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
GpsrRoutingProtocol::NotifyInterfaceUp (uint32_t interface)
{
}
void
GpsrRoutingProtocol::NotifyInterfaceDown (uint32_t interface)
{
}
void
GpsrRoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
}
void
GpsrRoutingProtocol::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
{
}
void
GpsrRoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
{
*stream->GetStream () << “GPSR 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 gpsr-helper.h for the GPSR.
#ifndef GPSR_HELPER_H
#define GPSR_HELPER_H
#include “ns3/ipv4-routing-helper.h”
#include “gpsr-routing-protocol.h”
namespace ns3 {
class GpsrHelper : public Ipv4RoutingHelper
{
public:
GpsrHelper ();
virtual ~GpsrHelper ();
GpsrHelper* Copy (void) const;
virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
};
} // namespace ns3
#endif /* GPSR_HELPER_H */
Create the GPSR helper source file gpsr-helper.cc in the helper directory.
#include “gpsr-helper.h”
#include “ns3/node.h”
#include “ns3/ipv4.h”
namespace ns3 {
GpsrHelper::GpsrHelper ()
{
}
GpsrHelper::~GpsrHelper ()
{
}
GpsrHelper*
GpsrHelper::Copy (void) const
{
return new GpsrHelper (*this);
}
Ptr<Ipv4RoutingProtocol>
GpsrHelper::Create (Ptr<Node> node) const
{
Ptr<GpsrRoutingProtocol> gpsrRouting = CreateObject<GpsrRoutingProtocol> ();
node->AggregateObject (gpsrRouting);
return gpsrRouting;
}
} // namespace ns3
- Update CMakeLists.txt
In the ns3 build system, add a new GPSR module. Edit src/CMakeLists.txt and add the following line:
add_subdirectory (gpsr)
Create src/gpsr/CMakeLists.txt with the following content:
ns3_add_library (gpsr
model/gpsr-routing-protocol.cc
helper/gpsr-helper.cc
)
target_link_libraries (gpsr)
- Set up the network topology
To use the GPSR 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 “gpsr-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;
GpsrHelper gpsr;
stack.SetRoutingHelper (gpsr);
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 (“gpsr-simulation.tr”));
wifiPhy.EnablePcapAll (“gpsr-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/gpsr-simulation
- Analyze the results
You can analyze the results after running the simulation, by using the generated trace files (gpsr-simulation.tr and gpsr-simulation-0-0.pcap).
Example script for GPSR 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 “gpsr-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;
GpsrHelper gpsr;
stack.SetRoutingHelper (gpsr);
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 (“gpsr-simulation.tr”));
wifiPhy.EnablePcapAll (“gpsr-simulation”);
// Run the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
Overall, we had learned on implementing GPSR (Geographic Perimeter Stateless Routing) in ns3 by creating a custom routing protocol through its performance analysis. Also, we provide more related information on GPSR protocol. custom routing protocol based on your project are developed by our researchers.