diff --git a/AUTHORS b/AUTHORS
index 7ade1a3d3..f016de8f2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,6 +6,7 @@ Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
Raj Bhattacharjea (raj.b@gatech.edu)
Timo Bingmann (timo.bingmann@student.kit.edu)
Pavel Boyko (boyko@iitp.ru)
+Elena Buchatskaia (borovkovaes@iitp.ru)
Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
Luis Cortes (cortes@gatech.edu)
diff --git a/CHANGES.html b/CHANGES.html
index 1beecb862..8c17d7d96 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -56,9 +56,15 @@ us a note on ns-developers mailing list.
'context' (a 32bit integer which, by convention identifies a node by its id). Simulator::GetContext
returns the context of the currently-executing event while Simulator::ScheduleWithContext creates an
event with a context different from the execution context of the caller. This API is used
-by the ns-3 logging system to report the execution context of each log line.
+by the ns-3 logging system to report the execution context of each log line.
+
Object::DoStart : Users who need to complete their object setup at the start of a simulation
-can override this virtual method, perform their adhoc setup, and then, must chain up to their parent.
+can override this virtual method, perform their adhoc setup, and then, must chain up to their parent.
+
+Aod hoc On-Demand Distance Vector (AODV) routing model,
+RFC 3561
+
+IPv6 extension support
Changes to existing API:
@@ -122,6 +128,9 @@ sched.SetTypeId ("ns3::ListScheduler");
Simulator::SetScheduler (sched);
+ Extensions to IPv4 Ping application: verbose output and the ability to configure different ping
+sizes and time intervals (via new attributes)
+
Changed behavior:
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 94ee6d58b..ae2734665 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -31,10 +31,14 @@ http://www.nsnam.org/wiki/index.php/Installation
New user-visible features
-------------------------
- * The ns-3 logging macros (NS_LOG_*) now report automatically the node id
- of the event which called the macro.
+ a) The ns-3 logging macros (NS_LOG_*) now report automatically the node id
+ of the event which called the macro.
-API changes from ns-3.5
+ b) Ad hoc On-Demand Distance Vector (AODV) routing model according to RFC 3561.
+
+ c) IPv6 extensions support and two new examples for fragmentation and loose routing.
+
+API changes from ns-3.6
-----------------------
API changes for this release are documented in the file CHANGES.html.
diff --git a/examples/ipv6/fragmentation-ipv6.cc b/examples/ipv6/fragmentation-ipv6.cc
index 056505ada..8160ca190 100644
--- a/examples/ipv6/fragmentation-ipv6.cc
+++ b/examples/ipv6/fragmentation-ipv6.cc
@@ -45,26 +45,25 @@ NS_LOG_COMPONENT_DEFINE ("FragmentationIpv6Example");
*/
class StackHelper
{
- public:
-
- /**
- * \brief Add an address to a IPv6 node.
- * \param n node
- * \param interface interface index
- * \param address IPv6 address to add
- */
- inline void AddAddress (Ptr& n, uint32_t interface, Ipv6Address address)
- {
+public:
+ /**
+ * \brief Add an address to a IPv6 node.
+ * \param n node
+ * \param interface interface index
+ * \param address IPv6 address to add
+ */
+ inline void AddAddress (Ptr& n, uint32_t interface, Ipv6Address address)
+ {
Ptr ipv6 = n->GetObject ();
ipv6->AddAddress (interface, address);
}
- /**
- * \brief Print the routing table.
- * \param n the node
- */
- inline void PrintRoutingTable (Ptr& n)
- {
+ /**
+ * \brief Print the routing table.
+ * \param n the node
+ */
+ inline void PrintRoutingTable (Ptr& n)
+ {
Ptr routing = 0;
Ipv6StaticRoutingHelper routingHelper;
Ptr ipv6 = n->GetObject ();
@@ -78,15 +77,15 @@ class StackHelper
nbRoutes = routing->GetNRoutes ();
for (uint32_t i = 0 ; i < nbRoutes ; i++)
- {
- route = routing->GetRoute (i);
- std::cout << route.GetDest () << "\t"
- << route.GetGateway () << "\t"
- << route.GetInterface () << "\t"
- << route.GetPrefixToUse () << "\t"
- << std::endl;
- }
- }
+ {
+ route = routing->GetRoute (i);
+ std::cout << route.GetDest () << "\t"
+ << route.GetGateway () << "\t"
+ << route.GetInterface () << "\t"
+ << route.GetPrefixToUse () << "\t"
+ << std::endl;
+ }
+ }
};
int main (int argc, char** argv)
diff --git a/examples/routing/aodv.cc b/examples/routing/aodv.cc
new file mode 100644
index 000000000..de1de85cd
--- /dev/null
+++ b/examples/routing/aodv.cc
@@ -0,0 +1,214 @@
+/* -*- 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
+ */
+
+#include "ns3/aodv-module.h"
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/node-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
+#include
+
+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;
+ //\}
+
+ ///\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 (120),
+ totalTime (10),
+ pcap (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 ("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 ("wifia-6mbs"), "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);
+}
+
+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));
+
+ // move node away
+ Ptr node = nodes.Get (size/2);
+ Ptr mob = node->GetObject ();
+ Simulator::Schedule (Seconds (totalTime/3), &MobilityModel::SetPosition, mob, Vector (1e5, 1e5, 1e5));
+}
+
diff --git a/examples/routing/wscript b/examples/routing/wscript
index bff2f8b0e..c3404d2c7 100644
--- a/examples/routing/wscript
+++ b/examples/routing/wscript
@@ -44,3 +44,7 @@ def build(bld):
obj = bld.create_ns3_program('simple-routing-ping6',
['csma', 'internet-stack'])
obj.source = 'simple-routing-ping6.cc'
+
+ obj = bld.create_ns3_program('aodv',
+ ['wifi', 'internet-stack', 'aodv'])
+ obj.source = 'aodv.cc'
diff --git a/src/applications/v4ping/v4ping.cc b/src/applications/v4ping/v4ping.cc
index 8523439f5..b23f45484 100644
--- a/src/applications/v4ping/v4ping.cc
+++ b/src/applications/v4ping/v4ping.cc
@@ -20,10 +20,10 @@
#include "ns3/ipv4-address.h"
#include "ns3/socket.h"
#include "ns3/uinteger.h"
+#include "ns3/boolean.h"
#include "ns3/inet-socket-address.h"
#include "ns3/packet.h"
#include "ns3/trace-source-accessor.h"
-#include "ns3/simulator.h"
namespace ns3 {
@@ -41,6 +41,19 @@ V4Ping::GetTypeId (void)
Ipv4AddressValue (),
MakeIpv4AddressAccessor (&V4Ping::m_remote),
MakeIpv4AddressChecker ())
+ .AddAttribute ("Verbose",
+ "Produce usual output.",
+ BooleanValue (false),
+ MakeBooleanAccessor (&V4Ping::m_verbose),
+ MakeBooleanChecker ())
+ .AddAttribute ("Interval", "Wait interval seconds between sending each packet.",
+ TimeValue (Seconds (1)),
+ MakeTimeAccessor (&V4Ping::m_interval),
+ MakeTimeChecker ())
+ .AddAttribute ("Size", "The number of data bytes to be sent, real packet will be 8 (ICMP) + 20 (IP) bytes longer.",
+ UintegerValue (56),
+ MakeUintegerAccessor (&V4Ping::m_size),
+ MakeUintegerChecker (16))
.AddTraceSource ("Rtt",
"The rtt calculated by the ping.",
MakeTraceSourceAccessor (&V4Ping::m_traceRtt));
@@ -49,9 +62,14 @@ V4Ping::GetTypeId (void)
}
V4Ping::V4Ping ()
- : m_socket (0),
- m_seq (0)
-{}
+ : m_interval (Seconds (1)),
+ m_size (56),
+ m_socket (0),
+ m_seq (0),
+ m_verbose (false),
+ m_recv (0)
+{
+}
V4Ping::~V4Ping ()
{}
@@ -92,6 +110,7 @@ V4Ping::Receive (Ptr socket)
NS_ASSERT (realFrom.GetPort () == 1); // protocol should be icmp.
Ipv4Header ipv4;
p->RemoveHeader (ipv4);
+ uint32_t recvSize = p->GetSize ();
NS_ASSERT (ipv4.GetProtocol () == 1); // protocol should be icmp.
Icmpv4Header icmp;
p->RemoveHeader (icmp);
@@ -99,10 +118,11 @@ V4Ping::Receive (Ptr socket)
{
Icmpv4Echo echo;
p->RemoveHeader (echo);
- if (echo.GetSequenceNumber () == (m_seq - 1) &&
- echo.GetIdentifier () == 0)
+ std::map::iterator i = m_sent.find(echo.GetSequenceNumber());
+
+ if (i != m_sent.end () && echo.GetIdentifier () == 0)
{
- uint32_t buf[4];
+ uint32_t buf[m_size / 4];
uint32_t dataSize = echo.GetDataSize ();
if (dataSize == sizeof(buf))
{
@@ -111,13 +131,22 @@ V4Ping::Receive (Ptr socket)
if (buf[0] == GetNode ()->GetId () &&
buf[1] == GetApplicationId ())
{
- int64_t ts = buf[3];
- ts <<= 32;
- ts |= buf[2];
- Time sendTime = TimeStep (ts);
+ Time sendTime = i->second;
NS_ASSERT (Simulator::Now () > sendTime);
Time delta = Simulator::Now () - sendTime;
+
+ m_sent.erase (i);
+ m_avgRtt.Update (delta.GetMilliSeconds());
+ m_recv++;
m_traceRtt (delta);
+
+ if (m_verbose)
+ {
+ std::cout << recvSize << " bytes from " << realFrom.GetIpv4() << ":"
+ << " icmp_seq=" << echo.GetSequenceNumber ()
+ << " ttl=" << (unsigned)ipv4.GetTtl ()
+ << " time=" << delta.GetMilliSeconds() << " ms\n";
+ }
}
}
}
@@ -135,20 +164,8 @@ V4Ping::Write32 (uint8_t *buffer, uint32_t data)
}
void
-V4Ping::StartApplication (void)
+V4Ping::Send ()
{
- NS_LOG_FUNCTION (this);
- m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
- NS_ASSERT (m_socket != 0);
- m_socket->SetAttribute ("Protocol", UintegerValue (1)); // icmp
- m_socket->SetRecvCallback (MakeCallback (&V4Ping::Receive, this));
- InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
- int status;
- status = m_socket->Bind (src);
- NS_ASSERT (status != -1);
- InetSocketAddress dst = InetSocketAddress (m_remote, 0);
- status = m_socket->Connect (dst);
- NS_ASSERT (status != -1);
Ptr p = Create ();
Icmpv4Echo echo;
echo.SetSequenceNumber (m_seq);
@@ -161,22 +178,17 @@ V4Ping::StartApplication (void)
// (where any difference would show up anyway) and borrow that code. Don't
// be too surprised when you see that this is a little endian convention.
//
- uint8_t data[4 * sizeof(uint32_t)];
+ uint8_t data[m_size];
+ for (uint32_t i = 0; i < m_size; ++i) data[i] = 0;
+ NS_ASSERT (m_size >= 16);
+
uint32_t tmp = GetNode ()->GetId ();
Write32 (&data[0 * sizeof(uint32_t)], tmp);
tmp = GetApplicationId ();
Write32 (&data[1 * sizeof(uint32_t)], tmp);
- int64_t now = Simulator::Now ().GetTimeStep ();
- tmp = now & 0xffffffff;
- Write32 (&data[2 * sizeof(uint32_t)], tmp);
-
- now >>= 32;
- tmp = now & 0xffffffff;
- Write32 (&data[3 * sizeof(uint32_t)], tmp);
-
- Ptr dataPacket = Create ((uint8_t *) &data, 16);
+ Ptr dataPacket = Create ((uint8_t *) &data, m_size);
echo.SetData (dataPacket);
p->AddHeader (echo);
Icmpv4Header header;
@@ -184,13 +196,57 @@ V4Ping::StartApplication (void)
header.SetCode (0);
p->AddHeader (header);
m_socket->Send (p, 0);
+ m_sent.insert (std::make_pair (m_seq - 1, Simulator::Now()));
+ m_next = Simulator::Schedule (m_interval, & V4Ping::Send, this);
+}
+
+void
+V4Ping::StartApplication (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_started = Simulator::Now ();
+ if (m_verbose)
+ {
+ std::cout << "PING " << m_remote << " 56(84) bytes of data.\n";
+ }
+
+ m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
+ NS_ASSERT (m_socket != 0);
+ m_socket->SetAttribute ("Protocol", UintegerValue (1)); // icmp
+ m_socket->SetRecvCallback (MakeCallback (&V4Ping::Receive, this));
+ InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
+ int status;
+ status = m_socket->Bind (src);
+ NS_ASSERT (status != -1);
+ InetSocketAddress dst = InetSocketAddress (m_remote, 0);
+ status = m_socket->Connect (dst);
+ NS_ASSERT (status != -1);
+
+ Send ();
}
void
V4Ping::StopApplication (void)
{
NS_LOG_FUNCTION (this);
+ m_next.Cancel();
m_socket->Close ();
+
+ if (m_verbose)
+ {
+ std::ostringstream os;
+ os.precision (4);
+ os << "--- " << m_remote << " ping statistics ---\n"
+ << m_seq << " packets transmitted, " << m_recv << " received, "
+ << ((m_seq - m_recv) * 100 / m_seq) << "% packet loss, "
+ << "time " << (Simulator::Now () - m_started).GetMilliSeconds () << "ms\n";
+
+ if (m_avgRtt.Count () > 0)
+ os << "rtt min/avg/max/mdev = " << m_avgRtt.Min() << "/" << m_avgRtt.Avg() << "/"
+ << m_avgRtt.Max() << "/" << m_avgRtt.Err()
+ << " ms\n";
+ std::cout << os.str();
+ }
}
diff --git a/src/applications/v4ping/v4ping.h b/src/applications/v4ping/v4ping.h
index ec7ed3820..3eb3e64b3 100644
--- a/src/applications/v4ping/v4ping.h
+++ b/src/applications/v4ping/v4ping.h
@@ -1,9 +1,27 @@
+/* -*- 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
+ */
#ifndef V4PING_H
#define V4PING_H
#include "ns3/application.h"
#include "ns3/traced-callback.h"
#include "ns3/nstime.h"
+#include "ns3/average.h"
+#include "ns3/simulator.h"
+#include
namespace ns3 {
@@ -35,11 +53,32 @@ private:
virtual void DoDispose (void);
uint32_t GetApplicationId (void) const;
void Receive (Ptr socket);
+ void Send ();
+ /// Remote address
Ipv4Address m_remote;
+ /// Wait interval seconds between sending each packet
+ Time m_interval;
+ /**
+ * Specifies the number of data bytes to be sent.
+ * The default is 56, which translates into 64 ICMP data bytes when combined with the 8 bytes of ICMP header data.
+ */
+ uint32_t m_size;
Ptr m_socket;
uint16_t m_seq;
TracedCallback m_traceRtt;
+ /// produce ping-style output if true
+ bool m_verbose;
+ /// received packets counter
+ uint32_t m_recv;
+ /// Start time to report total ping time
+ Time m_started;
+ /// Average rtt is ms
+ Average m_avgRtt;
+ /// Next packet will be sent
+ EventId m_next;
+ /// All sent but not answered packets. Map icmp seqno -> when sent
+ std::map m_sent;
};
} // namespace ns3
diff --git a/src/contrib/average.h b/src/contrib/average.h
new file mode 100644
index 000000000..fdb9e0da2
--- /dev/null
+++ b/src/contrib/average.h
@@ -0,0 +1,82 @@
+/* -*- 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
+ */
+
+#ifndef AVERAGE_H
+#define AVERAGE_H
+#include
+#include
+#include
+
+/// Simple average, min, max and std. deviation calculator
+template
+class Average
+{
+public:
+ Average () :
+ size (0), min (std::numeric_limits::max ()), max (0), avg (0), avg2 (0)
+ {
+ }
+
+ /// Add new value
+ void Update (T const & x)
+ {
+ min = std::min (x, min);
+ max = std::max (x, max);
+ avg = (size * avg + x) / (size + 1);
+ avg2 = (size * avg2 + x * x) / (size + 1);
+ size++;
+ }
+ /// Reset statistics
+ void Reset ()
+ {
+ size = 0;
+ min = std::numeric_limits::max ();
+ max = 0;
+ avg = 0;
+ avg2 = 0;
+ }
+
+ ///\name Access results
+ //\{
+ uint32_t Count () const { return size; }
+ T Min () const { return min; }
+ T Max () const { return max; }
+ double Avg () const { return avg; }
+ double Err () const { return sqrt ((avg2 - avg*avg)/(size - 1)); }
+ //\}
+
+private:
+ uint32_t size;
+ T min, max;
+ double avg, avg2;
+};
+
+/// Print avg (err) [min, max]
+template
+std::ostream & operator<< (std::ostream & os, Average const & x)
+{
+ if (x.Count () != 0)
+ os << x.Avg () << " (" << x.Err () << ") [" << x.Min () << ", " << x.Max () << "]";
+ else
+ os << "NA"; // not avaliable
+ return os;
+}
+
+#endif /* AVERAGE_H */
diff --git a/src/contrib/wscript b/src/contrib/wscript
index 1a32d13c9..09c857581 100644
--- a/src/contrib/wscript
+++ b/src/contrib/wscript
@@ -43,6 +43,7 @@ def build(bld):
'file-config.h',
'config-store.h',
'flow-id-tag.h',
+ 'average.h',
]
if bld.env['ENABLE_GTK_CONFIG_STORE']:
diff --git a/src/devices/point-to-point/ppp-header.cc b/src/devices/point-to-point/ppp-header.cc
index 04fa8bc5e..5a2ec273c 100644
--- a/src/devices/point-to-point/ppp-header.cc
+++ b/src/devices/point-to-point/ppp-header.cc
@@ -56,7 +56,20 @@ PppHeader::GetInstanceTypeId (void) const
void
PppHeader::Print (std::ostream &os) const
{
- os << "Point-to-Point Protocol: " << m_protocol;
+ std::string proto;
+
+ switch(m_protocol)
+ {
+ case 0x0021: /* IPv4 */
+ proto = "IP (0x0021)";
+ break;
+ case 0x0057: /* IPv6 */
+ proto = "IPv6 (0x0057)";
+ break;
+ default:
+ NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
+ }
+ os << "Point-to-Point Protocol: " << proto;
}
uint32_t
diff --git a/src/devices/wifi/adhoc-wifi-mac.cc b/src/devices/wifi/adhoc-wifi-mac.cc
index 3c11aa718..44af9e4d8 100644
--- a/src/devices/wifi/adhoc-wifi-mac.cc
+++ b/src/devices/wifi/adhoc-wifi-mac.cc
@@ -28,6 +28,7 @@
#include "ns3/pointer.h"
#include "ns3/packet.h"
#include "ns3/log.h"
+#include "ns3/trace-source-accessor.h"
NS_LOG_COMPONENT_DEFINE ("AdhocWifiMac");
@@ -48,6 +49,16 @@ AdhocWifiMac::GetTypeId (void)
PointerValue (),
MakePointerAccessor (&AdhocWifiMac::GetDcaTxop),
MakePointerChecker ())
+ .AddTraceSource ( "TxOkHeader",
+ "The header of successfully transmitted packet",
+ MakeTraceSourceAccessor (
+ &AdhocWifiMac::m_txOkCallback)
+ )
+ .AddTraceSource ( "TxErrHeader",
+ "The header of unsuccessfully transmitted packet",
+ MakeTraceSourceAccessor (
+ &AdhocWifiMac::m_txErrCallback)
+ )
;
return tid;
}
@@ -67,6 +78,7 @@ AdhocWifiMac::AdhocWifiMac ()
m_dca = CreateObject ();
m_dca->SetLow (m_low);
m_dca->SetManager (m_dcfManager);
+ m_dca->SetTxFailedCallback (MakeCallback (&AdhocWifiMac::TxFailed, this));
}
AdhocWifiMac::~AdhocWifiMac ()
{}
@@ -276,6 +288,14 @@ AdhocWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
break;
}
}
-
-
+void
+AdhocWifiMac::TxOk (const WifiMacHeader &hdr)
+{
+ m_txOkCallback (hdr);
+}
+void
+AdhocWifiMac::TxFailed (const WifiMacHeader &hdr)
+{
+ m_txErrCallback (hdr);
+}
} // namespace ns3
diff --git a/src/devices/wifi/adhoc-wifi-mac.h b/src/devices/wifi/adhoc-wifi-mac.h
index 21bd2d8f2..0d19e5644 100644
--- a/src/devices/wifi/adhoc-wifi-mac.h
+++ b/src/devices/wifi/adhoc-wifi-mac.h
@@ -87,8 +87,9 @@ private:
AdhocWifiMac (const AdhocWifiMac & ctor_arg);
AdhocWifiMac &operator = (const AdhocWifiMac &o);
Ptr GetDcaTxop(void) const;
+ void TxOk (WifiMacHeader const &hdr);
+ void TxFailed (WifiMacHeader const &hdr);
virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
-
Ptr m_dca;
Callback, Mac48Address, Mac48Address> m_upCallback;
Ptr m_stationManager;
@@ -97,6 +98,8 @@ private:
MacRxMiddle *m_rxMiddle;
Ptr m_low;
Ssid m_ssid;
+ TracedCallback m_txOkCallback;
+ TracedCallback m_txErrCallback;
};
} // namespace ns3
diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc
index 8d34f5b6c..0f58265c2 100644
--- a/src/devices/wifi/wifi-net-device.cc
+++ b/src/devices/wifi/wifi-net-device.cc
@@ -91,6 +91,15 @@ WifiNetDevice::DoDispose (void)
NetDevice::DoDispose ();
}
+void
+WifiNetDevice::DoStart (void)
+{
+ m_phy->Start ();
+ m_mac->Start ();
+ m_stationManager->Start ();
+ NetDevice::DoStart ();
+}
+
void
WifiNetDevice::CompleteConfig (void)
{
diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h
index 63190e340..1e9f4fb6d 100644
--- a/src/devices/wifi/wifi-net-device.h
+++ b/src/devices/wifi/wifi-net-device.h
@@ -104,6 +104,7 @@ public:
private:
virtual void DoDispose (void);
+ virtual void DoStart (void);
void ForwardUp (Ptr packet, Mac48Address from, Mac48Address to);
void LinkUp (void);
void LinkDown (void);
diff --git a/src/helper/aodv-helper.cc b/src/helper/aodv-helper.cc
new file mode 100644
index 000000000..e0e8f79af
--- /dev/null
+++ b/src/helper/aodv-helper.cc
@@ -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 , written after OlsrHelper by Mathieu Lacage
+ */
+#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
+AodvHelper::Create (Ptr node) const
+{
+ Ptr agent = m_agentFactory.Create ();
+ node->AggregateObject (agent);
+ return agent;
+}
+
+void
+AodvHelper::Set (std::string name, const AttributeValue &value)
+{
+ m_agentFactory.Set (name, value);
+}
+
+}
diff --git a/src/helper/aodv-helper.h b/src/helper/aodv-helper.h
new file mode 100644
index 000000000..c0b7d347b
--- /dev/null
+++ b/src/helper/aodv-helper.h
@@ -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 , written after OlsrHelper by Mathieu Lacage
+ */
+#ifndef AODVHELPER_H_
+#define AODVHELPER_H_
+
+#include "ns3/object-factory.h"
+#include "ns3/node.h"
+#include "node-container.h"
+#include "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 Create (Ptr 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_ */
diff --git a/src/helper/v4ping-helper.cc b/src/helper/v4ping-helper.cc
index 0e2467205..e8767db76 100644
--- a/src/helper/v4ping-helper.cc
+++ b/src/helper/v4ping-helper.cc
@@ -30,6 +30,12 @@ V4PingHelper::V4PingHelper (Ipv4Address remote)
m_factory.Set ("Remote", Ipv4AddressValue (remote));
}
+void
+V4PingHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+ m_factory.Set (name, value);
+}
+
ApplicationContainer
V4PingHelper::Install (Ptr node) const
{
diff --git a/src/helper/v4ping-helper.h b/src/helper/v4ping-helper.h
index 1e2f5617e..a26029c78 100644
--- a/src/helper/v4ping-helper.h
+++ b/src/helper/v4ping-helper.h
@@ -55,6 +55,12 @@ public:
*/
ApplicationContainer Install (std::string nodeName) const;
+ /**
+ * \brief Configure ping applications attribute
+ * \param name attribute's name
+ * \param value attribute's value
+ */
+ void SetAttribute (std::string name, const AttributeValue &value);
private:
/**
* \internal
diff --git a/src/helper/wscript b/src/helper/wscript
index 1d6ddd850..6c845735c 100644
--- a/src/helper/wscript
+++ b/src/helper/wscript
@@ -1,7 +1,7 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
- helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'nix-vector-routing', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
+ helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
helper.source = [
'node-container.cc',
'net-device-container.cc',
@@ -29,6 +29,7 @@ def build(bld):
'ipv4-global-routing-helper.cc',
'ipv4-list-routing-helper.cc',
'ipv4-routing-helper.cc',
+ 'aodv-helper.cc',
'mesh-helper.cc',
'dot11s-installer.cc',
'flame-installer.cc',
@@ -68,9 +69,10 @@ def build(bld):
'nqos-wifi-mac-helper.h',
'qos-wifi-mac-helper.h',
'ipv4-nix-vector-helper.h',
- 'ipv4-global-routing-helper.h',
+ 'ipv4-global-routing-helper.h',
'ipv4-list-routing-helper.h',
'ipv4-routing-helper.h',
+ 'aodv-helper.h',
'mesh-helper.h',
'mesh-stack-installer.h',
'dot11s-installer.h',
diff --git a/src/internet-stack/icmpv4-l4-protocol.cc b/src/internet-stack/icmpv4-l4-protocol.cc
index 93bd54467..d62c8cd79 100644
--- a/src/internet-stack/icmpv4-l4-protocol.cc
+++ b/src/internet-stack/icmpv4-l4-protocol.cc
@@ -86,6 +86,7 @@ Icmpv4L4Protocol::SendMessage (Ptr packet, Ipv4Address dest, uint8_t typ
NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
Ipv4Header header;
header.SetDestination (dest);
+ header.SetProtocol (PROT_NUMBER);
Socket::SocketErrno errno_;
Ptr route;
uint32_t oif = 0; //specify non-zero if bound to a source address
diff --git a/src/internet-stack/ipv4-interface.cc b/src/internet-stack/ipv4-interface.cc
index c54155152..9ca20cfa2 100644
--- a/src/internet-stack/ipv4-interface.cc
+++ b/src/internet-stack/ipv4-interface.cc
@@ -42,7 +42,8 @@ Ipv4Interface::GetTypeId (void)
.AddAttribute ("ArpCache",
"The arp cache for this ipv4 interface",
PointerValue (0),
- MakePointerAccessor (&Ipv4Interface::m_cache),
+ MakePointerAccessor (&Ipv4Interface::SetArpCache,
+ &Ipv4Interface::GetArpCache),
MakePointerChecker ())
;
;
@@ -128,6 +129,18 @@ Ipv4Interface::GetMetric (void) const
return m_metric;
}
+void
+Ipv4Interface::SetArpCache (Ptr a)
+{
+ m_cache = a;
+}
+
+Ptr
+Ipv4Interface::GetArpCache () const
+{
+ return m_cache;
+}
+
/**
* These are IP interface states and may be distinct from
* NetDevice states, such as found in real implementations
diff --git a/src/internet-stack/ipv4-interface.h b/src/internet-stack/ipv4-interface.h
index 0dcf732bb..671d58f07 100644
--- a/src/internet-stack/ipv4-interface.h
+++ b/src/internet-stack/ipv4-interface.h
@@ -56,12 +56,17 @@ public:
void SetNode (Ptr node);
void SetDevice (Ptr device);
+ void SetArpCache (Ptr);
/**
* \returns the underlying NetDevice. This method cannot return zero.
*/
Ptr GetDevice (void) const;
-
+ /**
+ * \return ARP cache used by this interface
+ */
+ Ptr GetArpCache () const;
+
/**
* \param metric configured routing metric (cost) of this interface
*
diff --git a/src/internet-stack/ipv4-l3-protocol.h b/src/internet-stack/ipv4-l3-protocol.h
index e3996559c..d56ea3754 100644
--- a/src/internet-stack/ipv4-l3-protocol.h
+++ b/src/internet-stack/ipv4-l3-protocol.h
@@ -241,7 +241,6 @@ private:
bool m_ipForward;
L4List_t m_protocols;
Ipv4InterfaceList m_interfaces;
- uint32_t m_nInterfaces;
uint8_t m_defaultTtl;
uint16_t m_identification;
Ptr m_node;
diff --git a/src/internet-stack/ipv4-raw-socket-impl.cc b/src/internet-stack/ipv4-raw-socket-impl.cc
index fe7a307b8..1a9777246 100644
--- a/src/internet-stack/ipv4-raw-socket-impl.cc
+++ b/src/internet-stack/ipv4-raw-socket-impl.cc
@@ -174,6 +174,7 @@ Ipv4RawSocketImpl::SendTo (Ptr p, uint32_t flags,
{
Ipv4Header header;
header.SetDestination (dst);
+ header.SetProtocol (m_protocol);
SocketErrno errno_ = ERROR_NOTERROR;//do not use errno as it is the standard C last error number
Ptr route;
uint32_t oif = 0; //specify non-zero if bound to a source address
@@ -247,6 +248,7 @@ Ipv4RawSocketImpl::ForwardUp (Ptr p, Ipv4Header ipHeader, Ptr ()
.AddAttribute ("Extensions", "The set of IPv6 extensions registered with this demux.",
- ObjectVectorValue (),
- MakeObjectVectorAccessor (&Ipv6ExtensionDemux::m_extensions),
- MakeObjectVectorChecker ())
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6ExtensionDemux::m_extensions),
+ MakeObjectVectorChecker ())
;
return tid;
}
@@ -53,10 +53,10 @@ Ipv6ExtensionDemux::~Ipv6ExtensionDemux ()
void Ipv6ExtensionDemux::DoDispose ()
{
for (Ipv6ExtensionList_t::iterator it = m_extensions.begin (); it != m_extensions.end (); it++)
- {
- (*it)->Dispose ();
- *it = 0;
- }
+ {
+ (*it)->Dispose ();
+ *it = 0;
+ }
m_extensions.clear ();
m_node = 0;
Object::DoDispose ();
@@ -75,12 +75,12 @@ void Ipv6ExtensionDemux::Insert (Ptr extension)
Ptr Ipv6ExtensionDemux::GetExtension (uint8_t extensionNumber)
{
for (Ipv6ExtensionList_t::iterator i = m_extensions.begin (); i != m_extensions.end (); ++i)
- {
- if ((*i)->GetExtensionNumber () == extensionNumber)
{
- return *i;
+ if ((*i)->GetExtensionNumber () == extensionNumber)
+ {
+ return *i;
+ }
}
- }
return 0;
}
diff --git a/src/internet-stack/ipv6-extension-demux.h b/src/internet-stack/ipv6-extension-demux.h
index 42cc9e252..344e6164d 100644
--- a/src/internet-stack/ipv6-extension-demux.h
+++ b/src/internet-stack/ipv6-extension-demux.h
@@ -37,66 +37,66 @@ class Node;
*/
class Ipv6ExtensionDemux : public Object
{
- public:
- /**
- * \brief The interface ID.
- * \return type ID
- */
- static TypeId GetTypeId (void);
+public:
+ /**
+ * \brief The interface ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
- /**
- * \brief Constructor.
- */
- Ipv6ExtensionDemux ();
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionDemux ();
- /**
- * \brief Destructor.
- */
- virtual ~Ipv6ExtensionDemux ();
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionDemux ();
- /**
- * \brief Set the node.
- * \param node the node to set
- */
- void SetNode (Ptr node);
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr node);
- /**
- * \brief Insert a new IPv6 Extension.
- * \param extension the extension to insert
- */
- void Insert (Ptr extension);
+ /**
+ * \brief Insert a new IPv6 Extension.
+ * \param extension the extension to insert
+ */
+ void Insert (Ptr extension);
- /**
- * \brief Get the extension corresponding to extensionNumber.
- * \param extensionNumber extension number of the extension to retrieve
- * \return a matching IPv6 extension
- */
- Ptr GetExtension (uint8_t extensionNumber);
+ /**
+ * \brief Get the extension corresponding to extensionNumber.
+ * \param extensionNumber extension number of the extension to retrieve
+ * \return a matching IPv6 extension
+ */
+ Ptr GetExtension (uint8_t extensionNumber);
- /**
- * \brief Remove an extension from this demux.
- * \param extension pointer on the extension to remove
- */
- void Remove (Ptr extension);
+ /**
+ * \brief Remove an extension from this demux.
+ * \param extension pointer on the extension to remove
+ */
+ void Remove (Ptr extension);
- protected:
- /**
- * \brief Dispose object.
- */
- virtual void DoDispose ();
+protected:
+ /**
+ * \brief Dispose object.
+ */
+ virtual void DoDispose ();
- private:
- typedef std::list > Ipv6ExtensionList_t;
+private:
+ typedef std::list > Ipv6ExtensionList_t;
- /**
- * \brief List of IPv6 Extensions supported.
- */
- Ipv6ExtensionList_t m_extensions;
+ /**
+ * \brief List of IPv6 Extensions supported.
+ */
+ Ipv6ExtensionList_t m_extensions;
- /**
- * \brief The node.
- */
- Ptr m_node;
+ /**
+ * \brief The node.
+ */
+ Ptr m_node;
};
} /* namespace ns3 */
diff --git a/src/internet-stack/ipv6-extension-header.cc b/src/internet-stack/ipv6-extension-header.cc
index 8bd6203e6..555a54dd8 100644
--- a/src/internet-stack/ipv6-extension-header.cc
+++ b/src/internet-stack/ipv6-extension-header.cc
@@ -45,7 +45,7 @@ TypeId Ipv6ExtensionHeader::GetInstanceTypeId () const
}
Ipv6ExtensionHeader::Ipv6ExtensionHeader ()
- : m_nextHeader (0),
+: m_nextHeader (0),
m_length (0),
m_data (0)
{
@@ -106,13 +106,13 @@ uint32_t Ipv6ExtensionHeader::Deserialize (Buffer::Iterator start)
i.Read (data, dataLength);
if (dataLength > m_data.GetSize ())
- {
- m_data.AddAtEnd (dataLength - m_data.GetSize ());
- }
+ {
+ m_data.AddAtEnd (dataLength - m_data.GetSize ());
+ }
else
- {
- m_data.RemoveAtEnd (m_data.GetSize () - dataLength);
- }
+ {
+ m_data.RemoveAtEnd (m_data.GetSize () - dataLength);
+ }
i = m_data.Begin ();
i.Write (data, dataLength);
@@ -121,7 +121,7 @@ uint32_t Ipv6ExtensionHeader::Deserialize (Buffer::Iterator start)
}
OptionField::OptionField (uint32_t optionsOffset)
- : m_optionData (0),
+: m_optionData (0),
m_optionsOffset (optionsOffset)
{
}
@@ -141,13 +141,13 @@ void OptionField::Serialize (Buffer::Iterator start) const
uint32_t fill = CalculatePad ((Ipv6OptionHeader::Alignment) {8,0});
NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
switch (fill)
- {
+ {
case 0: return;
case 1: Ipv6OptionPad1Header ().Serialize (start);
return;
default: Ipv6OptionPadnHeader (fill).Serialize (start);
return;
- }
+ }
}
uint32_t OptionField::Deserialize (Buffer::Iterator start, uint32_t length)
@@ -167,13 +167,13 @@ void OptionField::AddOption (Ipv6OptionHeader const& option)
uint32_t pad = CalculatePad (option.GetAlignment ());
NS_LOG_LOGIC ("need " << pad << " bytes padding");
switch (pad)
- {
+ {
case 0: break; //no padding needed
case 1: AddOption (Ipv6OptionPad1Header ());
- break;
+ break;
default: AddOption (Ipv6OptionPadnHeader (pad));
- break;
- }
+ break;
+ }
m_optionData.AddAtEnd (option.GetSerializedSize ());
Buffer::Iterator it = m_optionData.End ();
@@ -214,7 +214,7 @@ TypeId Ipv6ExtensionHopByHopHeader::GetInstanceTypeId () const
}
Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader ()
- : OptionField (2)
+: OptionField (2)
{
}
@@ -269,7 +269,7 @@ TypeId Ipv6ExtensionDestinationHeader::GetInstanceTypeId () const
}
Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader ()
- : OptionField (2)
+: OptionField (2)
{
}
@@ -325,7 +325,7 @@ TypeId Ipv6ExtensionFragmentHeader::GetInstanceTypeId () const
}
Ipv6ExtensionFragmentHeader::Ipv6ExtensionFragmentHeader ()
- : m_offset (0),
+: m_offset (0),
m_identification (0)
{
}
@@ -416,7 +416,7 @@ TypeId Ipv6ExtensionRoutingHeader::GetInstanceTypeId () const
}
Ipv6ExtensionRoutingHeader::Ipv6ExtensionRoutingHeader ()
- : m_typeRouting (0),
+: m_typeRouting (0),
m_segmentsLeft (0)
{
}
@@ -495,7 +495,7 @@ TypeId Ipv6ExtensionLooseRoutingHeader::GetInstanceTypeId () const
}
Ipv6ExtensionLooseRoutingHeader::Ipv6ExtensionLooseRoutingHeader ()
- : m_routersAddress (0)
+: m_routersAddress (0)
{
}
@@ -535,9 +535,9 @@ void Ipv6ExtensionLooseRoutingHeader::Print (std::ostream &os) const
<< " typeRouting = " << (uint32_t)GetTypeRouting () << " segmentsLeft = " << (uint32_t)GetSegmentsLeft () << " ";
for (std::vector::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
- {
- os << *it << " ";
- }
+ {
+ os << *it << " ";
+ }
os << " )";
}
@@ -559,10 +559,10 @@ void Ipv6ExtensionLooseRoutingHeader::Serialize (Buffer::Iterator start) const
i.WriteU32 (0);
for (VectorIpv6Address_t::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end () ; it++)
- {
- it->Serialize (buff);
- i.Write (buff, 16);
- }
+ {
+ it->Serialize (buff);
+ i.Write (buff, 16);
+ }
}
uint32_t Ipv6ExtensionLooseRoutingHeader::Deserialize (Buffer::Iterator start)
@@ -577,10 +577,10 @@ uint32_t Ipv6ExtensionLooseRoutingHeader::Deserialize (Buffer::Iterator start)
i.ReadU32 ();
for (std::vector::iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
- {
- i.Read (buff, 16);
- it->Set (buff);
- }
+ {
+ i.Read (buff, 16);
+ it->Set (buff);
+ }
return GetSerializedSize ();
}
diff --git a/src/internet-stack/ipv6-extension.cc b/src/internet-stack/ipv6-extension.cc
index d1a30bbd4..f35e64a3f 100644
--- a/src/internet-stack/ipv6-extension.cc
+++ b/src/internet-stack/ipv6-extension.cc
@@ -53,11 +53,11 @@ TypeId Ipv6Extension::GetTypeId ()
static TypeId tid = TypeId ("ns3::Ipv6Extension")
.SetParent ()
.AddAttribute ("ExtensionNumber", "The IPv6 extension number.",
- UintegerValue (0),
- MakeUintegerAccessor (&Ipv6Extension::GetExtensionNumber),
- MakeUintegerChecker ())
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6Extension::GetExtensionNumber),
+ MakeUintegerChecker ())
.AddTraceSource ("Drop", "Drop ipv6 packet",
- MakeTraceSourceAccessor (&Ipv6Extension::m_dropTrace))
+ MakeTraceSourceAccessor (&Ipv6Extension::m_dropTrace))
;
return tid;
}
@@ -102,64 +102,64 @@ uint8_t Ipv6Extension::ProcessOptions (Ptr& packet, uint8_t offset, uint
uint8_t optionLength = 0;
while (length > processedSize && !isDropped)
- {
- optionType = *(data + processedSize);
- ipv6Option = ipv6OptionDemux->GetOption (optionType);
-
- if (ipv6Option == 0)
{
- optionType >>= 6;
- switch (optionType)
- {
- case 0:
- optionLength = *(data + processedSize + 1);
- break;
+ optionType = *(data + processedSize);
+ ipv6Option = ipv6OptionDemux->GetOption (optionType);
- case 1:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
+ if (ipv6Option == 0)
+ {
+ optionType >>= 6;
+ switch (optionType)
+ {
+ case 0:
+ optionLength = *(data + processedSize + 1);
+ break;
- case 2:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
+ case 1:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
- case 3:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
+ case 2:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
- if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
- {
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
- }
+ case 3:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
+ if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
+ {
+ icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+ }
- default:
- break;
- }
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+ default:
+ break;
+ }
+
+ }
+ else
+ {
+ optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
+ }
+
+ processedSize += optionLength;
+ p->RemoveAtStart (optionLength);
}
- else
- {
- optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
- }
-
- processedSize += optionLength;
- p->RemoveAtStart (optionLength);
- }
return processedSize;
}
@@ -203,9 +203,9 @@ uint8_t Ipv6ExtensionHopByHop::Process (Ptr& packet, uint8_t offset, Ipv
Ipv6ExtensionHopByHopHeader hopbyhopHeader;
p->RemoveHeader (hopbyhopHeader);
if (nextHeader)
- {
- *nextHeader = hopbyhopHeader.GetNextHeader ();
- }
+ {
+ *nextHeader = hopbyhopHeader.GetNextHeader ();
+ }
uint8_t processedSize = hopbyhopHeader.GetOptionsOffset ();
offset += processedSize;
@@ -255,9 +255,9 @@ uint8_t Ipv6ExtensionDestination::Process (Ptr& packet, uint8_t offset,
Ipv6ExtensionDestinationHeader destinationHeader;
p->RemoveHeader (destinationHeader);
if (nextHeader)
- {
- *nextHeader = destinationHeader.GetNextHeader ();
- }
+ {
+ *nextHeader = destinationHeader.GetNextHeader ();
+ }
uint8_t processedSize = destinationHeader.GetOptionsOffset ();
offset += processedSize;
@@ -295,9 +295,9 @@ void Ipv6ExtensionFragment::DoDispose ()
NS_LOG_FUNCTION_NOARGS ();
for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
- {
- it->second = 0;
- }
+ {
+ it->second = 0;
+ }
m_fragments.clear ();
Ipv6Extension::DoDispose ();
@@ -321,9 +321,9 @@ uint8_t Ipv6ExtensionFragment::Process (Ptr& packet, uint8_t offset, Ipv
p->RemoveHeader (fragmentHeader);
if (nextHeader)
- {
- *nextHeader = fragmentHeader.GetNextHeader ();
- }
+ {
+ *nextHeader = fragmentHeader.GetNextHeader ();
+ }
bool moreFragment = fragmentHeader.GetMoreFragment ();
uint16_t fragmentOffset = fragmentHeader.GetOffset ();
@@ -335,35 +335,35 @@ uint8_t Ipv6ExtensionFragment::Process (Ptr& packet, uint8_t offset, Ipv
MapFragments_t::iterator it = m_fragments.find (fragmentsId);
if (it == m_fragments.end ())
- {
- fragments = Create ();
- m_fragments.insert (std::make_pair (fragmentsId, fragments));
- }
+ {
+ fragments = Create ();
+ m_fragments.insert (std::make_pair (fragmentsId, fragments));
+ }
else
- {
- fragments = it->second;
- }
+ {
+ fragments = it->second;
+ }
if (fragmentOffset == 0)
- {
- Ptr unfragmentablePart = packet->Copy ();
- unfragmentablePart->RemoveAtEnd (packet->GetSize () - offset);
- fragments->SetUnfragmentablePart (unfragmentablePart);
- }
+ {
+ Ptr unfragmentablePart = packet->Copy ();
+ unfragmentablePart->RemoveAtEnd (packet->GetSize () - offset);
+ fragments->SetUnfragmentablePart (unfragmentablePart);
+ }
fragments->AddFragment (p, fragmentOffset, moreFragment);
if (fragments->IsEntire ())
- {
- packet = fragments->GetPacket ();
- isDropped = false;
- }
+ {
+ packet = fragments->GetPacket ();
+ isDropped = false;
+ }
else
- {
- NS_LOG_LOGIC ("Fragment. Drop!");
- m_dropTrace (packet);
- isDropped = true;
- }
+ {
+ NS_LOG_LOGIC ("Fragment. Drop!");
+ m_dropTrace (packet);
+ isDropped = true;
+ }
return 0;
}
@@ -381,10 +381,10 @@ void Ipv6ExtensionFragment::GetFragments (Ptr packet, uint32_t maxFragme
bool moreHeader = true;
if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
|| (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
- {
- moreHeader = false;
- ipv6Header.SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
- }
+ {
+ moreHeader = false;
+ ipv6Header.SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
std::list > unfragmentablePart;
uint32_t unfragmentablePartSize = 0;
@@ -394,64 +394,64 @@ void Ipv6ExtensionFragment::GetFragments (Ptr packet, uint32_t maxFragme
uint8_t extensionHeaderLength;
while (moreHeader)
- {
- if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
{
- Ipv6ExtensionHopByHopHeader *hopbyhopHeader = new Ipv6ExtensionHopByHopHeader ();
- p->RemoveHeader (*hopbyhopHeader);
+ if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ {
+ Ipv6ExtensionHopByHopHeader *hopbyhopHeader = new Ipv6ExtensionHopByHopHeader ();
+ p->RemoveHeader (*hopbyhopHeader);
- nextHeader = hopbyhopHeader->GetNextHeader ();
- extensionHeaderLength = hopbyhopHeader->GetLength ();
+ nextHeader = hopbyhopHeader->GetNextHeader ();
+ extensionHeaderLength = hopbyhopHeader->GetLength ();
- if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
- || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
- {
- moreHeader = false;
- hopbyhopHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
- }
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ hopbyhopHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
- unfragmentablePart.push_back (std::make_pair (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
- unfragmentablePartSize += extensionHeaderLength;
+ unfragmentablePart.push_back (std::make_pair (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
+ unfragmentablePartSize += extensionHeaderLength;
+ }
+ else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
+ {
+ uint8_t numberAddress = (*(p->PeekData () + 1)) / 2;
+ Ipv6ExtensionLooseRoutingHeader *routingHeader = new Ipv6ExtensionLooseRoutingHeader ();
+ routingHeader->SetNumberAddress (numberAddress);
+ p->RemoveHeader (*routingHeader);
+
+ nextHeader = routingHeader->GetNextHeader ();
+ extensionHeaderLength = routingHeader->GetLength ();
+
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ routingHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
+
+ unfragmentablePart.push_back (std::make_pair (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
+ unfragmentablePartSize += extensionHeaderLength;
+ }
+ else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
+ {
+ Ipv6ExtensionDestinationHeader *destinationHeader = new Ipv6ExtensionDestinationHeader ();
+ p->RemoveHeader (*destinationHeader);
+
+ nextHeader = destinationHeader->GetNextHeader ();
+ extensionHeaderLength = destinationHeader->GetLength ();
+
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ destinationHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
+
+ unfragmentablePart.push_back (std::make_pair (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION));
+ unfragmentablePartSize += extensionHeaderLength;
+ }
}
- else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
- {
- uint8_t numberAddress = (*(p->PeekData () + 1)) / 2;
- Ipv6ExtensionLooseRoutingHeader *routingHeader = new Ipv6ExtensionLooseRoutingHeader ();
- routingHeader->SetNumberAddress (numberAddress);
- p->RemoveHeader (*routingHeader);
-
- nextHeader = routingHeader->GetNextHeader ();
- extensionHeaderLength = routingHeader->GetLength ();
-
- if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
- || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
- {
- moreHeader = false;
- routingHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
- }
-
- unfragmentablePart.push_back (std::make_pair (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
- unfragmentablePartSize += extensionHeaderLength;
- }
- else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
- {
- Ipv6ExtensionDestinationHeader *destinationHeader = new Ipv6ExtensionDestinationHeader ();
- p->RemoveHeader (*destinationHeader);
-
- nextHeader = destinationHeader->GetNextHeader ();
- extensionHeaderLength = destinationHeader->GetLength ();
-
- if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
- || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
- {
- moreHeader = false;
- destinationHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
- }
-
- unfragmentablePart.push_back (std::make_pair (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION));
- unfragmentablePartSize += extensionHeaderLength;
- }
- }
Ipv6ExtensionFragmentHeader fragmentHeader;
uint8_t fragmentHeaderSize = fragmentHeader.GetSerializedSize ();
@@ -465,65 +465,65 @@ void Ipv6ExtensionFragment::GetFragments (Ptr packet, uint32_t maxFragme
uint16_t offset = 0;
do
- {
- if (p->GetSize () > offset + maxFragmentablePartSize)
{
- moreFragment = true;
- currentFragmentablePartSize = maxFragmentablePartSize;
- }
- else
- {
- moreFragment = false;
- currentFragmentablePartSize = p->GetSize () - offset;
- }
+ if (p->GetSize () > offset + maxFragmentablePartSize)
+ {
+ moreFragment = true;
+ currentFragmentablePartSize = maxFragmentablePartSize;
+ }
+ else
+ {
+ moreFragment = false;
+ currentFragmentablePartSize = p->GetSize () - offset;
+ }
- currentFragmentablePartSize -= currentFragmentablePartSize % 8;
+ currentFragmentablePartSize -= currentFragmentablePartSize % 8;
- fragmentHeader.SetNextHeader (nextHeader);
- fragmentHeader.SetLength (currentFragmentablePartSize);
- fragmentHeader.SetOffset (offset);
- fragmentHeader.SetMoreFragment (moreFragment);
- fragmentHeader.SetIdentification (identification);
+ fragmentHeader.SetNextHeader (nextHeader);
+ fragmentHeader.SetLength (currentFragmentablePartSize);
+ fragmentHeader.SetOffset (offset);
+ fragmentHeader.SetMoreFragment (moreFragment);
+ fragmentHeader.SetIdentification (identification);
- Ptr fragment = p->CreateFragment (offset, currentFragmentablePartSize);
- offset += currentFragmentablePartSize;
+ Ptr fragment = p->CreateFragment (offset, currentFragmentablePartSize);
+ offset += currentFragmentablePartSize;
- fragment->AddHeader (fragmentHeader);
+ fragment->AddHeader (fragmentHeader);
- for (std::list >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
- {
- if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
- {
- fragment->AddHeader (*dynamic_cast(it->first));
- }
- else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
- {
- fragment->AddHeader (*dynamic_cast(it->first));
- }
- else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
- {
- fragment->AddHeader (*dynamic_cast(it->first));
- }
- }
+ for (std::list >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
+ {
+ if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ {
+ fragment->AddHeader (*dynamic_cast(it->first));
+ }
+ else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
+ {
+ fragment->AddHeader (*dynamic_cast(it->first));
+ }
+ else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
+ {
+ fragment->AddHeader (*dynamic_cast(it->first));
+ }
+ }
- ipv6Header.SetPayloadLength (fragment->GetSize ());
- fragment->AddHeader (ipv6Header);
+ ipv6Header.SetPayloadLength (fragment->GetSize ());
+ fragment->AddHeader (ipv6Header);
- std::ostringstream oss;
- fragment->Print (oss);
- listFragments.push_back (fragment);
- } while (moreFragment);
+ std::ostringstream oss;
+ fragment->Print (oss);
+ listFragments.push_back (fragment);
+ } while (moreFragment);
for (std::list >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
- {
- delete it->first;
- }
+ {
+ delete it->first;
+ }
unfragmentablePart.clear ();
}
Ipv6ExtensionFragment::Fragments::Fragments ()
- : m_moreFragment (0)
+: m_moreFragment (0)
{
}
@@ -536,17 +536,17 @@ void Ipv6ExtensionFragment::Fragments::AddFragment (Ptr fragment, uint16
std::list, uint16_t> >::iterator it;
for (it = m_fragments.begin (); it != m_fragments.end (); it++)
- {
- if (it->second > fragmentOffset)
{
- break;
+ if (it->second > fragmentOffset)
+ {
+ break;
+ }
}
- }
if (it == m_fragments.end ())
- {
- m_moreFragment = moreFragment;
- }
+ {
+ m_moreFragment = moreFragment;
+ }
m_fragments.insert (it, std::make_pair, uint16_t> (fragment, fragmentOffset));
}
@@ -561,20 +561,20 @@ bool Ipv6ExtensionFragment::Fragments::IsEntire () const
bool ret = !m_moreFragment && m_fragments.size () > 0;
if (ret)
- {
- uint16_t lastEndOffset = 0;
-
- for (std::list, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
{
- if (lastEndOffset != it->second)
- {
- ret = false;
- break;
- }
+ uint16_t lastEndOffset = 0;
- lastEndOffset += it->first->GetSize ();
+ for (std::list, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+ {
+ if (lastEndOffset != it->second)
+ {
+ ret = false;
+ break;
+ }
+
+ lastEndOffset += it->first->GetSize ();
+ }
}
- }
return ret;
}
@@ -584,9 +584,9 @@ Ptr Ipv6ExtensionFragment::Fragments::GetPacket () const
Ptr p = m_unfragmentable->Copy ();
for (std::list, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
- {
- p->AddAtEnd (it->first);
- }
+ {
+ p->AddAtEnd (it->first);
+ }
return p;
}
@@ -640,14 +640,14 @@ uint8_t Ipv6ExtensionRouting::Process (Ptr& packet, uint8_t offset, Ipv6
const uint8_t *buff = packet->PeekData ();
uint8_t routingNextHeader = *buff;
- uint8_t routingLength = *(buff+1);
- uint8_t routingTypeRouting = *(buff+2);
- uint8_t routingSegmentsLeft = *(buff+3);
+ uint8_t routingLength = *(buff + 1);
+ uint8_t routingTypeRouting = *(buff + 2);
+ uint8_t routingSegmentsLeft = *(buff + 3);
if (nextHeader)
- {
- *nextHeader = routingNextHeader;
- }
+ {
+ *nextHeader = routingNextHeader;
+ }
Ptr icmpv6 = GetNode ()->GetObject ()->GetIcmpv6 ();
@@ -655,22 +655,22 @@ uint8_t Ipv6ExtensionRouting::Process (Ptr& packet, uint8_t offset, Ipv6
Ptr ipv6ExtensionRouting = ipv6ExtensionRoutingDemux->GetExtensionRouting (routingTypeRouting);
if (ipv6ExtensionRouting == 0)
- {
- if (routingSegmentsLeft == 0)
{
- isDropped = false;
- }
- else
- {
- NS_LOG_LOGIC ("Malformed header. Drop!");
+ if (routingSegmentsLeft == 0)
+ {
+ isDropped = false;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Malformed header. Drop!");
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
- m_dropTrace (packet);
- isDropped = true;
- }
+ icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
+ m_dropTrace (packet);
+ isDropped = true;
+ }
- return routingLength;
- }
+ return routingLength;
+ }
return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, isDropped);
}
@@ -683,9 +683,9 @@ TypeId Ipv6ExtensionRoutingDemux::GetTypeId ()
static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingDemux")
.SetParent ()
.AddAttribute ("Routing Extensions", "The set of IPv6 Routing extensions registered with this demux.",
- ObjectVectorValue (),
- MakeObjectVectorAccessor (&Ipv6ExtensionRoutingDemux::m_extensionsRouting),
- MakeObjectVectorChecker ())
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6ExtensionRoutingDemux::m_extensionsRouting),
+ MakeObjectVectorChecker ())
;
return tid;
}
@@ -701,10 +701,10 @@ Ipv6ExtensionRoutingDemux::~Ipv6ExtensionRoutingDemux ()
void Ipv6ExtensionRoutingDemux::DoDispose ()
{
for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
- {
- (*it)->Dispose ();
- *it = 0;
- }
+ {
+ (*it)->Dispose ();
+ *it = 0;
+ }
m_extensionsRouting.clear ();
m_node = 0;
Object::DoDispose ();
@@ -723,12 +723,12 @@ void Ipv6ExtensionRoutingDemux::Insert (Ptr extensionRouti
Ptr Ipv6ExtensionRoutingDemux::GetExtensionRouting (uint8_t typeRouting)
{
for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
- {
- if ((*i)->GetTypeRouting () == typeRouting)
{
- return *i;
+ if ((*i)->GetTypeRouting () == typeRouting)
+ {
+ return *i;
+ }
}
- }
return 0;
}
@@ -792,9 +792,9 @@ uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset,
p->RemoveHeader (routingHeader);
if (nextHeader)
- {
- *nextHeader = routingHeader.GetNextHeader ();
- }
+ {
+ *nextHeader = routingHeader.GetNextHeader ();
+ }
Ptr icmpv6 = GetNode ()->GetObject ()->GetIcmpv6 ();
@@ -808,51 +808,51 @@ uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset,
Ipv6Address nextAddress;
if (segmentsLeft == 0)
- {
- isDropped = false;
- return routingHeader.GetSerializedSize ();
- }
+ {
+ isDropped = false;
+ return routingHeader.GetSerializedSize ();
+ }
if (length % 2 != 0)
- {
- NS_LOG_LOGIC ("Malformed header. Drop!");
- icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
- m_dropTrace (packet);
- isDropped = true;
- return routingHeader.GetSerializedSize ();
- }
+ {
+ NS_LOG_LOGIC ("Malformed header. Drop!");
+ icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
if (segmentsLeft > nbAddress)
- {
- NS_LOG_LOGIC ("Malformed header. Drop!");
- icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3);
- m_dropTrace (packet);
- isDropped = true;
- return routingHeader.GetSerializedSize ();
- }
+ {
+ NS_LOG_LOGIC ("Malformed header. Drop!");
+ icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3);
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
routingHeader.SetSegmentsLeft (segmentsLeft - 1);
nextAddressIndex = nbAddress - segmentsLeft;
nextAddress = routingHeader.GetRouterAddress (nextAddressIndex);
if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
- {
- m_dropTrace (packet);
- isDropped = true;
- return routingHeader.GetSerializedSize ();
- }
+ {
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
routingHeader.SetRouterAddress (nextAddressIndex, destAddress);
ipv6header.SetDestinationAddress (nextAddress);
if (hopLimit <= 1)
- {
- NS_LOG_LOGIC ("Time Exceeded : Hop Limit <= 1. Drop!");
- icmpv6->SendErrorTimeExceeded (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT);
- m_dropTrace (packet);
- isDropped = true;
- return routingHeader.GetSerializedSize ();
- }
+ {
+ NS_LOG_LOGIC ("Time Exceeded : Hop Limit <= 1. Drop!");
+ icmpv6->SendErrorTimeExceeded (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT);
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
routingHeader.SetLength (88);
ipv6header.SetHopLimit (hopLimit - 1);
@@ -873,14 +873,14 @@ uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset,
Ptr rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
if (rtentry)
- {
- /* we know a route exists so send packet now */
- ipv6->SendRealOut (rtentry, p, ipv6header);
- }
+ {
+ /* we know a route exists so send packet now */
+ ipv6->SendRealOut (rtentry, p, ipv6header);
+ }
else
- {
- NS_LOG_INFO ("No route for next router");
- }
+ {
+ NS_LOG_INFO ("No route for next router");
+ }
/* as we directly send packet, mark it as dropped */
isDropped = true;
diff --git a/src/internet-stack/ipv6-option-demux.cc b/src/internet-stack/ipv6-option-demux.cc
index 37b65917d..254793ad6 100644
--- a/src/internet-stack/ipv6-option-demux.cc
+++ b/src/internet-stack/ipv6-option-demux.cc
@@ -35,9 +35,9 @@ TypeId Ipv6OptionDemux::GetTypeId ()
static TypeId tid = TypeId ("ns3::Ipv6OptionDemux")
.SetParent ()
.AddAttribute ("Options", "The set of IPv6 options registered with this demux.",
- ObjectVectorValue (),
- MakeObjectVectorAccessor (&Ipv6OptionDemux::m_options),
- MakeObjectVectorChecker ())
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6OptionDemux::m_options),
+ MakeObjectVectorChecker ())
;
return tid;
}
@@ -53,10 +53,10 @@ Ipv6OptionDemux::~Ipv6OptionDemux ()
void Ipv6OptionDemux::DoDispose ()
{
for (Ipv6OptionList_t::iterator it = m_options.begin (); it != m_options.end (); it++)
- {
- (*it)->Dispose ();
- *it = 0;
- }
+ {
+ (*it)->Dispose ();
+ *it = 0;
+ }
m_options.clear ();
m_node = 0;
Object::DoDispose ();
@@ -75,12 +75,12 @@ void Ipv6OptionDemux::Insert (Ptr option)
Ptr Ipv6OptionDemux::GetOption (int optionNumber)
{
for (Ipv6OptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
- {
- if ((*i)->GetOptionNumber () == optionNumber)
{
- return *i;
+ if ((*i)->GetOptionNumber () == optionNumber)
+ {
+ return *i;
+ }
}
- }
return 0;
}
diff --git a/src/internet-stack/ipv6-option-demux.h b/src/internet-stack/ipv6-option-demux.h
index 63f6f7237..3349744ce 100644
--- a/src/internet-stack/ipv6-option-demux.h
+++ b/src/internet-stack/ipv6-option-demux.h
@@ -37,66 +37,66 @@ class Node;
*/
class Ipv6OptionDemux : public Object
{
- public:
- /**
- * \brief The interface ID.
- * \return type ID
- */
- static TypeId GetTypeId (void);
+public:
+ /**
+ * \brief The interface ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
- /**
- * \brief Constructor.
- */
- Ipv6OptionDemux ();
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionDemux ();
- /**
- * \brief Destructor.
- */
- virtual ~Ipv6OptionDemux ();
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionDemux ();
- /**
- * \brief Set the node.
- * \param node the node to set
- */
- void SetNode (Ptr node);
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr node);
- /**
- * \brief Insert a new IPv6 Option.
- * \param option the option to insert
- */
- void Insert (Ptr option);
+ /**
+ * \brief Insert a new IPv6 Option.
+ * \param option the option to insert
+ */
+ void Insert (Ptr option);
- /**
- * \brief Get the option corresponding to optionNumber.
- * \param optionNumber the option number of the option to retrieve
- * \return a matching IPv6 option
- */
- Ptr GetOption (int optionNumber);
+ /**
+ * \brief Get the option corresponding to optionNumber.
+ * \param optionNumber the option number of the option to retrieve
+ * \return a matching IPv6 option
+ */
+ Ptr GetOption (int optionNumber);
- /**
- * \brief Remove an option from this demux.
- * \param option pointer on the option to remove
- */
- void Remove (Ptr option);
+ /**
+ * \brief Remove an option from this demux.
+ * \param option pointer on the option to remove
+ */
+ void Remove (Ptr option);
- protected:
- /**
- * \brief Dispose this object.
- */
- virtual void DoDispose();
+protected:
+ /**
+ * \brief Dispose this object.
+ */
+ virtual void DoDispose();
- private:
- typedef std::list > Ipv6OptionList_t;
+private:
+ typedef std::list > Ipv6OptionList_t;
- /**
- * \brief List of IPv6 Options supported.
- */
- Ipv6OptionList_t m_options;
+ /**
+ * \brief List of IPv6 Options supported.
+ */
+ Ipv6OptionList_t m_options;
- /**
- * \brief The node.
- */
- Ptr m_node;
+ /**
+ * \brief The node.
+ */
+ Ptr m_node;
};
} /* namespace ns3 */
diff --git a/src/internet-stack/ipv6-option-header.cc b/src/internet-stack/ipv6-option-header.cc
index 75f8c17fc..05f124482 100644
--- a/src/internet-stack/ipv6-option-header.cc
+++ b/src/internet-stack/ipv6-option-header.cc
@@ -45,7 +45,7 @@ TypeId Ipv6OptionHeader::GetInstanceTypeId () const
}
Ipv6OptionHeader::Ipv6OptionHeader ()
- : m_type (0),
+: m_type (0),
m_length (0)
{
}
@@ -212,9 +212,9 @@ void Ipv6OptionPadnHeader::Serialize (Buffer::Iterator start) const
i.WriteU8 (GetLength ());
for (int padding = 0; padding < GetLength (); padding++)
- {
- i.WriteU8 (0);
- }
+ {
+ i.WriteU8 (0);
+ }
}
uint32_t Ipv6OptionPadnHeader::Deserialize (Buffer::Iterator start)
@@ -315,7 +315,7 @@ TypeId Ipv6OptionRouterAlertHeader::GetInstanceTypeId () const
}
Ipv6OptionRouterAlertHeader::Ipv6OptionRouterAlertHeader ()
- : m_value (0)
+: m_value (0)
{
SetLength (2);
}
diff --git a/src/internet-stack/ipv6-option.cc b/src/internet-stack/ipv6-option.cc
index 96c1fde13..8a6914e05 100644
--- a/src/internet-stack/ipv6-option.cc
+++ b/src/internet-stack/ipv6-option.cc
@@ -36,9 +36,9 @@ TypeId Ipv6Option::GetTypeId ()
static TypeId tid = TypeId ("ns3::Ipv6Option")
.SetParent ()
.AddAttribute ("OptionNumber", "The IPv6 option number.",
- UintegerValue (0),
- MakeUintegerAccessor (&Ipv6Option::GetOptionNumber),
- MakeUintegerChecker ())
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6Option::GetOptionNumber),
+ MakeUintegerChecker ())
;
return tid;
}
diff --git a/src/internet-stack/tcp-l4-protocol.cc b/src/internet-stack/tcp-l4-protocol.cc
index 7b9e87cec..b6c517cdf 100644
--- a/src/internet-stack/tcp-l4-protocol.cc
+++ b/src/internet-stack/tcp-l4-protocol.cc
@@ -576,6 +576,7 @@ TcpL4Protocol::Send (Ptr packet,
// should be cached.
Ipv4Header header;
header.SetDestination (daddr);
+ header.SetProtocol (PROT_NUMBER);
Socket::SocketErrno errno_;
Ptr route;
uint32_t oif = 0; //specify non-zero if bound to a source address
@@ -615,6 +616,7 @@ TcpL4Protocol::SendPacket (Ptr packet, const TcpHeader &outgoing,
// should be cached.
Ipv4Header header;
header.SetDestination (daddr);
+ header.SetProtocol (PROT_NUMBER);
Socket::SocketErrno errno_;
Ptr route;
uint32_t oif = 0; //specify non-zero if bound to a source address
diff --git a/src/internet-stack/udp-socket-impl.cc b/src/internet-stack/udp-socket-impl.cc
index c2a52df43..b76408dbc 100644
--- a/src/internet-stack/udp-socket-impl.cc
+++ b/src/internet-stack/udp-socket-impl.cc
@@ -373,6 +373,8 @@ UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port)
// Get the primary address
Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
Ipv4Address addri = iaddr.GetLocal ();
+ if (addri == Ipv4Address ("127.0.0.1"))
+ continue;
Ipv4Mask maski = iaddr.GetMask ();
if (maski == Ipv4Mask::GetOnes ())
{
@@ -403,6 +405,7 @@ UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port)
{
Ipv4Header header;
header.SetDestination (dest);
+ header.SetProtocol (UdpL4Protocol::PROT_NUMBER);
Socket::SocketErrno errno_;
Ptr route;
uint32_t oif = 0; //specify non-zero if bound to a source address
diff --git a/src/internet-stack/wscript b/src/internet-stack/wscript
index 099ee4113..7ac0383a9 100644
--- a/src/internet-stack/wscript
+++ b/src/internet-stack/wscript
@@ -128,6 +128,8 @@ def build(bld):
'sequence-number.h',
'icmpv4.h',
'icmpv6-header.h',
+ # used by routing
+ 'ipv4-interface.h',
'ipv4-l3-protocol.h',
'ipv6-l3-protocol.h',
'ipv6-extension-header.h',
diff --git a/src/node/socket.cc b/src/node/socket.cc
index d75ab7180..33c9c8db6 100644
--- a/src/node/socket.cc
+++ b/src/node/socket.cc
@@ -45,7 +45,9 @@ Ptr
Socket::CreateSocket (Ptr node, TypeId tid)
{
Ptr s;
+ NS_ASSERT (node != 0);
Ptr socketFactory = node->GetObject (tid);
+ NS_ASSERT (socketFactory != 0);
s = socketFactory->CreateSocket ();
NS_ASSERT (s != 0);
return s;
diff --git a/src/routing/manet/aodv/aodv-neighbor.cc b/src/routing/manet/aodv/aodv-neighbor.cc
new file mode 100644
index 000000000..0816bb82b
--- /dev/null
+++ b/src/routing/manet/aodv/aodv-neighbor.cc
@@ -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
+ * Pavel Boyko
+ */
+
+#include "aodv-neighbor.h"
+#include "ns3/log.h"
+#include
+
+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::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::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::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::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 a)
+{
+ m_arp.push_back (a);
+}
+
+void
+Neighbors::DelArpCache (Ptr 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 >::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::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
+ {
+ if (i->m_hardwareAddress == addr)
+ i->close = true;
+ }
+ Purge ();
+}
+}
+}
+
diff --git a/src/routing/manet/aodv/aodv-neighbor.h b/src/routing/manet/aodv/aodv-neighbor.h
new file mode 100644
index 000000000..7709ffc68
--- /dev/null
+++ b/src/routing/manet/aodv/aodv-neighbor.h
@@ -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
+ * Pavel Boyko
+ */
+
+#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
+
+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);
+ /// Don't use given ARP cache any more (interface is down)
+ void DelArpCache (Ptr);
+ /// Get callback to ProcessTxError
+ Callback GetTxErrorCallback () const { return m_txErrorCallback; }
+
+ ///\name Handle link failure callback
+ //\{
+ void SetCallback (Callback cb) { m_handleLinkFailure = cb;}
+ Callback GetCallback () const { return m_handleLinkFailure; }
+ //\}
+private:
+ /// link failure callback
+ Callback m_handleLinkFailure;
+ /// TX error callback
+ Callback m_txErrorCallback;
+ /// Timer for neighbor's list. Schedule Purge().
+ Timer m_ntimer;
+ /// vector of entries
+ std::vector m_nb;
+ /// list of ARP cached to be used for layer 2 notifications processing
+ std::vector > 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 */
diff --git a/src/routing/manet/aodv/aodv-packet.cc b/src/routing/manet/aodv/aodv-packet.cc
new file mode 100644
index 000000000..66c67aa09
--- /dev/null
+++ b/src/routing/manet/aodv/aodv-packet.cc
@@ -0,0 +1,580 @@
+/* -*- 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
+ * Pavel Boyko
+ */
+#include "aodv-packet.h"
+#include "ns3/address-utils.h"
+#include "ns3/packet.h"
+
+namespace ns3
+{
+namespace aodv
+{
+
+TypeHeader::TypeHeader (MessageType t) :
+ m_type (t), m_valid (true)
+{
+}
+
+TypeId
+TypeHeader::GetInstanceTypeId () const
+{
+ return TypeId ();
+}
+
+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" << "\n";
+ break;
+ }
+ case AODVTYPE_RREP:
+ {
+ os << "RREP" << "\n";
+ break;
+ }
+ case AODVTYPE_RERR:
+ {
+ os << "RERR" << "\n";
+ break;
+ }
+ case AODVTYPE_RREP_ACK:
+ {
+ os << "RREP_ACK" << "\n";
+ 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)
+{
+}
+
+TypeId
+RreqHeader::GetInstanceTypeId () const
+{
+ return TypeId ();
+}
+
+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 << "\n" << "destination: ipv4 " << m_dst
+ << " " << "sequence number " << m_dstSeqNo << "\n" << "source: ipv4 "
+ << m_origin << " " << "sequence number " << m_originSeqNo << "\n"
+ << "flags:\n" << "Gratuitous RREP " << (*this).GetGratiousRrep () << "\n"
+ << "Destination only " << (*this).GetDestinationOnly () << "\n"
+ << "Unknown sequence number " << (*this).GetUnknownSeqno () << "\n";
+}
+
+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 ());
+}
+
+TypeId
+RrepHeader::GetInstanceTypeId () const
+{
+ return TypeId ();
+}
+
+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 << "\n";
+ else
+ os << "\n";
+ os << "source ipv4 " << m_origin << "\n" << "life time " << m_lifeTime
+ << "\n" << "acknowledgment required flag " << (*this).GetAckRequired ()
+ << "\n";
+}
+
+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)
+{
+}
+
+TypeId
+RrepAckHeader::GetInstanceTypeId () const
+{
+ return TypeId ();
+}
+
+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)
+{
+}
+
+TypeId
+RerrHeader::GetInstanceTypeId () const
+{
+ return TypeId ();
+}
+
+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::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):\n";
+ std::map::const_iterator j;
+ for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
+ {
+ os << (*j).first << ", " << (*j).second << "\n";
+ }
+ os << "No delete flag " << (*this).GetNoDelete () << "\n";
+}
+
+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 & un )
+{
+ if (m_unreachableDstSeqNo.empty ())
+ return false;
+ std::map::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::const_iterator j = m_unreachableDstSeqNo.begin ();
+ std::map::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;
+}
+}
+}
diff --git a/src/routing/manet/aodv/aodv-packet.h b/src/routing/manet/aodv/aodv-packet.h
new file mode 100644
index 000000000..374272b06
--- /dev/null
+++ b/src/routing/manet/aodv/aodv-packet.h
@@ -0,0 +1,330 @@
+/* -*- 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
+ * Pavel Boyko
+ */
+#ifndef AODVPACKET_H
+#define AODVPACKET_H
+
+#include
+#include "ns3/header.h"
+#include "ns3/enum.h"
+#include "ns3/ipv4-address.h"
+#include
+#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
+ //\{
+ 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
+ //\{
+ 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; }
+ uint8_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
+ //\{
+ 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
+ //\{
+ 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
+ //\{
+ 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 & 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 m_unreachableDstSeqNo;
+};
+
+std::ostream & operator<< (std::ostream & os, RerrHeader const &);
+}
+}
+#endif /* AODVPACKET_H */
diff --git a/src/routing/manet/aodv/aodv-routing-protocol.cc b/src/routing/manet/aodv/aodv-routing-protocol.cc
new file mode 100644
index 000000000..aeb07b0b5
--- /dev/null
+++ b/src/routing/manet/aodv/aodv-routing-protocol.cc
@@ -0,0 +1,1498 @@
+/* -*- 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
+ * Pavel Boyko
+ */
+#include "aodv-routing-protocol.h"
+#include "ns3/log.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
+
+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;
+
+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 ()
+ .AddConstructor ()
+ .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 ())
+ .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
+ UintegerValue (10),
+ MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
+ MakeUintegerChecker ())
+ .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 ())
+ .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
+ UintegerValue (35),
+ MakeUintegerAccessor (&RoutingProtocol::NetDiameter),
+ MakeUintegerChecker ())
+ .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::MaxQueueLen),
+ MakeUintegerChecker ())
+ .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
+ TimeValue (Seconds (30)),
+ MakeTimeAccessor (&RoutingProtocol::MaxQueueTime),
+ MakeTimeChecker ())
+ .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
+ UintegerValue (2),
+ MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss),
+ MakeUintegerChecker ())
+ .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;
+}
+
+RoutingProtocol::~RoutingProtocol ()
+{
+}
+
+void
+RoutingProtocol::DoDispose ()
+{
+ m_ipv4 = 0;
+ for (std::map , Ipv4InterfaceAddress>::iterator iter =
+ m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
+ {
+ iter->first->Close ();
+ }
+ m_socketAddresses.clear ();
+ Ipv4RoutingProtocol::DoDispose ();
+}
+
+void
+RoutingProtocol::Start ()
+{
+ m_scb = MakeCallback (&RoutingProtocol::Send, this);
+ m_ecb = MakeCallback (&RoutingProtocol::Drop, this);
+
+ if (EnableHello)
+ {
+ m_nb.ScheduleTimer ();
+ }
+ m_rreqRateLimitTimer.SetFunction (&RoutingProtocol::RreqRateLimitTimerExpire,
+ this);
+ m_rreqRateLimitTimer.Schedule (Seconds (1));
+}
+
+Ptr
+RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header,
+ uint32_t oif, Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header.GetDestination ());
+ if (m_socketAddresses.empty ())
+ {
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ NS_LOG_LOGIC ("No aodv interfaces");
+ Ptr route;
+ return route;
+ }
+ sockerr = Socket::ERROR_NOTERROR;
+ Ptr route;
+ Ipv4Address dst = header.GetDestination ();
+ RoutingTableEntry rt;
+ if (m_routingTable.LookupRoute (dst, rt))
+ {
+ if (rt.GetFlag () == VALID)
+ {
+ route = rt.GetRoute ();
+ NS_ASSERT (route != 0);
+ NS_LOG_LOGIC("exist route to " << route->GetDestination() << " from interface " << route->GetSource());
+ UpdateRouteLifeTime (dst, ActiveRouteTimeout);
+ UpdateRouteLifeTime (route->GetGateway (), ActiveRouteTimeout);
+ }
+ else
+ {
+ bool result = true;
+ // May be null pointer (e.g. tcp-socket give null pointer)
+ if (p != Ptr ())
+ {
+ QueueEntry newEntry (p, header, m_scb, m_ecb);
+ result = m_queue.Enqueue (newEntry);
+ if (result)
+ NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue");
+
+ }
+ if ((rt.GetFlag () == INVALID) && result)
+ {
+ SendRequest (dst);
+ }
+ }
+ }
+ else
+ {
+ bool result = true;
+ if (p != Ptr ())
+ {
+ QueueEntry newEntry (p, header, m_scb, m_ecb);
+ // Some protocols may ask route several times for a single packet.
+ result = m_queue.Enqueue (newEntry);
+ if (result)
+ NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
+ }
+ if (result)
+ SendRequest (dst);
+ }
+ return route;
+}
+
+bool
+RoutingProtocol::RouteInput (Ptr p, const Ipv4Header &header,
+ Ptr 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);
+ // 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 ();
+
+ if (IsMyOwnAddress (origin))
+ return true;
+
+ // Local delivery to AODV interfaces
+ for (std::map , 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 ())
+ {
+ if (!EnableBroadcast)
+ {
+ return true;
+ }
+ 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 = p->Copy ();
+ lcb (p, header, iif);
+ if (header.GetTtl () > 1)
+ {
+ NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
+ RoutingTableEntry toBroadcast;
+ if (m_routingTable.LookupRoute (dst, toBroadcast))
+ {
+ Ptr 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;
+ }
+ }
+ for (std::map , Ipv4InterfaceAddress>::const_iterator j =
+ m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+ {
+ Ipv4InterfaceAddress iface = j->second;
+ if (dst == iface.GetLocal ())
+ {
+ UpdateRouteLifeTime (origin, ActiveRouteTimeout);
+ RoutingTableEntry toOrigin;
+ if (m_routingTable.LookupRoute (origin, toOrigin))
+ {
+ UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
+ m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
+ }
+ NS_LOG_LOGIC ("Unicast local delivery to " << iface.GetLocal ());
+ lcb (p, header, iif);
+ return true;
+ }
+ }
+
+ // Forwarding
+ return Forwarding (p, header, ucb, ecb);
+}
+
+bool
+RoutingProtocol::Forwarding (Ptr p, const Ipv4Header & header,
+ UnicastForwardCallback ucb, ErrorCallback ecb)
+{
+ Ipv4Address dst = header.GetDestination ();
+ Ipv4Address origin = header.GetSource ();
+ m_routingTable.Purge ();
+ RoutingTableEntry toDst;
+ if (m_routingTable.LookupRoute (dst, toDst))
+ {
+ if (toDst.GetFlag () == VALID)
+ {
+ Ptr 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)
+{
+ 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;
+ Simulator::ScheduleNow (&RoutingProtocol::Start, this);
+}
+
+void
+RoutingProtocol::NotifyInterfaceUp (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
+ Ptr l3 = m_ipv4->GetObject ();
+ 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::CreateSocket (GetObject (),
+ UdpSocketFactory::GetTypeId ());
+ NS_ASSERT (socket != 0);
+ socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
+ socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
+ socket->Connect (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
+ socket->SetAttribute ("IpTtl", UintegerValue (1));
+ m_socketAddresses.insert (std::make_pair (socket, iface));
+
+ // Add local broadcast record to the routing table
+ Ptr 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