Support dynamic routing and multiple routing protocols; static routing table is refactored as a "routing protocol".
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Thu, 26 Jul 2007 12:26:21 +0100
changeset 1714 9623867334c3
parent 1713 8f6d839d743b
child 1715 b51c9c412844
Support dynamic routing and multiple routing protocols; static routing table is refactored as a "routing protocol". Support sending IP broadcast (255.255.255.255) packets (bug #36).
src/internet-node/ipv4-impl.cc
src/internet-node/ipv4-impl.h
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/internet-node/ipv4-static-routing.cc
src/internet-node/ipv4-static-routing.h
src/internet-node/wscript
src/node/ipv4.h
--- a/src/internet-node/ipv4-impl.cc	Thu Jul 26 12:12:51 2007 +0100
+++ b/src/internet-node/ipv4-impl.cc	Thu Jul 26 12:26:21 2007 +0100
@@ -39,6 +39,13 @@
   m_ipv4 = 0;
 }
 
+void
+Ipv4Impl::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                              int priority)
+{
+  m_ipv4->AddRoutingProtocol (routingProtocol, priority);
+}
+
 void 
 Ipv4Impl::AddHostRouteTo (Ipv4Address dest, 
 			   Ipv4Address nextHop, 
--- a/src/internet-node/ipv4-impl.h	Thu Jul 26 12:12:51 2007 +0100
+++ b/src/internet-node/ipv4-impl.h	Thu Jul 26 12:26:21 2007 +0100
@@ -35,6 +35,9 @@
 
   virtual ~Ipv4Impl ();
 
+  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                                   int priority);
+
   virtual void AddHostRouteTo (Ipv4Address dest, 
 			       Ipv4Address nextHop, 
 			       uint32_t interface);
--- a/src/internet-node/ipv4-l3-protocol.cc	Thu Jul 26 12:12:51 2007 +0100
+++ b/src/internet-node/ipv4-l3-protocol.cc	Thu Jul 26 12:26:21 2007 +0100
@@ -48,9 +48,10 @@
     m_nInterfaces (0),
     m_defaultTtl (64),
     m_identification (0),
-    m_defaultRoute (0),
     m_node (node)
 {
+  m_staticRouting = Create<Ipv4StaticRouting> ();
+  AddRoutingProtocol (m_staticRouting, 0);
   SetupLoopback ();
 }
 Ipv4L3Protocol::~Ipv4L3Protocol ()
@@ -64,25 +65,10 @@
       delete (*i);
     }
   m_interfaces.clear ();
-  for (HostRoutesI i = m_hostRoutes.begin (); 
-       i != m_hostRoutes.end (); 
-       i = m_hostRoutes.erase (i)) 
-    {
-      delete (*i);
-    }
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j = m_networkRoutes.erase (j)) 
-    {
-      delete (*j);
-    }
-  if (m_defaultRoute != 0)
-    {
-      delete m_defaultRoute;
-      m_defaultRoute = 0;
-    }
   m_node = 0;
   L3Protocol::DoDispose ();
+  m_staticRouting->Dispose ();
+  m_staticRouting = 0;
 }
 
 void
@@ -132,17 +118,13 @@
                       Ipv4Address nextHop, 
                       uint32_t interface)
 {
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
-  m_hostRoutes.push_back (route);
+  m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
 }
 void 
 Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
 				uint32_t interface)
 {
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateHostRouteTo (dest, interface);
-  m_hostRoutes.push_back (route);
+  m_staticRouting->AddHostRouteTo (dest, interface);
 }
 void 
 Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
@@ -150,163 +132,63 @@
 				   Ipv4Address nextHop, 
 				   uint32_t interface)
 {
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            nextHop,
-                                            interface);
-  m_networkRoutes.push_back (route);
+  m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
 }
 void 
 Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
 				   Ipv4Mask networkMask, 
 				   uint32_t interface)
 {
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            interface);
-  m_networkRoutes.push_back (route);
+  m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
 }
 void 
 Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, 
 				 uint32_t interface)
 {
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
-  delete m_defaultRoute;
-  m_defaultRoute = route;
+  m_staticRouting->SetDefaultRoute (nextHop, interface);
 }
 
-Ipv4Route *
-Ipv4L3Protocol::Lookup (Ipv4Address dest)
+
+void
+Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
+                        Packet packet,
+                        Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
-  for (HostRoutesCI i = m_hostRoutes.begin (); 
-       i != m_hostRoutes.end (); 
-       i++) 
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++)
     {
-      NS_ASSERT ((*i)->IsHost ());
-      if ((*i)->GetDest ().IsEqual (dest)) 
-        {
-          return (*i);
-        }
+      if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply))
+        return;
     }
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      NS_ASSERT ((*j)->IsNetwork ());
-      Ipv4Mask mask = (*j)->GetDestNetworkMask ();
-      Ipv4Address entry = (*j)->GetDestNetwork ();
-      if (mask.IsMatch (dest, entry)) 
-        {
-          return (*j);
-        }
-    }
-  if (m_defaultRoute != 0) 
-    {
-      NS_ASSERT (m_defaultRoute->IsDefault ());
-      return m_defaultRoute;
-    }
-  return 0;
+  // No route found
+  routeReply (false, Ipv4Route (), packet, ipHeader);
+}
+
+void
+Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                                    int priority)
+{
+  m_routingProtocols.push_back
+    (std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
+  m_routingProtocols.sort ();
 }
 
 uint32_t 
 Ipv4L3Protocol::GetNRoutes (void)
 {
-  uint32_t n = 0;
-  if (m_defaultRoute != 0)
-    {
-      n++;
-    }
-  n += m_hostRoutes.size ();
-  n += m_networkRoutes.size ();
-  return n;
+  return m_staticRouting->GetNRoutes ();
 }
+
 Ipv4Route *
 Ipv4L3Protocol::GetRoute (uint32_t index)
 {
-  if (index == 0 && m_defaultRoute != 0)
-    {
-      return m_defaultRoute;
-    }
-  if (index > 0 && m_defaultRoute != 0)
-    {
-      index--;
-    }
-  if (index < m_hostRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (HostRoutesCI i = m_hostRoutes.begin (); 
-           i != m_hostRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              return *i;
-            }
-          tmp++;
-        }
-    }
-  index -= m_hostRoutes.size ();
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          return *j;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
+  return m_staticRouting->GetRoute (index);
 }
+
 void 
 Ipv4L3Protocol::RemoveRoute (uint32_t index)
 {
-  if (index == 0 && m_defaultRoute != 0)
-    {
-      delete m_defaultRoute;
-      m_defaultRoute = 0;
-    }
-  if (index > 0 && m_defaultRoute != 0)
-    {
-      index--;
-    }
-  if (index < m_hostRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (HostRoutesI i = m_hostRoutes.begin (); 
-           i != m_hostRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              delete *i;
-              m_hostRoutes.erase (i);
-              return;
-            }
-          tmp++;
-        }
-    }
-  index -= m_hostRoutes.size ();
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          delete *j;
-          m_networkRoutes.erase (j);
-          return;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
+  m_staticRouting->RemoveRoute (index);
 }
 
 
@@ -386,6 +268,7 @@
   ForwardUp (packet, ipHeader);
 }
 
+
 void 
 Ipv4L3Protocol::Send (Packet const &packet, 
             Ipv4Address source, 
@@ -404,30 +287,49 @@
 
   m_identification ++;
 
-  // XXX Note here that in most ipv4 stacks in the world,
-  // the route calculation for an outgoing packet is not
-  // done in the ip layer. It is done within the application
-  // socket when the first packet is sent to avoid this
-  // costly lookup on a per-packet basis.
-  // That would require us to get the route from the packet,
-  // most likely with a packet tag. The higher layers do not
-  // do this yet for us.
-  Ipv4Route *route = Lookup (ipHeader.GetDestination ());
-  if (route == 0) 
+  if (destination.IsBroadcast ())
+    {
+      uint32_t ifaceIndex = 0;
+      for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
+           ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
+        {
+          Ipv4Interface *outInterface = *ifaceIter;
+          Packet packetCopy = packet;
+
+          NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
+          packetCopy.AddHeader (ipHeader);
+          m_txTrace (packetCopy, ifaceIndex);
+          outInterface->Send (packetCopy, destination);
+        }
+    }
+  else
     {
-      NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
+      // XXX Note here that in most ipv4 stacks in the world,
+      // the route calculation for an outgoing packet is not
+      // done in the ip layer. It is done within the application
+      // socket when the first packet is sent to avoid this
+      // costly lookup on a per-packet basis.
+      // That would require us to get the route from the packet,
+      // most likely with a packet tag. The higher layers do not
+      // do this yet for us.
+      Lookup (ipHeader, packet,
+              MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
+    }
+}
+
+void
+Ipv4L3Protocol::SendRealOut (bool found,
+                             Ipv4Route const &route,
+                             Packet packet,
+                             Ipv4Header const &ipHeader)
+{
+  if (!found)
+    {
+      NS_DEBUG ("no route to host. drop.");
       m_dropTrace (packet);
       return;
     }
-
-  SendRealOut (packet, ipHeader, *route);
-}
-
-void
-Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route)
-{
-  Packet packet = p;
-  packet.AddHeader (ip);
+  packet.AddHeader (ipHeader);
   Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
   NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
   m_txTrace (packet, route.GetInterface ());
@@ -437,7 +339,7 @@
     } 
   else 
     {
-      outInterface->Send (packet, ip.GetDestination ());
+      outInterface->Send (packet, ipHeader.GetDestination ());
     }
 }
 
@@ -470,7 +372,7 @@
 	}
     }
       
-  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetBroadcast ())) 
+  if (ipHeader.GetDestination ().IsBroadcast ()) 
     {
       NS_DEBUG ("for me 3");
       return false;
@@ -489,15 +391,10 @@
       return true;
     }
   ipHeader.SetTtl (ipHeader.GetTtl () - 1);
-  Ipv4Route *route = Lookup (ipHeader.GetDestination ());
-  if (route == 0) 
-    {
-      NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
-      m_dropTrace (packet);
-      return true;
-    }
+
   NS_DEBUG ("not for me -- forwarding.");
-  SendRealOut (packet, ipHeader, *route);
+  Lookup (ipHeader, packet,
+          MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
   return true;
 }
 
--- a/src/internet-node/ipv4-l3-protocol.h	Thu Jul 26 12:12:51 2007 +0100
+++ b/src/internet-node/ipv4-l3-protocol.h	Thu Jul 26 12:26:21 2007 +0100
@@ -27,8 +27,11 @@
 #include "ns3/callback-trace-source.h"
 #include "ns3/array-trace-resolver.h"
 #include "ns3/ipv4-address.h"
+#include "ipv4-header.h"
 #include "ns3/ptr.h"
+#include "ns3/ipv4.h"
 #include "l3-protocol.h"
+#include "ipv4-static-routing.h"
 
 namespace ns3 {
 
@@ -124,7 +127,10 @@
   void SetDefaultRoute (Ipv4Address nextHop, 
                         uint32_t interface);
 
-  Ipv4Route *Lookup (Ipv4Address dest);
+  void Lookup (Ipv4Header const &ipHeader,
+               Packet packet,
+               Ipv4RoutingProtocol::RouteReplyCallback routeReply);
+
   uint32_t GetNRoutes (void);
   Ipv4Route *GetRoute (uint32_t i);
   void RemoveRoute (uint32_t i);
@@ -143,11 +149,19 @@
   void SetUp (uint32_t i);
   void SetDown (uint32_t i);
 
+  void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                           int priority);
 
 protected:
+
   virtual void DoDispose (void);
+
 private:
-  void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
+
+  void SendRealOut (bool found,
+                    Ipv4Route const &route,
+                    Packet packet,
+                    Ipv4Header const &ipHeader);
   bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
   void ForwardUp (Packet p, Ipv4Header const&ip);
   uint32_t AddIpv4Interface (Ipv4Interface *interface);
@@ -155,26 +169,22 @@
   TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
 
   typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
-  typedef std::list<Ipv4Route *> HostRoutes;
-  typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
-  typedef std::list<Ipv4Route *>::iterator HostRoutesI;
-  typedef std::list<Ipv4Route *> NetworkRoutes;
-  typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
-  typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
+  typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
 
   Ipv4InterfaceList m_interfaces;
   uint32_t m_nInterfaces;
   uint8_t m_defaultTtl;
   uint16_t m_identification;
-  HostRoutes m_hostRoutes;
-  NetworkRoutes m_networkRoutes;
-  Ipv4Route *m_defaultRoute;
   Ptr<Node> m_node;
   CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
   CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
   CallbackTraceSource<Packet const &> m_dropTrace;
+
+  Ipv4RoutingProtocolList m_routingProtocols;
+
+  Ptr<Ipv4StaticRouting> m_staticRouting;
 };
 
 } // Namespace ns3
 
-#endif /* IPV$_L3_PROTOCOL_H */
+#endif /* IPV4_L3_PROTOCOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-static-routing.cc	Thu Jul 26 12:26:21 2007 +0100
@@ -0,0 +1,253 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// All rights reserved.
+//
+// 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
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//         Gustavo Carneiro <gjc@inescporto.pt>
+
+#include "ipv4-static-routing.h"
+#include "ns3/packet.h"
+
+
+namespace ns3 {
+
+
+void 
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
+                                   Ipv4Address nextHop, 
+                                   uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
+  m_hostRoutes.push_back (route);
+}
+void 
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
+                                   uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateHostRouteTo (dest, interface);
+  m_hostRoutes.push_back (route);
+}
+void 
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      Ipv4Address nextHop, 
+                                      uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            nextHop,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+void 
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+void 
+Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
+                                    uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
+  delete m_defaultRoute;
+  m_defaultRoute = route;
+}
+
+Ipv4Route *
+Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
+{
+  for (HostRoutesCI i = m_hostRoutes.begin (); 
+       i != m_hostRoutes.end (); 
+       i++) 
+    {
+      NS_ASSERT ((*i)->IsHost ());
+      if ((*i)->GetDest ().IsEqual (dest)) 
+        {
+          return (*i);
+        }
+    }
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      NS_ASSERT ((*j)->IsNetwork ());
+      Ipv4Mask mask = (*j)->GetDestNetworkMask ();
+      Ipv4Address entry = (*j)->GetDestNetwork ();
+      if (mask.IsMatch (dest, entry)) 
+        {
+          return (*j);
+        }
+    }
+  if (m_defaultRoute != 0) 
+    {
+      NS_ASSERT (m_defaultRoute->IsDefault ());
+      return m_defaultRoute;
+    }
+  return 0;
+}
+
+uint32_t 
+Ipv4StaticRouting::GetNRoutes (void)
+{
+  uint32_t n = 0;
+  if (m_defaultRoute != 0)
+    {
+      n++;
+    }
+  n += m_hostRoutes.size ();
+  n += m_networkRoutes.size ();
+  return n;
+}
+Ipv4Route *
+Ipv4StaticRouting::GetRoute (uint32_t index)
+{
+  if (index == 0 && m_defaultRoute != 0)
+    {
+      return m_defaultRoute;
+    }
+  if (index > 0 && m_defaultRoute != 0)
+    {
+      index--;
+    }
+  if (index < m_hostRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (HostRoutesCI i = m_hostRoutes.begin (); 
+           i != m_hostRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          tmp++;
+        }
+    }
+  index -= m_hostRoutes.size ();
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          return *j;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+void 
+Ipv4StaticRouting::RemoveRoute (uint32_t index)
+{
+  if (index == 0 && m_defaultRoute != 0)
+    {
+      delete m_defaultRoute;
+      m_defaultRoute = 0;
+    }
+  if (index > 0 && m_defaultRoute != 0)
+    {
+      index--;
+    }
+  if (index < m_hostRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (HostRoutesI i = m_hostRoutes.begin (); 
+           i != m_hostRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              delete *i;
+              m_hostRoutes.erase (i);
+              return;
+            }
+          tmp++;
+        }
+    }
+  index -= m_hostRoutes.size ();
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          delete *j;
+          m_networkRoutes.erase (j);
+          return;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+}
+
+bool
+Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
+                                 Packet packet,
+                                 RouteReplyCallback routeReply)
+{
+  Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
+  if (route != 0)
+    {
+      routeReply (true, *route, packet, ipHeader);
+      return true;
+    }
+  else
+    {
+      return false; // Let other routing protocols try to handle this
+                    // route request.
+    }
+}
+
+void
+Ipv4StaticRouting::DoDispose (void)
+{
+  for (HostRoutesI i = m_hostRoutes.begin (); 
+       i != m_hostRoutes.end (); 
+       i = m_hostRoutes.erase (i)) 
+    {
+      delete (*i);
+    }
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j = m_networkRoutes.erase (j)) 
+    {
+      delete (*j);
+    }
+  if (m_defaultRoute != 0)
+    {
+      delete m_defaultRoute;
+      m_defaultRoute = 0;
+    }
+  Ipv4RoutingProtocol::DoDispose ();
+}
+
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-static-routing.h	Thu Jul 26 12:26:21 2007 +0100
@@ -0,0 +1,101 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// All rights reserved.
+//
+// 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
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//         Gustavo Carneiro <gjc@inescporto.pt>
+//
+
+#ifndef IPV4_STATIC_ROUTING_H
+#define IPV4_STATIC_ROUTING_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/callback-trace-source.h"
+#include "ns3/array-trace-resolver.h"
+#include "ns3/ipv4-address.h"
+#include "ipv4-header.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "l3-protocol.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4Route;
+class Node;
+class TraceResolver;
+class TraceContext;
+
+
+class Ipv4StaticRouting : public Ipv4RoutingProtocol
+{
+
+public:
+  Ipv4StaticRouting () : m_defaultRoute (0) {}
+
+  virtual bool RequestRoute (Ipv4Header const &ipHeader,
+                             Packet packet,
+                             RouteReplyCallback routeReply);
+
+
+  void AddHostRouteTo (Ipv4Address dest, 
+                       Ipv4Address nextHop, 
+                       uint32_t interface);
+  void AddHostRouteTo (Ipv4Address dest, 
+                       uint32_t interface);
+
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          Ipv4Address nextHop, 
+                          uint32_t interface);
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          uint32_t interface);
+  void SetDefaultRoute (Ipv4Address nextHop, 
+                        uint32_t interface);
+  uint32_t GetNRoutes (void);
+  Ipv4Route *GetRoute (uint32_t i);
+  void RemoveRoute (uint32_t i);
+
+protected:
+  void DoDispose (void);
+
+private:
+  typedef std::list<Ipv4Route *> HostRoutes;
+  typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
+  typedef std::list<Ipv4Route *>::iterator HostRoutesI;
+  typedef std::list<Ipv4Route *> NetworkRoutes;
+  typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
+  typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
+
+  Ipv4Route *LookupStatic (Ipv4Address dest);
+
+  HostRoutes m_hostRoutes;
+  NetworkRoutes m_networkRoutes;
+  Ipv4Route *m_defaultRoute;
+};
+
+
+
+} // Namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_H */
--- a/src/internet-node/wscript	Thu Jul 26 12:12:51 2007 +0100
+++ b/src/internet-node/wscript	Thu Jul 26 12:26:21 2007 +0100
@@ -17,6 +17,7 @@
         'ipv4-checksum.cc',
         'ipv4-interface.cc',
         'ipv4-l3-protocol.cc',
+        'ipv4-static-routing.cc',
         'ipv4-end-point.cc',
         'udp-l4-protocol.cc',
         'arp-header.cc',
@@ -41,4 +42,5 @@
         'internet-node.h',
         'ascii-trace.h',
         'pcap-trace.h',
+        'ipv4-header.h',
         ]
--- a/src/node/ipv4.h	Thu Jul 26 12:12:51 2007 +0100
+++ b/src/node/ipv4.h	Thu Jul 26 12:26:21 2007 +0100
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include "ns3/ipv4-address.h"
 #include "ns3/object.h"
+#include "ns3/callback.h"
 #include "ipv4-route.h"
 
 namespace ns3 {
@@ -31,6 +32,30 @@
 class NetDevice;
 class Packet;
 class Ipv4Route;
+class Ipv4Header; // FIXME: ipv4-header.h needs to move from module
+                  // "internet-node" to module "node"
+
+class Ipv4RoutingProtocol : public Object
+{
+public:
+  // void (*RouteReply) (bool found, Ipv4Route route, Packet packet, Ipv4Header const &ipHeader);
+  typedef Callback<void, bool, Ipv4Route const&, Packet, Ipv4Header const &> RouteReplyCallback;
+
+  /**
+   * \brief Asynchronously requests a route for a given packet and IP header 
+   *
+   * \param ipHeader IP header of the packet
+   * \param packet packet that is being sent or forwarded
+   * \param routeReply callback that will receive the route reply
+   *
+   * \returns true if the routing protocol should be able to get the
+   * route, false otherwise.
+   */
+  virtual bool RequestRoute (Ipv4Header const &ipHeader,
+                             Packet packet,
+                             RouteReplyCallback routeReply) = 0;
+};
+
 /**
  * \brief Access to the Ipv4 forwarding table and to the ipv4 interfaces
  *
@@ -47,7 +72,10 @@
   static const InterfaceId iid;
   Ipv4 ();
   virtual ~Ipv4 ();
-    
+
+  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                                   int priority) = 0;
+  
   /**
    * \param dest destination address
    * \param nextHop address of next hop.