--- a/examples/routing/aodv.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This is an example script for AODV manet routing protocol.
- *
- * Authors: Pavel Boyko <boyko@iitp.ru>
- */
-
-#include "ns3/aodv-module.h"
-#include "ns3/core-module.h"
-#include "ns3/network-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/mobility-module.h"
-#include "ns3/contrib-module.h"
-#include "ns3/wifi-module.h"
-#include "ns3/v4ping-helper.h"
-#include <iostream>
-#include <cmath>
-
-using namespace ns3;
-
-/**
- * \brief Test script.
- *
- * This script creates 1-dimensional grid topology and then ping last node from the first one:
- *
- * [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.04]
- *
- * ping 10.0.0.4
- */
-class AodvExample
-{
-public:
- AodvExample ();
- /// Configure script parameters, \return true on successful configuration
- bool Configure (int argc, char **argv);
- /// Run simulation
- void Run ();
- /// Report results
- void Report (std::ostream & os);
-
-private:
- ///\name parameters
- //\{
- /// Number of nodes
- uint32_t size;
- /// Distance between nodes, meters
- double step;
- /// Simulation time, seconds
- double totalTime;
- /// Write per-device PCAP traces if true
- bool pcap;
- /// Print routes if true
- bool printRoutes;
- //\}
-
- ///\name network
- //\{
- NodeContainer nodes;
- NetDeviceContainer devices;
- Ipv4InterfaceContainer interfaces;
- //\}
-
-private:
- void CreateNodes ();
- void CreateDevices ();
- void InstallInternetStack ();
- void InstallApplications ();
-};
-
-int main (int argc, char **argv)
-{
- AodvExample test;
- if (! test.Configure(argc, argv))
- NS_FATAL_ERROR ("Configuration failed. Aborted.");
-
- test.Run ();
- test.Report (std::cout);
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-AodvExample::AodvExample () :
- size (10),
- step (100),
- totalTime (10),
- pcap (true),
- printRoutes (true)
-{
-}
-
-bool
-AodvExample::Configure (int argc, char **argv)
-{
- // Enable AODV logs by default. Comment this if too noisy
- // LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
-
- SeedManager::SetSeed(12345);
- CommandLine cmd;
-
- cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
- cmd.AddValue ("printRoutes", "Print routing table dumps.", printRoutes);
- cmd.AddValue ("size", "Number of nodes.", size);
- cmd.AddValue ("time", "Simulation time, s.", totalTime);
- cmd.AddValue ("step", "Grid step, m", step);
-
- cmd.Parse (argc, argv);
- return true;
-}
-
-void
-AodvExample::Run ()
-{
-// Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1)); // enable rts cts all the time.
- CreateNodes ();
- CreateDevices ();
- InstallInternetStack ();
- InstallApplications ();
-
- std::cout << "Starting simulation for " << totalTime << " s ...\n";
-
- Simulator::Stop (Seconds (totalTime));
- Simulator::Run ();
- Simulator::Destroy ();
-}
-
-void
-AodvExample::Report (std::ostream &)
-{
-}
-
-void
-AodvExample::CreateNodes ()
-{
- std::cout << "Creating " << (unsigned)size << " nodes " << step << " m apart.\n";
- nodes.Create (size);
- // Name nodes
- for (uint32_t i = 0; i < size; ++i)
- {
- std::ostringstream os;
- os << "node-" << i;
- Names::Add (os.str (), nodes.Get (i));
- }
- // Create static grid
- MobilityHelper mobility;
- mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
- "MinX", DoubleValue (0.0),
- "MinY", DoubleValue (0.0),
- "DeltaX", DoubleValue (step),
- "DeltaY", DoubleValue (0),
- "GridWidth", UintegerValue (size),
- "LayoutType", StringValue ("RowFirst"));
- mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
- mobility.Install (nodes);
-}
-
-void
-AodvExample::CreateDevices ()
-{
- NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
- wifiMac.SetType ("ns3::AdhocWifiMac");
- YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
- YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
- wifiPhy.SetChannel (wifiChannel.Create ());
- WifiHelper wifi = WifiHelper::Default ();
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("OfdmRate6Mbps"), "RtsCtsThreshold", UintegerValue (0));
- devices = wifi.Install (wifiPhy, wifiMac, nodes);
-
- if (pcap)
- {
- wifiPhy.EnablePcapAll (std::string ("aodv"));
- }
-}
-
-void
-AodvExample::InstallInternetStack ()
-{
- AodvHelper aodv;
- // you can configure AODV attributes here using aodv.Set(name, value)
- InternetStackHelper stack;
- stack.SetRoutingHelper (aodv);
- stack.Install (nodes);
- Ipv4AddressHelper address;
- address.SetBase ("10.0.0.0", "255.0.0.0");
- interfaces = address.Assign (devices);
-
- if (printRoutes)
- {
- Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("aodv.routes", std::ios::out);
- aodv.PrintRoutingTableAllAt (Seconds (8), routingStream);
- }
-}
-
-void
-AodvExample::InstallApplications ()
-{
- V4PingHelper ping (interfaces.GetAddress (size - 1));
- ping.SetAttribute ("Verbose", BooleanValue (true));
-
- ApplicationContainer p = ping.Install (nodes.Get (0));
- p.Start (Seconds (0));
- p.Stop (Seconds (totalTime) - Seconds(0.001));
-
- // move node away
- Ptr<Node> node = nodes.Get (size/2);
- Ptr<MobilityModel> mob = node->GetObject<MobilityModel> ();
- Simulator::Schedule (Seconds (totalTime/3), &MobilityModel::SetPosition, mob, Vector (1e5, 1e5, 1e5));
-}
-
--- a/examples/routing/nix-simple.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ns3/core-module.h"
-#include "ns3/core-module.h"
-#include "ns3/network-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/ipv4-static-routing-helper.h"
-#include "ns3/ipv4-list-routing-helper.h"
-
-/*
- * Simple point to point links:
- *
- * n0 -- n1 -- n2 -- n3
- *
- * n0 has UdpEchoClient
- * n3 has UdpEchoServer
- *
- * n0 IP: 10.1.1.1
- * n1 IP: 10.1.1.2, 10.1.2.1
- * n2 IP: 10.1.2.2, 10.1.3.1
- * n3 IP: 10.1.3.2
- *
- */
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
-
- int
-main (int argc, char *argv[])
-{
- LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
- LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
-
- NodeContainer nodes12;
- nodes12.Create (2);
-
- NodeContainer nodes23;
- nodes23.Add (nodes12.Get (1));
- nodes23.Create (1);
-
- NodeContainer nodes34;
- nodes34.Add(nodes23.Get (1));
- nodes34.Create (1);
-
- PointToPointHelper pointToPoint;
- pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
- pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
-
- NodeContainer allNodes = NodeContainer (nodes12, nodes23.Get (1), nodes34.Get (1));
-
- // NixHelper to install nix-vector routing
- // on all nodes
- Ipv4NixVectorHelper nixRouting;
- Ipv4StaticRoutingHelper staticRouting;
-
- Ipv4ListRoutingHelper list;
- list.Add (staticRouting, 0);
- list.Add (nixRouting, 10);
-
- InternetStackHelper stack;
- stack.SetRoutingHelper (list);
- stack.Install (allNodes);
-
- NetDeviceContainer devices12;
- NetDeviceContainer devices23;
- NetDeviceContainer devices34;
- devices12 = pointToPoint.Install (nodes12);
- devices23 = pointToPoint.Install (nodes23);
- devices34 = pointToPoint.Install (nodes34);
-
- Ipv4AddressHelper address1;
- address1.SetBase ("10.1.1.0", "255.255.255.0");
- Ipv4AddressHelper address2;
- address2.SetBase ("10.1.2.0", "255.255.255.0");
- Ipv4AddressHelper address3;
- address3.SetBase ("10.1.3.0", "255.255.255.0");
-
- address1.Assign (devices12);
- address2.Assign (devices23);
- Ipv4InterfaceContainer interfaces = address3.Assign (devices34);
-
- UdpEchoServerHelper echoServer (9);
-
- ApplicationContainer serverApps = echoServer.Install (nodes34.Get (1));
- serverApps.Start (Seconds (1.0));
- serverApps.Stop (Seconds (10.0));
-
- UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
- echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
- echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
- echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
-
- ApplicationContainer clientApps = echoClient.Install (nodes12.Get (0));
- clientApps.Start (Seconds (2.0));
- clientApps.Stop (Seconds (10.0));
-
- // Trace routing tables
- Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-simple.routes", std::ios::out);
- nixRouting.PrintRoutingTableAllAt (Seconds (8), routingStream);
-
- Simulator::Run ();
- Simulator::Destroy ();
- return 0;
-}
--- a/examples/routing/nms-p2p-nix.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * (c) 2009, GTech Systems, Inc. - Alfred Park <park@gtech-systems.com>
- *
- * DARPA NMS Campus Network Model
- *
- * This topology replicates the original NMS Campus Network model
- * with the exception of chord links (which were never utilized in the
- * original model)
- * Link Bandwidths and Delays may not be the same as the original
- * specifications
- *
- * The fundamental unit of the NMS model consists of a campus network. The
- * campus network topology can been seen here:
- * http://www.nsnam.org/~jpelkey3/nms.png
- * The number of hosts (default 42) is variable. Finally, an arbitrary
- * number of these campus networks can be connected together (default 2)
- * to make very large simulations.
- */
-
-// for timing functions
-#include <cstdlib>
-#include <sys/time.h>
-#include <fstream>
-
-#include "ns3/core-module.h"
-#include "ns3/internet-module.h"
-#include "ns3/network-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/onoff-application.h"
-#include "ns3/packet-sink.h"
-#include "ns3/point-to-point-net-device.h"
-#include "ns3/simulator.h"
-#include "ns3/ipv4-static-routing-helper.h"
-#include "ns3/ipv4-list-routing-helper.h"
-
-using namespace std;
-using namespace ns3;
-
-typedef struct timeval TIMER_TYPE;
-#define TIMER_NOW(_t) gettimeofday(&_t,NULL);
-#define TIMER_SECONDS(_t) ((double)(_t).tv_sec + (_t).tv_usec*1e-6)
-#define TIMER_DIFF(_t1, _t2) (TIMER_SECONDS(_t1)-TIMER_SECONDS(_t2))
-
-NS_LOG_COMPONENT_DEFINE ("CampusNetworkModel");
-
-void Progress ()
-{
- Time now = Simulator::Now ();
- Simulator::Schedule (Seconds (0.1), Progress);
-}
-
-int
-main (int argc, char *argv[])
-{
- TIMER_TYPE t0, t1, t2;
- TIMER_NOW(t0);
- cout << " ==== DARPA NMS CAMPUS NETWORK SIMULATION ====" << endl;
- LogComponentEnable ("OnOffApplication", LOG_LEVEL_INFO);
-
- int nCN = 2, nLANClients = 42;
- bool nix = true;
-
- CommandLine cmd;
- cmd.AddValue ("CN", "Number of total CNs [2]", nCN);
- cmd.AddValue ("LAN", "Number of nodes per LAN [42]", nLANClients);
- cmd.AddValue ("NIX", "Toggle nix-vector routing", nix);
- cmd.Parse (argc,argv);
-
- if (nCN < 2)
- {
- cout << "Number of total CNs (" << nCN << ") lower than minimum of 2"
- << endl;
- return 1;
- }
-
- cout << "Number of CNs: " << nCN << ", LAN nodes: " << nLANClients << endl;
-
- NodeContainer nodes_net0[nCN][3], nodes_net1[nCN][6], nodes_netLR[nCN],
- nodes_net2[nCN][14], nodes_net2LAN[nCN][7][nLANClients],
- nodes_net3[nCN][9], nodes_net3LAN[nCN][5][nLANClients];
- PointToPointHelper p2p_2gb200ms, p2p_1gb5ms, p2p_100mb1ms;
- InternetStackHelper stack;
- Ipv4InterfaceContainer ifs, ifs0[nCN][3], ifs1[nCN][6], ifs2[nCN][14],
- ifs3[nCN][9], ifs2LAN[nCN][7][nLANClients],
- ifs3LAN[nCN][5][nLANClients];
- Ipv4AddressHelper address;
- std::ostringstream oss;
- p2p_1gb5ms.SetDeviceAttribute ("DataRate", StringValue ("1Gbps"));
- p2p_1gb5ms.SetChannelAttribute ("Delay", StringValue ("5ms"));
- p2p_2gb200ms.SetDeviceAttribute ("DataRate", StringValue ("2Gbps"));
- p2p_2gb200ms.SetChannelAttribute ("Delay", StringValue ("200ms"));
- p2p_100mb1ms.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
- p2p_100mb1ms.SetChannelAttribute ("Delay", StringValue ("1ms"));
-
- // Setup NixVector Routing
- Ipv4NixVectorHelper nixRouting;
- Ipv4StaticRoutingHelper staticRouting;
-
- Ipv4ListRoutingHelper list;
- list.Add (staticRouting, 0);
- list.Add (nixRouting, 10);
-
- if (nix)
- {
- stack.SetRoutingHelper (list);
- }
-
- // Create Campus Networks
- for (int z = 0; z < nCN; ++z)
- {
- cout << "Creating Campus Network " << z << ":" << endl;
- // Create Net0
- cout << " SubNet [ 0";
- for (int i = 0; i < 3; ++i)
- {
- nodes_net0[z][i].Create (1);
- stack.Install (nodes_net0[z][i]);
- }
- nodes_net0[z][0].Add (nodes_net0[z][1].Get (0));
- nodes_net0[z][1].Add (nodes_net0[z][2].Get (0));
- nodes_net0[z][2].Add (nodes_net0[z][0].Get (0));
- NetDeviceContainer ndc0[3];
- for (int i = 0; i < 3; ++i)
- {
- ndc0[i] = p2p_1gb5ms.Install (nodes_net0[z][i]);
- }
- // Create Net1
- cout << " 1";
- for (int i = 0; i < 6; ++i)
- {
- nodes_net1[z][i].Create (1);
- stack.Install (nodes_net1[z][i]);
- }
- nodes_net1[z][0].Add (nodes_net1[z][1].Get (0));
- nodes_net1[z][2].Add (nodes_net1[z][0].Get (0));
- nodes_net1[z][3].Add (nodes_net1[z][0].Get (0));
- nodes_net1[z][4].Add (nodes_net1[z][1].Get (0));
- nodes_net1[z][5].Add (nodes_net1[z][1].Get (0));
- NetDeviceContainer ndc1[6];
- for (int i = 0; i < 6; ++i)
- {
- if (i == 1)
- {
- continue;
- }
- ndc1[i] = p2p_1gb5ms.Install (nodes_net1[z][i]);
- }
- // Connect Net0 <-> Net1
- NodeContainer net0_1;
- net0_1.Add (nodes_net0[z][2].Get (0));
- net0_1.Add (nodes_net1[z][0].Get (0));
- NetDeviceContainer ndc0_1;
- ndc0_1 = p2p_1gb5ms.Install (net0_1);
- oss.str("");
- oss << 10 + z << ".1.252.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc0_1);
- // Create Net2
- cout << " 2";
- for (int i = 0; i < 14; ++i)
- {
- nodes_net2[z][i].Create (1);
- stack.Install (nodes_net2[z][i]);
- }
- nodes_net2[z][0].Add (nodes_net2[z][1].Get (0));
- nodes_net2[z][2].Add (nodes_net2[z][0].Get (0));
- nodes_net2[z][1].Add (nodes_net2[z][3].Get (0));
- nodes_net2[z][3].Add (nodes_net2[z][2].Get (0));
- nodes_net2[z][4].Add (nodes_net2[z][2].Get (0));
- nodes_net2[z][5].Add (nodes_net2[z][3].Get (0));
- nodes_net2[z][6].Add (nodes_net2[z][5].Get (0));
- nodes_net2[z][7].Add (nodes_net2[z][2].Get (0));
- nodes_net2[z][8].Add (nodes_net2[z][3].Get (0));
- nodes_net2[z][9].Add (nodes_net2[z][4].Get (0));
- nodes_net2[z][10].Add (nodes_net2[z][5].Get (0));
- nodes_net2[z][11].Add (nodes_net2[z][6].Get (0));
- nodes_net2[z][12].Add (nodes_net2[z][6].Get (0));
- nodes_net2[z][13].Add (nodes_net2[z][6].Get (0));
- NetDeviceContainer ndc2[14];
- for (int i = 0; i < 14; ++i)
- {
- ndc2[i] = p2p_1gb5ms.Install (nodes_net2[z][i]);
- }
- NetDeviceContainer ndc2LAN[7][nLANClients];
- for (int i = 0; i < 7; ++i)
- {
- oss.str ("");
- oss << 10 + z << ".4." << 15 + i << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- for (int j = 0; j < nLANClients; ++j)
- {
- nodes_net2LAN[z][i][j].Create (1);
- stack.Install (nodes_net2LAN[z][i][j]);
- nodes_net2LAN[z][i][j].Add (nodes_net2[z][i+7].Get (0));
- ndc2LAN[i][j] = p2p_100mb1ms.Install (nodes_net2LAN[z][i][j]);
- ifs2LAN[z][i][j] = address.Assign (ndc2LAN[i][j]);
- }
- }
- // Create Net3
- cout << " 3 ]" << endl;
- for (int i = 0; i < 9; ++i)
- {
- nodes_net3[z][i].Create (1);
- stack.Install(nodes_net3[z][i]);
- }
- nodes_net3[z][0].Add (nodes_net3[z][1].Get (0));
- nodes_net3[z][1].Add (nodes_net3[z][2].Get (0));
- nodes_net3[z][2].Add (nodes_net3[z][3].Get (0));
- nodes_net3[z][3].Add (nodes_net3[z][1].Get (0));
- nodes_net3[z][4].Add (nodes_net3[z][0].Get (0));
- nodes_net3[z][5].Add (nodes_net3[z][0].Get (0));
- nodes_net3[z][6].Add (nodes_net3[z][2].Get (0));
- nodes_net3[z][7].Add (nodes_net3[z][3].Get (0));
- nodes_net3[z][8].Add (nodes_net3[z][3].Get (0));
- NetDeviceContainer ndc3[9];
- for (int i = 0; i < 9; ++i)
- {
- ndc3[i] = p2p_1gb5ms.Install (nodes_net3[z][i]);
- }
- NetDeviceContainer ndc3LAN[5][nLANClients];
- for (int i = 0; i < 5; ++i)
- {
- oss.str ("");
- oss << 10 + z << ".5." << 10 + i << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.255");
- for (int j = 0; j < nLANClients; ++j)
- {
- nodes_net3LAN[z][i][j].Create (1);
- stack.Install (nodes_net3LAN[z][i][j]);
- nodes_net3LAN[z][i][j].Add (nodes_net3[z][i+4].Get (0));
- ndc3LAN[i][j] = p2p_100mb1ms.Install (nodes_net3LAN[z][i][j]);
- ifs3LAN[z][i][j] = address.Assign (ndc3LAN[i][j]);
- }
- }
- cout << " Connecting Subnets..." << endl;
- // Create Lone Routers (Node 4 & 5)
- nodes_netLR[z].Create (2);
- stack.Install (nodes_netLR[z]);
- NetDeviceContainer ndcLR;
- ndcLR = p2p_1gb5ms.Install (nodes_netLR[z]);
- // Connect Net2/Net3 through Lone Routers to Net0
- NodeContainer net0_4, net0_5, net2_4a, net2_4b, net3_5a, net3_5b;
- net0_4.Add (nodes_netLR[z].Get (0));
- net0_4.Add (nodes_net0[z][0].Get (0));
- net0_5.Add (nodes_netLR[z].Get (1));
- net0_5.Add (nodes_net0[z][1].Get (0));
- net2_4a.Add (nodes_netLR[z].Get (0));
- net2_4a.Add (nodes_net2[z][0].Get (0));
- net2_4b.Add (nodes_netLR[z].Get (1));
- net2_4b.Add (nodes_net2[z][1].Get (0));
- net3_5a.Add (nodes_netLR[z].Get (1));
- net3_5a.Add (nodes_net3[z][0].Get (0));
- net3_5b.Add (nodes_netLR[z].Get (1));
- net3_5b.Add (nodes_net3[z][1].Get (0));
- NetDeviceContainer ndc0_4, ndc0_5, ndc2_4a, ndc2_4b, ndc3_5a, ndc3_5b;
- ndc0_4 = p2p_1gb5ms.Install (net0_4);
- oss.str ("");
- oss << 10 + z << ".1.253.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc0_4);
- ndc0_5 = p2p_1gb5ms.Install (net0_5);
- oss.str ("");
- oss << 10 + z << ".1.254.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc0_5);
- ndc2_4a = p2p_1gb5ms.Install (net2_4a);
- oss.str ("");
- oss << 10 + z << ".4.253.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc2_4a);
- ndc2_4b = p2p_1gb5ms.Install (net2_4b);
- oss.str ("");
- oss << 10 + z << ".4.254.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc2_4b);
- ndc3_5a = p2p_1gb5ms.Install (net3_5a);
- oss.str ("");
- oss << 10 + z << ".5.253.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc3_5a);
- ndc3_5b = p2p_1gb5ms.Install (net3_5b);
- oss.str ("");
- oss << 10 + z << ".5.254.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc3_5b);
- // Assign IP addresses
- cout << " Assigning IP addresses..." << endl;
- for (int i = 0; i < 3; ++i)
- {
- oss.str ("");
- oss << 10 + z << ".1." << 1 + i << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs0[z][i] = address.Assign (ndc0[i]);
- }
- for (int i = 0; i < 6; ++i)
- {
- if (i == 1)
- {
- continue;
- }
- oss.str ("");
- oss << 10 + z << ".2." << 1 + i << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs1[z][i] = address.Assign (ndc1[i]);
- }
- oss.str ("");
- oss << 10 + z << ".3.1.0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndcLR);
- for (int i = 0; i < 14; ++i)
- {
- oss.str ("");
- oss << 10 + z << ".4." << 1 + i << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs2[z][i] = address.Assign (ndc2[i]);
- }
- for (int i = 0; i < 9; ++i)
- {
- oss.str ("");
- oss << 10 + z << ".5." << 1 + i << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs3[z][i] = address.Assign (ndc3[i]);
- }
- }
- // Create Ring Links
- if (nCN > 1)
- {
- cout << "Forming Ring Topology..." << endl;
- NodeContainer nodes_ring[nCN];
- for (int z = 0; z < nCN-1; ++z)
- {
- nodes_ring[z].Add (nodes_net0[z][0].Get (0));
- nodes_ring[z].Add (nodes_net0[z+1][0].Get (0));
- }
- nodes_ring[nCN-1].Add (nodes_net0[nCN-1][0].Get (0));
- nodes_ring[nCN-1].Add (nodes_net0[0][0].Get (0));
- NetDeviceContainer ndc_ring[nCN];
- for (int z = 0; z < nCN; ++z)
- {
- ndc_ring[z] = p2p_2gb200ms.Install (nodes_ring[z]);
- oss.str ("");
- oss << "254.1." << z + 1 << ".0";
- address.SetBase (oss.str ().c_str (), "255.255.255.0");
- ifs = address.Assign (ndc_ring[z]);
- }
- }
-
- // Create Traffic Flows
- cout << "Creating TCP Traffic Flows:" << endl;
- Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (500000));
- Config::SetDefault ("ns3::OnOffApplication::OnTime",
- RandomVariableValue (ConstantVariable (1)));
- Config::SetDefault ("ns3::OnOffApplication::OffTime",
- RandomVariableValue (ConstantVariable (0)));
- Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (512));
-
- UniformVariable urng;
- int r1;
- double r2;
- for (int z = 0; z < nCN; ++z)
- {
- int x = z + 1;
- if (z == nCN - 1)
- {
- x = 0;
- }
- // Subnet 2 LANs
- cout << " Campus Network " << z << " Flows [ Net2 ";
- for (int i = 0; i < 7; ++i)
- {
- for (int j = 0; j < nLANClients; ++j)
- {
- // Sinks
- PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory",
- InetSocketAddress (Ipv4Address::GetAny (), 9999));
- ApplicationContainer sinkApp = sinkHelper.Install (
- nodes_net2LAN[z][i][j].Get (0));
- sinkApp.Start (Seconds (0.0));
- // Sources
- r1 = 2 + (int)(4 * urng.GetValue ());
- r2 = 10 * urng.GetValue ();
- OnOffHelper client ("ns3::TcpSocketFactory", Address ());
- AddressValue remoteAddress(InetSocketAddress (
- ifs2LAN[z][i][j].GetAddress (0), 9999));
- client.SetAttribute ("Remote", remoteAddress);
- ApplicationContainer clientApp;
- clientApp.Add (client.Install (nodes_net1[x][r1].Get (0)));
- clientApp.Start (Seconds (r2));
- }
- }
- // Subnet 3 LANs
- cout << "Net3 ]" << endl;
- for (int i = 0; i < 5; ++i)
- {
- for (int j = 0; j < nLANClients; ++j)
- {
- // Sinks
- PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory",
- InetSocketAddress (Ipv4Address::GetAny (), 9999));
- ApplicationContainer sinkApp = sinkHelper.Install (
- nodes_net3LAN[z][i][j].Get (0));
- sinkApp.Start (Seconds (0.0));
- // Sources
- r1 = 2 + (int)(4 * urng.GetValue ());
- r2 = 10 * urng.GetValue ();
- OnOffHelper client ("ns3::TcpSocketFactory", Address ());
- AddressValue remoteAddress (InetSocketAddress (
- ifs3LAN[z][i][j].GetAddress (0), 9999));
- client.SetAttribute ("Remote", remoteAddress);
- ApplicationContainer clientApp;
- clientApp.Add (client.Install (nodes_net1[x][r1].Get (0)));
- clientApp.Start (Seconds (r2));
- }
- }
- }
-
- cout << "Created " << NodeList::GetNNodes () << " nodes." << endl;
- TIMER_TYPE routingStart;
- TIMER_NOW (routingStart);
-
- if (nix)
- {
- // Calculate routing tables
- cout << "Using Nix-vectors..." << endl;
- }
- else
- {
- // Calculate routing tables
- cout << "Populating Global Static Routing Tables..." << endl;
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
- }
-
- TIMER_TYPE routingEnd;
- TIMER_NOW (routingEnd);
- cout << "Routing tables population took "
- << TIMER_DIFF (routingEnd, routingStart) << endl;
-
- Simulator::ScheduleNow (Progress);
- cout << "Running simulator..." << endl;
- TIMER_NOW (t1);
- Simulator::Stop (Seconds (100.0));
- Simulator::Run ();
- TIMER_NOW (t2);
- cout << "Simulator finished." << endl;
- Simulator::Destroy ();
-
- double d1 = TIMER_DIFF (t1, t0), d2 = TIMER_DIFF (t2, t1);
- cout << "-----" << endl << "Runtime Stats:" << endl;
- cout << "Simulator init time: " << d1 << endl;
- cout << "Simulator run time: " << d2 << endl;
- cout << "Total elapsed time: " << d1+d2 << endl;
- return 0;
-}
--- a/examples/routing/wscript Fri Feb 25 17:21:08 2011 -0800
+++ b/examples/routing/wscript Sun Feb 27 01:00:17 2011 -0500
@@ -29,18 +29,6 @@
['point-to-point', 'internet', 'csma'])
obj.source = 'mixed-global-routing.cc'
- obj = bld.create_ns3_program('nix-simple',
- ['point-to-point', 'internet', 'nix-vector-routing'])
- obj.source = 'nix-simple.cc'
-
- obj = bld.create_ns3_program('nms-p2p-nix',
- ['point-to-point', 'internet', 'nix-vector-routing'])
- obj.source = 'nms-p2p-nix.cc'
-
obj = bld.create_ns3_program('simple-routing-ping6',
['csma', 'internet'])
obj.source = 'simple-routing-ping6.cc'
-
- obj = bld.create_ns3_program('aodv',
- ['wifi', 'internet', 'aodv'])
- obj.source = 'aodv.cc'
--- a/examples/topology-read/topology-example-sim.cc Fri Feb 25 17:21:08 2011 -0800
+++ b/examples/topology-read/topology-example-sim.cc Sun Feb 27 01:00:17 2011 -0500
@@ -32,6 +32,7 @@
#include "ns3/core-module.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/ipv4-list-routing-helper.h"
+#include "ns3/ipv4-nix-vector-helper.h"
#include "ns3/topology-read-module.h"
#include <list>
--- a/src/helper/aodv-helper.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Pavel Boyko <boyko@iitp.ru>, written after OlsrHelper by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "aodv-helper.h"
-#include "ns3/aodv-routing-protocol.h"
-#include "ns3/node-list.h"
-#include "ns3/names.h"
-#include "ns3/ipv4-list-routing.h"
-
-namespace ns3
-{
-
-AodvHelper::AodvHelper() :
- Ipv4RoutingHelper ()
-{
- m_agentFactory.SetTypeId ("ns3::aodv::RoutingProtocol");
-}
-
-AodvHelper*
-AodvHelper::Copy (void) const
-{
- return new AodvHelper (*this);
-}
-
-Ptr<Ipv4RoutingProtocol>
-AodvHelper::Create (Ptr<Node> node) const
-{
- Ptr<aodv::RoutingProtocol> agent = m_agentFactory.Create<aodv::RoutingProtocol> ();
- node->AggregateObject (agent);
- return agent;
-}
-
-void
-AodvHelper::Set (std::string name, const AttributeValue &value)
-{
- m_agentFactory.Set (name, value);
-}
-
-}
--- a/src/helper/aodv-helper.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Pavel Boyko <boyko@iitp.ru>, written after OlsrHelper by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef AODVHELPER_H_
-#define AODVHELPER_H_
-
-#include "ns3/object-factory.h"
-#include "ns3/node.h"
-#include "ns3/node-container.h"
-#include "ns3/ipv4-routing-helper.h"
-
-namespace ns3
-{
-/**
- * \ingroup aodv
- * \brief Helper class that adds AODV routing to nodes.
- */
-class AodvHelper : public Ipv4RoutingHelper
-{
-public:
- AodvHelper();
-
- /**
- * \internal
- * \returns pointer to clone of this OlsrHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- AodvHelper* Copy (void) const;
-
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- *
- * TODO: support installing AODV on the subset of all available IP interfaces
- */
- virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
- /**
- * \param name the name of the attribute to set
- * \param value the value of the attribute to set.
- *
- * This method controls the attributes of ns3::aodv::RoutingProtocol
- */
- void Set (std::string name, const AttributeValue &value);
-
-private:
- ObjectFactory m_agentFactory;
-};
-
-}
-#endif /* AODVHELPER_H_ */
--- a/src/helper/ipv4-nix-vector-helper.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 The Georgia Institute of Technology
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Josh Pelkey <jpelkey@gatech.edu>
- */
-
-#include "ipv4-nix-vector-helper.h"
-#include "ns3/ipv4-nix-vector-routing.h"
-
-namespace ns3 {
-
-Ipv4NixVectorHelper::Ipv4NixVectorHelper ()
-{
- m_agentFactory.SetTypeId ("ns3::Ipv4NixVectorRouting");
-}
-
-Ipv4NixVectorHelper::Ipv4NixVectorHelper (const Ipv4NixVectorHelper &o)
- : m_agentFactory (o.m_agentFactory)
-{
-}
-
-Ipv4NixVectorHelper*
-Ipv4NixVectorHelper::Copy (void) const
-{
- return new Ipv4NixVectorHelper (*this);
-}
-
-Ptr<Ipv4RoutingProtocol>
-Ipv4NixVectorHelper::Create (Ptr<Node> node) const
-{
- Ptr<Ipv4NixVectorRouting> agent = m_agentFactory.Create<Ipv4NixVectorRouting> ();
- agent->SetNode(node);
- node->AggregateObject (agent);
- return agent;
-}
-} // namespace ns3
--- a/src/helper/ipv4-nix-vector-helper.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 The Georgia Institute of Technology
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Josh Pelkey <jpelkey@gatech.edu>
- */
-
-#ifndef IPV4_NIX_VECTOR_HELPER_H
-#define IPV4_NIX_VECTOR_HELPER_H
-
-#include "ns3/object-factory.h"
-#include "ns3/ipv4-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds Nix-vector routing to nodes.
- *
- * This class is expected to be used in conjunction with
- * ns3::InternetStackHelper::SetRoutingHelper
- *
- */
-class Ipv4NixVectorHelper : public Ipv4RoutingHelper
-{
-public:
- /*
- * Construct an Ipv4NixVectorHelper to make life easier while adding Nix-vector
- * routing to nodes.
- */
- Ipv4NixVectorHelper ();
-
- /**
- * \brief Construct an Ipv4NixVectorHelper from another previously
- * initialized instance (Copy Constructor).
- */
- Ipv4NixVectorHelper (const Ipv4NixVectorHelper &);
-
- /**
- * \internal
- * \returns pointer to clone of this Ipv4NixVectorHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- Ipv4NixVectorHelper* Copy (void) const;
-
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- */
- virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-
-private:
- /**
- * \internal
- * \brief Assignment operator declared private and not implemented to disallow
- * assignment and prevent the compiler from happily inserting its own.
- */
- Ipv4NixVectorHelper &operator = (const Ipv4NixVectorHelper &o);
-
- ObjectFactory m_agentFactory;
-};
-} // namespace ns3
-
-#endif /* IPV4_NIX_VECTOR_HELPER_H */
--- a/src/helper/wscript Fri Feb 25 17:21:08 2011 -0800
+++ b/src/helper/wscript Sun Feb 27 01:00:17 2011 -0500
@@ -13,8 +13,6 @@
'v4ping-helper.cc',
'nqos-wifi-mac-helper.cc',
'qos-wifi-mac-helper.cc',
- 'ipv4-nix-vector-helper.cc',
- 'aodv-helper.cc',
'mesh-helper.cc',
'dot11s-installer.cc',
'flame-installer.cc',
@@ -45,8 +43,6 @@
'v4ping-helper.h',
'nqos-wifi-mac-helper.h',
'qos-wifi-mac-helper.h',
- 'ipv4-nix-vector-helper.h',
- 'aodv-helper.h',
'mesh-helper.h',
'mesh-stack-installer.h',
'dot11s-installer.h',
--- a/src/routing/aodv/aodv-dpd.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#include "aodv-dpd.h"
-
-namespace ns3
-{
-namespace aodv
-{
-
-bool
-DuplicatePacketDetection::IsDuplicate (Ptr<const Packet> p, const Ipv4Header & header)
-{
- return m_idCache.IsDuplicate (header.GetSource (), p->GetUid() );
-}
-void
-DuplicatePacketDetection::SetLifetime (Time lifetime)
-{
- m_idCache.SetLifetime(lifetime);
-}
-
-Time
-DuplicatePacketDetection::GetLifetime () const
-{
- return m_idCache.GetLifeTime();
-}
-
-
-}
-}
-
--- a/src/routing/aodv/aodv-dpd.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#ifndef DUPLICATEPACKETDETECTION_H_
-#define DUPLICATEPACKETDETECTION_H_
-
-#include "aodv-id-cache.h"
-#include "ns3/nstime.h"
-#include "ns3/packet.h"
-#include "ns3/ipv4-header.h"
-
-namespace ns3
-{
-namespace aodv
-{
-/**
- * \ingroup aodv
- *
- * \brief Helper class used to remember already seen packets and detect duplicates.
- *
- * Currently duplicate detection is based on uinique packet ID given by Packet::GetUid ()
- * This approach is known to be weak and should be changed.
- */
-class DuplicatePacketDetection
-{
-public:
- /// C-tor
- DuplicatePacketDetection (Time lifetime) : m_idCache(lifetime) {}
- /// Check that the packet is duplicated. If not, save information about this packet.
- bool IsDuplicate (Ptr<const Packet> p, const Ipv4Header & header);
- /// Set duplicate records lifetimes
- void SetLifetime (Time lifetime);
- /// Get duplicate records lifetimes
- Time GetLifetime () const;
-private:
- /// Impl
- IdCache m_idCache;
-};
-
-}
-}
-
-#endif
--- a/src/routing/aodv/aodv-id-cache.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#include "aodv-id-cache.h"
-#include "ns3/test.h"
-#include <algorithm>
-
-namespace ns3
-{
-namespace aodv
-{
-bool
-IdCache::IsDuplicate (Ipv4Address addr, uint32_t id)
-{
- Purge ();
- for (std::vector<UniqueId>::const_iterator i = m_idCache.begin ();
- i != m_idCache.end (); ++i)
- if (i->m_context == addr && i->m_id == id)
- return true;
- struct UniqueId uniqueId =
- { addr, id, m_lifetime + Simulator::Now () };
- m_idCache.push_back (uniqueId);
- return false;
-}
-void
-IdCache::Purge ()
-{
- m_idCache.erase (remove_if (m_idCache.begin (), m_idCache.end (),
- IsExpired ()), m_idCache.end ());
-}
-
-uint32_t
-IdCache::GetSize ()
-{
- Purge ();
- return m_idCache.size ();
-}
-
-//-----------------------------------------------------------------------------
-// Tests
-//-----------------------------------------------------------------------------
-/// Unit test for id cache
-struct IdCacheTest : public TestCase
-{
- IdCacheTest () : TestCase ("Id Cache"), cache (Seconds(10))
- {}
- virtual void DoRun();
- void CheckTimeout1 ();
- void CheckTimeout2 ();
- void CheckTimeout3 ();
-
- IdCache cache;
-};
-
-void
-IdCacheTest::DoRun ()
-{
- NS_TEST_EXPECT_MSG_EQ (cache.GetLifeTime(), Seconds(10), "Lifetime");
- NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 3), false, "Unknown ID & address");
- NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 4), false, "Unknown ID");
- NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("4.3.2.1"), 3), false, "Unknown address");
- NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 3), true, "Known address & ID");
- cache.SetLifetime(Seconds(15));
- NS_TEST_EXPECT_MSG_EQ (cache.GetLifeTime(), Seconds(15), "New lifetime");
- cache.IsDuplicate (Ipv4Address ("1.1.1.1"), 4);
- cache.IsDuplicate (Ipv4Address ("1.1.1.1"), 4);
- cache.IsDuplicate (Ipv4Address ("2.2.2.2"), 5);
- cache.IsDuplicate (Ipv4Address ("3.3.3.3"), 6);
- NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 6, "trivial");
-
- Simulator::Schedule (Seconds(5), &IdCacheTest::CheckTimeout1, this);
- Simulator::Schedule (Seconds(11), &IdCacheTest::CheckTimeout2, this);
- Simulator::Schedule (Seconds(30), &IdCacheTest::CheckTimeout3, this);
- Simulator::Run ();
- Simulator::Destroy ();
-}
-
-void
-IdCacheTest::CheckTimeout1 ()
-{
- NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 6, "Nothing expire");
-}
-
-void
-IdCacheTest::CheckTimeout2 ()
-{
- NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 3, "3 records left");
-}
-
-void
-IdCacheTest::CheckTimeout3 ()
-{
- NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 0, "All records expire");
-}
-//-----------------------------------------------------------------------------
-class IdCacheTestSuite : public TestSuite
-{
-public:
- IdCacheTestSuite () : TestSuite ("routing-id-cache", UNIT)
- {
- AddTestCase (new IdCacheTest);
- }
-} g_idCacheTestSuite;
-
-}}
--- a/src/routing/aodv/aodv-id-cache.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#ifndef IDCACHE_H_
-#define IDCACHE_H_
-
-#include "ns3/ipv4-address.h"
-#include "ns3/simulator.h"
-#include <vector>
-
-namespace ns3
-{
-namespace aodv
-{
-/**
- * \ingroup aodv
- *
- * \brief Unique packets identification cache used for simple duplicate detection.
- */
-class IdCache
-{
-public:
- /// c-tor
- IdCache (Time lifetime): m_lifetime (lifetime) {}
- /// Check that entry (addr, id) exists in cache. Add entry, if it doesn't exist.
- bool IsDuplicate (Ipv4Address addr, uint32_t id);
- /// Remove all expired entries
- void Purge ();
- /// Return number of entries in cache
- uint32_t GetSize ();
- /// Set lifetime for future added entries.
- void SetLifetime (Time lifetime) { m_lifetime = lifetime; }
- /// Return lifetime for existing entries in cache
- Time GetLifeTime () const { return m_lifetime; }
-private:
- /// Unique packet ID
- struct UniqueId
- {
- /// ID is supposed to be unique in single address context (e.g. sender address)
- Ipv4Address m_context;
- /// The id
- uint32_t m_id;
- /// When record will expire
- Time m_expire;
- };
- struct IsExpired
- {
- bool operator() (const struct UniqueId & u) const
- {
- return (u.m_expire < Simulator::Now ());
- }
- };
- /// Already seen IDs
- std::vector<UniqueId> m_idCache;
- /// Default lifetime for ID records
- Time m_lifetime;
-};
-
-}
-}
-#endif /* IDCACHE_H_ */
--- a/src/routing/aodv/aodv-neighbor.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#include "aodv-neighbor.h"
-#include "ns3/log.h"
-#include <algorithm>
-
-NS_LOG_COMPONENT_DEFINE ("AodvNeighbors");
-
-namespace ns3
-{
-namespace aodv
-{
-Neighbors::Neighbors (Time delay) :
- m_ntimer (Timer::CANCEL_ON_DESTROY)
-{
- m_ntimer.SetDelay(delay);
- m_ntimer.SetFunction(&Neighbors::Purge, this);
- m_txErrorCallback = MakeCallback (& Neighbors::ProcessTxError, this);
-}
-
-bool
-Neighbors::IsNeighbor (Ipv4Address addr)
-{
- Purge ();
- for (std::vector<Neighbor>::const_iterator i = m_nb.begin ();
- i != m_nb.end (); ++i)
- {
- if (i->m_neighborAddress == addr)
- return true;
- }
- return false;
-}
-
-Time
-Neighbors::GetExpireTime (Ipv4Address addr)
-{
- Purge ();
- for (std::vector<Neighbor>::const_iterator i = m_nb.begin (); i
- != m_nb.end (); ++i)
- {
- if (i->m_neighborAddress == addr)
- return (i->m_expireTime - Simulator::Now ());
- }
- return Seconds (0);
-}
-
-void
-Neighbors::Update (Ipv4Address addr, Time expire)
-{
- for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
- if (i->m_neighborAddress == addr)
- {
- i->m_expireTime
- = std::max (expire + Simulator::Now (), i->m_expireTime);
- if (i->m_hardwareAddress == Mac48Address ())
- i->m_hardwareAddress = LookupMacAddress (i->m_neighborAddress);
- return;
- }
-
- NS_LOG_LOGIC ("Open link to " << addr);
- Neighbor neighbor (addr, LookupMacAddress (addr), expire + Simulator::Now ());
- m_nb.push_back (neighbor);
- Purge ();
-}
-
-struct CloseNeighbor
-{
- bool operator() (const Neighbors::Neighbor & nb) const
- {
- return ((nb.m_expireTime < Simulator::Now ()) || nb.close);
- }
-};
-
-void
-Neighbors::Purge ()
-{
- if (m_nb.empty ())
- return;
-
- CloseNeighbor pred;
- if (!m_handleLinkFailure.IsNull ())
- {
- for (std::vector<Neighbor>::iterator j = m_nb.begin (); j != m_nb.end (); ++j)
- {
- if (pred (*j))
- {
- NS_LOG_LOGIC ("Close link to " << j->m_neighborAddress);
- m_handleLinkFailure (j->m_neighborAddress);
- }
- }
- }
- m_nb.erase (std::remove_if (m_nb.begin (), m_nb.end (), pred), m_nb.end ());
- m_ntimer.Cancel ();
- m_ntimer.Schedule ();
-}
-
-void
-Neighbors::ScheduleTimer ()
-{
- m_ntimer.Cancel ();
- m_ntimer.Schedule ();
-}
-
-void
-Neighbors::AddArpCache (Ptr<ArpCache> a)
-{
- m_arp.push_back (a);
-}
-
-void
-Neighbors::DelArpCache (Ptr<ArpCache> a)
-{
- m_arp.erase (std::remove (m_arp.begin (), m_arp.end (), a), m_arp.end ());
-}
-
-Mac48Address
-Neighbors::LookupMacAddress (Ipv4Address addr)
-{
- Mac48Address hwaddr;
- for (std::vector<Ptr<ArpCache> >::const_iterator i = m_arp.begin ();
- i != m_arp.end (); ++i)
- {
- ArpCache::Entry * entry = (*i)->Lookup (addr);
- if (entry != 0 && entry->IsAlive () && !entry->IsExpired ())
- {
- hwaddr = Mac48Address::ConvertFrom (entry->GetMacAddress ());
- break;
- }
- }
- return hwaddr;
-}
-
-void
-Neighbors::ProcessTxError (WifiMacHeader const & hdr)
-{
- Mac48Address addr = hdr.GetAddr1 ();
-
- for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
- {
- if (i->m_hardwareAddress == addr)
- i->close = true;
- }
- Purge ();
-}
-}
-}
-
--- a/src/routing/aodv/aodv-neighbor.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#ifndef AODVNEIGHBOR_H
-#define AODVNEIGHBOR_H
-
-#include "ns3/simulator.h"
-#include "ns3/timer.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/callback.h"
-#include "ns3/wifi-mac-header.h"
-#include "ns3/arp-cache.h"
-#include <vector>
-
-namespace ns3
-{
-namespace aodv
-{
-class RoutingProtocol;
-/**
- * \ingroup aodv
- * \brief maintain list of active neighbors
- */
-class Neighbors
-{
-public:
- /// c-tor
- Neighbors (Time delay);
- /// Neighbor description
- struct Neighbor
- {
- Ipv4Address m_neighborAddress;
- Mac48Address m_hardwareAddress;
- Time m_expireTime;
- bool close;
-
- Neighbor (Ipv4Address ip, Mac48Address mac, Time t) :
- m_neighborAddress (ip), m_hardwareAddress (mac), m_expireTime (t),
- close (false)
- {
- }
- };
- /// Return expire time for neighbor node with address addr, if exists, else return 0.
- Time GetExpireTime (Ipv4Address addr);
- /// Check that node with address addr is neighbor
- bool IsNeighbor (Ipv4Address addr);
- /// Update expire time for entry with address addr, if it exists, else add new entry
- void Update (Ipv4Address addr, Time expire);
- /// Remove all expired entries
- void Purge ();
- /// Schedule m_ntimer.
- void ScheduleTimer ();
- /// Remove all entries
- void Clear () { m_nb.clear (); }
-
- /// Add ARP cache to be used to allow layer 2 notifications processing
- void AddArpCache (Ptr<ArpCache>);
- /// Don't use given ARP cache any more (interface is down)
- void DelArpCache (Ptr<ArpCache>);
- /// Get callback to ProcessTxError
- Callback<void, WifiMacHeader const &> GetTxErrorCallback () const { return m_txErrorCallback; }
-
- ///\name Handle link failure callback
- //\{
- void SetCallback (Callback<void, Ipv4Address> cb) { m_handleLinkFailure = cb;}
- Callback<void, Ipv4Address> GetCallback () const { return m_handleLinkFailure; }
- //\}
-private:
- /// link failure callback
- Callback<void, Ipv4Address> m_handleLinkFailure;
- /// TX error callback
- Callback<void, WifiMacHeader const &> m_txErrorCallback;
- /// Timer for neighbor's list. Schedule Purge().
- Timer m_ntimer;
- /// vector of entries
- std::vector<Neighbor> m_nb;
- /// list of ARP cached to be used for layer 2 notifications processing
- std::vector<Ptr<ArpCache> > m_arp;
-
- /// Find MAC address by IP using list of ARP caches
- Mac48Address LookupMacAddress (Ipv4Address);
- /// Process layer 2 TX error notification
- void ProcessTxError (WifiMacHeader const &);
-};
-
-}
-}
-
-#endif /* AODVNEIGHBOR_H */
--- a/src/routing/aodv/aodv-packet.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,638 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#include "aodv-packet.h"
-#include "ns3/address-utils.h"
-#include "ns3/packet.h"
-
-namespace ns3
-{
-namespace aodv
-{
-
-NS_OBJECT_ENSURE_REGISTERED (TypeHeader);
-
-TypeHeader::TypeHeader (MessageType t = AODVTYPE_RREQ) :
- m_type (t), m_valid (true)
-{
-}
-
-TypeId
-TypeHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::aodv::TypeHeader")
- .SetParent<Header> ()
- .AddConstructor<TypeHeader> ()
- ;
- return tid;
-}
-
-TypeId
-TypeHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-uint32_t
-TypeHeader::GetSerializedSize () const
-{
- return 1;
-}
-
-void
-TypeHeader::Serialize (Buffer::Iterator i) const
-{
- i.WriteU8 ((uint8_t) m_type);
-}
-
-uint32_t
-TypeHeader::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
- uint8_t type = i.ReadU8 ();
- m_valid = true;
- switch (type)
- {
- case AODVTYPE_RREQ:
- case AODVTYPE_RREP:
- case AODVTYPE_RERR:
- case AODVTYPE_RREP_ACK:
- {
- m_type = (MessageType) type;
- break;
- }
- default:
- m_valid = false;
- }
- uint32_t dist = i.GetDistanceFrom (start);
- NS_ASSERT (dist == GetSerializedSize ());
- return dist;
-}
-
-void
-TypeHeader::Print (std::ostream &os) const
-{
- switch (m_type)
- {
- case AODVTYPE_RREQ:
- {
- os << "RREQ";
- break;
- }
- case AODVTYPE_RREP:
- {
- os << "RREP";
- break;
- }
- case AODVTYPE_RERR:
- {
- os << "RERR";
- break;
- }
- case AODVTYPE_RREP_ACK:
- {
- os << "RREP_ACK";
- break;
- }
- default:
- os << "UNKNOWN_TYPE";
- }
-}
-
-bool
-TypeHeader::operator== (TypeHeader const & o) const
-{
- return (m_type == o.m_type && m_valid == o.m_valid);
-}
-
-std::ostream &
-operator<< (std::ostream & os, TypeHeader const & h)
-{
- h.Print (os);
- return os;
-}
-
-//-----------------------------------------------------------------------------
-// RREQ
-//-----------------------------------------------------------------------------
-RreqHeader::RreqHeader (uint8_t flags, uint8_t reserved, uint8_t hopCount, uint32_t requestID, Ipv4Address dst,
- uint32_t dstSeqNo, Ipv4Address origin, uint32_t originSeqNo) :
- m_flags (flags), m_reserved (reserved), m_hopCount (hopCount), m_requestID (requestID), m_dst(dst),
- m_dstSeqNo (dstSeqNo), m_origin(origin), m_originSeqNo (originSeqNo)
-{
-}
-
-NS_OBJECT_ENSURE_REGISTERED (RreqHeader);
-
-TypeId
-RreqHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::aodv::RreqHeader")
- .SetParent<Header> ()
- .AddConstructor<RreqHeader> ()
- ;
- return tid;
-}
-
-TypeId
-RreqHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-uint32_t
-RreqHeader::GetSerializedSize () const
-{
- return 23;
-}
-
-void
-RreqHeader::Serialize (Buffer::Iterator i) const
-{
- i.WriteU8 (m_flags);
- i.WriteU8 (m_reserved);
- i.WriteU8 (m_hopCount);
- i.WriteHtonU32 (m_requestID);
- WriteTo (i, m_dst);
- i.WriteHtonU32 (m_dstSeqNo);
- WriteTo (i, m_origin);
- i.WriteHtonU32 (m_originSeqNo);
-}
-
-uint32_t
-RreqHeader::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
- m_flags = i.ReadU8 ();
- m_reserved = i.ReadU8 ();
- m_hopCount = i.ReadU8 ();
- m_requestID = i.ReadNtohU32 ();
- ReadFrom (i, m_dst);
- m_dstSeqNo = i.ReadNtohU32 ();
- ReadFrom (i, m_origin);
- m_originSeqNo = i.ReadNtohU32 ();
-
- uint32_t dist = i.GetDistanceFrom (start);
- NS_ASSERT (dist == GetSerializedSize ());
- return dist;
-}
-
-void
-RreqHeader::Print (std::ostream &os) const
-{
- os << "RREQ ID " << m_requestID << " destination: ipv4 " << m_dst
- << " sequence number " << m_dstSeqNo << " source: ipv4 "
- << m_origin << " sequence number " << m_originSeqNo
- << " flags:" << " Gratuitous RREP " << (*this).GetGratiousRrep ()
- << " Destination only " << (*this).GetDestinationOnly ()
- << " Unknown sequence number " << (*this).GetUnknownSeqno ();
-}
-
-std::ostream &
-operator<< (std::ostream & os, RreqHeader const & h)
-{
- h.Print (os);
- return os;
-}
-
-void
-RreqHeader::SetGratiousRrep (bool f)
-{
- if (f)
- m_flags |= (1 << 5);
- else
- m_flags &= ~(1 << 5);
-}
-
-bool
-RreqHeader::GetGratiousRrep () const
-{
- return (m_flags & (1 << 5));
-}
-
-void
-RreqHeader::SetDestinationOnly (bool f)
-{
- if (f)
- m_flags |= (1 << 4);
- else
- m_flags &= ~(1 << 4);
-}
-
-bool
-RreqHeader::GetDestinationOnly () const
-{
- return (m_flags & (1 << 4));
-}
-
-void
-RreqHeader::SetUnknownSeqno (bool f)
-{
- if (f)
- m_flags |= (1 << 3);
- else
- m_flags &= ~(1 << 3);
-}
-
-bool
-RreqHeader::GetUnknownSeqno () const
-{
- return (m_flags & (1 << 3));
-}
-
-bool
-RreqHeader::operator== (RreqHeader const & o) const
-{
- return (m_flags == o.m_flags && m_reserved == o.m_reserved &&
- m_hopCount == o.m_hopCount && m_requestID == o.m_requestID &&
- m_dst == o.m_dst && m_dstSeqNo == o.m_dstSeqNo &&
- m_origin == o.m_origin && m_originSeqNo == o.m_originSeqNo);
-}
-
-//-----------------------------------------------------------------------------
-// RREP
-//-----------------------------------------------------------------------------
-
-RrepHeader::RrepHeader (uint8_t prefixSize, uint8_t hopCount, Ipv4Address dst,
- uint32_t dstSeqNo, Ipv4Address origin, Time lifeTime) :
- m_flags (0), m_prefixSize (prefixSize), m_hopCount (hopCount),
- m_dst (dst), m_dstSeqNo (dstSeqNo), m_origin (origin)
-{
- m_lifeTime = uint32_t (lifeTime.GetMilliSeconds ());
-}
-
-NS_OBJECT_ENSURE_REGISTERED (RrepHeader);
-
-TypeId
-RrepHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::aodv::RrepHeader")
- .SetParent<Header> ()
- .AddConstructor<RrepHeader> ()
- ;
- return tid;
-}
-
-TypeId
-RrepHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-uint32_t
-RrepHeader::GetSerializedSize () const
-{
- return 19;
-}
-
-void
-RrepHeader::Serialize (Buffer::Iterator i) const
-{
- i.WriteU8 (m_flags);
- i.WriteU8 (m_prefixSize);
- i.WriteU8 (m_hopCount);
- WriteTo (i, m_dst);
- i.WriteHtonU32 (m_dstSeqNo);
- WriteTo (i, m_origin);
- i.WriteHtonU32 (m_lifeTime);
-}
-
-uint32_t
-RrepHeader::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
-
- m_flags = i.ReadU8 ();
- m_prefixSize = i.ReadU8 ();
- m_hopCount = i.ReadU8 ();
- ReadFrom (i, m_dst);
- m_dstSeqNo = i.ReadNtohU32 ();
- ReadFrom (i, m_origin);
- m_lifeTime = i.ReadNtohU32 ();
-
- uint32_t dist = i.GetDistanceFrom (start);
- NS_ASSERT (dist == GetSerializedSize ());
- return dist;
-}
-
-void
-RrepHeader::Print (std::ostream &os) const
-{
- os << "destination: ipv4 " << m_dst << " sequence number " << m_dstSeqNo;
- if (m_prefixSize != 0)
- {
- os << " prefix size " << m_prefixSize;
- }
- os << " source ipv4 " << m_origin << " lifetime " << m_lifeTime
- << " acknowledgment required flag " << (*this).GetAckRequired ();
-}
-
-void
-RrepHeader::SetLifeTime (Time t)
-{
- m_lifeTime = t.GetMilliSeconds ();
-}
-
-Time
-RrepHeader::GetLifeTime () const
-{
- Time t (MilliSeconds (m_lifeTime));
- return t;
-}
-
-void
-RrepHeader::SetAckRequired (bool f)
-{
- if (f)
- m_flags |= (1 << 6);
- else
- m_flags &= ~(1 << 6);
-}
-
-bool
-RrepHeader::GetAckRequired () const
-{
- return (m_flags & (1 << 6));
-}
-
-void
-RrepHeader::SetPrefixSize (uint8_t sz)
-{
- m_prefixSize = sz;
-}
-
-uint8_t
-RrepHeader::GetPrefixSize () const
-{
- return m_prefixSize;
-}
-
-bool
-RrepHeader::operator== (RrepHeader const & o) const
-{
- return (m_flags == o.m_flags && m_prefixSize == o.m_prefixSize &&
- m_hopCount == o.m_hopCount && m_dst == o.m_dst && m_dstSeqNo == o.m_dstSeqNo &&
- m_origin == o.m_origin && m_lifeTime == o.m_lifeTime);
-}
-
-void
-RrepHeader::SetHello (Ipv4Address origin, uint32_t srcSeqNo, Time lifetime)
-{
- m_flags = 0;
- m_prefixSize = 0;
- m_hopCount = 0;
- m_dst = origin;
- m_dstSeqNo = srcSeqNo;
- m_origin = origin;
- m_lifeTime = lifetime.GetMilliSeconds ();
-}
-
-std::ostream &
-operator<< (std::ostream & os, RrepHeader const & h)
-{
- h.Print (os);
- return os;
-}
-
-//-----------------------------------------------------------------------------
-// RREP-ACK
-//-----------------------------------------------------------------------------
-
-RrepAckHeader::RrepAckHeader () :
- m_reserved (0)
-{
-}
-
-NS_OBJECT_ENSURE_REGISTERED (RrepAckHeader);
-TypeId
-RrepAckHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::aodv::RrepAckHeader")
- .SetParent<Header> ()
- .AddConstructor<RrepAckHeader> ()
- ;
- return tid;
-}
-
-TypeId
-RrepAckHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-uint32_t
-RrepAckHeader::GetSerializedSize () const
-{
- return 1;
-}
-
-void
-RrepAckHeader::Serialize (Buffer::Iterator i ) const
-{
- i.WriteU8 (m_reserved);
-}
-
-uint32_t
-RrepAckHeader::Deserialize (Buffer::Iterator start )
-{
- Buffer::Iterator i = start;
- m_reserved = i.ReadU8 ();
- uint32_t dist = i.GetDistanceFrom (start);
- NS_ASSERT (dist == GetSerializedSize ());
- return dist;
-}
-
-void
-RrepAckHeader::Print (std::ostream &os ) const
-{
-}
-
-bool
-RrepAckHeader::operator== (RrepAckHeader const & o ) const
-{
- return m_reserved == o.m_reserved;
-}
-
-std::ostream &
-operator<< (std::ostream & os, RrepAckHeader const & h )
-{
- h.Print (os);
- return os;
-}
-
-//-----------------------------------------------------------------------------
-// RERR
-//-----------------------------------------------------------------------------
-RerrHeader::RerrHeader () :
- m_flag (0), m_reserved (0)
-{
-}
-
-NS_OBJECT_ENSURE_REGISTERED (RerrHeader);
-
-TypeId
-RerrHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::aodv::RerrHeader")
- .SetParent<Header> ()
- .AddConstructor<RerrHeader> ()
- ;
- return tid;
-}
-
-TypeId
-RerrHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-uint32_t
-RerrHeader::GetSerializedSize () const
-{
- return (3 + 8 * GetDestCount ());
-}
-
-void
-RerrHeader::Serialize (Buffer::Iterator i ) const
-{
- i.WriteU8 (m_flag);
- i.WriteU8 (m_reserved);
- i.WriteU8 (GetDestCount ());
- std::map<Ipv4Address, uint32_t>::const_iterator j;
- for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
- {
- WriteTo (i, (*j).first);
- i.WriteHtonU32 ((*j).second);
- }
-}
-
-uint32_t
-RerrHeader::Deserialize (Buffer::Iterator start )
-{
- Buffer::Iterator i = start;
- m_flag = i.ReadU8 ();
- m_reserved = i.ReadU8 ();
- uint8_t dest = i.ReadU8 ();
- m_unreachableDstSeqNo.clear ();
- Ipv4Address address;
- uint32_t seqNo;
- for (uint8_t k = 0; k < dest; ++k)
- {
- ReadFrom (i, address);
- seqNo = i.ReadNtohU32 ();
- m_unreachableDstSeqNo.insert (std::make_pair (address, seqNo));
- }
-
- uint32_t dist = i.GetDistanceFrom (start);
- NS_ASSERT (dist == GetSerializedSize ());
- return dist;
-}
-
-void
-RerrHeader::Print (std::ostream &os ) const
-{
- os << "Unreachable destination (ipv4 address, seq. number):";
- std::map<Ipv4Address, uint32_t>::const_iterator j;
- for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
- {
- os << (*j).first << ", " << (*j).second;
- }
- os << "No delete flag " << (*this).GetNoDelete ();
-}
-
-void
-RerrHeader::SetNoDelete (bool f )
-{
- if (f)
- m_flag |= (1 << 0);
- else
- m_flag &= ~(1 << 0);
-}
-
-bool
-RerrHeader::GetNoDelete () const
-{
- return (m_flag & (1 << 0));
-}
-
-bool
-RerrHeader::AddUnDestination (Ipv4Address dst, uint32_t seqNo )
-{
- if (m_unreachableDstSeqNo.find (dst) != m_unreachableDstSeqNo.end ())
- return true;
-
- NS_ASSERT (GetDestCount() < 255); // can't support more than 255 destinations in single RERR
- m_unreachableDstSeqNo.insert (std::make_pair (dst, seqNo));
- return true;
-}
-
-bool
-RerrHeader::RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un )
-{
- if (m_unreachableDstSeqNo.empty ())
- return false;
- std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.begin ();
- un = *i;
- m_unreachableDstSeqNo.erase (i);
- return true;
-}
-
-void
-RerrHeader::Clear ()
-{
- m_unreachableDstSeqNo.clear ();
- m_flag = 0;
- m_reserved = 0;
-}
-
-bool
-RerrHeader::operator== (RerrHeader const & o ) const
-{
- if (m_flag != o.m_flag || m_reserved != o.m_reserved || GetDestCount () != o.GetDestCount ())
- return false;
-
- std::map<Ipv4Address, uint32_t>::const_iterator j = m_unreachableDstSeqNo.begin ();
- std::map<Ipv4Address, uint32_t>::const_iterator k = o.m_unreachableDstSeqNo.begin ();
- for (uint8_t i = 0; i < GetDestCount (); ++i)
- {
- if ((j->first != k->first) || (j->second != k->second))
- return false;
-
- j++;
- k++;
- }
- return true;
-}
-
-std::ostream &
-operator<< (std::ostream & os, RerrHeader const & h )
-{
- h.Print (os);
- return os;
-}
-}
-}
--- a/src/routing/aodv/aodv-packet.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#ifndef AODVPACKET_H
-#define AODVPACKET_H
-
-#include <iostream>
-#include "ns3/header.h"
-#include "ns3/enum.h"
-#include "ns3/ipv4-address.h"
-#include <map>
-#include "ns3/nstime.h"
-
-namespace ns3 {
-namespace aodv {
-
-enum MessageType
-{
- AODVTYPE_RREQ = 1, //!< AODVTYPE_RREQ
- AODVTYPE_RREP = 2, //!< AODVTYPE_RREP
- AODVTYPE_RERR = 3, //!< AODVTYPE_RERR
- AODVTYPE_RREP_ACK = 4 //!< AODVTYPE_RREP_ACK
-};
-
-/**
-* \ingroup aodv
-* \brief AODV types
-*/
-class TypeHeader : public Header
-{
-public:
- /// c-tor
- TypeHeader (MessageType t);
-
- ///\name Header serialization/deserialization
- //\{
- static TypeId GetTypeId ();
- TypeId GetInstanceTypeId () const;
- uint32_t GetSerializedSize () const;
- void Serialize (Buffer::Iterator start) const;
- uint32_t Deserialize (Buffer::Iterator start);
- void Print (std::ostream &os) const;
- //\}
-
- /// Return type
- MessageType Get () const { return m_type; }
- /// Check that type if valid
- bool IsValid () const { return m_valid; }
- bool operator== (TypeHeader const & o) const;
-private:
- MessageType m_type;
- bool m_valid;
-};
-
-std::ostream & operator<< (std::ostream & os, TypeHeader const & h);
-
-/**
-* \ingroup aodv
-* \brief Route Request (RREQ) Message Format
- \verbatim
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type |J|R|G|D|U| Reserved | Hop Count |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | RREQ ID |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination IP Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination Sequence Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Originator IP Address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Originator Sequence Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- \endverbatim
-*/
-class RreqHeader : public Header
-{
-public:
- /// c-tor
- RreqHeader (uint8_t flags = 0, uint8_t reserved = 0, uint8_t hopCount = 0,
- uint32_t requestID = 0, Ipv4Address dst = Ipv4Address (),
- uint32_t dstSeqNo = 0, Ipv4Address origin = Ipv4Address (),
- uint32_t originSeqNo = 0);
-
- ///\name Header serialization/deserialization
- //\{
- static TypeId GetTypeId ();
- TypeId GetInstanceTypeId () const;
- uint32_t GetSerializedSize () const;
- void Serialize (Buffer::Iterator start) const;
- uint32_t Deserialize (Buffer::Iterator start);
- void Print (std::ostream &os) const;
- //\}
-
- ///\name Fields
- //\{
- void SetHopCount (uint8_t count) { m_hopCount = count; }
- uint8_t GetHopCount () const { return m_hopCount; }
- void SetId (uint32_t id) { m_requestID = id; }
- uint32_t GetId () const { return m_requestID; }
- void SetDst (Ipv4Address a) { m_dst = a; }
- Ipv4Address GetDst () const { return m_dst; }
- void SetDstSeqno (uint32_t s) { m_dstSeqNo = s; }
- uint32_t GetDstSeqno () const { return m_dstSeqNo; }
- void SetOrigin (Ipv4Address a) { m_origin = a; }
- Ipv4Address GetOrigin () const { return m_origin; }
- void SetOriginSeqno (uint32_t s) { m_originSeqNo = s; }
- uint32_t GetOriginSeqno () const { return m_originSeqNo; }
- //\}
-
- ///\name Flags
- //\{
- void SetGratiousRrep (bool f);
- bool GetGratiousRrep () const;
- void SetDestinationOnly (bool f);
- bool GetDestinationOnly () const;
- void SetUnknownSeqno (bool f);
- bool GetUnknownSeqno () const;
- //\}
-
- bool operator== (RreqHeader const & o) const;
-private:
- uint8_t m_flags; ///< |J|R|G|D|U| bit flags, see RFC
- uint8_t m_reserved; ///< Not used
- uint8_t m_hopCount; ///< Hop Count
- uint32_t m_requestID; ///< RREQ ID
- Ipv4Address m_dst; ///< Destination IP Address
- uint32_t m_dstSeqNo; ///< Destination Sequence Number
- Ipv4Address m_origin; ///< Originator IP Address
- uint32_t m_originSeqNo; ///< Source Sequence Number
-};
-
-std::ostream & operator<< (std::ostream & os, RreqHeader const &);
-
-/**
-* \ingroup aodv
-* \brief Route Reply (RREP) Message Format
- \verbatim
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type |R|A| Reserved |Prefix Sz| Hop Count |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination IP address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Destination Sequence Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Originator IP address |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Lifetime |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- \endverbatim
-*/
-class RrepHeader : public Header
-{
-public:
- /// c-tor
- RrepHeader (uint8_t prefixSize = 0, uint8_t hopCount = 0, Ipv4Address dst =
- Ipv4Address (), uint32_t dstSeqNo = 0, Ipv4Address origin =
- Ipv4Address (), Time lifetime = MilliSeconds (0));
- ///\name Header serialization/deserialization
- //\{
- static TypeId GetTypeId ();
- TypeId GetInstanceTypeId () const;
- uint32_t GetSerializedSize () const;
- void Serialize (Buffer::Iterator start) const;
- uint32_t Deserialize (Buffer::Iterator start);
- void Print (std::ostream &os) const;
- //\}
-
- ///\name Fields
- //\{
- void SetHopCount (uint8_t count) { m_hopCount = count; }
- uint8_t GetHopCount () const { return m_hopCount; }
- void SetDst (Ipv4Address a) { m_dst = a; }
- Ipv4Address GetDst () const { return m_dst; }
- void SetDstSeqno (uint32_t s) { m_dstSeqNo = s; }
- uint32_t GetDstSeqno () const { return m_dstSeqNo; }
- void SetOrigin (Ipv4Address a) { m_origin = a; }
- Ipv4Address GetOrigin () const { return m_origin; }
- void SetLifeTime (Time t);
- Time GetLifeTime () const;
- //\}
-
- ///\name Flags
- //\{
- void SetAckRequired (bool f);
- bool GetAckRequired () const;
- void SetPrefixSize (uint8_t sz);
- uint8_t GetPrefixSize () const;
- //\}
-
- /// Configure RREP to be a Hello message
- void SetHello (Ipv4Address src, uint32_t srcSeqNo, Time lifetime);
-
- bool operator== (RrepHeader const & o) const;
-private:
- uint8_t m_flags; ///< A - acknowledgment required flag
- uint8_t m_prefixSize; ///< Prefix Size
- uint8_t m_hopCount; ///< Hop Count
- Ipv4Address m_dst; ///< Destination IP Address
- uint32_t m_dstSeqNo; ///< Destination Sequence Number
- Ipv4Address m_origin; ///< Source IP Address
- uint32_t m_lifeTime; ///< Lifetime (in milliseconds)
-};
-
-std::ostream & operator<< (std::ostream & os, RrepHeader const &);
-
-/**
-* \ingroup aodv
-* \brief Route Reply Acknowledgment (RREP-ACK) Message Format
- \verbatim
- 0 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Reserved |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- \endverbatim
-*/
-class RrepAckHeader : public Header
-{
-public:
- /// c-tor
- RrepAckHeader ();
-
- ///\name Header serialization/deserialization
- //\{
- static TypeId GetTypeId ();
- TypeId GetInstanceTypeId () const;
- uint32_t GetSerializedSize () const;
- void Serialize (Buffer::Iterator start) const;
- uint32_t Deserialize (Buffer::Iterator start);
- void Print (std::ostream &os) const;
- //\}
-
- bool operator== (RrepAckHeader const & o) const;
-private:
- uint8_t m_reserved;
-};
-std::ostream & operator<< (std::ostream & os, RrepAckHeader const &);
-
-
-/**
-* \ingroup aodv
-* \brief Route Error (RERR) Message Format
- \verbatim
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type |N| Reserved | DestCount |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Unreachable Destination IP Address (1) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Unreachable Destination Sequence Number (1) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
- | Additional Unreachable Destination IP Addresses (if needed) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |Additional Unreachable Destination Sequence Numbers (if needed)|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- \endverbatim
-*/
-class RerrHeader : public Header
-{
-public:
- /// c-tor
- RerrHeader ();
-
- ///\name Header serialization/deserialization
- //\{
- static TypeId GetTypeId ();
- TypeId GetInstanceTypeId () const;
- uint32_t GetSerializedSize () const;
- void Serialize (Buffer::Iterator i) const;
- uint32_t Deserialize (Buffer::Iterator start);
- void Print (std::ostream &os) const;
- //\}
-
- ///\name No delete flag
- //\{
- void SetNoDelete (bool f);
- bool GetNoDelete () const;
- //\}
-
- /**
- * Add unreachable node address and its sequence number in RERR header
- *\return false if we already added maximum possible number of unreachable destinations
- */
- bool AddUnDestination (Ipv4Address dst, uint32_t seqNo);
- /** Delete pair (address + sequence number) from REER header, if the number of unreachable destinations > 0
- * \return true on success
- */
- bool RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un);
- /// Clear header
- void Clear();
- /// Return number of unreachable destinations in RERR message
- uint8_t GetDestCount () const { return (uint8_t)m_unreachableDstSeqNo.size(); }
- bool operator== (RerrHeader const & o) const;
-private:
- uint8_t m_flag; ///< No delete flag
- uint8_t m_reserved; ///< Not used
-
- /// List of Unreachable destination: IP addresses and sequence numbers
- std::map<Ipv4Address, uint32_t> m_unreachableDstSeqNo;
-};
-
-std::ostream & operator<< (std::ostream & os, RerrHeader const &);
-}
-}
-#endif /* AODVPACKET_H */
--- a/src/routing/aodv/aodv-routing-protocol.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1700 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#define NS_LOG_APPEND_CONTEXT \
- if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
-
-#include "aodv-routing-protocol.h"
-#include "ns3/log.h"
-#include "ns3/boolean.h"
-#include "ns3/random-variable.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/trace-source-accessor.h"
-#include "ns3/udp-socket-factory.h"
-#include "ns3/wifi-net-device.h"
-#include "ns3/adhoc-wifi-mac.h"
-#include <algorithm>
-#include <limits>
-
-NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
-
-namespace ns3
-{
-namespace aodv
-{
-NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
-
-/// UDP Port for AODV control traffic
-const uint32_t RoutingProtocol::AODV_PORT = 654;
-
-//-----------------------------------------------------------------------------
-/// Tag used by AODV implementation
-struct DeferredRouteOutputTag : public Tag
-{
- /// Positive if output device is fixed in RouteOutput
- int32_t oif;
-
- DeferredRouteOutputTag (int32_t o = -1) : Tag(), oif (o) {}
-
- static TypeId GetTypeId ()
- {
- static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag").SetParent<Tag> ();
- return tid;
- }
-
- TypeId GetInstanceTypeId () const
- {
- return GetTypeId ();
- }
-
- uint32_t GetSerializedSize () const
- {
- return sizeof(int32_t);
- }
-
- void Serialize (TagBuffer i) const
- {
- i.WriteU32 (oif);
- }
-
- void Deserialize (TagBuffer i)
- {
- oif = i.ReadU32 ();
- }
-
- void Print (std::ostream &os) const
- {
- os << "DeferredRouteOutputTag: output interface = " << oif;
- }
-};
-
-//-----------------------------------------------------------------------------
-RoutingProtocol::RoutingProtocol () :
- RreqRetries (2),
- RreqRateLimit (10),
- ActiveRouteTimeout (Seconds (3)),
- NetDiameter (35),
- NodeTraversalTime (MilliSeconds (40)),
- NetTraversalTime (Scalar (2 * NetDiameter) * NodeTraversalTime),
- PathDiscoveryTime ( Scalar (2) * NetTraversalTime),
- MyRouteTimeout (Scalar (2) * std::max (PathDiscoveryTime, ActiveRouteTimeout)),
- HelloInterval(Seconds (1)),
- AllowedHelloLoss (2),
- DeletePeriod (Scalar(5) * std::max(ActiveRouteTimeout, HelloInterval)),
- NextHopWait (NodeTraversalTime + MilliSeconds (10)),
- TimeoutBuffer (2),
- BlackListTimeout(Scalar (RreqRetries) * NetTraversalTime),
- MaxQueueLen (64),
- MaxQueueTime (Seconds(30)),
- DestinationOnly (false),
- GratuitousReply (true),
- EnableHello (true),
- m_routingTable (DeletePeriod),
- m_queue (MaxQueueLen, MaxQueueTime),
- m_requestId (0),
- m_seqNo (0),
- m_rreqIdCache (PathDiscoveryTime),
- m_dpd (PathDiscoveryTime),
- m_nb(HelloInterval),
- m_rreqCount (0),
- m_htimer (Timer::CANCEL_ON_DESTROY),
- m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY)
-{
- if (EnableHello)
- {
- m_nb.SetCallback (MakeCallback (&RoutingProtocol::SendRerrWhenBreaksLinkToNextHop, this));
- }
-}
-
-TypeId
-RoutingProtocol::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
- .SetParent<Ipv4RoutingProtocol> ()
- .AddConstructor<RoutingProtocol> ()
- .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
- TimeValue (Seconds (1)),
- MakeTimeAccessor (&RoutingProtocol::HelloInterval),
- MakeTimeChecker ())
- .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
- UintegerValue (2),
- MakeUintegerAccessor (&RoutingProtocol::RreqRetries),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
- UintegerValue (10),
- MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
- "queuing delays, interrupt processing times and transfer times.",
- TimeValue (MilliSeconds (40)),
- MakeTimeAccessor (&RoutingProtocol::NodeTraversalTime),
- MakeTimeChecker ())
- .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
- TimeValue (MilliSeconds (50)),
- MakeTimeAccessor (&RoutingProtocol::NextHopWait),
- MakeTimeChecker ())
- .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
- TimeValue (Seconds (3)),
- MakeTimeAccessor (&RoutingProtocol::ActiveRouteTimeout),
- MakeTimeChecker ())
- .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
- TimeValue (Seconds (11.2)),
- MakeTimeAccessor (&RoutingProtocol::MyRouteTimeout),
- MakeTimeChecker ())
- .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
- TimeValue (Seconds (5.6)),
- MakeTimeAccessor (&RoutingProtocol::BlackListTimeout),
- MakeTimeChecker ())
- .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
- "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
- " = 5 * max (HelloInterval, ActiveRouteTimeout)",
- TimeValue (Seconds (15)),
- MakeTimeAccessor (&RoutingProtocol::DeletePeriod),
- MakeTimeChecker ())
- .AddAttribute ("TimeoutBuffer", "Its purpose is to provide a buffer for the timeout so that if the RREP is delayed"
- " due to congestion, a timeout is less likely to occur while the RREP is still en route back to the source.",
- UintegerValue (2),
- MakeUintegerAccessor (&RoutingProtocol::TimeoutBuffer),
- MakeUintegerChecker<uint16_t> ())
- .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
- UintegerValue (35),
- MakeUintegerAccessor (&RoutingProtocol::NetDiameter),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
- TimeValue (Seconds (2.8)),
- MakeTimeAccessor (&RoutingProtocol::NetTraversalTime),
- MakeTimeChecker ())
- .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
- TimeValue (Seconds (5.6)),
- MakeTimeAccessor (&RoutingProtocol::PathDiscoveryTime),
- MakeTimeChecker ())
- .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
- UintegerValue (64),
- MakeUintegerAccessor (&RoutingProtocol::SetMaxQueueLen,
- &RoutingProtocol::GetMaxQueueLen),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
- TimeValue (Seconds (30)),
- MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
- &RoutingProtocol::GetMaxQueueTime),
- MakeTimeChecker ())
- .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
- UintegerValue (2),
- MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss),
- MakeUintegerChecker<uint16_t> ())
- .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
- BooleanValue (true),
- MakeBooleanAccessor (&RoutingProtocol::SetGratuitousReplyFlag,
- &RoutingProtocol::GetGratuitousReplyFlag),
- MakeBooleanChecker ())
- .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
- BooleanValue (false),
- MakeBooleanAccessor (&RoutingProtocol::SetDesinationOnlyFlag,
- &RoutingProtocol::GetDesinationOnlyFlag),
- MakeBooleanChecker ())
- .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
- BooleanValue (true),
- MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
- &RoutingProtocol::GetHelloEnable),
- MakeBooleanChecker ())
- .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
- BooleanValue (true),
- MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
- &RoutingProtocol::GetBroadcastEnable),
- MakeBooleanChecker ())
- ;
- return tid;
-}
-
-void
-RoutingProtocol::SetMaxQueueLen (uint32_t len)
-{
- MaxQueueLen = len;
- m_queue.SetMaxQueueLen (len);
-}
-void
-RoutingProtocol::SetMaxQueueTime (Time t)
-{
- MaxQueueTime = t;
- m_queue.SetQueueTimeout (t);
-}
-
-RoutingProtocol::~RoutingProtocol ()
-{
-}
-
-void
-RoutingProtocol::DoDispose ()
-{
- m_ipv4 = 0;
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::iterator iter =
- m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
- {
- iter->first->Close ();
- }
- m_socketAddresses.clear ();
- Ipv4RoutingProtocol::DoDispose ();
-}
-
-void
-RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
-{
- *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now().GetSeconds () << "s ";
- m_routingTable.Print (stream);
-}
-
-void
-RoutingProtocol::Start ()
-{
- NS_LOG_FUNCTION (this);
- if (EnableHello)
- {
- m_nb.ScheduleTimer ();
- }
- m_rreqRateLimitTimer.SetFunction (&RoutingProtocol::RreqRateLimitTimerExpire,
- this);
- m_rreqRateLimitTimer.Schedule (Seconds (1));
-}
-
-Ptr<Ipv4Route>
-RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
- Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
- NS_LOG_FUNCTION (this << header << (oif? oif->GetIfIndex () : 0));
- if (! p)
- {
- return LoopbackRoute (header, oif); // later
- }
- if (m_socketAddresses.empty ())
- {
- sockerr = Socket::ERROR_NOROUTETOHOST;
- NS_LOG_LOGIC ("No aodv interfaces");
- Ptr<Ipv4Route> route;
- return route;
- }
- sockerr = Socket::ERROR_NOTERROR;
- Ptr<Ipv4Route> route;
- Ipv4Address dst = header.GetDestination ();
- RoutingTableEntry rt;
- if (m_routingTable.LookupValidRoute (dst, rt))
- {
- route = rt.GetRoute ();
- NS_ASSERT (route != 0);
- NS_LOG_DEBUG ("Exist route to " << route->GetDestination() << " from interface " << route->GetSource());
- if (oif != 0 && route->GetOutputDevice () != oif)
- {
- NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
- sockerr = Socket::ERROR_NOROUTETOHOST;
- return Ptr<Ipv4Route> ();
- }
- UpdateRouteLifeTime (dst, ActiveRouteTimeout);
- UpdateRouteLifeTime (route->GetGateway (), ActiveRouteTimeout);
- return route;
- }
-
- // Valid route not found, in this case we return loopback.
- // Actual route request will be deferred until packet will be fully formed,
- // routed to loopback, received from loopback and passed to RouteInput (see below)
- uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
- DeferredRouteOutputTag tag (iif);
- if (! p->PeekPacketTag (tag))
- {
- p->AddPacketTag (tag);
- }
- return LoopbackRoute (header, oif);
-}
-
-void
-RoutingProtocol::DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header & header,
- UnicastForwardCallback ucb, ErrorCallback ecb)
-{
- NS_LOG_FUNCTION (this << p << header);
- NS_ASSERT (p != 0 && p != Ptr<Packet> ());
-
- QueueEntry newEntry (p, header, ucb, ecb);
- bool result = m_queue.Enqueue (newEntry);
- if (result)
- {
- NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
- RoutingTableEntry rt;
- bool result = m_routingTable.LookupRoute(header.GetDestination (), rt);
- if(!result || ((rt.GetFlag() != IN_SEARCH) && result))
- {
- NS_LOG_LOGIC ("Send RREQ to" <<header.GetDestination ());
- SendRequest (header.GetDestination ());
- }
- }
-}
-
-bool
-RoutingProtocol::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->GetUid() << header.GetDestination() << idev->GetAddress());
- if (m_socketAddresses.empty ())
- {
- NS_LOG_LOGIC ("No aodv interfaces");
- return false;
- }
- NS_ASSERT (m_ipv4 != 0);
- NS_ASSERT (p != 0);
- // Check if input device supports IP
- NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
- int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
-
- Ipv4Address dst = header.GetDestination ();
- Ipv4Address origin = header.GetSource ();
-
- // Deferred route request
- if (idev == m_lo)
- {
- DeferredRouteOutputTag tag;
- if (p->PeekPacketTag (tag))
- {
- DeferredRouteOutput (p, header, ucb, ecb);
- return true;
- }
- }
-
- // Duplicate of own packet
- if (IsMyOwnAddress (origin))
- return true;
-
- // Broadcast local delivery/forwarding
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
- m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ipv4InterfaceAddress iface = j->second;
- if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
- if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
- {
- if (m_dpd.IsDuplicate (p, header))
- {
- NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
- return true;
- }
- UpdateRouteLifeTime (origin, ActiveRouteTimeout);
- NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
- Ptr<Packet> packet = p->Copy ();
- lcb (p, header, iif);
- if (!EnableBroadcast)
- {
- return true;
- }
- if (header.GetTtl () > 1)
- {
- NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
- RoutingTableEntry toBroadcast;
- if (m_routingTable.LookupRoute (dst, toBroadcast))
- {
- Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
- ucb (route, packet, header);
- }
- else
- {
- NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
- }
- }
- else
- {
- NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
- }
- return true;
- }
- }
-
- // Unicast local delivery
- if (m_ipv4->IsDestinationAddress (dst, iif))
- {
- UpdateRouteLifeTime (origin, ActiveRouteTimeout);
- RoutingTableEntry toOrigin;
- if (m_routingTable.LookupValidRoute (origin, toOrigin))
- {
- UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
- m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
- }
- NS_LOG_LOGIC ("Unicast local delivery to " << dst);
- lcb (p, header, iif);
- return true;
- }
-
- // Forwarding
- return Forwarding (p, header, ucb, ecb);
-}
-
-bool
-RoutingProtocol::Forwarding (Ptr<const Packet> p, const Ipv4Header & header,
- UnicastForwardCallback ucb, ErrorCallback ecb)
-{
- NS_LOG_FUNCTION (this);
- Ipv4Address dst = header.GetDestination ();
- Ipv4Address origin = header.GetSource ();
- m_routingTable.Purge ();
- RoutingTableEntry toDst;
- if (m_routingTable.LookupRoute (dst, toDst))
- {
- if (toDst.GetFlag () == VALID)
- {
- Ptr<Ipv4Route> route = toDst.GetRoute ();
- NS_LOG_LOGIC (route->GetSource()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
-
- /*
- * Each time a route is used to forward a data packet, its Active Route
- * Lifetime field of the source, destination and the next hop on the
- * path to the destination is updated to be no less than the current
- * time plus ActiveRouteTimeout.
- */
- UpdateRouteLifeTime (origin, ActiveRouteTimeout);
- UpdateRouteLifeTime (dst, ActiveRouteTimeout);
- UpdateRouteLifeTime (route->GetGateway (), ActiveRouteTimeout);
- /*
- * Since the route between each originator and destination pair is expected to be symmetric, the
- * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
- * to be no less than the current time plus ActiveRouteTimeout
- */
- RoutingTableEntry toOrigin;
- m_routingTable.LookupRoute (origin, toOrigin);
- UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
-
- m_nb.Update (route->GetGateway (), ActiveRouteTimeout);
- m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
-
- ucb (route, p, header);
- return true;
- }
- else
- {
- if (toDst.GetValidSeqNo ())
- {
- SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
- NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
- return false;
- }
- }
- }
- NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
- NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
- SendRerrWhenNoRouteToForward (dst, 0, origin);
- return false;
-}
-
-void
-RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
-{
- NS_ASSERT (ipv4 != 0);
- NS_ASSERT (m_ipv4 == 0);
-
- if (EnableHello)
- {
- m_htimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this);
- m_htimer.Schedule (MilliSeconds (UniformVariable ().GetInteger (0, 100)));
- }
-
- m_ipv4 = ipv4;
-
- // Create lo route. It is asserted that the only one interface up for now is loopback
- NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
- m_lo = m_ipv4->GetNetDevice (0);
- NS_ASSERT (m_lo != 0);
- // Remember lo route
- RoutingTableEntry rt (/*device=*/m_lo, /*dst=*/Ipv4Address::GetLoopback (), /*know seqno=*/true, /*seqno=*/0,
- /*iface=*/Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
- /*hops=*/1, /*next hop=*/Ipv4Address::GetLoopback (),
- /*lifetime=*/Simulator::GetMaximumSimulationTime ());
- m_routingTable.AddRoute (rt);
-
- Simulator::ScheduleNow (&RoutingProtocol::Start, this);
-}
-
-void
-RoutingProtocol::NotifyInterfaceUp (uint32_t i)
-{
- NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
- Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
- if (l3->GetNAddresses (i) > 1)
- {
- NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
- }
- Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
- if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
- return;
-
- // Create a socket to listen only on this interface
- Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
- UdpSocketFactory::GetTypeId ());
- NS_ASSERT (socket != 0);
- socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
- socket->BindToNetDevice (l3->GetNetDevice (i));
- socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT));
- socket->SetAllowBroadcast (true);
- socket->SetAttribute ("IpTtl", UintegerValue (1));
- m_socketAddresses.insert (std::make_pair (socket, iface));
-
- // Add local broadcast record to the routing table
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
- RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true, /*seqno=*/0, /*iface=*/iface,
- /*hops=*/1, /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Simulator::GetMaximumSimulationTime ());
- m_routingTable.AddRoute (rt);
-
- // Allow neighbor manager use this interface for layer 2 feedback if possible
- Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
- if (wifi == 0)
- return;
- Ptr<WifiMac> mac = wifi->GetMac ();
- if (mac == 0)
- return;
-
- mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
- m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
-}
-
-void
-RoutingProtocol::NotifyInterfaceDown (uint32_t i)
-{
- NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
-
- // Disable layer 2 link state monitoring (if possible)
- Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
- Ptr<NetDevice> dev = l3->GetNetDevice (i);
- Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
- if (wifi != 0)
- {
- Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
- if (mac != 0)
- {
- mac->TraceDisconnectWithoutContext ("TxErrHeader",
- m_nb.GetTxErrorCallback ());
- m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
- }
- }
-
- // Close socket
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
- NS_ASSERT (socket);
- socket->Close ();
- m_socketAddresses.erase (socket);
- if (m_socketAddresses.empty ())
- {
- NS_LOG_LOGIC ("No aodv interfaces");
- m_htimer.Cancel ();
- m_nb.Clear ();
- m_routingTable.Clear ();
- return;
- }
- m_routingTable.DeleteAllRoutesFromInterface (m_ipv4->GetAddress (i, 0));
-}
-
-void
-RoutingProtocol::NotifyAddAddress (uint32_t i, Ipv4InterfaceAddress address)
-{
- NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
- Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
- if (!l3->IsUp (i))
- return;
- if (l3->GetNAddresses (i) == 1)
- {
- Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (iface);
- if (!socket)
- {
- if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
- return;
- // Create a socket to listen only on this interface
- Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
- UdpSocketFactory::GetTypeId ());
- NS_ASSERT (socket != 0);
- socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv,this));
- socket->BindToNetDevice (l3->GetNetDevice (i));
- // Bind to any IP address so that broadcasts can be received
- socket->Bind (InetSocketAddress (Ipv4Address::GetAny(), AODV_PORT));
- socket->SetAllowBroadcast (true);
- m_socketAddresses.insert (std::make_pair (socket, iface));
-
- // Add local broadcast record to the routing table
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
- m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
- RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true,
- /*seqno=*/0, /*iface=*/iface, /*hops=*/1,
- /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Simulator::GetMaximumSimulationTime ());
- m_routingTable.AddRoute (rt);
- }
- }
- else
- {
- NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
- }
-}
-
-void
-RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address)
-{
- NS_LOG_FUNCTION (this);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
- if (socket)
- {
- m_routingTable.DeleteAllRoutesFromInterface (address);
- m_socketAddresses.erase (socket);
- Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
- if (l3->GetNAddresses (i))
- {
- Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
- // Create a socket to listen only on this interface
- Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
- UdpSocketFactory::GetTypeId ());
- NS_ASSERT (socket != 0);
- socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
- // Bind to any IP address so that broadcasts can be received
- socket->Bind (InetSocketAddress (Ipv4Address::GetAny(), AODV_PORT));
- socket->SetAllowBroadcast (true);
- m_socketAddresses.insert (std::make_pair (socket, iface));
-
- // Add local broadcast record to the routing table
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
- RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true, /*seqno=*/0, /*iface=*/iface,
- /*hops=*/1, /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Simulator::GetMaximumSimulationTime ());
- m_routingTable.AddRoute (rt);
- }
- if (m_socketAddresses.empty ())
- {
- NS_LOG_LOGIC ("No aodv interfaces");
- m_htimer.Cancel ();
- m_nb.Clear ();
- m_routingTable.Clear ();
- return;
- }
- }
- else
- {
- NS_LOG_LOGIC ("Remove address not participating in AODV operation");
- }
-}
-
-bool
-RoutingProtocol::IsMyOwnAddress (Ipv4Address src)
-{
- NS_LOG_FUNCTION (this << src);
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
- m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ipv4InterfaceAddress iface = j->second;
- if (src == iface.GetLocal ())
- {
- return true;
- }
- }
- return false;
-}
-
-Ptr<Ipv4Route>
-RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr, Ptr<NetDevice> oif) const
-{
- NS_LOG_FUNCTION (this << hdr);
- NS_ASSERT (m_lo != 0);
- Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
- rt->SetDestination (hdr.GetDestination ());
- //
- // Source address selection here is tricky. The loopback route is
- // returned when AODV does not have a route; this causes the packet
- // to be looped back and handled (cached) in RouteInput() method
- // while a route is found. However, connection-oriented protocols
- // like TCP need to create an endpoint four-tuple (src, src port,
- // dst, dst port) and create a pseudo-header for checksumming. So,
- // AODV needs to guess correctly what the eventual source address
- // will be.
- //
- // For single interface, single address nodes, this is not a problem.
- // When there are possibly multiple outgoing interfaces, the policy
- // implemented here is to pick the first available AODV interface.
- // If RouteOutput() caller specified an outgoing interface, that
- // further constrains the selection of source address
- //
- std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
- if (oif)
- {
- // Iterate to find an address on the oif device
- for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ipv4Address addr = j->second.GetLocal ();
- int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
- if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
- {
- rt->SetSource (addr);
- break;
- }
- }
- }
- else
- {
- rt->SetSource (j->second.GetLocal ());
- }
- NS_ASSERT_MSG (rt->GetSource() != Ipv4Address (), "Valid AODV source address not found");
- rt->SetGateway (Ipv4Address ("127.0.0.1"));
- rt->SetOutputDevice (m_lo);
- return rt;
-}
-
-void
-RoutingProtocol::SendRequest (Ipv4Address dst)
-{
- NS_LOG_FUNCTION ( this << dst);
- // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
- if (m_rreqCount == RreqRateLimit)
- {
- Simulator::Schedule (m_rreqRateLimitTimer.GetDelayLeft () + MicroSeconds (100),
- &RoutingProtocol::SendRequest, this, dst);
- return;
- }
- else
- m_rreqCount++;
- // Create RREQ header
- RreqHeader rreqHeader;
- rreqHeader.SetDst (dst);
-
- RoutingTableEntry rt;
- if (m_routingTable.LookupRoute (dst, rt))
- {
- rreqHeader.SetHopCount (rt.GetHop ());
- if (rt.GetValidSeqNo ())
- rreqHeader.SetDstSeqno (rt.GetSeqNo ());
- else
- rreqHeader.SetUnknownSeqno (true);
- rt.SetFlag (IN_SEARCH);
- m_routingTable.AddRoute (rt);
- }
- else
- {
- rreqHeader.SetUnknownSeqno (true);
- Ptr<NetDevice> dev = 0;
- RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/dst, /*validSeqNo=*/false, /*seqno=*/0,
- /*iface=*/Ipv4InterfaceAddress(),/*hop=*/0,
- /*nextHop=*/Ipv4Address(), /*lifeTime=*/Seconds(0));
- newEntry.SetFlag (IN_SEARCH);
- m_routingTable.AddRoute (newEntry);
- }
-
- if (GratuitousReply)
- rreqHeader.SetGratiousRrep (true);
- if (DestinationOnly)
- rreqHeader.SetDestinationOnly (true);
-
- m_seqNo++;
- rreqHeader.SetOriginSeqno (m_seqNo);
- m_requestId++;
- rreqHeader.SetId (m_requestId);
- rreqHeader.SetHopCount (0);
-
- // Send RREQ as subnet directed broadcast from each interface used by aodv
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
- m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ptr<Socket> socket = j->first;
- Ipv4InterfaceAddress iface = j->second;
-
- rreqHeader.SetOrigin (iface.GetLocal ());
- m_rreqIdCache.IsDuplicate (iface.GetLocal (), m_requestId);
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rreqHeader);
- TypeHeader tHeader (AODVTYPE_RREQ);
- packet->AddHeader (tHeader);
- // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
- Ipv4Address destination;
- if (iface.GetMask () == Ipv4Mask::GetOnes ())
- {
- destination = Ipv4Address ("255.255.255.255");
- }
- else
- {
- destination = iface.GetBroadcast ();
- }
- socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
- }
- ScheduleRreqRetry (dst);
- if (EnableHello)
- {
- m_htimer.Cancel ();
- m_htimer.Schedule (HelloInterval - Scalar (0.01) * MilliSeconds (UniformVariable ().GetInteger (0, 10)));
- }
-}
-
-void
-RoutingProtocol::ScheduleRreqRetry (Ipv4Address dst)
-{
- NS_LOG_FUNCTION (this << dst);
- if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
- {
- Timer timer (Timer::CANCEL_ON_DESTROY);
- m_addressReqTimer[dst] = timer;
- }
- m_addressReqTimer[dst].SetFunction (&RoutingProtocol::RouteRequestTimerExpire, this);
- m_addressReqTimer[dst].Remove ();
- m_addressReqTimer[dst].SetArguments (dst);
- RoutingTableEntry rt;
- m_routingTable.LookupRoute (dst, rt);
- rt.IncrementRreqCnt ();
- m_routingTable.Update (rt);
- m_addressReqTimer[dst].Schedule (Scalar (rt.GetRreqCnt ()) * NetTraversalTime);
-}
-
-void
-RoutingProtocol::RecvAodv (Ptr<Socket> socket)
-{
- NS_LOG_FUNCTION (this << socket);
- Address sourceAddress;
- Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
- InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
- Ipv4Address sender = inetSourceAddr.GetIpv4 ();
- Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
- NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
-
- UpdateRouteToNeighbor (sender, receiver);
- TypeHeader tHeader (AODVTYPE_RREQ);
- packet->RemoveHeader (tHeader);
- if (!tHeader.IsValid ())
- {
- NS_LOG_DEBUG ("AODV message " << packet->GetUid() << " with unknown type received: " << tHeader.Get() << ". Drop");
- return; // drop
- }
- switch (tHeader.Get ())
- {
- case AODVTYPE_RREQ:
- {
- RecvRequest (packet, receiver, sender);
- break;
- }
- case AODVTYPE_RREP:
- {
- RecvReply (packet, receiver, sender);
- break;
- }
- case AODVTYPE_RERR:
- {
- RecvError (packet, sender);
- break;
- }
- case AODVTYPE_RREP_ACK:
- {
- RecvReplyAck (sender);
- break;
- }
- }
-}
-
-bool
-RoutingProtocol::UpdateRouteLifeTime (Ipv4Address addr, Time lifetime)
-{
- NS_LOG_FUNCTION (this << addr << lifetime);
- RoutingTableEntry rt;
- if (m_routingTable.LookupRoute (addr, rt))
- {
- rt.SetFlag (VALID);
- rt.SetRreqCnt (0);
- rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
- m_routingTable.Update (rt);
- return true;
- }
- return false;
-}
-
-void
-RoutingProtocol::UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver)
-{
- NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
- RoutingTableEntry toNeighbor;
- if (!m_routingTable.LookupRoute (sender, toNeighbor))
- {
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
- RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/sender, /*know seqno=*/false, /*seqno=*/0,
- /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
- /*hops=*/1, /*next hop=*/sender, /*lifetime=*/ActiveRouteTimeout);
- m_routingTable.AddRoute (newEntry);
- }
- else
- {
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
- if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
- {
- toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
- }
- else
- {
- RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/sender, /*know seqno=*/false, /*seqno=*/0,
- /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
- /*hops=*/1, /*next hop=*/sender, /*lifetime=*/std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
- m_routingTable.Update (newEntry);
- }
- }
-
-}
-
-void
-RoutingProtocol::RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src)
-{
- NS_LOG_FUNCTION (this);
- RreqHeader rreqHeader;
- p->RemoveHeader (rreqHeader);
-
- // A node ignores all RREQs received from any node in its blacklist
- RoutingTableEntry toPrev;
- if (m_routingTable.LookupRoute (src, toPrev))
- {
- if (toPrev.IsUnidirectional ())
- return;
- }
-
- uint32_t id = rreqHeader.GetId ();
- Ipv4Address origin = rreqHeader.GetOrigin ();
-
- /*
- * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
- * If such a RREQ has been received, the node silently discards the newly received RREQ.
- */
- if (m_rreqIdCache.IsDuplicate (origin, id))
- {
- return;
- }
-
- // Increment RREQ hop count
- uint8_t hop = rreqHeader.GetHopCount () + 1;
- rreqHeader.SetHopCount (hop);
-
- /*
- * When the reverse route is created or updated, the following actions on the route are also carried out:
- * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
- * in the route table entry and copied if greater than the existing value there
- * 2. the valid sequence number field is set to true;
- * 3. the next hop in the routing table becomes the node from which the RREQ was received
- * 4. the hop count is copied from the Hop Count in the RREQ message;
- * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
- * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
- */
- RoutingTableEntry toOrigin;
- if (!m_routingTable.LookupRoute (origin, toOrigin))
- {
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
- RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/origin, /*validSeno=*/true, /*seqNo=*/rreqHeader.GetOriginSeqno (),
- /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/hop,
- /*nextHop*/src, /*timeLife=*/Scalar (2) * NetTraversalTime - Scalar (2 * hop) * NodeTraversalTime);
- m_routingTable.AddRoute (newEntry);
- }
- else
- {
- if (toOrigin.GetValidSeqNo ())
- {
- if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
- toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
- }
- else
- toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
- toOrigin.SetValidSeqNo (true);
- toOrigin.SetNextHop (src);
- toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
- toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
- toOrigin.SetHop (hop);
- toOrigin.SetLifeTime (std::max (Scalar (2) * NetTraversalTime - Scalar (2 * hop) * NodeTraversalTime, toOrigin.GetLifeTime ()));
- m_routingTable.Update (toOrigin);
- }
- NS_LOG_LOGIC (receiver << " receive RREQ to destination " << rreqHeader.GetDst ());
-
- // A node generates a RREP if either:
- // (i) it is itself the destination,
- if (IsMyOwnAddress (rreqHeader.GetDst ()))
- {
- m_routingTable.LookupRoute (origin, toOrigin);
- SendReply (rreqHeader, toOrigin);
- return;
- }
- /*
- * (ii) or it has an active route to the destination, the destination sequence number in the node's existing route table entry for the destination
- * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
- */
- RoutingTableEntry toDst;
- Ipv4Address dst = rreqHeader.GetDst ();
- if (m_routingTable.LookupRoute (dst, toDst))
- {
- /*
- * Drop RREQ, This node RREP wil make a loop.
- */
- if (toDst.GetNextHop () == src)
- {
- NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
- return;
- }
- /*
- * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
- * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
- * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
- * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
- */
- if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
- && toDst.GetValidSeqNo () )
- {
- if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag() == VALID)
- {
- m_routingTable.LookupRoute (origin, toOrigin);
- SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
- return;
- }
- rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
- rreqHeader.SetUnknownSeqno (false);
- }
- }
-
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
- m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ptr<Socket> socket = j->first;
- Ipv4InterfaceAddress iface = j->second;
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rreqHeader);
- TypeHeader tHeader (AODVTYPE_RREQ);
- packet->AddHeader (tHeader);
- // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
- Ipv4Address destination;
- if (iface.GetMask () == Ipv4Mask::GetOnes ())
- {
- destination = Ipv4Address ("255.255.255.255");
- }
- else
- {
- destination = iface.GetBroadcast ();
- }
- socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
- }
-
- if (EnableHello)
- {
- m_htimer.Cancel ();
- m_htimer.Schedule (HelloInterval - Scalar(0.1)*MilliSeconds(UniformVariable().GetInteger (0, 10)));
- }
-}
-
-void
-RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
-{
- NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
- /*
- * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
- * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
- */
- if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
- m_seqNo++;
- RrepHeader rrepHeader ( /*prefixSize=*/0, /*hops=*/0, /*dst=*/rreqHeader.GetDst (),
- /*dstSeqNo=*/m_seqNo, /*origin=*/toOrigin.GetDestination (), /*lifeTime=*/MyRouteTimeout);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rrepHeader);
- TypeHeader tHeader (AODVTYPE_RREP);
- packet->AddHeader (tHeader);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
- NS_ASSERT (socket);
- socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
-}
-
-void
-RoutingProtocol::SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep)
-{
- NS_LOG_FUNCTION (this);
- RrepHeader rrepHeader (/*prefix size=*/0, /*hops=*/toDst.GetHop (), /*dst=*/toDst.GetDestination (), /*dst seqno=*/toDst.GetSeqNo (),
- /*origin=*/toOrigin.GetDestination (), /*lifetime=*/toDst.GetLifeTime ());
- /* If the node we received a RREQ for is a neighbor we are
- * probably facing a unidirectional link... Better request a RREP-ack
- */
- if (toDst.GetHop () == 1)
- {
- rrepHeader.SetAckRequired (true);
- RoutingTableEntry toNextHop;
- m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
- toNextHop.m_ackTimer.SetFunction (&RoutingProtocol::AckTimerExpire, this);
- toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
- toNextHop.m_ackTimer.SetDelay (NextHopWait);
- }
- toDst.InsertPrecursor (toOrigin.GetNextHop ());
- toOrigin.InsertPrecursor (toDst.GetNextHop ());
- m_routingTable.Update (toDst);
- m_routingTable.Update (toOrigin);
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rrepHeader);
- TypeHeader tHeader (AODVTYPE_RREP);
- packet->AddHeader (tHeader);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
- NS_ASSERT (socket);
- socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
-
- // Generating gratuitous RREPs
- if (gratRep)
- {
- RrepHeader gratRepHeader (/*prefix size=*/0, /*hops=*/toOrigin.GetHop (), /*dst=*/toOrigin.GetDestination (),
- /*dst seqno=*/toOrigin.GetSeqNo (), /*origin=*/toDst.GetDestination (),
- /*lifetime=*/toOrigin.GetLifeTime ());
- Ptr<Packet> packetToDst = Create<Packet> ();
- packetToDst->AddHeader (gratRepHeader);
- TypeHeader type (AODVTYPE_RREP);
- packetToDst->AddHeader (type);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (toDst.GetInterface ());
- NS_ASSERT (socket);
- NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid());
- socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
- }
-}
-
-void
-RoutingProtocol::SendReplyAck (Ipv4Address neighbor)
-{
- NS_LOG_FUNCTION (this << " to " << neighbor);
- RrepAckHeader h;
- TypeHeader typeHeader (AODVTYPE_RREP_ACK);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (h);
- packet->AddHeader (typeHeader);
- RoutingTableEntry toNeighbor;
- m_routingTable.LookupRoute (neighbor, toNeighbor);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
- NS_ASSERT (socket);
- socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
-}
-
-void
-RoutingProtocol::RecvReply (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address sender)
-{
- NS_LOG_FUNCTION(this << " src " << sender);
- RrepHeader rrepHeader;
- p->RemoveHeader (rrepHeader);
- Ipv4Address dst = rrepHeader.GetDst ();
- NS_LOG_LOGIC("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin());
-
- uint8_t hop = rrepHeader.GetHopCount () + 1;
- rrepHeader.SetHopCount (hop);
-
- // If RREP is Hello message
- if (dst == rrepHeader.GetOrigin ())
- {
- ProcessHello (rrepHeader, receiver);
- return;
- }
-
- /*
- * If the route table entry to the destination is created or updated, then the following actions occur:
- * - the route is marked as active,
- * - the destination sequence number is marked as valid,
- * - the next hop in the route entry is assigned to be the node from which the RREP is received,
- * which is indicated by the source IP address field in the IP header,
- * - the hop count is set to the value of the hop count from RREP message + 1
- * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
- * - and the destination sequence number is the Destination Sequence Number in the RREP message.
- */
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
- RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/dst, /*validSeqNo=*/true, /*seqno=*/rrepHeader.GetDstSeqno (),
- /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/hop,
- /*nextHop=*/sender, /*lifeTime=*/rrepHeader.GetLifeTime ());
- RoutingTableEntry toDst;
- if (m_routingTable.LookupRoute (dst, toDst))
- {
- /*
- * The existing entry is updated only in the following circumstances:
- * (i) the sequence number in the routing table is marked as invalid in route table entry.
- */
- if (!toDst.GetValidSeqNo ())
- {
- m_routingTable.Update (newEntry);
- }
- // (ii)the Destination Sequence Number in the RREP is greater than the node's copy of the destination sequence number and the known value is valid,
- else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
- {
- m_routingTable.Update (newEntry);
- }
- else
- {
- // (iii) the sequence numbers are the same, but the route is marked as inactive.
- if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
- {
- m_routingTable.Update (newEntry);
- }
- // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
- else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
- {
- m_routingTable.Update (newEntry);
- }
- }
- }
- else
- {
- // The forward route for this destination is created if it does not already exist.
- NS_LOG_LOGIC ("add new route");
- m_routingTable.AddRoute (newEntry);
- }
- // Acknowledge receipt of the RREP by sending a RREP-ACK message back
- if (rrepHeader.GetAckRequired ())
- {
- SendReplyAck (sender);
- rrepHeader.SetAckRequired (false);
- }
- NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
- if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
- {
- if (toDst.GetFlag () == IN_SEARCH)
- {
- m_routingTable.Update (newEntry);
- m_addressReqTimer[dst].Remove ();
- m_addressReqTimer.erase (dst);
- }
- m_routingTable.LookupRoute (dst, toDst);
- SendPacketFromQueue (dst, toDst.GetRoute ());
- return;
- }
-
- RoutingTableEntry toOrigin;
- if (! m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
- {
- return; // Impossible! drop.
- }
- toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
- m_routingTable.Update (toOrigin);
-
- // Update information about precursors
- if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
- {
- toDst.InsertPrecursor (toOrigin.GetNextHop ());
- m_routingTable.Update (toDst);
-
- RoutingTableEntry toNextHopToDst;
- m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
- toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
- m_routingTable.Update (toNextHopToDst);
-
- toOrigin.InsertPrecursor (toDst.GetNextHop ());
- m_routingTable.Update (toOrigin);
-
- RoutingTableEntry toNextHopToOrigin;
- m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
- toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
- m_routingTable.Update (toNextHopToOrigin);
- }
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rrepHeader);
- TypeHeader tHeader (AODVTYPE_RREP);
- packet->AddHeader (tHeader);
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
- NS_ASSERT (socket);
- socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
-}
-
-void
-RoutingProtocol::RecvReplyAck (Ipv4Address neighbor)
-{
- NS_LOG_FUNCTION (this);
- RoutingTableEntry rt;
- if(m_routingTable.LookupRoute(neighbor, rt))
- {
- rt.m_ackTimer.Cancel ();
- rt.SetFlag (VALID);
- m_routingTable.Update(rt);
- }
-}
-
-void
-RoutingProtocol::ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiver )
-{
- NS_LOG_FUNCTION(this << "from " << rrepHeader.GetDst ());
- /*
- * Whenever a node receives a Hello message from a neighbor, the node
- * SHOULD make sure that it has an active route to the neighbor, and
- * create one if necessary.
- */
- RoutingTableEntry toNeighbor;
- if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
- {
- Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
- RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/rrepHeader.GetDst (), /*validSeqNo=*/true, /*seqno=*/rrepHeader.GetDstSeqno (),
- /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
- /*hop=*/1, /*nextHop=*/rrepHeader.GetDst (), /*lifeTime=*/rrepHeader.GetLifeTime ());
- m_routingTable.AddRoute (newEntry);
- }
- else
- {
- toNeighbor.SetLifeTime (std::max (Scalar (AllowedHelloLoss) * HelloInterval, toNeighbor.GetLifeTime ()));
- toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
- toNeighbor.SetValidSeqNo (true);
- toNeighbor.SetFlag (VALID);
- toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
- toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
- m_routingTable.Update (toNeighbor);
- }
- if (EnableHello)
- {
- m_nb.Update (rrepHeader.GetDst (), Scalar (AllowedHelloLoss) * HelloInterval);
- }
-}
-
-void
-RoutingProtocol::RecvError (Ptr<Packet> p, Ipv4Address src )
-{
- NS_LOG_FUNCTION (this << " from " << src);
- RerrHeader rerrHeader;
- p->RemoveHeader (rerrHeader);
- std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
- std::map<Ipv4Address, uint32_t> unreachable;
- m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
- std::pair<Ipv4Address, uint32_t> un;
- while (rerrHeader.RemoveUnDestination (un))
- {
- if (m_nb.IsNeighbor (un.first))
- SendRerrWhenBreaksLinkToNextHop (un.first);
- else
- {
- for (std::map<Ipv4Address, uint32_t>::const_iterator i =
- dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
- {
- if (i->first == un.first)
- {
- Ipv4Address dst = un.first;
- unreachable.insert (un);
- }
- }
- }
- }
-
- std::vector<Ipv4Address> precursors;
- for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
- i != unreachable.end ();)
- {
- if (!rerrHeader.AddUnDestination (i->first, i->second))
- {
- TypeHeader typeHeader (AODVTYPE_RERR);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rerrHeader);
- packet->AddHeader (typeHeader);
- SendRerrMessage (packet, precursors);
- rerrHeader.Clear ();
- }
- else
- {
- RoutingTableEntry toDst;
- m_routingTable.LookupRoute (i->first, toDst);
- toDst.GetPrecursors (precursors);
- ++i;
- }
- }
- if (rerrHeader.GetDestCount () != 0)
- {
- TypeHeader typeHeader (AODVTYPE_RERR);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rerrHeader);
- packet->AddHeader (typeHeader);
- SendRerrMessage (packet, precursors);
- }
- m_routingTable.InvalidateRoutesWithDst (unreachable);
-}
-
-void
-RoutingProtocol::RouteRequestTimerExpire (Ipv4Address dst)
-{
- NS_LOG_LOGIC(this);
- RoutingTableEntry toDst;
- if (m_routingTable.LookupValidRoute (dst, toDst))
- {
- SendPacketFromQueue (dst, toDst.GetRoute ());
- NS_LOG_LOGIC ("route to " << dst << " found");
- return;
- }
- /*
- * If a route discovery has been attempted RreqRetries times at the maximum TTL without
- * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
- * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
- */
- if (toDst.GetRreqCnt () == RreqRetries)
- {
- NS_LOG_LOGIC("route discovery to " << dst << " has been attempted RreqRetries times");
- m_addressReqTimer.erase (dst);
- m_routingTable.DeleteRoute (dst);
- NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
- m_queue.DropPacketWithDst (dst);
- return;
- }
-
- if (toDst.GetFlag () == IN_SEARCH)
- {
- NS_LOG_LOGIC ("Send new RREQ to " << dst << " ttl " << NetDiameter);
- SendRequest (dst);
- }
- else
- {
- NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
- m_addressReqTimer.erase(dst);
- m_routingTable.DeleteRoute(dst);
- m_queue.DropPacketWithDst(dst);
- }
-}
-
-void
-RoutingProtocol::HelloTimerExpire ()
-{
- NS_LOG_FUNCTION (this);
- SendHello ();
- m_htimer.Cancel ();
- Time t = Scalar(0.01)*MilliSeconds(UniformVariable().GetInteger (0, 100));
- m_htimer.Schedule (HelloInterval - t);
-}
-
-void
-RoutingProtocol::RreqRateLimitTimerExpire ()
-{
- NS_LOG_FUNCTION (this);
- m_rreqCount = 0;
- m_rreqRateLimitTimer.Schedule (Seconds (1));
-}
-
-void
-RoutingProtocol::AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout)
-{
- NS_LOG_FUNCTION (this);
- m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
-}
-
-void
-RoutingProtocol::SendHello ()
-{
- NS_LOG_FUNCTION (this);
- /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
- * Destination IP Address The node's IP address.
- * Destination Sequence Number The node's latest sequence number.
- * Hop Count 0
- * Lifetime AllowedHelloLoss * HelloInterval
- */
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ptr<Socket> socket = j->first;
- Ipv4InterfaceAddress iface = j->second;
- RrepHeader helloHeader (/*prefix size=*/0, /*hops=*/0, /*dst=*/iface.GetLocal (), /*dst seqno=*/m_seqNo,
- /*origin=*/iface.GetLocal (),/*lifetime=*/Scalar (AllowedHelloLoss) * HelloInterval);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (helloHeader);
- TypeHeader tHeader (AODVTYPE_RREP);
- packet->AddHeader (tHeader);
- // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
- Ipv4Address destination;
- if (iface.GetMask () == Ipv4Mask::GetOnes ())
- {
- destination = Ipv4Address ("255.255.255.255");
- }
- else
- {
- destination = iface.GetBroadcast ();
- }
- socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
- }
-}
-
-void
-RoutingProtocol::SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route)
-{
- NS_LOG_FUNCTION (this);
- QueueEntry queueEntry;
- while (m_queue.Dequeue (dst, queueEntry))
- {
- DeferredRouteOutputTag tag;
- Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
- if (p->RemovePacketTag (tag) &&
- tag.oif != -1 &&
- tag.oif != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
- {
- NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
- return;
- }
- UnicastForwardCallback ucb = queueEntry.GetUnicastForwardCallback ();
- Ipv4Header header = queueEntry.GetIpv4Header ();
- header.SetSource (route->GetSource ());
- header.SetTtl (header.GetTtl() + 1); // compensate extra TTL decrement by fake loopback routing
- ucb (route, p, header);
- }
-}
-
-void
-RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop)
-{
- NS_LOG_FUNCTION (this << nextHop);
- RerrHeader rerrHeader;
- std::vector<Ipv4Address> precursors;
- std::map<Ipv4Address, uint32_t> unreachable;
-
- RoutingTableEntry toNextHop;
- if (!m_routingTable.LookupRoute (nextHop, toNextHop))
- return;
- toNextHop.GetPrecursors (precursors);
- rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
- m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
- for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
- != unreachable.end ();)
- {
- if (!rerrHeader.AddUnDestination (i->first, i->second))
- {
- NS_LOG_LOGIC ("Send RERR message with maximum size.");
- TypeHeader typeHeader (AODVTYPE_RERR);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rerrHeader);
- packet->AddHeader (typeHeader);
- SendRerrMessage (packet, precursors);
- rerrHeader.Clear ();
- }
- else
- {
- RoutingTableEntry toDst;
- m_routingTable.LookupRoute (i->first, toDst);
- toDst.GetPrecursors (precursors);
- ++i;
- }
- }
- if (rerrHeader.GetDestCount () != 0)
- {
- TypeHeader typeHeader (AODVTYPE_RERR);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rerrHeader);
- packet->AddHeader (typeHeader);
- SendRerrMessage (packet, precursors);
- }
- unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
- m_routingTable.InvalidateRoutesWithDst (unreachable);
-}
-
-void
-RoutingProtocol::SendRerrWhenNoRouteToForward (Ipv4Address dst,
- uint32_t dstSeqNo, Ipv4Address origin)
-{
- NS_LOG_FUNCTION (this);
- RerrHeader rerrHeader;
- rerrHeader.AddUnDestination (dst, dstSeqNo);
- RoutingTableEntry toOrigin;
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (rerrHeader);
- packet->AddHeader (TypeHeader (AODVTYPE_RERR));
- if (m_routingTable.LookupValidRoute (origin, toOrigin))
- {
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (
- toOrigin.GetInterface ());
- NS_ASSERT (socket);
- NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
- socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
- }
- else
- {
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator i =
- m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
- {
- Ptr<Socket> socket = i->first;
- Ipv4InterfaceAddress iface = i->second;
- NS_ASSERT (socket);
- NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal());
- // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
- Ipv4Address destination;
- if (iface.GetMask () == Ipv4Mask::GetOnes ())
- {
- destination = Ipv4Address ("255.255.255.255");
- }
- else
- {
- destination = iface.GetBroadcast ();
- }
- socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
- }
- }
-}
-
-void
-RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
-{
- NS_LOG_FUNCTION (this);
-
- if (precursors.empty ())
- {
- NS_LOG_LOGIC ("No precursors");
- return;
- }
- // If there is only one precursor, RERR SHOULD be unicast toward that precursor
- if (precursors.size () == 1)
- {
- RoutingTableEntry toPrecursor;
- if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
- {
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
- NS_ASSERT (socket);
- NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination() << " from " << toPrecursor.GetInterface ().GetLocal ());
- socket->SendTo (packet, 0, InetSocketAddress (precursors.front (), AODV_PORT));
- }
- return;
- }
-
- // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
- std::vector<Ipv4InterfaceAddress> ifaces;
- RoutingTableEntry toPrecursor;
- for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
- {
- if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
- std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
- {
- ifaces.push_back (toPrecursor.GetInterface ());
- }
- }
-
- for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
- {
- Ptr<Socket> socket = FindSocketWithInterfaceAddress (*i);
- NS_ASSERT (socket);
- NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal());
- // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
- Ipv4Address destination;
- if (i->GetMask () == Ipv4Mask::GetOnes ())
- {
- destination = Ipv4Address ("255.255.255.255");
- }
- else
- {
- destination = i->GetBroadcast ();
- }
- socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
- }
-}
-
-Ptr<Socket>
-RoutingProtocol::FindSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) const
-{
- NS_LOG_FUNCTION (this << addr);
- for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
- m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
- {
- Ptr<Socket> socket = j->first;
- Ipv4InterfaceAddress iface = j->second;
- if (iface == addr)
- return socket;
- }
- Ptr<Socket> socket;
- return socket;
-}
-
-}
-}
--- a/src/routing/aodv/aodv-routing-protocol.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,254 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#ifndef AODVROUTINGPROTOCOL_H
-#define AODVROUTINGPROTOCOL_H
-
-#include "aodv-rtable.h"
-#include "aodv-rqueue.h"
-#include "aodv-packet.h"
-#include "aodv-neighbor.h"
-#include "aodv-dpd.h"
-#include "ns3/node.h"
-#include "ns3/output-stream-wrapper.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/ipv4-interface.h"
-#include "ns3/ipv4-l3-protocol.h"
-#include <map>
-
-namespace ns3
-{
-namespace aodv
-{
-/**
- * \ingroup aodv
- *
- * \brief AODV routing protocol
- */
-class RoutingProtocol : public Ipv4RoutingProtocol
-{
-public:
- static TypeId GetTypeId (void);
- static const uint32_t AODV_PORT;
-
- /// c-tor
- RoutingProtocol ();
- virtual ~RoutingProtocol();
- virtual void DoDispose ();
-
- ///\name From Ipv4RoutingProtocol
- //\{
- Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
- 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;
- //\}
-
- ///\name Handle protocol parameters
- //\{
- Time GetMaxQueueTime () const { return MaxQueueTime; }
- void SetMaxQueueTime (Time t);
- uint32_t GetMaxQueueLen () const { return MaxQueueLen; }
- void SetMaxQueueLen (uint32_t len);
- bool GetDesinationOnlyFlag () const { return DestinationOnly; }
- void SetDesinationOnlyFlag (bool f) { DestinationOnly = f; }
- bool GetGratuitousReplyFlag () const { return GratuitousReply; }
- void SetGratuitousReplyFlag (bool f) { GratuitousReply = f; }
- void SetHelloEnable (bool f) { EnableHello = f; }
- bool GetHelloEnable () const { return EnableHello; }
- void SetBroadcastEnable (bool f) { EnableBroadcast = f; }
- bool GetBroadcastEnable () const { return EnableBroadcast; }
- //\}
-private:
- ///\name Protocol parameters.
- //\{
- uint32_t RreqRetries; ///< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
- uint16_t RreqRateLimit; ///< Maximum number of RREQ per second.
- Time ActiveRouteTimeout; ///< Period of time during which the route is considered to be valid.
- uint32_t NetDiameter; ///< Net diameter measures the maximum possible number of hops between two nodes in the network
- /**
- * NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets
- * and should include queuing delays, interrupt processing times and transfer times.
- */
- Time NodeTraversalTime;
- Time NetTraversalTime; ///< Estimate of the average net traversal time.
- Time PathDiscoveryTime; ///< Estimate of maximum time needed to find route in network.
- Time MyRouteTimeout; ///< Value of lifetime field in RREP generating by this node.
- /**
- * Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval.
- * If it has not, it MAY broadcast a Hello message
- */
- Time HelloInterval;
- uint32_t AllowedHelloLoss; ///< Number of hello messages which may be loss for valid link
- /**
- * DeletePeriod is intended to provide an upper bound on the time for which an upstream node A
- * can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D.
- */
- Time DeletePeriod;
- Time NextHopWait; ///< Period of our waiting for the neighbour's RREP_ACK
- /**
- * The TimeoutBuffer is configurable. Its purpose is to provide a buffer for the timeout so that if the RREP is delayed
- * due to congestion, a timeout is less likely to occur while the RREP is still en route back to the source.
- */
- uint16_t TimeoutBuffer;
- Time BlackListTimeout; ///< Time for which the node is put into the blacklist
- uint32_t MaxQueueLen; ///< The maximum number of packets that we allow a routing protocol to buffer.
- Time MaxQueueTime; ///< The maximum period of time that a routing protocol is allowed to buffer a packet for.
- bool DestinationOnly; ///< Indicates only the destination may respond to this RREQ.
- bool GratuitousReply; ///< Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.
- bool EnableHello; ///< Indicates whether a hello messages enable
- bool EnableBroadcast; ///< Indicates whether a a broadcast data packets forwarding enable
- //\}
-
- /// IP protocol
- Ptr<Ipv4> m_ipv4;
- /// Raw socket per each IP interface, map socket -> iface address (IP + mask)
- std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketAddresses;
- /// Loopback device used to defer RREQ until packet will be fully formed
- Ptr<NetDevice> m_lo;
-
- /// Routing table
- RoutingTable m_routingTable;
- /// A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route.
- RequestQueue m_queue;
- /// Broadcast ID
- uint32_t m_requestId;
- /// Request sequence number
- uint32_t m_seqNo;
- /// Handle duplicated RREQ
- IdCache m_rreqIdCache;
- /// Handle duplicated broadcast/multicast packets
- DuplicatePacketDetection m_dpd;
- /// Handle neighbors
- Neighbors m_nb;
- /// Number of RREQs used for RREQ rate control
- uint16_t m_rreqCount;
-
-private:
- /// Start protocol operation
- void Start ();
- /// Queue packet and send route request
- void DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
- /// If route exists and valid, forward packet.
- bool Forwarding (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
- /**
- * To reduce congestion in a network, repeated attempts by a source node at route discovery
- * for a single destination MUST utilize a binary exponential backoff.
- */
- void ScheduleRreqRetry (Ipv4Address dst);
- /**
- * Set lifetime field in routing table entry to the maximum of existing lifetime and lt, if the entry exists
- * \param addr - destination address
- * \param lt - proposed time for lifetime field in routing table entry for destination with address addr.
- * \return true if route to destination address addr exist
- */
- bool UpdateRouteLifeTime (Ipv4Address addr, Time lt);
- /**
- * Update neighbor record.
- * \param receiver is supposed to be my interface
- * \param sender is supposed to be IP address of my neighbor.
- */
- void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver);
- /// Check that packet is send from own interface
- bool IsMyOwnAddress (Ipv4Address src);
- /// Find socket with local interface address iface
- Ptr<Socket> FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
- /// Process hello message
- void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr);
- /// Create loopback route for given header
- Ptr<Ipv4Route> LoopbackRoute (const Ipv4Header & header, Ptr<NetDevice> oif) const;
-
- ///\name Receive control packets
- //\{
- /// Receive and process control packet
- void RecvAodv (Ptr<Socket> socket);
- /// Receive RREQ
- void RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src);
- /// Receive RREP
- void RecvReply (Ptr<Packet> p, Ipv4Address my ,Ipv4Address src);
- /// Receive RREP_ACK
- void RecvReplyAck (Ipv4Address neighbor);
- /// Receive RERR from node with address src
- void RecvError (Ptr<Packet> p, Ipv4Address src);
- //\}
-
- ///\name Send
- //\{
- /// Forward packet from route request queue
- void SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route);
- /// Send hello
- void SendHello ();
- /// Send RREQ
- void SendRequest (Ipv4Address dst);
- /// Send RREP
- void SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin);
- /** Send RREP by intermediate node
- * \param toDst routing table entry to destination
- * \param toOrigin routing table entry to originator
- * \param gratRep indicates whether a gratuitous RREP should be unicast to destination
- */
- void SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep);
- /// Send RREP_ACK
- void SendReplyAck (Ipv4Address neighbor);
- /// Initiate RERR
- void SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop);
- /// Forward RERR
- void SendRerrMessage(Ptr<Packet> packet, std::vector<Ipv4Address> precursors);
- /**
- * Send RERR message when no route to forward input packet. Unicast if there is reverse route to originating node, broadcast otherwise.
- * \param dst - destination node IP address
- * \param dstSeqNo - destination node sequence number
- * \param origin - originating node IP address
- */
- void SendRerrWhenNoRouteToForward (Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin);
- //\}
-
- /// Hello timer
- Timer m_htimer;
- /// Schedule next send of hello message
- void HelloTimerExpire ();
- /// RREQ rate limit timer
- Timer m_rreqRateLimitTimer;
- /// Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
- void RreqRateLimitTimerExpire ();
- /// Map IP address + RREQ timer.
- std::map<Ipv4Address, Timer> m_addressReqTimer;
- /// Handle route discovery process
- void RouteRequestTimerExpire (Ipv4Address dst);
- /// Mark link to neighbor node as unidirectional for blacklistTimeout
- void AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout);
-};
-
-}
-}
-#endif /* AODVROUTINGPROTOCOL_H */
--- a/src/routing/aodv/aodv-rqueue.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#include "aodv-rqueue.h"
-#include <algorithm>
-#include <functional>
-#include "ns3/ipv4-route.h"
-#include "ns3/socket.h"
-#include "ns3/log.h"
-
-NS_LOG_COMPONENT_DEFINE ("AodvRequestQueue");
-
-namespace ns3
-{
-namespace aodv
-{
-uint32_t
-RequestQueue::GetSize ()
-{
- Purge ();
- return m_queue.size ();
-}
-
-bool
-RequestQueue::Enqueue (QueueEntry & entry)
-{
- Purge ();
- for (std::vector<QueueEntry>::const_iterator i = m_queue.begin (); i
- != m_queue.end (); ++i)
- {
- if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ())
- && (i->GetIpv4Header ().GetDestination ()
- == entry.GetIpv4Header ().GetDestination ()))
- return false;
- }
- entry.SetExpireTime (m_queueTimeout);
- if (m_queue.size () == m_maxLen)
- {
- Drop (m_queue.front (), "Drop the most aged packet"); // Drop the most aged packet
- m_queue.erase (m_queue.begin ());
- }
- m_queue.push_back (entry);
- return true;
-}
-
-void
-RequestQueue::DropPacketWithDst (Ipv4Address dst)
-{
- NS_LOG_FUNCTION (this << dst);
- Purge ();
- const Ipv4Address addr = dst;
- for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i
- != m_queue.end (); ++i)
- {
- if (IsEqual (*i, dst))
- {
- Drop (*i, "DropPacketWithDst ");
- }
- }
- m_queue.erase (std::remove_if (m_queue.begin (), m_queue.end (),
- std::bind2nd (std::ptr_fun (RequestQueue::IsEqual), dst)), m_queue.end ());
-}
-
-bool
-RequestQueue::Dequeue (Ipv4Address dst, QueueEntry & entry)
-{
- Purge ();
- for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i != m_queue.end (); ++i)
- {
- if (i->GetIpv4Header ().GetDestination () == dst)
- {
- entry = *i;
- m_queue.erase (i);
- return true;
- }
- }
- return false;
-}
-
-bool
-RequestQueue::Find (Ipv4Address dst)
-{
- for (std::vector<QueueEntry>::const_iterator i = m_queue.begin (); i
- != m_queue.end (); ++i)
- {
- if (i->GetIpv4Header ().GetDestination () == dst)
- return true;
- }
- return false;
-}
-
-struct IsExpired
-{
- bool
- operator() (QueueEntry const & e) const
- {
- return (e.GetExpireTime () < Seconds (0));
- }
-};
-
-void
-RequestQueue::Purge ()
-{
- IsExpired pred;
- for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i
- != m_queue.end (); ++i)
- {
- if (pred (*i))
- {
- Drop (*i, "Drop outdated packet ");
- }
- }
- m_queue.erase (std::remove_if (m_queue.begin (), m_queue.end (), pred),
- m_queue.end ());
-}
-
-void
-RequestQueue::Drop (QueueEntry en, std::string reason)
-{
- NS_LOG_LOGIC (reason << en.GetPacket ()->GetUid () << " " << en.GetIpv4Header ().GetDestination ());
- en.GetErrorCallback () (en.GetPacket (), en.GetIpv4Header (),
- Socket::ERROR_NOROUTETOHOST);
- return;
-}
-
-}
-}
--- a/src/routing/aodv/aodv-rqueue.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#ifndef AODV_RQUEUE_H
-#define AODV_RQUEUE_H
-
-#include <vector>
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/simulator.h"
-
-
-namespace ns3 {
-namespace aodv {
-
-/**
- * \ingroup aodv
- * \brief AODV Queue Entry
- */
-class QueueEntry
-{
-public:
- typedef Ipv4RoutingProtocol::UnicastForwardCallback UnicastForwardCallback;
- typedef Ipv4RoutingProtocol::ErrorCallback ErrorCallback;
- /// c-tor
- QueueEntry (Ptr<const Packet> pa = 0, Ipv4Header const & h = Ipv4Header (),
- UnicastForwardCallback ucb = UnicastForwardCallback (),
- ErrorCallback ecb = ErrorCallback (), Time exp = Simulator::Now ()) :
- m_packet (pa), m_header (h), m_ucb (ucb), m_ecb (ecb),
- m_expire (exp + Simulator::Now ())
- {}
-
- /**
- * Compare queue entries
- * \return true if equal
- */
- bool operator== (QueueEntry const & o) const
- {
- return ((m_packet == o.m_packet) && (m_header.GetDestination () == o.m_header.GetDestination ()) && (m_expire == o.m_expire));
- }
- ///\name Fields
- //\{
- UnicastForwardCallback GetUnicastForwardCallback () const { return m_ucb; }
- void SetUnicastForwardCallback (UnicastForwardCallback ucb) { m_ucb = ucb; }
- ErrorCallback GetErrorCallback () const { return m_ecb; }
- void SetErrorCallback (ErrorCallback ecb) { m_ecb = ecb; }
- Ptr<const Packet> GetPacket () const { return m_packet; }
- void SetPacket (Ptr<const Packet> p) { m_packet = p; }
- Ipv4Header GetIpv4Header() const { return m_header; }
- void SetIpv4Header (Ipv4Header h) { m_header = h; }
- void SetExpireTime (Time exp) { m_expire = exp + Simulator::Now(); }
- Time GetExpireTime () const { return m_expire - Simulator::Now(); }
- //\}
-private:
- /// Data packet
- Ptr<const Packet> m_packet;
- /// IP header
- Ipv4Header m_header;
- /// Unicast forward callback
- UnicastForwardCallback m_ucb;
- /// Error callback
- ErrorCallback m_ecb;
- /// Expire time for queue entry
- Time m_expire;
-};
-/**
- * \ingroup aodv
- * \brief AODV route request queue
- *
- * Since AODV is an on demand routing we queue requests while looking for route.
- */
-class RequestQueue
-{
-public:
- /// Default c-tor
- RequestQueue (uint32_t maxLen, Time routeToQueueTimeout) :
- m_maxLen (maxLen), m_queueTimeout (routeToQueueTimeout)
- {
- }
- /// Push entry in queue, if there is no entry with the same packet and destination address in queue.
- bool Enqueue (QueueEntry & entry);
- /// Return first found (the earliest) entry for given destination
- bool Dequeue (Ipv4Address dst, QueueEntry & entry);
- /// Remove all packets with destination IP address dst
- void DropPacketWithDst (Ipv4Address dst);
- /// Finds whether a packet with destination dst exists in the queue
- bool Find (Ipv4Address dst);
- /// Number of entries
- uint32_t GetSize ();
- ///\name Fields
- //\{
- uint32_t GetMaxQueueLen () const { return m_maxLen; }
- void SetMaxQueueLen (uint32_t len) { m_maxLen = len; }
- Time GetQueueTimeout () const { return m_queueTimeout; }
- void SetQueueTimeout (Time t) { m_queueTimeout = t; }
- //\}
-
-private:
- std::vector<QueueEntry> m_queue;
- /// Remove all expired entries
- void Purge ();
- /// Notify that packet is dropped from queue by timeout
- void Drop (QueueEntry en, std::string reason);
- /// The maximum number of packets that we allow a routing protocol to buffer.
- uint32_t m_maxLen;
- /// The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
- Time m_queueTimeout;
- static bool IsEqual (QueueEntry en, const Ipv4Address dst) { return (en.GetIpv4Header ().GetDestination () == dst); }
-};
-
-
-}}
-
-#endif /* AODV_RQUEUE_H */
--- a/src/routing/aodv/aodv-rtable.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#include "aodv-rtable.h"
-#include <algorithm>
-#include <iomanip>
-#include "ns3/simulator.h"
-#include "ns3/log.h"
-
-NS_LOG_COMPONENT_DEFINE ("AodvRoutingTable");
-
-namespace ns3
-{
-namespace aodv
-{
-
-/*
- The Routing Table
- */
-
-RoutingTableEntry::RoutingTableEntry (Ptr<NetDevice> dev, Ipv4Address dst, bool vSeqNo, uint32_t seqNo,
- Ipv4InterfaceAddress iface, uint16_t hops, Ipv4Address nextHop, Time lifetime) :
- m_ackTimer (Timer::CANCEL_ON_DESTROY),
- m_validSeqNo (vSeqNo), m_seqNo (seqNo), m_hops (hops),
- m_lifeTime (lifetime + Simulator::Now ()), m_iface (iface), m_flag (VALID),
- m_reqCount (0), m_blackListState (false), m_blackListTimeout (Simulator::Now ())
-{
- m_ipv4Route = Create<Ipv4Route> ();
- m_ipv4Route->SetDestination (dst);
- m_ipv4Route->SetGateway (nextHop);
- m_ipv4Route->SetSource (m_iface.GetLocal ());
- m_ipv4Route->SetOutputDevice (dev);
-}
-
-RoutingTableEntry::~RoutingTableEntry ()
-{
-}
-
-bool
-RoutingTableEntry::InsertPrecursor (Ipv4Address id)
-{
- NS_LOG_FUNCTION (this << id);
- if (!LookupPrecursor (id))
- {
- m_precursorList.push_back (id);
- return true;
- }
- else
- return false;
-}
-
-bool
-RoutingTableEntry::LookupPrecursor (Ipv4Address id)
-{
- NS_LOG_FUNCTION (this << id);
- for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
- != m_precursorList.end (); ++i)
- {
- if (*i == id)
- {
- NS_LOG_LOGIC ("Precursor " << id << " found");
- return true;
- }
- }
- NS_LOG_LOGIC ("Precursor " << id << " not found");
- return false;
-}
-
-bool
-RoutingTableEntry::DeletePrecursor (Ipv4Address id)
-{
- NS_LOG_FUNCTION (this << id);
- std::vector<Ipv4Address>::iterator i = std::remove (m_precursorList.begin (),
- m_precursorList.end (), id);
- if (i == m_precursorList.end ())
- {
- NS_LOG_LOGIC ("Precursor " << id << " not found");
- return false;
- }
- else
- {
- NS_LOG_LOGIC ("Precursor " << id << " found");
- m_precursorList.erase (i, m_precursorList.end ());
- }
- return true;
-}
-
-void
-RoutingTableEntry::DeleteAllPrecursors ()
-{
- NS_LOG_FUNCTION (this);
- m_precursorList.clear ();
-}
-
-bool
-RoutingTableEntry::IsPrecursorListEmpty () const
-{
- return m_precursorList.empty ();
-}
-
-void
-RoutingTableEntry::GetPrecursors (std::vector<Ipv4Address> & prec) const
-{
- NS_LOG_FUNCTION (this);
- if (IsPrecursorListEmpty ())
- return;
- for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
- != m_precursorList.end (); ++i)
- {
- bool result = true;
- for (std::vector<Ipv4Address>::const_iterator j = prec.begin (); j
- != prec.end (); ++j)
- {
- if (*j == *i)
- result = false;
- }
- if (result)
- prec.push_back (*i);
- }
-}
-
-void
-RoutingTableEntry::Invalidate (Time badLinkLifetime)
-{
- NS_LOG_FUNCTION (this << badLinkLifetime.GetSeconds ());
- if (m_flag == INVALID)
- return;
- m_flag = INVALID;
- m_reqCount = 0;
- m_lifeTime = badLinkLifetime + Simulator::Now ();
-}
-
-void
-RoutingTableEntry::Print (Ptr<OutputStreamWrapper> stream) const
-{
- std::ostream* os = stream->GetStream();
- *os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
- << "\t" << m_iface.GetLocal () << "\t";
- switch (m_flag)
- {
- case VALID:
- {
- *os << "UP";
- break;
- }
- case INVALID:
- {
- *os << "DOWN";
- break;
- }
- case IN_SEARCH:
- {
- *os << "IN_SEARCH";
- break;
- }
- }
- *os << "\t";
- *os << std::setiosflags (std::ios::fixed) <<
- std::setiosflags (std::ios::left) << std::setprecision (2) <<
- std::setw (14) << (m_lifeTime - Simulator::Now ()).GetSeconds ();
- *os << "\t" << m_hops << "\n";
-}
-
-/*
- The Routing Table
- */
-
-RoutingTable::RoutingTable (Time t) :
- m_badLinkLifetime (t)
-{
-}
-
-bool
-RoutingTable::LookupRoute (Ipv4Address id, RoutingTableEntry & rt)
-{
- NS_LOG_FUNCTION (this << id);
- Purge ();
- if (m_ipv4AddressEntry.empty ())
- {
- NS_LOG_LOGIC ("Route to " << id << " not found; m_ipv4AddressEntry is empty");
- return false;
- }
- std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
- m_ipv4AddressEntry.find (id);
- if (i == m_ipv4AddressEntry.end ())
- {
- NS_LOG_LOGIC ("Route to " << id << " not found");
- return false;
- }
- rt = i->second;
- NS_LOG_LOGIC ("Route to " << id << " found");
- return true;
-}
-
-bool
-RoutingTable::LookupValidRoute (Ipv4Address id, RoutingTableEntry & rt)
-{
- NS_LOG_FUNCTION (this << id);
- if (! LookupRoute (id, rt))
- {
- NS_LOG_LOGIC ("Route to " << id << " not found");
- return false;
- }
- NS_LOG_LOGIC ("Route to " << id << " flag is " << ((rt.GetFlag () == VALID) ? "valid" : "not valid"));
- return (rt.GetFlag () == VALID);
-}
-
-bool
-RoutingTable::DeleteRoute (Ipv4Address dst)
-{
- NS_LOG_FUNCTION (this << dst);
- Purge ();
- if (m_ipv4AddressEntry.erase (dst) != 0)
- {
- NS_LOG_LOGIC ("Route deletion to " << dst << " successful");
- return true;
- }
- NS_LOG_LOGIC ("Route deletion to " << dst << " not successful");
- return false;
-}
-
-bool
-RoutingTable::AddRoute (RoutingTableEntry & rt)
-{
- NS_LOG_FUNCTION (this);
- Purge ();
- if (rt.GetFlag () != IN_SEARCH)
- rt.SetRreqCnt (0);
- std::pair<std::map<Ipv4Address, RoutingTableEntry>::iterator, bool> result =
- m_ipv4AddressEntry.insert (std::make_pair (rt.GetDestination (), rt));
- return result.second;
-}
-
-bool
-RoutingTable::Update (RoutingTableEntry & rt)
-{
- NS_LOG_FUNCTION (this);
- std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- m_ipv4AddressEntry.find (rt.GetDestination ());
- if (i == m_ipv4AddressEntry.end ())
- {
- NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " fails; not found");
- return false;
- }
- i->second = rt;
- if (i->second.GetFlag () != IN_SEARCH)
- {
- NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " set RreqCnt to 0");
- i->second.SetRreqCnt (0);
- }
- return true;
-}
-
-bool
-RoutingTable::SetEntryState (Ipv4Address id, RouteFlags state)
-{
- NS_LOG_FUNCTION (this);
- std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- m_ipv4AddressEntry.find (id);
- if (i == m_ipv4AddressEntry.end ())
- {
- NS_LOG_LOGIC ("Route set entry state to " << id << " fails; not found");
- return false;
- }
- i->second.SetFlag (state);
- i->second.SetRreqCnt (0);
- NS_LOG_LOGIC ("Route set entry state to " << id << ": new state is " << state);
- return true;
-}
-
-void
-RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
-{
- NS_LOG_FUNCTION (this);
- Purge ();
- unreachable.clear ();
- for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
- m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
- {
- if (i->second.GetNextHop () == nextHop)
- {
- NS_LOG_LOGIC ("Unreachable insert " << i->first << " " << i->second.GetSeqNo ());
- unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
- }
- }
-}
-
-void
-RoutingTable::InvalidateRoutesWithDst (const std::map<Ipv4Address, uint32_t> & unreachable)
-{
- NS_LOG_FUNCTION (this);
- Purge ();
- for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
- {
- for (std::map<Ipv4Address, uint32_t>::const_iterator j =
- unreachable.begin (); j != unreachable.end (); ++j)
- {
- if ((i->first == j->first) && (i->second.GetFlag () == VALID))
- {
- NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
- i->second.Invalidate (m_badLinkLifetime);
- }
- }
- }
-}
-
-void
-RoutingTable::DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface)
-{
- NS_LOG_FUNCTION (this);
- if (m_ipv4AddressEntry.empty ())
- return;
- for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
- {
- if (i->second.GetInterface () == iface)
- {
- std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
- ++i;
- m_ipv4AddressEntry.erase (tmp);
- }
- else
- ++i;
- }
-}
-
-void
-RoutingTable::Purge ()
-{
- NS_LOG_FUNCTION (this);
- if (m_ipv4AddressEntry.empty ())
- return;
- for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
- {
- if (i->second.GetLifeTime () < Seconds (0))
- {
- if (i->second.GetFlag () == INVALID)
- {
- std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
- ++i;
- m_ipv4AddressEntry.erase (tmp);
- }
- else if (i->second.GetFlag () == VALID)
- {
- NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
- i->second.Invalidate (m_badLinkLifetime);
- ++i;
- }
- else
- ++i;
- }
- else
- {
- ++i;
- }
- }
-}
-
-void
-RoutingTable::Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const
-{
- NS_LOG_FUNCTION (this);
- if (table.empty ())
- return;
- for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- table.begin (); i != table.end ();)
- {
- if (i->second.GetLifeTime () < Seconds (0))
- {
- if (i->second.GetFlag () == INVALID)
- {
- std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
- ++i;
- table.erase (tmp);
- }
- else if (i->second.GetFlag () == VALID)
- {
- NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
- i->second.Invalidate (m_badLinkLifetime);
- ++i;
- }
- else
- ++i;
- }
- else
- {
- ++i;
- }
- }
-}
-
-bool
-RoutingTable::MarkLinkAsUnidirectional (Ipv4Address neighbor, Time blacklistTimeout)
-{
- NS_LOG_FUNCTION (this << neighbor << blacklistTimeout.GetSeconds ());
- std::map<Ipv4Address, RoutingTableEntry>::iterator i =
- m_ipv4AddressEntry.find (neighbor);
- if (i == m_ipv4AddressEntry.end ())
- {
- NS_LOG_LOGIC ("Mark link unidirectional to " << neighbor << " fails; not found");
- return false;
- }
- i->second.SetUnidirectional (true);
- i->second.SetBalcklistTimeout (blacklistTimeout);
- i->second.SetRreqCnt (0);
- NS_LOG_LOGIC ("Set link to " << neighbor << " to unidirectional");
- return true;
-}
-
-void
-RoutingTable::Print (Ptr<OutputStreamWrapper> stream) const
-{
- std::map<Ipv4Address, RoutingTableEntry> table = m_ipv4AddressEntry;
- Purge (table);
- *stream->GetStream () << "\nAODV Routing table\n"
- << "Destination\tGateway\t\tInterface\tFlag\tExpire\t\tHops\n";
- for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
- table.begin (); i != table.end (); ++i)
- {
- i->second.Print (stream);
- }
- *stream->GetStream () << "\n";
-}
-
-}
-}
--- a/src/routing/aodv/aodv-rtable.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-#ifndef AODV_RTABLE_H
-#define AODV_RTABLE_H
-
-#include <stdint.h>
-#include <cassert>
-#include <map>
-#include <sys/types.h>
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/timer.h"
-#include "ns3/net-device.h"
-#include "ns3/output-stream-wrapper.h"
-
-namespace ns3 {
-namespace aodv {
-
-/**
- * \ingroup aodv
- * \brief Route record states
- */
-enum RouteFlags
-{
- VALID = 0, //!< VALID
- INVALID = 1, //!< INVALID
- IN_SEARCH = 2, //!< IN_SEARCH
-};
-
-/**
- * \ingroup aodv
- * \brief Routing table entry
- */
-class RoutingTableEntry
-{
-public:
- /// c-to
- RoutingTableEntry (Ptr<NetDevice> dev = 0,Ipv4Address dst = Ipv4Address(), bool vSeqNo = false, uint32_t m_seqNo = 0,
- Ipv4InterfaceAddress iface = Ipv4InterfaceAddress(), uint16_t hops = 0,
- Ipv4Address nextHop = Ipv4Address(), Time lifetime = Simulator::Now());
-
- ~RoutingTableEntry ();
-
- ///\name Precursors management
- //\{
- /**
- * Insert precursor in precursor list if it doesn't yet exist in the list
- * \param id precursor address
- * \return true on success
- */
- bool InsertPrecursor (Ipv4Address id);
- /**
- * Lookup precursor by address
- * \param id precursor address
- * \return true on success
- */
- bool LookupPrecursor (Ipv4Address id);
- /**
- * \brief Delete precursor
- * \param id precursor address
- * \return true on success
- */
- bool DeletePrecursor (Ipv4Address id);
- /// Delete all precursors
- void DeleteAllPrecursors ();
- /**
- * Check that precursor list empty
- * \return true if precursor list empty
- */
- bool IsPrecursorListEmpty () const;
- /**
- * Inserts precursors in vector prec if they does not yet exist in vector
- */
- void GetPrecursors (std::vector<Ipv4Address> & prec) const;
- //\}
-
- /// Mark entry as "down" (i.e. disable it)
- void Invalidate (Time badLinkLifetime);
- ///\name Fields
- //\{
- Ipv4Address GetDestination () const { return m_ipv4Route->GetDestination(); }
- Ptr<Ipv4Route> GetRoute () const { return m_ipv4Route; }
- void SetRoute (Ptr<Ipv4Route> r) { m_ipv4Route = r; }
- void SetNextHop (Ipv4Address nextHop) { m_ipv4Route->SetGateway(nextHop); }
- Ipv4Address GetNextHop () const { return m_ipv4Route->GetGateway(); }
- void SetOutputDevice (Ptr<NetDevice> dev) { m_ipv4Route->SetOutputDevice(dev); }
- Ptr<NetDevice> GetOutputDevice () const { return m_ipv4Route->GetOutputDevice(); }
- Ipv4InterfaceAddress GetInterface () const { return m_iface;}
- void SetInterface (Ipv4InterfaceAddress iface) { m_iface = iface; }
- void SetValidSeqNo (bool s) { m_validSeqNo = s; }
- bool GetValidSeqNo () const { return m_validSeqNo; }
- void SetSeqNo (uint32_t sn) { m_seqNo = sn; }
- uint32_t GetSeqNo () const { return m_seqNo; }
- void SetHop (uint16_t hop) { m_hops = hop; }
- uint16_t GetHop () const {return m_hops; }
- void SetLifeTime (Time lt) { m_lifeTime = lt + Simulator::Now(); }
- Time GetLifeTime () const { return m_lifeTime - Simulator::Now(); }
- void SetFlag (RouteFlags flag) { m_flag = flag; }
- RouteFlags GetFlag () const { return m_flag; }
- void SetRreqCnt (uint8_t n) { m_reqCount = n; }
- uint8_t GetRreqCnt () const { return m_reqCount; }
- void IncrementRreqCnt () { m_reqCount++; }
- void SetUnidirectional (bool u) { m_blackListState = u; }
- bool IsUnidirectional () const { return m_blackListState; }
- void SetBalcklistTimeout (Time t) { m_blackListTimeout = t; }
- Time GetBlacklistTimeout () const { return m_blackListTimeout; }
- /// RREP_ACK timer
- Timer m_ackTimer;
- //\}
-
- /**
- * \brief Compare destination address
- * \return true if equal
- */
- bool operator== (Ipv4Address const dst) const
- {
- return (m_ipv4Route->GetDestination () == dst);
- }
- void Print(Ptr<OutputStreamWrapper> stream) const;
-
-private:
- /// Valid Destination Sequence Number flag
- bool m_validSeqNo;
- /// Destination Sequence Number, if m_validSeqNo = true
- uint32_t m_seqNo;
- /// Hop Count (number of hops needed to reach destination)
- uint16_t m_hops;
- /**
- * \brief Expiration or deletion time of the route
- * Lifetime field in the routing table plays dual role --
- * for an active route it is the expiration time, and for an invalid route
- * it is the deletion time.
- */
- Time m_lifeTime;
- /** Ip route, include
- * - destination address
- * - source address
- * - next hop address (gateway)
- * - output device
- */
- Ptr<Ipv4Route> m_ipv4Route;
- /// Output interface address
- Ipv4InterfaceAddress m_iface;
- /// Routing flags: valid, invalid or in search
- RouteFlags m_flag;
-
- /// List of precursors
- std::vector<Ipv4Address> m_precursorList;
- /// When I can send another request
- Time m_routeRequestTimout;
- /// Number of route requests
- uint8_t m_reqCount;
- /// Indicate if this entry is in "blacklist"
- bool m_blackListState;
- /// Time for which the node is put into the blacklist
- Time m_blackListTimeout;
-};
-
-/**
- * \ingroup aodv
- * \brief The Routing table used by AODV protocol
- */
-class RoutingTable
-{
-public:
- /// c-tor
- RoutingTable (Time t);
- ///\name Handle life time of invalid route
- //\{
- Time GetBadLinkLifetime () const { return m_badLinkLifetime; }
- void SetBadLinkLifetime (Time t) { m_badLinkLifetime = t; }
- //\}
- /**
- * Add routing table entry if it doesn't yet exist in routing table
- * \param r routing table entry
- * \return true in success
- */
- bool AddRoute (RoutingTableEntry & r);
- /**
- * Delete routing table entry with destination address dst, if it exists.
- * \param dst destination address
- * \return true on success
- */
- bool DeleteRoute (Ipv4Address dst);
- /**
- * Lookup routing table entry with destination address dst
- * \param dst destination address
- * \param rt entry with destination address dst, if exists
- * \return true on success
- */
- bool LookupRoute (Ipv4Address dst, RoutingTableEntry & rt);
- /// Lookup route in VALID state
- bool LookupValidRoute (Ipv4Address dst, RoutingTableEntry & rt);
- /// Update routing table
- bool Update (RoutingTableEntry & rt);
- /// Set routing table entry flags
- bool SetEntryState (Ipv4Address dst, RouteFlags state);
- /// Lookup routing entries with next hop Address dst and not empty list of precursors.
- void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable);
- /**
- * Update routing entries with this destinations as follows:
- * 1. The destination sequence number of this routing entry, if it
- * exists and is valid, is incremented.
- * 2. The entry is invalidated by marking the route entry as invalid
- * 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
- */
- void InvalidateRoutesWithDst (std::map<Ipv4Address, uint32_t> const & unreachable);
- /// Delete all route from interface with address iface
- void DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface);
- /// Delete all entries from routing table
- void Clear () { m_ipv4AddressEntry.clear (); }
- /// Delete all outdated entries and invalidate valid entry if Lifetime is expired
- void Purge ();
- /** Mark entry as unidirectional (e.g. add this neighbor to "blacklist" for blacklistTimeout period)
- * \param neighbor - neighbor address link to which assumed to be unidirectional
- * \param blacklistTimeout - time for which the neighboring node is put into the blacklist
- * \return true on success
- */
- bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout);
- /// Print routing table
- void Print(Ptr<OutputStreamWrapper> stream) const;
-
-private:
- std::map<Ipv4Address, RoutingTableEntry> m_ipv4AddressEntry;
- /// Deletion time for invalid routes
- Time m_badLinkLifetime;
- /// const version of Purge, for use by Print() method
- void Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const;
-};
-
-}}
-
-#endif /* AODV_RTABLE_H */
--- a/src/routing/aodv/aodv-test-suite.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,541 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Pavel Boyko <boyko@iitp.ru>
- */
-#include "ns3/test.h"
-#include "aodv-neighbor.h"
-#include "aodv-packet.h"
-#include "aodv-rqueue.h"
-#include "aodv-rtable.h"
-#include "ns3/ipv4-route.h"
-
-namespace ns3
-{
-namespace aodv
-{
-
-/// Unit test for neighbors
-struct NeighborTest : public TestCase
-{
- NeighborTest () : TestCase ("Neighbor"), neighbor (0) { }
- virtual void DoRun ();
- void Handler (Ipv4Address addr);
- void CheckTimeout1 ();
- void CheckTimeout2 ();
- void CheckTimeout3 ();
- Neighbors * neighbor;
-};
-
-void
-NeighborTest::Handler (Ipv4Address addr)
-{
-}
-
-void
-NeighborTest::CheckTimeout1 ()
-{
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), true, "Neighbor exists");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), true, "Neighbor exists");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), true, "Neighbor exists");
-}
-void
-NeighborTest::CheckTimeout2 ()
-{
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), false, "Neighbor doesn't exist");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), false, "Neighbor doesn't exist");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), false, "Neighbor doesn't exist");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), true, "Neighbor exists");
-}
-void
-NeighborTest::CheckTimeout3 ()
-{
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), false, "Neighbor doesn't exist");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), false, "Neighbor doesn't exist");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), false, "Neighbor doesn't exist");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), false, "Neighbor doesn't exist");
-}
-
-void
-NeighborTest::DoRun ()
-{
- Neighbors nb (Seconds (1));
- neighbor = &nb;
- neighbor->SetCallback (MakeCallback (&NeighborTest::Handler, this));
- neighbor->Update (Ipv4Address ("1.2.3.4"), Seconds (1));
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("4.3.2.1")), false, "Neighbor doesn't exist");
- neighbor->Update (Ipv4Address ("1.2.3.4"), Seconds (10));
- NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
- NS_TEST_EXPECT_MSG_EQ (neighbor->GetExpireTime (Ipv4Address ("1.2.3.4")), Seconds (10), "Known expire time");
- NS_TEST_EXPECT_MSG_EQ (neighbor->GetExpireTime (Ipv4Address ("4.3.2.1")), Seconds (0), "Known expire time");
- neighbor->Update (Ipv4Address ("1.1.1.1"), Seconds (5));
- neighbor->Update (Ipv4Address ("2.2.2.2"), Seconds (10));
- neighbor->Update (Ipv4Address ("3.3.3.3"), Seconds (20));
-
- Simulator::Schedule (Seconds (2), &NeighborTest::CheckTimeout1, this);
- Simulator::Schedule (Seconds (15), &NeighborTest::CheckTimeout2, this);
- Simulator::Schedule (Seconds (30), &NeighborTest::CheckTimeout3, this);
- Simulator::Run ();
- Simulator::Destroy ();
- }
-//-----------------------------------------------------------------------------
-struct TypeHeaderTest : public TestCase
-{
- TypeHeaderTest () : TestCase ("AODV TypeHeader")
- {
- }
- virtual void DoRun ()
- {
- TypeHeader h (AODVTYPE_RREQ);
- NS_TEST_EXPECT_MSG_EQ (h.IsValid (), true, "Default header is valid");
- NS_TEST_EXPECT_MSG_EQ (h.Get (), AODVTYPE_RREQ, "Default header is RREQ");
-
- Ptr<Packet> p = Create<Packet> ();
- p->AddHeader (h);
- TypeHeader h2 (AODVTYPE_RREP);
- uint32_t bytes = p->RemoveHeader (h2);
- NS_TEST_EXPECT_MSG_EQ (bytes, 1, "Type header is 1 byte long");
- NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for RREQ
-struct RreqHeaderTest : public TestCase
-{
- RreqHeaderTest () : TestCase ("AODV RREQ")
- {
- }
- virtual void DoRun ()
- {
- RreqHeader h (/*flags*/0, /*reserved*/0, /*hopCount*/6, /*requestID*/1, /*dst*/Ipv4Address ("1.2.3.4"),
- /*dstSeqNo*/40, /*origin*/Ipv4Address ("4.3.2.1"), /*originSeqNo*/10);
- NS_TEST_EXPECT_MSG_EQ (h.GetGratiousRrep (), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetDestinationOnly (), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 6, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetId (), 1, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.2.3.4"), "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 40, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.3.2.1"), "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetOriginSeqno (), 10, "trivial");
-
- h.SetGratiousRrep (true);
- NS_TEST_EXPECT_MSG_EQ (h.GetGratiousRrep (), true, "trivial");
- h.SetDestinationOnly (true);
- NS_TEST_EXPECT_MSG_EQ (h.GetDestinationOnly (), true, "trivial");
- h.SetUnknownSeqno (true);
- NS_TEST_EXPECT_MSG_EQ (h.GetUnknownSeqno (), true, "trivial");
- h.SetDst (Ipv4Address ("1.1.1.1"));
- NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.1.1.1"), "trivial");
- h.SetDstSeqno (5);
- NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 5, "trivial");
- h.SetHopCount (7);
- NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 7, "trivial");
- h.SetId (55);
- NS_TEST_EXPECT_MSG_EQ (h.GetId (), 55, "trivial");
- h.SetOrigin (Ipv4Address ("4.4.4.4"));
- NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.4.4.4"), "trivial");
- h.SetOriginSeqno (23);
- NS_TEST_EXPECT_MSG_EQ (h.GetOriginSeqno (), 23, "trivial");
-
- Ptr<Packet> p = Create<Packet> ();
- p->AddHeader (h);
- RreqHeader h2;
- uint32_t bytes = p->RemoveHeader (h2);
- NS_TEST_EXPECT_MSG_EQ (bytes, 23, "RREP is 23 bytes long");
- NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
-
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for RREP
-struct RrepHeaderTest : public TestCase
-{
- RrepHeaderTest () : TestCase ("AODV RREP") {}
- virtual void DoRun ()
- {
- RrepHeader h (/*prefixSize*/0, /*hopCount*/12, /*dst*/Ipv4Address ("1.2.3.4"), /*dstSeqNo*/2,
- /*origin*/Ipv4Address ("4.3.2.1"), /*lifetime*/Seconds (3));
- NS_TEST_EXPECT_MSG_EQ (h.GetPrefixSize (), 0, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 12, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.2.3.4"), "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 2, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.3.2.1"), "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), Seconds (3), "trivial");
- h.SetDst (Ipv4Address ("1.1.1.1"));
- NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.1.1.1"), "trivial");
- h.SetDstSeqno (123);
- NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 123, "trivial");
- h.SetOrigin (Ipv4Address ("4.4.4.4"));
- NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.4.4.4"), "trivial");
- h.SetLifeTime (MilliSeconds (1200));
- NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), MilliSeconds (1200), "trivial");
- h.SetAckRequired (true);
- NS_TEST_EXPECT_MSG_EQ (h.GetAckRequired (), true, "trivial");
- h.SetAckRequired (false);
- NS_TEST_EXPECT_MSG_EQ (h.GetAckRequired (), false, "trivial");
- h.SetPrefixSize (2);
- NS_TEST_EXPECT_MSG_EQ (h.GetPrefixSize (), 2, "trivial");
- h.SetHopCount (15);
- NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 15, "trivial");
-
- h.SetHello (Ipv4Address ("10.0.0.2"), 9, Seconds (15));
- NS_TEST_EXPECT_MSG_EQ (h.GetDst (), h.GetOrigin (), "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 9, "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), Seconds (15), "trivial");
-
- Ptr<Packet> p = Create<Packet> ();
- p->AddHeader (h);
- RrepHeader h2;
- uint32_t bytes = p->RemoveHeader (h2);
- NS_TEST_EXPECT_MSG_EQ (bytes, 19, "RREP is 19 bytes long");
- NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for RREP-ACK
-struct RrepAckHeaderTest : public TestCase
-{
- RrepAckHeaderTest () : TestCase ("AODV RREP-ACK")
- {
- }
- virtual void DoRun()
- {
- RrepAckHeader h;
- Ptr<Packet> p = Create<Packet> ();
- p->AddHeader (h);
- RrepAckHeader h2;
- uint32_t bytes = p->RemoveHeader(h2);
- NS_TEST_EXPECT_MSG_EQ (bytes, 1, "ACK is 1 byte long");
- NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for RERR
-struct RerrHeaderTest : public TestCase
-{
- RerrHeaderTest () : TestCase ("AODV RERR")
- {
- }
- virtual void DoRun()
- {
- RerrHeader h;
- h.SetNoDelete(true);
- NS_TEST_EXPECT_MSG_EQ(h.GetNoDelete(), true, "trivial");
- Ipv4Address dst = Ipv4Address("1.2.3.4");
- NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst, 12), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ(h.GetDestCount(), 1, "trivial");
- NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst, 13), true, "trivial");
- Ipv4Address dst2 = Ipv4Address("4.3.2.1");
- NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst2, 12), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ(h.GetDestCount(), 2, "trivial");
-
- Ptr<Packet> p = Create<Packet> ();
- p->AddHeader (h);
- RerrHeader h2;
- uint32_t bytes = p->RemoveHeader(h2);
- NS_TEST_EXPECT_MSG_EQ (bytes, h.GetSerializedSize(), "(De)Serialized size match");
- NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for AODV routing table entry
-struct QueueEntryTest : public TestCase
-{
- QueueEntryTest () : TestCase ("QueueEntry") {}
- void Unicast (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
- void Error (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
- void Unicast2 (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
- void Error2 (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
- virtual void DoRun()
- {
- Ptr<const Packet> packet = Create<Packet> ();
- Ipv4Header h;
- h.SetDestination (Ipv4Address ("1.2.3.4"));
- h.SetSource (Ipv4Address ("4.3.2.1"));
- Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&QueueEntryTest::Unicast, this);
- Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&QueueEntryTest::Error, this);
- QueueEntry entry (packet, h, ucb, ecb, Seconds (1));
- NS_TEST_EXPECT_MSG_EQ (h.GetDestination (), entry.GetIpv4Header ().GetDestination (), "trivial");
- NS_TEST_EXPECT_MSG_EQ (h.GetSource (), entry.GetIpv4Header ().GetSource (), "trivial");
- NS_TEST_EXPECT_MSG_EQ (ucb.IsEqual(entry.GetUnicastForwardCallback ()), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (ecb.IsEqual(entry.GetErrorCallback ()), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (entry.GetExpireTime (), Seconds (1), "trivial");
- NS_TEST_EXPECT_MSG_EQ (entry.GetPacket (), packet, "trivial");
- entry.SetExpireTime (Seconds (3));
- NS_TEST_EXPECT_MSG_EQ (entry.GetExpireTime (), Seconds (3), "trivial");
- Ipv4Header h2;
- h2.SetDestination(Ipv4Address ("1.1.1.1"));
- entry.SetIpv4Header (h2);
- NS_TEST_EXPECT_MSG_EQ (entry.GetIpv4Header ().GetDestination (), Ipv4Address ("1.1.1.1"), "trivial");
- Ipv4RoutingProtocol::UnicastForwardCallback ucb2 = MakeCallback (&QueueEntryTest::Unicast2, this);
- Ipv4RoutingProtocol::ErrorCallback ecb2 = MakeCallback (&QueueEntryTest::Error2, this);
- entry.SetErrorCallback (ecb2);
- NS_TEST_EXPECT_MSG_EQ (ecb2.IsEqual (entry.GetErrorCallback ()), true, "trivial");
- entry.SetUnicastForwardCallback (ucb2);
- NS_TEST_EXPECT_MSG_EQ (ucb2.IsEqual (entry.GetUnicastForwardCallback ()), true, "trivial");
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for RequestQueue
-struct AodvRqueueTest : public TestCase
-{
- AodvRqueueTest () : TestCase ("Rqueue"), q (64, Seconds (30)) {}
- virtual void DoRun ();
- void Unicast (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
- void Error (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
- void CheckSizeLimit ();
- void CheckTimeout ();
-
- RequestQueue q;
-};
-
-void
-AodvRqueueTest::DoRun ()
-{
- NS_TEST_EXPECT_MSG_EQ (q.GetMaxQueueLen (), 64, "trivial");
- q.SetMaxQueueLen (32);
- NS_TEST_EXPECT_MSG_EQ (q.GetMaxQueueLen (), 32, "trivial");
- NS_TEST_EXPECT_MSG_EQ (q.GetQueueTimeout (), Seconds (30), "trivial");
- q.SetQueueTimeout (Seconds(10));
- NS_TEST_EXPECT_MSG_EQ (q.GetQueueTimeout (), Seconds (10), "trivial");
-
- Ptr<const Packet> packet = Create<Packet> ();
- Ipv4Header h;
- h.SetDestination (Ipv4Address ("1.2.3.4"));
- h.SetSource (Ipv4Address ("4.3.2.1"));
- Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&AodvRqueueTest::Unicast, this);
- Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&AodvRqueueTest::Error, this);
- QueueEntry e1 (packet, h, ucb, ecb, Seconds (1));
- q.Enqueue (e1);
- q.Enqueue (e1);
- q.Enqueue (e1);
- NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.2.3.4")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.1.1.1")), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 1, "trivial");
- q.DropPacketWithDst (Ipv4Address ("1.2.3.4"));
- NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.2.3.4")), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 0, "trivial");
-
- h.SetDestination (Ipv4Address ("2.2.2.2"));
- QueueEntry e2 (packet, h, ucb, ecb, Seconds (1));
- q.Enqueue (e1);
- q.Enqueue (e2);
- Ptr<Packet> packet2 = Create<Packet> ();
- QueueEntry e3 (packet2, h, ucb, ecb, Seconds (1));
- NS_TEST_EXPECT_MSG_EQ (q.Dequeue (Ipv4Address("3.3.3.3"), e3), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (q.Dequeue (Ipv4Address ("2.2.2.2"), e3), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("2.2.2.2")), false, "trivial");
- q.Enqueue (e2);
- q.Enqueue (e3);
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
- Ptr<Packet> packet4 = Create<Packet> ();
- h.SetDestination (Ipv4Address ("1.2.3.4"));
- QueueEntry e4 (packet4, h, ucb, ecb, Seconds (20));
- q.Enqueue (e4);
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 3, "trivial");
- q.DropPacketWithDst (Ipv4Address ("1.2.3.4"));
- NS_TEST_EXPECT_MSG_EQ (q.GetSize(), 1, "trivial");
-
- CheckSizeLimit ();
-
- Ipv4Header header2;
- Ipv4Address dst2 ("1.2.3.4");
- header2.SetDestination (dst2);
-
- Simulator::Schedule (q.GetQueueTimeout () + Seconds (1), &AodvRqueueTest::CheckTimeout, this);
-
- Simulator::Run ();
- Simulator::Destroy ();
-}
-
-void
-AodvRqueueTest::CheckSizeLimit ()
-{
- Ptr<Packet> packet = Create<Packet> ();
- Ipv4Header header;
- Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&AodvRqueueTest::Unicast, this);
- Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&AodvRqueueTest::Error, this);
- QueueEntry e1 (packet, header, ucb, ecb, Seconds (1));
-
- for (uint32_t i = 0; i < q.GetMaxQueueLen (); ++i)
- q.Enqueue (e1);
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
-
- for (uint32_t i = 0; i < q.GetMaxQueueLen (); ++i)
- q.Enqueue (e1);
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
-}
-
-void
-AodvRqueueTest::CheckTimeout ()
-{
- NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 0, "Must be empty now");
-}
-//-----------------------------------------------------------------------------
-/// Unit test for AODV routing table entry
-struct AodvRtableEntryTest : public TestCase
-{
- AodvRtableEntryTest () : TestCase ("RtableEntry") {}
- virtual void DoRun()
- {
- Ptr<NetDevice> dev;
- Ipv4InterfaceAddress iface;
- RoutingTableEntry rt (/*output device*/dev, /*dst*/Ipv4Address("1.2.3.4"), /*validSeqNo*/true, /*seqNo*/10,
- /*interface*/iface, /*hop*/5, /*next hop*/Ipv4Address("3.3.3.3"), /*lifetime*/Seconds(10));
- NS_TEST_EXPECT_MSG_EQ (rt.GetOutputDevice (), dev, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetDestination (), Ipv4Address ("1.2.3.4"), "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetValidSeqNo (), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetSeqNo (), 10, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetInterface (), iface, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetHop (), 5, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetNextHop (), Ipv4Address ("3.3.3.3"), "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (10), "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), VALID, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 0, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
-
- Ptr<NetDevice> dev2;
- Ipv4InterfaceAddress iface2;
- rt.SetOutputDevice (dev2);
- NS_TEST_EXPECT_MSG_EQ (rt.GetOutputDevice (), dev2, "trivial");
- rt.SetInterface (iface2);
- NS_TEST_EXPECT_MSG_EQ (rt.GetInterface (), iface2, "trivial");
- rt.SetValidSeqNo (false);
- NS_TEST_EXPECT_MSG_EQ (rt.GetValidSeqNo (), false, "trivial");
- rt.SetFlag (INVALID);
- NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
- rt.SetFlag (IN_SEARCH);
- NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), IN_SEARCH, "trivial");
- rt.SetHop (12);
- NS_TEST_EXPECT_MSG_EQ (rt.GetHop (), 12, "trivial");
- rt.SetLifeTime (Seconds (1));
- NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (1), "trivial");
- rt.SetNextHop (Ipv4Address ("1.1.1.1"));
- NS_TEST_EXPECT_MSG_EQ (rt.GetNextHop (), Ipv4Address ("1.1.1.1"), "trivial");
- rt.SetUnidirectional (true);
- NS_TEST_EXPECT_MSG_EQ (rt.IsUnidirectional (), true, "trivial");
- rt.SetBalcklistTimeout (Seconds (7));
- NS_TEST_EXPECT_MSG_EQ (rt.GetBlacklistTimeout (), Seconds (7), "trivial");
- rt.SetRreqCnt (2);
- NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 2, "trivial");
- rt.IncrementRreqCnt ();
- NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 3, "trivial");
- rt.Invalidate (Seconds (13));
- NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (13), "trivial");
- rt.SetLifeTime (MilliSeconds (100));
- NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), MilliSeconds (100), "trivial");
- Ptr<Ipv4Route> route = rt.GetRoute ();
- NS_TEST_EXPECT_MSG_EQ (route->GetDestination (), Ipv4Address ("1.2.3.4"), "trivial");
-
- NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.1")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.2")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.2")), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.3")), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.1")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.DeletePrecursor (Ipv4Address ("10.0.0.2")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.2")), false, "trivial");
- std::vector<Ipv4Address> prec;
- rt.GetPrecursors (prec);
- NS_TEST_EXPECT_MSG_EQ (prec.size (), 1, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.4")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.DeletePrecursor (Ipv4Address ("10.0.0.5")), false, "trivial");
- rt.GetPrecursors (prec);
- NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
- rt.DeleteAllPrecursors ();
- NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
- rt.GetPrecursors (prec);
- NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
- Simulator::Destroy ();
- }
-};
-//-----------------------------------------------------------------------------
-/// Unit test for AODV routing table
-struct AodvRtableTest : public TestCase
-{
- AodvRtableTest () : TestCase ("Rtable") {}
- virtual void DoRun()
- {
- RoutingTable rtable (Seconds (2));
- NS_TEST_EXPECT_MSG_EQ (rtable.GetBadLinkLifetime (), Seconds (2), "trivial");
- rtable.SetBadLinkLifetime (Seconds (1));
- NS_TEST_EXPECT_MSG_EQ (rtable.GetBadLinkLifetime (), Seconds (1), "trivial");
- Ptr<NetDevice> dev;
- Ipv4InterfaceAddress iface;
- RoutingTableEntry rt (/*output device*/dev, /*dst*/Ipv4Address("1.2.3.4"), /*validSeqNo*/true, /*seqNo*/10,
- /*interface*/iface, /*hop*/5, /*next hop*/Ipv4Address("1.1.1.1"), /*lifetime*/Seconds(10));
- NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt), false, "trivial");
- RoutingTableEntry rt2 (/*output device*/dev, /*dst*/Ipv4Address("4.3.2.1"), /*validSeqNo*/false, /*seqNo*/0,
- /*interface*/iface, /*hop*/15, /*next hop*/Ipv4Address("1.1.1.1"), /*lifetime*/Seconds(1));
- NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt2), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (rt2.GetDestination (), rt), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt2.GetDestination (), rt.GetDestination (), "trivial");
- rt.SetHop (20);
- rt.InsertPrecursor (Ipv4Address ("10.0.0.3"));
- NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt), true, "trivial");
- RoutingTableEntry rt3;
- NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("10.0.0.1"), rt), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt3), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("10.0.0.1"), INVALID), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("1.2.3.4"), IN_SEARCH), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("5.5.5.5")), false, "trivial");
- RoutingTableEntry rt4 (/*output device*/dev, /*dst*/Ipv4Address ("5.5.5.5"), /*validSeqNo*/false, /*seqNo*/0,
- /*interface*/iface, /*hop*/15, /*next hop*/Ipv4Address ("1.1.1.1"), /*lifetime*/Seconds (-10));
- NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt4), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("5.5.5.5"), INVALID), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("5.5.5.5"), rt), false, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.MarkLinkAsUnidirectional (Ipv4Address ("1.2.3.4"), Seconds (2)), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("1.2.3.4"), rt), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.IsUnidirectional (), true, "trivial");
- rt.SetLifeTime (Seconds (-5));
- NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt), true, "trivial");
- std::map<Ipv4Address, uint32_t> unreachable;
- rtable.GetListOfDestinationWithNextHop (Ipv4Address ("1.1.1.1"), unreachable);
- NS_TEST_EXPECT_MSG_EQ (unreachable.size (), 2, "trivial");
- unreachable.insert (std::make_pair (Ipv4Address ("4.3.2.1"), 3));
- rtable.InvalidateRoutesWithDst (unreachable);
- NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("4.3.2.1"), rt), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), true, "trivial");
- NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), false, "trivial");
- Simulator::Destroy ();
- }
-};
-//-----------------------------------------------------------------------------
-class AodvTestSuite : public TestSuite
-{
-public:
- AodvTestSuite () : TestSuite ("routing-aodv", UNIT)
- {
- AddTestCase (new NeighborTest);
- AddTestCase (new TypeHeaderTest);
- AddTestCase (new RreqHeaderTest);
- AddTestCase (new RrepHeaderTest);
- AddTestCase (new RrepAckHeaderTest);
- AddTestCase (new RerrHeaderTest);
- AddTestCase (new QueueEntryTest);
- AddTestCase (new AodvRqueueTest);
- AddTestCase (new AodvRtableEntryTest);
- AddTestCase (new AodvRtableTest);
- }
-} g_aodvTestSuite;
-
-}}
--- a/src/routing/aodv/aodv.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 IITP RAS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based on
- * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
- *
- * AODV-UU implementation by Erik Nordström of Uppsala University
- * http://core.it.uu.se/core/index.php/AODV-UU
- *
- * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#ifndef AODV_H
-#define AODV_H
-
-/**
- * \ingroup routing
- * \defgroup aodv AODV
- *
- * This model implements the base specification of the Ad hoc on demand distance vector (AODV)
- * protocol. Implementation is based on RFC3561.
- *
- * Class aodv::RoutingProtocol implements all functionality of service packet exchange and inherits Ipv4RoutingProtocol.
- * Base class defines two virtual functions for packet routing and forwarding. The first one,
- * RouteOutput(), is used for locally originated packets, and the second one, RouteInput(), is used for forwarding
- * and/or delivering received packets.
- *
- * Protocol operation depends on the many adjustable parameters. Parameters for this functionality are attributes of
- * aodv::RoutingProtocol. We support parameters, with their default values, from RFC and parameters that enable/disable
- * protocol features, such as broadcasting HELLO messages, broadcasting data packets and so on.
- *
- * AODV discovers routes on demand. Therefore, our AODV model buffer all packets, while a route request packet (RREQ)
- * is disseminated. We implement a packet queue in aodv-rqueue.cc. Smart pointer to packet, Ipv4RoutingProtocol::ErrorCallback,
- * Ipv4RoutingProtocol::UnicastForwardCallback and IP header are stored in this queue. The packet queue implements garbage collection of old
- * packets and a queue size limit.
- *
- * Routing table implementation support garbage collection of old entries and state machine, defined in standard.
- * It implements as a STL map container. The key is a destination IP address.
- *
- * Some moments of protocol operation aren't described in RFC. This moments generally concern cooperation of different OSI model layers.
- * We use following heuristics:
- *
- * 1) This AODV implementation can detect the presence of unidirectional links and avoid them if necessary.
- * If the node we received a RREQ for is a neighbor we are probably facing a unidirectional link...
- * This heuristic is taken from AODV-UU implementation and can be disabled.
- *
- * 2) Protocol operation strongly depends on broken link detection mechanism. We implements two such heuristics.
- * First, this implementation support HELLO messages. However HELLO messages are not a good way to do neighbor sensing
- * in a wireless environment (at least not over 802.11). Therefore, you may experience bad performance when running over wireless.
- * There are several reasons for this:
- * -# HELLO messages are broadcasted. In 802.11, broadcasting is done at a lower bit rate than unicasting,
- * thus HELLO messages travel further than data.
- * -# HELLO messages are small, thus less prone to bit errors than data transmissions.
- * -# Broadcast transmissions are not guaranteed to be bidirectional, unlike unicast transmissions.
- * Second, we use layer 2 feedback when possible. Link considered to be broken, if frame transmission results in a transmission
- * failure for all retries. This mechanism meant for active links and work much more faster, than first method.
- * Layer 2 feedback implementation relies on TxErrHeader trace source, currently it is supported in AdhocWifiMac only.
- *
- * 3) Duplicate packet detection. We use special class DuplicatePacketDetection for this purpose.
- *
- * Following optional protocol optimizations aren't implemented:
- * - Expanding ring search.
- * - Local link repair.
- * - RREP, RREQ and HELLO message extensions.
- * This techniques require direct access to IP header, which contradict assertion from AODV RFC that AODV works over UDP. Our model use UDP
- * for simplicity, but this disable us to implement protocol optimizations. We don't use low layer raw socket, because they are not portable.
- *
- */
-
-#endif /* AODV_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/doc/aodv.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,86 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#ifndef AODV_H
+#define AODV_H
+
+/**
+ * \ingroup routing
+ * \defgroup aodv AODV
+ *
+ * This model implements the base specification of the Ad hoc on demand distance vector (AODV)
+ * protocol. Implementation is based on RFC3561.
+ *
+ * Class aodv::RoutingProtocol implements all functionality of service packet exchange and inherits Ipv4RoutingProtocol.
+ * Base class defines two virtual functions for packet routing and forwarding. The first one,
+ * RouteOutput(), is used for locally originated packets, and the second one, RouteInput(), is used for forwarding
+ * and/or delivering received packets.
+ *
+ * Protocol operation depends on the many adjustable parameters. Parameters for this functionality are attributes of
+ * aodv::RoutingProtocol. We support parameters, with their default values, from RFC and parameters that enable/disable
+ * protocol features, such as broadcasting HELLO messages, broadcasting data packets and so on.
+ *
+ * AODV discovers routes on demand. Therefore, our AODV model buffer all packets, while a route request packet (RREQ)
+ * is disseminated. We implement a packet queue in aodv-rqueue.cc. Smart pointer to packet, Ipv4RoutingProtocol::ErrorCallback,
+ * Ipv4RoutingProtocol::UnicastForwardCallback and IP header are stored in this queue. The packet queue implements garbage collection of old
+ * packets and a queue size limit.
+ *
+ * Routing table implementation support garbage collection of old entries and state machine, defined in standard.
+ * It implements as a STL map container. The key is a destination IP address.
+ *
+ * Some moments of protocol operation aren't described in RFC. This moments generally concern cooperation of different OSI model layers.
+ * We use following heuristics:
+ *
+ * 1) This AODV implementation can detect the presence of unidirectional links and avoid them if necessary.
+ * If the node we received a RREQ for is a neighbor we are probably facing a unidirectional link...
+ * This heuristic is taken from AODV-UU implementation and can be disabled.
+ *
+ * 2) Protocol operation strongly depends on broken link detection mechanism. We implements two such heuristics.
+ * First, this implementation support HELLO messages. However HELLO messages are not a good way to do neighbor sensing
+ * in a wireless environment (at least not over 802.11). Therefore, you may experience bad performance when running over wireless.
+ * There are several reasons for this:
+ * -# HELLO messages are broadcasted. In 802.11, broadcasting is done at a lower bit rate than unicasting,
+ * thus HELLO messages travel further than data.
+ * -# HELLO messages are small, thus less prone to bit errors than data transmissions.
+ * -# Broadcast transmissions are not guaranteed to be bidirectional, unlike unicast transmissions.
+ * Second, we use layer 2 feedback when possible. Link considered to be broken, if frame transmission results in a transmission
+ * failure for all retries. This mechanism meant for active links and work much more faster, than first method.
+ * Layer 2 feedback implementation relies on TxErrHeader trace source, currently it is supported in AdhocWifiMac only.
+ *
+ * 3) Duplicate packet detection. We use special class DuplicatePacketDetection for this purpose.
+ *
+ * Following optional protocol optimizations aren't implemented:
+ * - Expanding ring search.
+ * - Local link repair.
+ * - RREP, RREQ and HELLO message extensions.
+ * This techniques require direct access to IP header, which contradict assertion from AODV RFC that AODV works over UDP. Our model use UDP
+ * for simplicity, but this disable us to implement protocol optimizations. We don't use low layer raw socket, because they are not portable.
+ *
+ */
+
+#endif /* AODV_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/examples/aodv.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,222 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This is an example script for AODV manet routing protocol.
+ *
+ * Authors: Pavel Boyko <boyko@iitp.ru>
+ */
+
+#include "ns3/aodv-module.h"
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/v4ping-helper.h"
+#include <iostream>
+#include <cmath>
+
+using namespace ns3;
+
+/**
+ * \brief Test script.
+ *
+ * This script creates 1-dimensional grid topology and then ping last node from the first one:
+ *
+ * [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.04]
+ *
+ * ping 10.0.0.4
+ */
+class AodvExample
+{
+public:
+ AodvExample ();
+ /// Configure script parameters, \return true on successful configuration
+ bool Configure (int argc, char **argv);
+ /// Run simulation
+ void Run ();
+ /// Report results
+ void Report (std::ostream & os);
+
+private:
+ ///\name parameters
+ //\{
+ /// Number of nodes
+ uint32_t size;
+ /// Distance between nodes, meters
+ double step;
+ /// Simulation time, seconds
+ double totalTime;
+ /// Write per-device PCAP traces if true
+ bool pcap;
+ /// Print routes if true
+ bool printRoutes;
+ //\}
+
+ ///\name network
+ //\{
+ NodeContainer nodes;
+ NetDeviceContainer devices;
+ Ipv4InterfaceContainer interfaces;
+ //\}
+
+private:
+ void CreateNodes ();
+ void CreateDevices ();
+ void InstallInternetStack ();
+ void InstallApplications ();
+};
+
+int main (int argc, char **argv)
+{
+ AodvExample test;
+ if (! test.Configure(argc, argv))
+ NS_FATAL_ERROR ("Configuration failed. Aborted.");
+
+ test.Run ();
+ test.Report (std::cout);
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+AodvExample::AodvExample () :
+ size (10),
+ step (100),
+ totalTime (10),
+ pcap (true),
+ printRoutes (true)
+{
+}
+
+bool
+AodvExample::Configure (int argc, char **argv)
+{
+ // Enable AODV logs by default. Comment this if too noisy
+ // LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
+
+ SeedManager::SetSeed(12345);
+ CommandLine cmd;
+
+ cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
+ cmd.AddValue ("printRoutes", "Print routing table dumps.", printRoutes);
+ cmd.AddValue ("size", "Number of nodes.", size);
+ cmd.AddValue ("time", "Simulation time, s.", totalTime);
+ cmd.AddValue ("step", "Grid step, m", step);
+
+ cmd.Parse (argc, argv);
+ return true;
+}
+
+void
+AodvExample::Run ()
+{
+// Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1)); // enable rts cts all the time.
+ CreateNodes ();
+ CreateDevices ();
+ InstallInternetStack ();
+ InstallApplications ();
+
+ std::cout << "Starting simulation for " << totalTime << " s ...\n";
+
+ Simulator::Stop (Seconds (totalTime));
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+
+void
+AodvExample::Report (std::ostream &)
+{
+}
+
+void
+AodvExample::CreateNodes ()
+{
+ std::cout << "Creating " << (unsigned)size << " nodes " << step << " m apart.\n";
+ nodes.Create (size);
+ // Name nodes
+ for (uint32_t i = 0; i < size; ++i)
+ {
+ std::ostringstream os;
+ os << "node-" << i;
+ Names::Add (os.str (), nodes.Get (i));
+ }
+ // Create static grid
+ MobilityHelper mobility;
+ mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
+ "MinX", DoubleValue (0.0),
+ "MinY", DoubleValue (0.0),
+ "DeltaX", DoubleValue (step),
+ "DeltaY", DoubleValue (0),
+ "GridWidth", UintegerValue (size),
+ "LayoutType", StringValue ("RowFirst"));
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (nodes);
+}
+
+void
+AodvExample::CreateDevices ()
+{
+ NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+ wifiMac.SetType ("ns3::AdhocWifiMac");
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+ YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+ wifiPhy.SetChannel (wifiChannel.Create ());
+ WifiHelper wifi = WifiHelper::Default ();
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("OfdmRate6Mbps"), "RtsCtsThreshold", UintegerValue (0));
+ devices = wifi.Install (wifiPhy, wifiMac, nodes);
+
+ if (pcap)
+ {
+ wifiPhy.EnablePcapAll (std::string ("aodv"));
+ }
+}
+
+void
+AodvExample::InstallInternetStack ()
+{
+ AodvHelper aodv;
+ // you can configure AODV attributes here using aodv.Set(name, value)
+ InternetStackHelper stack;
+ stack.SetRoutingHelper (aodv);
+ stack.Install (nodes);
+ Ipv4AddressHelper address;
+ address.SetBase ("10.0.0.0", "255.0.0.0");
+ interfaces = address.Assign (devices);
+
+ if (printRoutes)
+ {
+ Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("aodv.routes", std::ios::out);
+ aodv.PrintRoutingTableAllAt (Seconds (8), routingStream);
+ }
+}
+
+void
+AodvExample::InstallApplications ()
+{
+ V4PingHelper ping (interfaces.GetAddress (size - 1));
+ ping.SetAttribute ("Verbose", BooleanValue (true));
+
+ ApplicationContainer p = ping.Install (nodes.Get (0));
+ p.Start (Seconds (0));
+ p.Stop (Seconds (totalTime) - Seconds(0.001));
+
+ // move node away
+ Ptr<Node> node = nodes.Get (size/2);
+ Ptr<MobilityModel> mob = node->GetObject<MobilityModel> ();
+ Simulator::Schedule (Seconds (totalTime/3), &MobilityModel::SetPosition, mob, Vector (1e5, 1e5, 1e5));
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/examples/wscript Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,6 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('aodv',
+ ['wifi', 'internet', 'aodv'])
+ obj.source = 'aodv.cc'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/helper/aodv-helper.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,55 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Pavel Boyko <boyko@iitp.ru>, written after OlsrHelper by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "aodv-helper.h"
+#include "ns3/aodv-routing-protocol.h"
+#include "ns3/node-list.h"
+#include "ns3/names.h"
+#include "ns3/ipv4-list-routing.h"
+
+namespace ns3
+{
+
+AodvHelper::AodvHelper() :
+ Ipv4RoutingHelper ()
+{
+ m_agentFactory.SetTypeId ("ns3::aodv::RoutingProtocol");
+}
+
+AodvHelper*
+AodvHelper::Copy (void) const
+{
+ return new AodvHelper (*this);
+}
+
+Ptr<Ipv4RoutingProtocol>
+AodvHelper::Create (Ptr<Node> node) const
+{
+ Ptr<aodv::RoutingProtocol> agent = m_agentFactory.Create<aodv::RoutingProtocol> ();
+ node->AggregateObject (agent);
+ return agent;
+}
+
+void
+AodvHelper::Set (std::string name, const AttributeValue &value)
+{
+ m_agentFactory.Set (name, value);
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/helper/aodv-helper.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Pavel Boyko <boyko@iitp.ru>, written after OlsrHelper by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef AODVHELPER_H_
+#define AODVHELPER_H_
+
+#include "ns3/object-factory.h"
+#include "ns3/node.h"
+#include "ns3/node-container.h"
+#include "ns3/ipv4-routing-helper.h"
+
+namespace ns3
+{
+/**
+ * \ingroup aodv
+ * \brief Helper class that adds AODV routing to nodes.
+ */
+class AodvHelper : public Ipv4RoutingHelper
+{
+public:
+ AodvHelper();
+
+ /**
+ * \internal
+ * \returns pointer to clone of this OlsrHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ AodvHelper* Copy (void) const;
+
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ *
+ * TODO: support installing AODV on the subset of all available IP interfaces
+ */
+ virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+ /**
+ * \param name the name of the attribute to set
+ * \param value the value of the attribute to set.
+ *
+ * This method controls the attributes of ns3::aodv::RoutingProtocol
+ */
+ void Set (std::string name, const AttributeValue &value);
+
+private:
+ ObjectFactory m_agentFactory;
+};
+
+}
+#endif /* AODVHELPER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-dpd.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#include "aodv-dpd.h"
+
+namespace ns3
+{
+namespace aodv
+{
+
+bool
+DuplicatePacketDetection::IsDuplicate (Ptr<const Packet> p, const Ipv4Header & header)
+{
+ return m_idCache.IsDuplicate (header.GetSource (), p->GetUid() );
+}
+void
+DuplicatePacketDetection::SetLifetime (Time lifetime)
+{
+ m_idCache.SetLifetime(lifetime);
+}
+
+Time
+DuplicatePacketDetection::GetLifetime () const
+{
+ return m_idCache.GetLifeTime();
+}
+
+
+}
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-dpd.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#ifndef DUPLICATEPACKETDETECTION_H_
+#define DUPLICATEPACKETDETECTION_H_
+
+#include "aodv-id-cache.h"
+#include "ns3/nstime.h"
+#include "ns3/packet.h"
+#include "ns3/ipv4-header.h"
+
+namespace ns3
+{
+namespace aodv
+{
+/**
+ * \ingroup aodv
+ *
+ * \brief Helper class used to remember already seen packets and detect duplicates.
+ *
+ * Currently duplicate detection is based on uinique packet ID given by Packet::GetUid ()
+ * This approach is known to be weak and should be changed.
+ */
+class DuplicatePacketDetection
+{
+public:
+ /// C-tor
+ DuplicatePacketDetection (Time lifetime) : m_idCache(lifetime) {}
+ /// Check that the packet is duplicated. If not, save information about this packet.
+ bool IsDuplicate (Ptr<const Packet> p, const Ipv4Header & header);
+ /// Set duplicate records lifetimes
+ void SetLifetime (Time lifetime);
+ /// Get duplicate records lifetimes
+ Time GetLifetime () const;
+private:
+ /// Impl
+ IdCache m_idCache;
+};
+
+}
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-id-cache.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,129 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#include "aodv-id-cache.h"
+#include "ns3/test.h"
+#include <algorithm>
+
+namespace ns3
+{
+namespace aodv
+{
+bool
+IdCache::IsDuplicate (Ipv4Address addr, uint32_t id)
+{
+ Purge ();
+ for (std::vector<UniqueId>::const_iterator i = m_idCache.begin ();
+ i != m_idCache.end (); ++i)
+ if (i->m_context == addr && i->m_id == id)
+ return true;
+ struct UniqueId uniqueId =
+ { addr, id, m_lifetime + Simulator::Now () };
+ m_idCache.push_back (uniqueId);
+ return false;
+}
+void
+IdCache::Purge ()
+{
+ m_idCache.erase (remove_if (m_idCache.begin (), m_idCache.end (),
+ IsExpired ()), m_idCache.end ());
+}
+
+uint32_t
+IdCache::GetSize ()
+{
+ Purge ();
+ return m_idCache.size ();
+}
+
+//-----------------------------------------------------------------------------
+// Tests
+//-----------------------------------------------------------------------------
+/// Unit test for id cache
+struct IdCacheTest : public TestCase
+{
+ IdCacheTest () : TestCase ("Id Cache"), cache (Seconds(10))
+ {}
+ virtual void DoRun();
+ void CheckTimeout1 ();
+ void CheckTimeout2 ();
+ void CheckTimeout3 ();
+
+ IdCache cache;
+};
+
+void
+IdCacheTest::DoRun ()
+{
+ NS_TEST_EXPECT_MSG_EQ (cache.GetLifeTime(), Seconds(10), "Lifetime");
+ NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 3), false, "Unknown ID & address");
+ NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 4), false, "Unknown ID");
+ NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("4.3.2.1"), 3), false, "Unknown address");
+ NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 3), true, "Known address & ID");
+ cache.SetLifetime(Seconds(15));
+ NS_TEST_EXPECT_MSG_EQ (cache.GetLifeTime(), Seconds(15), "New lifetime");
+ cache.IsDuplicate (Ipv4Address ("1.1.1.1"), 4);
+ cache.IsDuplicate (Ipv4Address ("1.1.1.1"), 4);
+ cache.IsDuplicate (Ipv4Address ("2.2.2.2"), 5);
+ cache.IsDuplicate (Ipv4Address ("3.3.3.3"), 6);
+ NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 6, "trivial");
+
+ Simulator::Schedule (Seconds(5), &IdCacheTest::CheckTimeout1, this);
+ Simulator::Schedule (Seconds(11), &IdCacheTest::CheckTimeout2, this);
+ Simulator::Schedule (Seconds(30), &IdCacheTest::CheckTimeout3, this);
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+
+void
+IdCacheTest::CheckTimeout1 ()
+{
+ NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 6, "Nothing expire");
+}
+
+void
+IdCacheTest::CheckTimeout2 ()
+{
+ NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 3, "3 records left");
+}
+
+void
+IdCacheTest::CheckTimeout3 ()
+{
+ NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 0, "All records expire");
+}
+//-----------------------------------------------------------------------------
+class IdCacheTestSuite : public TestSuite
+{
+public:
+ IdCacheTestSuite () : TestSuite ("routing-id-cache", UNIT)
+ {
+ AddTestCase (new IdCacheTest);
+ }
+} g_idCacheTestSuite;
+
+}}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-id-cache.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,86 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#ifndef IDCACHE_H_
+#define IDCACHE_H_
+
+#include "ns3/ipv4-address.h"
+#include "ns3/simulator.h"
+#include <vector>
+
+namespace ns3
+{
+namespace aodv
+{
+/**
+ * \ingroup aodv
+ *
+ * \brief Unique packets identification cache used for simple duplicate detection.
+ */
+class IdCache
+{
+public:
+ /// c-tor
+ IdCache (Time lifetime): m_lifetime (lifetime) {}
+ /// Check that entry (addr, id) exists in cache. Add entry, if it doesn't exist.
+ bool IsDuplicate (Ipv4Address addr, uint32_t id);
+ /// Remove all expired entries
+ void Purge ();
+ /// Return number of entries in cache
+ uint32_t GetSize ();
+ /// Set lifetime for future added entries.
+ void SetLifetime (Time lifetime) { m_lifetime = lifetime; }
+ /// Return lifetime for existing entries in cache
+ Time GetLifeTime () const { return m_lifetime; }
+private:
+ /// Unique packet ID
+ struct UniqueId
+ {
+ /// ID is supposed to be unique in single address context (e.g. sender address)
+ Ipv4Address m_context;
+ /// The id
+ uint32_t m_id;
+ /// When record will expire
+ Time m_expire;
+ };
+ struct IsExpired
+ {
+ bool operator() (const struct UniqueId & u) const
+ {
+ return (u.m_expire < Simulator::Now ());
+ }
+ };
+ /// Already seen IDs
+ std::vector<UniqueId> m_idCache;
+ /// Default lifetime for ID records
+ Time m_lifetime;
+};
+
+}
+}
+#endif /* IDCACHE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-neighbor.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,173 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#include "aodv-neighbor.h"
+#include "ns3/log.h"
+#include <algorithm>
+
+NS_LOG_COMPONENT_DEFINE ("AodvNeighbors");
+
+namespace ns3
+{
+namespace aodv
+{
+Neighbors::Neighbors (Time delay) :
+ m_ntimer (Timer::CANCEL_ON_DESTROY)
+{
+ m_ntimer.SetDelay(delay);
+ m_ntimer.SetFunction(&Neighbors::Purge, this);
+ m_txErrorCallback = MakeCallback (& Neighbors::ProcessTxError, this);
+}
+
+bool
+Neighbors::IsNeighbor (Ipv4Address addr)
+{
+ Purge ();
+ for (std::vector<Neighbor>::const_iterator i = m_nb.begin ();
+ i != m_nb.end (); ++i)
+ {
+ if (i->m_neighborAddress == addr)
+ return true;
+ }
+ return false;
+}
+
+Time
+Neighbors::GetExpireTime (Ipv4Address addr)
+{
+ Purge ();
+ for (std::vector<Neighbor>::const_iterator i = m_nb.begin (); i
+ != m_nb.end (); ++i)
+ {
+ if (i->m_neighborAddress == addr)
+ return (i->m_expireTime - Simulator::Now ());
+ }
+ return Seconds (0);
+}
+
+void
+Neighbors::Update (Ipv4Address addr, Time expire)
+{
+ for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
+ if (i->m_neighborAddress == addr)
+ {
+ i->m_expireTime
+ = std::max (expire + Simulator::Now (), i->m_expireTime);
+ if (i->m_hardwareAddress == Mac48Address ())
+ i->m_hardwareAddress = LookupMacAddress (i->m_neighborAddress);
+ return;
+ }
+
+ NS_LOG_LOGIC ("Open link to " << addr);
+ Neighbor neighbor (addr, LookupMacAddress (addr), expire + Simulator::Now ());
+ m_nb.push_back (neighbor);
+ Purge ();
+}
+
+struct CloseNeighbor
+{
+ bool operator() (const Neighbors::Neighbor & nb) const
+ {
+ return ((nb.m_expireTime < Simulator::Now ()) || nb.close);
+ }
+};
+
+void
+Neighbors::Purge ()
+{
+ if (m_nb.empty ())
+ return;
+
+ CloseNeighbor pred;
+ if (!m_handleLinkFailure.IsNull ())
+ {
+ for (std::vector<Neighbor>::iterator j = m_nb.begin (); j != m_nb.end (); ++j)
+ {
+ if (pred (*j))
+ {
+ NS_LOG_LOGIC ("Close link to " << j->m_neighborAddress);
+ m_handleLinkFailure (j->m_neighborAddress);
+ }
+ }
+ }
+ m_nb.erase (std::remove_if (m_nb.begin (), m_nb.end (), pred), m_nb.end ());
+ m_ntimer.Cancel ();
+ m_ntimer.Schedule ();
+}
+
+void
+Neighbors::ScheduleTimer ()
+{
+ m_ntimer.Cancel ();
+ m_ntimer.Schedule ();
+}
+
+void
+Neighbors::AddArpCache (Ptr<ArpCache> a)
+{
+ m_arp.push_back (a);
+}
+
+void
+Neighbors::DelArpCache (Ptr<ArpCache> a)
+{
+ m_arp.erase (std::remove (m_arp.begin (), m_arp.end (), a), m_arp.end ());
+}
+
+Mac48Address
+Neighbors::LookupMacAddress (Ipv4Address addr)
+{
+ Mac48Address hwaddr;
+ for (std::vector<Ptr<ArpCache> >::const_iterator i = m_arp.begin ();
+ i != m_arp.end (); ++i)
+ {
+ ArpCache::Entry * entry = (*i)->Lookup (addr);
+ if (entry != 0 && entry->IsAlive () && !entry->IsExpired ())
+ {
+ hwaddr = Mac48Address::ConvertFrom (entry->GetMacAddress ());
+ break;
+ }
+ }
+ return hwaddr;
+}
+
+void
+Neighbors::ProcessTxError (WifiMacHeader const & hdr)
+{
+ Mac48Address addr = hdr.GetAddr1 ();
+
+ for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
+ {
+ if (i->m_hardwareAddress == addr)
+ i->close = true;
+ }
+ Purge ();
+}
+}
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-neighbor.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#ifndef AODVNEIGHBOR_H
+#define AODVNEIGHBOR_H
+
+#include "ns3/simulator.h"
+#include "ns3/timer.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/callback.h"
+#include "ns3/wifi-mac-header.h"
+#include "ns3/arp-cache.h"
+#include <vector>
+
+namespace ns3
+{
+namespace aodv
+{
+class RoutingProtocol;
+/**
+ * \ingroup aodv
+ * \brief maintain list of active neighbors
+ */
+class Neighbors
+{
+public:
+ /// c-tor
+ Neighbors (Time delay);
+ /// Neighbor description
+ struct Neighbor
+ {
+ Ipv4Address m_neighborAddress;
+ Mac48Address m_hardwareAddress;
+ Time m_expireTime;
+ bool close;
+
+ Neighbor (Ipv4Address ip, Mac48Address mac, Time t) :
+ m_neighborAddress (ip), m_hardwareAddress (mac), m_expireTime (t),
+ close (false)
+ {
+ }
+ };
+ /// Return expire time for neighbor node with address addr, if exists, else return 0.
+ Time GetExpireTime (Ipv4Address addr);
+ /// Check that node with address addr is neighbor
+ bool IsNeighbor (Ipv4Address addr);
+ /// Update expire time for entry with address addr, if it exists, else add new entry
+ void Update (Ipv4Address addr, Time expire);
+ /// Remove all expired entries
+ void Purge ();
+ /// Schedule m_ntimer.
+ void ScheduleTimer ();
+ /// Remove all entries
+ void Clear () { m_nb.clear (); }
+
+ /// Add ARP cache to be used to allow layer 2 notifications processing
+ void AddArpCache (Ptr<ArpCache>);
+ /// Don't use given ARP cache any more (interface is down)
+ void DelArpCache (Ptr<ArpCache>);
+ /// Get callback to ProcessTxError
+ Callback<void, WifiMacHeader const &> GetTxErrorCallback () const { return m_txErrorCallback; }
+
+ ///\name Handle link failure callback
+ //\{
+ void SetCallback (Callback<void, Ipv4Address> cb) { m_handleLinkFailure = cb;}
+ Callback<void, Ipv4Address> GetCallback () const { return m_handleLinkFailure; }
+ //\}
+private:
+ /// link failure callback
+ Callback<void, Ipv4Address> m_handleLinkFailure;
+ /// TX error callback
+ Callback<void, WifiMacHeader const &> m_txErrorCallback;
+ /// Timer for neighbor's list. Schedule Purge().
+ Timer m_ntimer;
+ /// vector of entries
+ std::vector<Neighbor> m_nb;
+ /// list of ARP cached to be used for layer 2 notifications processing
+ std::vector<Ptr<ArpCache> > m_arp;
+
+ /// Find MAC address by IP using list of ARP caches
+ Mac48Address LookupMacAddress (Ipv4Address);
+ /// Process layer 2 TX error notification
+ void ProcessTxError (WifiMacHeader const &);
+};
+
+}
+}
+
+#endif /* AODVNEIGHBOR_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-packet.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,638 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#include "aodv-packet.h"
+#include "ns3/address-utils.h"
+#include "ns3/packet.h"
+
+namespace ns3
+{
+namespace aodv
+{
+
+NS_OBJECT_ENSURE_REGISTERED (TypeHeader);
+
+TypeHeader::TypeHeader (MessageType t = AODVTYPE_RREQ) :
+ m_type (t), m_valid (true)
+{
+}
+
+TypeId
+TypeHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::aodv::TypeHeader")
+ .SetParent<Header> ()
+ .AddConstructor<TypeHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+TypeHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+TypeHeader::GetSerializedSize () const
+{
+ return 1;
+}
+
+void
+TypeHeader::Serialize (Buffer::Iterator i) const
+{
+ i.WriteU8 ((uint8_t) m_type);
+}
+
+uint32_t
+TypeHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t type = i.ReadU8 ();
+ m_valid = true;
+ switch (type)
+ {
+ case AODVTYPE_RREQ:
+ case AODVTYPE_RREP:
+ case AODVTYPE_RERR:
+ case AODVTYPE_RREP_ACK:
+ {
+ m_type = (MessageType) type;
+ break;
+ }
+ default:
+ m_valid = false;
+ }
+ uint32_t dist = i.GetDistanceFrom (start);
+ NS_ASSERT (dist == GetSerializedSize ());
+ return dist;
+}
+
+void
+TypeHeader::Print (std::ostream &os) const
+{
+ switch (m_type)
+ {
+ case AODVTYPE_RREQ:
+ {
+ os << "RREQ";
+ break;
+ }
+ case AODVTYPE_RREP:
+ {
+ os << "RREP";
+ break;
+ }
+ case AODVTYPE_RERR:
+ {
+ os << "RERR";
+ break;
+ }
+ case AODVTYPE_RREP_ACK:
+ {
+ os << "RREP_ACK";
+ break;
+ }
+ default:
+ os << "UNKNOWN_TYPE";
+ }
+}
+
+bool
+TypeHeader::operator== (TypeHeader const & o) const
+{
+ return (m_type == o.m_type && m_valid == o.m_valid);
+}
+
+std::ostream &
+operator<< (std::ostream & os, TypeHeader const & h)
+{
+ h.Print (os);
+ return os;
+}
+
+//-----------------------------------------------------------------------------
+// RREQ
+//-----------------------------------------------------------------------------
+RreqHeader::RreqHeader (uint8_t flags, uint8_t reserved, uint8_t hopCount, uint32_t requestID, Ipv4Address dst,
+ uint32_t dstSeqNo, Ipv4Address origin, uint32_t originSeqNo) :
+ m_flags (flags), m_reserved (reserved), m_hopCount (hopCount), m_requestID (requestID), m_dst(dst),
+ m_dstSeqNo (dstSeqNo), m_origin(origin), m_originSeqNo (originSeqNo)
+{
+}
+
+NS_OBJECT_ENSURE_REGISTERED (RreqHeader);
+
+TypeId
+RreqHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::aodv::RreqHeader")
+ .SetParent<Header> ()
+ .AddConstructor<RreqHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+RreqHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+RreqHeader::GetSerializedSize () const
+{
+ return 23;
+}
+
+void
+RreqHeader::Serialize (Buffer::Iterator i) const
+{
+ i.WriteU8 (m_flags);
+ i.WriteU8 (m_reserved);
+ i.WriteU8 (m_hopCount);
+ i.WriteHtonU32 (m_requestID);
+ WriteTo (i, m_dst);
+ i.WriteHtonU32 (m_dstSeqNo);
+ WriteTo (i, m_origin);
+ i.WriteHtonU32 (m_originSeqNo);
+}
+
+uint32_t
+RreqHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ m_flags = i.ReadU8 ();
+ m_reserved = i.ReadU8 ();
+ m_hopCount = i.ReadU8 ();
+ m_requestID = i.ReadNtohU32 ();
+ ReadFrom (i, m_dst);
+ m_dstSeqNo = i.ReadNtohU32 ();
+ ReadFrom (i, m_origin);
+ m_originSeqNo = i.ReadNtohU32 ();
+
+ uint32_t dist = i.GetDistanceFrom (start);
+ NS_ASSERT (dist == GetSerializedSize ());
+ return dist;
+}
+
+void
+RreqHeader::Print (std::ostream &os) const
+{
+ os << "RREQ ID " << m_requestID << " destination: ipv4 " << m_dst
+ << " sequence number " << m_dstSeqNo << " source: ipv4 "
+ << m_origin << " sequence number " << m_originSeqNo
+ << " flags:" << " Gratuitous RREP " << (*this).GetGratiousRrep ()
+ << " Destination only " << (*this).GetDestinationOnly ()
+ << " Unknown sequence number " << (*this).GetUnknownSeqno ();
+}
+
+std::ostream &
+operator<< (std::ostream & os, RreqHeader const & h)
+{
+ h.Print (os);
+ return os;
+}
+
+void
+RreqHeader::SetGratiousRrep (bool f)
+{
+ if (f)
+ m_flags |= (1 << 5);
+ else
+ m_flags &= ~(1 << 5);
+}
+
+bool
+RreqHeader::GetGratiousRrep () const
+{
+ return (m_flags & (1 << 5));
+}
+
+void
+RreqHeader::SetDestinationOnly (bool f)
+{
+ if (f)
+ m_flags |= (1 << 4);
+ else
+ m_flags &= ~(1 << 4);
+}
+
+bool
+RreqHeader::GetDestinationOnly () const
+{
+ return (m_flags & (1 << 4));
+}
+
+void
+RreqHeader::SetUnknownSeqno (bool f)
+{
+ if (f)
+ m_flags |= (1 << 3);
+ else
+ m_flags &= ~(1 << 3);
+}
+
+bool
+RreqHeader::GetUnknownSeqno () const
+{
+ return (m_flags & (1 << 3));
+}
+
+bool
+RreqHeader::operator== (RreqHeader const & o) const
+{
+ return (m_flags == o.m_flags && m_reserved == o.m_reserved &&
+ m_hopCount == o.m_hopCount && m_requestID == o.m_requestID &&
+ m_dst == o.m_dst && m_dstSeqNo == o.m_dstSeqNo &&
+ m_origin == o.m_origin && m_originSeqNo == o.m_originSeqNo);
+}
+
+//-----------------------------------------------------------------------------
+// RREP
+//-----------------------------------------------------------------------------
+
+RrepHeader::RrepHeader (uint8_t prefixSize, uint8_t hopCount, Ipv4Address dst,
+ uint32_t dstSeqNo, Ipv4Address origin, Time lifeTime) :
+ m_flags (0), m_prefixSize (prefixSize), m_hopCount (hopCount),
+ m_dst (dst), m_dstSeqNo (dstSeqNo), m_origin (origin)
+{
+ m_lifeTime = uint32_t (lifeTime.GetMilliSeconds ());
+}
+
+NS_OBJECT_ENSURE_REGISTERED (RrepHeader);
+
+TypeId
+RrepHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::aodv::RrepHeader")
+ .SetParent<Header> ()
+ .AddConstructor<RrepHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+RrepHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+RrepHeader::GetSerializedSize () const
+{
+ return 19;
+}
+
+void
+RrepHeader::Serialize (Buffer::Iterator i) const
+{
+ i.WriteU8 (m_flags);
+ i.WriteU8 (m_prefixSize);
+ i.WriteU8 (m_hopCount);
+ WriteTo (i, m_dst);
+ i.WriteHtonU32 (m_dstSeqNo);
+ WriteTo (i, m_origin);
+ i.WriteHtonU32 (m_lifeTime);
+}
+
+uint32_t
+RrepHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ m_flags = i.ReadU8 ();
+ m_prefixSize = i.ReadU8 ();
+ m_hopCount = i.ReadU8 ();
+ ReadFrom (i, m_dst);
+ m_dstSeqNo = i.ReadNtohU32 ();
+ ReadFrom (i, m_origin);
+ m_lifeTime = i.ReadNtohU32 ();
+
+ uint32_t dist = i.GetDistanceFrom (start);
+ NS_ASSERT (dist == GetSerializedSize ());
+ return dist;
+}
+
+void
+RrepHeader::Print (std::ostream &os) const
+{
+ os << "destination: ipv4 " << m_dst << " sequence number " << m_dstSeqNo;
+ if (m_prefixSize != 0)
+ {
+ os << " prefix size " << m_prefixSize;
+ }
+ os << " source ipv4 " << m_origin << " lifetime " << m_lifeTime
+ << " acknowledgment required flag " << (*this).GetAckRequired ();
+}
+
+void
+RrepHeader::SetLifeTime (Time t)
+{
+ m_lifeTime = t.GetMilliSeconds ();
+}
+
+Time
+RrepHeader::GetLifeTime () const
+{
+ Time t (MilliSeconds (m_lifeTime));
+ return t;
+}
+
+void
+RrepHeader::SetAckRequired (bool f)
+{
+ if (f)
+ m_flags |= (1 << 6);
+ else
+ m_flags &= ~(1 << 6);
+}
+
+bool
+RrepHeader::GetAckRequired () const
+{
+ return (m_flags & (1 << 6));
+}
+
+void
+RrepHeader::SetPrefixSize (uint8_t sz)
+{
+ m_prefixSize = sz;
+}
+
+uint8_t
+RrepHeader::GetPrefixSize () const
+{
+ return m_prefixSize;
+}
+
+bool
+RrepHeader::operator== (RrepHeader const & o) const
+{
+ return (m_flags == o.m_flags && m_prefixSize == o.m_prefixSize &&
+ m_hopCount == o.m_hopCount && m_dst == o.m_dst && m_dstSeqNo == o.m_dstSeqNo &&
+ m_origin == o.m_origin && m_lifeTime == o.m_lifeTime);
+}
+
+void
+RrepHeader::SetHello (Ipv4Address origin, uint32_t srcSeqNo, Time lifetime)
+{
+ m_flags = 0;
+ m_prefixSize = 0;
+ m_hopCount = 0;
+ m_dst = origin;
+ m_dstSeqNo = srcSeqNo;
+ m_origin = origin;
+ m_lifeTime = lifetime.GetMilliSeconds ();
+}
+
+std::ostream &
+operator<< (std::ostream & os, RrepHeader const & h)
+{
+ h.Print (os);
+ return os;
+}
+
+//-----------------------------------------------------------------------------
+// RREP-ACK
+//-----------------------------------------------------------------------------
+
+RrepAckHeader::RrepAckHeader () :
+ m_reserved (0)
+{
+}
+
+NS_OBJECT_ENSURE_REGISTERED (RrepAckHeader);
+TypeId
+RrepAckHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::aodv::RrepAckHeader")
+ .SetParent<Header> ()
+ .AddConstructor<RrepAckHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+RrepAckHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+RrepAckHeader::GetSerializedSize () const
+{
+ return 1;
+}
+
+void
+RrepAckHeader::Serialize (Buffer::Iterator i ) const
+{
+ i.WriteU8 (m_reserved);
+}
+
+uint32_t
+RrepAckHeader::Deserialize (Buffer::Iterator start )
+{
+ Buffer::Iterator i = start;
+ m_reserved = i.ReadU8 ();
+ uint32_t dist = i.GetDistanceFrom (start);
+ NS_ASSERT (dist == GetSerializedSize ());
+ return dist;
+}
+
+void
+RrepAckHeader::Print (std::ostream &os ) const
+{
+}
+
+bool
+RrepAckHeader::operator== (RrepAckHeader const & o ) const
+{
+ return m_reserved == o.m_reserved;
+}
+
+std::ostream &
+operator<< (std::ostream & os, RrepAckHeader const & h )
+{
+ h.Print (os);
+ return os;
+}
+
+//-----------------------------------------------------------------------------
+// RERR
+//-----------------------------------------------------------------------------
+RerrHeader::RerrHeader () :
+ m_flag (0), m_reserved (0)
+{
+}
+
+NS_OBJECT_ENSURE_REGISTERED (RerrHeader);
+
+TypeId
+RerrHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::aodv::RerrHeader")
+ .SetParent<Header> ()
+ .AddConstructor<RerrHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+RerrHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+RerrHeader::GetSerializedSize () const
+{
+ return (3 + 8 * GetDestCount ());
+}
+
+void
+RerrHeader::Serialize (Buffer::Iterator i ) const
+{
+ i.WriteU8 (m_flag);
+ i.WriteU8 (m_reserved);
+ i.WriteU8 (GetDestCount ());
+ std::map<Ipv4Address, uint32_t>::const_iterator j;
+ for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
+ {
+ WriteTo (i, (*j).first);
+ i.WriteHtonU32 ((*j).second);
+ }
+}
+
+uint32_t
+RerrHeader::Deserialize (Buffer::Iterator start )
+{
+ Buffer::Iterator i = start;
+ m_flag = i.ReadU8 ();
+ m_reserved = i.ReadU8 ();
+ uint8_t dest = i.ReadU8 ();
+ m_unreachableDstSeqNo.clear ();
+ Ipv4Address address;
+ uint32_t seqNo;
+ for (uint8_t k = 0; k < dest; ++k)
+ {
+ ReadFrom (i, address);
+ seqNo = i.ReadNtohU32 ();
+ m_unreachableDstSeqNo.insert (std::make_pair (address, seqNo));
+ }
+
+ uint32_t dist = i.GetDistanceFrom (start);
+ NS_ASSERT (dist == GetSerializedSize ());
+ return dist;
+}
+
+void
+RerrHeader::Print (std::ostream &os ) const
+{
+ os << "Unreachable destination (ipv4 address, seq. number):";
+ std::map<Ipv4Address, uint32_t>::const_iterator j;
+ for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
+ {
+ os << (*j).first << ", " << (*j).second;
+ }
+ os << "No delete flag " << (*this).GetNoDelete ();
+}
+
+void
+RerrHeader::SetNoDelete (bool f )
+{
+ if (f)
+ m_flag |= (1 << 0);
+ else
+ m_flag &= ~(1 << 0);
+}
+
+bool
+RerrHeader::GetNoDelete () const
+{
+ return (m_flag & (1 << 0));
+}
+
+bool
+RerrHeader::AddUnDestination (Ipv4Address dst, uint32_t seqNo )
+{
+ if (m_unreachableDstSeqNo.find (dst) != m_unreachableDstSeqNo.end ())
+ return true;
+
+ NS_ASSERT (GetDestCount() < 255); // can't support more than 255 destinations in single RERR
+ m_unreachableDstSeqNo.insert (std::make_pair (dst, seqNo));
+ return true;
+}
+
+bool
+RerrHeader::RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un )
+{
+ if (m_unreachableDstSeqNo.empty ())
+ return false;
+ std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.begin ();
+ un = *i;
+ m_unreachableDstSeqNo.erase (i);
+ return true;
+}
+
+void
+RerrHeader::Clear ()
+{
+ m_unreachableDstSeqNo.clear ();
+ m_flag = 0;
+ m_reserved = 0;
+}
+
+bool
+RerrHeader::operator== (RerrHeader const & o ) const
+{
+ if (m_flag != o.m_flag || m_reserved != o.m_reserved || GetDestCount () != o.GetDestCount ())
+ return false;
+
+ std::map<Ipv4Address, uint32_t>::const_iterator j = m_unreachableDstSeqNo.begin ();
+ std::map<Ipv4Address, uint32_t>::const_iterator k = o.m_unreachableDstSeqNo.begin ();
+ for (uint8_t i = 0; i < GetDestCount (); ++i)
+ {
+ if ((j->first != k->first) || (j->second != k->second))
+ return false;
+
+ j++;
+ k++;
+ }
+ return true;
+}
+
+std::ostream &
+operator<< (std::ostream & os, RerrHeader const & h )
+{
+ h.Print (os);
+ return os;
+}
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-packet.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,335 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#ifndef AODVPACKET_H
+#define AODVPACKET_H
+
+#include <iostream>
+#include "ns3/header.h"
+#include "ns3/enum.h"
+#include "ns3/ipv4-address.h"
+#include <map>
+#include "ns3/nstime.h"
+
+namespace ns3 {
+namespace aodv {
+
+enum MessageType
+{
+ AODVTYPE_RREQ = 1, //!< AODVTYPE_RREQ
+ AODVTYPE_RREP = 2, //!< AODVTYPE_RREP
+ AODVTYPE_RERR = 3, //!< AODVTYPE_RERR
+ AODVTYPE_RREP_ACK = 4 //!< AODVTYPE_RREP_ACK
+};
+
+/**
+* \ingroup aodv
+* \brief AODV types
+*/
+class TypeHeader : public Header
+{
+public:
+ /// c-tor
+ TypeHeader (MessageType t);
+
+ ///\name Header serialization/deserialization
+ //\{
+ static TypeId GetTypeId ();
+ TypeId GetInstanceTypeId () const;
+ uint32_t GetSerializedSize () const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+ void Print (std::ostream &os) const;
+ //\}
+
+ /// Return type
+ MessageType Get () const { return m_type; }
+ /// Check that type if valid
+ bool IsValid () const { return m_valid; }
+ bool operator== (TypeHeader const & o) const;
+private:
+ MessageType m_type;
+ bool m_valid;
+};
+
+std::ostream & operator<< (std::ostream & os, TypeHeader const & h);
+
+/**
+* \ingroup aodv
+* \brief Route Request (RREQ) Message Format
+ \verbatim
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type |J|R|G|D|U| Reserved | Hop Count |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | RREQ ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Destination IP Address |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Destination Sequence Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Originator IP Address |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Originator Sequence Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \endverbatim
+*/
+class RreqHeader : public Header
+{
+public:
+ /// c-tor
+ RreqHeader (uint8_t flags = 0, uint8_t reserved = 0, uint8_t hopCount = 0,
+ uint32_t requestID = 0, Ipv4Address dst = Ipv4Address (),
+ uint32_t dstSeqNo = 0, Ipv4Address origin = Ipv4Address (),
+ uint32_t originSeqNo = 0);
+
+ ///\name Header serialization/deserialization
+ //\{
+ static TypeId GetTypeId ();
+ TypeId GetInstanceTypeId () const;
+ uint32_t GetSerializedSize () const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+ void Print (std::ostream &os) const;
+ //\}
+
+ ///\name Fields
+ //\{
+ void SetHopCount (uint8_t count) { m_hopCount = count; }
+ uint8_t GetHopCount () const { return m_hopCount; }
+ void SetId (uint32_t id) { m_requestID = id; }
+ uint32_t GetId () const { return m_requestID; }
+ void SetDst (Ipv4Address a) { m_dst = a; }
+ Ipv4Address GetDst () const { return m_dst; }
+ void SetDstSeqno (uint32_t s) { m_dstSeqNo = s; }
+ uint32_t GetDstSeqno () const { return m_dstSeqNo; }
+ void SetOrigin (Ipv4Address a) { m_origin = a; }
+ Ipv4Address GetOrigin () const { return m_origin; }
+ void SetOriginSeqno (uint32_t s) { m_originSeqNo = s; }
+ uint32_t GetOriginSeqno () const { return m_originSeqNo; }
+ //\}
+
+ ///\name Flags
+ //\{
+ void SetGratiousRrep (bool f);
+ bool GetGratiousRrep () const;
+ void SetDestinationOnly (bool f);
+ bool GetDestinationOnly () const;
+ void SetUnknownSeqno (bool f);
+ bool GetUnknownSeqno () const;
+ //\}
+
+ bool operator== (RreqHeader const & o) const;
+private:
+ uint8_t m_flags; ///< |J|R|G|D|U| bit flags, see RFC
+ uint8_t m_reserved; ///< Not used
+ uint8_t m_hopCount; ///< Hop Count
+ uint32_t m_requestID; ///< RREQ ID
+ Ipv4Address m_dst; ///< Destination IP Address
+ uint32_t m_dstSeqNo; ///< Destination Sequence Number
+ Ipv4Address m_origin; ///< Originator IP Address
+ uint32_t m_originSeqNo; ///< Source Sequence Number
+};
+
+std::ostream & operator<< (std::ostream & os, RreqHeader const &);
+
+/**
+* \ingroup aodv
+* \brief Route Reply (RREP) Message Format
+ \verbatim
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type |R|A| Reserved |Prefix Sz| Hop Count |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Destination IP address |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Destination Sequence Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Originator IP address |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Lifetime |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \endverbatim
+*/
+class RrepHeader : public Header
+{
+public:
+ /// c-tor
+ RrepHeader (uint8_t prefixSize = 0, uint8_t hopCount = 0, Ipv4Address dst =
+ Ipv4Address (), uint32_t dstSeqNo = 0, Ipv4Address origin =
+ Ipv4Address (), Time lifetime = MilliSeconds (0));
+ ///\name Header serialization/deserialization
+ //\{
+ static TypeId GetTypeId ();
+ TypeId GetInstanceTypeId () const;
+ uint32_t GetSerializedSize () const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+ void Print (std::ostream &os) const;
+ //\}
+
+ ///\name Fields
+ //\{
+ void SetHopCount (uint8_t count) { m_hopCount = count; }
+ uint8_t GetHopCount () const { return m_hopCount; }
+ void SetDst (Ipv4Address a) { m_dst = a; }
+ Ipv4Address GetDst () const { return m_dst; }
+ void SetDstSeqno (uint32_t s) { m_dstSeqNo = s; }
+ uint32_t GetDstSeqno () const { return m_dstSeqNo; }
+ void SetOrigin (Ipv4Address a) { m_origin = a; }
+ Ipv4Address GetOrigin () const { return m_origin; }
+ void SetLifeTime (Time t);
+ Time GetLifeTime () const;
+ //\}
+
+ ///\name Flags
+ //\{
+ void SetAckRequired (bool f);
+ bool GetAckRequired () const;
+ void SetPrefixSize (uint8_t sz);
+ uint8_t GetPrefixSize () const;
+ //\}
+
+ /// Configure RREP to be a Hello message
+ void SetHello (Ipv4Address src, uint32_t srcSeqNo, Time lifetime);
+
+ bool operator== (RrepHeader const & o) const;
+private:
+ uint8_t m_flags; ///< A - acknowledgment required flag
+ uint8_t m_prefixSize; ///< Prefix Size
+ uint8_t m_hopCount; ///< Hop Count
+ Ipv4Address m_dst; ///< Destination IP Address
+ uint32_t m_dstSeqNo; ///< Destination Sequence Number
+ Ipv4Address m_origin; ///< Source IP Address
+ uint32_t m_lifeTime; ///< Lifetime (in milliseconds)
+};
+
+std::ostream & operator<< (std::ostream & os, RrepHeader const &);
+
+/**
+* \ingroup aodv
+* \brief Route Reply Acknowledgment (RREP-ACK) Message Format
+ \verbatim
+ 0 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Reserved |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \endverbatim
+*/
+class RrepAckHeader : public Header
+{
+public:
+ /// c-tor
+ RrepAckHeader ();
+
+ ///\name Header serialization/deserialization
+ //\{
+ static TypeId GetTypeId ();
+ TypeId GetInstanceTypeId () const;
+ uint32_t GetSerializedSize () const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+ void Print (std::ostream &os) const;
+ //\}
+
+ bool operator== (RrepAckHeader const & o) const;
+private:
+ uint8_t m_reserved;
+};
+std::ostream & operator<< (std::ostream & os, RrepAckHeader const &);
+
+
+/**
+* \ingroup aodv
+* \brief Route Error (RERR) Message Format
+ \verbatim
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type |N| Reserved | DestCount |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Unreachable Destination IP Address (1) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Unreachable Destination Sequence Number (1) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+ | Additional Unreachable Destination IP Addresses (if needed) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |Additional Unreachable Destination Sequence Numbers (if needed)|
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \endverbatim
+*/
+class RerrHeader : public Header
+{
+public:
+ /// c-tor
+ RerrHeader ();
+
+ ///\name Header serialization/deserialization
+ //\{
+ static TypeId GetTypeId ();
+ TypeId GetInstanceTypeId () const;
+ uint32_t GetSerializedSize () const;
+ void Serialize (Buffer::Iterator i) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+ void Print (std::ostream &os) const;
+ //\}
+
+ ///\name No delete flag
+ //\{
+ void SetNoDelete (bool f);
+ bool GetNoDelete () const;
+ //\}
+
+ /**
+ * Add unreachable node address and its sequence number in RERR header
+ *\return false if we already added maximum possible number of unreachable destinations
+ */
+ bool AddUnDestination (Ipv4Address dst, uint32_t seqNo);
+ /** Delete pair (address + sequence number) from REER header, if the number of unreachable destinations > 0
+ * \return true on success
+ */
+ bool RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un);
+ /// Clear header
+ void Clear();
+ /// Return number of unreachable destinations in RERR message
+ uint8_t GetDestCount () const { return (uint8_t)m_unreachableDstSeqNo.size(); }
+ bool operator== (RerrHeader const & o) const;
+private:
+ uint8_t m_flag; ///< No delete flag
+ uint8_t m_reserved; ///< Not used
+
+ /// List of Unreachable destination: IP addresses and sequence numbers
+ std::map<Ipv4Address, uint32_t> m_unreachableDstSeqNo;
+};
+
+std::ostream & operator<< (std::ostream & os, RerrHeader const &);
+}
+}
+#endif /* AODVPACKET_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-routing-protocol.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,1700 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#define NS_LOG_APPEND_CONTEXT \
+ if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
+
+#include "aodv-routing-protocol.h"
+#include "ns3/log.h"
+#include "ns3/boolean.h"
+#include "ns3/random-variable.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/udp-socket-factory.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/adhoc-wifi-mac.h"
+#include <algorithm>
+#include <limits>
+
+NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
+
+namespace ns3
+{
+namespace aodv
+{
+NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
+
+/// UDP Port for AODV control traffic
+const uint32_t RoutingProtocol::AODV_PORT = 654;
+
+//-----------------------------------------------------------------------------
+/// Tag used by AODV implementation
+struct DeferredRouteOutputTag : public Tag
+{
+ /// Positive if output device is fixed in RouteOutput
+ int32_t oif;
+
+ DeferredRouteOutputTag (int32_t o = -1) : Tag(), oif (o) {}
+
+ static TypeId GetTypeId ()
+ {
+ static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag").SetParent<Tag> ();
+ return tid;
+ }
+
+ TypeId GetInstanceTypeId () const
+ {
+ return GetTypeId ();
+ }
+
+ uint32_t GetSerializedSize () const
+ {
+ return sizeof(int32_t);
+ }
+
+ void Serialize (TagBuffer i) const
+ {
+ i.WriteU32 (oif);
+ }
+
+ void Deserialize (TagBuffer i)
+ {
+ oif = i.ReadU32 ();
+ }
+
+ void Print (std::ostream &os) const
+ {
+ os << "DeferredRouteOutputTag: output interface = " << oif;
+ }
+};
+
+//-----------------------------------------------------------------------------
+RoutingProtocol::RoutingProtocol () :
+ RreqRetries (2),
+ RreqRateLimit (10),
+ ActiveRouteTimeout (Seconds (3)),
+ NetDiameter (35),
+ NodeTraversalTime (MilliSeconds (40)),
+ NetTraversalTime (Scalar (2 * NetDiameter) * NodeTraversalTime),
+ PathDiscoveryTime ( Scalar (2) * NetTraversalTime),
+ MyRouteTimeout (Scalar (2) * std::max (PathDiscoveryTime, ActiveRouteTimeout)),
+ HelloInterval(Seconds (1)),
+ AllowedHelloLoss (2),
+ DeletePeriod (Scalar(5) * std::max(ActiveRouteTimeout, HelloInterval)),
+ NextHopWait (NodeTraversalTime + MilliSeconds (10)),
+ TimeoutBuffer (2),
+ BlackListTimeout(Scalar (RreqRetries) * NetTraversalTime),
+ MaxQueueLen (64),
+ MaxQueueTime (Seconds(30)),
+ DestinationOnly (false),
+ GratuitousReply (true),
+ EnableHello (true),
+ m_routingTable (DeletePeriod),
+ m_queue (MaxQueueLen, MaxQueueTime),
+ m_requestId (0),
+ m_seqNo (0),
+ m_rreqIdCache (PathDiscoveryTime),
+ m_dpd (PathDiscoveryTime),
+ m_nb(HelloInterval),
+ m_rreqCount (0),
+ m_htimer (Timer::CANCEL_ON_DESTROY),
+ m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY)
+{
+ if (EnableHello)
+ {
+ m_nb.SetCallback (MakeCallback (&RoutingProtocol::SendRerrWhenBreaksLinkToNextHop, this));
+ }
+}
+
+TypeId
+RoutingProtocol::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
+ .SetParent<Ipv4RoutingProtocol> ()
+ .AddConstructor<RoutingProtocol> ()
+ .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
+ TimeValue (Seconds (1)),
+ MakeTimeAccessor (&RoutingProtocol::HelloInterval),
+ MakeTimeChecker ())
+ .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
+ UintegerValue (2),
+ MakeUintegerAccessor (&RoutingProtocol::RreqRetries),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
+ UintegerValue (10),
+ MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
+ "queuing delays, interrupt processing times and transfer times.",
+ TimeValue (MilliSeconds (40)),
+ MakeTimeAccessor (&RoutingProtocol::NodeTraversalTime),
+ MakeTimeChecker ())
+ .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
+ TimeValue (MilliSeconds (50)),
+ MakeTimeAccessor (&RoutingProtocol::NextHopWait),
+ MakeTimeChecker ())
+ .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
+ TimeValue (Seconds (3)),
+ MakeTimeAccessor (&RoutingProtocol::ActiveRouteTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
+ TimeValue (Seconds (11.2)),
+ MakeTimeAccessor (&RoutingProtocol::MyRouteTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
+ TimeValue (Seconds (5.6)),
+ MakeTimeAccessor (&RoutingProtocol::BlackListTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
+ "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
+ " = 5 * max (HelloInterval, ActiveRouteTimeout)",
+ TimeValue (Seconds (15)),
+ MakeTimeAccessor (&RoutingProtocol::DeletePeriod),
+ MakeTimeChecker ())
+ .AddAttribute ("TimeoutBuffer", "Its purpose is to provide a buffer for the timeout so that if the RREP is delayed"
+ " due to congestion, a timeout is less likely to occur while the RREP is still en route back to the source.",
+ UintegerValue (2),
+ MakeUintegerAccessor (&RoutingProtocol::TimeoutBuffer),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
+ UintegerValue (35),
+ MakeUintegerAccessor (&RoutingProtocol::NetDiameter),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
+ TimeValue (Seconds (2.8)),
+ MakeTimeAccessor (&RoutingProtocol::NetTraversalTime),
+ MakeTimeChecker ())
+ .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
+ TimeValue (Seconds (5.6)),
+ MakeTimeAccessor (&RoutingProtocol::PathDiscoveryTime),
+ MakeTimeChecker ())
+ .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
+ UintegerValue (64),
+ MakeUintegerAccessor (&RoutingProtocol::SetMaxQueueLen,
+ &RoutingProtocol::GetMaxQueueLen),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
+ TimeValue (Seconds (30)),
+ MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
+ &RoutingProtocol::GetMaxQueueTime),
+ MakeTimeChecker ())
+ .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
+ UintegerValue (2),
+ MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
+ BooleanValue (true),
+ MakeBooleanAccessor (&RoutingProtocol::SetGratuitousReplyFlag,
+ &RoutingProtocol::GetGratuitousReplyFlag),
+ MakeBooleanChecker ())
+ .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
+ BooleanValue (false),
+ MakeBooleanAccessor (&RoutingProtocol::SetDesinationOnlyFlag,
+ &RoutingProtocol::GetDesinationOnlyFlag),
+ MakeBooleanChecker ())
+ .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
+ BooleanValue (true),
+ MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
+ &RoutingProtocol::GetHelloEnable),
+ MakeBooleanChecker ())
+ .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
+ BooleanValue (true),
+ MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
+ &RoutingProtocol::GetBroadcastEnable),
+ MakeBooleanChecker ())
+ ;
+ return tid;
+}
+
+void
+RoutingProtocol::SetMaxQueueLen (uint32_t len)
+{
+ MaxQueueLen = len;
+ m_queue.SetMaxQueueLen (len);
+}
+void
+RoutingProtocol::SetMaxQueueTime (Time t)
+{
+ MaxQueueTime = t;
+ m_queue.SetQueueTimeout (t);
+}
+
+RoutingProtocol::~RoutingProtocol ()
+{
+}
+
+void
+RoutingProtocol::DoDispose ()
+{
+ m_ipv4 = 0;
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::iterator iter =
+ m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
+ {
+ iter->first->Close ();
+ }
+ m_socketAddresses.clear ();
+ Ipv4RoutingProtocol::DoDispose ();
+}
+
+void
+RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+ *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now().GetSeconds () << "s ";
+ m_routingTable.Print (stream);
+}
+
+void
+RoutingProtocol::Start ()
+{
+ NS_LOG_FUNCTION (this);
+ if (EnableHello)
+ {
+ m_nb.ScheduleTimer ();
+ }
+ m_rreqRateLimitTimer.SetFunction (&RoutingProtocol::RreqRateLimitTimerExpire,
+ this);
+ m_rreqRateLimitTimer.Schedule (Seconds (1));
+}
+
+Ptr<Ipv4Route>
+RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
+ Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header << (oif? oif->GetIfIndex () : 0));
+ if (! p)
+ {
+ return LoopbackRoute (header, oif); // later
+ }
+ if (m_socketAddresses.empty ())
+ {
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ NS_LOG_LOGIC ("No aodv interfaces");
+ Ptr<Ipv4Route> route;
+ return route;
+ }
+ sockerr = Socket::ERROR_NOTERROR;
+ Ptr<Ipv4Route> route;
+ Ipv4Address dst = header.GetDestination ();
+ RoutingTableEntry rt;
+ if (m_routingTable.LookupValidRoute (dst, rt))
+ {
+ route = rt.GetRoute ();
+ NS_ASSERT (route != 0);
+ NS_LOG_DEBUG ("Exist route to " << route->GetDestination() << " from interface " << route->GetSource());
+ if (oif != 0 && route->GetOutputDevice () != oif)
+ {
+ NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ return Ptr<Ipv4Route> ();
+ }
+ UpdateRouteLifeTime (dst, ActiveRouteTimeout);
+ UpdateRouteLifeTime (route->GetGateway (), ActiveRouteTimeout);
+ return route;
+ }
+
+ // Valid route not found, in this case we return loopback.
+ // Actual route request will be deferred until packet will be fully formed,
+ // routed to loopback, received from loopback and passed to RouteInput (see below)
+ uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
+ DeferredRouteOutputTag tag (iif);
+ if (! p->PeekPacketTag (tag))
+ {
+ p->AddPacketTag (tag);
+ }
+ return LoopbackRoute (header, oif);
+}
+
+void
+RoutingProtocol::DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header & header,
+ UnicastForwardCallback ucb, ErrorCallback ecb)
+{
+ NS_LOG_FUNCTION (this << p << header);
+ NS_ASSERT (p != 0 && p != Ptr<Packet> ());
+
+ QueueEntry newEntry (p, header, ucb, ecb);
+ bool result = m_queue.Enqueue (newEntry);
+ if (result)
+ {
+ NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
+ RoutingTableEntry rt;
+ bool result = m_routingTable.LookupRoute(header.GetDestination (), rt);
+ if(!result || ((rt.GetFlag() != IN_SEARCH) && result))
+ {
+ NS_LOG_LOGIC ("Send RREQ to" <<header.GetDestination ());
+ SendRequest (header.GetDestination ());
+ }
+ }
+}
+
+bool
+RoutingProtocol::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->GetUid() << header.GetDestination() << idev->GetAddress());
+ if (m_socketAddresses.empty ())
+ {
+ NS_LOG_LOGIC ("No aodv interfaces");
+ return false;
+ }
+ NS_ASSERT (m_ipv4 != 0);
+ NS_ASSERT (p != 0);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+ int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
+
+ Ipv4Address dst = header.GetDestination ();
+ Ipv4Address origin = header.GetSource ();
+
+ // Deferred route request
+ if (idev == m_lo)
+ {
+ DeferredRouteOutputTag tag;
+ if (p->PeekPacketTag (tag))
+ {
+ DeferredRouteOutput (p, header, ucb, ecb);
+ return true;
+ }
+ }
+
+ // Duplicate of own packet
+ if (IsMyOwnAddress (origin))
+ return true;
+
+ // Broadcast local delivery/forwarding
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
+ m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ipv4InterfaceAddress iface = j->second;
+ if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
+ if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
+ {
+ if (m_dpd.IsDuplicate (p, header))
+ {
+ NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
+ return true;
+ }
+ UpdateRouteLifeTime (origin, ActiveRouteTimeout);
+ NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
+ Ptr<Packet> packet = p->Copy ();
+ lcb (p, header, iif);
+ if (!EnableBroadcast)
+ {
+ return true;
+ }
+ if (header.GetTtl () > 1)
+ {
+ NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
+ RoutingTableEntry toBroadcast;
+ if (m_routingTable.LookupRoute (dst, toBroadcast))
+ {
+ Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
+ ucb (route, packet, header);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
+ }
+ }
+ else
+ {
+ NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
+ }
+ return true;
+ }
+ }
+
+ // Unicast local delivery
+ if (m_ipv4->IsDestinationAddress (dst, iif))
+ {
+ UpdateRouteLifeTime (origin, ActiveRouteTimeout);
+ RoutingTableEntry toOrigin;
+ if (m_routingTable.LookupValidRoute (origin, toOrigin))
+ {
+ UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
+ m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
+ }
+ NS_LOG_LOGIC ("Unicast local delivery to " << dst);
+ lcb (p, header, iif);
+ return true;
+ }
+
+ // Forwarding
+ return Forwarding (p, header, ucb, ecb);
+}
+
+bool
+RoutingProtocol::Forwarding (Ptr<const Packet> p, const Ipv4Header & header,
+ UnicastForwardCallback ucb, ErrorCallback ecb)
+{
+ NS_LOG_FUNCTION (this);
+ Ipv4Address dst = header.GetDestination ();
+ Ipv4Address origin = header.GetSource ();
+ m_routingTable.Purge ();
+ RoutingTableEntry toDst;
+ if (m_routingTable.LookupRoute (dst, toDst))
+ {
+ if (toDst.GetFlag () == VALID)
+ {
+ Ptr<Ipv4Route> route = toDst.GetRoute ();
+ NS_LOG_LOGIC (route->GetSource()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
+
+ /*
+ * Each time a route is used to forward a data packet, its Active Route
+ * Lifetime field of the source, destination and the next hop on the
+ * path to the destination is updated to be no less than the current
+ * time plus ActiveRouteTimeout.
+ */
+ UpdateRouteLifeTime (origin, ActiveRouteTimeout);
+ UpdateRouteLifeTime (dst, ActiveRouteTimeout);
+ UpdateRouteLifeTime (route->GetGateway (), ActiveRouteTimeout);
+ /*
+ * Since the route between each originator and destination pair is expected to be symmetric, the
+ * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
+ * to be no less than the current time plus ActiveRouteTimeout
+ */
+ RoutingTableEntry toOrigin;
+ m_routingTable.LookupRoute (origin, toOrigin);
+ UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
+
+ m_nb.Update (route->GetGateway (), ActiveRouteTimeout);
+ m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
+
+ ucb (route, p, header);
+ return true;
+ }
+ else
+ {
+ if (toDst.GetValidSeqNo ())
+ {
+ SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
+ NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
+ return false;
+ }
+ }
+ }
+ NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
+ NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
+ SendRerrWhenNoRouteToForward (dst, 0, origin);
+ return false;
+}
+
+void
+RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+ NS_ASSERT (ipv4 != 0);
+ NS_ASSERT (m_ipv4 == 0);
+
+ if (EnableHello)
+ {
+ m_htimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this);
+ m_htimer.Schedule (MilliSeconds (UniformVariable ().GetInteger (0, 100)));
+ }
+
+ m_ipv4 = ipv4;
+
+ // Create lo route. It is asserted that the only one interface up for now is loopback
+ NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
+ m_lo = m_ipv4->GetNetDevice (0);
+ NS_ASSERT (m_lo != 0);
+ // Remember lo route
+ RoutingTableEntry rt (/*device=*/m_lo, /*dst=*/Ipv4Address::GetLoopback (), /*know seqno=*/true, /*seqno=*/0,
+ /*iface=*/Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
+ /*hops=*/1, /*next hop=*/Ipv4Address::GetLoopback (),
+ /*lifetime=*/Simulator::GetMaximumSimulationTime ());
+ m_routingTable.AddRoute (rt);
+
+ Simulator::ScheduleNow (&RoutingProtocol::Start, this);
+}
+
+void
+RoutingProtocol::NotifyInterfaceUp (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
+ Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
+ if (l3->GetNAddresses (i) > 1)
+ {
+ NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
+ }
+ Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
+ if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
+ return;
+
+ // Create a socket to listen only on this interface
+ Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
+ UdpSocketFactory::GetTypeId ());
+ NS_ASSERT (socket != 0);
+ socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
+ socket->BindToNetDevice (l3->GetNetDevice (i));
+ socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT));
+ socket->SetAllowBroadcast (true);
+ socket->SetAttribute ("IpTtl", UintegerValue (1));
+ m_socketAddresses.insert (std::make_pair (socket, iface));
+
+ // Add local broadcast record to the routing table
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
+ RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true, /*seqno=*/0, /*iface=*/iface,
+ /*hops=*/1, /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Simulator::GetMaximumSimulationTime ());
+ m_routingTable.AddRoute (rt);
+
+ // Allow neighbor manager use this interface for layer 2 feedback if possible
+ Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
+ if (wifi == 0)
+ return;
+ Ptr<WifiMac> mac = wifi->GetMac ();
+ if (mac == 0)
+ return;
+
+ mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
+ m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
+}
+
+void
+RoutingProtocol::NotifyInterfaceDown (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
+
+ // Disable layer 2 link state monitoring (if possible)
+ Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
+ Ptr<NetDevice> dev = l3->GetNetDevice (i);
+ Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
+ if (wifi != 0)
+ {
+ Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
+ if (mac != 0)
+ {
+ mac->TraceDisconnectWithoutContext ("TxErrHeader",
+ m_nb.GetTxErrorCallback ());
+ m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
+ }
+ }
+
+ // Close socket
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
+ NS_ASSERT (socket);
+ socket->Close ();
+ m_socketAddresses.erase (socket);
+ if (m_socketAddresses.empty ())
+ {
+ NS_LOG_LOGIC ("No aodv interfaces");
+ m_htimer.Cancel ();
+ m_nb.Clear ();
+ m_routingTable.Clear ();
+ return;
+ }
+ m_routingTable.DeleteAllRoutesFromInterface (m_ipv4->GetAddress (i, 0));
+}
+
+void
+RoutingProtocol::NotifyAddAddress (uint32_t i, Ipv4InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
+ Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
+ if (!l3->IsUp (i))
+ return;
+ if (l3->GetNAddresses (i) == 1)
+ {
+ Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (iface);
+ if (!socket)
+ {
+ if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
+ return;
+ // Create a socket to listen only on this interface
+ Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
+ UdpSocketFactory::GetTypeId ());
+ NS_ASSERT (socket != 0);
+ socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv,this));
+ socket->BindToNetDevice (l3->GetNetDevice (i));
+ // Bind to any IP address so that broadcasts can be received
+ socket->Bind (InetSocketAddress (Ipv4Address::GetAny(), AODV_PORT));
+ socket->SetAllowBroadcast (true);
+ m_socketAddresses.insert (std::make_pair (socket, iface));
+
+ // Add local broadcast record to the routing table
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
+ m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
+ RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true,
+ /*seqno=*/0, /*iface=*/iface, /*hops=*/1,
+ /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Simulator::GetMaximumSimulationTime ());
+ m_routingTable.AddRoute (rt);
+ }
+ }
+ else
+ {
+ NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
+ }
+}
+
+void
+RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
+ if (socket)
+ {
+ m_routingTable.DeleteAllRoutesFromInterface (address);
+ m_socketAddresses.erase (socket);
+ Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
+ if (l3->GetNAddresses (i))
+ {
+ Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
+ // Create a socket to listen only on this interface
+ Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
+ UdpSocketFactory::GetTypeId ());
+ NS_ASSERT (socket != 0);
+ socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
+ // Bind to any IP address so that broadcasts can be received
+ socket->Bind (InetSocketAddress (Ipv4Address::GetAny(), AODV_PORT));
+ socket->SetAllowBroadcast (true);
+ m_socketAddresses.insert (std::make_pair (socket, iface));
+
+ // Add local broadcast record to the routing table
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
+ RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true, /*seqno=*/0, /*iface=*/iface,
+ /*hops=*/1, /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Simulator::GetMaximumSimulationTime ());
+ m_routingTable.AddRoute (rt);
+ }
+ if (m_socketAddresses.empty ())
+ {
+ NS_LOG_LOGIC ("No aodv interfaces");
+ m_htimer.Cancel ();
+ m_nb.Clear ();
+ m_routingTable.Clear ();
+ return;
+ }
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Remove address not participating in AODV operation");
+ }
+}
+
+bool
+RoutingProtocol::IsMyOwnAddress (Ipv4Address src)
+{
+ NS_LOG_FUNCTION (this << src);
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
+ m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ipv4InterfaceAddress iface = j->second;
+ if (src == iface.GetLocal ())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+Ptr<Ipv4Route>
+RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr, Ptr<NetDevice> oif) const
+{
+ NS_LOG_FUNCTION (this << hdr);
+ NS_ASSERT (m_lo != 0);
+ Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
+ rt->SetDestination (hdr.GetDestination ());
+ //
+ // Source address selection here is tricky. The loopback route is
+ // returned when AODV does not have a route; this causes the packet
+ // to be looped back and handled (cached) in RouteInput() method
+ // while a route is found. However, connection-oriented protocols
+ // like TCP need to create an endpoint four-tuple (src, src port,
+ // dst, dst port) and create a pseudo-header for checksumming. So,
+ // AODV needs to guess correctly what the eventual source address
+ // will be.
+ //
+ // For single interface, single address nodes, this is not a problem.
+ // When there are possibly multiple outgoing interfaces, the policy
+ // implemented here is to pick the first available AODV interface.
+ // If RouteOutput() caller specified an outgoing interface, that
+ // further constrains the selection of source address
+ //
+ std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
+ if (oif)
+ {
+ // Iterate to find an address on the oif device
+ for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ipv4Address addr = j->second.GetLocal ();
+ int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
+ if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
+ {
+ rt->SetSource (addr);
+ break;
+ }
+ }
+ }
+ else
+ {
+ rt->SetSource (j->second.GetLocal ());
+ }
+ NS_ASSERT_MSG (rt->GetSource() != Ipv4Address (), "Valid AODV source address not found");
+ rt->SetGateway (Ipv4Address ("127.0.0.1"));
+ rt->SetOutputDevice (m_lo);
+ return rt;
+}
+
+void
+RoutingProtocol::SendRequest (Ipv4Address dst)
+{
+ NS_LOG_FUNCTION ( this << dst);
+ // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
+ if (m_rreqCount == RreqRateLimit)
+ {
+ Simulator::Schedule (m_rreqRateLimitTimer.GetDelayLeft () + MicroSeconds (100),
+ &RoutingProtocol::SendRequest, this, dst);
+ return;
+ }
+ else
+ m_rreqCount++;
+ // Create RREQ header
+ RreqHeader rreqHeader;
+ rreqHeader.SetDst (dst);
+
+ RoutingTableEntry rt;
+ if (m_routingTable.LookupRoute (dst, rt))
+ {
+ rreqHeader.SetHopCount (rt.GetHop ());
+ if (rt.GetValidSeqNo ())
+ rreqHeader.SetDstSeqno (rt.GetSeqNo ());
+ else
+ rreqHeader.SetUnknownSeqno (true);
+ rt.SetFlag (IN_SEARCH);
+ m_routingTable.AddRoute (rt);
+ }
+ else
+ {
+ rreqHeader.SetUnknownSeqno (true);
+ Ptr<NetDevice> dev = 0;
+ RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/dst, /*validSeqNo=*/false, /*seqno=*/0,
+ /*iface=*/Ipv4InterfaceAddress(),/*hop=*/0,
+ /*nextHop=*/Ipv4Address(), /*lifeTime=*/Seconds(0));
+ newEntry.SetFlag (IN_SEARCH);
+ m_routingTable.AddRoute (newEntry);
+ }
+
+ if (GratuitousReply)
+ rreqHeader.SetGratiousRrep (true);
+ if (DestinationOnly)
+ rreqHeader.SetDestinationOnly (true);
+
+ m_seqNo++;
+ rreqHeader.SetOriginSeqno (m_seqNo);
+ m_requestId++;
+ rreqHeader.SetId (m_requestId);
+ rreqHeader.SetHopCount (0);
+
+ // Send RREQ as subnet directed broadcast from each interface used by aodv
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
+ m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ptr<Socket> socket = j->first;
+ Ipv4InterfaceAddress iface = j->second;
+
+ rreqHeader.SetOrigin (iface.GetLocal ());
+ m_rreqIdCache.IsDuplicate (iface.GetLocal (), m_requestId);
+
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rreqHeader);
+ TypeHeader tHeader (AODVTYPE_RREQ);
+ packet->AddHeader (tHeader);
+ // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
+ Ipv4Address destination;
+ if (iface.GetMask () == Ipv4Mask::GetOnes ())
+ {
+ destination = Ipv4Address ("255.255.255.255");
+ }
+ else
+ {
+ destination = iface.GetBroadcast ();
+ }
+ socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
+ }
+ ScheduleRreqRetry (dst);
+ if (EnableHello)
+ {
+ m_htimer.Cancel ();
+ m_htimer.Schedule (HelloInterval - Scalar (0.01) * MilliSeconds (UniformVariable ().GetInteger (0, 10)));
+ }
+}
+
+void
+RoutingProtocol::ScheduleRreqRetry (Ipv4Address dst)
+{
+ NS_LOG_FUNCTION (this << dst);
+ if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
+ {
+ Timer timer (Timer::CANCEL_ON_DESTROY);
+ m_addressReqTimer[dst] = timer;
+ }
+ m_addressReqTimer[dst].SetFunction (&RoutingProtocol::RouteRequestTimerExpire, this);
+ m_addressReqTimer[dst].Remove ();
+ m_addressReqTimer[dst].SetArguments (dst);
+ RoutingTableEntry rt;
+ m_routingTable.LookupRoute (dst, rt);
+ rt.IncrementRreqCnt ();
+ m_routingTable.Update (rt);
+ m_addressReqTimer[dst].Schedule (Scalar (rt.GetRreqCnt ()) * NetTraversalTime);
+}
+
+void
+RoutingProtocol::RecvAodv (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+ Address sourceAddress;
+ Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
+ InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
+ Ipv4Address sender = inetSourceAddr.GetIpv4 ();
+ Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
+ NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
+
+ UpdateRouteToNeighbor (sender, receiver);
+ TypeHeader tHeader (AODVTYPE_RREQ);
+ packet->RemoveHeader (tHeader);
+ if (!tHeader.IsValid ())
+ {
+ NS_LOG_DEBUG ("AODV message " << packet->GetUid() << " with unknown type received: " << tHeader.Get() << ". Drop");
+ return; // drop
+ }
+ switch (tHeader.Get ())
+ {
+ case AODVTYPE_RREQ:
+ {
+ RecvRequest (packet, receiver, sender);
+ break;
+ }
+ case AODVTYPE_RREP:
+ {
+ RecvReply (packet, receiver, sender);
+ break;
+ }
+ case AODVTYPE_RERR:
+ {
+ RecvError (packet, sender);
+ break;
+ }
+ case AODVTYPE_RREP_ACK:
+ {
+ RecvReplyAck (sender);
+ break;
+ }
+ }
+}
+
+bool
+RoutingProtocol::UpdateRouteLifeTime (Ipv4Address addr, Time lifetime)
+{
+ NS_LOG_FUNCTION (this << addr << lifetime);
+ RoutingTableEntry rt;
+ if (m_routingTable.LookupRoute (addr, rt))
+ {
+ rt.SetFlag (VALID);
+ rt.SetRreqCnt (0);
+ rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
+ m_routingTable.Update (rt);
+ return true;
+ }
+ return false;
+}
+
+void
+RoutingProtocol::UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver)
+{
+ NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
+ RoutingTableEntry toNeighbor;
+ if (!m_routingTable.LookupRoute (sender, toNeighbor))
+ {
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
+ RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/sender, /*know seqno=*/false, /*seqno=*/0,
+ /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
+ /*hops=*/1, /*next hop=*/sender, /*lifetime=*/ActiveRouteTimeout);
+ m_routingTable.AddRoute (newEntry);
+ }
+ else
+ {
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
+ if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
+ {
+ toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
+ }
+ else
+ {
+ RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/sender, /*know seqno=*/false, /*seqno=*/0,
+ /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
+ /*hops=*/1, /*next hop=*/sender, /*lifetime=*/std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
+ m_routingTable.Update (newEntry);
+ }
+ }
+
+}
+
+void
+RoutingProtocol::RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src)
+{
+ NS_LOG_FUNCTION (this);
+ RreqHeader rreqHeader;
+ p->RemoveHeader (rreqHeader);
+
+ // A node ignores all RREQs received from any node in its blacklist
+ RoutingTableEntry toPrev;
+ if (m_routingTable.LookupRoute (src, toPrev))
+ {
+ if (toPrev.IsUnidirectional ())
+ return;
+ }
+
+ uint32_t id = rreqHeader.GetId ();
+ Ipv4Address origin = rreqHeader.GetOrigin ();
+
+ /*
+ * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
+ * If such a RREQ has been received, the node silently discards the newly received RREQ.
+ */
+ if (m_rreqIdCache.IsDuplicate (origin, id))
+ {
+ return;
+ }
+
+ // Increment RREQ hop count
+ uint8_t hop = rreqHeader.GetHopCount () + 1;
+ rreqHeader.SetHopCount (hop);
+
+ /*
+ * When the reverse route is created or updated, the following actions on the route are also carried out:
+ * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
+ * in the route table entry and copied if greater than the existing value there
+ * 2. the valid sequence number field is set to true;
+ * 3. the next hop in the routing table becomes the node from which the RREQ was received
+ * 4. the hop count is copied from the Hop Count in the RREQ message;
+ * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
+ * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
+ */
+ RoutingTableEntry toOrigin;
+ if (!m_routingTable.LookupRoute (origin, toOrigin))
+ {
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
+ RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/origin, /*validSeno=*/true, /*seqNo=*/rreqHeader.GetOriginSeqno (),
+ /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/hop,
+ /*nextHop*/src, /*timeLife=*/Scalar (2) * NetTraversalTime - Scalar (2 * hop) * NodeTraversalTime);
+ m_routingTable.AddRoute (newEntry);
+ }
+ else
+ {
+ if (toOrigin.GetValidSeqNo ())
+ {
+ if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
+ toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
+ }
+ else
+ toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
+ toOrigin.SetValidSeqNo (true);
+ toOrigin.SetNextHop (src);
+ toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
+ toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
+ toOrigin.SetHop (hop);
+ toOrigin.SetLifeTime (std::max (Scalar (2) * NetTraversalTime - Scalar (2 * hop) * NodeTraversalTime, toOrigin.GetLifeTime ()));
+ m_routingTable.Update (toOrigin);
+ }
+ NS_LOG_LOGIC (receiver << " receive RREQ to destination " << rreqHeader.GetDst ());
+
+ // A node generates a RREP if either:
+ // (i) it is itself the destination,
+ if (IsMyOwnAddress (rreqHeader.GetDst ()))
+ {
+ m_routingTable.LookupRoute (origin, toOrigin);
+ SendReply (rreqHeader, toOrigin);
+ return;
+ }
+ /*
+ * (ii) or it has an active route to the destination, the destination sequence number in the node's existing route table entry for the destination
+ * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
+ */
+ RoutingTableEntry toDst;
+ Ipv4Address dst = rreqHeader.GetDst ();
+ if (m_routingTable.LookupRoute (dst, toDst))
+ {
+ /*
+ * Drop RREQ, This node RREP wil make a loop.
+ */
+ if (toDst.GetNextHop () == src)
+ {
+ NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
+ return;
+ }
+ /*
+ * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
+ * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
+ * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
+ * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
+ */
+ if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
+ && toDst.GetValidSeqNo () )
+ {
+ if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag() == VALID)
+ {
+ m_routingTable.LookupRoute (origin, toOrigin);
+ SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
+ return;
+ }
+ rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
+ rreqHeader.SetUnknownSeqno (false);
+ }
+ }
+
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
+ m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ptr<Socket> socket = j->first;
+ Ipv4InterfaceAddress iface = j->second;
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rreqHeader);
+ TypeHeader tHeader (AODVTYPE_RREQ);
+ packet->AddHeader (tHeader);
+ // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
+ Ipv4Address destination;
+ if (iface.GetMask () == Ipv4Mask::GetOnes ())
+ {
+ destination = Ipv4Address ("255.255.255.255");
+ }
+ else
+ {
+ destination = iface.GetBroadcast ();
+ }
+ socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
+ }
+
+ if (EnableHello)
+ {
+ m_htimer.Cancel ();
+ m_htimer.Schedule (HelloInterval - Scalar(0.1)*MilliSeconds(UniformVariable().GetInteger (0, 10)));
+ }
+}
+
+void
+RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
+{
+ NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
+ /*
+ * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
+ * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
+ */
+ if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
+ m_seqNo++;
+ RrepHeader rrepHeader ( /*prefixSize=*/0, /*hops=*/0, /*dst=*/rreqHeader.GetDst (),
+ /*dstSeqNo=*/m_seqNo, /*origin=*/toOrigin.GetDestination (), /*lifeTime=*/MyRouteTimeout);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rrepHeader);
+ TypeHeader tHeader (AODVTYPE_RREP);
+ packet->AddHeader (tHeader);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
+ NS_ASSERT (socket);
+ socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
+}
+
+void
+RoutingProtocol::SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep)
+{
+ NS_LOG_FUNCTION (this);
+ RrepHeader rrepHeader (/*prefix size=*/0, /*hops=*/toDst.GetHop (), /*dst=*/toDst.GetDestination (), /*dst seqno=*/toDst.GetSeqNo (),
+ /*origin=*/toOrigin.GetDestination (), /*lifetime=*/toDst.GetLifeTime ());
+ /* If the node we received a RREQ for is a neighbor we are
+ * probably facing a unidirectional link... Better request a RREP-ack
+ */
+ if (toDst.GetHop () == 1)
+ {
+ rrepHeader.SetAckRequired (true);
+ RoutingTableEntry toNextHop;
+ m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
+ toNextHop.m_ackTimer.SetFunction (&RoutingProtocol::AckTimerExpire, this);
+ toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
+ toNextHop.m_ackTimer.SetDelay (NextHopWait);
+ }
+ toDst.InsertPrecursor (toOrigin.GetNextHop ());
+ toOrigin.InsertPrecursor (toDst.GetNextHop ());
+ m_routingTable.Update (toDst);
+ m_routingTable.Update (toOrigin);
+
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rrepHeader);
+ TypeHeader tHeader (AODVTYPE_RREP);
+ packet->AddHeader (tHeader);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
+ NS_ASSERT (socket);
+ socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
+
+ // Generating gratuitous RREPs
+ if (gratRep)
+ {
+ RrepHeader gratRepHeader (/*prefix size=*/0, /*hops=*/toOrigin.GetHop (), /*dst=*/toOrigin.GetDestination (),
+ /*dst seqno=*/toOrigin.GetSeqNo (), /*origin=*/toDst.GetDestination (),
+ /*lifetime=*/toOrigin.GetLifeTime ());
+ Ptr<Packet> packetToDst = Create<Packet> ();
+ packetToDst->AddHeader (gratRepHeader);
+ TypeHeader type (AODVTYPE_RREP);
+ packetToDst->AddHeader (type);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (toDst.GetInterface ());
+ NS_ASSERT (socket);
+ NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid());
+ socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
+ }
+}
+
+void
+RoutingProtocol::SendReplyAck (Ipv4Address neighbor)
+{
+ NS_LOG_FUNCTION (this << " to " << neighbor);
+ RrepAckHeader h;
+ TypeHeader typeHeader (AODVTYPE_RREP_ACK);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (h);
+ packet->AddHeader (typeHeader);
+ RoutingTableEntry toNeighbor;
+ m_routingTable.LookupRoute (neighbor, toNeighbor);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
+ NS_ASSERT (socket);
+ socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
+}
+
+void
+RoutingProtocol::RecvReply (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address sender)
+{
+ NS_LOG_FUNCTION(this << " src " << sender);
+ RrepHeader rrepHeader;
+ p->RemoveHeader (rrepHeader);
+ Ipv4Address dst = rrepHeader.GetDst ();
+ NS_LOG_LOGIC("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin());
+
+ uint8_t hop = rrepHeader.GetHopCount () + 1;
+ rrepHeader.SetHopCount (hop);
+
+ // If RREP is Hello message
+ if (dst == rrepHeader.GetOrigin ())
+ {
+ ProcessHello (rrepHeader, receiver);
+ return;
+ }
+
+ /*
+ * If the route table entry to the destination is created or updated, then the following actions occur:
+ * - the route is marked as active,
+ * - the destination sequence number is marked as valid,
+ * - the next hop in the route entry is assigned to be the node from which the RREP is received,
+ * which is indicated by the source IP address field in the IP header,
+ * - the hop count is set to the value of the hop count from RREP message + 1
+ * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
+ * - and the destination sequence number is the Destination Sequence Number in the RREP message.
+ */
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
+ RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/dst, /*validSeqNo=*/true, /*seqno=*/rrepHeader.GetDstSeqno (),
+ /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/hop,
+ /*nextHop=*/sender, /*lifeTime=*/rrepHeader.GetLifeTime ());
+ RoutingTableEntry toDst;
+ if (m_routingTable.LookupRoute (dst, toDst))
+ {
+ /*
+ * The existing entry is updated only in the following circumstances:
+ * (i) the sequence number in the routing table is marked as invalid in route table entry.
+ */
+ if (!toDst.GetValidSeqNo ())
+ {
+ m_routingTable.Update (newEntry);
+ }
+ // (ii)the Destination Sequence Number in the RREP is greater than the node's copy of the destination sequence number and the known value is valid,
+ else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
+ {
+ m_routingTable.Update (newEntry);
+ }
+ else
+ {
+ // (iii) the sequence numbers are the same, but the route is marked as inactive.
+ if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
+ {
+ m_routingTable.Update (newEntry);
+ }
+ // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
+ else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
+ {
+ m_routingTable.Update (newEntry);
+ }
+ }
+ }
+ else
+ {
+ // The forward route for this destination is created if it does not already exist.
+ NS_LOG_LOGIC ("add new route");
+ m_routingTable.AddRoute (newEntry);
+ }
+ // Acknowledge receipt of the RREP by sending a RREP-ACK message back
+ if (rrepHeader.GetAckRequired ())
+ {
+ SendReplyAck (sender);
+ rrepHeader.SetAckRequired (false);
+ }
+ NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
+ if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
+ {
+ if (toDst.GetFlag () == IN_SEARCH)
+ {
+ m_routingTable.Update (newEntry);
+ m_addressReqTimer[dst].Remove ();
+ m_addressReqTimer.erase (dst);
+ }
+ m_routingTable.LookupRoute (dst, toDst);
+ SendPacketFromQueue (dst, toDst.GetRoute ());
+ return;
+ }
+
+ RoutingTableEntry toOrigin;
+ if (! m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
+ {
+ return; // Impossible! drop.
+ }
+ toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
+ m_routingTable.Update (toOrigin);
+
+ // Update information about precursors
+ if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
+ {
+ toDst.InsertPrecursor (toOrigin.GetNextHop ());
+ m_routingTable.Update (toDst);
+
+ RoutingTableEntry toNextHopToDst;
+ m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
+ toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
+ m_routingTable.Update (toNextHopToDst);
+
+ toOrigin.InsertPrecursor (toDst.GetNextHop ());
+ m_routingTable.Update (toOrigin);
+
+ RoutingTableEntry toNextHopToOrigin;
+ m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
+ toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
+ m_routingTable.Update (toNextHopToOrigin);
+ }
+
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rrepHeader);
+ TypeHeader tHeader (AODVTYPE_RREP);
+ packet->AddHeader (tHeader);
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
+ NS_ASSERT (socket);
+ socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
+}
+
+void
+RoutingProtocol::RecvReplyAck (Ipv4Address neighbor)
+{
+ NS_LOG_FUNCTION (this);
+ RoutingTableEntry rt;
+ if(m_routingTable.LookupRoute(neighbor, rt))
+ {
+ rt.m_ackTimer.Cancel ();
+ rt.SetFlag (VALID);
+ m_routingTable.Update(rt);
+ }
+}
+
+void
+RoutingProtocol::ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiver )
+{
+ NS_LOG_FUNCTION(this << "from " << rrepHeader.GetDst ());
+ /*
+ * Whenever a node receives a Hello message from a neighbor, the node
+ * SHOULD make sure that it has an active route to the neighbor, and
+ * create one if necessary.
+ */
+ RoutingTableEntry toNeighbor;
+ if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
+ {
+ Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
+ RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/rrepHeader.GetDst (), /*validSeqNo=*/true, /*seqno=*/rrepHeader.GetDstSeqno (),
+ /*iface=*/m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
+ /*hop=*/1, /*nextHop=*/rrepHeader.GetDst (), /*lifeTime=*/rrepHeader.GetLifeTime ());
+ m_routingTable.AddRoute (newEntry);
+ }
+ else
+ {
+ toNeighbor.SetLifeTime (std::max (Scalar (AllowedHelloLoss) * HelloInterval, toNeighbor.GetLifeTime ()));
+ toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
+ toNeighbor.SetValidSeqNo (true);
+ toNeighbor.SetFlag (VALID);
+ toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
+ toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
+ m_routingTable.Update (toNeighbor);
+ }
+ if (EnableHello)
+ {
+ m_nb.Update (rrepHeader.GetDst (), Scalar (AllowedHelloLoss) * HelloInterval);
+ }
+}
+
+void
+RoutingProtocol::RecvError (Ptr<Packet> p, Ipv4Address src )
+{
+ NS_LOG_FUNCTION (this << " from " << src);
+ RerrHeader rerrHeader;
+ p->RemoveHeader (rerrHeader);
+ std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
+ std::map<Ipv4Address, uint32_t> unreachable;
+ m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
+ std::pair<Ipv4Address, uint32_t> un;
+ while (rerrHeader.RemoveUnDestination (un))
+ {
+ if (m_nb.IsNeighbor (un.first))
+ SendRerrWhenBreaksLinkToNextHop (un.first);
+ else
+ {
+ for (std::map<Ipv4Address, uint32_t>::const_iterator i =
+ dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
+ {
+ if (i->first == un.first)
+ {
+ Ipv4Address dst = un.first;
+ unreachable.insert (un);
+ }
+ }
+ }
+ }
+
+ std::vector<Ipv4Address> precursors;
+ for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
+ i != unreachable.end ();)
+ {
+ if (!rerrHeader.AddUnDestination (i->first, i->second))
+ {
+ TypeHeader typeHeader (AODVTYPE_RERR);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rerrHeader);
+ packet->AddHeader (typeHeader);
+ SendRerrMessage (packet, precursors);
+ rerrHeader.Clear ();
+ }
+ else
+ {
+ RoutingTableEntry toDst;
+ m_routingTable.LookupRoute (i->first, toDst);
+ toDst.GetPrecursors (precursors);
+ ++i;
+ }
+ }
+ if (rerrHeader.GetDestCount () != 0)
+ {
+ TypeHeader typeHeader (AODVTYPE_RERR);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rerrHeader);
+ packet->AddHeader (typeHeader);
+ SendRerrMessage (packet, precursors);
+ }
+ m_routingTable.InvalidateRoutesWithDst (unreachable);
+}
+
+void
+RoutingProtocol::RouteRequestTimerExpire (Ipv4Address dst)
+{
+ NS_LOG_LOGIC(this);
+ RoutingTableEntry toDst;
+ if (m_routingTable.LookupValidRoute (dst, toDst))
+ {
+ SendPacketFromQueue (dst, toDst.GetRoute ());
+ NS_LOG_LOGIC ("route to " << dst << " found");
+ return;
+ }
+ /*
+ * If a route discovery has been attempted RreqRetries times at the maximum TTL without
+ * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
+ * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
+ */
+ if (toDst.GetRreqCnt () == RreqRetries)
+ {
+ NS_LOG_LOGIC("route discovery to " << dst << " has been attempted RreqRetries times");
+ m_addressReqTimer.erase (dst);
+ m_routingTable.DeleteRoute (dst);
+ NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
+ m_queue.DropPacketWithDst (dst);
+ return;
+ }
+
+ if (toDst.GetFlag () == IN_SEARCH)
+ {
+ NS_LOG_LOGIC ("Send new RREQ to " << dst << " ttl " << NetDiameter);
+ SendRequest (dst);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
+ m_addressReqTimer.erase(dst);
+ m_routingTable.DeleteRoute(dst);
+ m_queue.DropPacketWithDst(dst);
+ }
+}
+
+void
+RoutingProtocol::HelloTimerExpire ()
+{
+ NS_LOG_FUNCTION (this);
+ SendHello ();
+ m_htimer.Cancel ();
+ Time t = Scalar(0.01)*MilliSeconds(UniformVariable().GetInteger (0, 100));
+ m_htimer.Schedule (HelloInterval - t);
+}
+
+void
+RoutingProtocol::RreqRateLimitTimerExpire ()
+{
+ NS_LOG_FUNCTION (this);
+ m_rreqCount = 0;
+ m_rreqRateLimitTimer.Schedule (Seconds (1));
+}
+
+void
+RoutingProtocol::AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout)
+{
+ NS_LOG_FUNCTION (this);
+ m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
+}
+
+void
+RoutingProtocol::SendHello ()
+{
+ NS_LOG_FUNCTION (this);
+ /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
+ * Destination IP Address The node's IP address.
+ * Destination Sequence Number The node's latest sequence number.
+ * Hop Count 0
+ * Lifetime AllowedHelloLoss * HelloInterval
+ */
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ptr<Socket> socket = j->first;
+ Ipv4InterfaceAddress iface = j->second;
+ RrepHeader helloHeader (/*prefix size=*/0, /*hops=*/0, /*dst=*/iface.GetLocal (), /*dst seqno=*/m_seqNo,
+ /*origin=*/iface.GetLocal (),/*lifetime=*/Scalar (AllowedHelloLoss) * HelloInterval);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (helloHeader);
+ TypeHeader tHeader (AODVTYPE_RREP);
+ packet->AddHeader (tHeader);
+ // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
+ Ipv4Address destination;
+ if (iface.GetMask () == Ipv4Mask::GetOnes ())
+ {
+ destination = Ipv4Address ("255.255.255.255");
+ }
+ else
+ {
+ destination = iface.GetBroadcast ();
+ }
+ socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
+ }
+}
+
+void
+RoutingProtocol::SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route)
+{
+ NS_LOG_FUNCTION (this);
+ QueueEntry queueEntry;
+ while (m_queue.Dequeue (dst, queueEntry))
+ {
+ DeferredRouteOutputTag tag;
+ Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
+ if (p->RemovePacketTag (tag) &&
+ tag.oif != -1 &&
+ tag.oif != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
+ {
+ NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
+ return;
+ }
+ UnicastForwardCallback ucb = queueEntry.GetUnicastForwardCallback ();
+ Ipv4Header header = queueEntry.GetIpv4Header ();
+ header.SetSource (route->GetSource ());
+ header.SetTtl (header.GetTtl() + 1); // compensate extra TTL decrement by fake loopback routing
+ ucb (route, p, header);
+ }
+}
+
+void
+RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop)
+{
+ NS_LOG_FUNCTION (this << nextHop);
+ RerrHeader rerrHeader;
+ std::vector<Ipv4Address> precursors;
+ std::map<Ipv4Address, uint32_t> unreachable;
+
+ RoutingTableEntry toNextHop;
+ if (!m_routingTable.LookupRoute (nextHop, toNextHop))
+ return;
+ toNextHop.GetPrecursors (precursors);
+ rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
+ m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
+ for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
+ != unreachable.end ();)
+ {
+ if (!rerrHeader.AddUnDestination (i->first, i->second))
+ {
+ NS_LOG_LOGIC ("Send RERR message with maximum size.");
+ TypeHeader typeHeader (AODVTYPE_RERR);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rerrHeader);
+ packet->AddHeader (typeHeader);
+ SendRerrMessage (packet, precursors);
+ rerrHeader.Clear ();
+ }
+ else
+ {
+ RoutingTableEntry toDst;
+ m_routingTable.LookupRoute (i->first, toDst);
+ toDst.GetPrecursors (precursors);
+ ++i;
+ }
+ }
+ if (rerrHeader.GetDestCount () != 0)
+ {
+ TypeHeader typeHeader (AODVTYPE_RERR);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rerrHeader);
+ packet->AddHeader (typeHeader);
+ SendRerrMessage (packet, precursors);
+ }
+ unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
+ m_routingTable.InvalidateRoutesWithDst (unreachable);
+}
+
+void
+RoutingProtocol::SendRerrWhenNoRouteToForward (Ipv4Address dst,
+ uint32_t dstSeqNo, Ipv4Address origin)
+{
+ NS_LOG_FUNCTION (this);
+ RerrHeader rerrHeader;
+ rerrHeader.AddUnDestination (dst, dstSeqNo);
+ RoutingTableEntry toOrigin;
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rerrHeader);
+ packet->AddHeader (TypeHeader (AODVTYPE_RERR));
+ if (m_routingTable.LookupValidRoute (origin, toOrigin))
+ {
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (
+ toOrigin.GetInterface ());
+ NS_ASSERT (socket);
+ NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
+ socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
+ }
+ else
+ {
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator i =
+ m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
+ {
+ Ptr<Socket> socket = i->first;
+ Ipv4InterfaceAddress iface = i->second;
+ NS_ASSERT (socket);
+ NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal());
+ // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
+ Ipv4Address destination;
+ if (iface.GetMask () == Ipv4Mask::GetOnes ())
+ {
+ destination = Ipv4Address ("255.255.255.255");
+ }
+ else
+ {
+ destination = iface.GetBroadcast ();
+ }
+ socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
+ }
+ }
+}
+
+void
+RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
+{
+ NS_LOG_FUNCTION (this);
+
+ if (precursors.empty ())
+ {
+ NS_LOG_LOGIC ("No precursors");
+ return;
+ }
+ // If there is only one precursor, RERR SHOULD be unicast toward that precursor
+ if (precursors.size () == 1)
+ {
+ RoutingTableEntry toPrecursor;
+ if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
+ {
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
+ NS_ASSERT (socket);
+ NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination() << " from " << toPrecursor.GetInterface ().GetLocal ());
+ socket->SendTo (packet, 0, InetSocketAddress (precursors.front (), AODV_PORT));
+ }
+ return;
+ }
+
+ // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
+ std::vector<Ipv4InterfaceAddress> ifaces;
+ RoutingTableEntry toPrecursor;
+ for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
+ {
+ if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
+ std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
+ {
+ ifaces.push_back (toPrecursor.GetInterface ());
+ }
+ }
+
+ for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
+ {
+ Ptr<Socket> socket = FindSocketWithInterfaceAddress (*i);
+ NS_ASSERT (socket);
+ NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal());
+ // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
+ Ipv4Address destination;
+ if (i->GetMask () == Ipv4Mask::GetOnes ())
+ {
+ destination = Ipv4Address ("255.255.255.255");
+ }
+ else
+ {
+ destination = i->GetBroadcast ();
+ }
+ socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
+ }
+}
+
+Ptr<Socket>
+RoutingProtocol::FindSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) const
+{
+ NS_LOG_FUNCTION (this << addr);
+ for (std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j =
+ m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ptr<Socket> socket = j->first;
+ Ipv4InterfaceAddress iface = j->second;
+ if (iface == addr)
+ return socket;
+ }
+ Ptr<Socket> socket;
+ return socket;
+}
+
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-routing-protocol.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,254 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#ifndef AODVROUTINGPROTOCOL_H
+#define AODVROUTINGPROTOCOL_H
+
+#include "aodv-rtable.h"
+#include "aodv-rqueue.h"
+#include "aodv-packet.h"
+#include "aodv-neighbor.h"
+#include "aodv-dpd.h"
+#include "ns3/node.h"
+#include "ns3/output-stream-wrapper.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/ipv4-interface.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include <map>
+
+namespace ns3
+{
+namespace aodv
+{
+/**
+ * \ingroup aodv
+ *
+ * \brief AODV routing protocol
+ */
+class RoutingProtocol : public Ipv4RoutingProtocol
+{
+public:
+ static TypeId GetTypeId (void);
+ static const uint32_t AODV_PORT;
+
+ /// c-tor
+ RoutingProtocol ();
+ virtual ~RoutingProtocol();
+ virtual void DoDispose ();
+
+ ///\name From Ipv4RoutingProtocol
+ //\{
+ Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+ 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;
+ //\}
+
+ ///\name Handle protocol parameters
+ //\{
+ Time GetMaxQueueTime () const { return MaxQueueTime; }
+ void SetMaxQueueTime (Time t);
+ uint32_t GetMaxQueueLen () const { return MaxQueueLen; }
+ void SetMaxQueueLen (uint32_t len);
+ bool GetDesinationOnlyFlag () const { return DestinationOnly; }
+ void SetDesinationOnlyFlag (bool f) { DestinationOnly = f; }
+ bool GetGratuitousReplyFlag () const { return GratuitousReply; }
+ void SetGratuitousReplyFlag (bool f) { GratuitousReply = f; }
+ void SetHelloEnable (bool f) { EnableHello = f; }
+ bool GetHelloEnable () const { return EnableHello; }
+ void SetBroadcastEnable (bool f) { EnableBroadcast = f; }
+ bool GetBroadcastEnable () const { return EnableBroadcast; }
+ //\}
+private:
+ ///\name Protocol parameters.
+ //\{
+ uint32_t RreqRetries; ///< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
+ uint16_t RreqRateLimit; ///< Maximum number of RREQ per second.
+ Time ActiveRouteTimeout; ///< Period of time during which the route is considered to be valid.
+ uint32_t NetDiameter; ///< Net diameter measures the maximum possible number of hops between two nodes in the network
+ /**
+ * NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets
+ * and should include queuing delays, interrupt processing times and transfer times.
+ */
+ Time NodeTraversalTime;
+ Time NetTraversalTime; ///< Estimate of the average net traversal time.
+ Time PathDiscoveryTime; ///< Estimate of maximum time needed to find route in network.
+ Time MyRouteTimeout; ///< Value of lifetime field in RREP generating by this node.
+ /**
+ * Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval.
+ * If it has not, it MAY broadcast a Hello message
+ */
+ Time HelloInterval;
+ uint32_t AllowedHelloLoss; ///< Number of hello messages which may be loss for valid link
+ /**
+ * DeletePeriod is intended to provide an upper bound on the time for which an upstream node A
+ * can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D.
+ */
+ Time DeletePeriod;
+ Time NextHopWait; ///< Period of our waiting for the neighbour's RREP_ACK
+ /**
+ * The TimeoutBuffer is configurable. Its purpose is to provide a buffer for the timeout so that if the RREP is delayed
+ * due to congestion, a timeout is less likely to occur while the RREP is still en route back to the source.
+ */
+ uint16_t TimeoutBuffer;
+ Time BlackListTimeout; ///< Time for which the node is put into the blacklist
+ uint32_t MaxQueueLen; ///< The maximum number of packets that we allow a routing protocol to buffer.
+ Time MaxQueueTime; ///< The maximum period of time that a routing protocol is allowed to buffer a packet for.
+ bool DestinationOnly; ///< Indicates only the destination may respond to this RREQ.
+ bool GratuitousReply; ///< Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.
+ bool EnableHello; ///< Indicates whether a hello messages enable
+ bool EnableBroadcast; ///< Indicates whether a a broadcast data packets forwarding enable
+ //\}
+
+ /// IP protocol
+ Ptr<Ipv4> m_ipv4;
+ /// Raw socket per each IP interface, map socket -> iface address (IP + mask)
+ std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketAddresses;
+ /// Loopback device used to defer RREQ until packet will be fully formed
+ Ptr<NetDevice> m_lo;
+
+ /// Routing table
+ RoutingTable m_routingTable;
+ /// A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route.
+ RequestQueue m_queue;
+ /// Broadcast ID
+ uint32_t m_requestId;
+ /// Request sequence number
+ uint32_t m_seqNo;
+ /// Handle duplicated RREQ
+ IdCache m_rreqIdCache;
+ /// Handle duplicated broadcast/multicast packets
+ DuplicatePacketDetection m_dpd;
+ /// Handle neighbors
+ Neighbors m_nb;
+ /// Number of RREQs used for RREQ rate control
+ uint16_t m_rreqCount;
+
+private:
+ /// Start protocol operation
+ void Start ();
+ /// Queue packet and send route request
+ void DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
+ /// If route exists and valid, forward packet.
+ bool Forwarding (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
+ /**
+ * To reduce congestion in a network, repeated attempts by a source node at route discovery
+ * for a single destination MUST utilize a binary exponential backoff.
+ */
+ void ScheduleRreqRetry (Ipv4Address dst);
+ /**
+ * Set lifetime field in routing table entry to the maximum of existing lifetime and lt, if the entry exists
+ * \param addr - destination address
+ * \param lt - proposed time for lifetime field in routing table entry for destination with address addr.
+ * \return true if route to destination address addr exist
+ */
+ bool UpdateRouteLifeTime (Ipv4Address addr, Time lt);
+ /**
+ * Update neighbor record.
+ * \param receiver is supposed to be my interface
+ * \param sender is supposed to be IP address of my neighbor.
+ */
+ void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver);
+ /// Check that packet is send from own interface
+ bool IsMyOwnAddress (Ipv4Address src);
+ /// Find socket with local interface address iface
+ Ptr<Socket> FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
+ /// Process hello message
+ void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr);
+ /// Create loopback route for given header
+ Ptr<Ipv4Route> LoopbackRoute (const Ipv4Header & header, Ptr<NetDevice> oif) const;
+
+ ///\name Receive control packets
+ //\{
+ /// Receive and process control packet
+ void RecvAodv (Ptr<Socket> socket);
+ /// Receive RREQ
+ void RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src);
+ /// Receive RREP
+ void RecvReply (Ptr<Packet> p, Ipv4Address my ,Ipv4Address src);
+ /// Receive RREP_ACK
+ void RecvReplyAck (Ipv4Address neighbor);
+ /// Receive RERR from node with address src
+ void RecvError (Ptr<Packet> p, Ipv4Address src);
+ //\}
+
+ ///\name Send
+ //\{
+ /// Forward packet from route request queue
+ void SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route);
+ /// Send hello
+ void SendHello ();
+ /// Send RREQ
+ void SendRequest (Ipv4Address dst);
+ /// Send RREP
+ void SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin);
+ /** Send RREP by intermediate node
+ * \param toDst routing table entry to destination
+ * \param toOrigin routing table entry to originator
+ * \param gratRep indicates whether a gratuitous RREP should be unicast to destination
+ */
+ void SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep);
+ /// Send RREP_ACK
+ void SendReplyAck (Ipv4Address neighbor);
+ /// Initiate RERR
+ void SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop);
+ /// Forward RERR
+ void SendRerrMessage(Ptr<Packet> packet, std::vector<Ipv4Address> precursors);
+ /**
+ * Send RERR message when no route to forward input packet. Unicast if there is reverse route to originating node, broadcast otherwise.
+ * \param dst - destination node IP address
+ * \param dstSeqNo - destination node sequence number
+ * \param origin - originating node IP address
+ */
+ void SendRerrWhenNoRouteToForward (Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin);
+ //\}
+
+ /// Hello timer
+ Timer m_htimer;
+ /// Schedule next send of hello message
+ void HelloTimerExpire ();
+ /// RREQ rate limit timer
+ Timer m_rreqRateLimitTimer;
+ /// Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
+ void RreqRateLimitTimerExpire ();
+ /// Map IP address + RREQ timer.
+ std::map<Ipv4Address, Timer> m_addressReqTimer;
+ /// Handle route discovery process
+ void RouteRequestTimerExpire (Ipv4Address dst);
+ /// Mark link to neighbor node as unidirectional for blacklistTimeout
+ void AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout);
+};
+
+}
+}
+#endif /* AODVROUTINGPROTOCOL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-rqueue.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,151 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#include "aodv-rqueue.h"
+#include <algorithm>
+#include <functional>
+#include "ns3/ipv4-route.h"
+#include "ns3/socket.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("AodvRequestQueue");
+
+namespace ns3
+{
+namespace aodv
+{
+uint32_t
+RequestQueue::GetSize ()
+{
+ Purge ();
+ return m_queue.size ();
+}
+
+bool
+RequestQueue::Enqueue (QueueEntry & entry)
+{
+ Purge ();
+ for (std::vector<QueueEntry>::const_iterator i = m_queue.begin (); i
+ != m_queue.end (); ++i)
+ {
+ if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ())
+ && (i->GetIpv4Header ().GetDestination ()
+ == entry.GetIpv4Header ().GetDestination ()))
+ return false;
+ }
+ entry.SetExpireTime (m_queueTimeout);
+ if (m_queue.size () == m_maxLen)
+ {
+ Drop (m_queue.front (), "Drop the most aged packet"); // Drop the most aged packet
+ m_queue.erase (m_queue.begin ());
+ }
+ m_queue.push_back (entry);
+ return true;
+}
+
+void
+RequestQueue::DropPacketWithDst (Ipv4Address dst)
+{
+ NS_LOG_FUNCTION (this << dst);
+ Purge ();
+ const Ipv4Address addr = dst;
+ for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i
+ != m_queue.end (); ++i)
+ {
+ if (IsEqual (*i, dst))
+ {
+ Drop (*i, "DropPacketWithDst ");
+ }
+ }
+ m_queue.erase (std::remove_if (m_queue.begin (), m_queue.end (),
+ std::bind2nd (std::ptr_fun (RequestQueue::IsEqual), dst)), m_queue.end ());
+}
+
+bool
+RequestQueue::Dequeue (Ipv4Address dst, QueueEntry & entry)
+{
+ Purge ();
+ for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i != m_queue.end (); ++i)
+ {
+ if (i->GetIpv4Header ().GetDestination () == dst)
+ {
+ entry = *i;
+ m_queue.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+RequestQueue::Find (Ipv4Address dst)
+{
+ for (std::vector<QueueEntry>::const_iterator i = m_queue.begin (); i
+ != m_queue.end (); ++i)
+ {
+ if (i->GetIpv4Header ().GetDestination () == dst)
+ return true;
+ }
+ return false;
+}
+
+struct IsExpired
+{
+ bool
+ operator() (QueueEntry const & e) const
+ {
+ return (e.GetExpireTime () < Seconds (0));
+ }
+};
+
+void
+RequestQueue::Purge ()
+{
+ IsExpired pred;
+ for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i
+ != m_queue.end (); ++i)
+ {
+ if (pred (*i))
+ {
+ Drop (*i, "Drop outdated packet ");
+ }
+ }
+ m_queue.erase (std::remove_if (m_queue.begin (), m_queue.end (), pred),
+ m_queue.end ());
+}
+
+void
+RequestQueue::Drop (QueueEntry en, std::string reason)
+{
+ NS_LOG_LOGIC (reason << en.GetPacket ()->GetUid () << " " << en.GetIpv4Header ().GetDestination ());
+ en.GetErrorCallback () (en.GetPacket (), en.GetIpv4Header (),
+ Socket::ERROR_NOROUTETOHOST);
+ return;
+}
+
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-rqueue.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#ifndef AODV_RQUEUE_H
+#define AODV_RQUEUE_H
+
+#include <vector>
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/simulator.h"
+
+
+namespace ns3 {
+namespace aodv {
+
+/**
+ * \ingroup aodv
+ * \brief AODV Queue Entry
+ */
+class QueueEntry
+{
+public:
+ typedef Ipv4RoutingProtocol::UnicastForwardCallback UnicastForwardCallback;
+ typedef Ipv4RoutingProtocol::ErrorCallback ErrorCallback;
+ /// c-tor
+ QueueEntry (Ptr<const Packet> pa = 0, Ipv4Header const & h = Ipv4Header (),
+ UnicastForwardCallback ucb = UnicastForwardCallback (),
+ ErrorCallback ecb = ErrorCallback (), Time exp = Simulator::Now ()) :
+ m_packet (pa), m_header (h), m_ucb (ucb), m_ecb (ecb),
+ m_expire (exp + Simulator::Now ())
+ {}
+
+ /**
+ * Compare queue entries
+ * \return true if equal
+ */
+ bool operator== (QueueEntry const & o) const
+ {
+ return ((m_packet == o.m_packet) && (m_header.GetDestination () == o.m_header.GetDestination ()) && (m_expire == o.m_expire));
+ }
+ ///\name Fields
+ //\{
+ UnicastForwardCallback GetUnicastForwardCallback () const { return m_ucb; }
+ void SetUnicastForwardCallback (UnicastForwardCallback ucb) { m_ucb = ucb; }
+ ErrorCallback GetErrorCallback () const { return m_ecb; }
+ void SetErrorCallback (ErrorCallback ecb) { m_ecb = ecb; }
+ Ptr<const Packet> GetPacket () const { return m_packet; }
+ void SetPacket (Ptr<const Packet> p) { m_packet = p; }
+ Ipv4Header GetIpv4Header() const { return m_header; }
+ void SetIpv4Header (Ipv4Header h) { m_header = h; }
+ void SetExpireTime (Time exp) { m_expire = exp + Simulator::Now(); }
+ Time GetExpireTime () const { return m_expire - Simulator::Now(); }
+ //\}
+private:
+ /// Data packet
+ Ptr<const Packet> m_packet;
+ /// IP header
+ Ipv4Header m_header;
+ /// Unicast forward callback
+ UnicastForwardCallback m_ucb;
+ /// Error callback
+ ErrorCallback m_ecb;
+ /// Expire time for queue entry
+ Time m_expire;
+};
+/**
+ * \ingroup aodv
+ * \brief AODV route request queue
+ *
+ * Since AODV is an on demand routing we queue requests while looking for route.
+ */
+class RequestQueue
+{
+public:
+ /// Default c-tor
+ RequestQueue (uint32_t maxLen, Time routeToQueueTimeout) :
+ m_maxLen (maxLen), m_queueTimeout (routeToQueueTimeout)
+ {
+ }
+ /// Push entry in queue, if there is no entry with the same packet and destination address in queue.
+ bool Enqueue (QueueEntry & entry);
+ /// Return first found (the earliest) entry for given destination
+ bool Dequeue (Ipv4Address dst, QueueEntry & entry);
+ /// Remove all packets with destination IP address dst
+ void DropPacketWithDst (Ipv4Address dst);
+ /// Finds whether a packet with destination dst exists in the queue
+ bool Find (Ipv4Address dst);
+ /// Number of entries
+ uint32_t GetSize ();
+ ///\name Fields
+ //\{
+ uint32_t GetMaxQueueLen () const { return m_maxLen; }
+ void SetMaxQueueLen (uint32_t len) { m_maxLen = len; }
+ Time GetQueueTimeout () const { return m_queueTimeout; }
+ void SetQueueTimeout (Time t) { m_queueTimeout = t; }
+ //\}
+
+private:
+ std::vector<QueueEntry> m_queue;
+ /// Remove all expired entries
+ void Purge ();
+ /// Notify that packet is dropped from queue by timeout
+ void Drop (QueueEntry en, std::string reason);
+ /// The maximum number of packets that we allow a routing protocol to buffer.
+ uint32_t m_maxLen;
+ /// The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
+ Time m_queueTimeout;
+ static bool IsEqual (QueueEntry en, const Ipv4Address dst) { return (en.GetIpv4Header ().GetDestination () == dst); }
+};
+
+
+}}
+
+#endif /* AODV_RQUEUE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-rtable.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,453 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+#include "aodv-rtable.h"
+#include <algorithm>
+#include <iomanip>
+#include "ns3/simulator.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("AodvRoutingTable");
+
+namespace ns3
+{
+namespace aodv
+{
+
+/*
+ The Routing Table
+ */
+
+RoutingTableEntry::RoutingTableEntry (Ptr<NetDevice> dev, Ipv4Address dst, bool vSeqNo, uint32_t seqNo,
+ Ipv4InterfaceAddress iface, uint16_t hops, Ipv4Address nextHop, Time lifetime) :
+ m_ackTimer (Timer::CANCEL_ON_DESTROY),
+ m_validSeqNo (vSeqNo), m_seqNo (seqNo), m_hops (hops),
+ m_lifeTime (lifetime + Simulator::Now ()), m_iface (iface), m_flag (VALID),
+ m_reqCount (0), m_blackListState (false), m_blackListTimeout (Simulator::Now ())
+{
+ m_ipv4Route = Create<Ipv4Route> ();
+ m_ipv4Route->SetDestination (dst);
+ m_ipv4Route->SetGateway (nextHop);
+ m_ipv4Route->SetSource (m_iface.GetLocal ());
+ m_ipv4Route->SetOutputDevice (dev);
+}
+
+RoutingTableEntry::~RoutingTableEntry ()
+{
+}
+
+bool
+RoutingTableEntry::InsertPrecursor (Ipv4Address id)
+{
+ NS_LOG_FUNCTION (this << id);
+ if (!LookupPrecursor (id))
+ {
+ m_precursorList.push_back (id);
+ return true;
+ }
+ else
+ return false;
+}
+
+bool
+RoutingTableEntry::LookupPrecursor (Ipv4Address id)
+{
+ NS_LOG_FUNCTION (this << id);
+ for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
+ != m_precursorList.end (); ++i)
+ {
+ if (*i == id)
+ {
+ NS_LOG_LOGIC ("Precursor " << id << " found");
+ return true;
+ }
+ }
+ NS_LOG_LOGIC ("Precursor " << id << " not found");
+ return false;
+}
+
+bool
+RoutingTableEntry::DeletePrecursor (Ipv4Address id)
+{
+ NS_LOG_FUNCTION (this << id);
+ std::vector<Ipv4Address>::iterator i = std::remove (m_precursorList.begin (),
+ m_precursorList.end (), id);
+ if (i == m_precursorList.end ())
+ {
+ NS_LOG_LOGIC ("Precursor " << id << " not found");
+ return false;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Precursor " << id << " found");
+ m_precursorList.erase (i, m_precursorList.end ());
+ }
+ return true;
+}
+
+void
+RoutingTableEntry::DeleteAllPrecursors ()
+{
+ NS_LOG_FUNCTION (this);
+ m_precursorList.clear ();
+}
+
+bool
+RoutingTableEntry::IsPrecursorListEmpty () const
+{
+ return m_precursorList.empty ();
+}
+
+void
+RoutingTableEntry::GetPrecursors (std::vector<Ipv4Address> & prec) const
+{
+ NS_LOG_FUNCTION (this);
+ if (IsPrecursorListEmpty ())
+ return;
+ for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
+ != m_precursorList.end (); ++i)
+ {
+ bool result = true;
+ for (std::vector<Ipv4Address>::const_iterator j = prec.begin (); j
+ != prec.end (); ++j)
+ {
+ if (*j == *i)
+ result = false;
+ }
+ if (result)
+ prec.push_back (*i);
+ }
+}
+
+void
+RoutingTableEntry::Invalidate (Time badLinkLifetime)
+{
+ NS_LOG_FUNCTION (this << badLinkLifetime.GetSeconds ());
+ if (m_flag == INVALID)
+ return;
+ m_flag = INVALID;
+ m_reqCount = 0;
+ m_lifeTime = badLinkLifetime + Simulator::Now ();
+}
+
+void
+RoutingTableEntry::Print (Ptr<OutputStreamWrapper> stream) const
+{
+ std::ostream* os = stream->GetStream();
+ *os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
+ << "\t" << m_iface.GetLocal () << "\t";
+ switch (m_flag)
+ {
+ case VALID:
+ {
+ *os << "UP";
+ break;
+ }
+ case INVALID:
+ {
+ *os << "DOWN";
+ break;
+ }
+ case IN_SEARCH:
+ {
+ *os << "IN_SEARCH";
+ break;
+ }
+ }
+ *os << "\t";
+ *os << std::setiosflags (std::ios::fixed) <<
+ std::setiosflags (std::ios::left) << std::setprecision (2) <<
+ std::setw (14) << (m_lifeTime - Simulator::Now ()).GetSeconds ();
+ *os << "\t" << m_hops << "\n";
+}
+
+/*
+ The Routing Table
+ */
+
+RoutingTable::RoutingTable (Time t) :
+ m_badLinkLifetime (t)
+{
+}
+
+bool
+RoutingTable::LookupRoute (Ipv4Address id, RoutingTableEntry & rt)
+{
+ NS_LOG_FUNCTION (this << id);
+ Purge ();
+ if (m_ipv4AddressEntry.empty ())
+ {
+ NS_LOG_LOGIC ("Route to " << id << " not found; m_ipv4AddressEntry is empty");
+ return false;
+ }
+ std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
+ m_ipv4AddressEntry.find (id);
+ if (i == m_ipv4AddressEntry.end ())
+ {
+ NS_LOG_LOGIC ("Route to " << id << " not found");
+ return false;
+ }
+ rt = i->second;
+ NS_LOG_LOGIC ("Route to " << id << " found");
+ return true;
+}
+
+bool
+RoutingTable::LookupValidRoute (Ipv4Address id, RoutingTableEntry & rt)
+{
+ NS_LOG_FUNCTION (this << id);
+ if (! LookupRoute (id, rt))
+ {
+ NS_LOG_LOGIC ("Route to " << id << " not found");
+ return false;
+ }
+ NS_LOG_LOGIC ("Route to " << id << " flag is " << ((rt.GetFlag () == VALID) ? "valid" : "not valid"));
+ return (rt.GetFlag () == VALID);
+}
+
+bool
+RoutingTable::DeleteRoute (Ipv4Address dst)
+{
+ NS_LOG_FUNCTION (this << dst);
+ Purge ();
+ if (m_ipv4AddressEntry.erase (dst) != 0)
+ {
+ NS_LOG_LOGIC ("Route deletion to " << dst << " successful");
+ return true;
+ }
+ NS_LOG_LOGIC ("Route deletion to " << dst << " not successful");
+ return false;
+}
+
+bool
+RoutingTable::AddRoute (RoutingTableEntry & rt)
+{
+ NS_LOG_FUNCTION (this);
+ Purge ();
+ if (rt.GetFlag () != IN_SEARCH)
+ rt.SetRreqCnt (0);
+ std::pair<std::map<Ipv4Address, RoutingTableEntry>::iterator, bool> result =
+ m_ipv4AddressEntry.insert (std::make_pair (rt.GetDestination (), rt));
+ return result.second;
+}
+
+bool
+RoutingTable::Update (RoutingTableEntry & rt)
+{
+ NS_LOG_FUNCTION (this);
+ std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ m_ipv4AddressEntry.find (rt.GetDestination ());
+ if (i == m_ipv4AddressEntry.end ())
+ {
+ NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " fails; not found");
+ return false;
+ }
+ i->second = rt;
+ if (i->second.GetFlag () != IN_SEARCH)
+ {
+ NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " set RreqCnt to 0");
+ i->second.SetRreqCnt (0);
+ }
+ return true;
+}
+
+bool
+RoutingTable::SetEntryState (Ipv4Address id, RouteFlags state)
+{
+ NS_LOG_FUNCTION (this);
+ std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ m_ipv4AddressEntry.find (id);
+ if (i == m_ipv4AddressEntry.end ())
+ {
+ NS_LOG_LOGIC ("Route set entry state to " << id << " fails; not found");
+ return false;
+ }
+ i->second.SetFlag (state);
+ i->second.SetRreqCnt (0);
+ NS_LOG_LOGIC ("Route set entry state to " << id << ": new state is " << state);
+ return true;
+}
+
+void
+RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
+{
+ NS_LOG_FUNCTION (this);
+ Purge ();
+ unreachable.clear ();
+ for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
+ m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
+ {
+ if (i->second.GetNextHop () == nextHop)
+ {
+ NS_LOG_LOGIC ("Unreachable insert " << i->first << " " << i->second.GetSeqNo ());
+ unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
+ }
+ }
+}
+
+void
+RoutingTable::InvalidateRoutesWithDst (const std::map<Ipv4Address, uint32_t> & unreachable)
+{
+ NS_LOG_FUNCTION (this);
+ Purge ();
+ for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
+ {
+ for (std::map<Ipv4Address, uint32_t>::const_iterator j =
+ unreachable.begin (); j != unreachable.end (); ++j)
+ {
+ if ((i->first == j->first) && (i->second.GetFlag () == VALID))
+ {
+ NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
+ i->second.Invalidate (m_badLinkLifetime);
+ }
+ }
+ }
+}
+
+void
+RoutingTable::DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface)
+{
+ NS_LOG_FUNCTION (this);
+ if (m_ipv4AddressEntry.empty ())
+ return;
+ for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
+ {
+ if (i->second.GetInterface () == iface)
+ {
+ std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
+ ++i;
+ m_ipv4AddressEntry.erase (tmp);
+ }
+ else
+ ++i;
+ }
+}
+
+void
+RoutingTable::Purge ()
+{
+ NS_LOG_FUNCTION (this);
+ if (m_ipv4AddressEntry.empty ())
+ return;
+ for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
+ {
+ if (i->second.GetLifeTime () < Seconds (0))
+ {
+ if (i->second.GetFlag () == INVALID)
+ {
+ std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
+ ++i;
+ m_ipv4AddressEntry.erase (tmp);
+ }
+ else if (i->second.GetFlag () == VALID)
+ {
+ NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
+ i->second.Invalidate (m_badLinkLifetime);
+ ++i;
+ }
+ else
+ ++i;
+ }
+ else
+ {
+ ++i;
+ }
+ }
+}
+
+void
+RoutingTable::Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const
+{
+ NS_LOG_FUNCTION (this);
+ if (table.empty ())
+ return;
+ for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ table.begin (); i != table.end ();)
+ {
+ if (i->second.GetLifeTime () < Seconds (0))
+ {
+ if (i->second.GetFlag () == INVALID)
+ {
+ std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
+ ++i;
+ table.erase (tmp);
+ }
+ else if (i->second.GetFlag () == VALID)
+ {
+ NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
+ i->second.Invalidate (m_badLinkLifetime);
+ ++i;
+ }
+ else
+ ++i;
+ }
+ else
+ {
+ ++i;
+ }
+ }
+}
+
+bool
+RoutingTable::MarkLinkAsUnidirectional (Ipv4Address neighbor, Time blacklistTimeout)
+{
+ NS_LOG_FUNCTION (this << neighbor << blacklistTimeout.GetSeconds ());
+ std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+ m_ipv4AddressEntry.find (neighbor);
+ if (i == m_ipv4AddressEntry.end ())
+ {
+ NS_LOG_LOGIC ("Mark link unidirectional to " << neighbor << " fails; not found");
+ return false;
+ }
+ i->second.SetUnidirectional (true);
+ i->second.SetBalcklistTimeout (blacklistTimeout);
+ i->second.SetRreqCnt (0);
+ NS_LOG_LOGIC ("Set link to " << neighbor << " to unidirectional");
+ return true;
+}
+
+void
+RoutingTable::Print (Ptr<OutputStreamWrapper> stream) const
+{
+ std::map<Ipv4Address, RoutingTableEntry> table = m_ipv4AddressEntry;
+ Purge (table);
+ *stream->GetStream () << "\nAODV Routing table\n"
+ << "Destination\tGateway\t\tInterface\tFlag\tExpire\t\tHops\n";
+ for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
+ table.begin (); i != table.end (); ++i)
+ {
+ i->second.Print (stream);
+ }
+ *stream->GetStream () << "\n";
+}
+
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/model/aodv-rtable.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,258 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on
+ * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
+ *
+ * AODV-UU implementation by Erik Nordström of Uppsala University
+ * http://core.it.uu.se/core/index.php/AODV-UU
+ *
+ * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+#ifndef AODV_RTABLE_H
+#define AODV_RTABLE_H
+
+#include <stdint.h>
+#include <cassert>
+#include <map>
+#include <sys/types.h>
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/timer.h"
+#include "ns3/net-device.h"
+#include "ns3/output-stream-wrapper.h"
+
+namespace ns3 {
+namespace aodv {
+
+/**
+ * \ingroup aodv
+ * \brief Route record states
+ */
+enum RouteFlags
+{
+ VALID = 0, //!< VALID
+ INVALID = 1, //!< INVALID
+ IN_SEARCH = 2, //!< IN_SEARCH
+};
+
+/**
+ * \ingroup aodv
+ * \brief Routing table entry
+ */
+class RoutingTableEntry
+{
+public:
+ /// c-to
+ RoutingTableEntry (Ptr<NetDevice> dev = 0,Ipv4Address dst = Ipv4Address(), bool vSeqNo = false, uint32_t m_seqNo = 0,
+ Ipv4InterfaceAddress iface = Ipv4InterfaceAddress(), uint16_t hops = 0,
+ Ipv4Address nextHop = Ipv4Address(), Time lifetime = Simulator::Now());
+
+ ~RoutingTableEntry ();
+
+ ///\name Precursors management
+ //\{
+ /**
+ * Insert precursor in precursor list if it doesn't yet exist in the list
+ * \param id precursor address
+ * \return true on success
+ */
+ bool InsertPrecursor (Ipv4Address id);
+ /**
+ * Lookup precursor by address
+ * \param id precursor address
+ * \return true on success
+ */
+ bool LookupPrecursor (Ipv4Address id);
+ /**
+ * \brief Delete precursor
+ * \param id precursor address
+ * \return true on success
+ */
+ bool DeletePrecursor (Ipv4Address id);
+ /// Delete all precursors
+ void DeleteAllPrecursors ();
+ /**
+ * Check that precursor list empty
+ * \return true if precursor list empty
+ */
+ bool IsPrecursorListEmpty () const;
+ /**
+ * Inserts precursors in vector prec if they does not yet exist in vector
+ */
+ void GetPrecursors (std::vector<Ipv4Address> & prec) const;
+ //\}
+
+ /// Mark entry as "down" (i.e. disable it)
+ void Invalidate (Time badLinkLifetime);
+ ///\name Fields
+ //\{
+ Ipv4Address GetDestination () const { return m_ipv4Route->GetDestination(); }
+ Ptr<Ipv4Route> GetRoute () const { return m_ipv4Route; }
+ void SetRoute (Ptr<Ipv4Route> r) { m_ipv4Route = r; }
+ void SetNextHop (Ipv4Address nextHop) { m_ipv4Route->SetGateway(nextHop); }
+ Ipv4Address GetNextHop () const { return m_ipv4Route->GetGateway(); }
+ void SetOutputDevice (Ptr<NetDevice> dev) { m_ipv4Route->SetOutputDevice(dev); }
+ Ptr<NetDevice> GetOutputDevice () const { return m_ipv4Route->GetOutputDevice(); }
+ Ipv4InterfaceAddress GetInterface () const { return m_iface;}
+ void SetInterface (Ipv4InterfaceAddress iface) { m_iface = iface; }
+ void SetValidSeqNo (bool s) { m_validSeqNo = s; }
+ bool GetValidSeqNo () const { return m_validSeqNo; }
+ void SetSeqNo (uint32_t sn) { m_seqNo = sn; }
+ uint32_t GetSeqNo () const { return m_seqNo; }
+ void SetHop (uint16_t hop) { m_hops = hop; }
+ uint16_t GetHop () const {return m_hops; }
+ void SetLifeTime (Time lt) { m_lifeTime = lt + Simulator::Now(); }
+ Time GetLifeTime () const { return m_lifeTime - Simulator::Now(); }
+ void SetFlag (RouteFlags flag) { m_flag = flag; }
+ RouteFlags GetFlag () const { return m_flag; }
+ void SetRreqCnt (uint8_t n) { m_reqCount = n; }
+ uint8_t GetRreqCnt () const { return m_reqCount; }
+ void IncrementRreqCnt () { m_reqCount++; }
+ void SetUnidirectional (bool u) { m_blackListState = u; }
+ bool IsUnidirectional () const { return m_blackListState; }
+ void SetBalcklistTimeout (Time t) { m_blackListTimeout = t; }
+ Time GetBlacklistTimeout () const { return m_blackListTimeout; }
+ /// RREP_ACK timer
+ Timer m_ackTimer;
+ //\}
+
+ /**
+ * \brief Compare destination address
+ * \return true if equal
+ */
+ bool operator== (Ipv4Address const dst) const
+ {
+ return (m_ipv4Route->GetDestination () == dst);
+ }
+ void Print(Ptr<OutputStreamWrapper> stream) const;
+
+private:
+ /// Valid Destination Sequence Number flag
+ bool m_validSeqNo;
+ /// Destination Sequence Number, if m_validSeqNo = true
+ uint32_t m_seqNo;
+ /// Hop Count (number of hops needed to reach destination)
+ uint16_t m_hops;
+ /**
+ * \brief Expiration or deletion time of the route
+ * Lifetime field in the routing table plays dual role --
+ * for an active route it is the expiration time, and for an invalid route
+ * it is the deletion time.
+ */
+ Time m_lifeTime;
+ /** Ip route, include
+ * - destination address
+ * - source address
+ * - next hop address (gateway)
+ * - output device
+ */
+ Ptr<Ipv4Route> m_ipv4Route;
+ /// Output interface address
+ Ipv4InterfaceAddress m_iface;
+ /// Routing flags: valid, invalid or in search
+ RouteFlags m_flag;
+
+ /// List of precursors
+ std::vector<Ipv4Address> m_precursorList;
+ /// When I can send another request
+ Time m_routeRequestTimout;
+ /// Number of route requests
+ uint8_t m_reqCount;
+ /// Indicate if this entry is in "blacklist"
+ bool m_blackListState;
+ /// Time for which the node is put into the blacklist
+ Time m_blackListTimeout;
+};
+
+/**
+ * \ingroup aodv
+ * \brief The Routing table used by AODV protocol
+ */
+class RoutingTable
+{
+public:
+ /// c-tor
+ RoutingTable (Time t);
+ ///\name Handle life time of invalid route
+ //\{
+ Time GetBadLinkLifetime () const { return m_badLinkLifetime; }
+ void SetBadLinkLifetime (Time t) { m_badLinkLifetime = t; }
+ //\}
+ /**
+ * Add routing table entry if it doesn't yet exist in routing table
+ * \param r routing table entry
+ * \return true in success
+ */
+ bool AddRoute (RoutingTableEntry & r);
+ /**
+ * Delete routing table entry with destination address dst, if it exists.
+ * \param dst destination address
+ * \return true on success
+ */
+ bool DeleteRoute (Ipv4Address dst);
+ /**
+ * Lookup routing table entry with destination address dst
+ * \param dst destination address
+ * \param rt entry with destination address dst, if exists
+ * \return true on success
+ */
+ bool LookupRoute (Ipv4Address dst, RoutingTableEntry & rt);
+ /// Lookup route in VALID state
+ bool LookupValidRoute (Ipv4Address dst, RoutingTableEntry & rt);
+ /// Update routing table
+ bool Update (RoutingTableEntry & rt);
+ /// Set routing table entry flags
+ bool SetEntryState (Ipv4Address dst, RouteFlags state);
+ /// Lookup routing entries with next hop Address dst and not empty list of precursors.
+ void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable);
+ /**
+ * Update routing entries with this destinations as follows:
+ * 1. The destination sequence number of this routing entry, if it
+ * exists and is valid, is incremented.
+ * 2. The entry is invalidated by marking the route entry as invalid
+ * 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
+ */
+ void InvalidateRoutesWithDst (std::map<Ipv4Address, uint32_t> const & unreachable);
+ /// Delete all route from interface with address iface
+ void DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface);
+ /// Delete all entries from routing table
+ void Clear () { m_ipv4AddressEntry.clear (); }
+ /// Delete all outdated entries and invalidate valid entry if Lifetime is expired
+ void Purge ();
+ /** Mark entry as unidirectional (e.g. add this neighbor to "blacklist" for blacklistTimeout period)
+ * \param neighbor - neighbor address link to which assumed to be unidirectional
+ * \param blacklistTimeout - time for which the neighboring node is put into the blacklist
+ * \return true on success
+ */
+ bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout);
+ /// Print routing table
+ void Print(Ptr<OutputStreamWrapper> stream) const;
+
+private:
+ std::map<Ipv4Address, RoutingTableEntry> m_ipv4AddressEntry;
+ /// Deletion time for invalid routes
+ Time m_badLinkLifetime;
+ /// const version of Purge, for use by Print() method
+ void Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const;
+};
+
+}}
+
+#endif /* AODV_RTABLE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/aodv/test/aodv-test-suite.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,541 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Pavel Boyko <boyko@iitp.ru>
+ */
+#include "ns3/test.h"
+#include "ns3/aodv-neighbor.h"
+#include "ns3/aodv-packet.h"
+#include "ns3/aodv-rqueue.h"
+#include "ns3/aodv-rtable.h"
+#include "ns3/ipv4-route.h"
+
+namespace ns3
+{
+namespace aodv
+{
+
+/// Unit test for neighbors
+struct NeighborTest : public TestCase
+{
+ NeighborTest () : TestCase ("Neighbor"), neighbor (0) { }
+ virtual void DoRun ();
+ void Handler (Ipv4Address addr);
+ void CheckTimeout1 ();
+ void CheckTimeout2 ();
+ void CheckTimeout3 ();
+ Neighbors * neighbor;
+};
+
+void
+NeighborTest::Handler (Ipv4Address addr)
+{
+}
+
+void
+NeighborTest::CheckTimeout1 ()
+{
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), true, "Neighbor exists");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), true, "Neighbor exists");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), true, "Neighbor exists");
+}
+void
+NeighborTest::CheckTimeout2 ()
+{
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), false, "Neighbor doesn't exist");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), false, "Neighbor doesn't exist");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), false, "Neighbor doesn't exist");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), true, "Neighbor exists");
+}
+void
+NeighborTest::CheckTimeout3 ()
+{
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), false, "Neighbor doesn't exist");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), false, "Neighbor doesn't exist");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), false, "Neighbor doesn't exist");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), false, "Neighbor doesn't exist");
+}
+
+void
+NeighborTest::DoRun ()
+{
+ Neighbors nb (Seconds (1));
+ neighbor = &nb;
+ neighbor->SetCallback (MakeCallback (&NeighborTest::Handler, this));
+ neighbor->Update (Ipv4Address ("1.2.3.4"), Seconds (1));
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("4.3.2.1")), false, "Neighbor doesn't exist");
+ neighbor->Update (Ipv4Address ("1.2.3.4"), Seconds (10));
+ NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->GetExpireTime (Ipv4Address ("1.2.3.4")), Seconds (10), "Known expire time");
+ NS_TEST_EXPECT_MSG_EQ (neighbor->GetExpireTime (Ipv4Address ("4.3.2.1")), Seconds (0), "Known expire time");
+ neighbor->Update (Ipv4Address ("1.1.1.1"), Seconds (5));
+ neighbor->Update (Ipv4Address ("2.2.2.2"), Seconds (10));
+ neighbor->Update (Ipv4Address ("3.3.3.3"), Seconds (20));
+
+ Simulator::Schedule (Seconds (2), &NeighborTest::CheckTimeout1, this);
+ Simulator::Schedule (Seconds (15), &NeighborTest::CheckTimeout2, this);
+ Simulator::Schedule (Seconds (30), &NeighborTest::CheckTimeout3, this);
+ Simulator::Run ();
+ Simulator::Destroy ();
+ }
+//-----------------------------------------------------------------------------
+struct TypeHeaderTest : public TestCase
+{
+ TypeHeaderTest () : TestCase ("AODV TypeHeader")
+ {
+ }
+ virtual void DoRun ()
+ {
+ TypeHeader h (AODVTYPE_RREQ);
+ NS_TEST_EXPECT_MSG_EQ (h.IsValid (), true, "Default header is valid");
+ NS_TEST_EXPECT_MSG_EQ (h.Get (), AODVTYPE_RREQ, "Default header is RREQ");
+
+ Ptr<Packet> p = Create<Packet> ();
+ p->AddHeader (h);
+ TypeHeader h2 (AODVTYPE_RREP);
+ uint32_t bytes = p->RemoveHeader (h2);
+ NS_TEST_EXPECT_MSG_EQ (bytes, 1, "Type header is 1 byte long");
+ NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for RREQ
+struct RreqHeaderTest : public TestCase
+{
+ RreqHeaderTest () : TestCase ("AODV RREQ")
+ {
+ }
+ virtual void DoRun ()
+ {
+ RreqHeader h (/*flags*/0, /*reserved*/0, /*hopCount*/6, /*requestID*/1, /*dst*/Ipv4Address ("1.2.3.4"),
+ /*dstSeqNo*/40, /*origin*/Ipv4Address ("4.3.2.1"), /*originSeqNo*/10);
+ NS_TEST_EXPECT_MSG_EQ (h.GetGratiousRrep (), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetDestinationOnly (), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 6, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetId (), 1, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.2.3.4"), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 40, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.3.2.1"), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetOriginSeqno (), 10, "trivial");
+
+ h.SetGratiousRrep (true);
+ NS_TEST_EXPECT_MSG_EQ (h.GetGratiousRrep (), true, "trivial");
+ h.SetDestinationOnly (true);
+ NS_TEST_EXPECT_MSG_EQ (h.GetDestinationOnly (), true, "trivial");
+ h.SetUnknownSeqno (true);
+ NS_TEST_EXPECT_MSG_EQ (h.GetUnknownSeqno (), true, "trivial");
+ h.SetDst (Ipv4Address ("1.1.1.1"));
+ NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.1.1.1"), "trivial");
+ h.SetDstSeqno (5);
+ NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 5, "trivial");
+ h.SetHopCount (7);
+ NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 7, "trivial");
+ h.SetId (55);
+ NS_TEST_EXPECT_MSG_EQ (h.GetId (), 55, "trivial");
+ h.SetOrigin (Ipv4Address ("4.4.4.4"));
+ NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.4.4.4"), "trivial");
+ h.SetOriginSeqno (23);
+ NS_TEST_EXPECT_MSG_EQ (h.GetOriginSeqno (), 23, "trivial");
+
+ Ptr<Packet> p = Create<Packet> ();
+ p->AddHeader (h);
+ RreqHeader h2;
+ uint32_t bytes = p->RemoveHeader (h2);
+ NS_TEST_EXPECT_MSG_EQ (bytes, 23, "RREP is 23 bytes long");
+ NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
+
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for RREP
+struct RrepHeaderTest : public TestCase
+{
+ RrepHeaderTest () : TestCase ("AODV RREP") {}
+ virtual void DoRun ()
+ {
+ RrepHeader h (/*prefixSize*/0, /*hopCount*/12, /*dst*/Ipv4Address ("1.2.3.4"), /*dstSeqNo*/2,
+ /*origin*/Ipv4Address ("4.3.2.1"), /*lifetime*/Seconds (3));
+ NS_TEST_EXPECT_MSG_EQ (h.GetPrefixSize (), 0, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 12, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.2.3.4"), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 2, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.3.2.1"), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), Seconds (3), "trivial");
+ h.SetDst (Ipv4Address ("1.1.1.1"));
+ NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.1.1.1"), "trivial");
+ h.SetDstSeqno (123);
+ NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 123, "trivial");
+ h.SetOrigin (Ipv4Address ("4.4.4.4"));
+ NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.4.4.4"), "trivial");
+ h.SetLifeTime (MilliSeconds (1200));
+ NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), MilliSeconds (1200), "trivial");
+ h.SetAckRequired (true);
+ NS_TEST_EXPECT_MSG_EQ (h.GetAckRequired (), true, "trivial");
+ h.SetAckRequired (false);
+ NS_TEST_EXPECT_MSG_EQ (h.GetAckRequired (), false, "trivial");
+ h.SetPrefixSize (2);
+ NS_TEST_EXPECT_MSG_EQ (h.GetPrefixSize (), 2, "trivial");
+ h.SetHopCount (15);
+ NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 15, "trivial");
+
+ h.SetHello (Ipv4Address ("10.0.0.2"), 9, Seconds (15));
+ NS_TEST_EXPECT_MSG_EQ (h.GetDst (), h.GetOrigin (), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 9, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), Seconds (15), "trivial");
+
+ Ptr<Packet> p = Create<Packet> ();
+ p->AddHeader (h);
+ RrepHeader h2;
+ uint32_t bytes = p->RemoveHeader (h2);
+ NS_TEST_EXPECT_MSG_EQ (bytes, 19, "RREP is 19 bytes long");
+ NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for RREP-ACK
+struct RrepAckHeaderTest : public TestCase
+{
+ RrepAckHeaderTest () : TestCase ("AODV RREP-ACK")
+ {
+ }
+ virtual void DoRun()
+ {
+ RrepAckHeader h;
+ Ptr<Packet> p = Create<Packet> ();
+ p->AddHeader (h);
+ RrepAckHeader h2;
+ uint32_t bytes = p->RemoveHeader(h2);
+ NS_TEST_EXPECT_MSG_EQ (bytes, 1, "ACK is 1 byte long");
+ NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for RERR
+struct RerrHeaderTest : public TestCase
+{
+ RerrHeaderTest () : TestCase ("AODV RERR")
+ {
+ }
+ virtual void DoRun()
+ {
+ RerrHeader h;
+ h.SetNoDelete(true);
+ NS_TEST_EXPECT_MSG_EQ(h.GetNoDelete(), true, "trivial");
+ Ipv4Address dst = Ipv4Address("1.2.3.4");
+ NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst, 12), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ(h.GetDestCount(), 1, "trivial");
+ NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst, 13), true, "trivial");
+ Ipv4Address dst2 = Ipv4Address("4.3.2.1");
+ NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst2, 12), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ(h.GetDestCount(), 2, "trivial");
+
+ Ptr<Packet> p = Create<Packet> ();
+ p->AddHeader (h);
+ RerrHeader h2;
+ uint32_t bytes = p->RemoveHeader(h2);
+ NS_TEST_EXPECT_MSG_EQ (bytes, h.GetSerializedSize(), "(De)Serialized size match");
+ NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for AODV routing table entry
+struct QueueEntryTest : public TestCase
+{
+ QueueEntryTest () : TestCase ("QueueEntry") {}
+ void Unicast (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
+ void Error (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
+ void Unicast2 (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
+ void Error2 (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
+ virtual void DoRun()
+ {
+ Ptr<const Packet> packet = Create<Packet> ();
+ Ipv4Header h;
+ h.SetDestination (Ipv4Address ("1.2.3.4"));
+ h.SetSource (Ipv4Address ("4.3.2.1"));
+ Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&QueueEntryTest::Unicast, this);
+ Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&QueueEntryTest::Error, this);
+ QueueEntry entry (packet, h, ucb, ecb, Seconds (1));
+ NS_TEST_EXPECT_MSG_EQ (h.GetDestination (), entry.GetIpv4Header ().GetDestination (), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (h.GetSource (), entry.GetIpv4Header ().GetSource (), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (ucb.IsEqual(entry.GetUnicastForwardCallback ()), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (ecb.IsEqual(entry.GetErrorCallback ()), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (entry.GetExpireTime (), Seconds (1), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (entry.GetPacket (), packet, "trivial");
+ entry.SetExpireTime (Seconds (3));
+ NS_TEST_EXPECT_MSG_EQ (entry.GetExpireTime (), Seconds (3), "trivial");
+ Ipv4Header h2;
+ h2.SetDestination(Ipv4Address ("1.1.1.1"));
+ entry.SetIpv4Header (h2);
+ NS_TEST_EXPECT_MSG_EQ (entry.GetIpv4Header ().GetDestination (), Ipv4Address ("1.1.1.1"), "trivial");
+ Ipv4RoutingProtocol::UnicastForwardCallback ucb2 = MakeCallback (&QueueEntryTest::Unicast2, this);
+ Ipv4RoutingProtocol::ErrorCallback ecb2 = MakeCallback (&QueueEntryTest::Error2, this);
+ entry.SetErrorCallback (ecb2);
+ NS_TEST_EXPECT_MSG_EQ (ecb2.IsEqual (entry.GetErrorCallback ()), true, "trivial");
+ entry.SetUnicastForwardCallback (ucb2);
+ NS_TEST_EXPECT_MSG_EQ (ucb2.IsEqual (entry.GetUnicastForwardCallback ()), true, "trivial");
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for RequestQueue
+struct AodvRqueueTest : public TestCase
+{
+ AodvRqueueTest () : TestCase ("Rqueue"), q (64, Seconds (30)) {}
+ virtual void DoRun ();
+ void Unicast (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
+ void Error (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
+ void CheckSizeLimit ();
+ void CheckTimeout ();
+
+ RequestQueue q;
+};
+
+void
+AodvRqueueTest::DoRun ()
+{
+ NS_TEST_EXPECT_MSG_EQ (q.GetMaxQueueLen (), 64, "trivial");
+ q.SetMaxQueueLen (32);
+ NS_TEST_EXPECT_MSG_EQ (q.GetMaxQueueLen (), 32, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (q.GetQueueTimeout (), Seconds (30), "trivial");
+ q.SetQueueTimeout (Seconds(10));
+ NS_TEST_EXPECT_MSG_EQ (q.GetQueueTimeout (), Seconds (10), "trivial");
+
+ Ptr<const Packet> packet = Create<Packet> ();
+ Ipv4Header h;
+ h.SetDestination (Ipv4Address ("1.2.3.4"));
+ h.SetSource (Ipv4Address ("4.3.2.1"));
+ Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&AodvRqueueTest::Unicast, this);
+ Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&AodvRqueueTest::Error, this);
+ QueueEntry e1 (packet, h, ucb, ecb, Seconds (1));
+ q.Enqueue (e1);
+ q.Enqueue (e1);
+ q.Enqueue (e1);
+ NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.2.3.4")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.1.1.1")), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 1, "trivial");
+ q.DropPacketWithDst (Ipv4Address ("1.2.3.4"));
+ NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.2.3.4")), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 0, "trivial");
+
+ h.SetDestination (Ipv4Address ("2.2.2.2"));
+ QueueEntry e2 (packet, h, ucb, ecb, Seconds (1));
+ q.Enqueue (e1);
+ q.Enqueue (e2);
+ Ptr<Packet> packet2 = Create<Packet> ();
+ QueueEntry e3 (packet2, h, ucb, ecb, Seconds (1));
+ NS_TEST_EXPECT_MSG_EQ (q.Dequeue (Ipv4Address("3.3.3.3"), e3), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (q.Dequeue (Ipv4Address ("2.2.2.2"), e3), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("2.2.2.2")), false, "trivial");
+ q.Enqueue (e2);
+ q.Enqueue (e3);
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
+ Ptr<Packet> packet4 = Create<Packet> ();
+ h.SetDestination (Ipv4Address ("1.2.3.4"));
+ QueueEntry e4 (packet4, h, ucb, ecb, Seconds (20));
+ q.Enqueue (e4);
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 3, "trivial");
+ q.DropPacketWithDst (Ipv4Address ("1.2.3.4"));
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize(), 1, "trivial");
+
+ CheckSizeLimit ();
+
+ Ipv4Header header2;
+ Ipv4Address dst2 ("1.2.3.4");
+ header2.SetDestination (dst2);
+
+ Simulator::Schedule (q.GetQueueTimeout () + Seconds (1), &AodvRqueueTest::CheckTimeout, this);
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+
+void
+AodvRqueueTest::CheckSizeLimit ()
+{
+ Ptr<Packet> packet = Create<Packet> ();
+ Ipv4Header header;
+ Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&AodvRqueueTest::Unicast, this);
+ Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&AodvRqueueTest::Error, this);
+ QueueEntry e1 (packet, header, ucb, ecb, Seconds (1));
+
+ for (uint32_t i = 0; i < q.GetMaxQueueLen (); ++i)
+ q.Enqueue (e1);
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
+
+ for (uint32_t i = 0; i < q.GetMaxQueueLen (); ++i)
+ q.Enqueue (e1);
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
+}
+
+void
+AodvRqueueTest::CheckTimeout ()
+{
+ NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 0, "Must be empty now");
+}
+//-----------------------------------------------------------------------------
+/// Unit test for AODV routing table entry
+struct AodvRtableEntryTest : public TestCase
+{
+ AodvRtableEntryTest () : TestCase ("RtableEntry") {}
+ virtual void DoRun()
+ {
+ Ptr<NetDevice> dev;
+ Ipv4InterfaceAddress iface;
+ RoutingTableEntry rt (/*output device*/dev, /*dst*/Ipv4Address("1.2.3.4"), /*validSeqNo*/true, /*seqNo*/10,
+ /*interface*/iface, /*hop*/5, /*next hop*/Ipv4Address("3.3.3.3"), /*lifetime*/Seconds(10));
+ NS_TEST_EXPECT_MSG_EQ (rt.GetOutputDevice (), dev, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetDestination (), Ipv4Address ("1.2.3.4"), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetValidSeqNo (), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetSeqNo (), 10, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetInterface (), iface, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetHop (), 5, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetNextHop (), Ipv4Address ("3.3.3.3"), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (10), "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), VALID, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 0, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
+
+ Ptr<NetDevice> dev2;
+ Ipv4InterfaceAddress iface2;
+ rt.SetOutputDevice (dev2);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetOutputDevice (), dev2, "trivial");
+ rt.SetInterface (iface2);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetInterface (), iface2, "trivial");
+ rt.SetValidSeqNo (false);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetValidSeqNo (), false, "trivial");
+ rt.SetFlag (INVALID);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
+ rt.SetFlag (IN_SEARCH);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), IN_SEARCH, "trivial");
+ rt.SetHop (12);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetHop (), 12, "trivial");
+ rt.SetLifeTime (Seconds (1));
+ NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (1), "trivial");
+ rt.SetNextHop (Ipv4Address ("1.1.1.1"));
+ NS_TEST_EXPECT_MSG_EQ (rt.GetNextHop (), Ipv4Address ("1.1.1.1"), "trivial");
+ rt.SetUnidirectional (true);
+ NS_TEST_EXPECT_MSG_EQ (rt.IsUnidirectional (), true, "trivial");
+ rt.SetBalcklistTimeout (Seconds (7));
+ NS_TEST_EXPECT_MSG_EQ (rt.GetBlacklistTimeout (), Seconds (7), "trivial");
+ rt.SetRreqCnt (2);
+ NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 2, "trivial");
+ rt.IncrementRreqCnt ();
+ NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 3, "trivial");
+ rt.Invalidate (Seconds (13));
+ NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (13), "trivial");
+ rt.SetLifeTime (MilliSeconds (100));
+ NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), MilliSeconds (100), "trivial");
+ Ptr<Ipv4Route> route = rt.GetRoute ();
+ NS_TEST_EXPECT_MSG_EQ (route->GetDestination (), Ipv4Address ("1.2.3.4"), "trivial");
+
+ NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.1")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.2")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.2")), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.3")), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.1")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.DeletePrecursor (Ipv4Address ("10.0.0.2")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.2")), false, "trivial");
+ std::vector<Ipv4Address> prec;
+ rt.GetPrecursors (prec);
+ NS_TEST_EXPECT_MSG_EQ (prec.size (), 1, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.4")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.DeletePrecursor (Ipv4Address ("10.0.0.5")), false, "trivial");
+ rt.GetPrecursors (prec);
+ NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
+ rt.DeleteAllPrecursors ();
+ NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
+ rt.GetPrecursors (prec);
+ NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
+ Simulator::Destroy ();
+ }
+};
+//-----------------------------------------------------------------------------
+/// Unit test for AODV routing table
+struct AodvRtableTest : public TestCase
+{
+ AodvRtableTest () : TestCase ("Rtable") {}
+ virtual void DoRun()
+ {
+ RoutingTable rtable (Seconds (2));
+ NS_TEST_EXPECT_MSG_EQ (rtable.GetBadLinkLifetime (), Seconds (2), "trivial");
+ rtable.SetBadLinkLifetime (Seconds (1));
+ NS_TEST_EXPECT_MSG_EQ (rtable.GetBadLinkLifetime (), Seconds (1), "trivial");
+ Ptr<NetDevice> dev;
+ Ipv4InterfaceAddress iface;
+ RoutingTableEntry rt (/*output device*/dev, /*dst*/Ipv4Address("1.2.3.4"), /*validSeqNo*/true, /*seqNo*/10,
+ /*interface*/iface, /*hop*/5, /*next hop*/Ipv4Address("1.1.1.1"), /*lifetime*/Seconds(10));
+ NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt), false, "trivial");
+ RoutingTableEntry rt2 (/*output device*/dev, /*dst*/Ipv4Address("4.3.2.1"), /*validSeqNo*/false, /*seqNo*/0,
+ /*interface*/iface, /*hop*/15, /*next hop*/Ipv4Address("1.1.1.1"), /*lifetime*/Seconds(1));
+ NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt2), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (rt2.GetDestination (), rt), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt2.GetDestination (), rt.GetDestination (), "trivial");
+ rt.SetHop (20);
+ rt.InsertPrecursor (Ipv4Address ("10.0.0.3"));
+ NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt), true, "trivial");
+ RoutingTableEntry rt3;
+ NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("10.0.0.1"), rt), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt3), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("10.0.0.1"), INVALID), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("1.2.3.4"), IN_SEARCH), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("5.5.5.5")), false, "trivial");
+ RoutingTableEntry rt4 (/*output device*/dev, /*dst*/Ipv4Address ("5.5.5.5"), /*validSeqNo*/false, /*seqNo*/0,
+ /*interface*/iface, /*hop*/15, /*next hop*/Ipv4Address ("1.1.1.1"), /*lifetime*/Seconds (-10));
+ NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt4), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("5.5.5.5"), INVALID), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("5.5.5.5"), rt), false, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.MarkLinkAsUnidirectional (Ipv4Address ("1.2.3.4"), Seconds (2)), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("1.2.3.4"), rt), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.IsUnidirectional (), true, "trivial");
+ rt.SetLifeTime (Seconds (-5));
+ NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt), true, "trivial");
+ std::map<Ipv4Address, uint32_t> unreachable;
+ rtable.GetListOfDestinationWithNextHop (Ipv4Address ("1.1.1.1"), unreachable);
+ NS_TEST_EXPECT_MSG_EQ (unreachable.size (), 2, "trivial");
+ unreachable.insert (std::make_pair (Ipv4Address ("4.3.2.1"), 3));
+ rtable.InvalidateRoutesWithDst (unreachable);
+ NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("4.3.2.1"), rt), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), true, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), false, "trivial");
+ Simulator::Destroy ();
+ }
+};
+//-----------------------------------------------------------------------------
+class AodvTestSuite : public TestSuite
+{
+public:
+ AodvTestSuite () : TestSuite ("routing-aodv", UNIT)
+ {
+ AddTestCase (new NeighborTest);
+ AddTestCase (new TypeHeaderTest);
+ AddTestCase (new RreqHeaderTest);
+ AddTestCase (new RrepHeaderTest);
+ AddTestCase (new RrepAckHeaderTest);
+ AddTestCase (new RerrHeaderTest);
+ AddTestCase (new QueueEntryTest);
+ AddTestCase (new AodvRqueueTest);
+ AddTestCase (new AodvRtableEntryTest);
+ AddTestCase (new AodvRtableTest);
+ }
+} g_aodvTestSuite;
+
+}}
--- a/src/routing/aodv/wscript Fri Feb 25 17:21:08 2011 -0800
+++ b/src/routing/aodv/wscript Sun Feb 27 01:00:17 2011 -0500
@@ -4,14 +4,15 @@
module = bld.create_ns3_module('aodv', ['internet', 'contrib'])
module.includes = '.'
module.source = [
- 'aodv-id-cache.cc',
- 'aodv-dpd.cc',
- 'aodv-rtable.cc',
- 'aodv-rqueue.cc',
- 'aodv-packet.cc',
- 'aodv-neighbor.cc',
- 'aodv-routing-protocol.cc',
- 'aodv-test-suite.cc',
+ 'model/aodv-id-cache.cc',
+ 'model/aodv-dpd.cc',
+ 'model/aodv-rtable.cc',
+ 'model/aodv-rqueue.cc',
+ 'model/aodv-packet.cc',
+ 'model/aodv-neighbor.cc',
+ 'model/aodv-routing-protocol.cc',
+ 'helper/aodv-helper.cc',
+ 'test/aodv-test-suite.cc',
'test/aodv-regression.cc',
'test/bug-772.cc',
'test/loopback.cc',
@@ -20,12 +21,15 @@
headers = bld.new_task_gen('ns3header')
headers.module = 'aodv'
headers.source = [
- 'aodv-id-cache.h',
- 'aodv-dpd.h',
- 'aodv-rtable.h',
- 'aodv-rqueue.h',
- 'aodv-packet.h',
- 'aodv-neighbor.h',
- 'aodv-routing-protocol.h',
+ 'model/aodv-id-cache.h',
+ 'model/aodv-dpd.h',
+ 'model/aodv-rtable.h',
+ 'model/aodv-rqueue.h',
+ 'model/aodv-packet.h',
+ 'model/aodv-neighbor.h',
+ 'model/aodv-routing-protocol.h',
+ 'helper/aodv-helper.h',
]
+ if bld.env['ENABLE_EXAMPLES']:
+ bld.add_subdirs('examples')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/doc/nix-vector-routing.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Josh Pelkey <jpelkey@gatech.edu>
+ */
+
+/**
+ * \ingroup routing
+ * \defgroup nixvectorrouting Nix-vector Routing
+ *
+ * \section model Model
+ *
+ * Nix-vector routing is a simulation specific routing protocol and is
+ * intended for large network topologies. The on-demand nature of this
+ * protocol as well as the low-memory footprint of the nix-vector provides
+ * improved performance in terms of memory usage and simulation run time
+ * when dealing with a large number of nodes.
+ *
+ * Currently, the ns-3 model of nix-vector routing supports IPv4 p2p links
+ * as well as CSMA links. It does not (yet) provide support for
+ * efficient adaptation to link failures. It simply flushes all nix-vector
+ * routing caches. Finally, IPv6 is not supported.
+ *
+ * \section api API and Usage
+ *
+ * Nix-vector routing has been rolled into a helper class. In order to
+ * utilize these helper functions, users must include ns3/helper-module.h.
+ * The Nix-vector routing protocol must be added to a list of routing
+ * protocols. It is important that list routing is utilized.
+ *
+ * Example:
+ *
+ * Ipv4NixVectorHelper nixRouting;
+ * Ipv4StaticRoutingHelper staticRouting;
+ *
+ * Ipv4ListRoutingHelper list;
+ * list.Add (staticRouting, 0);
+ * list.Add (nixRouting, 10);
+ *
+ * InternetStackHelper stack;
+ * stack.SetRoutingHelper (list);
+ * stack.Install (allNodes);
+ *
+ * \section impl Implementation
+ *
+ * ns-3 nix-vector-routing performs on-demand route computation using
+ * a breadth-first search and an efficient route-storage data structure
+ * known as a nix-vector. When a packet is generated at a node for
+ * transmission, the route is calculated, and the nix-vector is built.
+ * The nix-vector stores an index for each hop along the path, which
+ * corresponds to the neighbor-index. This index is used to determine
+ * which net-device and gateway should be used. To route a packet, the
+ * nix-vector must be transmitted with the packet. At each hop, the
+ * current node extracts the appropriate neighbor-index from the
+ * nix-vector and transmits the packet through the corresponding
+ * net-device. This continues until the packet reaches the destination.
+ * */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/examples/nix-simple.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,119 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
+#include "ns3/ipv4-nix-vector-helper.h"
+
+/*
+ * Simple point to point links:
+ *
+ * n0 -- n1 -- n2 -- n3
+ *
+ * n0 has UdpEchoClient
+ * n3 has UdpEchoServer
+ *
+ * n0 IP: 10.1.1.1
+ * n1 IP: 10.1.1.2, 10.1.2.1
+ * n2 IP: 10.1.2.2, 10.1.3.1
+ * n3 IP: 10.1.3.2
+ *
+ */
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
+
+ int
+main (int argc, char *argv[])
+{
+ LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
+ LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
+
+ NodeContainer nodes12;
+ nodes12.Create (2);
+
+ NodeContainer nodes23;
+ nodes23.Add (nodes12.Get (1));
+ nodes23.Create (1);
+
+ NodeContainer nodes34;
+ nodes34.Add(nodes23.Get (1));
+ nodes34.Create (1);
+
+ PointToPointHelper pointToPoint;
+ pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+ pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+ NodeContainer allNodes = NodeContainer (nodes12, nodes23.Get (1), nodes34.Get (1));
+
+ // NixHelper to install nix-vector routing
+ // on all nodes
+ Ipv4NixVectorHelper nixRouting;
+ Ipv4StaticRoutingHelper staticRouting;
+
+ Ipv4ListRoutingHelper list;
+ list.Add (staticRouting, 0);
+ list.Add (nixRouting, 10);
+
+ InternetStackHelper stack;
+ stack.SetRoutingHelper (list);
+ stack.Install (allNodes);
+
+ NetDeviceContainer devices12;
+ NetDeviceContainer devices23;
+ NetDeviceContainer devices34;
+ devices12 = pointToPoint.Install (nodes12);
+ devices23 = pointToPoint.Install (nodes23);
+ devices34 = pointToPoint.Install (nodes34);
+
+ Ipv4AddressHelper address1;
+ address1.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4AddressHelper address2;
+ address2.SetBase ("10.1.2.0", "255.255.255.0");
+ Ipv4AddressHelper address3;
+ address3.SetBase ("10.1.3.0", "255.255.255.0");
+
+ address1.Assign (devices12);
+ address2.Assign (devices23);
+ Ipv4InterfaceContainer interfaces = address3.Assign (devices34);
+
+ UdpEchoServerHelper echoServer (9);
+
+ ApplicationContainer serverApps = echoServer.Install (nodes34.Get (1));
+ serverApps.Start (Seconds (1.0));
+ serverApps.Stop (Seconds (10.0));
+
+ UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
+ echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
+ echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
+ echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
+
+ ApplicationContainer clientApps = echoClient.Install (nodes12.Get (0));
+ clientApps.Start (Seconds (2.0));
+ clientApps.Stop (Seconds (10.0));
+
+ // Trace routing tables
+ Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-simple.routes", std::ios::out);
+ nixRouting.PrintRoutingTableAllAt (Seconds (8), routingStream);
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/examples/nms-p2p-nix.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,468 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * (c) 2009, GTech Systems, Inc. - Alfred Park <park@gtech-systems.com>
+ *
+ * DARPA NMS Campus Network Model
+ *
+ * This topology replicates the original NMS Campus Network model
+ * with the exception of chord links (which were never utilized in the
+ * original model)
+ * Link Bandwidths and Delays may not be the same as the original
+ * specifications
+ *
+ * The fundamental unit of the NMS model consists of a campus network. The
+ * campus network topology can been seen here:
+ * http://www.nsnam.org/~jpelkey3/nms.png
+ * The number of hosts (default 42) is variable. Finally, an arbitrary
+ * number of these campus networks can be connected together (default 2)
+ * to make very large simulations.
+ */
+
+// for timing functions
+#include <cstdlib>
+#include <sys/time.h>
+#include <fstream>
+
+#include "ns3/core-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/onoff-application.h"
+#include "ns3/packet-sink.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/simulator.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
+#include "ns3/ipv4-nix-vector-helper.h"
+
+using namespace std;
+using namespace ns3;
+
+typedef struct timeval TIMER_TYPE;
+#define TIMER_NOW(_t) gettimeofday(&_t,NULL);
+#define TIMER_SECONDS(_t) ((double)(_t).tv_sec + (_t).tv_usec*1e-6)
+#define TIMER_DIFF(_t1, _t2) (TIMER_SECONDS(_t1)-TIMER_SECONDS(_t2))
+
+NS_LOG_COMPONENT_DEFINE ("CampusNetworkModel");
+
+void Progress ()
+{
+ Time now = Simulator::Now ();
+ Simulator::Schedule (Seconds (0.1), Progress);
+}
+
+int
+main (int argc, char *argv[])
+{
+ TIMER_TYPE t0, t1, t2;
+ TIMER_NOW(t0);
+ cout << " ==== DARPA NMS CAMPUS NETWORK SIMULATION ====" << endl;
+ LogComponentEnable ("OnOffApplication", LOG_LEVEL_INFO);
+
+ int nCN = 2, nLANClients = 42;
+ bool nix = true;
+
+ CommandLine cmd;
+ cmd.AddValue ("CN", "Number of total CNs [2]", nCN);
+ cmd.AddValue ("LAN", "Number of nodes per LAN [42]", nLANClients);
+ cmd.AddValue ("NIX", "Toggle nix-vector routing", nix);
+ cmd.Parse (argc,argv);
+
+ if (nCN < 2)
+ {
+ cout << "Number of total CNs (" << nCN << ") lower than minimum of 2"
+ << endl;
+ return 1;
+ }
+
+ cout << "Number of CNs: " << nCN << ", LAN nodes: " << nLANClients << endl;
+
+ NodeContainer nodes_net0[nCN][3], nodes_net1[nCN][6], nodes_netLR[nCN],
+ nodes_net2[nCN][14], nodes_net2LAN[nCN][7][nLANClients],
+ nodes_net3[nCN][9], nodes_net3LAN[nCN][5][nLANClients];
+ PointToPointHelper p2p_2gb200ms, p2p_1gb5ms, p2p_100mb1ms;
+ InternetStackHelper stack;
+ Ipv4InterfaceContainer ifs, ifs0[nCN][3], ifs1[nCN][6], ifs2[nCN][14],
+ ifs3[nCN][9], ifs2LAN[nCN][7][nLANClients],
+ ifs3LAN[nCN][5][nLANClients];
+ Ipv4AddressHelper address;
+ std::ostringstream oss;
+ p2p_1gb5ms.SetDeviceAttribute ("DataRate", StringValue ("1Gbps"));
+ p2p_1gb5ms.SetChannelAttribute ("Delay", StringValue ("5ms"));
+ p2p_2gb200ms.SetDeviceAttribute ("DataRate", StringValue ("2Gbps"));
+ p2p_2gb200ms.SetChannelAttribute ("Delay", StringValue ("200ms"));
+ p2p_100mb1ms.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
+ p2p_100mb1ms.SetChannelAttribute ("Delay", StringValue ("1ms"));
+
+ // Setup NixVector Routing
+ Ipv4NixVectorHelper nixRouting;
+ Ipv4StaticRoutingHelper staticRouting;
+
+ Ipv4ListRoutingHelper list;
+ list.Add (staticRouting, 0);
+ list.Add (nixRouting, 10);
+
+ if (nix)
+ {
+ stack.SetRoutingHelper (list);
+ }
+
+ // Create Campus Networks
+ for (int z = 0; z < nCN; ++z)
+ {
+ cout << "Creating Campus Network " << z << ":" << endl;
+ // Create Net0
+ cout << " SubNet [ 0";
+ for (int i = 0; i < 3; ++i)
+ {
+ nodes_net0[z][i].Create (1);
+ stack.Install (nodes_net0[z][i]);
+ }
+ nodes_net0[z][0].Add (nodes_net0[z][1].Get (0));
+ nodes_net0[z][1].Add (nodes_net0[z][2].Get (0));
+ nodes_net0[z][2].Add (nodes_net0[z][0].Get (0));
+ NetDeviceContainer ndc0[3];
+ for (int i = 0; i < 3; ++i)
+ {
+ ndc0[i] = p2p_1gb5ms.Install (nodes_net0[z][i]);
+ }
+ // Create Net1
+ cout << " 1";
+ for (int i = 0; i < 6; ++i)
+ {
+ nodes_net1[z][i].Create (1);
+ stack.Install (nodes_net1[z][i]);
+ }
+ nodes_net1[z][0].Add (nodes_net1[z][1].Get (0));
+ nodes_net1[z][2].Add (nodes_net1[z][0].Get (0));
+ nodes_net1[z][3].Add (nodes_net1[z][0].Get (0));
+ nodes_net1[z][4].Add (nodes_net1[z][1].Get (0));
+ nodes_net1[z][5].Add (nodes_net1[z][1].Get (0));
+ NetDeviceContainer ndc1[6];
+ for (int i = 0; i < 6; ++i)
+ {
+ if (i == 1)
+ {
+ continue;
+ }
+ ndc1[i] = p2p_1gb5ms.Install (nodes_net1[z][i]);
+ }
+ // Connect Net0 <-> Net1
+ NodeContainer net0_1;
+ net0_1.Add (nodes_net0[z][2].Get (0));
+ net0_1.Add (nodes_net1[z][0].Get (0));
+ NetDeviceContainer ndc0_1;
+ ndc0_1 = p2p_1gb5ms.Install (net0_1);
+ oss.str("");
+ oss << 10 + z << ".1.252.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc0_1);
+ // Create Net2
+ cout << " 2";
+ for (int i = 0; i < 14; ++i)
+ {
+ nodes_net2[z][i].Create (1);
+ stack.Install (nodes_net2[z][i]);
+ }
+ nodes_net2[z][0].Add (nodes_net2[z][1].Get (0));
+ nodes_net2[z][2].Add (nodes_net2[z][0].Get (0));
+ nodes_net2[z][1].Add (nodes_net2[z][3].Get (0));
+ nodes_net2[z][3].Add (nodes_net2[z][2].Get (0));
+ nodes_net2[z][4].Add (nodes_net2[z][2].Get (0));
+ nodes_net2[z][5].Add (nodes_net2[z][3].Get (0));
+ nodes_net2[z][6].Add (nodes_net2[z][5].Get (0));
+ nodes_net2[z][7].Add (nodes_net2[z][2].Get (0));
+ nodes_net2[z][8].Add (nodes_net2[z][3].Get (0));
+ nodes_net2[z][9].Add (nodes_net2[z][4].Get (0));
+ nodes_net2[z][10].Add (nodes_net2[z][5].Get (0));
+ nodes_net2[z][11].Add (nodes_net2[z][6].Get (0));
+ nodes_net2[z][12].Add (nodes_net2[z][6].Get (0));
+ nodes_net2[z][13].Add (nodes_net2[z][6].Get (0));
+ NetDeviceContainer ndc2[14];
+ for (int i = 0; i < 14; ++i)
+ {
+ ndc2[i] = p2p_1gb5ms.Install (nodes_net2[z][i]);
+ }
+ NetDeviceContainer ndc2LAN[7][nLANClients];
+ for (int i = 0; i < 7; ++i)
+ {
+ oss.str ("");
+ oss << 10 + z << ".4." << 15 + i << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ for (int j = 0; j < nLANClients; ++j)
+ {
+ nodes_net2LAN[z][i][j].Create (1);
+ stack.Install (nodes_net2LAN[z][i][j]);
+ nodes_net2LAN[z][i][j].Add (nodes_net2[z][i+7].Get (0));
+ ndc2LAN[i][j] = p2p_100mb1ms.Install (nodes_net2LAN[z][i][j]);
+ ifs2LAN[z][i][j] = address.Assign (ndc2LAN[i][j]);
+ }
+ }
+ // Create Net3
+ cout << " 3 ]" << endl;
+ for (int i = 0; i < 9; ++i)
+ {
+ nodes_net3[z][i].Create (1);
+ stack.Install(nodes_net3[z][i]);
+ }
+ nodes_net3[z][0].Add (nodes_net3[z][1].Get (0));
+ nodes_net3[z][1].Add (nodes_net3[z][2].Get (0));
+ nodes_net3[z][2].Add (nodes_net3[z][3].Get (0));
+ nodes_net3[z][3].Add (nodes_net3[z][1].Get (0));
+ nodes_net3[z][4].Add (nodes_net3[z][0].Get (0));
+ nodes_net3[z][5].Add (nodes_net3[z][0].Get (0));
+ nodes_net3[z][6].Add (nodes_net3[z][2].Get (0));
+ nodes_net3[z][7].Add (nodes_net3[z][3].Get (0));
+ nodes_net3[z][8].Add (nodes_net3[z][3].Get (0));
+ NetDeviceContainer ndc3[9];
+ for (int i = 0; i < 9; ++i)
+ {
+ ndc3[i] = p2p_1gb5ms.Install (nodes_net3[z][i]);
+ }
+ NetDeviceContainer ndc3LAN[5][nLANClients];
+ for (int i = 0; i < 5; ++i)
+ {
+ oss.str ("");
+ oss << 10 + z << ".5." << 10 + i << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.255");
+ for (int j = 0; j < nLANClients; ++j)
+ {
+ nodes_net3LAN[z][i][j].Create (1);
+ stack.Install (nodes_net3LAN[z][i][j]);
+ nodes_net3LAN[z][i][j].Add (nodes_net3[z][i+4].Get (0));
+ ndc3LAN[i][j] = p2p_100mb1ms.Install (nodes_net3LAN[z][i][j]);
+ ifs3LAN[z][i][j] = address.Assign (ndc3LAN[i][j]);
+ }
+ }
+ cout << " Connecting Subnets..." << endl;
+ // Create Lone Routers (Node 4 & 5)
+ nodes_netLR[z].Create (2);
+ stack.Install (nodes_netLR[z]);
+ NetDeviceContainer ndcLR;
+ ndcLR = p2p_1gb5ms.Install (nodes_netLR[z]);
+ // Connect Net2/Net3 through Lone Routers to Net0
+ NodeContainer net0_4, net0_5, net2_4a, net2_4b, net3_5a, net3_5b;
+ net0_4.Add (nodes_netLR[z].Get (0));
+ net0_4.Add (nodes_net0[z][0].Get (0));
+ net0_5.Add (nodes_netLR[z].Get (1));
+ net0_5.Add (nodes_net0[z][1].Get (0));
+ net2_4a.Add (nodes_netLR[z].Get (0));
+ net2_4a.Add (nodes_net2[z][0].Get (0));
+ net2_4b.Add (nodes_netLR[z].Get (1));
+ net2_4b.Add (nodes_net2[z][1].Get (0));
+ net3_5a.Add (nodes_netLR[z].Get (1));
+ net3_5a.Add (nodes_net3[z][0].Get (0));
+ net3_5b.Add (nodes_netLR[z].Get (1));
+ net3_5b.Add (nodes_net3[z][1].Get (0));
+ NetDeviceContainer ndc0_4, ndc0_5, ndc2_4a, ndc2_4b, ndc3_5a, ndc3_5b;
+ ndc0_4 = p2p_1gb5ms.Install (net0_4);
+ oss.str ("");
+ oss << 10 + z << ".1.253.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc0_4);
+ ndc0_5 = p2p_1gb5ms.Install (net0_5);
+ oss.str ("");
+ oss << 10 + z << ".1.254.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc0_5);
+ ndc2_4a = p2p_1gb5ms.Install (net2_4a);
+ oss.str ("");
+ oss << 10 + z << ".4.253.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc2_4a);
+ ndc2_4b = p2p_1gb5ms.Install (net2_4b);
+ oss.str ("");
+ oss << 10 + z << ".4.254.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc2_4b);
+ ndc3_5a = p2p_1gb5ms.Install (net3_5a);
+ oss.str ("");
+ oss << 10 + z << ".5.253.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc3_5a);
+ ndc3_5b = p2p_1gb5ms.Install (net3_5b);
+ oss.str ("");
+ oss << 10 + z << ".5.254.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc3_5b);
+ // Assign IP addresses
+ cout << " Assigning IP addresses..." << endl;
+ for (int i = 0; i < 3; ++i)
+ {
+ oss.str ("");
+ oss << 10 + z << ".1." << 1 + i << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs0[z][i] = address.Assign (ndc0[i]);
+ }
+ for (int i = 0; i < 6; ++i)
+ {
+ if (i == 1)
+ {
+ continue;
+ }
+ oss.str ("");
+ oss << 10 + z << ".2." << 1 + i << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs1[z][i] = address.Assign (ndc1[i]);
+ }
+ oss.str ("");
+ oss << 10 + z << ".3.1.0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndcLR);
+ for (int i = 0; i < 14; ++i)
+ {
+ oss.str ("");
+ oss << 10 + z << ".4." << 1 + i << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs2[z][i] = address.Assign (ndc2[i]);
+ }
+ for (int i = 0; i < 9; ++i)
+ {
+ oss.str ("");
+ oss << 10 + z << ".5." << 1 + i << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs3[z][i] = address.Assign (ndc3[i]);
+ }
+ }
+ // Create Ring Links
+ if (nCN > 1)
+ {
+ cout << "Forming Ring Topology..." << endl;
+ NodeContainer nodes_ring[nCN];
+ for (int z = 0; z < nCN-1; ++z)
+ {
+ nodes_ring[z].Add (nodes_net0[z][0].Get (0));
+ nodes_ring[z].Add (nodes_net0[z+1][0].Get (0));
+ }
+ nodes_ring[nCN-1].Add (nodes_net0[nCN-1][0].Get (0));
+ nodes_ring[nCN-1].Add (nodes_net0[0][0].Get (0));
+ NetDeviceContainer ndc_ring[nCN];
+ for (int z = 0; z < nCN; ++z)
+ {
+ ndc_ring[z] = p2p_2gb200ms.Install (nodes_ring[z]);
+ oss.str ("");
+ oss << "254.1." << z + 1 << ".0";
+ address.SetBase (oss.str ().c_str (), "255.255.255.0");
+ ifs = address.Assign (ndc_ring[z]);
+ }
+ }
+
+ // Create Traffic Flows
+ cout << "Creating TCP Traffic Flows:" << endl;
+ Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (500000));
+ Config::SetDefault ("ns3::OnOffApplication::OnTime",
+ RandomVariableValue (ConstantVariable (1)));
+ Config::SetDefault ("ns3::OnOffApplication::OffTime",
+ RandomVariableValue (ConstantVariable (0)));
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (512));
+
+ UniformVariable urng;
+ int r1;
+ double r2;
+ for (int z = 0; z < nCN; ++z)
+ {
+ int x = z + 1;
+ if (z == nCN - 1)
+ {
+ x = 0;
+ }
+ // Subnet 2 LANs
+ cout << " Campus Network " << z << " Flows [ Net2 ";
+ for (int i = 0; i < 7; ++i)
+ {
+ for (int j = 0; j < nLANClients; ++j)
+ {
+ // Sinks
+ PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory",
+ InetSocketAddress (Ipv4Address::GetAny (), 9999));
+ ApplicationContainer sinkApp = sinkHelper.Install (
+ nodes_net2LAN[z][i][j].Get (0));
+ sinkApp.Start (Seconds (0.0));
+ // Sources
+ r1 = 2 + (int)(4 * urng.GetValue ());
+ r2 = 10 * urng.GetValue ();
+ OnOffHelper client ("ns3::TcpSocketFactory", Address ());
+ AddressValue remoteAddress(InetSocketAddress (
+ ifs2LAN[z][i][j].GetAddress (0), 9999));
+ client.SetAttribute ("Remote", remoteAddress);
+ ApplicationContainer clientApp;
+ clientApp.Add (client.Install (nodes_net1[x][r1].Get (0)));
+ clientApp.Start (Seconds (r2));
+ }
+ }
+ // Subnet 3 LANs
+ cout << "Net3 ]" << endl;
+ for (int i = 0; i < 5; ++i)
+ {
+ for (int j = 0; j < nLANClients; ++j)
+ {
+ // Sinks
+ PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory",
+ InetSocketAddress (Ipv4Address::GetAny (), 9999));
+ ApplicationContainer sinkApp = sinkHelper.Install (
+ nodes_net3LAN[z][i][j].Get (0));
+ sinkApp.Start (Seconds (0.0));
+ // Sources
+ r1 = 2 + (int)(4 * urng.GetValue ());
+ r2 = 10 * urng.GetValue ();
+ OnOffHelper client ("ns3::TcpSocketFactory", Address ());
+ AddressValue remoteAddress (InetSocketAddress (
+ ifs3LAN[z][i][j].GetAddress (0), 9999));
+ client.SetAttribute ("Remote", remoteAddress);
+ ApplicationContainer clientApp;
+ clientApp.Add (client.Install (nodes_net1[x][r1].Get (0)));
+ clientApp.Start (Seconds (r2));
+ }
+ }
+ }
+
+ cout << "Created " << NodeList::GetNNodes () << " nodes." << endl;
+ TIMER_TYPE routingStart;
+ TIMER_NOW (routingStart);
+
+ if (nix)
+ {
+ // Calculate routing tables
+ cout << "Using Nix-vectors..." << endl;
+ }
+ else
+ {
+ // Calculate routing tables
+ cout << "Populating Global Static Routing Tables..." << endl;
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ }
+
+ TIMER_TYPE routingEnd;
+ TIMER_NOW (routingEnd);
+ cout << "Routing tables population took "
+ << TIMER_DIFF (routingEnd, routingStart) << endl;
+
+ Simulator::ScheduleNow (Progress);
+ cout << "Running simulator..." << endl;
+ TIMER_NOW (t1);
+ Simulator::Stop (Seconds (100.0));
+ Simulator::Run ();
+ TIMER_NOW (t2);
+ cout << "Simulator finished." << endl;
+ Simulator::Destroy ();
+
+ double d1 = TIMER_DIFF (t1, t0), d2 = TIMER_DIFF (t2, t1);
+ cout << "-----" << endl << "Runtime Stats:" << endl;
+ cout << "Simulator init time: " << d1 << endl;
+ cout << "Simulator run time: " << d2 << endl;
+ cout << "Total elapsed time: " << d1+d2 << endl;
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/examples/wscript Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,10 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('nix-simple',
+ ['point-to-point', 'internet', 'nix-vector-routing'])
+ obj.source = 'nix-simple.cc'
+
+ obj = bld.create_ns3_program('nms-p2p-nix',
+ ['point-to-point', 'internet', 'nix-vector-routing'])
+ obj.source = 'nms-p2p-nix.cc'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/helper/ipv4-nix-vector-helper.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Josh Pelkey <jpelkey@gatech.edu>
+ */
+
+#include "ipv4-nix-vector-helper.h"
+#include "ns3/ipv4-nix-vector-routing.h"
+
+namespace ns3 {
+
+Ipv4NixVectorHelper::Ipv4NixVectorHelper ()
+{
+ m_agentFactory.SetTypeId ("ns3::Ipv4NixVectorRouting");
+}
+
+Ipv4NixVectorHelper::Ipv4NixVectorHelper (const Ipv4NixVectorHelper &o)
+ : m_agentFactory (o.m_agentFactory)
+{
+}
+
+Ipv4NixVectorHelper*
+Ipv4NixVectorHelper::Copy (void) const
+{
+ return new Ipv4NixVectorHelper (*this);
+}
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4NixVectorHelper::Create (Ptr<Node> node) const
+{
+ Ptr<Ipv4NixVectorRouting> agent = m_agentFactory.Create<Ipv4NixVectorRouting> ();
+ agent->SetNode(node);
+ node->AggregateObject (agent);
+ return agent;
+}
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/helper/ipv4-nix-vector-helper.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Josh Pelkey <jpelkey@gatech.edu>
+ */
+
+#ifndef IPV4_NIX_VECTOR_HELPER_H
+#define IPV4_NIX_VECTOR_HELPER_H
+
+#include "ns3/object-factory.h"
+#include "ns3/ipv4-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds Nix-vector routing to nodes.
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ *
+ */
+class Ipv4NixVectorHelper : public Ipv4RoutingHelper
+{
+public:
+ /*
+ * Construct an Ipv4NixVectorHelper to make life easier while adding Nix-vector
+ * routing to nodes.
+ */
+ Ipv4NixVectorHelper ();
+
+ /**
+ * \brief Construct an Ipv4NixVectorHelper from another previously
+ * initialized instance (Copy Constructor).
+ */
+ Ipv4NixVectorHelper (const Ipv4NixVectorHelper &);
+
+ /**
+ * \internal
+ * \returns pointer to clone of this Ipv4NixVectorHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ Ipv4NixVectorHelper* Copy (void) const;
+
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+
+private:
+ /**
+ * \internal
+ * \brief Assignment operator declared private and not implemented to disallow
+ * assignment and prevent the compiler from happily inserting its own.
+ */
+ Ipv4NixVectorHelper &operator = (const Ipv4NixVectorHelper &o);
+
+ ObjectFactory m_agentFactory;
+};
+} // namespace ns3
+
+#endif /* IPV4_NIX_VECTOR_HELPER_H */
--- a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,876 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 The Georgia Institute of Technology
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Josh Pelkey <jpelkey@gatech.edu>
- */
-
-#include <queue>
-#include <iomanip>
-
-#include "ns3/log.h"
-#include "ns3/abort.h"
-#include "ns3/names.h"
-#include "ns3/ipv4-list-routing.h"
-
-#include "ipv4-nix-vector-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4NixVectorRouting");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4NixVectorRouting);
-
-TypeId
-Ipv4NixVectorRouting::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Ipv4NixVectorRouting")
- .SetParent<Ipv4RoutingProtocol> ()
- .AddConstructor<Ipv4NixVectorRouting> ()
- ;
- return tid;
-}
-
-Ipv4NixVectorRouting::Ipv4NixVectorRouting ()
-:m_totalNeighbors (0)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv4NixVectorRouting::~Ipv4NixVectorRouting ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv4NixVectorRouting::SetIpv4 (Ptr<Ipv4> ipv4)
-{
- NS_ASSERT (ipv4 != 0);
- NS_ASSERT (m_ipv4 == 0);
- NS_LOG_DEBUG ("Created Ipv4NixVectorProtocol");
-
- m_ipv4 = ipv4;
-}
-
-void
-Ipv4NixVectorRouting::DoDispose ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- m_node = 0;
- m_ipv4 = 0;
-
- Ipv4RoutingProtocol::DoDispose ();
-}
-
-
-void
-Ipv4NixVectorRouting::SetNode (Ptr<Node> node)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- m_node = node;
-}
-
-void
-Ipv4NixVectorRouting::FlushGlobalNixRoutingCache ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
- {
- Ptr<Node> node = *i;
- Ptr<Ipv4NixVectorRouting> rp = node->GetObject<Ipv4NixVectorRouting> ();
- if (!rp)
- {
- continue;
- }
- NS_LOG_LOGIC ("Flushing Nix caches.");
- rp->FlushNixCache ();
- rp->FlushIpv4RouteCache ();
- }
-}
-
-void
-Ipv4NixVectorRouting::FlushNixCache ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_nixCache.clear ();
-}
-
-void
-Ipv4NixVectorRouting::FlushIpv4RouteCache ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_ipv4RouteCache.clear ();
-}
-
-Ptr<NixVector>
-Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest, Ptr<NetDevice> oif)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Ptr<NixVector> nixVector = Create<NixVector> ();
-
- // not in cache, must build the nix vector
- // First, we have to figure out the nodes
- // associated with these IPs
- Ptr<Node> destNode = GetNodeByIp (dest);
- if (destNode == 0)
- {
- NS_LOG_ERROR ("No routing path exists");
- return 0;
- }
-
- // if source == dest, then we have a special case
- // because the node is sending to itself. have to
- // build the nix vector a little differently
- if (source == destNode)
- {
- BuildNixVectorLocal(nixVector);
- return nixVector;
- }
- else
- {
- // otherwise proceed as normal
- // and build the nix vector
- std::vector< Ptr<Node> > parentVector;
-
- BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
-
- if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
- {
- return nixVector;
- }
- else
- {
- NS_LOG_ERROR ("No routing path exists");
- return 0;
- }
- }
-}
-
-Ptr<NixVector>
-Ipv4NixVectorRouting::GetNixVectorInCache (Ipv4Address address)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NixMap_t::iterator iter = m_nixCache.find (address);
- if (iter != m_nixCache.end ())
- {
- NS_LOG_LOGIC ("Found Nix-vector in cache.");
- return iter->second;
- }
-
- // not in cache
- return 0;
-}
-
-Ptr<Ipv4Route>
-Ipv4NixVectorRouting::GetIpv4RouteInCache (Ipv4Address address)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Ipv4RouteMap_t::iterator iter = m_ipv4RouteCache.find (address);
- if (iter != m_ipv4RouteCache.end ())
- {
- NS_LOG_LOGIC ("Found Ipv4Route in cache.");
- return iter->second;
- }
-
- // not in cache
- return 0;
-}
-
-bool
-Ipv4NixVectorRouting::BuildNixVectorLocal (Ptr<NixVector> nixVector)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- uint32_t numberOfDevices = m_node->GetNDevices ();
-
- // here we are building a nix vector to
- // ourself, so we need to find the loopback
- // interface and add that to the nix vector
- Ipv4Address loopback ("127.0.0.1");
- for (uint32_t i = 0; i < numberOfDevices; i++)
- {
- uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(i));
- Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
- if (ifAddr.GetLocal() == loopback)
- {
- NS_LOG_LOGIC ("Adding loopback to nix.");
- NS_LOG_LOGIC ("Adding Nix: " << i << " with " << nixVector->BitCount (numberOfDevices)
- << " bits, for node " << m_node->GetId());
- nixVector->AddNeighborIndex (i, nixVector->BitCount (numberOfDevices));
- return true;
- }
- }
- return false;
-}
-
-bool
-Ipv4NixVectorRouting::BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- if (source == dest)
- {
- return true;
- }
-
- if (parentVector.at (dest) == 0)
- {
- return false;
- }
-
- Ptr<Node> parentNode = parentVector.at (dest);
-
- uint32_t numberOfDevices = parentNode->GetNDevices ();
- uint32_t destId = 0;
- uint32_t totalNeighbors = 0;
-
- // scan through the net devices on the parent node
- // and then look at the nodes adjacent to them
- for (uint32_t i = 0; i < numberOfDevices; i++)
- {
- // Get a net device from the node
- // as well as the channel, and figure
- // out the adjacent net devices
- Ptr<NetDevice> localNetDevice = parentNode->GetDevice (i);
- if (localNetDevice->IsBridge ())
- {
- continue;
- }
- Ptr<Channel> channel = localNetDevice->GetChannel ();
- if (channel == 0)
- {
- continue;
- }
-
- // this function takes in the local net dev, and channnel, and
- // writes to the netDeviceContainer the adjacent net devs
- NetDeviceContainer netDeviceContainer;
- GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
-
- // Finally we can get the adjacent nodes
- // and scan through them. If we find the
- // node that matches "dest" then we can add
- // the index to the nix vector.
- // the index corresponds to the neighbor index
- uint32_t offset = 0;
- for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
- {
- Ptr<Node> remoteNode = (*iter)->GetNode ();
-
- if (remoteNode->GetId () == dest)
- {
- destId = totalNeighbors + offset;
- }
- offset += 1;
- }
-
- totalNeighbors += netDeviceContainer.GetN ();
- }
- NS_LOG_LOGIC ("Adding Nix: " << destId << " with "
- << nixVector->BitCount (totalNeighbors) << " bits, for node " << parentNode->GetId());
- nixVector->AddNeighborIndex (destId, nixVector->BitCount (totalNeighbors));
-
- // recurse through parent vector, grabbing the path
- // and building the nix vector
- BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
- return true;
-}
-
-void
-Ipv4NixVectorRouting::GetAdjacentNetDevices (Ptr<NetDevice> netDevice, Ptr<Channel> channel, NetDeviceContainer & netDeviceContainer)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- for (uint32_t i = 0; i < channel->GetNDevices (); i++)
- {
- Ptr<NetDevice> remoteDevice = channel->GetDevice (i);
- if (remoteDevice != netDevice)
- {
- Ptr<BridgeNetDevice> bd = NetDeviceIsBridged (remoteDevice);
- // we have a bridged device, we need to add all
- // bridged devices
- if (bd)
- {
- NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bd);
- for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
- {
- Ptr<NetDevice> ndBridged = bd->GetBridgePort (j);
- if (ndBridged == remoteDevice)
- {
- NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
- continue;
- }
- Ptr<Channel> chBridged = ndBridged->GetChannel ();
- if (channel == 0)
- {
- continue;
- }
- GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
- }
- }
- else
- {
- netDeviceContainer.Add (channel->GetDevice (i));
- }
- }
- }
-}
-
-Ptr<Node>
-Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NodeContainer allNodes = NodeContainer::GetGlobal ();
- Ptr<Node> destNode;
-
- for (NodeContainer::Iterator i = allNodes.Begin (); i != allNodes.End (); ++i)
- {
- Ptr<Node> node = *i;
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- if (ipv4->GetInterfaceForAddress (dest) != -1)
- {
- destNode = node;
- break;
- }
- }
-
- if (!destNode)
- {
- NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
- return 0;
- }
-
- return destNode;
-}
-
-uint32_t
-Ipv4NixVectorRouting::FindTotalNeighbors ()
-{
- uint32_t numberOfDevices = m_node->GetNDevices ();
- uint32_t totalNeighbors = 0;
-
- // scan through the net devices on the parent node
- // and then look at the nodes adjacent to them
- for (uint32_t i = 0; i < numberOfDevices; i++)
- {
- // Get a net device from the node
- // as well as the channel, and figure
- // out the adjacent net devices
- Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
- Ptr<Channel> channel = localNetDevice->GetChannel ();
- if (channel == 0)
- {
- continue;
- }
-
- // this function takes in the local net dev, and channnel, and
- // writes to the netDeviceContainer the adjacent net devs
- NetDeviceContainer netDeviceContainer;
- GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
-
- totalNeighbors += netDeviceContainer.GetN ();
- }
-
- return totalNeighbors;
-}
-
-Ptr<BridgeNetDevice>
-Ipv4NixVectorRouting::NetDeviceIsBridged (Ptr<NetDevice> nd) const
-{
- NS_LOG_FUNCTION (nd);
-
- Ptr<Node> node = nd->GetNode ();
- uint32_t nDevices = node->GetNDevices();
-
- //
- // There is no bit on a net device that says it is being bridged, so we have
- // to look for bridges on the node to which the device is attached. If we
- // find a bridge, we need to look through its bridge ports (the devices it
- // bridges) to see if we find the device in question.
- //
- for (uint32_t i = 0; i < nDevices; ++i)
- {
- Ptr<NetDevice> ndTest = node->GetDevice(i);
- NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
-
- if (ndTest->IsBridge ())
- {
- NS_LOG_LOGIC ("device " << i << " is a bridge net device");
- Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
- NS_ABORT_MSG_UNLESS (bnd, "Ipv4NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
-
- for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
- {
- NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
- if (bnd->GetBridgePort (j) == nd)
- {
- NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
- return bnd;
- }
- }
- }
- }
- NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
- return 0;
-}
-
-uint32_t
-Ipv4NixVectorRouting::FindNetDeviceForNixIndex (uint32_t nodeIndex, Ipv4Address & gatewayIp)
-{
- uint32_t numberOfDevices = m_node->GetNDevices ();
- uint32_t index = 0;
- uint32_t totalNeighbors = 0;
-
- // scan through the net devices on the parent node
- // and then look at the nodes adjacent to them
- for (uint32_t i = 0; i < numberOfDevices; i++)
- {
- // Get a net device from the node
- // as well as the channel, and figure
- // out the adjacent net devices
- Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
- Ptr<Channel> channel = localNetDevice->GetChannel ();
- if (channel == 0)
- {
- continue;
- }
-
- // this function takes in the local net dev, and channnel, and
- // writes to the netDeviceContainer the adjacent net devs
- NetDeviceContainer netDeviceContainer;
- GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
-
- // check how many neighbors we have
- if (nodeIndex < (totalNeighbors + netDeviceContainer.GetN ()))
- {
- // found the proper net device
- index = i;
- Ptr<NetDevice> gatewayDevice = netDeviceContainer.Get (nodeIndex-totalNeighbors);
- Ptr<Node> gatewayNode = gatewayDevice->GetNode ();
- Ptr<Ipv4> ipv4 = gatewayNode->GetObject<Ipv4> ();
-
- uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(gatewayDevice);
- Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (interfaceIndex, 0);
- gatewayIp = ifAddr.GetLocal ();
- break;
- }
- totalNeighbors += netDeviceContainer.GetN ();
- }
-
- return index;
-}
-
-Ptr<Ipv4Route>
-Ipv4NixVectorRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- Ptr<Ipv4Route> rtentry;
- Ptr<NixVector> nixVectorInCache;
- Ptr<NixVector> nixVectorForPacket;
-
- NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
- // check if cache
- nixVectorInCache = GetNixVectorInCache(header.GetDestination ());
-
- // not in cache
- if (!nixVectorInCache)
- {
- NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
- // Build the nix-vector, given this node and the
- // dest IP address
- nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
-
- // cache it
- m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
- }
-
- // path exists
- if (nixVectorInCache)
- {
- NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
-
- // create a new nix vector to be used,
- // we want to keep the cached version clean
- nixVectorForPacket = Create<NixVector> ();
- nixVectorForPacket = nixVectorInCache->Copy ();
-
- // Get the interface number that we go out of, by extracting
- // from the nix-vector
- if (m_totalNeighbors == 0)
- {
- m_totalNeighbors = FindTotalNeighbors ();
- }
-
- // Get the interface number that we go out of, by extracting
- // from the nix-vector
- uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
- uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
-
- // Search here in a cache for this node index
- // and look for a Ipv4Route
- rtentry = GetIpv4RouteInCache (header.GetDestination ());
-
- if (!rtentry || !(rtentry->GetOutputDevice () == oif))
- {
- // not in cache or a different specified output
- // device is to be used
-
- // first, make sure we erase existing (incorrect)
- // rtentry from the map
- if (rtentry)
- {
- m_ipv4RouteCache.erase(header.GetDestination ());
- }
-
- NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
- Ipv4Address gatewayIp;
- uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
- int32_t interfaceIndex = 0;
-
- if (!oif)
- {
- interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
- }
- else
- {
- interfaceIndex = (m_ipv4)->GetInterfaceForDevice(oif);
- }
-
- NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
-
- Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
-
- // start filling in the Ipv4Route info
- rtentry = Create<Ipv4Route> ();
- rtentry->SetSource (ifAddr.GetLocal ());
-
- rtentry->SetGateway (gatewayIp);
- rtentry->SetDestination (header.GetDestination ());
-
- if (!oif)
- {
- rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
- }
- else
- {
- rtentry->SetOutputDevice (oif);
- }
-
- sockerr = Socket::ERROR_NOTERROR;
-
- // add rtentry to cache
- m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
- }
-
- NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits());
-
- // Add nix-vector in the packet class
- // make sure the packet exists first
- if (p)
- {
- NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
- p->SetNixVector (nixVectorForPacket);
- }
- }
- else // path doesn't exist
- {
- NS_LOG_ERROR ("No path to the dest: " << header.GetDestination ());
- sockerr = Socket::ERROR_NOROUTETOHOST;
- }
-
- return rtentry;
-}
-
-bool
-Ipv4NixVectorRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Ptr<Ipv4Route> rtentry;
-
- // Get the nix-vector from the packet
- Ptr<NixVector> nixVector = p->GetNixVector();
-
- // If nixVector isn't in packet, something went wrong
- NS_ASSERT (nixVector);
-
- // Get the interface number that we go out of, by extracting
- // from the nix-vector
- if (m_totalNeighbors == 0)
- {
- m_totalNeighbors = FindTotalNeighbors ();
- }
- uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
- uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
-
- rtentry = GetIpv4RouteInCache (header.GetDestination ());
- // not in cache
- if (!rtentry)
- {
- NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
- Ipv4Address gatewayIp;
- uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
- uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
- Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
-
- // start filling in the Ipv4Route info
- rtentry = Create<Ipv4Route> ();
- rtentry->SetSource (ifAddr.GetLocal ());
-
- rtentry->SetGateway (gatewayIp);
- rtentry->SetDestination (header.GetDestination ());
- rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
-
- // add rtentry to cache
- m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
- }
-
- NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits <<
- " bits from Nix-vector: " << nixVector << " : " << *nixVector);
-
- // call the unicast callback
- // local deliver is handled by Ipv4StaticRoutingImpl
- // so this code is never even called if the packet is
- // destined for this node.
- ucb (rtentry, p, header);
-
- return true;
-}
-
-void
-Ipv4NixVectorRouting::PrintRoutingTable(Ptr<OutputStreamWrapper> stream) const
-{
-
- std::ostream* os = stream->GetStream();
- *os << "NixCache:" << std::endl;
- if (m_nixCache.size () > 0)
- {
- *os << "Destination NixVector" << std::endl;
- for (NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
- {
- std::ostringstream dest;
- dest << it->first;
- *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
- *os << *(it->second) << std::endl;
- }
- }
- *os << "Ipv4RouteCache:" << std::endl;
- if (m_ipv4RouteCache.size () > 0)
- {
- *os << "Destination Gateway Source OutputDevice" << std::endl;
- for (Ipv4RouteMap_t::const_iterator it = m_ipv4RouteCache.begin (); it != m_ipv4RouteCache.end (); it++)
- {
- std::ostringstream dest, gw, src;
- dest << it->second->GetDestination ();
- *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
- gw << it->second->GetGateway ();
- *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str();
- src << it->second->GetSource ();
- *os << std::setiosflags (std::ios::left) << std::setw (16) << src.str();
- *os << " ";
- if (Names::FindName (it->second->GetOutputDevice ()) != "")
- {
- *os << Names::FindName (it->second->GetOutputDevice ());
- }
- else
- {
- *os << it->second->GetOutputDevice ()->GetIfIndex ();
- }
- *os << std::endl;
- }
- }
-}
-
-// virtual functions from Ipv4RoutingProtocol
-void
-Ipv4NixVectorRouting::NotifyInterfaceUp (uint32_t i)
-{
- FlushGlobalNixRoutingCache ();
-}
-void
-Ipv4NixVectorRouting::NotifyInterfaceDown (uint32_t i)
-{
- FlushGlobalNixRoutingCache ();
-}
-void
-Ipv4NixVectorRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
- FlushGlobalNixRoutingCache ();
-}
-void
-Ipv4NixVectorRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
- FlushGlobalNixRoutingCache ();
-}
-
-bool
-Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source,
- Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
- Ptr<NetDevice> oif)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NS_LOG_LOGIC ("Going from Node " << source->GetId() << " to Node " << dest->GetId());
- std::queue< Ptr<Node> > greyNodeList; // discovered nodes with unexplored children
-
- // reset the parent vector
- parentVector.clear ();
- parentVector.reserve (sizeof (Ptr<Node>)*numberOfNodes);
- parentVector.insert (parentVector.begin (), sizeof (Ptr<Node>)*numberOfNodes, 0); // initialize to 0
-
- // Add the source node to the queue, set its parent to itself
- greyNodeList.push (source);
- parentVector.at (source->GetId()) = source;
-
- // BFS loop
- while (greyNodeList.size () != 0)
- {
- Ptr<Node> currNode = greyNodeList.front ();
- Ptr<Ipv4> ipv4 = currNode->GetObject<Ipv4> ();
-
- if (currNode == dest)
- {
- NS_LOG_LOGIC ("Made it to Node " << currNode->GetId());
- return true;
- }
-
- // if this is the first iteration of the loop and a
- // specific output interface was given, make sure
- // we go this way
- if (currNode == source && oif)
- {
- // make sure that we can go this way
- if (ipv4)
- {
- uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(oif);
- if (!(ipv4->IsUp (interfaceIndex)))
- {
- NS_LOG_LOGIC ("Ipv4Interface is down");
- return false;
- }
- }
- if (!(oif->IsLinkUp ()))
- {
- NS_LOG_LOGIC ("Link is down.");
- return false;
- }
- Ptr<Channel> channel = oif->GetChannel ();
- if (channel == 0)
- {
- return false;
- }
-
- // this function takes in the local net dev, and channnel, and
- // writes to the netDeviceContainer the adjacent net devs
- NetDeviceContainer netDeviceContainer;
- GetAdjacentNetDevices (oif, channel, netDeviceContainer);
-
- // Finally we can get the adjacent nodes
- // and scan through them. We push them
- // to the greyNode queue, if they aren't
- // already there.
- for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
- {
- Ptr<Node> remoteNode = (*iter)->GetNode ();
-
- // check to see if this node has been pushed before
- // by checking to see if it has a parent
- // if it doesn't (null or 0), then set its parent and
- // push to the queue
- if (parentVector.at (remoteNode->GetId ()) == 0)
- {
- parentVector.at (remoteNode->GetId ()) = currNode;
- greyNodeList.push (remoteNode);
- }
- }
- }
- else
- {
- // Iterate over the current node's adjacent vertices
- // and push them into the queue
- for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
- {
- // Get a net device from the node
- // as well as the channel, and figure
- // out the adjacent net device
- Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
-
- // make sure that we can go this way
- if (ipv4)
- {
- uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
- if (!(ipv4->IsUp (interfaceIndex)))
- {
- NS_LOG_LOGIC ("Ipv4Interface is down");
- continue;
- }
- }
- if (!(localNetDevice->IsLinkUp ()))
- {
- NS_LOG_LOGIC ("Link is down.");
- continue;
- }
- Ptr<Channel> channel = localNetDevice->GetChannel ();
- if (channel == 0)
- {
- continue;
- }
-
- // this function takes in the local net dev, and channnel, and
- // writes to the netDeviceContainer the adjacent net devs
- NetDeviceContainer netDeviceContainer;
- GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
-
- // Finally we can get the adjacent nodes
- // and scan through them. We push them
- // to the greyNode queue, if they aren't
- // already there.
- for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
- {
- Ptr<Node> remoteNode = (*iter)->GetNode ();
-
- // check to see if this node has been pushed before
- // by checking to see if it has a parent
- // if it doesn't (null or 0), then set its parent and
- // push to the queue
- if (parentVector.at (remoteNode->GetId ()) == 0)
- {
- parentVector.at (remoteNode->GetId ()) = currNode;
- greyNodeList.push (remoteNode);
- }
- }
- }
- }
-
- // Pop off the head grey node. We have all its children.
- // It is now black.
- greyNodeList.pop ();
- }
-
- // Didn't find the dest...
- return false;
-}
-
-} // namespace ns3
--- a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 The Georgia Institute of Technology
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Josh Pelkey <jpelkey@gatech.edu>
- */
-
-#ifndef __IPV4_NIX_VECTOR_ROUTING_H__
-#define __IPV4_NIX_VECTOR_ROUTING_H__
-
-#include <map>
-
-#include "ns3/channel.h"
-#include "ns3/node-container.h"
-#include "ns3/node-list.h"
-#include "ns3/net-device-container.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/nix-vector.h"
-#include "ns3/bridge-net-device.h"
-
-namespace ns3 {
-
-/**
- * Map of Ipv4Address to NixVector
- */
-typedef std::map<Ipv4Address, Ptr<NixVector> > NixMap_t;
-/**
- * Map of Ipv4Address to Ipv4Route
- */
-typedef std::map<Ipv4Address, Ptr<Ipv4Route> > Ipv4RouteMap_t;
-
-/**
- * Nix-vector routing protocol
- */
-class Ipv4NixVectorRouting : public Ipv4RoutingProtocol
-{
- public:
- Ipv4NixVectorRouting ();
- ~Ipv4NixVectorRouting ();
- /**
- * @brief The Interface ID of the Global Router interface.
- *
- * @see Object::GetObject ()
- */
- static TypeId GetTypeId (void);
- /**
- * @brief Set the Node pointer of the node for which this
- * routing protocol is to be placed
- *
- * @param node Node pointer
- */
- void SetNode (Ptr<Node> node);
-
- /**
- * @brief Called when run-time link topology change occurs
- * which iterates through the node list and flushes any
- * nix vector caches
- *
- */
- void FlushGlobalNixRoutingCache (void);
-
- private:
- /* flushes the cache which stores nix-vector based on
- * destination IP */
- void FlushNixCache (void);
-
- /* flushes the cache which stores the Ipv4 route
- * based on the destination IP */
- void FlushIpv4RouteCache (void);
-
- /* upon a run-time topology change caches are
- * flushed and the total number of neighbors is
- * reset to zero */
- void ResetTotalNeighbors (void);
-
- /* takes in the source node and dest IP and calls GetNodeByIp,
- * BFS, accounting for any output interface specified, and finally
- * BuildNixVector to return the built nix-vector */
- Ptr<NixVector> GetNixVector (Ptr<Node>, Ipv4Address, Ptr<NetDevice>);
-
- /* checks the cache based on dest IP for the nix-vector */
- Ptr<NixVector> GetNixVectorInCache (Ipv4Address);
-
- /* checks the cache based on dest IP for the Ipv4Route */
- Ptr<Ipv4Route> GetIpv4RouteInCache (Ipv4Address);
-
- /* given a net-device returns all the adjacent net-devices,
- * essentially getting the neighbors on that channel */
- void GetAdjacentNetDevices (Ptr<NetDevice>, Ptr<Channel>, NetDeviceContainer &);
-
- /* iterates through the node list and finds the one
- * corresponding to the given Ipv4Address */
- Ptr<Node> GetNodeByIp (Ipv4Address);
-
- /* Recurses the parent vector, created by BFS and actually builds the nixvector */
- bool BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector);
-
- /* special variation of BuildNixVector for when a node is sending to itself */
- bool BuildNixVectorLocal (Ptr<NixVector> nixVector);
-
- /* simple iterates through the nodes net-devices and determines
- * how many neighbors it has */
- uint32_t FindTotalNeighbors (void);
-
- /* determine if the netdevice is bridged */
- Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
-
-
- /* Nix index is with respect to the neighbors. The net-device index must be
- * derived from this */
- uint32_t FindNetDeviceForNixIndex (uint32_t nodeIndex, Ipv4Address & gatewayIp);
-
- /* Breadth first search algorithm
- * Param1: total number of nodes
- * Param2: Source Node
- * Param3: Dest Node
- * Param4: (returned) Parent vector for retracing routes
- * Param5: specific output interface to use from source node, if not null
- * Returns: false if dest not found, true o.w.
- */
- bool BFS (uint32_t numberOfNodes,
- Ptr<Node> source,
- Ptr<Node> dest,
- std::vector< Ptr<Node> > & parentVector,
- Ptr<NetDevice> oif);
-
- void DoDispose (void);
-
- /* 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;
-
-
- /* cache stores nix-vectors based on destination ip */
- NixMap_t m_nixCache;
-
- /* cache stores Ipv4Routes based on destination ip */
- Ipv4RouteMap_t m_ipv4RouteCache;
-
- Ptr<Ipv4> m_ipv4;
- Ptr<Node> m_node;
-
- /* total neighbors used for nix-vector to determine
- * number of bits */
- uint32_t m_totalNeighbors;
-};
-} // namespace ns3
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/model/ipv4-nix-vector-routing.cc Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,876 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Josh Pelkey <jpelkey@gatech.edu>
+ */
+
+#include <queue>
+#include <iomanip>
+
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/names.h"
+#include "ns3/ipv4-list-routing.h"
+
+#include "ipv4-nix-vector-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4NixVectorRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4NixVectorRouting);
+
+TypeId
+Ipv4NixVectorRouting::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv4NixVectorRouting")
+ .SetParent<Ipv4RoutingProtocol> ()
+ .AddConstructor<Ipv4NixVectorRouting> ()
+ ;
+ return tid;
+}
+
+Ipv4NixVectorRouting::Ipv4NixVectorRouting ()
+:m_totalNeighbors (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv4NixVectorRouting::~Ipv4NixVectorRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv4NixVectorRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+ NS_ASSERT (ipv4 != 0);
+ NS_ASSERT (m_ipv4 == 0);
+ NS_LOG_DEBUG ("Created Ipv4NixVectorProtocol");
+
+ m_ipv4 = ipv4;
+}
+
+void
+Ipv4NixVectorRouting::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ m_node = 0;
+ m_ipv4 = 0;
+
+ Ipv4RoutingProtocol::DoDispose ();
+}
+
+
+void
+Ipv4NixVectorRouting::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ m_node = node;
+}
+
+void
+Ipv4NixVectorRouting::FlushGlobalNixRoutingCache ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+ Ptr<Ipv4NixVectorRouting> rp = node->GetObject<Ipv4NixVectorRouting> ();
+ if (!rp)
+ {
+ continue;
+ }
+ NS_LOG_LOGIC ("Flushing Nix caches.");
+ rp->FlushNixCache ();
+ rp->FlushIpv4RouteCache ();
+ }
+}
+
+void
+Ipv4NixVectorRouting::FlushNixCache ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_nixCache.clear ();
+}
+
+void
+Ipv4NixVectorRouting::FlushIpv4RouteCache ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_ipv4RouteCache.clear ();
+}
+
+Ptr<NixVector>
+Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest, Ptr<NetDevice> oif)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ Ptr<NixVector> nixVector = Create<NixVector> ();
+
+ // not in cache, must build the nix vector
+ // First, we have to figure out the nodes
+ // associated with these IPs
+ Ptr<Node> destNode = GetNodeByIp (dest);
+ if (destNode == 0)
+ {
+ NS_LOG_ERROR ("No routing path exists");
+ return 0;
+ }
+
+ // if source == dest, then we have a special case
+ // because the node is sending to itself. have to
+ // build the nix vector a little differently
+ if (source == destNode)
+ {
+ BuildNixVectorLocal(nixVector);
+ return nixVector;
+ }
+ else
+ {
+ // otherwise proceed as normal
+ // and build the nix vector
+ std::vector< Ptr<Node> > parentVector;
+
+ BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
+
+ if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
+ {
+ return nixVector;
+ }
+ else
+ {
+ NS_LOG_ERROR ("No routing path exists");
+ return 0;
+ }
+ }
+}
+
+Ptr<NixVector>
+Ipv4NixVectorRouting::GetNixVectorInCache (Ipv4Address address)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NixMap_t::iterator iter = m_nixCache.find (address);
+ if (iter != m_nixCache.end ())
+ {
+ NS_LOG_LOGIC ("Found Nix-vector in cache.");
+ return iter->second;
+ }
+
+ // not in cache
+ return 0;
+}
+
+Ptr<Ipv4Route>
+Ipv4NixVectorRouting::GetIpv4RouteInCache (Ipv4Address address)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ Ipv4RouteMap_t::iterator iter = m_ipv4RouteCache.find (address);
+ if (iter != m_ipv4RouteCache.end ())
+ {
+ NS_LOG_LOGIC ("Found Ipv4Route in cache.");
+ return iter->second;
+ }
+
+ // not in cache
+ return 0;
+}
+
+bool
+Ipv4NixVectorRouting::BuildNixVectorLocal (Ptr<NixVector> nixVector)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ uint32_t numberOfDevices = m_node->GetNDevices ();
+
+ // here we are building a nix vector to
+ // ourself, so we need to find the loopback
+ // interface and add that to the nix vector
+ Ipv4Address loopback ("127.0.0.1");
+ for (uint32_t i = 0; i < numberOfDevices; i++)
+ {
+ uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(i));
+ Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
+ if (ifAddr.GetLocal() == loopback)
+ {
+ NS_LOG_LOGIC ("Adding loopback to nix.");
+ NS_LOG_LOGIC ("Adding Nix: " << i << " with " << nixVector->BitCount (numberOfDevices)
+ << " bits, for node " << m_node->GetId());
+ nixVector->AddNeighborIndex (i, nixVector->BitCount (numberOfDevices));
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+Ipv4NixVectorRouting::BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (source == dest)
+ {
+ return true;
+ }
+
+ if (parentVector.at (dest) == 0)
+ {
+ return false;
+ }
+
+ Ptr<Node> parentNode = parentVector.at (dest);
+
+ uint32_t numberOfDevices = parentNode->GetNDevices ();
+ uint32_t destId = 0;
+ uint32_t totalNeighbors = 0;
+
+ // scan through the net devices on the parent node
+ // and then look at the nodes adjacent to them
+ for (uint32_t i = 0; i < numberOfDevices; i++)
+ {
+ // Get a net device from the node
+ // as well as the channel, and figure
+ // out the adjacent net devices
+ Ptr<NetDevice> localNetDevice = parentNode->GetDevice (i);
+ if (localNetDevice->IsBridge ())
+ {
+ continue;
+ }
+ Ptr<Channel> channel = localNetDevice->GetChannel ();
+ if (channel == 0)
+ {
+ continue;
+ }
+
+ // this function takes in the local net dev, and channnel, and
+ // writes to the netDeviceContainer the adjacent net devs
+ NetDeviceContainer netDeviceContainer;
+ GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
+
+ // Finally we can get the adjacent nodes
+ // and scan through them. If we find the
+ // node that matches "dest" then we can add
+ // the index to the nix vector.
+ // the index corresponds to the neighbor index
+ uint32_t offset = 0;
+ for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
+ {
+ Ptr<Node> remoteNode = (*iter)->GetNode ();
+
+ if (remoteNode->GetId () == dest)
+ {
+ destId = totalNeighbors + offset;
+ }
+ offset += 1;
+ }
+
+ totalNeighbors += netDeviceContainer.GetN ();
+ }
+ NS_LOG_LOGIC ("Adding Nix: " << destId << " with "
+ << nixVector->BitCount (totalNeighbors) << " bits, for node " << parentNode->GetId());
+ nixVector->AddNeighborIndex (destId, nixVector->BitCount (totalNeighbors));
+
+ // recurse through parent vector, grabbing the path
+ // and building the nix vector
+ BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
+ return true;
+}
+
+void
+Ipv4NixVectorRouting::GetAdjacentNetDevices (Ptr<NetDevice> netDevice, Ptr<Channel> channel, NetDeviceContainer & netDeviceContainer)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ for (uint32_t i = 0; i < channel->GetNDevices (); i++)
+ {
+ Ptr<NetDevice> remoteDevice = channel->GetDevice (i);
+ if (remoteDevice != netDevice)
+ {
+ Ptr<BridgeNetDevice> bd = NetDeviceIsBridged (remoteDevice);
+ // we have a bridged device, we need to add all
+ // bridged devices
+ if (bd)
+ {
+ NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bd);
+ for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
+ {
+ Ptr<NetDevice> ndBridged = bd->GetBridgePort (j);
+ if (ndBridged == remoteDevice)
+ {
+ NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
+ continue;
+ }
+ Ptr<Channel> chBridged = ndBridged->GetChannel ();
+ if (channel == 0)
+ {
+ continue;
+ }
+ GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
+ }
+ }
+ else
+ {
+ netDeviceContainer.Add (channel->GetDevice (i));
+ }
+ }
+ }
+}
+
+Ptr<Node>
+Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NodeContainer allNodes = NodeContainer::GetGlobal ();
+ Ptr<Node> destNode;
+
+ for (NodeContainer::Iterator i = allNodes.Begin (); i != allNodes.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ if (ipv4->GetInterfaceForAddress (dest) != -1)
+ {
+ destNode = node;
+ break;
+ }
+ }
+
+ if (!destNode)
+ {
+ NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
+ return 0;
+ }
+
+ return destNode;
+}
+
+uint32_t
+Ipv4NixVectorRouting::FindTotalNeighbors ()
+{
+ uint32_t numberOfDevices = m_node->GetNDevices ();
+ uint32_t totalNeighbors = 0;
+
+ // scan through the net devices on the parent node
+ // and then look at the nodes adjacent to them
+ for (uint32_t i = 0; i < numberOfDevices; i++)
+ {
+ // Get a net device from the node
+ // as well as the channel, and figure
+ // out the adjacent net devices
+ Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
+ Ptr<Channel> channel = localNetDevice->GetChannel ();
+ if (channel == 0)
+ {
+ continue;
+ }
+
+ // this function takes in the local net dev, and channnel, and
+ // writes to the netDeviceContainer the adjacent net devs
+ NetDeviceContainer netDeviceContainer;
+ GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
+
+ totalNeighbors += netDeviceContainer.GetN ();
+ }
+
+ return totalNeighbors;
+}
+
+Ptr<BridgeNetDevice>
+Ipv4NixVectorRouting::NetDeviceIsBridged (Ptr<NetDevice> nd) const
+{
+ NS_LOG_FUNCTION (nd);
+
+ Ptr<Node> node = nd->GetNode ();
+ uint32_t nDevices = node->GetNDevices();
+
+ //
+ // There is no bit on a net device that says it is being bridged, so we have
+ // to look for bridges on the node to which the device is attached. If we
+ // find a bridge, we need to look through its bridge ports (the devices it
+ // bridges) to see if we find the device in question.
+ //
+ for (uint32_t i = 0; i < nDevices; ++i)
+ {
+ Ptr<NetDevice> ndTest = node->GetDevice(i);
+ NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
+
+ if (ndTest->IsBridge ())
+ {
+ NS_LOG_LOGIC ("device " << i << " is a bridge net device");
+ Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
+ NS_ABORT_MSG_UNLESS (bnd, "Ipv4NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
+
+ for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+ {
+ NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
+ if (bnd->GetBridgePort (j) == nd)
+ {
+ NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
+ return bnd;
+ }
+ }
+ }
+ }
+ NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
+ return 0;
+}
+
+uint32_t
+Ipv4NixVectorRouting::FindNetDeviceForNixIndex (uint32_t nodeIndex, Ipv4Address & gatewayIp)
+{
+ uint32_t numberOfDevices = m_node->GetNDevices ();
+ uint32_t index = 0;
+ uint32_t totalNeighbors = 0;
+
+ // scan through the net devices on the parent node
+ // and then look at the nodes adjacent to them
+ for (uint32_t i = 0; i < numberOfDevices; i++)
+ {
+ // Get a net device from the node
+ // as well as the channel, and figure
+ // out the adjacent net devices
+ Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
+ Ptr<Channel> channel = localNetDevice->GetChannel ();
+ if (channel == 0)
+ {
+ continue;
+ }
+
+ // this function takes in the local net dev, and channnel, and
+ // writes to the netDeviceContainer the adjacent net devs
+ NetDeviceContainer netDeviceContainer;
+ GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
+
+ // check how many neighbors we have
+ if (nodeIndex < (totalNeighbors + netDeviceContainer.GetN ()))
+ {
+ // found the proper net device
+ index = i;
+ Ptr<NetDevice> gatewayDevice = netDeviceContainer.Get (nodeIndex-totalNeighbors);
+ Ptr<Node> gatewayNode = gatewayDevice->GetNode ();
+ Ptr<Ipv4> ipv4 = gatewayNode->GetObject<Ipv4> ();
+
+ uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(gatewayDevice);
+ Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (interfaceIndex, 0);
+ gatewayIp = ifAddr.GetLocal ();
+ break;
+ }
+ totalNeighbors += netDeviceContainer.GetN ();
+ }
+
+ return index;
+}
+
+Ptr<Ipv4Route>
+Ipv4NixVectorRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv4Route> rtentry;
+ Ptr<NixVector> nixVectorInCache;
+ Ptr<NixVector> nixVectorForPacket;
+
+ NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
+ // check if cache
+ nixVectorInCache = GetNixVectorInCache(header.GetDestination ());
+
+ // not in cache
+ if (!nixVectorInCache)
+ {
+ NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
+ // Build the nix-vector, given this node and the
+ // dest IP address
+ nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
+
+ // cache it
+ m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
+ }
+
+ // path exists
+ if (nixVectorInCache)
+ {
+ NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
+
+ // create a new nix vector to be used,
+ // we want to keep the cached version clean
+ nixVectorForPacket = Create<NixVector> ();
+ nixVectorForPacket = nixVectorInCache->Copy ();
+
+ // Get the interface number that we go out of, by extracting
+ // from the nix-vector
+ if (m_totalNeighbors == 0)
+ {
+ m_totalNeighbors = FindTotalNeighbors ();
+ }
+
+ // Get the interface number that we go out of, by extracting
+ // from the nix-vector
+ uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
+ uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
+
+ // Search here in a cache for this node index
+ // and look for a Ipv4Route
+ rtentry = GetIpv4RouteInCache (header.GetDestination ());
+
+ if (!rtentry || !(rtentry->GetOutputDevice () == oif))
+ {
+ // not in cache or a different specified output
+ // device is to be used
+
+ // first, make sure we erase existing (incorrect)
+ // rtentry from the map
+ if (rtentry)
+ {
+ m_ipv4RouteCache.erase(header.GetDestination ());
+ }
+
+ NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
+ Ipv4Address gatewayIp;
+ uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
+ int32_t interfaceIndex = 0;
+
+ if (!oif)
+ {
+ interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
+ }
+ else
+ {
+ interfaceIndex = (m_ipv4)->GetInterfaceForDevice(oif);
+ }
+
+ NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
+
+ Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
+
+ // start filling in the Ipv4Route info
+ rtentry = Create<Ipv4Route> ();
+ rtentry->SetSource (ifAddr.GetLocal ());
+
+ rtentry->SetGateway (gatewayIp);
+ rtentry->SetDestination (header.GetDestination ());
+
+ if (!oif)
+ {
+ rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
+ }
+ else
+ {
+ rtentry->SetOutputDevice (oif);
+ }
+
+ sockerr = Socket::ERROR_NOTERROR;
+
+ // add rtentry to cache
+ m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
+ }
+
+ NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits());
+
+ // Add nix-vector in the packet class
+ // make sure the packet exists first
+ if (p)
+ {
+ NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
+ p->SetNixVector (nixVectorForPacket);
+ }
+ }
+ else // path doesn't exist
+ {
+ NS_LOG_ERROR ("No path to the dest: " << header.GetDestination ());
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ }
+
+ return rtentry;
+}
+
+bool
+Ipv4NixVectorRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ Ptr<Ipv4Route> rtentry;
+
+ // Get the nix-vector from the packet
+ Ptr<NixVector> nixVector = p->GetNixVector();
+
+ // If nixVector isn't in packet, something went wrong
+ NS_ASSERT (nixVector);
+
+ // Get the interface number that we go out of, by extracting
+ // from the nix-vector
+ if (m_totalNeighbors == 0)
+ {
+ m_totalNeighbors = FindTotalNeighbors ();
+ }
+ uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
+ uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
+
+ rtentry = GetIpv4RouteInCache (header.GetDestination ());
+ // not in cache
+ if (!rtentry)
+ {
+ NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
+ Ipv4Address gatewayIp;
+ uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
+ uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
+ Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
+
+ // start filling in the Ipv4Route info
+ rtentry = Create<Ipv4Route> ();
+ rtentry->SetSource (ifAddr.GetLocal ());
+
+ rtentry->SetGateway (gatewayIp);
+ rtentry->SetDestination (header.GetDestination ());
+ rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
+
+ // add rtentry to cache
+ m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
+ }
+
+ NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits <<
+ " bits from Nix-vector: " << nixVector << " : " << *nixVector);
+
+ // call the unicast callback
+ // local deliver is handled by Ipv4StaticRoutingImpl
+ // so this code is never even called if the packet is
+ // destined for this node.
+ ucb (rtentry, p, header);
+
+ return true;
+}
+
+void
+Ipv4NixVectorRouting::PrintRoutingTable(Ptr<OutputStreamWrapper> stream) const
+{
+
+ std::ostream* os = stream->GetStream();
+ *os << "NixCache:" << std::endl;
+ if (m_nixCache.size () > 0)
+ {
+ *os << "Destination NixVector" << std::endl;
+ for (NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
+ {
+ std::ostringstream dest;
+ dest << it->first;
+ *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
+ *os << *(it->second) << std::endl;
+ }
+ }
+ *os << "Ipv4RouteCache:" << std::endl;
+ if (m_ipv4RouteCache.size () > 0)
+ {
+ *os << "Destination Gateway Source OutputDevice" << std::endl;
+ for (Ipv4RouteMap_t::const_iterator it = m_ipv4RouteCache.begin (); it != m_ipv4RouteCache.end (); it++)
+ {
+ std::ostringstream dest, gw, src;
+ dest << it->second->GetDestination ();
+ *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
+ gw << it->second->GetGateway ();
+ *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str();
+ src << it->second->GetSource ();
+ *os << std::setiosflags (std::ios::left) << std::setw (16) << src.str();
+ *os << " ";
+ if (Names::FindName (it->second->GetOutputDevice ()) != "")
+ {
+ *os << Names::FindName (it->second->GetOutputDevice ());
+ }
+ else
+ {
+ *os << it->second->GetOutputDevice ()->GetIfIndex ();
+ }
+ *os << std::endl;
+ }
+ }
+}
+
+// virtual functions from Ipv4RoutingProtocol
+void
+Ipv4NixVectorRouting::NotifyInterfaceUp (uint32_t i)
+{
+ FlushGlobalNixRoutingCache ();
+}
+void
+Ipv4NixVectorRouting::NotifyInterfaceDown (uint32_t i)
+{
+ FlushGlobalNixRoutingCache ();
+}
+void
+Ipv4NixVectorRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+ FlushGlobalNixRoutingCache ();
+}
+void
+Ipv4NixVectorRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+ FlushGlobalNixRoutingCache ();
+}
+
+bool
+Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source,
+ Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
+ Ptr<NetDevice> oif)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_LOG_LOGIC ("Going from Node " << source->GetId() << " to Node " << dest->GetId());
+ std::queue< Ptr<Node> > greyNodeList; // discovered nodes with unexplored children
+
+ // reset the parent vector
+ parentVector.clear ();
+ parentVector.reserve (sizeof (Ptr<Node>)*numberOfNodes);
+ parentVector.insert (parentVector.begin (), sizeof (Ptr<Node>)*numberOfNodes, 0); // initialize to 0
+
+ // Add the source node to the queue, set its parent to itself
+ greyNodeList.push (source);
+ parentVector.at (source->GetId()) = source;
+
+ // BFS loop
+ while (greyNodeList.size () != 0)
+ {
+ Ptr<Node> currNode = greyNodeList.front ();
+ Ptr<Ipv4> ipv4 = currNode->GetObject<Ipv4> ();
+
+ if (currNode == dest)
+ {
+ NS_LOG_LOGIC ("Made it to Node " << currNode->GetId());
+ return true;
+ }
+
+ // if this is the first iteration of the loop and a
+ // specific output interface was given, make sure
+ // we go this way
+ if (currNode == source && oif)
+ {
+ // make sure that we can go this way
+ if (ipv4)
+ {
+ uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(oif);
+ if (!(ipv4->IsUp (interfaceIndex)))
+ {
+ NS_LOG_LOGIC ("Ipv4Interface is down");
+ return false;
+ }
+ }
+ if (!(oif->IsLinkUp ()))
+ {
+ NS_LOG_LOGIC ("Link is down.");
+ return false;
+ }
+ Ptr<Channel> channel = oif->GetChannel ();
+ if (channel == 0)
+ {
+ return false;
+ }
+
+ // this function takes in the local net dev, and channnel, and
+ // writes to the netDeviceContainer the adjacent net devs
+ NetDeviceContainer netDeviceContainer;
+ GetAdjacentNetDevices (oif, channel, netDeviceContainer);
+
+ // Finally we can get the adjacent nodes
+ // and scan through them. We push them
+ // to the greyNode queue, if they aren't
+ // already there.
+ for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
+ {
+ Ptr<Node> remoteNode = (*iter)->GetNode ();
+
+ // check to see if this node has been pushed before
+ // by checking to see if it has a parent
+ // if it doesn't (null or 0), then set its parent and
+ // push to the queue
+ if (parentVector.at (remoteNode->GetId ()) == 0)
+ {
+ parentVector.at (remoteNode->GetId ()) = currNode;
+ greyNodeList.push (remoteNode);
+ }
+ }
+ }
+ else
+ {
+ // Iterate over the current node's adjacent vertices
+ // and push them into the queue
+ for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
+ {
+ // Get a net device from the node
+ // as well as the channel, and figure
+ // out the adjacent net device
+ Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
+
+ // make sure that we can go this way
+ if (ipv4)
+ {
+ uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
+ if (!(ipv4->IsUp (interfaceIndex)))
+ {
+ NS_LOG_LOGIC ("Ipv4Interface is down");
+ continue;
+ }
+ }
+ if (!(localNetDevice->IsLinkUp ()))
+ {
+ NS_LOG_LOGIC ("Link is down.");
+ continue;
+ }
+ Ptr<Channel> channel = localNetDevice->GetChannel ();
+ if (channel == 0)
+ {
+ continue;
+ }
+
+ // this function takes in the local net dev, and channnel, and
+ // writes to the netDeviceContainer the adjacent net devs
+ NetDeviceContainer netDeviceContainer;
+ GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
+
+ // Finally we can get the adjacent nodes
+ // and scan through them. We push them
+ // to the greyNode queue, if they aren't
+ // already there.
+ for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
+ {
+ Ptr<Node> remoteNode = (*iter)->GetNode ();
+
+ // check to see if this node has been pushed before
+ // by checking to see if it has a parent
+ // if it doesn't (null or 0), then set its parent and
+ // push to the queue
+ if (parentVector.at (remoteNode->GetId ()) == 0)
+ {
+ parentVector.at (remoteNode->GetId ()) = currNode;
+ greyNodeList.push (remoteNode);
+ }
+ }
+ }
+ }
+
+ // Pop off the head grey node. We have all its children.
+ // It is now black.
+ greyNodeList.pop ();
+ }
+
+ // Didn't find the dest...
+ return false;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/nix-vector-routing/model/ipv4-nix-vector-routing.h Sun Feb 27 01:00:17 2011 -0500
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Josh Pelkey <jpelkey@gatech.edu>
+ */
+
+#ifndef __IPV4_NIX_VECTOR_ROUTING_H__
+#define __IPV4_NIX_VECTOR_ROUTING_H__
+
+#include <map>
+
+#include "ns3/channel.h"
+#include "ns3/node-container.h"
+#include "ns3/node-list.h"
+#include "ns3/net-device-container.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/nix-vector.h"
+#include "ns3/bridge-net-device.h"
+
+namespace ns3 {
+
+/**
+ * Map of Ipv4Address to NixVector
+ */
+typedef std::map<Ipv4Address, Ptr<NixVector> > NixMap_t;
+/**
+ * Map of Ipv4Address to Ipv4Route
+ */
+typedef std::map<Ipv4Address, Ptr<Ipv4Route> > Ipv4RouteMap_t;
+
+/**
+ * Nix-vector routing protocol
+ */
+class Ipv4NixVectorRouting : public Ipv4RoutingProtocol
+{
+ public:
+ Ipv4NixVectorRouting ();
+ ~Ipv4NixVectorRouting ();
+ /**
+ * @brief The Interface ID of the Global Router interface.
+ *
+ * @see Object::GetObject ()
+ */
+ static TypeId GetTypeId (void);
+ /**
+ * @brief Set the Node pointer of the node for which this
+ * routing protocol is to be placed
+ *
+ * @param node Node pointer
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * @brief Called when run-time link topology change occurs
+ * which iterates through the node list and flushes any
+ * nix vector caches
+ *
+ */
+ void FlushGlobalNixRoutingCache (void);
+
+ private:
+ /* flushes the cache which stores nix-vector based on
+ * destination IP */
+ void FlushNixCache (void);
+
+ /* flushes the cache which stores the Ipv4 route
+ * based on the destination IP */
+ void FlushIpv4RouteCache (void);
+
+ /* upon a run-time topology change caches are
+ * flushed and the total number of neighbors is
+ * reset to zero */
+ void ResetTotalNeighbors (void);
+
+ /* takes in the source node and dest IP and calls GetNodeByIp,
+ * BFS, accounting for any output interface specified, and finally
+ * BuildNixVector to return the built nix-vector */
+ Ptr<NixVector> GetNixVector (Ptr<Node>, Ipv4Address, Ptr<NetDevice>);
+
+ /* checks the cache based on dest IP for the nix-vector */
+ Ptr<NixVector> GetNixVectorInCache (Ipv4Address);
+
+ /* checks the cache based on dest IP for the Ipv4Route */
+ Ptr<Ipv4Route> GetIpv4RouteInCache (Ipv4Address);
+
+ /* given a net-device returns all the adjacent net-devices,
+ * essentially getting the neighbors on that channel */
+ void GetAdjacentNetDevices (Ptr<NetDevice>, Ptr<Channel>, NetDeviceContainer &);
+
+ /* iterates through the node list and finds the one
+ * corresponding to the given Ipv4Address */
+ Ptr<Node> GetNodeByIp (Ipv4Address);
+
+ /* Recurses the parent vector, created by BFS and actually builds the nixvector */
+ bool BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector);
+
+ /* special variation of BuildNixVector for when a node is sending to itself */
+ bool BuildNixVectorLocal (Ptr<NixVector> nixVector);
+
+ /* simple iterates through the nodes net-devices and determines
+ * how many neighbors it has */
+ uint32_t FindTotalNeighbors (void);
+
+ /* determine if the netdevice is bridged */
+ Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
+
+
+ /* Nix index is with respect to the neighbors. The net-device index must be
+ * derived from this */
+ uint32_t FindNetDeviceForNixIndex (uint32_t nodeIndex, Ipv4Address & gatewayIp);
+
+ /* Breadth first search algorithm
+ * Param1: total number of nodes
+ * Param2: Source Node
+ * Param3: Dest Node
+ * Param4: (returned) Parent vector for retracing routes
+ * Param5: specific output interface to use from source node, if not null
+ * Returns: false if dest not found, true o.w.
+ */
+ bool BFS (uint32_t numberOfNodes,
+ Ptr<Node> source,
+ Ptr<Node> dest,
+ std::vector< Ptr<Node> > & parentVector,
+ Ptr<NetDevice> oif);
+
+ void DoDispose (void);
+
+ /* 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;
+
+
+ /* cache stores nix-vectors based on destination ip */
+ NixMap_t m_nixCache;
+
+ /* cache stores Ipv4Routes based on destination ip */
+ Ipv4RouteMap_t m_ipv4RouteCache;
+
+ Ptr<Ipv4> m_ipv4;
+ Ptr<Node> m_node;
+
+ /* total neighbors used for nix-vector to determine
+ * number of bits */
+ uint32_t m_totalNeighbors;
+};
+} // namespace ns3
+#endif
--- a/src/routing/nix-vector-routing/nix-vector-routing.h Fri Feb 25 17:21:08 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 The Georgia Institute of Technology
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Josh Pelkey <jpelkey@gatech.edu>
- */
-
-/**
- * \ingroup routing
- * \defgroup nixvectorrouting Nix-vector Routing
- *
- * \section model Model
- *
- * Nix-vector routing is a simulation specific routing protocol and is
- * intended for large network topologies. The on-demand nature of this
- * protocol as well as the low-memory footprint of the nix-vector provides
- * improved performance in terms of memory usage and simulation run time
- * when dealing with a large number of nodes.
- *
- * Currently, the ns-3 model of nix-vector routing supports IPv4 p2p links
- * as well as CSMA links. It does not (yet) provide support for
- * efficient adaptation to link failures. It simply flushes all nix-vector
- * routing caches. Finally, IPv6 is not supported.
- *
- * \section api API and Usage
- *
- * Nix-vector routing has been rolled into a helper class. In order to
- * utilize these helper functions, users must include ns3/helper-module.h.
- * The Nix-vector routing protocol must be added to a list of routing
- * protocols. It is important that list routing is utilized.
- *
- * Example:
- *
- * Ipv4NixVectorHelper nixRouting;
- * Ipv4StaticRoutingHelper staticRouting;
- *
- * Ipv4ListRoutingHelper list;
- * list.Add (staticRouting, 0);
- * list.Add (nixRouting, 10);
- *
- * InternetStackHelper stack;
- * stack.SetRoutingHelper (list);
- * stack.Install (allNodes);
- *
- * \section impl Implementation
- *
- * ns-3 nix-vector-routing performs on-demand route computation using
- * a breadth-first search and an efficient route-storage data structure
- * known as a nix-vector. When a packet is generated at a node for
- * transmission, the route is calculated, and the nix-vector is built.
- * The nix-vector stores an index for each hop along the path, which
- * corresponds to the neighbor-index. This index is used to determine
- * which net-device and gateway should be used. To route a packet, the
- * nix-vector must be transmitted with the packet. At each hop, the
- * current node extracts the appropriate neighbor-index from the
- * nix-vector and transmits the packet through the corresponding
- * net-device. This continues until the packet reaches the destination.
- * */
--- a/src/routing/nix-vector-routing/wscript Fri Feb 25 17:21:08 2011 -0800
+++ b/src/routing/nix-vector-routing/wscript Sun Feb 27 01:00:17 2011 -0500
@@ -4,12 +4,16 @@
module = bld.create_ns3_module('nix-vector-routing', ['internet', 'contrib'])
module.includes = '.'
module.source = [
- 'ipv4-nix-vector-routing.cc',
+ 'model/ipv4-nix-vector-routing.cc',
+ 'helper/ipv4-nix-vector-helper.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'nix-vector-routing'
headers.source = [
- 'ipv4-nix-vector-routing.h',
+ 'model/ipv4-nix-vector-routing.h',
+ 'helper/ipv4-nix-vector-helper.h',
]
+ if bld.env['ENABLE_EXAMPLES']:
+ bld.add_subdirs('examples')
--- a/test.py Fri Feb 25 17:21:08 2011 -0800
+++ b/test.py Sun Feb 27 01:00:17 2011 -0500
@@ -124,14 +124,14 @@
("examples/routing/global-injection-slash32", "True", "True"),
("examples/routing/global-routing-slash32", "True", "True"),
("examples/routing/mixed-global-routing", "True", "True"),
- ("examples/routing/nix-simple", "True", "True"),
- ("examples/routing/nms-p2p-nix", "False", "True"), # Takes too long to run
+ ("src/routing/nix-vector-routing/examples/routing/nix-simple", "True", "True"),
+ ("src/routing/nix-vector-routing/examples/routing/nms-p2p-nix", "False", "True"), # Takes too long to run
("examples/routing/simple-alternate-routing", "True", "True"),
("examples/routing/simple-global-routing", "True", "True"),
("src/routing/olsr/examples/simple-point-to-point-olsr", "True", "True"),
("examples/routing/simple-routing-ping6", "True", "True"),
("examples/routing/static-routing-slash32", "True", "True"),
- ("examples/routing/aodv", "True", "True"),
+ ("src/routing/aodv/examples/routing/aodv", "True", "True"),
("src/spectrum/examples/adhoc-aloha-ideal-phy", "True", "True"),
("src/spectrum/examples/adhoc-aloha-ideal-phy-with-microwave-oven", "True", "True"),