Module layout rework for static-routing, list-routing, global-routing
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Tue, 26 Oct 2010 18:02:17 +0100
changeset 6648 d1785ce489c5
parent 6647 bdbbfbc6bda7
child 6649 f5413d463948
Module layout rework for static-routing, list-routing, global-routing
examples/csma/csma-multicast.cc
examples/emulation/emu-ping.cc
examples/ipv6/fragmentation-ipv6.cc
examples/ipv6/icmpv6-redirect.cc
examples/ipv6/radvd-two-prefix.cc
examples/routing/global-injection-slash32.cc
examples/routing/nix-simple.cc
examples/routing/nms-p2p-nix.cc
examples/routing/simple-routing-ping6.cc
examples/routing/static-routing-slash32.cc
examples/socket/socket-bound-static-routing.cc
examples/socket/socket-bound-tcp-static-routing.cc
examples/topology-read/topology-example-sim.cc
examples/wimax/wimax-multicast.cc
examples/wireless/multirate.cc
examples/wireless/wifi-simple-adhoc-grid.cc
src/helper/internet-stack-helper.cc
src/helper/ipv4-global-routing-helper.cc
src/helper/ipv4-global-routing-helper.h
src/helper/ipv4-list-routing-helper.cc
src/helper/ipv4-list-routing-helper.h
src/helper/ipv4-static-routing-helper.cc
src/helper/ipv4-static-routing-helper.h
src/helper/ipv6-interface-container.cc
src/helper/ipv6-list-routing-helper.cc
src/helper/ipv6-list-routing-helper.h
src/helper/ipv6-static-routing-helper.cc
src/helper/ipv6-static-routing-helper.h
src/helper/wscript
src/routing/global-routing/candidate-queue.cc
src/routing/global-routing/candidate-queue.h
src/routing/global-routing/global-route-manager-impl.cc
src/routing/global-routing/global-route-manager-impl.h
src/routing/global-routing/global-route-manager.cc
src/routing/global-routing/global-route-manager.h
src/routing/global-routing/global-router-interface.cc
src/routing/global-routing/global-router-interface.h
src/routing/global-routing/global-routing.h
src/routing/global-routing/helper/ipv4-global-routing-helper.cc
src/routing/global-routing/helper/ipv4-global-routing-helper.h
src/routing/global-routing/ipv4-global-routing.cc
src/routing/global-routing/ipv4-global-routing.h
src/routing/global-routing/model/candidate-queue.cc
src/routing/global-routing/model/candidate-queue.h
src/routing/global-routing/model/global-route-manager-impl.cc
src/routing/global-routing/model/global-route-manager-impl.h
src/routing/global-routing/model/global-route-manager.cc
src/routing/global-routing/model/global-route-manager.h
src/routing/global-routing/model/global-router-interface.cc
src/routing/global-routing/model/global-router-interface.h
src/routing/global-routing/model/global-routing.h
src/routing/global-routing/model/ipv4-global-routing.cc
src/routing/global-routing/model/ipv4-global-routing.h
src/routing/global-routing/wscript
src/routing/list-routing/helper/ipv4-list-routing-helper.cc
src/routing/list-routing/helper/ipv4-list-routing-helper.h
src/routing/list-routing/helper/ipv6-list-routing-helper.cc
src/routing/list-routing/helper/ipv6-list-routing-helper.h
src/routing/list-routing/ipv4-list-routing.cc
src/routing/list-routing/ipv4-list-routing.h
src/routing/list-routing/ipv6-list-routing.cc
src/routing/list-routing/ipv6-list-routing.h
src/routing/list-routing/model/ipv4-list-routing.cc
src/routing/list-routing/model/ipv4-list-routing.h
src/routing/list-routing/model/ipv6-list-routing.cc
src/routing/list-routing/model/ipv6-list-routing.h
src/routing/list-routing/wscript
src/routing/olsr/examples/olsr-hna.cc
src/routing/olsr/examples/simple-point-to-point-olsr.cc
src/routing/static-routing/helper/ipv4-static-routing-helper.cc
src/routing/static-routing/helper/ipv4-static-routing-helper.h
src/routing/static-routing/helper/ipv6-static-routing-helper.cc
src/routing/static-routing/helper/ipv6-static-routing-helper.h
src/routing/static-routing/ipv4-routing-table-entry.cc
src/routing/static-routing/ipv4-routing-table-entry.h
src/routing/static-routing/ipv4-static-routing.cc
src/routing/static-routing/ipv4-static-routing.h
src/routing/static-routing/ipv6-routing-table-entry.cc
src/routing/static-routing/ipv6-routing-table-entry.h
src/routing/static-routing/ipv6-static-routing.cc
src/routing/static-routing/ipv6-static-routing.h
src/routing/static-routing/model/ipv4-routing-table-entry.cc
src/routing/static-routing/model/ipv4-routing-table-entry.h
src/routing/static-routing/model/ipv4-static-routing.cc
src/routing/static-routing/model/ipv4-static-routing.h
src/routing/static-routing/model/ipv6-routing-table-entry.cc
src/routing/static-routing/model/ipv6-routing-table-entry.h
src/routing/static-routing/model/ipv6-static-routing.cc
src/routing/static-routing/model/ipv6-static-routing.h
src/routing/static-routing/wscript
--- a/examples/csma/csma-multicast.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/csma/csma-multicast.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -36,6 +36,8 @@
 #include "ns3/simulator-module.h"
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace ns3;
 
--- a/examples/emulation/emu-ping.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/emulation/emu-ping.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -58,6 +58,8 @@
 #include "ns3/emu-module.h"
 #include "ns3/v4ping-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace ns3;
 
--- a/examples/ipv6/fragmentation-ipv6.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/ipv6/fragmentation-ipv6.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -32,6 +32,7 @@
 #include "ns3/core-module.h"
 #include "ns3/simulator-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv6-static-routing-helper.h"
 
 #include "ns3/ipv6-routing-table-entry.h"
 
--- a/examples/ipv6/icmpv6-redirect.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/ipv6/icmpv6-redirect.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -44,6 +44,7 @@
 #include "ns3/core-module.h"
 #include "ns3/simulator-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv6-static-routing-helper.h"
 
 #include "ns3/ipv6-routing-table-entry.h"
 
--- a/examples/ipv6/radvd-two-prefix.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/ipv6/radvd-two-prefix.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -41,6 +41,7 @@
 #include "ns3/radvd.h"
 #include "ns3/radvd-interface.h"
 #include "ns3/radvd-prefix.h"
+#include "ns3/ipv6-static-routing-helper.h"
 
 using namespace ns3;
 
--- a/examples/routing/global-injection-slash32.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/global-injection-slash32.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -34,6 +34,8 @@
 #include "ns3/ipv4-list-routing.h"
 #include "ns3/ipv4-routing-table-entry.h"
 #include "ns3/global-router-interface.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace ns3;
 using std::cout;
--- a/examples/routing/nix-simple.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/nix-simple.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -18,6 +18,8 @@
 #include "ns3/simulator-module.h"
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 /*
  *  Simple point to point links:
--- a/examples/routing/nms-p2p-nix.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/nms-p2p-nix.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -23,6 +23,8 @@
 #include "ns3/packet-sink.h"
 #include "ns3/point-to-point-net-device.h"
 #include "ns3/simulator.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace std;
 using namespace ns3;
--- a/examples/routing/simple-routing-ping6.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/simple-routing-ping6.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -32,6 +32,7 @@
 #include "ns3/core-module.h"
 #include "ns3/simulator-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv6-static-routing-helper.h"
 
 #include "ns3/ipv6-routing-table-entry.h"
 
--- a/examples/routing/static-routing-slash32.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/static-routing-slash32.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -29,6 +29,7 @@
 #include "ns3/simulator-module.h"
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
 
 using namespace ns3;
 
--- a/examples/socket/socket-bound-static-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/socket/socket-bound-static-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -39,6 +39,8 @@
 #include "ns3/simulator-module.h"
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace ns3;
 
--- a/examples/socket/socket-bound-tcp-static-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/socket/socket-bound-tcp-static-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -39,6 +39,8 @@
 #include "ns3/simulator-module.h"
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace ns3;
 
--- a/examples/topology-read/topology-example-sim.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/topology-read/topology-example-sim.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -31,6 +31,8 @@
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
 #include "ns3/simulator-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 #include "ns3/topology-read-module.h"
 #include <list>
--- a/examples/wimax/wimax-multicast.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/wimax/wimax-multicast.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -61,6 +61,8 @@
 #include "ns3/global-route-manager.h"
 #include "ns3/constant-position-mobility-model.h"
 #include "ns3/random-waypoint-mobility-model.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 #include "ns3/vector.h"
 
--- a/examples/wireless/multirate.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/wireless/multirate.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -58,6 +58,8 @@
 #include "ns3/wifi-module.h"
 #include "ns3/flow-monitor-helper.h"
 #include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 #include <iostream>
 #include <fstream>
--- a/examples/wireless/wifi-simple-adhoc-grid.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/wireless/wifi-simple-adhoc-grid.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -77,6 +77,8 @@
 #include "ns3/contrib-module.h"
 #include "ns3/wifi-module.h"
 #include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 #include <iostream>
 #include <fstream>
--- a/src/helper/internet-stack-helper.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/helper/internet-stack-helper.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -164,11 +164,11 @@
 #include "ns3/core-config.h"
 #include "ns3/arp-l3-protocol.h"
 #include "internet-stack-helper.h"
-#include "ipv4-list-routing-helper.h"
-#include "ipv4-static-routing-helper.h"
-#include "ipv4-global-routing-helper.h"
-#include "ipv6-list-routing-helper.h"
-#include "ipv6-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/ipv6-list-routing-helper.h"
+#include "ns3/ipv6-static-routing-helper.h"
 #include "trace-helper.h"
 #include <limits>
 #include <map>
--- a/src/helper/ipv4-global-routing-helper.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ipv4-global-routing-helper.h"
-#include "ns3/global-router-interface.h"
-#include "ns3/ipv4-global-routing.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/log.h"
-
-NS_LOG_COMPONENT_DEFINE("GlobalRoutingHelper");
-
-namespace ns3 {
-
-Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper ()
-{}
-
-Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &o)
-{
-}
-
-Ipv4GlobalRoutingHelper* 
-Ipv4GlobalRoutingHelper::Copy (void) const 
-{
-  return new Ipv4GlobalRoutingHelper (*this); 
-}
-
-Ptr<Ipv4RoutingProtocol> 
-Ipv4GlobalRoutingHelper::Create (Ptr<Node> node) const
-{
-  NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << 
-		node->GetId ());
-
-  Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
-  node->AggregateObject (globalRouter);
-
-  NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
-  Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
-  globalRouter->SetRoutingProtocol (globalRouting);
-
-  return globalRouting;
-}
-
-void 
-Ipv4GlobalRoutingHelper::PopulateRoutingTables (void)
-{
-  GlobalRouteManager::BuildGlobalRoutingDatabase ();
-  GlobalRouteManager::InitializeRoutes ();
-}
-void 
-Ipv4GlobalRoutingHelper::RecomputeRoutingTables (void)
-{
-  GlobalRouteManager::DeleteGlobalRoutes ();
-  GlobalRouteManager::BuildGlobalRoutingDatabase ();
-  GlobalRouteManager::InitializeRoutes ();
-}
-
-
-} // namespace ns3
--- a/src/helper/ipv4-global-routing-helper.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_GLOBAL_ROUTING_HELPER_H
-#define IPV4_GLOBAL_ROUTING_HELPER_H
-
-#include "node-container.h"
-#include "ipv4-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv4GlobalRouting objects
- */
-class Ipv4GlobalRoutingHelper  : public Ipv4RoutingHelper
-{
-public:
-  /**
-   * \brief Construct a GlobalRoutingHelper to make life easier for managing
-   * global routing tasks.
-   */
-  Ipv4GlobalRoutingHelper ();
-
-  /**
-   * \brief Construct a GlobalRoutingHelper from another previously initialized
-   * instance (Copy Constructor).
-   */
-  Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &);
-
-  /**
-   * \internal
-   * \returns pointer to clone of this Ipv4GlobalRoutingHelper
-   *
-   * This method is mainly for internal use by the other helpers;
-   * clients are expected to free the dynamic memory allocated by this method
-   */
-  Ipv4GlobalRoutingHelper* Copy (void) const;
-
-  /**
-   * \param node the node on which the routing protocol will run
-   * \returns a newly-created routing protocol
-   *
-   * This method will be called by ns3::InternetStackHelper::Install
-   */
-  virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-
-  /**
-   * \brief Build a routing database and initialize the routing tables of
-   * the nodes in the simulation.  Makes all nodes in the simulation into
-   * routers.
-   *
-   * All this function does is call the functions
-   * BuildGlobalRoutingDatabase () and  InitializeRoutes ().
-   *
-   */
-  static void PopulateRoutingTables (void);
-  /**
-   * \brief Remove all routes that were previously installed in a prior call
-   * to either PopulateRoutingTables() or RecomputeRoutingTables(), and 
-   * add a new set of routes.  
-   * 
-   * This method does not change the set of nodes
-   * over which GlobalRouting is being used, but it will dynamically update
-   * its representation of the global topology before recomputing routes.
-   * Users must first call PopulateRoutingTables() and then may subsequently
-   * call RecomputeRoutingTables() at any later time in the simulation.
-   *
-   */
-  static void RecomputeRoutingTables (void);
-private:
-  /**
-   * \internal
-   * \brief Assignment operator declared private and not implemented to disallow
-   * assignment and prevent the compiler from happily inserting its own.
-   */
-  Ipv4GlobalRoutingHelper &operator = (const Ipv4GlobalRoutingHelper &o);
-};
-
-} // namespace ns3
-
-#endif /* IPV4_GLOBAL_ROUTING_HELPER_H */
--- a/src/helper/ipv4-list-routing-helper.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ipv4-list-routing-helper.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/node.h"
-
-namespace ns3 {
-
-Ipv4ListRoutingHelper::Ipv4ListRoutingHelper()
-{}
-
-Ipv4ListRoutingHelper::~Ipv4ListRoutingHelper()
-{
-  for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
-       i != m_list.end (); ++i)
-    {
-      delete i->first;
-    }
-}
-
-Ipv4ListRoutingHelper::Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &o)
-{
-  std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i;
-  for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
-    {
-      m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (i->first->Copy ()), i->second));
-    }
-}
-
-Ipv4ListRoutingHelper* 
-Ipv4ListRoutingHelper::Copy (void) const 
-{
-  return new Ipv4ListRoutingHelper (*this); 
-}
-
-void 
-Ipv4ListRoutingHelper::Add (const Ipv4RoutingHelper &routing, int16_t priority)
-{
-  m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (routing.Copy ()), priority));
-}
-
-Ptr<Ipv4RoutingProtocol> 
-Ipv4ListRoutingHelper::Create (Ptr<Node> node) const
-{
-  Ptr<Ipv4ListRouting> list = CreateObject<Ipv4ListRouting> ();
-  for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i = m_list.begin ();
-       i != m_list.end (); ++i)
-    {
-      Ptr<Ipv4RoutingProtocol> prot = i->first->Create (node);
-      list->AddRoutingProtocol (prot,i->second);
-    }
-  return list;
-}
-
-} // namespace ns3
--- a/src/helper/ipv4-list-routing-helper.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_LIST_ROUTING_HELPER_H
-#define IPV4_LIST_ROUTING_HELPER_H
-
-#include "ipv4-routing-helper.h"
-#include <stdint.h>
-#include <list>
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv4ListRouting objects
- *
- * This class is expected to be used in conjunction with 
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
-{
-public:
-  /*
-   * Construct an Ipv4ListRoutingHelper used to make installing routing
-   * protocols easier.
-   */
-  Ipv4ListRoutingHelper ();
-
-  /*
-   * \internal
-   * Destroy an Ipv4ListRoutingHelper.
-   */
-  virtual ~Ipv4ListRoutingHelper ();
-
-  /**
-   * \brief Construct an Ipv4ListRoutingHelper from another previously 
-   * initialized instance (Copy Constructor).
-   */
-  Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &);
-
-  /**
-   * \internal
-   * \returns pointer to clone of this Ipv4ListRoutingHelper 
-   * 
-   * This method is mainly for internal use by the other helpers;
-   * clients are expected to free the dynamic memory allocated by this method
-   */
-  Ipv4ListRoutingHelper* Copy (void) const;
-
-  /**
-   * \param routing a routing helper
-   * \param priority the priority of the associated helper
-   *
-   * Store in the internal list a reference to the input routing helper
-   * and associated priority. These helpers will be used later by
-   * the ns3::Ipv4ListRoutingHelper::Create method to create
-   * an ns3::Ipv4ListRouting object and add in it routing protocols
-   * created with the helpers.
-   */
-  void Add (const Ipv4RoutingHelper &routing, int16_t priority);
-  /**
-   * \param node the node on which the routing protocol will run
-   * \returns a newly-created routing protocol
-   *
-   * This method will be called by ns3::InternetStackHelper::Install
-   */
-  virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-private:
-  /**
-   * \internal
-   * \brief Assignment operator declared private and not implemented to disallow
-   * assignment and prevent the compiler from happily inserting its own.
-   */
-  Ipv4ListRoutingHelper &operator = (const Ipv4ListRoutingHelper &o);
-
-  std::list<std::pair<const Ipv4RoutingHelper *,int16_t> > m_list;
-};
-
-} // namespace ns3
-
-#endif /* IPV4_LIST_ROUTING_HELPER_H */
--- a/src/helper/ipv4-static-routing-helper.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <vector>
-#include "ns3/log.h"
-#include "ns3/ptr.h"
-#include "ns3/names.h"
-#include "ns3/node.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/assert.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ipv4-static-routing-helper.h"
-
-NS_LOG_COMPONENT_DEFINE("Ipv4StaticRoutingHelper");
-
-namespace ns3 {
-
-Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper()
-{}
-
-Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &o)
-{
-}
-
-Ipv4StaticRoutingHelper* 
-Ipv4StaticRoutingHelper::Copy (void) const 
-{
-  return new Ipv4StaticRoutingHelper (*this); 
-}
-
-Ptr<Ipv4RoutingProtocol> 
-Ipv4StaticRoutingHelper::Create (Ptr<Node> node) const
-{
-  return CreateObject<Ipv4StaticRouting> ();
-}
-
-
-Ptr<Ipv4StaticRouting>
-Ipv4StaticRoutingHelper::GetStaticRouting (Ptr<Ipv4> ipv4) const
-{
-  NS_LOG_FUNCTION (this);
-  Ptr<Ipv4RoutingProtocol> ipv4rp = ipv4->GetRoutingProtocol ();
-  NS_ASSERT_MSG (ipv4rp, "No routing protocol associated with Ipv4");
-  if (DynamicCast<Ipv4StaticRouting> (ipv4rp))
-    {
-      NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
-      return DynamicCast<Ipv4StaticRouting> (ipv4rp); 
-    } 
-  if (DynamicCast<Ipv4ListRouting> (ipv4rp))
-    {
-      Ptr<Ipv4ListRouting> lrp = DynamicCast<Ipv4ListRouting> (ipv4rp);
-      int16_t priority;
-      for (uint32_t i = 0; i < lrp->GetNRoutingProtocols ();  i++)
-        {
-          NS_LOG_LOGIC ("Searching for static routing in list");
-          Ptr<Ipv4RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
-          if (DynamicCast<Ipv4StaticRouting> (temp))
-            {
-              NS_LOG_LOGIC ("Found static routing in list");
-              return DynamicCast<Ipv4StaticRouting> (temp);
-            }
-        }
-    }
-  NS_LOG_LOGIC ("Static routing not found");
-  return 0;
-}
-
-void  
-Ipv4StaticRoutingHelper::AddMulticastRoute (
-  Ptr<Node> n,
-  Ipv4Address source, 
-  Ipv4Address group,  
-  Ptr<NetDevice> input, 
-  NetDeviceContainer output)
-{
-  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
-
-  // We need to convert the NetDeviceContainer to an array of interface 
-  // numbers
-  std::vector<uint32_t> outputInterfaces;
-  for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
-    {
-      Ptr<NetDevice> nd = *i;
-      int32_t interface = ipv4->GetInterfaceForDevice (nd);
-      NS_ASSERT_MSG(interface >= 0, 
-        "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
-        "Expected an interface associated with the device nd");
-      outputInterfaces.push_back(interface);
-    }
-
-  int32_t inputInterface = ipv4->GetInterfaceForDevice (input);
-  NS_ASSERT_MSG(inputInterface >= 0, 
-    "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
-    "Expected an interface associated with the device input");
-  Ipv4StaticRoutingHelper helper;
-  Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
-  if (!ipv4StaticRouting)
-    {
-  NS_ASSERT_MSG (ipv4StaticRouting, 
-    "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
-    "Expected an Ipv4StaticRouting associated with this node");
-    }
-  ipv4StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
-}
-
-void  
-Ipv4StaticRoutingHelper::AddMulticastRoute (
-  Ptr<Node> n,
-  Ipv4Address source, 
-  Ipv4Address group,  
-  std::string inputName, 
-  NetDeviceContainer output)
-{
-  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
-  AddMulticastRoute (n, source, group, input, output);
-}
-
-void  
-Ipv4StaticRoutingHelper::AddMulticastRoute (
-  std::string nName,
-  Ipv4Address source, 
-  Ipv4Address group,  
-  Ptr<NetDevice> input, 
-  NetDeviceContainer output)
-{
-  Ptr<Node> n = Names::Find<Node> (nName);
-  AddMulticastRoute (n, source, group, input, output);
-}
-
-void  
-Ipv4StaticRoutingHelper::AddMulticastRoute (
-  std::string nName,
-  Ipv4Address source, 
-  Ipv4Address group,  
-  std::string inputName, 
-  NetDeviceContainer output)
-{
-  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
-  Ptr<Node> n = Names::Find<Node> (nName);
-  AddMulticastRoute (n, source, group, input, output);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
-  Ptr<Node> n, 
-  Ptr<NetDevice> nd)
-{
-  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
-  int32_t interfaceSrc = ipv4->GetInterfaceForDevice (nd);
-  NS_ASSERT_MSG(interfaceSrc >= 0, 
-    "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
-    "Expected an interface associated with the device");
-  Ipv4StaticRoutingHelper helper;
-  Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
-  if (!ipv4StaticRouting)
-    {
-      NS_ASSERT_MSG (ipv4StaticRouting, 
-        "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
-        "Expected an Ipv4StaticRouting associated with this node");
-    }
-  ipv4StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
-  Ptr<Node> n, 
-  std::string ndName)
-{
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
-  std::string nName, 
-  Ptr<NetDevice> nd)
-{
-  Ptr<Node> n = Names::Find<Node> (nName);
-  SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
-  std::string nName, 
-  std::string ndName)
-{
-  Ptr<Node> n = Names::Find<Node> (nName);
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  SetDefaultMulticastRoute (n, nd);
-}
-
-}; // namespace ns3
--- a/src/helper/ipv4-static-routing-helper.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * 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 IPV4_STATIC_ROUTING_HELPER_H
-#define IPV4_STATIC_ROUTING_HELPER_H
-
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-static-routing.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-#include "ipv4-routing-helper.h"
-#include "node-container.h"
-#include "net-device-container.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv4StaticRouting objects
- *
- * This class is expected to be used in conjunction with 
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv4StaticRoutingHelper : public Ipv4RoutingHelper
-{
-public:
-  /*
-   * Construct an Ipv4StaticRoutingHelper object, used to make configuration
-   * of static routing easier.
-   */
-  Ipv4StaticRoutingHelper ();
-
-  /**
-   * \brief Construct an Ipv4StaticRoutingHelper from another previously 
-   * initialized instance (Copy Constructor).
-   */
-  Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &);
-
-  /**
-   * \internal
-   * \returns pointer to clone of this Ipv4StaticRoutingHelper
-   *
-   * This method is mainly for internal use by the other helpers;
-   * clients are expected to free the dynamic memory allocated by this method
-   */
-  Ipv4StaticRoutingHelper* Copy (void) const;
-
-  /**
-   * \param node the node on which the routing protocol will run
-   * \returns a newly-created routing protocol
-   *
-   * This method will be called by ns3::InternetStackHelper::Install
-   */
-  virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-
-  /**
-   * Try and find the static routing protocol as either the main routing
-   * protocol or in the list of routing protocols associated with the 
-   * Ipv4 provided.
-   *
-   * \param ipv4 the Ptr<Ipv4> to search for the static routing protocol
-   */
-  Ptr<Ipv4StaticRouting> GetStaticRouting (Ptr<Ipv4> ipv4) const;
-
-  /**
-   * \brief Add a multicast route to a node and net device using explicit 
-   * Ptr<Node> and Ptr<NetDevice>
-   */
-  void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,  
-    Ptr<NetDevice> input, NetDeviceContainer output);
-
-  /**
-   * \brief Add a multicast route to a node and device using a name string 
-   * previously associated to the node using the Object Name Service and a
-   * Ptr<NetDevice>
-   */
-  void AddMulticastRoute (std::string n, Ipv4Address source, Ipv4Address group,  
-    Ptr<NetDevice> input, NetDeviceContainer output);
-
-  /**
-   * \brief Add a multicast route to a node and device using a Ptr<Node> and a 
-   * name string previously associated to the device using the Object Name Service.
-   */
-  void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,  
-    std::string inputName, NetDeviceContainer output);
-
-  /**
-   * \brief Add a multicast route to a node and device using name strings
-   * previously associated to both the node and device using the Object Name 
-   * Service.
-   */
-  void AddMulticastRoute (std::string nName, Ipv4Address source, Ipv4Address group,  
-    std::string inputName, NetDeviceContainer output);
-
-  /**
-   * \brief Add a default route to the static routing protocol to forward
-   *        packets out a particular interface
-   *
-   * Functionally equivalent to:
-   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
-   * \param n node
-   * \param nd device of the node to add default route
-   */
-  void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
-
-  /**
-   * \brief Add a default route to the static routing protocol to forward
-   *        packets out a particular interface
-   *
-   * Functionally equivalent to:
-   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
-   * \param n node
-   * \param ndName string with name previously associated to device using the 
-   *        Object Name Service
-   */
-  void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
-
-  /**
-   * \brief Add a default route to the static routing protocol to forward
-   *        packets out a particular interface
-   *
-   * Functionally equivalent to:
-   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
-   * \param nName string with name previously associated to node using the 
-   *        Object Name Service
-   * \param nd device of the node to add default route
-   */
-  void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
-
-  /**
-   * \brief Add a default route to the static routing protocol to forward
-   *        packets out a particular interface
-   *
-   * Functionally equivalent to:
-   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
-   * \param nName string with name previously associated to node using the 
-   *        Object Name Service
-   * \param ndName string with name previously associated to device using the 
-   *        Object Name Service
-   */
-  void SetDefaultMulticastRoute (std::string nName, std::string ndName);
-private:
-  /**
-   * \internal
-   * \brief Assignment operator declared private and not implemented to disallow
-   * assignment and prevent the compiler from happily inserting its own.
-   */
-  Ipv4StaticRoutingHelper &operator = (const Ipv4StaticRoutingHelper &o);
-};
-
-} // namespace ns3
-
-#endif /* IPV4_STATIC_ROUTING_HELPER_H */
--- a/src/helper/ipv6-interface-container.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/helper/ipv6-interface-container.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -22,7 +22,7 @@
 #include "ns3/names.h"
 
 #include "ipv6-interface-container.h"
-#include "ipv6-static-routing-helper.h"
+#include "ns3/ipv6-static-routing-helper.h"
 
 namespace ns3 
 {
--- a/src/helper/ipv6-list-routing-helper.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/ipv6-list-routing.h"
-#include "ns3/node.h"
-
-#include "ipv6-list-routing-helper.h"
-
-namespace ns3 {
-
-Ipv6ListRoutingHelper::Ipv6ListRoutingHelper ()
-{}
-
-Ipv6ListRoutingHelper::~Ipv6ListRoutingHelper()
-{
-  for (std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
-       i != m_list.end (); ++i)
-    {
-      delete i->first;
-    }
-}
-Ipv6ListRoutingHelper::Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &o)
-{
-  std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::const_iterator i;
-  for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
-    {
-      m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (i->first->Copy ()), i->second));
-    }
-}
-
-Ipv6ListRoutingHelper* 
-Ipv6ListRoutingHelper::Copy (void) const 
-{
-  return new Ipv6ListRoutingHelper (*this); 
-}
-
-void 
-Ipv6ListRoutingHelper::Add (const Ipv6RoutingHelper &routing, int16_t priority)
-{
-  m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (routing.Copy ()), priority));
-}
-Ptr<Ipv6RoutingProtocol> 
-Ipv6ListRoutingHelper::Create (Ptr<Node> node) const
-{
-  Ptr<Ipv6ListRouting> list = CreateObject<Ipv6ListRouting> ();
-  for (std::list<std::pair<const Ipv6RoutingHelper *,int16_t> >::const_iterator i = m_list.begin ();
-       i != m_list.end (); ++i)
-    {
-      Ptr<Ipv6RoutingProtocol> prot = i->first->Create (node);
-      list->AddRoutingProtocol (prot,i->second);
-    }
-  return list;
-}
-
-} // namespace ns3
--- a/src/helper/ipv6-list-routing-helper.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV6_LIST_ROUTING_HELPER_H
-#define IPV6_LIST_ROUTING_HELPER_H
-
-#include <stdint.h>
-
-#include <list>
-
-#include "ipv6-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv6ListRouting objects
- *
- * This class is expected to be used in conjunction with 
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv6ListRoutingHelper : public Ipv6RoutingHelper
-{
-public:
-  /**
-   * Construct an Ipv6 Ipv6ListRoutingHelper which is used to make life easier
-   * for people wanting to configure routing using Ipv6.
-   */
-  Ipv6ListRoutingHelper ();
-
-  /**
-   * \internal
-   * \brief Destroy an Ipv6 Ipv6ListRoutingHelper.
-   */
-  virtual ~Ipv6ListRoutingHelper ();
-
-  /**
-   * \brief Construct an Ipv6ListRoutingHelper from another previously 
-   * initialized instance (Copy Constructor).
-   */
-  Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &);
-
-  /**
-   * \returns pointer to clone of this Ipv6ListRoutingHelper 
-   * 
-   * This method is mainly for internal use by the other helpers;
-   * clients are expected to free the dynamic memory allocated by this method
-   */
-  Ipv6ListRoutingHelper* Copy (void) const;
-
-  /**
-   * \param routing a routing helper
-   * \param priority the priority of the associated helper
-   *
-   * Store in the internal list a reference to the input routing helper
-   * and associated priority. These helpers will be used later by
-   * the ns3::Ipv6ListRoutingHelper::Create method to create
-   * an ns3::Ipv6ListRouting object and add in it routing protocols
-   * created with the helpers.
-   */
-  void Add (const Ipv6RoutingHelper &routing, int16_t priority);
-  /**
-   * \param node the node on which the routing protocol will run
-   * \returns a newly-created routing protocol
-   *
-   * This method will be called by ns3::InternetStackHelper::Install
-   */
-  virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
-private:
-  /**
-   * \internal
-   * \brief Assignment operator declared private and not implemented to disallow
-   * assignment and prevent the compiler from happily inserting its own.
-   */
-  Ipv6ListRoutingHelper &operator = (const Ipv6ListRoutingHelper &o);
-
-  std::list<std::pair<const Ipv6RoutingHelper *,int16_t> > m_list;
-};
-
-} // namespace ns3
-
-#endif /* IPV6_LIST_ROUTING_HELPER_H */
-
--- a/src/helper/ipv6-static-routing-helper.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <vector>
-
-#include "ns3/log.h"
-#include "ns3/ptr.h"
-#include "ns3/names.h"
-#include "ns3/node.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-route.h"
-#include "ns3/ipv6-list-routing.h"
-#include "ns3/assert.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/ipv6-routing-protocol.h"
-
-#include "ipv6-static-routing-helper.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRoutingHelper");
-
-namespace ns3 {
-
-Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper ()
-{}
-
-Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &o)
-{
-}
-
-Ipv6StaticRoutingHelper* 
-Ipv6StaticRoutingHelper::Copy (void) const 
-{
-  return new Ipv6StaticRoutingHelper (*this); 
-}
-
-Ptr<Ipv6RoutingProtocol> 
-Ipv6StaticRoutingHelper::Create (Ptr<Node> node) const
-{
-  return CreateObject<Ipv6StaticRouting> ();
-}
-
-Ptr<Ipv6StaticRouting>
-Ipv6StaticRoutingHelper::GetStaticRouting (Ptr<Ipv6> ipv6) const
-{
-  NS_LOG_FUNCTION (this);
-  Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
-  NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
-  if (DynamicCast<Ipv6StaticRouting> (ipv6rp))
-    {
-      NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
-      return DynamicCast<Ipv6StaticRouting> (ipv6rp); 
-    } 
-  if (DynamicCast<Ipv6ListRouting> (ipv6rp))
-    {
-      Ptr<Ipv6ListRouting> lrp = DynamicCast<Ipv6ListRouting> (ipv6rp);
-      int16_t priority;
-      for (uint32_t i = 0; i < lrp->GetNRoutingProtocols ();  i++)
-        {
-          NS_LOG_LOGIC ("Searching for static routing in list");
-          Ptr<Ipv6RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
-          if (DynamicCast<Ipv6StaticRouting> (temp))
-            {
-              NS_LOG_LOGIC ("Found static routing in list");
-              return DynamicCast<Ipv6StaticRouting> (temp);
-            }
-        }
-    }
-  NS_LOG_LOGIC ("Static routing not found");
-  return 0;
-}
-
-void  
-Ipv6StaticRoutingHelper::AddMulticastRoute (
-  Ptr<Node> n,
-  Ipv6Address source, 
-  Ipv6Address group,  
-  Ptr<NetDevice> input, 
-  NetDeviceContainer output)
-{
-  Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
-
-  // We need to convert the NetDeviceContainer to an array of interface 
-  // numbers
-  std::vector<uint32_t> outputInterfaces;
-  for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
-    {
-      Ptr<NetDevice> nd = *i;
-      int32_t interface = ipv6->GetInterfaceForDevice (nd);
-      NS_ASSERT_MSG (interface >= 0, 
-        "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
-        "Expected an interface associated with the device nd");
-      outputInterfaces.push_back (interface);
-    }
-
-  int32_t inputInterface = ipv6->GetInterfaceForDevice (input);
-  NS_ASSERT_MSG (inputInterface >= 0, 
-    "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
-    "Expected an interface associated with the device input");
-  Ipv6StaticRoutingHelper helper;
-  Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
-  if (!ipv6StaticRouting)
-    {
-  NS_ASSERT_MSG (ipv6StaticRouting, 
-    "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
-    "Expected an Ipv6StaticRouting associated with this node");
-    }
-  ipv6StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
-}
-
-void  
-Ipv6StaticRoutingHelper::AddMulticastRoute (
-  Ptr<Node> n,
-  Ipv6Address source, 
-  Ipv6Address group,  
-  std::string inputName, 
-  NetDeviceContainer output)
-{
-  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
-  AddMulticastRoute (n, source, group, input, output);
-}
-
-void  
-Ipv6StaticRoutingHelper::AddMulticastRoute (
-  std::string nName,
-  Ipv6Address source, 
-  Ipv6Address group,  
-  Ptr<NetDevice> input, 
-  NetDeviceContainer output)
-{
-  Ptr<Node> n = Names::Find<Node> (nName);
-  AddMulticastRoute (n, source, group, input, output);
-}
-
-void  
-Ipv6StaticRoutingHelper::AddMulticastRoute (
-  std::string nName,
-  Ipv6Address source, 
-  Ipv6Address group,  
-  std::string inputName, 
-  NetDeviceContainer output)
-{
-  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
-  Ptr<Node> n = Names::Find<Node> (nName);
-  AddMulticastRoute (n, source, group, input, output);
-}
-
-#if 0
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
-  Ptr<Node> n, 
-  Ptr<NetDevice> nd)
-{
-  Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
-  int32_t interfaceSrc = ipv6->GetInterfaceForDevice (nd);
-  NS_ASSERT_MSG (interfaceSrc >= 0, 
-    "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
-    "Expected an interface associated with the device");
-  Ipv6StaticRoutingHelper helper;
-  Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
-  if (!ipv6StaticRouting)
-    {
-      NS_ASSERT_MSG (ipv6StaticRouting, 
-        "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
-        "Expected an Ipv6StaticRouting associated with this node");
-    }
-  ipv6StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
-}
-
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
-  Ptr<Node> n, 
-  std::string ndName)
-{
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
-  std::string nName, 
-  Ptr<NetDevice> nd)
-{
-  Ptr<Node> n = Names::Find<Node> (nName);
-  SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
-  std::string nName, 
-  std::string ndName)
-{
-  Ptr<Node> n = Names::Find<Node> (nName);
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  SetDefaultMulticastRoute (n, nd);
-}
-#endif
-
-}; // namespace ns3
--- a/src/helper/ipv6-static-routing-helper.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * 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 IPV6_STATIC_ROUTING_HELPER_H
-#define IPV6_STATIC_ROUTING_HELPER_H
-
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-static-routing.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-
-#include "node-container.h"
-#include "net-device-container.h"
-#include "ipv6-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv6StaticRouting objects
- *
- * This class is expected to be used in conjunction with 
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv6StaticRoutingHelper : public Ipv6RoutingHelper
-{
-public:
-  /**
-   * \brief Constructor.
-   */
-  Ipv6StaticRoutingHelper ();
-
-  /**
-   * \brief Construct an Ipv6ListRoutingHelper from another previously 
-   * initialized instance (Copy Constructor).
-   */
-  Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &);
-
-  /**
-   * \internal
-   * \returns pointer to clone of this Ipv6StaticRoutingHelper
-   *
-   * This method is mainly for internal use by the other helpers;
-   * clients are expected to free the dynamic memory allocated by this method
-   */
-  Ipv6StaticRoutingHelper* Copy (void) const;
-
-  /**
-   * \param node the node on which the routing protocol will run
-   * \returns a newly-created routing protocol
-   *
-   * This method will be called by ns3::InternetStackHelper::Install
-   */
-  virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
-
-  /**
-   * \brief Get Ipv6StaticRouting pointer from IPv6 stack.
-   * \param ipv6 Ipv6 pointer
-   * \return Ipv6StaticRouting pointer or 0 if not exist
-   */
-  Ptr<Ipv6StaticRouting> GetStaticRouting (Ptr<Ipv6> ipv6) const;
-
-  /**
-   * \brief Add a multicast route to a node and net device using explicit 
-   * Ptr<Node> and Ptr<NetDevice>
-   */
-  void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,  
-    Ptr<NetDevice> input, NetDeviceContainer output);
-
-  /**
-   * \brief Add a multicast route to a node and device using a name string 
-   * previously associated to the node using the Object Name Service and a
-   * Ptr<NetDevice>
-   */
-  void AddMulticastRoute (std::string n, Ipv6Address source, Ipv6Address group,  
-    Ptr<NetDevice> input, NetDeviceContainer output);
-
-  /**
-   * \brief Add a multicast route to a node and device using a Ptr<Node> and a 
-   * name string previously associated to the device using the Object Name Service.
-   */
-  void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,  
-    std::string inputName, NetDeviceContainer output);
-
-  /**
-   * \brief Add a multicast route to a node and device using name strings
-   * previously associated to both the node and device using the Object Name 
-   * Service.
-   */
-  void AddMulticastRoute (std::string nName, Ipv6Address source, Ipv6Address group,  
-    std::string inputName, NetDeviceContainer output);
-
-#if 0
-  /**
-   * \brief Add a default route to the static routing protocol to forward
-   *        packets out a particular interface
-   */
-  void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
-  void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
-  void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
-  void SetDefaultMulticastRoute (std::string nName, std::string ndName);
-#endif
-private:
-  /**
-   * \internal
-   * \brief Assignment operator declared private and not implemented to disallow
-   * assignment and prevent the compiler from happily inserting its own.
-   */
-  Ipv6StaticRoutingHelper &operator = (const Ipv6StaticRoutingHelper &o);
-};
-
-} // namespace ns3
-
-#endif /* IPV6_STATIC_ROUTING_HELPER_H */
-
--- a/src/helper/wscript	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/helper/wscript	Tue Oct 26 18:02:17 2010 +0100
@@ -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', 'global-routing', 'onoff', 'packet-sink', 'udp-echo', 'spectrum'])
+    helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'onoff', 'packet-sink', 'udp-echo', 'spectrum'])
     helper.source = [
         'node-container.cc',
         'net-device-container.cc',
@@ -11,7 +11,6 @@
         'mobility-helper.cc',
         'ns2-mobility-helper.cc',
         'ipv4-address-helper.cc',
-        'ipv4-static-routing-helper.cc',
         'internet-stack-helper.cc',
         'application-container.cc',
         'on-off-helper.cc',
@@ -26,8 +25,6 @@
         'nqos-wifi-mac-helper.cc',
         'qos-wifi-mac-helper.cc',
         'ipv4-nix-vector-helper.cc',
-        'ipv4-global-routing-helper.cc',
-        'ipv4-list-routing-helper.cc',
         'ipv4-routing-helper.cc',
         'aodv-helper.cc',
         'mesh-helper.cc',
@@ -36,8 +33,6 @@
         'athstats-helper.cc',
         'ipv6-address-helper.cc',
         'ipv6-interface-container.cc',
-        'ipv6-static-routing-helper.cc',
-        'ipv6-list-routing-helper.cc',
         'ipv6-routing-helper.cc',
         'ping6-helper.cc',
         'animation-interface.cc',
@@ -65,7 +60,6 @@
         'mobility-helper.h',
         'ns2-mobility-helper.h',
         'ipv4-address-helper.h',
-        'ipv4-static-routing-helper.h',
         'internet-stack-helper.h',
         'application-container.h',
         'on-off-helper.h',
@@ -80,8 +74,6 @@
         'nqos-wifi-mac-helper.h',
         'qos-wifi-mac-helper.h',
         'ipv4-nix-vector-helper.h',
-	'ipv4-global-routing-helper.h',
-        'ipv4-list-routing-helper.h',
         'ipv4-routing-helper.h',
         'aodv-helper.h',
         'mesh-helper.h',
@@ -91,8 +83,6 @@
         'athstats-helper.h',
         'ipv6-address-helper.h',
         'ipv6-interface-container.h',
-        'ipv6-static-routing-helper.h',
-        'ipv6-list-routing-helper.h',
         'ipv6-routing-helper.h',
         'ping6-helper.h',
         'animation-interface.h',
--- a/src/routing/global-routing/candidate-queue.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <algorithm>
-#include <iostream>
-#include "ns3/log.h"
-#include "ns3/assert.h"
-#include "candidate-queue.h"
-#include "global-route-manager-impl.h"
-
-NS_LOG_COMPONENT_DEFINE ("CandidateQueue");
-
-namespace ns3 {
-
-std::ostream&
-operator<< (std::ostream& os, const SPFVertex::VertexType& t)
-{
-  switch (t)
-    {
-    case SPFVertex::VertexRouter:  os << "router"; break;
-    case SPFVertex::VertexNetwork: os << "network"; break;
-    default:                       os << "unknown"; break;
-    };
-  return os;
-}
-
-std::ostream& 
-operator<< (std::ostream& os, const CandidateQueue& q)
-{
-  typedef CandidateQueue::CandidateList_t List_t;
-  typedef List_t::const_iterator CIter_t;
-  const CandidateQueue::CandidateList_t& list = q.m_candidates;
-
-  os << "*** CandidateQueue Begin (<id, distance, LSA-type>) ***" << std::endl;
-  for (CIter_t iter = list.begin (); iter != list.end (); iter++)
-    {
-      os << "<" 
-         << (*iter)->GetVertexId () << ", " 
-         << (*iter)->GetDistanceFromRoot () << ", " 
-         << (*iter)->GetVertexType () << ">" << std::endl;
-    }
-  os << "*** CandidateQueue End ***";
-  return os;
-}
-
-CandidateQueue::CandidateQueue()
-  : m_candidates ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-CandidateQueue::~CandidateQueue()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Clear ();
-}
-
-  void
-CandidateQueue::Clear (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  while (!m_candidates.empty ())
-    {
-      SPFVertex *p = Pop ();
-      delete p;
-      p = 0;
-    }
-}
-
-  void
-CandidateQueue::Push (SPFVertex *vNew)
-{
-  NS_LOG_FUNCTION (this << vNew);
-
-  CandidateList_t::iterator i = std::upper_bound (
-    m_candidates.begin (), m_candidates.end (), vNew,
-    &CandidateQueue::CompareSPFVertex
-    );
-  m_candidates.insert (i, vNew);
-}
-
-  SPFVertex *
-CandidateQueue::Pop (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_candidates.empty ())
-    {
-      return 0;
-    }
-
-  SPFVertex *v = m_candidates.front ();
-  m_candidates.pop_front ();
-  return v;
-}
-
-  SPFVertex *
-CandidateQueue::Top (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_candidates.empty ())
-    {
-      return 0;
-    }
-
-  return m_candidates.front ();
-}
-
-  bool
-CandidateQueue::Empty (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_candidates.empty ();
-}
-
-  uint32_t
-CandidateQueue::Size (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_candidates.size ();
-}
-
-  SPFVertex *
-CandidateQueue::Find (const Ipv4Address addr) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  CandidateList_t::const_iterator i = m_candidates.begin ();
-
-  for (; i != m_candidates.end (); i++)
-    {
-      SPFVertex *v = *i;
-      if (v->GetVertexId() == addr)
-        {
-          return v;
-        }
-    }
-
-  return 0;
-}
-
-  void
-CandidateQueue::Reorder (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  m_candidates.sort (&CandidateQueue::CompareSPFVertex);
-  NS_LOG_LOGIC ("After reordering the CandidateQueue");
-  NS_LOG_LOGIC (*this);
-}
-
-/*
- * In this implementation, SPFVertex follows the ordering where
- * a vertex is ranked first if its GetDistanceFromRoot () is smaller;
- * In case of a tie, NetworkLSA is always ranked before RouterLSA.
- *
- * This ordering is necessary for implementing ECMP
- */
-bool 
-CandidateQueue::CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2)
-{
-  NS_LOG_FUNCTION (&v1 << &v2);
-
-  bool result = false;
-  if (v1->GetDistanceFromRoot () < v2->GetDistanceFromRoot ())
-    {  
-      result = true;
-    }
-  else if (v1->GetDistanceFromRoot () == v2->GetDistanceFromRoot ())
-    {
-      if (v1->GetVertexType () == SPFVertex::VertexNetwork 
-          && v2->GetVertexType () == SPFVertex::VertexRouter)
-        {
-          result = true;
-        }
-    }
-  return result;
-}
-
-} // namespace ns3
--- a/src/routing/global-routing/candidate-queue.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * 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:  Craig Dowell (craigdo@ee.washington.edu)
- */
-
-#ifndef CANDIDATE_QUEUE_H
-#define CANDIDATE_QUEUE_H
-
-#include <stdint.h>
-#include <list>
-#include "ns3/ipv4-address.h"
-
-namespace ns3 {
-
-class SPFVertex;
-
-/**  
- * \brief A Candidate Queue used in static routing.
- *
- * The CandidateQueue is used in the OSPF shortest path computations.  It
- * is a priority queue used to store candidates for the shortest path to a
- * given network.  
- *
- * The queue holds Shortest Path First Vertex pointers and orders them
- * according to the lowest value of the field m_distanceFromRoot.  Remaining
- * vertices are ordered according to increasing distance.  This implements a
- * priority queue.
- *
- * Although a STL priority_queue almost does what we want, the requirement
- * for a Find () operation, the dynamic nature of the data and the derived
- * requirement for a Reorder () operation led us to implement this simple 
- * enhanced priority queue.
- */
-class CandidateQueue
-{
-public:
-/**
- * @brief Create an empty SPF Candidate Queue.  
- * @internal
- *
- * @see SPFVertex
- */
-  CandidateQueue ();
-
-/**
- * @internal Destroy an SPF Candidate Queue and release any resources held 
- * by the contents.
- * @internal
- *
- * @see SPFVertex
- */
-  virtual ~CandidateQueue ();
-
-/**
- * @brief Empty the Candidate Queue and release all of the resources 
- * associated with the Shortest Path First Vertex pointers in the queue.
- * @internal
- *
- * @see SPFVertex
- */
-  void Clear (void);
-
-/**
- * @brief Push a Shortest Path First Vertex pointer onto the queue according
- * to the priority scheme.
- * @internal
- * 
- * On completion, the top of the queue will hold the Shortest Path First
- * Vertex pointer that points to a vertex having lowest value of the field
- * m_distanceFromRoot.  Remaining vertices are ordered according to 
- * increasing distance.
- *
- * @see SPFVertex
- * @param vNew The Shortest Path First Vertex to add to the queue.
- */
-  void Push (SPFVertex *vNew);
-
-/**
- * @brief Pop the Shortest Path First Vertex pointer at the top of the queue.
- * @internal
- *
- * The caller is given the responsibility for releasing the resources 
- * associated with the vertex.
- *
- * @see SPFVertex
- * @see Top ()
- * @returns The Shortest Path First Vertex pointer at the top of the queue.
- */
-  SPFVertex* Pop (void);
-
-/**
- * @brief Return the Shortest Path First Vertex pointer at the top of the 
- * queue.  
- * @internal
- *
- * This method does not pop the SPFVertex* off of the queue, it simply 
- * returns the pointer.
- *
- * @see SPFVertex
- * @see Pop ()
- * @returns The Shortest Path First Vertex pointer at the top of the queue.
- */
-  SPFVertex* Top (void) const;
-
-/**
- * @brief Test the Candidate Queue to determine if it is empty.
- * @internal
- *
- * @returns True if the queue is empty, false otherwise.
- */
-  bool Empty (void) const;
-
-/**
- * @brief Return the number of Shortest Path First Vertex pointers presently
- * stored in the Candidate Queue.
- * @internal
- *
- * @see SPFVertex
- * @returns The number of SPFVertex* pointers in the Candidate Queue.
- */
-  uint32_t Size (void) const;
-
-/**
- * @brief Searches the Candidate Queue for a Shortest Path First Vertex 
- * pointer that points to a vertex having the given IP address.
- * @internal
- *
- * @see SPFVertex
- * @param addr The IP address to search for.
- * @returns The SPFVertex* pointer corresponding to the given IP address.
- */
-  SPFVertex* Find (const Ipv4Address addr) const;
-
-/**
- * @brief Reorders the Candidate Queue according to the priority scheme.  
- * @internal
- * 
- * On completion, the top of the queue will hold the Shortest Path First
- * Vertex pointer that points to a vertex having lowest value of the field
- * m_distanceFromRoot.  Remaining vertices are ordered according to 
- * increasing distance.
- *
- * This method is provided in case the values of m_distanceFromRoot change
- * during the routing calculations.
- *
- * @see SPFVertex
- */
-  void Reorder (void);
-
-private:
-/**
- * Candidate Queue copy construction is disallowed (not implemented) to 
- * prevent the compiler from slipping in incorrect versions that don't
- * properly deal with deep copies.
- * \param sr object to copy
- */
-  CandidateQueue (CandidateQueue& sr);
-
-/**
- * Candidate Queue assignment operator is disallowed (not implemented) to
- * prevent the compiler from slipping in incorrect versions that don't
- * properly deal with deep copies.
- * \param sr object to assign
- */
-  CandidateQueue& operator= (CandidateQueue& sr);
-/**
- * \brief return true if v1 < v2
- *
- * SPFVertexes are added into the queue according to the ordering
- * defined by this method. If v1 should be popped before v2, this 
- * method return true; false otherwise
- *
- * \return True if v1 should be popped before v2; false otherwise
- */
-  static bool CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2);
-
-  typedef std::list<SPFVertex*> CandidateList_t;
-  CandidateList_t m_candidates;
-
-  friend std::ostream& operator<< (std::ostream& os, const CandidateQueue& q);
-};
-
-} // namespace ns3
-
-#endif /* CANDIDATE_QUEUE_H */
--- a/src/routing/global-routing/global-route-manager-impl.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2402 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
- * 
- * 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:  Tom Henderson (tomhend@u.washington.edu)
- * 
- * Kunihiro Ishigura, Toshiaki Takada (GNU Zebra) are attributed authors
- * of the quagga 0.99.7/src/ospfd/ospf_spf.c code which was ported here
- */
-
-#include <utility>
-#include <vector>
-#include <queue>
-#include <algorithm>
-#include <iostream>
-#include "ns3/assert.h"
-#include "ns3/fatal-error.h"
-#include "ns3/log.h"
-#include "ns3/node-list.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/mpi-interface.h"
-#include "global-router-interface.h"
-#include "global-route-manager-impl.h"
-#include "candidate-queue.h"
-#include "ipv4-global-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("GlobalRouteManager");
-
-namespace ns3 {
-
-std::ostream& 
-operator<< (std::ostream& os, const SPFVertex::NodeExit_t& exit)
-{
-  os << "(" << exit.first << " ," << exit.second << ")";
-  return os;
-}
-
-std::ostream& 
-operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs)
-{
-  typedef SPFVertex::ListOfSPFVertex_t::const_iterator CIter_t;
-  os << "{";
-  for (CIter_t iter = vs.begin (); iter != vs.end ();)
-    {
-      os << (*iter)->m_vertexId;
-      if (++iter != vs.end ()) 
-        {
-          os << ", ";
-        }
-      else 
-        { 
-          break;
-        }
-    }
-  os << "}";
-  return os;
-}
-
-// ---------------------------------------------------------------------------
-//
-// SPFVertex Implementation
-//
-// ---------------------------------------------------------------------------
-
-SPFVertex::SPFVertex () : 
-  m_vertexType (VertexUnknown), 
-  m_vertexId ("255.255.255.255"), 
-  m_lsa (0),
-  m_distanceFromRoot (SPF_INFINITY), 
-  m_rootOif (SPF_INFINITY),
-  m_nextHop ("0.0.0.0"),
-  m_parents (),
-  m_children (),
-  m_vertexProcessed (false)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) : 
-  m_vertexId (lsa->GetLinkStateId ()),
-  m_lsa (lsa),
-  m_distanceFromRoot (SPF_INFINITY), 
-  m_rootOif (SPF_INFINITY),
-  m_nextHop ("0.0.0.0"),
-  m_parents (),
-  m_children (),
-  m_vertexProcessed (false)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) 
-    {
-      NS_LOG_LOGIC ("Setting m_vertexType to VertexRouter");
-      m_vertexType = SPFVertex::VertexRouter;
-    }
-  else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA) 
-    { 
-      NS_LOG_LOGIC ("Setting m_vertexType to VertexNetwork");
-      m_vertexType = SPFVertex::VertexNetwork;
-    }
-}
-
-SPFVertex::~SPFVertex ()
-{
-  NS_LOG_FUNCTION (m_vertexId);
-  
-  NS_LOG_LOGIC ("Children vertices - " << m_children);
-  NS_LOG_LOGIC ("Parent verteices - " << m_parents);
-
-  // find this node from all its parents and remove the entry of this node
-  // from all its parents
-  for (ListOfSPFVertex_t::iterator piter = m_parents.begin (); 
-      piter != m_parents.end (); 
-      piter++)
-    {
-      // remove the current vertex from its parent's children list. Check
-      // if the size of the list is reduced, or the child<->parent relation
-      // is not bidirectional
-      uint32_t orgCount = (*piter)->m_children.size ();
-      (*piter)->m_children.remove (this);
-      uint32_t newCount = (*piter)->m_children.size ();
-      if (orgCount > newCount)
-        {
-          NS_ASSERT_MSG (orgCount > newCount, "Unable to find the current vertex from its parents --- impossible!");
-        }
-    }
-
-  // delete children
-  while (m_children.size () > 0)
-    {
-      // pop out children one by one. Some children may disapper 
-      // when deleting some other children in the list. As a result,
-      // it is necessary to use pop to walk through all children, instead
-      // of using iterator.
-      //
-      // Note that m_children.pop_front () is not necessary as this
-      // p is removed from the children list when p is deleted
-      SPFVertex* p = m_children.front ();
-      // 'p' == 0, this child is already deleted by its other parent
-      if (p == 0) continue;
-      NS_LOG_LOGIC ("Parent vertex-" << m_vertexId << " deleting its child vertex-" << p->GetVertexId ());
-      delete p;
-      p = 0;
-    }
-  m_children.clear ();
-  // delete parents
-  m_parents.clear ();
-  // delete root exit direction
-  m_ecmpRootExits.clear ();
-
-  NS_LOG_LOGIC ("Vertex-" << m_vertexId << " completed deleted");
-}
-
-  void 
-SPFVertex::SetVertexType (SPFVertex::VertexType type)
-{
-  NS_LOG_FUNCTION (type);
-  m_vertexType = type;
-}
-
-  SPFVertex::VertexType 
-SPFVertex::GetVertexType (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_vertexType;
-}
-
-  void 
-SPFVertex::SetVertexId (Ipv4Address id)
-{
-  NS_LOG_FUNCTION (id);
-  m_vertexId = id;
-}
-
-  Ipv4Address
-SPFVertex::GetVertexId (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_vertexId;
-}
-
-  void 
-SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
-{
-  NS_LOG_FUNCTION (lsa);
-  m_lsa = lsa;
-}
-
-  GlobalRoutingLSA* 
-SPFVertex::GetLSA (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_lsa;
-}
-
-  void 
-SPFVertex::SetDistanceFromRoot (uint32_t distance)
-{
-  NS_LOG_FUNCTION (distance);
-  m_distanceFromRoot = distance;
-}
-
-  uint32_t
-SPFVertex::GetDistanceFromRoot (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_distanceFromRoot;
-}
-
-  void
-SPFVertex::SetParent (SPFVertex* parent)
-{
-  NS_LOG_FUNCTION (parent);
-
-  // always maintain only one parent when using setter/getter methods
-  m_parents.clear ();
-  m_parents.push_back (parent);
-}
-
-  SPFVertex* 
-SPFVertex::GetParent (uint32_t i) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  // If the index i is out-of-range, return 0 and do nothing
-  if (m_parents.size () <= i)
-    {
-      NS_LOG_LOGIC ("Index to SPFVertex's parent is out-of-range.");
-      return 0;
-    }
-  ListOfSPFVertex_t::const_iterator iter = m_parents.begin ();
-  while (i-- > 0) 
-    {
-      iter++;
-    }
-  return *iter;
-}
-
-void 
-SPFVertex::MergeParent (const SPFVertex* v)
-{
-  NS_LOG_FUNCTION (v);
-
-  NS_LOG_LOGIC ("Before merge, list of parents = " << m_parents);
-  // combine the two lists first, and then remove any duplicated after
-  m_parents.insert (m_parents.end (), 
-    v->m_parents.begin (), v->m_parents.end ());
-  // remove duplication
-  m_parents.sort ();
-  m_parents.unique ();
-  NS_LOG_LOGIC ("After merge, list of parents = " << m_parents);
-}
-
-void 
-SPFVertex::SetRootExitDirection (Ipv4Address nextHop, int32_t id)
-{
-  NS_LOG_FUNCTION (nextHop << id);
-  
-  // always maintain only one root's exit
-  m_ecmpRootExits.clear ();
-  m_ecmpRootExits.push_back (NodeExit_t (nextHop, id));
-  // update the following in order to be backward compatitable with
-  // GetNextHop and GetOutgoingInterface methods
-  m_nextHop = nextHop;
-  m_rootOif = id;
-}
-
-void 
-SPFVertex::SetRootExitDirection (SPFVertex::NodeExit_t exit)
-{
-  NS_LOG_FUNCTION (exit);
-  SetRootExitDirection (exit.first, exit.second);
-}
-
-SPFVertex::NodeExit_t
-SPFVertex::GetRootExitDirection (uint32_t i) const
-{
-  NS_LOG_FUNCTION (i);
-  typedef ListOfNodeExit_t::const_iterator CIter_t;
-
-  NS_ASSERT_MSG (i < m_ecmpRootExits.size (), "Index out-of-range when accessing SPFVertex::m_ecmpRootExits!");
-  CIter_t iter = m_ecmpRootExits.begin ();
-  while (i-- > 0) {iter++;}
-
-  return *iter;
-}
-
-SPFVertex::NodeExit_t 
-SPFVertex::GetRootExitDirection () const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  NS_ASSERT_MSG (m_ecmpRootExits.size () <= 1, "Assumed there is at most one exit from the root to this vertex");
-  return GetRootExitDirection (0);
-}
-
-void 
-SPFVertex::MergeRootExitDirections (const SPFVertex* vertex)
-{
-  NS_LOG_FUNCTION (vertex);
-
-  // obtain the external list of exit directions
-  //
-  // Append the external list into 'this' and remove duplication afterward
-  const ListOfNodeExit_t& extList = vertex->m_ecmpRootExits;
-  m_ecmpRootExits.insert (m_ecmpRootExits.end (), 
-    extList.begin(), extList.end ());
-  m_ecmpRootExits.sort ();
-  m_ecmpRootExits.unique ();
-}
-
-void 
-SPFVertex::InheritAllRootExitDirections (const SPFVertex* vertex)
-{
-  NS_LOG_FUNCTION (vertex);
-
-  // discard all exit direction currently associated with this vertex,
-  // and copy all the exit directions from the given vertex
-  if (m_ecmpRootExits.size () > 0)
-    {
-      NS_LOG_WARN ("x root exit directions in this vertex are going to be discarded");
-    }
-  m_ecmpRootExits.clear ();
-  m_ecmpRootExits.insert (m_ecmpRootExits.end (), 
-      vertex->m_ecmpRootExits.begin (), vertex->m_ecmpRootExits.end ());
-}
-
-uint32_t 
-SPFVertex::GetNRootExitDirections () const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_ecmpRootExits.size ();
-}
-
-uint32_t 
-SPFVertex::GetNChildren (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_children.size ();
-}
-
-  SPFVertex* 
-SPFVertex::GetChild (uint32_t n) const
-{
-  NS_LOG_FUNCTION (n);
-  uint32_t j = 0;
-
-  for ( ListOfSPFVertex_t::const_iterator i = m_children.begin ();
-        i != m_children.end ();
-        i++, j++)
-    {
-      if (j == n)
-        {
-          return *i;
-        }
-    }
-  NS_ASSERT_MSG (false, "Index <n> out of range.");
-  return 0;
-}
-
-  uint32_t 
-SPFVertex::AddChild (SPFVertex* child)
-{
-  NS_LOG_FUNCTION (child);
-  m_children.push_back (child);
-  return m_children.size ();
-}
-
-void 
-SPFVertex::SetVertexProcessed (bool value)
-{
-  m_vertexProcessed = value;
-}
-
-bool 
-SPFVertex::IsVertexProcessed (void) const
-{
-  return m_vertexProcessed;
-}
-
-void
-SPFVertex::ClearVertexProcessed (void)
-{
-  for (uint32_t i = 0; i < this->GetNChildren (); i++)
-    {
-      this->GetChild (i)->ClearVertexProcessed ();
-    }
-  this->SetVertexProcessed (false);
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouteManagerLSDB Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
-:
-  m_database (),
-  m_extdatabase ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  LSDBMap_t::iterator i;
-  for (i= m_database.begin (); i!= m_database.end (); i++)
-    {
-      NS_LOG_LOGIC ("free LSA");
-      GlobalRoutingLSA* temp = i->second;
-      delete temp;
-    }
-  for (uint32_t j = 0; j < m_extdatabase.size (); j++)
-    {
-      NS_LOG_LOGIC ("free ASexternalLSA");
-      GlobalRoutingLSA* temp = m_extdatabase.at (j);
-      delete temp;
-    }
-  NS_LOG_LOGIC ("clear map");
-  m_database.clear ();
-}
-
-  void
-GlobalRouteManagerLSDB::Initialize ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  LSDBMap_t::iterator i;
-  for (i= m_database.begin (); i!= m_database.end (); i++)
-    {
-      GlobalRoutingLSA* temp = i->second;
-      temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
-    }
-}
-
-  void
-GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
-{
-  NS_LOG_FUNCTION (addr << lsa);
-  if (lsa->GetLSType () == GlobalRoutingLSA::ASExternalLSAs) 
-    {
-      m_extdatabase.push_back (lsa);
-    } 
-  else
-    {
-      m_database.insert (LSDBPair_t (addr, lsa));
-    }
-}
-
-  GlobalRoutingLSA*
-GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const
-{
-  return m_extdatabase.at (index);
-}
-
-  uint32_t
-GlobalRouteManagerLSDB::GetNumExtLSAs () const
-{
-  return m_extdatabase.size ();
-}
-
-  GlobalRoutingLSA*
-GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
-{
-  NS_LOG_FUNCTION (addr);
-//
-// Look up an LSA by its address.
-//
-  LSDBMap_t::const_iterator i;
-  for (i= m_database.begin (); i!= m_database.end (); i++)
-  {
-    if (i->first == addr)
-    {
-      return i->second;
-    }
-  }
-  return 0;
-}
-
-  GlobalRoutingLSA*
-GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
-{
-  NS_LOG_FUNCTION (addr);
-//
-// Look up an LSA by its address.
-//
-  LSDBMap_t::const_iterator i;
-  for (i= m_database.begin (); i!= m_database.end (); i++)
-    {
-      GlobalRoutingLSA* temp = i->second;
-// Iterate among temp's Link Records
-      for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
-        {
-          GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
-          if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
-               lr->GetLinkData () == addr)
-            {
-              return temp;
-            }
-        }
-    }
-  return 0;
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouteManagerImpl Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRouteManagerImpl::GlobalRouteManagerImpl () 
-: 
-  m_spfroot (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_lsdb = new GlobalRouteManagerLSDB ();
-}
-
-GlobalRouteManagerImpl::~GlobalRouteManagerImpl ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_lsdb)
-    {
-      delete m_lsdb;
-    }
-}
-
-  void
-GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb)
-{
-  NS_LOG_FUNCTION (lsdb);
-  if (m_lsdb)
-    {
-      delete m_lsdb;
-    }
-  m_lsdb = lsdb;
-}
-
-  void
-GlobalRouteManagerImpl::DeleteGlobalRoutes ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-      Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
-      if (router == 0)
-        {
-          continue;
-        }
-      Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
-      uint32_t j = 0;
-      uint32_t nRoutes = gr->GetNRoutes ();
-      NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ());
-      // Each time we delete route 0, the route index shifts downward
-      // We can delete all routes if we delete the route numbered 0
-      // nRoutes times
-      for (j = 0; j < nRoutes; j++)
-        {
-          NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ());
-          gr->RemoveRoute (0);        
-        }
-      NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ());
-    }
-  if (m_lsdb)
-    {
-      NS_LOG_LOGIC ("Deleting LSDB, creating new one");
-      delete m_lsdb;
-      m_lsdb = new GlobalRouteManagerLSDB ();
-    }
-}
-
-//
-// In order to build the routing database, we need to walk the list of nodes
-// in the system and look for those that support the GlobalRouter interface.
-// These routers will export a number of Link State Advertisements (LSAs)
-// that describe the links and networks that are "adjacent" (i.e., that are
-// on the other side of a point-to-point link).  We take these LSAs and put
-// add them to the Link State DataBase (LSDB) from which the routes will 
-// ultimately be computed.
-//
-  void
-GlobalRouteManagerImpl::BuildGlobalRoutingDatabase () 
-{
-  NS_LOG_FUNCTION_NOARGS ();
-//
-// Walk the list of nodes looking for the GlobalRouter Interface.  Nodes with
-// global router interfaces are, not too surprisingly, our routers.
-//
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-
-      Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
-//      
-// Ignore nodes that aren't participating in routing.
-//
-      if (!rtr)
-        {
-          continue;
-        }
-//
-// You must call DiscoverLSAs () before trying to use any routing info or to
-// update LSAs.  DiscoverLSAs () drives the process of discovering routes in
-// the GlobalRouter.  Afterward, you may use GetNumLSAs (), which is a very
-// computationally inexpensive call.  If you call GetNumLSAs () before calling 
-// DiscoverLSAs () will get zero as the number since no routes have been 
-// found.
-//
-      Ptr<Ipv4GlobalRouting> grouting = rtr->GetRoutingProtocol ();
-      uint32_t numLSAs = rtr->DiscoverLSAs ();
-      NS_LOG_LOGIC ("Found " << numLSAs << " LSAs");
-
-      for (uint32_t j = 0; j < numLSAs; ++j)
-        {
-          GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
-//
-// This is the call to actually fetch a Link State Advertisement from the 
-// router.
-//
-          rtr->GetLSA (j, *lsa);
-          NS_LOG_LOGIC (*lsa);
-//
-// Write the newly discovered link state advertisement to the database.
-//
-          m_lsdb->Insert (lsa->GetLinkStateId (), lsa); 
-        }
-    }
-}
-
-//
-// For each node that is a global router (which is determined by the presence
-// of an aggregated GlobalRouter interface), run the Dijkstra SPF calculation
-// on the database rooted at that router, and populate the node forwarding
-// tables.
-//
-// This function parallels RFC2328, Section 16.1.1, and quagga ospfd
-//
-// This calculation yields the set of intra-area routes associated
-// with an area (called hereafter Area A).  A router calculates the
-// shortest-path tree using itself as the root.  The formation
-// of the shortest path tree is done here in two stages.  In the
-// first stage, only links between routers and transit networks are
-// considered.  Using the Dijkstra algorithm, a tree is formed from
-// this subset of the link state database.  In the second stage,
-// leaves are added to the tree by considering the links to stub
-// networks.
-//
-// The area's link state database is represented as a directed graph.  
-// The graph's vertices are routers, transit networks and stub networks.  
-//
-// The first stage of the procedure (i.e., the Dijkstra algorithm)
-// can now be summarized as follows. At each iteration of the
-// algorithm, there is a list of candidate vertices.  Paths from
-// the root to these vertices have been found, but not necessarily
-// the shortest ones.  However, the paths to the candidate vertex
-// that is closest to the root are guaranteed to be shortest; this
-// vertex is added to the shortest-path tree, removed from the
-// candidate list, and its adjacent vertices are examined for
-// possible addition to/modification of the candidate list.  The
-// algorithm then iterates again.  It terminates when the candidate
-// list becomes empty. 
-//
-  void
-GlobalRouteManagerImpl::InitializeRoutes ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-//
-// Walk the list of nodes in the system.
-//
-  NS_LOG_INFO ("About to start SPF calculation");
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-//
-// Look for the GlobalRouter interface that indicates that the node is
-// participating in routing.
-//
-      Ptr<GlobalRouter> rtr = 
-        node->GetObject<GlobalRouter> ();
-
-      // Ignore nodes that are not assigned to our systemId (distributed sim)
-      if (node->GetSystemId () != MpiInterface::GetSystemId ()) 
-        {
-          continue;
-        }
-      
-//
-// if the node has a global router interface, then run the global routing
-// algorithms.
-//
-      if (rtr && rtr->GetNumLSAs () )
-        {
-          SPFCalculate (rtr->GetRouterId ());
-        }
-    }
-  NS_LOG_INFO ("Finished SPF calculation");
-}
-
-//
-// This method is derived from quagga ospf_spf_next ().  See RFC2328 Section 
-// 16.1 (2) for further details.
-//
-// We're passed a parameter <v> that is a vertex which is already in the SPF
-// tree.  A vertex represents a router node.  We also get a reference to the
-// SPF candidate queue, which is a priority queue containing the shortest paths
-// to the networks we know about.
-//
-// We examine the links in v's LSA and update the list of candidates with any
-// vertices not already on the list.  If a lower-cost path is found to a
-// vertex already on the candidate list, store the new (lower) cost.
-//
-  void
-GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
-{
-  NS_LOG_FUNCTION (v << &candidate);
-
-  SPFVertex* w = 0;
-  GlobalRoutingLSA* w_lsa = 0;
-  GlobalRoutingLinkRecord *l = 0;
-  uint32_t distance = 0;
-  uint32_t numRecordsInVertex = 0;
-//
-// V points to a Router-LSA or Network-LSA
-// Loop over the links in router LSA or attached routers in Network LSA
-//
-  if (v->GetVertexType () == SPFVertex::VertexRouter)
-    {
-      numRecordsInVertex = v->GetLSA ()->GetNLinkRecords (); 
-    }
-  if (v->GetVertexType () == SPFVertex::VertexNetwork)
-    {
-      numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters (); 
-    }
-
-  for (uint32_t i = 0; i < numRecordsInVertex; i++)
-    {
-// Get w_lsa:  In case of V is Router-LSA
-      if (v->GetVertexType () == SPFVertex::VertexRouter) 
-        {
-          NS_LOG_LOGIC ("Examining link " << i << " of " << 
-            v->GetVertexId () << "'s " <<
-            v->GetLSA ()->GetNLinkRecords () << " link records");
-//
-// (a) If this is a link to a stub network, examine the next link in V's LSA.
-// Links to stub networks will be considered in the second stage of the
-// shortest path calculation.
-//
-          l = v->GetLSA ()->GetLinkRecord (i);
-          if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
-            {
-              NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
-              continue;
-            }
-//
-// (b) Otherwise, W is a transit vertex (router or transit network).  Look up
-// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
-// database. 
-//
-          if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
-            {
-//
-// Lookup the link state advertisement of the new link -- we call it <w> in
-// the link state database.
-//
-              w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
-              NS_ASSERT (w_lsa);
-              NS_LOG_LOGIC ("Found a P2P record from " << 
-                v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
-            }
-          else if (l->GetLinkType () == 
-            GlobalRoutingLinkRecord::TransitNetwork)
-            {
-              w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
-              NS_ASSERT (w_lsa);
-              NS_LOG_LOGIC ("Found a Transit record from " << 
-                v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
-            }
-          else 
-            {
-              NS_ASSERT_MSG (0, "illegal Link Type");
-            }
-        }
-// Get w_lsa:  In case of V is Network-LSA
-      if (v->GetVertexType () == SPFVertex::VertexNetwork) 
-        {
-          w_lsa = m_lsdb->GetLSAByLinkData 
-            (v->GetLSA ()->GetAttachedRouter (i)); 
-          if (!w_lsa)
-            {
-              continue;
-            }
-          NS_LOG_LOGIC ("Found a Network LSA from " << 
-            v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
-        }
-
-// Note:  w_lsa at this point may be either RouterLSA or NetworkLSA
-//
-// (c) If vertex W is already on the shortest-path tree, examine the next
-// link in the LSA.
-//
-// If the link is to a router that is already in the shortest path first tree
-// then we have it covered -- ignore it.
-//
-      if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE) 
-        {
-          NS_LOG_LOGIC ("Skipping ->  LSA "<< 
-            w_lsa->GetLinkStateId () << " already in SPF tree");
-          continue;
-        }
-//
-// (d) Calculate the link state cost D of the resulting path from the root to 
-// vertex W.  D is equal to the sum of the link state cost of the (already 
-// calculated) shortest path to vertex V and the advertised cost of the link
-// between vertices V and W.  
-//
-      if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
-        {
-          distance = v->GetDistanceFromRoot () + l->GetMetric ();
-        }
-      else
-        {
-          distance = v->GetDistanceFromRoot ();
-        }
-
-      NS_LOG_LOGIC ("Considering w_lsa " << w_lsa->GetLinkStateId ());
-
-// Is there already vertex w in candidate list?
-      if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
-        {
-// Calculate nexthop to w
-// We need to figure out how to actually get to the new router represented
-// by <w>.  This will (among other things) find the next hop address to send
-// packets destined for this network to, and also find the outbound interface
-// used to forward the packets.
-
-// prepare vertex w
-          w = new SPFVertex (w_lsa);
-          if (SPFNexthopCalculation (v, w, l, distance))
-            {
-              w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
-//
-// Push this new vertex onto the priority queue (ordered by distance from the
-// root node).
-//
-              candidate.Push (w);
-              NS_LOG_LOGIC ("Pushing " << 
-                w->GetVertexId () << ", parent vertexId: " << 
-                v->GetVertexId () << ", distance: " <<
-                w->GetDistanceFromRoot ());
-            }
-          else
-            NS_ASSERT_MSG (0, "SPFNexthopCalculation never " 
-              << "return false, but it does now!");
-        }
-      else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
-        {
-//
-// We have already considered the link represented by <w>.  What wse have to
-// do now is to decide if this new router represents a route with a shorter
-// distance metric.
-//
-// So, locate the vertex in the candidate queue and take a look at the 
-// distance.
-
-/* (quagga-0.98.6) W is already on the candidate list; call it cw.
-* Compare the previously calculated cost (cw->distance)
-* with the cost we just determined (w->distance) to see
-* if we've found a shorter path.
-*/
-          SPFVertex* cw;
-          cw = candidate.Find (w_lsa->GetLinkStateId ());
-          if (cw->GetDistanceFromRoot () < distance)
-            {
-//
-// This is not a shorter path, so don't do anything.
-//
-              continue;
-            }
-          else if (cw->GetDistanceFromRoot () == distance)
-            {
-//
-// This path is one with an equal cost.  
-//
-              NS_LOG_LOGIC ("Equal cost multiple paths found.");
-
-// At this point, there are two instances 'w' and 'cw' of the
-// same vertex, the vertex that is currently being considered
-// for adding into the shortest path tree. 'w' is the instance
-// as seen from the root via vertex 'v', and 'cw' is the instance 
-// as seen from the root via some other vertices other than 'v'.
-// These two instances are being merged in the following code.
-// In particular, the parent nodes, the next hops, and the root's
-// output interfaces of the two instances are being merged.
-// 
-// Note that this is functionally equivalent to calling
-// ospf_nexthop_merge (cw->nexthop, w->nexthop) in quagga-0.98.6
-// (ospf_spf.c::859), although the detail implementation
-// is very different from quagga (blame ns3::GlobalRouteManagerImpl)
-
-// prepare vertex w
-              w = new SPFVertex (w_lsa);
-              SPFNexthopCalculation (v, w, l, distance);
-              cw->MergeRootExitDirections (w);
-              cw->MergeParent (w);
-// SPFVertexAddParent (w) is necessary as the destructor of 
-// SPFVertex checks if the vertex and its parent is linked
-// bidirectionally
-              SPFVertexAddParent (w);
-              delete w;
-            }
-          else // cw->GetDistanceFromRoot () > w->GetDistanceFromRoot ()
-            {
-// 
-// this path represents a new, lower-cost path to <w> (the vertex we found in
-// the current link record of the link state advertisement of the current root
-// (vertex <v>)
-//
-// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
-// it will call spf_add_parents, which will flush the old parents
-//
-              if (SPFNexthopCalculation (v, cw, l, distance))
-                {
-//
-// If we've changed the cost to get to the vertex represented by <w>, we 
-// must reorder the priority queue keyed to that cost.
-//
-                  candidate.Reorder ();
-                }
-            } // new lower cost path found  
-        } // end W is already on the candidate list
-    } // end loop over the links in V's LSA
-}
-
-//
-// This method is derived from quagga ospf_nexthop_calculation() 16.1.1.  
-//
-// Calculate nexthop from root through V (parent) to vertex W (destination)
-// with given distance from root->W.
-//
-// As appropriate, set w's parent, distance, and nexthop information
-//
-// For now, this is greatly simplified from the quagga code
-//                  
-  int
-GlobalRouteManagerImpl::SPFNexthopCalculation (
-  SPFVertex* v, 
-  SPFVertex* w,
-  GlobalRoutingLinkRecord* l,
-  uint32_t distance)
-{
-  NS_LOG_FUNCTION (v << w << l << distance);
-//
-// If w is a NetworkVertex, l should be null
-/*
-  if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
-    {
-        NS_ASSERT_MSG (0, "Error:  SPFNexthopCalculation parameter problem");
-    }
-*/
-
-//
-// The vertex m_spfroot is a distinguished vertex representing the node at
-// the root of the calculations.  That is, it is the node for which we are
-// calculating the routes.
-//
-// There are two distinct cases for calculating the next hop information.
-// First, if we're considering a hop from the root to an "adjacent" network
-// (one that is on the other side of a point-to-point link connected to the
-// root), then we need to store the information needed to forward down that
-// link.  The second case is if the network is not directly adjacent.  In that
-// case we need to use the forwarding information from the vertex on the path
-// to the destination that is directly adjacent [node 1] in both cases of the
-// diagram below.
-// 
-// (1) [root] -> [point-to-point] -> [node 1]
-// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2]
-//
-// We call the propagation of next hop information down vertices of a path
-// "inheriting" the next hop information.
-//
-// The point-to-point link information is only useful in this calculation when
-// we are examining the root node. 
-//
-  if (v == m_spfroot)
-    {
-//
-// In this case <v> is the root node, which means it is the starting point
-// for the packets forwarded by that node.  This also means that the next hop
-// address of packets headed for some arbitrary off-network destination must
-// be the destination at the other end of one of the links off of the root
-// node if this root node is a router.  We then need to see if this node <w>
-// is a router.
-//
-      if (w->GetVertexType () == SPFVertex::VertexRouter) 
-        {
-//
-// In the case of point-to-point links, the link data field (m_linkData) of a
-// Global Router Link Record contains the local IP address.  If we look at the
-// link record describing the link from the perspecive of <w> (the remote
-// node from the viewpoint of <v>) back to the root node, we can discover the
-// IP address of the router to which <v> is adjacent.  This is a distinguished
-// address -- the next hop address to get from <v> to <w> and all networks 
-// accessed through that path.
-//
-// SPFGetNextLink () is a little odd.  used in this way it is just going to
-// return the link record describing the link from <w> to <v>.  Think of it as
-// SPFGetLink.
-//
-          NS_ASSERT (l);
-          GlobalRoutingLinkRecord *linkRemote = 0;
-          linkRemote = SPFGetNextLink (w, v, linkRemote);
-// 
-// At this point, <l> is the Global Router Link Record describing the point-
-// to point link from <v> to <w> from the perspective of <v>; and <linkRemote>
-// is the Global Router Link Record describing that same link from the 
-// perspective of <w> (back to <v>).  Now we can just copy the next hop 
-// address from the m_linkData member variable.
-// 
-// The next hop member variable we put in <w> has the sense "in order to get
-// from the root node to the host represented by vertex <w>, you have to send
-// the packet to the next hop address specified in w->m_nextHop.
-//
-          Ipv4Address nextHop = linkRemote->GetLinkData ();
-// 
-// Now find the outgoing interface corresponding to the point to point link
-// from the perspective of <v> -- remember that <l> is the link "from"
-// <v> "to" <w>.
-//
-          uint32_t outIf = FindOutgoingInterfaceId (l->GetLinkData ());
-
-          w->SetRootExitDirection (nextHop, outIf);
-          w->SetDistanceFromRoot (distance);
-          w->SetParent (v);
-          NS_LOG_LOGIC ("Next hop from " << 
-            v->GetVertexId () << " to " << w->GetVertexId () << 
-            " goes through next hop " << nextHop <<
-            " via outgoing interface " << outIf <<
-            " with distance " << distance);
-        }  // end W is a router vertes
-      else 
-        {
-          NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
-// W is a directly connected network; no next hop is required
-          GlobalRoutingLSA* w_lsa = w->GetLSA ();
-          NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
-// Find outgoing interface ID for this network
-          uint32_t outIf = FindOutgoingInterfaceId (w_lsa->GetLinkStateId (), 
-            w_lsa->GetNetworkLSANetworkMask () );
-// Set the next hop to 0.0.0.0 meaning "not exist"
-          Ipv4Address nextHop = Ipv4Address::GetZero ();
-          w->SetRootExitDirection (nextHop, outIf);
-          w->SetDistanceFromRoot (distance);
-          w->SetParent (v);
-          NS_LOG_LOGIC ("Next hop from " << 
-            v->GetVertexId () << " to network " << w->GetVertexId () << 
-            " via outgoing interface " << outIf <<
-            " with distance " << distance);
-          return 1;
-        }
-    } // end v is the root
-  else if (v->GetVertexType () == SPFVertex::VertexNetwork) 
-    {
-// See if any of v's parents are the root
-      if (v->GetParent () == m_spfroot)
-        {
-// 16.1.1 para 5. ...the parent vertex is a network that
-// directly connects the calculating router to the destination
-// router.  The list of next hops is then determined by
-// examining the destination's router-LSA...
-          NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
-          GlobalRoutingLinkRecord *linkRemote = 0;
-          while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
-            {
-/* ...For each link in the router-LSA that points back to the
- * parent network, the link's Link Data field provides the IP
- * address of a next hop router.  The outgoing interface to
- * use can then be derived from the next hop IP address (or 
- * it can be inherited from the parent network).
- */
-                Ipv4Address nextHop = linkRemote->GetLinkData ();
-                uint32_t outIf = v->GetRootExitDirection ().second;
-                w->SetRootExitDirection (nextHop, outIf);
-                NS_LOG_LOGIC ("Next hop from " << 
-                  v->GetVertexId () << " to " << w->GetVertexId () << 
-                  " goes through next hop " << nextHop <<
-                  " via outgoing interface " << outIf);
-            }
-        }
-      else 
-        {
-          w->SetRootExitDirection (v->GetRootExitDirection ());
-        }
-    }
-  else 
-    {
-//
-// If we're calculating the next hop information from a node (v) that is 
-// *not* the root, then we need to "inherit" the information needed to
-// forward the packet from the vertex closer to the root.  That is, we'll
-// still send packets to the next hop address of the router adjacent to the
-// root on the path toward <w>.
-//
-// Above, when we were considering the root node, we calculated the next hop
-// address and outgoing interface required to get off of the root network.  
-// At this point, we are further away from the root network along one of the
-// (shortest) paths.  So the next hop and outoing interface remain the same
-// (are inherited).
-//
-      w->InheritAllRootExitDirections (v);
-    }
-//
-// In all cases, we need valid values for the distance metric and a parent.
-//
-  w->SetDistanceFromRoot (distance);
-  w->SetParent (v);
-
-  return 1;
-}
-
-//
-// This method is derived from quagga ospf_get_next_link ()
-//
-// First search the Global Router Link Records of vertex <v> for one
-// representing a point-to point link to vertex <w>.
-//
-// What is done depends on prev_link.  Contrary to appearances, prev_link just
-// acts as a flag here.  If prev_link is NULL, we return the first Global
-// Router Link Record we find that describes a point-to-point link from <v> 
-// to <w>.  If prev_link is not NULL, we return a Global Router Link Record
-// representing a possible *second* link from <v> to <w>.
-//
-  GlobalRoutingLinkRecord* 
-GlobalRouteManagerImpl::SPFGetNextLink (
-  SPFVertex* v,
-  SPFVertex* w,
-  GlobalRoutingLinkRecord* prev_link) 
-{
-  NS_LOG_FUNCTION (v << w << prev_link);
-
-  bool skip = true;
-  bool found_prev_link = false;
-  GlobalRoutingLinkRecord* l;
-//
-// If prev_link is 0, we are really looking for the first link, not the next 
-// link.
-//
-  if (prev_link == 0)
-    {
-      skip = false;
-      found_prev_link = true;
-    }
-//  
-// Iterate through the Global Router Link Records advertised by the vertex
-// <v> looking for records representing the point-to-point links off of this
-// vertex.
-//
-  for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
-    {
-      l = v->GetLSA ()->GetLinkRecord (i);
-//
-// The link ID of a link record representing a point-to-point link is set to
-// the router ID of the neighboring router -- the router to which the link
-// connects from the perspective of <v> in this case.  The vertex ID is also
-// set to the router ID (using the link state advertisement of a router node).
-// We're just checking to see if the link <l> is actually the link from <v> to
-// <w>.
-//
-      if (l->GetLinkId () == w->GetVertexId ()) 
-        {
-          if (!found_prev_link)
-            {
-              NS_LOG_LOGIC ("Skipping links before prev_link found");
-              found_prev_link = true;
-              continue;
-            }
-        
-          NS_LOG_LOGIC ("Found matching link l:  linkId = " <<
-          l->GetLinkId () << " linkData = " << l->GetLinkData ());
-//
-// If skip is false, don't (not too surprisingly) skip the link found -- it's 
-// the one we're interested in.  That's either because we didn't pass in a 
-// previous link, and we're interested in the first one, or because we've 
-// skipped a previous link and moved forward to the next (which is then the
-// one we want).
-//
-        if (skip == false) 
-          {
-            NS_LOG_LOGIC ("Returning the found link");
-            return l;
-          }
-        else
-          {
-//
-// Skip is true and we've found a link from <v> to <w>.  We want the next one.
-// Setting skip to false gets us the next point-to-point global router link
-// record in the LSA from <v>.
-//
-            NS_LOG_LOGIC ("Skipping the found link");
-            skip = false;
-            continue;
-          }
-      }
-    }
-  return 0;
-}
-  
-//
-// Used for unit tests.
-//
-  void
-GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root)
-{
-  NS_LOG_FUNCTION (root);
-  SPFCalculate (root);
-}
-
-//
-// Used to test if a node is a stub, from an OSPF sense.
-// If there is only one link of type 1 or 2, then a default route
-// can safely be added to the next-hop router and SPF does not need
-// to be run
-//
-bool
-GlobalRouteManagerImpl::CheckForStubNode (Ipv4Address root)
-{
-  NS_LOG_FUNCTION (root);
-  GlobalRoutingLSA *rlsa = m_lsdb->GetLSA (root);
-  Ipv4Address myRouterId = rlsa->GetLinkStateId ();
-  int transits = 0;
-  GlobalRoutingLinkRecord *transitLink = 0;
-  for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
-    {
-      GlobalRoutingLinkRecord *l = rlsa->GetLinkRecord (i);
-      if (l->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
-        {
-          transits++;
-          transitLink = l;
-        }
-      else if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
-        {
-          transits++;
-          transitLink = l;
-        }
-    }
-  if (transits == 0)
-    {
-      // This router is not connected to any router.  Probably, global
-      // routing should not be called for this node, but we can just raise
-      // a warning here and return true.
-      NS_LOG_WARN ("all nodes should have at least one transit link:" << root );
-      return true;
-    }
-  if (transits == 1)
-    {
-      if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
-        {
-          // Install default route to next hop router
-          // What is the next hop?  We need to check all neighbors on the link.
-          // If there is a single router that has two transit links, then
-          // that is the default next hop.  If there are more than one
-          // routers on link with multiple transit links, return false.
-          // Not yet implemented, so simply return false
-          NS_LOG_LOGIC ("TBD: Would have inserted default for transit");
-          return false;
-        }
-      else if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
-        {
-          // Install default route to next hop
-          // The link record LinkID is the router ID of the peer.
-          // The Link Data is the local IP interface address
-          GlobalRoutingLSA *w_lsa = m_lsdb->GetLSA (transitLink->GetLinkId ());
-          uint32_t nLinkRecords = w_lsa->GetNLinkRecords ();
-          for (uint32_t j = 0; j < nLinkRecords; ++j)
-            {
-              //
-              // We are only concerned about point-to-point links
-              //
-              GlobalRoutingLinkRecord *lr = w_lsa->GetLinkRecord (j);
-              if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
-                {
-                  continue;
-                }
-              // Find the link record that corresponds to our routerId
-              if (lr->GetLinkId () == myRouterId)
-                {
-                  // Next hop is stored in the LinkID field of lr
-                  Ptr<GlobalRouter> router = rlsa->GetNode ()->GetObject<GlobalRouter> ();
-                  NS_ASSERT (router);
-                  Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
-                  NS_ASSERT (gr);
-                  gr->AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask ("0.0.0.0"), lr->GetLinkData (), 
-                                         FindOutgoingInterfaceId (transitLink->GetLinkData ()));
-                  NS_LOG_LOGIC ("Inserting default route for node " << myRouterId << " to next hop " << 
-                                lr->GetLinkData () << " via interface " << 
-                                FindOutgoingInterfaceId(transitLink->GetLinkData()));
-                  return true;
-                }
-            }
-        }
-    }
-  return false;
-}
-
-// quagga ospf_spf_calculate
-  void
-GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
-{
-  NS_LOG_FUNCTION (this << root);
-
-  SPFVertex *v;
-//
-// Initialize the Link State Database.
-//
-  m_lsdb->Initialize ();
-//
-// The candidate queue is a priority queue of SPFVertex objects, with the top
-// of the queue being the closest vertex in terms of distance from the root
-// of the tree.  Initially, this queue is empty.
-//
-  CandidateQueue candidate;
-  NS_ASSERT (candidate.Size () == 0);
-//
-// Initialize the shortest-path tree to only contain the router doing the 
-// calculation.  Each router (and corresponding network) is a vertex in the
-// shortest path first (SPF) tree.
-//
-  v = new SPFVertex (m_lsdb->GetLSA (root));
-// 
-// This vertex is the root of the SPF tree and it is distance 0 from the root.
-// We also mark this vertex as being in the SPF tree.
-//
-  m_spfroot= v;
-  v->SetDistanceFromRoot (0);
-  v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
-  NS_LOG_LOGIC ("Starting SPFCalculate for node " << root);
-
-//
-// Optimize SPF calculation, for ns-3.
-// We do not need to calculate SPF for every node in the network if this
-// node has only one interface through which another router can be 
-// reached.  Instead, short-circuit this computation and just install
-// a default route in the CheckForStubNode() method.
-//
-  if (NodeList::GetNNodes () > 0 && CheckForStubNode (root))
-    {
-      NS_LOG_LOGIC ("SPFCalculate truncated for stub node " << root);
-      delete m_spfroot;
-      return;
-    }
-
-  for (;;)
-    {
-//
-// The operations we need to do are given in the OSPF RFC which we reference
-// as we go along.
-//
-// RFC2328 16.1. (2). 
-//
-// We examine the Global Router Link Records in the Link State 
-// Advertisements of the current vertex.  If there are any point-to-point
-// links to unexplored adjacent vertices we add them to the tree and update
-// the distance and next hop information on how to get there.  We also add
-// the new vertices to the candidate queue (the priority queue ordered by
-// shortest path).  If the new vertices represent shorter paths, we use them
-// and update the path cost.
-//
-      SPFNext (v, candidate);
-//
-// RFC2328 16.1. (3). 
-//
-// If at this step the candidate list is empty, the shortest-path tree (of
-// transit vertices) has been completely built and this stage of the
-// procedure terminates. 
-//
-      if (candidate.Size () == 0)
-        {
-          break;
-        }
-//
-// Choose the vertex belonging to the candidate list that is closest to the
-// root, and add it to the shortest-path tree (removing it from the candidate
-// list in the process).
-//
-// Recall that in the previous step, we created SPFVertex structures for each
-// of the routers found in the Global Router Link Records and added tehm to 
-// the candidate list.
-//
-      NS_LOG_LOGIC (candidate);
-      v = candidate.Pop ();
-      NS_LOG_LOGIC ("Popped vertex " << v->GetVertexId ());
-//
-// Update the status field of the vertex to indicate that it is in the SPF
-// tree.
-//
-      v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
-//
-// The current vertex has a parent pointer.  By calling this rather oddly 
-// named method (blame quagga) we add the current vertex to the list of 
-// children of that parent vertex.  In the next hop calculation called during
-// SPFNext, the parent pointer was set but the vertex has been orphaned up
-// to now.
-//
-      SPFVertexAddParent (v);
-//
-// Note that when there is a choice of vertices closest to the root, network
-// vertices must be chosen before router vertices in order to necessarily
-// find all equal-cost paths. 
-//
-// RFC2328 16.1. (4). 
-//
-// This is the method that actually adds the routes.  It'll walk the list
-// of nodes in the system, looking for the node corresponding to the router
-// ID of the root of the tree -- that is the router we're building the routes
-// for.  It looks for the Ipv4 interface of that node and remembers it.  So
-// we are only actually adding routes to that one node at the root of the SPF 
-// tree.
-//
-// We're going to pop of a pointer to every vertex in the tree except the 
-// root in order of distance from the root.  For each of the vertices, we call
-// SPFIntraAddRouter ().  Down in SPFIntraAddRouter, we look at all of the 
-// point-to-point Global Router Link Records (the links to nodes adjacent to
-// the node represented by the vertex).  We add a route to the IP address 
-// specified by the m_linkData field of each of those link records.  This will
-// be the *local* IP address associated with the interface attached to the 
-// link.  We use the outbound interface and next hop information present in 
-// the vertex <v> which have possibly been inherited from the root.
-//
-// To summarize, we're going to look at the node represented by <v> and loop
-// through its point-to-point links, adding a *host* route to the local IP
-// address (at the <v> side) for each of those links.
-//
-      if (v->GetVertexType () == SPFVertex::VertexRouter)
-        {
-          SPFIntraAddRouter (v);
-        }
-      else if (v->GetVertexType () == SPFVertex::VertexNetwork)
-        {
-          SPFIntraAddTransit (v);
-        }
-      else
-        {
-          NS_ASSERT_MSG (0, "illegal SPFVertex type");
-        }
-//
-// RFC2328 16.1. (5). 
-//
-// Iterate the algorithm by returning to Step 2 until there are no more
-// candidate vertices.
-
-    }  // end for loop
-
-// Second stage of SPF calculation procedure  
-  SPFProcessStubs (m_spfroot);
-  for (uint32_t i = 0; i < m_lsdb->GetNumExtLSAs (); i++)
-    {
-      m_spfroot->ClearVertexProcessed ();
-      GlobalRoutingLSA *extlsa = m_lsdb->GetExtLSA (i);
-      NS_LOG_LOGIC ("Processing External LSA with id " << extlsa->GetLinkStateId ());
-      ProcessASExternals (m_spfroot, extlsa);
-    }
-
-//
-// We're all done setting the routing information for the node at the root of
-// the SPF tree.  Delete all of the vertices and corresponding resources.  Go
-// possibly do it again for the next router.
-//
-  delete m_spfroot;
-  m_spfroot = 0;
-}
-
-void
-GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC ("Processing external for destination " << 
-      extlsa->GetLinkStateId () <<
-      ", for router "  << v->GetVertexId () << 
-      ", advertised by " << extlsa->GetAdvertisingRouter ());
-  if (v->GetVertexType () == SPFVertex::VertexRouter)
-    {
-      GlobalRoutingLSA *rlsa = v->GetLSA ();
-      NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
-      if ((rlsa->GetLinkStateId ()) == (extlsa->GetAdvertisingRouter ()))
-        {
-          NS_LOG_LOGIC ("Found advertising router to destination");
-          SPFAddASExternal(extlsa,v);
-        }
-    }
-  for (uint32_t i = 0; i < v->GetNChildren (); i++)
-    {
-      if (!v->GetChild (i)->IsVertexProcessed ())
-        {
-          NS_LOG_LOGIC ("Vertex's child " << i << " not yet processed, processing...");
-          ProcessASExternals (v->GetChild (i), extlsa);
-          v->GetChild (i)->SetVertexProcessed (true);
-        }
-    }
-}
-
-//
-// Adding external routes to routing table - modeled after
-// SPFAddIntraAddStub()
-//
-
-void
-GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set");
-// Two cases to consider: We are advertising the external ourselves
-// => No need to add anything
-// OR find best path to the advertising router
-  if (v->GetVertexId () == m_spfroot->GetVertexId ())
-    {
-      NS_LOG_LOGIC ("External is on local host: " 
-        << v->GetVertexId () << "; returning");
-      return;
-    }
-  NS_LOG_LOGIC ("External is on remote host: " 
-    << extlsa->GetAdvertisingRouter () << "; installing");
-  
-  Ipv4Address routerId = m_spfroot->GetVertexId ();
-
-  NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex.  This is the one we're going to write
-// the routing information to.
-//
-  NodeList::Iterator i = NodeList::Begin (); 
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (; i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to QI for that interface.  If there's no GlobalRouter interface, the node
-// in question cannot be the router we want, so we continue.
-// 
-      Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
-
-      if (rtr == 0)
-        {
-          NS_LOG_LOGIC ("No GlobalRouter interface on node " << node->GetId ());
-          continue;
-        }
-//
-// If the router ID of the current node is equal to the router ID of the 
-// root of the SPF tree, then this node is the one for which we need to 
-// write the routing tables.
-//
-      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
-      if (rtr->GetRouterId () == routerId)
-        {
-          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface.  We need to QI
-// for that interface.  If the node is acting as an IP version 4 router, it
-// should absolutely have an Ipv4 interface.
-//
-          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-          NS_ASSERT_MSG (ipv4, 
-                     "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
-                         "QI for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to.  The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node.  We're going
-// to be interested in the records corresponding to point-to-point links.
-//
-          NS_ASSERT_MSG (v->GetLSA (), 
-                     "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
-                         "Expected valid LSA in SPFVertex* v");
-          Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask ();
-          Ipv4Address tempip = extlsa->GetLinkStateId ();
-          tempip = tempip.CombineMask (tempmask);
-
-//
-// Here's why we did all of that work.  We're going to add a host route to the
-// host address found in the m_linkData field of the point-to-point link
-// record.  In the case of a point-to-point link, this is the local IP address
-// of the node connected to the link.  Each of these point-to-point links
-// will correspond to a local interface that has an IP address to which
-// the node at the root of the SPF tree can send packets.  The vertex <v> 
-// (corresponding to the node that has these links and interfaces) has 
-// an m_nextHop address precalculated for us that is the address to which the
-// root node should send packets to be forwarded to these IP addresses.
-// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
-// which the packets should be send for forwarding.
-//
-          Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
-          if (router == 0)
-            {
-              continue;
-            }
-          Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
-          NS_ASSERT (gr);
-          // walk through all next-hop-IPs and out-going-interfaces for reaching
-          // the stub network gateway 'v' from the root node
-          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
-            {
-              SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
-              Ipv4Address nextHop = exit.first;
-              int32_t outIf = exit.second;
-              if (outIf >= 0)
-                {
-                  gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf);
-                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                    " add external network route to " << tempip <<
-                    " using next hop " << nextHop <<
-                    " via interface " << outIf);
-                }
-              else
-                {
-                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                    " NOT able to add network route to " << tempip <<
-                    " using next hop " << nextHop <<
-                    " since outgoing interface id is negative");
-                }
-            }
-          return;
-        } // if
-    } // for
-}
-
-
-// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
-// stub link records will exist for point-to-point interfaces and for
-// broadcast interfaces for which no neighboring router can be found
-void
-GlobalRouteManagerImpl::SPFProcessStubs (SPFVertex* v)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC ("Processing stubs for " << v->GetVertexId ());
-  if (v->GetVertexType () == SPFVertex::VertexRouter)
-    {
-      GlobalRoutingLSA *rlsa = v->GetLSA ();
-      NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
-      for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
-        {
-          NS_LOG_LOGIC ("Examining link " << i << " of " << 
-            v->GetVertexId () << "'s " <<
-            v->GetLSA ()->GetNLinkRecords () << " link records");
-          GlobalRoutingLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
-          if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
-            {
-              NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
-              SPFIntraAddStub (l, v);
-              continue;
-            }
-        }
-    }
-    for (uint32_t i = 0; i < v->GetNChildren (); i++)
-      {
-        if (!v->GetChild (i)->IsVertexProcessed ())
-          {
-            SPFProcessStubs (v->GetChild (i));
-            v->GetChild (i)->SetVertexProcessed (true);
-          }
-      }
-}
-
-// RFC2328 16.1. second stage. 
-void
-GlobalRouteManagerImpl::SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  NS_ASSERT_MSG (m_spfroot, 
-    "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set");
-
-  // XXX simplifed logic for the moment.  There are two cases to consider:
-  // 1) the stub network is on this router; do nothing for now
-  //    (already handled above)
-  // 2) the stub network is on a remote router, so I should use the
-  // same next hop that I use to get to vertex v
-  if (v->GetVertexId () == m_spfroot->GetVertexId ())
-    {
-      NS_LOG_LOGIC ("Stub is on local host: " << v->GetVertexId () << "; returning");
-      return;
-    }
-      NS_LOG_LOGIC ("Stub is on remote host: " << v->GetVertexId () << "; installing");
-//
-// The root of the Shortest Path First tree is the router to which we are 
-// going to write the actual routing table entries.  The vertex corresponding
-// to this router has a vertex ID which is the router ID of that node.  We're
-// going to use this ID to discover which node it is that we're actually going
-// to update.
-//
-  Ipv4Address routerId = m_spfroot->GetVertexId ();
-
-  NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex.  This is the one we're going to write
-// the routing information to.
-//
-  NodeList::Iterator i = NodeList::Begin (); 
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (; i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to QI for that interface.  If there's no GlobalRouter interface, the node
-// in question cannot be the router we want, so we continue.
-// 
-      Ptr<GlobalRouter> rtr = 
-        node->GetObject<GlobalRouter> ();
-
-      if (rtr == 0)
-        {
-          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
-            node->GetId ());
-          continue;
-        }
-//
-// If the router ID of the current node is equal to the router ID of the 
-// root of the SPF tree, then this node is the one for which we need to 
-// write the routing tables.
-//
-      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
-      if (rtr->GetRouterId () == routerId)
-        {
-          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface.  We need to QI
-// for that interface.  If the node is acting as an IP version 4 router, it
-// should absolutely have an Ipv4 interface.
-//
-          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-          NS_ASSERT_MSG (ipv4, 
-            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
-            "QI for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to.  The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node.  We're going
-// to be interested in the records corresponding to point-to-point links.
-//
-          NS_ASSERT_MSG (v->GetLSA (), 
-            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
-            "Expected valid LSA in SPFVertex* v");
-          Ipv4Mask tempmask (l->GetLinkData ().Get ());
-          Ipv4Address tempip = l->GetLinkId ();
-          tempip = tempip.CombineMask (tempmask);
-//
-// Here's why we did all of that work.  We're going to add a host route to the
-// host address found in the m_linkData field of the point-to-point link
-// record.  In the case of a point-to-point link, this is the local IP address
-// of the node connected to the link.  Each of these point-to-point links
-// will correspond to a local interface that has an IP address to which
-// the node at the root of the SPF tree can send packets.  The vertex <v> 
-// (corresponding to the node that has these links and interfaces) has 
-// an m_nextHop address precalculated for us that is the address to which the
-// root node should send packets to be forwarded to these IP addresses.
-// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
-// which the packets should be send for forwarding.
-//
-          
-          Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
-          if (router == 0)
-            {
-              continue;
-            }
-          Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
-          NS_ASSERT (gr);
-          // walk through all next-hop-IPs and out-going-interfaces for reaching
-          // the stub network gateway 'v' from the root node
-          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
-            {
-              SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
-              Ipv4Address nextHop = exit.first;
-              int32_t outIf = exit.second;
-              if (outIf >= 0)
-                {
-                  gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
-                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                    " add network route to " << tempip <<
-                    " using next hop " << nextHop <<
-                    " via interface " << outIf);
-                }
-              else
-                {
-                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                    " NOT able to add network route to " << tempip <<
-                    " using next hop " << nextHop <<
-                    " since outgoing interface id is negative");
-                }
-            }
-          return;
-        } // if
-    } // for
-}
-
-//
-// Return the interface number corresponding to a given IP address and mask
-// This is a wrapper around GetInterfaceForPrefix(), but we first
-// have to find the right node pointer to pass to that function.
-// If no such interface is found, return -1 (note:  unit test framework
-// for routing assumes -1 to be a legal return value)
-//
-int32_t
-GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
-{
-  NS_LOG_FUNCTION (a << amask);
-//
-// We have an IP address <a> and a vertex ID of the root of the SPF tree.  
-// The question is what interface index does this address correspond to.
-// The answer is a little complicated since we have to find a pointer to
-// the node corresponding to the vertex ID, find the Ipv4 interface on that
-// node in order to iterate the interfaces and find the one corresponding to
-// the address in question.
-//
-  Ipv4Address routerId = m_spfroot->GetVertexId ();
-//
-// Walk the list of nodes in the system looking for the one corresponding to
-// the node at the root of the SPF tree.  This is the node for which we are
-// building the routing table.
-//
-  NodeList::Iterator i = NodeList::Begin (); 
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (; i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-
-      Ptr<GlobalRouter> rtr = 
-        node->GetObject<GlobalRouter> ();
-//
-// If the node doesn't have a GlobalRouter interface it can't be the one
-// we're interested in.
-//
-      if (rtr == 0)
-        {
-          continue;
-        }
-
-      if (rtr->GetRouterId () == routerId)
-        {
-//
-// This is the node we're building the routing table for.  We're going to need
-// the Ipv4 interface to look for the ipv4 interface index.  Since this node
-// is participating in routing IP version 4 packets, it certainly must have 
-// an Ipv4 interface.
-//
-          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-          NS_ASSERT_MSG (ipv4, 
-            "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
-            "GetObject for <Ipv4> interface failed");
-//
-// Look through the interfaces on this node for one that has the IP address
-// we're looking for.  If we find one, return the corresponding interface
-// index, or -1 if not found.
-//
-          int32_t interface = ipv4->GetInterfaceForPrefix (a, amask);
-
-#if 0
-          if (interface < 0)
-            {
-              NS_FATAL_ERROR ("GlobalRouteManagerImpl::FindOutgoingInterfaceId(): "
-                "Expected an interface associated with address a:" << a);
-            }
-#endif 
-          return interface;
-        }
-    }
-//
-// Couldn't find it.
-//
-  NS_LOG_LOGIC ("FindOutgoingInterfaceId():Can't find root node " << routerId);
-  return -1;
-}
-
-//
-// This method is derived from quagga ospf_intra_add_router ()
-//
-// This is where we are actually going to add the host routes to the routing
-// tables of the individual nodes.
-//
-// The vertex passed as a parameter has just been added to the SPF tree.
-// This vertex must have a valid m_root_oid, corresponding to the outgoing
-// interface on the root router of the tree that is the first hop on the path
-// to the vertex.  The vertex must also have a next hop address, corresponding
-// to the next hop on the path to the vertex.  The vertex has an m_lsa field
-// that has some number of link records.  For each point to point link record,
-// the m_linkData is the local IP address of the link.  This corresponds to
-// a destination IP address, reachable from the root, to which we add a host
-// route.
-//
-  void
-GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
-{
-  NS_LOG_FUNCTION (v);
-
-  NS_ASSERT_MSG (m_spfroot, 
-    "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set");
-//
-// The root of the Shortest Path First tree is the router to which we are 
-// going to write the actual routing table entries.  The vertex corresponding
-// to this router has a vertex ID which is the router ID of that node.  We're
-// going to use this ID to discover which node it is that we're actually going
-// to update.
-//
-  Ipv4Address routerId = m_spfroot->GetVertexId ();
-
-  NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex.  This is the one we're going to write
-// the routing information to.
-//
-  NodeList::Iterator i = NodeList::Begin (); 
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (; i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to GetObject for that interface.  If there's no GlobalRouter interface, 
-// the node in question cannot be the router we want, so we continue.
-// 
-      Ptr<GlobalRouter> rtr = 
-        node->GetObject<GlobalRouter> ();
-
-      if (rtr == 0)
-        {
-          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
-            node->GetId ());
-          continue;
-        }
-//
-// If the router ID of the current node is equal to the router ID of the 
-// root of the SPF tree, then this node is the one for which we need to 
-// write the routing tables.
-//
-      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
-      if (rtr->GetRouterId () == routerId)
-        {
-          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface.  We need to 
-// GetObject for that interface.  If the node is acting as an IP version 4 
-// router, it should absolutely have an Ipv4 interface.
-//
-          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-          NS_ASSERT_MSG (ipv4, 
-            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
-            "GetObject for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to.  The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node.  We're going
-// to be interested in the records corresponding to point-to-point links.
-//
-          GlobalRoutingLSA *lsa = v->GetLSA ();
-          NS_ASSERT_MSG (lsa, 
-            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
-            "Expected valid LSA in SPFVertex* v");
-
-          uint32_t nLinkRecords = lsa->GetNLinkRecords ();
-//
-// Iterate through the link records on the vertex to which we're going to add
-// routes.  To make sure we're being clear, we're going to add routing table
-// entries to the tables on the node corresping to the root of the SPF tree.
-// These entries will have routes to the IP addresses we find from looking at
-// the local side of the point-to-point links found on the node described by
-// the vertex <v>.
-//
-          NS_LOG_LOGIC (" Node " << node->GetId () <<
-             " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ());
-          for (uint32_t j = 0; j < nLinkRecords; ++j)
-            {
-//
-// We are only concerned about point-to-point links
-//
-              GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
-              if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
-                {
-                  continue;
-                }
-//
-// Here's why we did all of that work.  We're going to add a host route to the
-// host address found in the m_linkData field of the point-to-point link
-// record.  In the case of a point-to-point link, this is the local IP address
-// of the node connected to the link.  Each of these point-to-point links
-// will correspond to a local interface that has an IP address to which
-// the node at the root of the SPF tree can send packets.  The vertex <v> 
-// (corresponding to the node that has these links and interfaces) has 
-// an m_nextHop address precalculated for us that is the address to which the
-// root node should send packets to be forwarded to these IP addresses.
-// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
-// which the packets should be send for forwarding.
-//
-              Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
-              if (router == 0)
-                {
-                  continue;
-                }
-              Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
-              NS_ASSERT (gr);
-              // walk through all available exit directions due to ECMP,
-              // and add host route for each of the exit direction toward
-              // the vertex 'v'
-              for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
-              {
-                SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
-                Ipv4Address nextHop = exit.first;
-                int32_t outIf = exit.second;
-                if (outIf >= 0)
-                  {
-                    gr->AddHostRouteTo (lr->GetLinkData (), nextHop,
-                      outIf);
-                    NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                      " adding host route to " << lr->GetLinkData () <<
-                      " using next hop " << nextHop <<
-                      " and outgoing interface " << outIf);
-                  }
-                else
-                  {
-                    NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                      " NOT able to add host route to " << lr->GetLinkData () <<
-                      " using next hop " << nextHop <<
-                      " since outgoing interface id is negative " << outIf);
-                  }
-              } // for all routes from the root the vertex 'v'
-            }
-//
-// Done adding the routes for the selected node.
-//
-          return;
-        }
-    }
-}
-  void
-GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
-{
-  NS_LOG_FUNCTION (v);
-
-  NS_ASSERT_MSG (m_spfroot, 
-    "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
-//
-// The root of the Shortest Path First tree is the router to which we are 
-// going to write the actual routing table entries.  The vertex corresponding
-// to this router has a vertex ID which is the router ID of that node.  We're
-// going to use this ID to discover which node it is that we're actually going
-// to update.
-//
-  Ipv4Address routerId = m_spfroot->GetVertexId ();
-
-  NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex.  This is the one we're going to write
-// the routing information to.
-//
-  NodeList::Iterator i = NodeList::Begin (); 
-  NodeList::Iterator listEnd = NodeList::End ();
-  for (; i != listEnd; i++)
-    {
-      Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to GetObject for that interface.  If there's no GlobalRouter interface, 
-// the node in question cannot be the router we want, so we continue.
-// 
-      Ptr<GlobalRouter> rtr = 
-        node->GetObject<GlobalRouter> ();
-
-      if (rtr == 0)
-        {
-          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
-            node->GetId ());
-          continue;
-        }
-//
-// If the router ID of the current node is equal to the router ID of the 
-// root of the SPF tree, then this node is the one for which we need to 
-// write the routing tables.
-//
-      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
-      if (rtr->GetRouterId () == routerId)
-        {
-          NS_LOG_LOGIC ("setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface.  We need to 
-// GetObject for that interface.  If the node is acting as an IP version 4 
-// router, it should absolutely have an Ipv4 interface.
-//
-          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-          NS_ASSERT_MSG (ipv4, 
-            "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
-            "GetObject for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to.  The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node.  We're going
-// to be interested in the records corresponding to point-to-point links.
-//
-          GlobalRoutingLSA *lsa = v->GetLSA ();
-          NS_ASSERT_MSG (lsa, 
-            "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
-            "Expected valid LSA in SPFVertex* v");
-          Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
-          Ipv4Address tempip = lsa->GetLinkStateId ();
-          tempip = tempip.CombineMask (tempmask);
-          Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
-          if (router == 0)
-            {
-              continue;
-            }
-          Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
-          NS_ASSERT (gr);
-          // walk through all available exit directions due to ECMP,
-          // and add host route for each of the exit direction toward
-          // the vertex 'v'
-          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
-          {
-            SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
-            Ipv4Address nextHop = exit.first;
-            int32_t outIf = exit.second;
-
-            if (outIf >= 0)
-              {
-                gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
-                NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                  " add network route to " << tempip <<
-                  " using next hop " << nextHop <<
-                  " via interface " << outIf);
-              }
-            else
-              {
-                NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
-                  " NOT able to add network route to " << tempip <<
-                  " using next hop " << nextHop <<
-                  " since outgoing interface id is negative " << outIf);
-              }
-            }
-        }
-    } 
-}
-
-// Derived from quagga ospf_vertex_add_parents ()
-//
-// This is a somewhat oddly named method (blame quagga).  Although you might
-// expect it to add a parent *to* something, it actually adds a vertex
-// to the list of children *in* each of its parents. 
-//
-// Given a pointer to a vertex, it links back to the vertex's parent that it
-// already has set and adds itself to that vertex's list of children.
-//
-  void
-GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v)
-{
-  NS_LOG_FUNCTION (v);
-
-  for (uint32_t i=0;;)
-    {
-      SPFVertex* parent;
-      // check if all parents of vertex v
-      if ((parent = v->GetParent (i++)) == 0) break;
-      parent->AddChild (v);
-    }
-}
-
-} // namespace ns3
-
-
-#include "ns3/test.h"
-#include "ns3/simulator.h"
-#include <stdlib.h> // for rand()
-
-namespace ns3 {
-
-class GlobalRouteManagerImplTestCase : public TestCase
-{
-public:
-  GlobalRouteManagerImplTestCase();
-  virtual bool DoRun(void);
-};
-
-GlobalRouteManagerImplTestCase::GlobalRouteManagerImplTestCase()
-  : TestCase("GlobalRouteManagerImplTestCase")
-{}
-bool 
-GlobalRouteManagerImplTestCase::DoRun(void)
-{
-  CandidateQueue candidate;
-
-  for (int i = 0; i < 100; ++i)
-    {
-      SPFVertex *v = new SPFVertex;
-      v->SetDistanceFromRoot (rand () % 100);
-      candidate.Push (v);
-    }
-
-  uint32_t lastDistance = 0;
-
-  for (int i = 0; i < 100; ++i)
-    {
-      SPFVertex *v = candidate.Pop ();
-      if (v->GetDistanceFromRoot () < lastDistance)
-        {
-          // XXX does nothing.
-          UpdateErrorStatus (false);
-        }
-      lastDistance = v->GetDistanceFromRoot ();
-      delete v;
-      v = 0;
-    }
-
-  // Build fake link state database; four routers (0-3), 3 point-to-point
-  // links
-  //
-  //   n0
-  //      \ link 0
-  //       \          link 2
-  //        n2 -------------------------n3
-  //       /
-  //      / link 1
-  //    n1
-  //
-  //  link0:  10.1.1.1/30, 10.1.1.2/30
-  //  link1:  10.1.2.1/30, 10.1.2.2/30
-  //  link2:  10.1.3.1/30, 10.1.3.2/30
-  //
-  // Router 0
-  GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::PointToPoint, 
-    "0.0.0.2",  // router ID 0.0.0.2
-    "10.1.1.1", // local ID
-    1);         // metric
-
-  GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::StubNetwork,
-    "10.1.1.1",
-    "255.255.255.252",
-    1);
-
-  GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
-  lsa0->SetLSType (GlobalRoutingLSA::RouterLSA);
-  lsa0->SetLinkStateId ("0.0.0.0");
-  lsa0->SetAdvertisingRouter ("0.0.0.0");
-  lsa0->AddLinkRecord (lr0);
-  lsa0->AddLinkRecord (lr1);
-
-  // Router 1
-  GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::PointToPoint,
-    "0.0.0.2",
-    "10.1.2.1",
-    1);
-
-  GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::StubNetwork,
-    "10.1.2.1",
-    "255.255.255.252",
-    1);
-
-  GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
-  lsa1->SetLSType (GlobalRoutingLSA::RouterLSA);
-  lsa1->SetLinkStateId ("0.0.0.1");
-  lsa1->SetAdvertisingRouter ("0.0.0.1");
-  lsa1->AddLinkRecord (lr2);
-  lsa1->AddLinkRecord (lr3);
-  
-  // Router 2 
-  GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::PointToPoint,
-    "0.0.0.0",
-    "10.1.1.2",
-    1);
-
-  GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::StubNetwork,
-    "10.1.1.2",
-    "255.255.255.252",
-    1);
-
-  GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::PointToPoint,
-    "0.0.0.1",
-    "10.1.2.2",
-    1);
-
-  GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::StubNetwork,
-    "10.1.2.2",
-    "255.255.255.252",
-    1);
-
-  GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::PointToPoint,
-    "0.0.0.3",
-    "10.1.3.2",
-    1);
-
-  GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::StubNetwork,
-    "10.1.3.2",
-    "255.255.255.252",
-    1);
-
-  GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
-  lsa2->SetLSType (GlobalRoutingLSA::RouterLSA);
-  lsa2->SetLinkStateId ("0.0.0.2");
-  lsa2->SetAdvertisingRouter ("0.0.0.2");
-  lsa2->AddLinkRecord (lr4);
-  lsa2->AddLinkRecord (lr5);
-  lsa2->AddLinkRecord (lr6);
-  lsa2->AddLinkRecord (lr7);
-  lsa2->AddLinkRecord (lr8);
-  lsa2->AddLinkRecord (lr9);
-
-  // Router 3
-  GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::PointToPoint,
-    "0.0.0.2",
-    "10.1.2.1",
-    1);
-
-  GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
-    GlobalRoutingLinkRecord::StubNetwork,
-    "10.1.2.1",
-    "255.255.255.252",
-    1);
-
-  GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
-  lsa3->SetLSType (GlobalRoutingLSA::RouterLSA);
-  lsa3->SetLinkStateId ("0.0.0.3");
-  lsa3->SetAdvertisingRouter ("0.0.0.3");
-  lsa3->AddLinkRecord (lr10);
-  lsa3->AddLinkRecord (lr11);
-
-  // Test the database 
-  GlobalRouteManagerLSDB* srmlsdb = new GlobalRouteManagerLSDB ();
-  srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0);
-  srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1);
-  srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2);
-  srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3);
-  NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ()));
-
-  // next, calculate routes based on the manually created LSDB
-  GlobalRouteManagerImpl* srm = new GlobalRouteManagerImpl ();
-  srm->DebugUseLsdb (srmlsdb);  // manually add in an LSDB
-  // Note-- this will succeed without any nodes in the topology
-  // because the NodeList is empty
-  srm->DebugSPFCalculate (lsa0->GetLinkStateId ());  // node n0
-
-  Simulator::Run ();
-
-// XXX here we should do some verification of the routes built
-
-  Simulator::Destroy ();
-
-  // This delete clears the srm, which deletes the LSDB, which clears 
-  // all of the LSAs, which each destroys the attached LinkRecords.
-  delete srm;
-
-  // XXX
-  // No testing has actually been done other than making sure that this code
-  // does not crash
-  return GetErrorStatus ();
-}
-
-
-static class GlobalRouteManagerImplTestSuite : public TestSuite
-{
-public:
-  GlobalRouteManagerImplTestSuite()
-    : TestSuite("global-route-manager-impl", UNIT)
-  {
-    AddTestCase(new GlobalRouteManagerImplTestCase());
-  }
-} g_globalRoutingManagerImplTestSuite;
-
-} // namespace ns3
--- a/src/routing/global-routing/global-route-manager-impl.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,781 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * 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:  Craig Dowell (craigdo@ee.washington.edu)
- *           Tom Henderson (tomhend@u.washington.edu)
- */
-
-#ifndef GLOBAL_ROUTE_MANAGER_IMPL_H
-#define GLOBAL_ROUTE_MANAGER_IMPL_H
-
-#include <stdint.h>
-#include <list>
-#include <queue>
-#include <map>
-#include <vector>
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "global-router-interface.h"
-
-namespace ns3 {
-
-const uint32_t SPF_INFINITY = 0xffffffff;
-
-class CandidateQueue;
-class Ipv4GlobalRouting;
-
-/**
- * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328,
- * Section 16.
- *
- * Each router in the simulation is associated with an SPFVertex object.  When
- * calculating routes, each of these routers is, in turn, chosen as the "root"
- * of the calculation and routes to all of the other routers are eventually
- * saved in the routing tables of each of the chosen nodes.  Each of these 
- * routers in the calculation has an associated SPFVertex.
- *
- * The "Root" vertex is the SPFVertex representing the router that is having
- * its routing tables set.  The SPFVertex objects representing other routers
- * or networks in the simulation are arranged in the SPF tree.  It is this 
- * tree that represents the Shortest Paths to the other networks.
- *
- * Each SPFVertex has a pointer to the Global Router Link State Advertisement
- * (LSA) that its underlying router has exported.  Within these LSAs are
- * Global Router Link Records that describe the point to point links from the
- * underlying router to other nodes (represented by other SPFVertex objects)
- * in the simulation topology.  The combination of the arrangement of the 
- * SPFVertex objects in the SPF tree, along with the details of the link
- * records that connect them provide the information required to construct the
- * required routes.
- */
-class SPFVertex
-{
-public:
-/**
- * @brief Enumeration of the possible types of SPFVertex objects.
- * @internal
- *
- * Currently we use VertexRouter to identify objects that represent a router 
- * in the simulation topology, and VertexNetwork to identify objects that 
- * represent a network.
- */
-  enum VertexType {
-    VertexUnknown = 0,  /**< Uninitialized Link Record */
-    VertexRouter,       /**< Vertex representing a router in the topology */
-    VertexNetwork       /**< Vertex representing a network in the topology */
-  };
-
-/**
- * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First 
- * Vertex).
- * @internal
- *
- * The Vertex Type is set to VertexUnknown, the Vertex ID is set to 
- * 255.255.255.255, and the distance from root is set to infinity 
- * (UINT32_MAX).  The referenced Link State Advertisement (LSA) is set to 
- * null as is the parent SPFVertex.  The outgoing interface index is set to
- * infinity, the next hop address is set to 0.0.0.0 and the list of children
- * of the SPFVertex is initialized to empty.
- *
- * @see VertexType
- */
-  SPFVertex();
-
-/**
- * @brief Construct an initialized SPFVertex (Shortest Path First Vertex).
- * @internal
- *
- * The Vertex Type is initialized to VertexRouter and the Vertex ID is found
- * from the Link State ID of the Link State Advertisement (LSA) passed as a
- * parameter.  The Link State ID is set to the Router ID of the advertising
- * router.  The referenced LSA (m_lsa) is set to the given LSA.  Other than 
- * these members, initialization is as in the default constructor.
- * of the SPFVertex is initialized to empty.
- *
- * @see SPFVertex::SPFVertex ()
- * @see VertexType
- * @see GlobalRoutingLSA
- * @param lsa The Link State Advertisement used for finding initial values.
- */
-  SPFVertex(GlobalRoutingLSA* lsa);
-
-/**
- * @brief Destroy an SPFVertex (Shortest Path First Vertex).
- * @internal
- *
- * The children vertices of the SPFVertex are recursively deleted.
- *
- * @see SPFVertex::SPFVertex ()
- */
-  ~SPFVertex();
-
-/**
- * @brief Get the Vertex Type field of a SPFVertex object.
- * @internal
- *
- * The Vertex Type describes the kind of simulation object a given SPFVertex
- * represents.
- *
- * @see VertexType
- * @returns The VertexType of the current SPFVertex object.
- */
-  VertexType GetVertexType (void) const;
-
-/**
- * @brief Set the Vertex Type field of a SPFVertex object.
- * @internal
- *
- * The Vertex Type describes the kind of simulation object a given SPFVertex
- * represents.
- *
- * @see VertexType
- * @param type The new VertexType for the current SPFVertex object.
- */
-  void SetVertexType (VertexType type);
-
-/**
- * @brief Get the Vertex ID field of a SPFVertex object.
- * @internal
- *
- * The Vertex ID uniquely identifies the simulation object a given SPFVertex
- * represents.  Typically, this is the Router ID for SPFVertex objects 
- * representing routers, and comes from the Link State Advertisement of a 
- * router aggregated to a node in the simulation.  These IDs are allocated
- * automatically by the routing environment and look like IP addresses 
- * beginning at 0.0.0.0 and monotonically increasing as new routers are
- * instantiated.
- *
- * @returns The Ipv4Address Vertex ID of the current SPFVertex object.
- */
-  Ipv4Address GetVertexId (void) const;
-
-/**
- * @brief Set the Vertex ID field of a SPFVertex object.
- * @internal
- *
- * The Vertex ID uniquely identifies the simulation object a given SPFVertex
- * represents.  Typically, this is the Router ID for SPFVertex objects 
- * representing routers, and comes from the Link State Advertisement of a 
- * router aggregated to a node in the simulation.  These IDs are allocated
- * automatically by the routing environment and look like IP addresses 
- * beginning at 0.0.0.0 and monotonically increase as new routers are
- * instantiated.  This method is an explicit override of the automatically
- * generated value.
- *
- * @param id The new Ipv4Address Vertex ID for the current SPFVertex object.
- */
-  void SetVertexId (Ipv4Address id);
-
-/**
- * @brief Get the Global Router Link State Advertisement returned by the 
- * Global Router represented by this SPFVertex during the route discovery 
- * process.
- * @internal
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRouter::DiscoverLSAs ()
- * @returns A pointer to the GlobalRoutingLSA found by the router represented
- * by this SPFVertex object.
- */
-  GlobalRoutingLSA* GetLSA (void) const;
-
-/**
- * @brief Set the Global Router Link State Advertisement returned by the 
- * Global Router represented by this SPFVertex during the route discovery 
- * process.
- * @internal
- *
- * @see SPFVertex::GetLSA ()
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRouter::DiscoverLSAs ()
- * @warning Ownership of the LSA is transferred to the "this" SPFVertex.  You
- * must not delete the LSA after calling this method.
- * @param lsa A pointer to the GlobalRoutingLSA.
- */
-  void SetLSA (GlobalRoutingLSA* lsa);
-
-/**
- * @brief Get the distance from the root vertex to "this" SPFVertex object.
- * @internal
- *
- * Each router in the simulation is associated with an SPFVertex object.  When
- * calculating routes, each of these routers is, in turn, chosen as the "root"
- * of the calculation and routes to all of the other routers are eventually
- * saved in the routing tables of each of the chosen nodes.  Each of these 
- * routers in the calculation has an associated SPFVertex.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex to which
- * a route is being calculated from the root.  The distance from the root that
- * we're asking for is the number of hops from the root vertex to the vertex
- * in question.
- *
- * The distance is calculated during route discovery and is stored in a
- * member variable.  This method simply fetches that value.
- *
- * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex.
- */
-  uint32_t GetDistanceFromRoot (void) const;
-
-/**
- * @brief Set the distance from the root vertex to "this" SPFVertex object.
- * @internal
- *
- * Each router in the simulation is associated with an SPFVertex object.  When
- * calculating routes, each of these routers is, in turn, chosen as the "root"
- * of the calculation and routes to all of the other routers are eventually
- * saved in the routing tables of each of the chosen nodes.  Each of these 
- * routers in the calculation has an associated SPFVertex.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex to which
- * a route is being calculated from the root.  The distance from the root that
- * we're asking for is the number of hops from the root vertex to the vertex
- * in question.
- *
- * @param distance The distance, in hops, from the root SPFVertex to "this"
- * SPFVertex.
- */
-  void SetDistanceFromRoot (uint32_t distance);
-
-/**
- * @brief Set the IP address and outgoing interface index that should be used 
- * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from 
- * the root.  The IP address that we're asking for is the address on the 
- * remote side of a link off of the root node that should be used as the
- * destination for packets along the path to "this" vertex.
- *
- * When initializing the root SPFVertex, the IP address used when forwarding
- * packets is determined by examining the Global Router Link Records of the
- * Link State Advertisement generated by the root node's GlobalRouter.  This
- * address is used to forward packets off of the root's network down those
- * links.  As other vertices / nodes are discovered which are further away
- * from the root, they will be accessible down one of the paths via a link
- * described by one of these Global Router Link Records.
- * 
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to a first hop router down
- * an interface.  This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices.  We call this "inheriting"
- * the interface and next hop.
- *
- * In this method we are telling the root node which exit direction it should send
- * should I send a packet to the network or host represented by 'this' SPFVertex.
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @param nextHop The IP address to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- * @param id The interface index to use when forwarding packets to the host or
- * network represented by "this" SPFVertex.
- */
-  void SetRootExitDirection (Ipv4Address nextHop, int32_t id = SPF_INFINITY);
-  typedef std::pair<Ipv4Address, int32_t> NodeExit_t;
-/**
- * @brief Set the IP address and outgoing interface index that should be used 
- * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from 
- * the root.  The IP address that we're asking for is the address on the 
- * remote side of a link off of the root node that should be used as the
- * destination for packets along the path to "this" vertex.
- *
- * When initializing the root SPFVertex, the IP address used when forwarding
- * packets is determined by examining the Global Router Link Records of the
- * Link State Advertisement generated by the root node's GlobalRouter.  This
- * address is used to forward packets off of the root's network down those
- * links.  As other vertices / nodes are discovered which are further away
- * from the root, they will be accessible down one of the paths via a link
- * described by one of these Global Router Link Records.
- * 
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to a first hop router down
- * an interface.  This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices.  We call this "inheriting"
- * the interface and next hop.
- *
- * In this method we are telling the root node which exit direction it should send
- * should I send a packet to the network or host represented by 'this' SPFVertex.
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @param nextHop The IP address to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- * @param exit The pair of next-hop-IP and outgoing-interface-index to use when 
- * forwarding packets to the host or network represented by "this" SPFVertex.
- */
-  void SetRootExitDirection (SPFVertex::NodeExit_t exit);
- /**
-  * \brief Obtain a pair indicating the exit direction from the root
-  *
-  * \param i An index to a pair
-  * \return A pair of next-hop-IP and outgoing-interface-index for 
-  * indicating an exit direction from the root. It is 0 if the index 'i'
-  * is out-of-range
-  */
-  NodeExit_t GetRootExitDirection (uint32_t i) const;
-  /**
-   * \brief Obtain a pair indicating the exit direction from the root
-   *
-   * This method assumes there is only a single exit direction from the root.
-   * Error occur if this assumption is invalid.
-   *
-   * \return The pair of next-hop-IP and outgoing-interface-index for reaching
-   * 'this' vertex from the root
-   */
-  NodeExit_t GetRootExitDirection () const;
-  /**
-   * \brief Merge into 'this' vertex the list of exit directions from
-   * another vertex
-   *
-   * This merge is necessary when ECMP are found. 
-   *
-   * \param vertex From which the list of exit directions are obtain
-   * and are merged into 'this' vertex
-   */
-  void MergeRootExitDirections (const SPFVertex* vertex);
-  /**
-   * \brief Inherit all root exit directions from a given vertex to 'this' vertex
-   * \param vertex The vertex from which all root exit directions are to be inherited
-   *
-   * After the call of this method, the original root exit directions
-   * in 'this' vertex are all lost.
-   */
-  void InheritAllRootExitDirections (const SPFVertex* vertex);
-  /**
-   * \brief Get the number of exit directions from root for reaching 'this' vertex
-   * \return The number of exit directions from root
-   */
-  uint32_t GetNRootExitDirections () const;
-
-/**
- * @brief Get a pointer to the SPFVector that is the parent of "this" 
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.
- *
- * This method returns a pointer to the parent node of "this" SPFVertex
- * (both of which reside in that SPF tree).
- *
- * @param i The index to one of the parents
- * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex
- * in the SPF tree.
- */
-  SPFVertex* GetParent (uint32_t i = 0) const;
-
-/**
- * @brief Set the pointer to the SPFVector that is the parent of "this" 
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.
- *
- * This method sets the parent pointer of "this" SPFVertex (both of which
- * reside in that SPF tree).
- *
- * @param parent A pointer to the SPFVertex that is the parent of "this" 
- * SPFVertex* in the SPF tree.
- */
-  void SetParent (SPFVertex* parent);
-  /**
-   * \brief Merge the Parent list from the v into this vertex
-   *
-   * \param v The vertex from which its list of Parent is read
-   * and then merged into the list of Parent of *this* vertex.
-   * Note that the list in v remains intact
-   */
-  void MergeParent (const SPFVertex* v);
-
-/**
- * @brief Get the number of children of "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.  Each vertex
- * in the SPF tree can have a number of children that represent host or 
- * network routes available via that vertex.
- *
- * This method returns the number of children of "this" SPFVertex (which 
- * reside in the SPF tree).
- *
- * @returns The number of children of "this" SPFVertex (which reside in the
- * SPF tree).
- */
-  uint32_t GetNChildren (void) const;
-
-/**
- * @brief Get a borrowed SPFVertex pointer to the specified child of "this" 
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.  Each vertex
- * in the SPF tree can have a number of children that represent host or 
- * network routes available via that vertex.
- *
- * This method the number of children of "this" SPFVertex (which reside in
- * the SPF tree.
- *
- * @see SPFVertex::GetNChildren
- * @param n The index (from 0 to the number of children minus 1) of the 
- * child SPFVertex to return.
- * @warning The pointer returned by GetChild () is a borrowed pointer.  You
- * do not have any ownership of the underlying object and must not delete
- * that object.
- * @returns A pointer to the specified child SPFVertex (which resides in the
- * SPF tree).
- */
-  SPFVertex* GetChild (uint32_t n) const;
-
-/**
- * @brief Get a borrowed SPFVertex pointer to the specified child of "this" 
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.  Each vertex
- * in the SPF tree can have a number of children that represent host or 
- * network routes available via that vertex.
- *
- * This method the number of children of "this" SPFVertex (which reside in
- * the SPF tree.
- *
- * @see SPFVertex::GetNChildren
- * @warning Ownership of the pointer added to the children of "this" 
- * SPFVertex is transferred to the "this" SPFVertex.  You must not delete the
- * (now) child SPFVertex after calling this method.
- * @param child A pointer to the SPFVertex (which resides in the SPF tree) to
- * be added to the list of children of "this" SPFVertex.
- * @returns The number of children of "this" SPFVertex after the addition of
- * the new child.
- */
-  uint32_t AddChild (SPFVertex* child);
-
-  /**
-   * @brief Set the value of the VertexProcessed flag
-   *
-   * Flag to note whether vertex has been processed in stage two of 
-   * SPF computation
-   * @param value boolean value to set the flag
-   */ 
-  void SetVertexProcessed (bool value);
-
-  /**
-   * @brief Check the value of the VertexProcessed flag
-   *
-   * Flag to note whether vertex has been processed in stage two of 
-   * SPF computation
-   * @returns value of underlying flag
-   */ 
-  bool IsVertexProcessed (void) const;
-  
-  void ClearVertexProcessed (void);
-      
-private:
-  VertexType m_vertexType;
-  Ipv4Address m_vertexId;
-  GlobalRoutingLSA* m_lsa;
-  uint32_t m_distanceFromRoot;
-  int32_t m_rootOif;
-  Ipv4Address m_nextHop;
-  typedef std::list< NodeExit_t > ListOfNodeExit_t;
-  /// store the multiple root's exits for supporting ECMP
-  ListOfNodeExit_t m_ecmpRootExits;
-  typedef std::list<SPFVertex*> ListOfSPFVertex_t;
-  ListOfSPFVertex_t m_parents;
-  ListOfSPFVertex_t m_children;
-  bool m_vertexProcessed; 
-
-/**
- * @brief The SPFVertex copy construction is disallowed.  There's no need for
- * it and a compiler provided shallow copy would be wrong.
- */
-  SPFVertex (SPFVertex& v);
-
-/**
- * @brief The SPFVertex copy assignment operator is disallowed.  There's no 
- * need for it and a compiler provided shallow copy would be wrong.
- */
-  SPFVertex& operator= (SPFVertex& v);
-
-  //friend std::ostream& operator<< (std::ostream& os, const ListOfIf_t& ifs);
-  //friend std::ostream& operator<< (std::ostream& os, const ListOfAddr_t& addrs);
-  friend std::ostream& operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs);
-};
-
-/**
- * @brief The Link State DataBase (LSDB) of the Global Route Manager.
- *
- * Each node in the simulation participating in global routing has a
- * GlobalRouter interface.  The primary job of this interface is to export
- * Global Router Link State Advertisements (LSAs).  These advertisements in
- * turn contain a number of Global Router Link Records that describe the 
- * point to point links from the underlying node to other nodes (that will 
- * also export their own LSAs.
- *
- * This class implements a searchable database of LSAs gathered from every
- * router in the simulation.
- */
-class GlobalRouteManagerLSDB
-{
-public:
-/**
- * @brief Construct an empty Global Router Manager Link State Database.
- * @internal
- *
- * The database map composing the Link State Database is initialized in
- * this constructor.
- */
-  GlobalRouteManagerLSDB ();
-
-/**
- * @brief Destroy an empty Global Router Manager Link State Database.
- * @internal
- *
- * The database map is walked and all of the Link State Advertisements stored
- * in the database are freed; then the database map itself is clear ()ed to
- * release any remaining resources.
- */
-  ~GlobalRouteManagerLSDB ();
-
-/**
- * @brief Insert an IP address / Link State Advertisement pair into the Link
- * State Database.
- * @internal
- *
- * The IPV4 address and the GlobalRoutingLSA given as parameters are converted
- * to an STL pair and are inserted into the database map.
- *
- * @see GlobalRoutingLSA
- * @see Ipv4Address
- * @param addr The IP address associated with the LSA.  Typically the Router 
- * ID.
- * @param lsa A pointer to the Link State Advertisement for the router.
- */
-  void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
-
-/**
- * @brief Look up the Link State Advertisement associated with the given
- * link state ID (address).
- * @internal
- *
- * The database map is searched for the given IPV4 address and corresponding
- * GlobalRoutingLSA is returned.
- *
- * @see GlobalRoutingLSA
- * @see Ipv4Address
- * @param addr The IP address associated with the LSA.  Typically the Router 
- * ID.
- * @returns A pointer to the Link State Advertisement for the router specified
- * by the IP address addr.
- */
-  GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
-/**
- * @brief Look up the Link State Advertisement associated with the given
- * link state ID (address).  This is a variation of the GetLSA call
- * to allow the LSA to be found by matching addr with the LinkData field
- * of the TransitNetwork link record.
- * @internal
- *
- * @see GetLSA
- * @param addr The IP address associated with the LSA.  Typically the Router 
- * @returns A pointer to the Link State Advertisement for the router specified
- * by the IP address addr.
- * ID.
- */
-  GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
-
-/**
- * @brief Set all LSA flags to an initialized state, for SPF computation
- * @internal
- *
- * This function walks the database and resets the status flags of all of the
- * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED.  This is done
- * prior to each SPF calculation to reset the state of the SPFVertex structures
- * that will reference the LSAs during the calculation.
- *
- * @see GlobalRoutingLSA
- * @see SPFVertex
- */
-  void Initialize ();
-  
-  GlobalRoutingLSA* GetExtLSA (uint32_t index) const;
-  uint32_t GetNumExtLSAs () const;
-      
-
-private:
-  typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
-  typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
-
-  LSDBMap_t m_database;
-  std::vector<GlobalRoutingLSA*> m_extdatabase;
-  
-/**
- * @brief GlobalRouteManagerLSDB copy construction is disallowed.  There's no 
- * need for it and a compiler provided shallow copy would be wrong.
- */
-  GlobalRouteManagerLSDB (GlobalRouteManagerLSDB& lsdb);
-
-/**
- * @brief The SPFVertex copy assignment operator is disallowed.  There's no 
- * need for it and a compiler provided shallow copy would be wrong.
- */
-  GlobalRouteManagerLSDB& operator= (GlobalRouteManagerLSDB& lsdb);
-};
-
-/**
- * @brief A global router implementation.
- *
- * This singleton object can query interface each node in the system
- * for a GlobalRouter interface.  For those nodes, it fetches one or
- * more Link State Advertisements and stores them in a local database.
- * Then, it can compute shortest paths on a per-node basis to all routers, 
- * and finally configure each of the node's forwarding tables.
- *
- * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
- */
-class GlobalRouteManagerImpl
-{
-public:
-  GlobalRouteManagerImpl ();
-  virtual ~GlobalRouteManagerImpl ();
-/**
- * @brief Delete all static routes on all nodes that have a
- * GlobalRouterInterface
- *
- * TODO:  separate manually assigned static routes from static routes that
- * the global routing code injects, and only delete the latter
- * @internal
- *
- */
-  virtual void DeleteGlobalRoutes ();
-
-/**
- * @brief Build the routing database by gathering Link State Advertisements
- * from each node exporting a GlobalRouter interface.
- * @internal
- */
-  virtual void BuildGlobalRoutingDatabase ();
-
-/**
- * @brief Compute routes using a Dijkstra SPF computation and populate
- * per-node forwarding tables
- * @internal
- */
-  virtual void InitializeRoutes ();
-
-/**
- * @brief Debugging routine; allow client code to supply a pre-built LSDB
- * @internal
- */
-  void DebugUseLsdb (GlobalRouteManagerLSDB*);
-
-/**
- * @brief Debugging routine; call the core SPF from the unit tests
- * @internal
- */
-  void DebugSPFCalculate (Ipv4Address root);
-
-private:
-/**
- * @brief GlobalRouteManagerImpl copy construction is disallowed.
- * There's no  need for it and a compiler provided shallow copy would be 
- * wrong.
- */
-  GlobalRouteManagerImpl (GlobalRouteManagerImpl& srmi);
-
-/**
- * @brief Global Route Manager Implementation assignment operator is
- * disallowed.  There's no  need for it and a compiler provided shallow copy
- * would be hopelessly wrong.
- */
-  GlobalRouteManagerImpl& operator= (GlobalRouteManagerImpl& srmi);
-
-  SPFVertex* m_spfroot;
-  GlobalRouteManagerLSDB* m_lsdb;
-  bool CheckForStubNode (Ipv4Address root);
-  void SPFCalculate (Ipv4Address root);
-  void SPFProcessStubs (SPFVertex* v);
-  void ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa);
-  void SPFNext (SPFVertex*, CandidateQueue&);
-  int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, 
-    GlobalRoutingLinkRecord* l, uint32_t distance);
-  void SPFVertexAddParent (SPFVertex* v);
-  GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, 
-    GlobalRoutingLinkRecord* prev_link);
-  void SPFIntraAddRouter (SPFVertex* v);
-  void SPFIntraAddTransit (SPFVertex* v);
-  void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
-  void SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v);
-  int32_t FindOutgoingInterfaceId (Ipv4Address a, 
-    Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
-};
-
-} // namespace ns3
-
-#endif /* GLOBAL_ROUTE_MANAGER_IMPL_H */
--- a/src/routing/global-routing/global-route-manager.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * 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: Tom Henderson (tomhend@u.washington.edu)
- */
-
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/simulation-singleton.h"
-#include "global-route-manager.h"
-#include "global-route-manager-impl.h"
-
-namespace ns3 {
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouteManager Implementation
-//
-// ---------------------------------------------------------------------------
-
-  void
-GlobalRouteManager::DeleteGlobalRoutes ()
-{
-  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
-    DeleteGlobalRoutes ();
-}
-
-  void
-GlobalRouteManager::BuildGlobalRoutingDatabase (void) 
-{
-  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
-    BuildGlobalRoutingDatabase ();
-}
-
-  void
-GlobalRouteManager::InitializeRoutes (void)
-{
-  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
-    InitializeRoutes ();
-}
-
-  uint32_t
-GlobalRouteManager::AllocateRouterId (void)
-{
-  static uint32_t routerId = 0;
-  return routerId++;
-}
-
-
-} // namespace ns3
--- a/src/routing/global-routing/global-route-manager.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * 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:  Craig Dowell (craigdo@ee.washington.edu)
- *           Tom Henderson (tomhend@u.washington.edu)
- */
-
-#ifndef GLOBAL_ROUTE_MANAGER_H
-#define GLOBAL_ROUTE_MANAGER_H
-
-#include "ns3/deprecated.h"
-
-namespace ns3 {
-
-/**
- * @brief A global global router
- *
- * This singleton object can query interface each node in the system
- * for a GlobalRouter interface.  For those nodes, it fetches one or
- * more Link State Advertisements and stores them in a local database.
- * Then, it can compute shortest paths on a per-node basis to all routers, 
- * and finally configure each of the node's forwarding tables.
- *
- * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
- */
-class GlobalRouteManager
-{
-public:
-/**
- * @brief Allocate a 32-bit router ID from monotonically increasing counter.
- */
-  static uint32_t AllocateRouterId ();
-
-/**
- * @brief Delete all static routes on all nodes that have a 
- * GlobalRouterInterface
- *
- */
-  static void DeleteGlobalRoutes ();
-
-/**
- * @brief Build the routing database by gathering Link State Advertisements
- * from each node exporting a GlobalRouter interface.
- * @internal
- *
- */
-  static void BuildGlobalRoutingDatabase ();
-
-/**
- * @brief Compute routes using a Dijkstra SPF computation and populate
- * per-node forwarding tables
- * @internal
- */
-  static void InitializeRoutes ();
-
-private:
-/**
- * @brief Global Route Manager copy construction is disallowed.  There's no 
- * need for it and a compiler provided shallow copy would be wrong.
- *
- */
-  GlobalRouteManager (GlobalRouteManager& srm);
-
-/**
- * @brief Global Router copy assignment operator is disallowed.  There's no 
- * need for it and a compiler provided shallow copy would be wrong.
- */
-  GlobalRouteManager& operator= (GlobalRouteManager& srm);
-};
-
-} // namespace ns3
-
-#endif /* GLOBAL_ROUTE_MANAGER_H */
--- a/src/routing/global-routing/global-router-interface.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1694 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * 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:  Tom Henderson (tomhend@u.washington.edu)
- */
-
-#include "ns3/log.h"
-#include "ns3/assert.h"
-#include "ns3/abort.h"
-#include "ns3/channel.h"
-#include "ns3/net-device.h"
-#include "ns3/node.h"
-#include "ns3/node-list.h"
-#include "ns3/ipv4.h"
-#include "ns3/bridge-net-device.h"
-#include "ipv4-global-routing.h"
-#include "global-router-interface.h"
-#include <vector>
-
-NS_LOG_COMPONENT_DEFINE ("GlobalRouter");
-
-namespace ns3 {
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRoutingLinkRecord Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
-:
-  m_linkId ("0.0.0.0"),
-  m_linkData ("0.0.0.0"),
-  m_linkType (Unknown),
-  m_metric (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
-  LinkType    linkType, 
-  Ipv4Address linkId, 
-  Ipv4Address linkData, 
-  uint16_t    metric)
-:
-  m_linkId (linkId),
-  m_linkData (linkData),
-  m_linkType (linkType),
-  m_metric (metric)
-{
-  NS_LOG_FUNCTION (this << linkType << linkId << linkData << metric);
-}
-
-GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-  Ipv4Address
-GlobalRoutingLinkRecord::GetLinkId (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_linkId;
-}
-
-  void
-GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_linkId = addr;
-}
-
-  Ipv4Address
-GlobalRoutingLinkRecord::GetLinkData (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_linkData;
-}
-
-  void
-GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_linkData = addr;
-}
-
-  GlobalRoutingLinkRecord::LinkType
-GlobalRoutingLinkRecord::GetLinkType (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_linkType;
-}
-
-  void
-GlobalRoutingLinkRecord::SetLinkType (
-  GlobalRoutingLinkRecord::LinkType linkType)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_linkType = linkType;
-}
-
-  uint16_t
-GlobalRoutingLinkRecord::GetMetric (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_metric;
-}
-
-  void
-GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_metric = metric;
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRoutingLSA Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRoutingLSA::GlobalRoutingLSA()
-  : 
-  m_lsType (GlobalRoutingLSA::Unknown),
-  m_linkStateId("0.0.0.0"),
-  m_advertisingRtr("0.0.0.0"),
-  m_linkRecords(),
-  m_networkLSANetworkMask("0.0.0.0"),
-  m_attachedRouters(),
-  m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED),
-  m_node_id(0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-GlobalRoutingLSA::GlobalRoutingLSA (
-  GlobalRoutingLSA::SPFStatus status,
-  Ipv4Address linkStateId, 
-  Ipv4Address advertisingRtr)
-:
-  m_lsType (GlobalRoutingLSA::Unknown),
-  m_linkStateId(linkStateId),
-  m_advertisingRtr(advertisingRtr),
-  m_linkRecords(),
-  m_networkLSANetworkMask("0.0.0.0"),
-  m_attachedRouters(),
-  m_status(status),
-  m_node_id(0)
-{
-  NS_LOG_FUNCTION (this << status << linkStateId << advertisingRtr);
-}
-
-GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
-  : m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId), 
-    m_advertisingRtr(lsa.m_advertisingRtr), 
-    m_networkLSANetworkMask(lsa.m_networkLSANetworkMask), 
-    m_status(lsa.m_status),
-    m_node_id(lsa.m_node_id)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT_MSG(IsEmpty(), 
-    "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
-  CopyLinkRecords (lsa);
-}
-
-  GlobalRoutingLSA&
-GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_lsType = lsa.m_lsType;
-  m_linkStateId = lsa.m_linkStateId;
-  m_advertisingRtr = lsa.m_advertisingRtr;
-  m_networkLSANetworkMask = lsa.m_networkLSANetworkMask, 
-  m_status = lsa.m_status;
-  m_node_id = lsa.m_node_id;
-
-  ClearLinkRecords ();
-  CopyLinkRecords (lsa);
-  return *this;
-}
-
-  void
-GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
-       i != lsa.m_linkRecords.end (); 
-       i++)
-    {
-      GlobalRoutingLinkRecord *pSrc = *i;
-      GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
-
-      pDst->SetLinkType (pSrc->GetLinkType ());
-      pDst->SetLinkId (pSrc->GetLinkId ());
-      pDst->SetLinkData (pSrc->GetLinkData ());
-      pDst->SetMetric (pSrc->GetMetric ());
-
-      m_linkRecords.push_back(pDst);
-      pDst = 0;
-    }
-
-   m_attachedRouters = lsa.m_attachedRouters;
-}
-
-GlobalRoutingLSA::~GlobalRoutingLSA()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  ClearLinkRecords ();
-}
-
-  void
-GlobalRoutingLSA::ClearLinkRecords(void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
-        i != m_linkRecords.end (); 
-        i++)
-    {
-      NS_LOG_LOGIC ("Free link record");
-
-      GlobalRoutingLinkRecord *p = *i;
-      delete p;
-      p = 0;
-
-      *i = 0;
-    }
-  NS_LOG_LOGIC ("Clear list");
-  m_linkRecords.clear();
-}
-
-  uint32_t
-GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_linkRecords.push_back (lr);
-  return m_linkRecords.size ();
-}
-
-  uint32_t
-GlobalRoutingLSA::GetNLinkRecords (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_linkRecords.size ();
-}
-
-  GlobalRoutingLinkRecord *
-GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t j = 0;
-  for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
-        i != m_linkRecords.end (); 
-        i++, j++)
-    {
-      if (j == n) 
-        {
-          return *i;
-        }
-    }
-  NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
-  return 0;
-}
-
-  bool
-GlobalRoutingLSA::IsEmpty (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_linkRecords.size () == 0;
-}
-
-  GlobalRoutingLSA::LSType
-GlobalRoutingLSA::GetLSType (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_lsType;
-}
-
-  void 
-GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ) 
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_lsType = typ;
-}
-
-  Ipv4Address
-GlobalRoutingLSA::GetLinkStateId (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_linkStateId;
-}
-
-  void
-GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_linkStateId = addr;
-}
-
-  Ipv4Address
-GlobalRoutingLSA::GetAdvertisingRouter (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_advertisingRtr;
-}
-
-  void
-GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_advertisingRtr = addr;
-}
-
-  void 
-GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_networkLSANetworkMask = mask;
-}
-
-  Ipv4Mask 
-GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_networkLSANetworkMask;
-}
-
-  GlobalRoutingLSA::SPFStatus
-GlobalRoutingLSA::GetStatus (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_status;
-}
-
-  uint32_t 
-GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_attachedRouters.push_back (addr);
-  return m_attachedRouters.size ();
-}
-
-  uint32_t 
-GlobalRoutingLSA::GetNAttachedRouters (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_attachedRouters.size (); 
-}
-
-  Ipv4Address 
-GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t j = 0;
-  for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
-        i != m_attachedRouters.end (); 
-        i++, j++)
-    {
-      if (j == n) 
-        {
-          return *i;
-        }
-    }
-  NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
-  return Ipv4Address("0.0.0.0");
-}
-
-  void
-GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_status = status;
-}
-
-  Ptr<Node>
-GlobalRoutingLSA::GetNode (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return NodeList::GetNode (m_node_id);
-}
-
-  void
-GlobalRoutingLSA::SetNode (Ptr<Node> node)
-{
-  NS_LOG_FUNCTION (node);
-  m_node_id = node->GetId ();
-}
-
-  void 
-GlobalRoutingLSA::Print (std::ostream &os) const
-{
-  os << std::endl;
-  os << "========== Global Routing LSA ==========" << std::endl;
-  os << "m_lsType = " << m_lsType;
-  if (m_lsType == GlobalRoutingLSA::RouterLSA) 
-    {
-      os << " (GlobalRoutingLSA::RouterLSA)";
-    }
-  else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
-    {
-      os << " (GlobalRoutingLSA::NetworkLSA)";
-    }
-  else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
-    {
-      os << " (GlobalRoutingLSA::ASExternalLSA)";
-    }
-  else
-    {
-      os << "(Unknown LSType)";
-    }
-  os << std::endl;
-
-  os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl;
-  os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl;
-
-  if (m_lsType == GlobalRoutingLSA::RouterLSA) 
-    {
-      for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
-            i != m_linkRecords.end (); 
-            i++)
-        {
-          GlobalRoutingLinkRecord *p = *i;
-
-          os << "---------- RouterLSA Link Record ----------" << std::endl;
-          os << "m_linkType = " << p->m_linkType;
-          if (p->m_linkType == GlobalRoutingLinkRecord::PointToPoint)
-            {
-              os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl;
-              os << "m_linkId = " << p->m_linkId << std::endl;
-              os << "m_linkData = " << p->m_linkData << std::endl;
-              os << "m_metric = " << p->m_metric << std::endl;
-            }
-          else if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
-            {
-              os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
-              os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
-              os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
-              os << "m_metric = " << p->m_metric << std::endl;
-            }
-          else if (p->m_linkType == GlobalRoutingLinkRecord::StubNetwork)
-            {
-              os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
-              os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
-              os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
-              os << "m_metric = " << p->m_metric << std::endl;
-            }
-          else
-            {
-              os << " (Unknown LinkType)" << std::endl;
-              os << "m_linkId = " << p->m_linkId << std::endl;
-              os << "m_linkData = " << p->m_linkData << std::endl;
-              os << "m_metric = " << p->m_metric << std::endl;
-            }
-          os << "---------- End RouterLSA Link Record ----------" << std::endl;
-        }
-    }
-  else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
-    {
-      os << "---------- NetworkLSA Link Record ----------" << std::endl;
-      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
-      for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++)
-        {
-          Ipv4Address p = *i;
-          os << "attachedRouter = " << p << std::endl;
-        }
-      os << "---------- End NetworkLSA Link Record ----------" << std::endl;
-    }
-  else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
-    {
-      os << "---------- ASExternalLSA Link Record --------" << std::endl;
-      os << "m_linkStateId = " << m_linkStateId << std::endl;
-      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
-    }
-  else 
-    {
-      NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
-    }
-  os << "========== End Global Routing LSA ==========" << std::endl;
-}
-
-std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
-{
-  lsa.Print (os);
-  return os;
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouter Implementation
-//
-// ---------------------------------------------------------------------------
-
-NS_OBJECT_ENSURE_REGISTERED (GlobalRouter);
-
-TypeId 
-GlobalRouter::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::GlobalRouter")
-    .SetParent<Object> ();
-  return tid;
-}
-
-GlobalRouter::GlobalRouter ()
-  : m_LSAs()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_routerId.Set(GlobalRouteManager::AllocateRouterId ());
-}
-
-GlobalRouter::~GlobalRouter ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  ClearLSAs();
-}
-
-void 
-GlobalRouter::SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing)
-{
-  m_routingProtocol = routing;
-}
-Ptr<Ipv4GlobalRouting> 
-GlobalRouter::GetRoutingProtocol (void)
-{
-  return m_routingProtocol;
-}
-
-void
-GlobalRouter::DoDispose ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_routingProtocol = 0;
-  for (InjectedRoutesI k = m_injectedRoutes.begin ();
-         k != m_injectedRoutes.end ();
-         k = m_injectedRoutes.erase (k))
-    {
-      delete (*k);
-    }
-  Object::DoDispose ();
-}
-
-  void
-GlobalRouter::ClearLSAs ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
-        i != m_LSAs.end (); 
-        i++)
-    {
-      NS_LOG_LOGIC ("Free LSA");
-
-      GlobalRoutingLSA *p = *i;
-      delete p;
-      p = 0;
-
-      *i = 0;
-    }
-  NS_LOG_LOGIC ("Clear list of LSAs");
-  m_LSAs.clear();
-}
-
-  Ipv4Address
-GlobalRouter::GetRouterId (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_routerId;
-}
-
-//
-// DiscoverLSAs is called on all nodes in the system that have a GlobalRouter
-// interface aggregated.  We need to go out and discover any adjacent routers 
-// and build the Link State Advertisements that reflect them and their associated
-// networks.
-// 
-uint32_t 
-GlobalRouter::DiscoverLSAs ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ptr<Node> node = GetObject<Node> ();
-  NS_ABORT_MSG_UNLESS (node, "GlobalRouter::DiscoverLSAs (): GetObject for <Node> interface failed");
-  NS_LOG_LOGIC ("For node " << node->GetId () );
-
-  ClearLSAs ();
-
-  //
-  // While building the Router-LSA, keep a list of those NetDevices for
-  // which the current node is the designated router and we will later build 
-  // a NetworkLSA for.
-  //
-  NetDeviceContainer c;
-
-  //
-  // We're aggregated to a node.  We need to ask the node for a pointer to its
-  // Ipv4 interface.  This is where the information regarding the attached 
-  // interfaces lives.  If we're a router, we had better have an Ipv4 interface.
-  //
-  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
-  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for <Ipv4> interface failed");
-
-  //
-  // Every router node originates a Router-LSA
-  //
-  GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
-  pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
-  pLSA->SetLinkStateId (m_routerId);
-  pLSA->SetAdvertisingRouter (m_routerId);
-  pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
-  pLSA->SetNode (node);
-
-  //
-  // Ask the node for the number of net devices attached. This isn't necessarily 
-  // equal to the number of links to adjacent nodes (other routers) as the number
-  // of devices may include those for stub networks (e.g., ethernets, etc.) and 
-  // bridge devices also take up an "extra" net device.
-  //
-  uint32_t numDevices = node->GetNDevices();
-
-  //
-  // Iterate through the devices on the node and walk the channel to see what's
-  // on the other side of the standalone devices..
-  //
-  for (uint32_t i = 0; i < numDevices; ++i)
-    {
-      Ptr<NetDevice> ndLocal = node->GetDevice(i);
-
-      //
-      // There is an assumption that bridge ports must never have an IP address 
-      // associated with them.  This turns out to be a very convenient place to
-      // check and make sure that this is the case.
-      //
-      if (NetDeviceIsBridged (ndLocal))
-        {
-          uint32_t interfaceBridge;
-          bool rc = FindInterfaceForDevice(node, ndLocal, interfaceBridge);
-          NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index");
-        }
-
-      //
-      // Check to see if the net device we just got has a corresponding IP 
-      // interface (could be a pure L2 NetDevice) -- for example a net device
-      // associated with a bridge.  We are only going to involve devices with 
-      // IP addresses in routing.
-      //
-      bool isForwarding = false;
-      for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
-        {
-          if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j) &&
-              ipv4Local->IsForwarding (j)) 
-            {
-              isForwarding = true;
-              break;
-            }
-        }
-
-      if (!isForwarding)
-        {
-          NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface or is not enabled for forwarding, skipping");
-          continue;
-        }
-
-      //
-      // We have a net device that we need to check out.  If it suports 
-      // broadcast and is not a point-point link, then it will be either a stub 
-      // network or a transit network depending on the number of routers on
-      // the segment.  We add the appropriate link record to the LSA.
-      //
-      // If the device is a point to point link, we treat it separately.  In
-      // that case, there may be zero, one, or two link records added.
-      //
-
-      if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
-        {
-          NS_LOG_LOGIC ("Broadcast link");
-          ProcessBroadcastLink (ndLocal, pLSA, c);
-        }
-      else if (ndLocal->IsPointToPoint () )
-        {
-          NS_LOG_LOGIC ("Point=to-point link");
-          ProcessPointToPointLink (ndLocal, pLSA);
-        }
-      else
-        {
-          NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
-        }
-    }
-
-  NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
-  NS_LOG_LOGIC (*pLSA);
-  m_LSAs.push_back (pLSA);
-  pLSA = 0;
-
-  // 
-  // Now, determine whether we need to build a NetworkLSA.  This is the case if
-  // we found at least one designated router.
-  //
-  uint32_t nDesignatedRouters = c.GetN ();
-  if (nDesignatedRouters > 0)
-    {
-      NS_LOG_LOGIC ("Build Network LSAs");
-      BuildNetworkLSAs (c);
-    }
-
-  //
-  // Build injected route LSAs as external routes
-  // RFC 2328, section 12.4.4
-  //
-  for (InjectedRoutesCI i = m_injectedRoutes.begin();
-       i != m_injectedRoutes.end();
-       i++)
-    {
-      GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
-      pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs);
-      pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
-      pLSA->SetAdvertisingRouter (m_routerId);
-      pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
-      pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
-      m_LSAs.push_back (pLSA); 
-    }
-  return m_LSAs.size ();
-}
-
-  void
-GlobalRouter::ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
-{
-  NS_LOG_FUNCTION (nd << pLSA << &c);
-
-  if (nd->IsBridge ())
-    {
-      ProcessBridgedBroadcastLink (nd, pLSA, c);
-    }
-  else
-    {
-      ProcessSingleBroadcastLink (nd, pLSA, c);
-    }
-}
-
-  void
-GlobalRouter::ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
-{
-  NS_LOG_FUNCTION (nd << pLSA << &c);
-
-  GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
-  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record");
-
-  //
-  // We have some preliminaries to do to get enough information to proceed.
-  // This information we need comes from the internet stack, so notice that
-  // there is an implied assumption that global routing is only going to 
-  // work with devices attached to the internet stack (have an ipv4 interface
-  // associated to them.
-  //
-  Ptr<Node> node = nd->GetNode ();
-
-  uint32_t interfaceLocal;
-  bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
-  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
-
-  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
-  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
-
-  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
-    {
-      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-    }
-  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
-  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
-  NS_LOG_LOGIC ("Working with local address " << addrLocal);
-  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
-
-  //
-  // Check to see if the net device is connected to a channel/network that has
-  // another router on it.  If there is no other router on the link (but us) then
-  // this is a stub network.  If we find another router, then what we have here
-  // is a transit network.
-  //
-  if (AnotherRouterOnLink (nd, true) == false)
-    {
-      //
-      // This is a net device connected to a stub network
-      //
-      NS_LOG_LOGIC("Router-LSA Stub Network");
-      plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
-
-      // 
-      // According to OSPF, the Link ID is the IP network number of 
-      // the attached network.
-      //
-      plr->SetLinkId (addrLocal.CombineMask(maskLocal));
-
-      //
-      // and the Link Data is the network mask; converted to Ipv4Address
-      //
-      Ipv4Address maskLocalAddr;
-      maskLocalAddr.Set(maskLocal.Get ());
-      plr->SetLinkData (maskLocalAddr);
-      plr->SetMetric (metricLocal);
-      pLSA->AddLinkRecord(plr);
-      plr = 0;
-    }
-  else
-    {
-      //
-      // We have multiple routers on a broadcast interface, so this is
-      // a transit network.
-      //
-      NS_LOG_LOGIC ("Router-LSA Transit Network");
-      plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
-
-      // 
-      // By definition, the router with the lowest IP address is the
-      // designated router for the network.  OSPF says that the Link ID
-      // gets the IP interface address of the designated router in this 
-      // case.
-      //
-      Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true);
-
-      //
-      // Let's double-check that any designated router we find out on our
-      // network is really on our network.
-      //
-      if (desigRtr != "255.255.255.255")
-        {
-          Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
-          Ipv4Address networkThere = desigRtr.CombineMask (maskLocal);
-          NS_ABORT_MSG_UNLESS (networkHere == networkThere, 
-                               "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
-        }
-      if (desigRtr == addrLocal) 
-        {
-          c.Add (nd);
-          NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
-        }
-      plr->SetLinkId (desigRtr);
-      
-      //
-      // OSPF says that the Link Data is this router's own IP address.
-      //
-      plr->SetLinkData (addrLocal);
-      plr->SetMetric (metricLocal);
-      pLSA->AddLinkRecord (plr);
-      plr = 0;
-    }
-}
-
-  void
-GlobalRouter::ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
-{
-  NS_LOG_FUNCTION (nd << pLSA << &c);
-  NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
-
-#if 0
-  //
-  // It is possible to admit the possibility that a bridge device on a node
-  // can also participate in routing.  This would surprise people who don't
-  // come from Microsoft-land where they do use such a construct.  Based on
-  // the principle of least-surprise, we will leave the relatively simple
-  // code in place to do this, but not enable it until someone really wants
-  // the capability.  Even then, we will not enable this code as a default
-  // but rather something you will have to go and turn on.
-  //
-
-  Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
-  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
-
-  //
-  // We have some preliminaries to do to get enough information to proceed.
-  // This information we need comes from the internet stack, so notice that
-  // there is an implied assumption that global routing is only going to 
-  // work with devices attached to the internet stack (have an ipv4 interface
-  // associated to them.
-  //
-  Ptr<Node> node = nd->GetNode ();
-
-  uint32_t interfaceLocal;
-  bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
-  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
-
-  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
-  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
-
-  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
-    {
-      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-    }
-  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
-  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();;
-  NS_LOG_LOGIC ("Working with local address " << addrLocal);
-  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
-
-  //
-  // We need to handle a bridge on the router.  This means that we have been 
-  // given a net device that is a BridgeNetDevice.  It has an associated Ipv4
-  // interface index and address.  Some number of other net devices live "under"
-  // the bridge device as so-called bridge ports.  In a nutshell, what we have
-  // to do is to repeat what is done for a single broadcast link on all of 
-  // those net devices living under the bridge (trolls?)
-  //
-
-  bool areTransitNetwork = false;
-  Ipv4Address desigRtr ("255.255.255.255");
-
-  for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
-    {
-      Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
-
-      //
-      // We have to decide if we are a transit network.  This is characterized
-      // by the presence of another router on the network segment.  If we find
-      // another router on any of our bridged links, we are a transit network.
-      //
-      if (AnotherRouterOnLink (ndTemp, true))
-        {
-          areTransitNetwork = true;
-
-          //
-          // If we're going to be a transit network, then we have got to elect
-          // a designated router for the whole bridge.  This means finding the
-          // router with the lowest IP address on the whole bridge.  We ask 
-          // for the lowest address on each segment and pick the lowest of them
-          // all.
-          //
-          Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true);
-
-          //
-          // Let's double-check that any designated router we find out on our
-          // network is really on our network.
-          //
-          if (desigRtrTemp != "255.255.255.255")
-            {
-              Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
-              Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal);
-              NS_ABORT_MSG_UNLESS (networkHere == networkThere, 
-                                   "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
-            }
-          if (desigRtrTemp < desigRtr)
-            {
-              desigRtr = desigRtrTemp;
-            }
-        }
-    }
-  //
-  // That's all the information we need to put it all together, just like we did
-  // in the case of a single broadcast link.
-  //
-
-  GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
-  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
-
-  if (areTransitNetwork == false)
-    {
-      //
-      // This is a net device connected to a bridge of stub networks
-      //
-      NS_LOG_LOGIC("Router-LSA Stub Network");
-      plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
-
-      // 
-      // According to OSPF, the Link ID is the IP network number of 
-      // the attached network.
-      //
-      plr->SetLinkId (addrLocal.CombineMask(maskLocal));
-
-      //
-      // and the Link Data is the network mask; converted to Ipv4Address
-      //
-      Ipv4Address maskLocalAddr;
-      maskLocalAddr.Set(maskLocal.Get ());
-      plr->SetLinkData (maskLocalAddr);
-      plr->SetMetric (metricLocal);
-      pLSA->AddLinkRecord(plr);
-      plr = 0;
-    }
-  else
-    {
-      //
-      // We have multiple routers on a bridged broadcast interface, so this is
-      // a transit network.
-      //
-      NS_LOG_LOGIC ("Router-LSA Transit Network");
-      plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
-
-      // 
-      // By definition, the router with the lowest IP address is the
-      // designated router for the network.  OSPF says that the Link ID
-      // gets the IP interface address of the designated router in this 
-      // case.
-      //
-      if (desigRtr == addrLocal) 
-        {
-          c.Add (nd);
-          NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
-        }
-      plr->SetLinkId (desigRtr);
-      
-      //
-      // OSPF says that the Link Data is this router's own IP address.
-      //
-      plr->SetLinkData (addrLocal);
-      plr->SetMetric (metricLocal);
-      pLSA->AddLinkRecord (plr);
-      plr = 0;
-    }
-#endif
-}
-
-  void
-GlobalRouter::ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA)
-{
-  NS_LOG_FUNCTION (ndLocal << pLSA);
-
-  //
-  // We have some preliminaries to do to get enough information to proceed.
-  // This information we need comes from the internet stack, so notice that
-  // there is an implied assumption that global routing is only going to 
-  // work with devices attached to the internet stack (have an ipv4 interface
-  // associated to them.
-  //
-  Ptr<Node> nodeLocal = ndLocal->GetNode ();
-
-  uint32_t interfaceLocal;
-  bool rc = FindInterfaceForDevice(nodeLocal, ndLocal, interfaceLocal);
-  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
-
-  Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
-  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
-
-  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
-    {
-      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-    }
-  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
-  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
-  NS_LOG_LOGIC ("Working with local address " << addrLocal);
-  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
-
-  //
-  // Now, we're going to walk over to the remote net device on the other end of 
-  // the point-to-point channel we know we have.  This is where our adjacent 
-  // router (to use OSPF lingo) is running.  
-  //
-  Ptr<Channel> ch = ndLocal->GetChannel();
-
-  //
-  // Get the net device on the other side of the point-to-point channel.
-  //
-  Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
-
-  //
-  // The adjacent net device is aggregated to a node.  We need to ask that net 
-  // device for its node, then ask that node for its Ipv4 interface.  Note a
-  // requirement that nodes on either side of a point-to-point link must have 
-  // internet stacks; and an assumption that point-to-point links are incompatible 
-  // with bridging.
-  //
-  Ptr<Node> nodeRemote = ndRemote->GetNode();
-  Ptr<Ipv4> ipv4Remote = nodeRemote->GetObject<Ipv4> ();
-  NS_ABORT_MSG_UNLESS (ipv4Remote, 
-                       "GlobalRouter::ProcessPointToPointLink(): GetObject for remote <Ipv4> failed");
-
-  //
-  // Further note the requirement that nodes on either side of a point-to-point 
-  // link must participate in global routing and therefore have a GlobalRouter
-  // interface aggregated.
-  //
-  Ptr<GlobalRouter> rtrRemote = nodeRemote->GetObject<GlobalRouter> ();
-  if (rtrRemote == 0)
-    {
-      // This case is possible if the remote does not participate in global routing
-      return;
-    }
-  //
-  // We're going to need the remote router ID, so we might as well get it now.
-  //
-  Ipv4Address rtrIdRemote = rtrRemote->GetRouterId();
-  NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote);
-
-  //
-  // Now, just like we did above, we need to get the IP interface index for the 
-  // net device on the other end of the point-to-point channel.
-  //
-  uint32_t interfaceRemote;
-  rc = FindInterfaceForDevice(nodeRemote, ndRemote, interfaceRemote);
-  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
-
-  //
-  // Now that we have the Ipv4 interface, we can get the (remote) address and
-  // mask we need.
-  //
-  if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
-    {
-      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-    }
-  Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
-  Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
-  NS_LOG_LOGIC ("Working with remote address " << addrRemote);
-
-  //
-  // Now we can fill out the link records for this link.  There are always two
-  // link records; the first is a point-to-point record describing the link and
-  // the second is a stub network record with the network number.
-  //
-  GlobalRoutingLinkRecord *plr;
-  if (ipv4Remote->IsUp (interfaceRemote))
-    {
-      NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
- 
-      plr  = new GlobalRoutingLinkRecord;
-      NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
-      plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
-      plr->SetLinkId (rtrIdRemote);
-      plr->SetLinkData (addrLocal);
-      plr->SetMetric (metricLocal);
-      pLSA->AddLinkRecord (plr);
-      plr = 0;
-    }
-
-  // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
-  plr = new GlobalRoutingLinkRecord;
-  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
-  plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
-  plr->SetLinkId (addrRemote);
-  plr->SetLinkData (Ipv4Address(maskRemote.Get()));  // Frown
-  plr->SetMetric (metricLocal);
-  pLSA->AddLinkRecord (plr);
-  plr = 0;
-}
-
-  void
-GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c)
-{
-  NS_LOG_FUNCTION (&c);
-
-  uint32_t nDesignatedRouters = c.GetN ();
-      
-  for (uint32_t i = 0; i < nDesignatedRouters; ++i)
-    {
-      //
-      // Build one NetworkLSA for each net device talking to a network that we are the 
-      // designated router for.  These devices are in the provided container.
-      //
-      Ptr<NetDevice> ndLocal = c.Get (i);
-      Ptr<Node> node = ndLocal->GetNode ();
-
-      uint32_t interfaceLocal;
-      bool rc = FindInterfaceForDevice(node, ndLocal, interfaceLocal);
-      NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
-
-      Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
-      NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
-
-      if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
-        {
-          NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-        }
-      Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
-      Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
-
-      GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
-      NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
-
-      pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
-      pLSA->SetLinkStateId (addrLocal);
-      pLSA->SetAdvertisingRouter (m_routerId);
-      pLSA->SetNetworkLSANetworkMask (maskLocal);
-      pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
-      pLSA->SetNode (node);
-
-      //
-      // Build a list of AttachedRouters by walking the devices in the channel
-      // and, if we find a node with a GlobalRouter interface and an IPv4 
-      // interface associated with that device, we call it an attached router.  
-      //
-      Ptr<Channel> ch = ndLocal->GetChannel();
-      uint32_t nDevices = ch->GetNDevices();
-      NS_ASSERT (nDevices);
-      
-      for (uint32_t i = 0; i < nDevices; i++)
-        {
-          Ptr<NetDevice> tempNd = ch->GetDevice (i);
-          NS_ASSERT (tempNd);
-          Ptr<Node> tempNode = tempNd->GetNode ();
-
-          //
-          // Does the node in question have a GlobalRouter interface?  If not it can
-          // hardly be considered an attached router.
-          //
-          Ptr<GlobalRouter> rtr = tempNode->GetObject<GlobalRouter> ();
-          if (rtr == 0)
-            { 
-              continue;
-            }
-
-          //
-          // Does the attached node have an ipv4 interface for the device we're probing?
-          // If not, it can't play router.
-          //
-          uint32_t tempInterface;
-          if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
-            {
-              Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
-              NS_ASSERT (tempIpv4);
-              if (!tempIpv4->IsUp (tempInterface))
-                {
-                  NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
-                }
-              else 
-                {
-                  if (tempIpv4->GetNAddresses (tempInterface) > 1)
-                    {
-                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-                    }
-                  Ipv4Address tempAddr = tempIpv4->GetAddress(tempInterface, 0).GetLocal ();
-                  pLSA->AddAttachedRouter (tempAddr);
-                }
-            }
-        }
-      m_LSAs.push_back (pLSA);
-      pLSA = 0;
-    }
-}
-
-//
-// Given a local net device, we need to walk the channel to which the net device is
-// attached and look for nodes with GlobalRouter interfaces on them (one of them 
-// will be us).  Of these, the router with the lowest IP address on the net device 
-// connecting to the channel becomes the designated router for the link.
-//
-  Ipv4Address
-GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const
-{
-  NS_LOG_FUNCTION (ndLocal << allowRecursion);
-
-  Ptr<Channel> ch = ndLocal->GetChannel();
-  uint32_t nDevices = ch->GetNDevices();
-  NS_ASSERT (nDevices);
-
-  NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " << 
-                ndLocal->GetNode ()->GetId ());
-
-  Ipv4Address desigRtr ("255.255.255.255");
-
-  //
-  // Look through all of the devices on the channel to which the net device
-  // in question is attached.
-  //
-  for (uint32_t i = 0; i < nDevices; i++)
-    {
-      Ptr<NetDevice> ndOther = ch->GetDevice (i);
-      NS_ASSERT (ndOther);
-
-      Ptr<Node> nodeOther = ndOther->GetNode ();
-
-      NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ());
-
-      //
-      // For all other net devices, we need to check and see if a router
-      // is present.  If the net device on the other side is a bridged
-      // device, we need to consider all of the other devices on the 
-      // bridge as well (all of the bridge ports.
-      //
-      NS_LOG_LOGIC ("checking to see if the device is bridged");
-      Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
-      if (bnd)
-        {
-          NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd);
-
-          //
-          // It is possible that the bridge net device is sitting under a
-          // router, so we have to check for the presence of that router
-          // before we run off and follow all the links
-          //
-          // We require a designated router to have a GlobalRouter interface and
-          // an internet stack that includes the Ipv4 interface.  If it doesn't
-          // it can't play router.
-          //
-          NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd);
-          Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
-          Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
-          if (rtr && ipv4)
-            {
-              uint32_t interfaceOther;
-              if (FindInterfaceForDevice(nodeOther, bnd, interfaceOther))
-                {
-                  NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
-                  if (!ipv4->IsUp (interfaceOther))
-                    {
-                      NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
-                      continue;
-                    }
-                  if (ipv4->GetNAddresses (interfaceOther) > 1)
-                    {
-                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-                    }
-                  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
-                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
-                  NS_LOG_LOGIC ("designated router now " << desigRtr);
-                }
-            }
-
-          NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
-          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
-            {
-              Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
-              NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
-              if (ndBridged == ndOther)
-                {
-                  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
-                  continue;
-                }
-
-              if (allowRecursion)
-                {
-                  NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged);
-                  Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false);
-                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
-                  NS_LOG_LOGIC ("designated router now " << desigRtr);
-                }
-            }
-        }
-      else
-        {
-          NS_LOG_LOGIC ("This device is not bridged");
-          Ptr<Node> nodeOther = ndOther->GetNode ();
-          NS_ASSERT (nodeOther);
-
-          //
-          // We require a designated router to have a GlobalRouter interface and
-          // an internet stack that includes the Ipv4 interface.  If it doesn't
-          //
-          Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
-          Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
-          if (rtr && ipv4)
-            {
-              uint32_t interfaceOther;
-              if (FindInterfaceForDevice(nodeOther, ndOther, interfaceOther))
-                {
-                  if (!ipv4->IsUp (interfaceOther))
-                    {
-                      NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
-                      continue;
-                    }
-                  NS_LOG_LOGIC ("Found router on net device " << ndOther);
-                  if (ipv4->GetNAddresses (interfaceOther) > 1)
-                    {
-                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
-                    }
-                  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
-                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
-                  NS_LOG_LOGIC ("designated router now " << desigRtr);
-                }
-            }
-        }
-    }
-  return desigRtr;
-}
-
-//
-// Given a node and an attached net device, take a look off in the channel to 
-// which the net device is attached and look for a node on the other side
-// that has a GlobalRouter interface aggregated.  Life gets more complicated
-// when there is a bridged net device on the other side.
-//
-  bool
-GlobalRouter::AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const
-{
-  NS_LOG_FUNCTION (nd << allowRecursion);
-
-  Ptr<Channel> ch = nd->GetChannel();
-  if (!ch)
-    {
-      // It may be that this net device is a stub device, without a channel
-      return false;
-    }
-  uint32_t nDevices = ch->GetNDevices();
-  NS_ASSERT (nDevices);
-
-  NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
-
-  //
-  // Look through all of the devices on the channel to which the net device
-  // in question is attached.
-  //
-  for (uint32_t i = 0; i < nDevices; i++)
-    {
-      Ptr<NetDevice> ndOther = ch->GetDevice (i);
-      NS_ASSERT (ndOther);
-
-      NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
-
-      // 
-      // Ignore the net device itself.
-      //
-      if (ndOther == nd)
-        {
-          NS_LOG_LOGIC ("Myself, skip");
-          continue;
-        }
-
-      //
-      // For all other net devices, we need to check and see if a router
-      // is present.  If the net device on the other side is a bridged
-      // device, we need to consider all of the other devices on the 
-      // bridge.
-      //
-      NS_LOG_LOGIC ("checking to see if device is bridged");
-      Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
-      if (bnd)
-        {
-          NS_LOG_LOGIC ("Device is bridged by net device " << bnd);
-          NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
-          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
-            {
-              Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
-              NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
-              if (ndBridged == ndOther)
-                {
-                  NS_LOG_LOGIC ("That bridge port is me, skip");
-                  continue;
-                }
-
-              if (allowRecursion)
-                {
-                  NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged);
-                  if (AnotherRouterOnLink (ndBridged, false))
-                    {
-                      NS_LOG_LOGIC ("Found routers on bridge port, return true");
-                      return true;
-                    }
-                }
-            }
-          NS_LOG_LOGIC ("No routers on bridged net device, return false");
-          return false;
-        }
-
-      NS_LOG_LOGIC ("This device is not bridged");
-      Ptr<Node> nodeTemp = ndOther->GetNode ();
-      NS_ASSERT (nodeTemp);
-
-      Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
-      if (rtr)
-        {
-          NS_LOG_LOGIC ("Found GlobalRouter interface, return true");
-          return true;
-        }
-      else 
-        {
-          NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search");
-        }
-    }
-  NS_LOG_LOGIC ("No routers found, return false");
-  return false;
-}
-
-  uint32_t 
-GlobalRouter::GetNumLSAs (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_LSAs.size ();
-}
-
-//
-// Get the nth link state advertisement from this router.
-//
-  bool
-GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
-//
-// All of the work was done in GetNumLSAs.  All we have to do here is to
-// walk the list of link state advertisements created there and return the 
-// one the client is interested in.
-//
-  ListOfLSAs_t::const_iterator i = m_LSAs.begin ();
-  uint32_t j = 0;
-
-  for (; i != m_LSAs.end (); i++, j++)
-    {
-      if (j == n)
-        {
-          GlobalRoutingLSA *p = *i;
-          lsa = *p;
-          return true;
-        }
-    }
-
-  return false;
-}
-
-void
-GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
-{
-  NS_LOG_FUNCTION (network << networkMask);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-//
-// Interface number does not matter here, using 1.
-//
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-      networkMask,
-      1);
-  m_injectedRoutes.push_back (route);
-}
-
-Ipv4RoutingTableEntry *
-GlobalRouter::GetInjectedRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (index);
-  if (index < m_injectedRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (InjectedRoutesCI i = m_injectedRoutes.begin ();
-           i != m_injectedRoutes.end ();
-           i++)
-        {
-          if (tmp  == index)
-            {
-              return *i;
-            }
-          tmp++;
-        }
-     }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-
-uint32_t
-GlobalRouter::GetNInjectedRoutes ()
-{
-  return m_injectedRoutes.size ();
-}
-
-void
-GlobalRouter::RemoveInjectedRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (index);
-  NS_ASSERT (index < m_injectedRoutes.size ());
-  uint32_t tmp = 0;
-  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
-    {
-      if (tmp  == index)
-        {
-          NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size());
-          delete *i;
-          m_injectedRoutes.erase (i);
-          return;
-        }
-      tmp++;
-    }
-}
-
-bool
-GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
-{
-  NS_LOG_FUNCTION (network << networkMask);
-  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
-    {
-      if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
-        {
-          NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
-          delete *i;
-          m_injectedRoutes.erase (i);
-          return true;
-        }
-    }
-  return false;
-}
-
-
-//
-// Link through the given channel and find the net device that's on the
-// other end.  This only makes sense with a point-to-point channel.
-//
-  Ptr<NetDevice>
-GlobalRouter::GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT_MSG(ch->GetNDevices() == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices");
-//
-// This is a point to point channel with two endpoints.  Get both of them.
-//
-  Ptr<NetDevice> nd1 = ch->GetDevice(0);
-  Ptr<NetDevice> nd2 = ch->GetDevice(1);
-//
-// One of the endpoints is going to be "us" -- that is the net device attached
-// to the node on which we're running -- i.e., "nd".  The other endpoint (the
-// one to which we are connected via the channel) is the adjacent router.
-//
-  if (nd1 == nd)
-    {
-      return nd2;
-    }
-  else if (nd2 == nd)
-    {
-      return nd1;
-    }
-  else
-    {
-      NS_ASSERT_MSG(false,
-        "GlobalRouter::GetAdjacent (): Wrong or confused channel?");
-      return 0;
-    }
-}
-
-//
-// Given a node and a net device, find an IPV4 interface index that corresponds
-// to that net device.  This function may fail for various reasons.  If a node
-// does not have an internet stack (for example if it is a bridge) we won't have
-// an IPv4 at all.  If the node does have a stack, but the net device in question
-// is bridged, there will not be an interface associated directly with the device.
-//
-  bool
-GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd );
-
-  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-  if (ipv4 == 0)
-    {
-      NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ());
-      return false;
-    }
-
-  for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i )
-    {
-      if (ipv4->GetNetDevice(i) == nd) 
-        {
-          NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i);
-          index = i;
-          return true;
-        }
-    }
-
-  NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index");
-  return false;
-}
-
-//
-// Decide whether or not a given net device is being bridged by a BridgeNetDevice.
-//
-  Ptr<BridgeNetDevice>
-GlobalRouter::NetDeviceIsBridged (Ptr<NetDevice> nd) const
-{
-  NS_LOG_FUNCTION (nd);
-
-  Ptr<Node> node = nd->GetNode ();
-  uint32_t nDevices = node->GetNDevices();
-
-  //
-  // There is no bit on a net device that says it is being bridged, so we have
-  // to look for bridges on the node to which the device is attached.  If we
-  // find a bridge, we need to look through its bridge ports (the devices it
-  // bridges) to see if we find the device in question.
-  //
-  for (uint32_t i = 0; i < nDevices; ++i)
-    {
-      Ptr<NetDevice> ndTest = node->GetDevice(i);
-      NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
-
-      if (ndTest->IsBridge ())
-        {
-          NS_LOG_LOGIC ("device " << i << " is a bridge net device");
-          Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
-          NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
-
-          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
-            {
-              NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
-              if (bnd->GetBridgePort (j) == nd)
-                {
-                  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
-                  return bnd;
-                }
-            }
-        }
-    }
-  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
-  return 0;
-}
-
-} // namespace ns3
--- a/src/routing/global-routing/global-router-interface.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,754 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * 
- * 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:  Craig Dowell (craigdo@ee.washington.edu)
- *           Tom Henderson (tomhend@u.washington.edu)
- */
-
-#ifndef GLOBAL_ROUTER_INTERFACE_H
-#define GLOBAL_ROUTER_INTERFACE_H
-
-#include <stdint.h>
-#include <list>
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-#include "ns3/node.h"
-#include "ns3/channel.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/net-device-container.h"
-#include "ns3/bridge-net-device.h"
-#include "ns3/global-route-manager.h"
-#include "ns3/ipv4-routing-table-entry.h"
-
-namespace ns3 {
-
-class GlobalRouter;
-class Ipv4GlobalRouting;
-
-/**
- * @brief A single link record for a link state advertisement.
- *
- * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
- * a Link State Advertisement.  Right now we will only see two types of link
- * records corresponding to a stub network and a point-to-point link (channel).
- */
-class GlobalRoutingLinkRecord
-{
-public:
-  friend class GlobalRoutingLSA;
-/**
- * @enum LinkType
- * @brief Enumeration of the possible types of Global Routing Link Records.
- *
- * These values are defined in the OSPF spec.  We currently only use 
- * PointToPoint and StubNetwork types.
- */
-  enum LinkType {
-    Unknown = 0,        /**< Uninitialized Link Record */
-    PointToPoint,       /**< Record representing a point to point channel */
-    TransitNetwork,     /**< Unused -- for future OSPF compatibility  */
-    StubNetwork,        /**< Record represents a leaf node network */
-    VirtualLink         /**< Unused -- for future OSPF compatibility  */
-  };
-
-/**
- * @brief Construct an empty ("uninitialized") Global Routing Link Record.
- *
- * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
- * The Link Type is set to Unknown;
- * The metric is set to 0.
- */
-  GlobalRoutingLinkRecord ();
-
-/**
- * Construct an initialized Global Routing Link Record.
- *
- * @param linkType The type of link record to construct.
- * @param linkId The link ID for the record.
- * @param linkData The link data field for the record.
- * @param metric The metric field for the record.
- * @see LinkType
- * @see SetLinkId
- * @see SetLinkData
- */
-  GlobalRoutingLinkRecord (
-    LinkType    linkType, 
-    Ipv4Address linkId, 
-    Ipv4Address linkData, 
-    uint16_t    metric);
-
-/**
- * @brief Destroy a Global Routing Link Record.
- *
- * Currently does nothing.  Here as a placeholder only.
- */
-  ~GlobalRoutingLinkRecord ();
-
-/**
- * Get the Link ID field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
- * of the neighboring router.
- *
- * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent
- * neighbor's IP address
- *
- * @returns The Ipv4Address corresponding to the Link ID field of the record.
- */
-  Ipv4Address GetLinkId(void) const;
-
-/**
- * @brief Set the Link ID field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
- * of the neighboring router.
- *
- * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent
- * neighbor's IP address
- *
- * @param addr An Ipv4Address to store in the Link ID field of the record.
- */
-  void SetLinkId(Ipv4Address addr);
-
-/**
- * @brief Get the Link Data field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
- * address of the node of the local side of the link.
- *
- * For an OSPF type 3 link (StubNetwork), the Link Data will be the
- * network mask
- *
- * @returns The Ipv4Address corresponding to the Link Data field of the record.
- */
-  Ipv4Address GetLinkData(void) const;
-
-/**
- * @brief Set the Link Data field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
- * address of the node of the local side of the link.
- *
- * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the
- * network mask
- *
- * @param addr An Ipv4Address to store in the Link Data field of the record.
- */
-  void SetLinkData(Ipv4Address addr);
-
-/**
- * @brief Get the Link Type field of the Global Routing Link Record.
- *
- * The Link Type describes the kind of link a given record represents.  The
- * values are defined by OSPF.
- *
- * @see LinkType
- * @returns The LinkType of the current Global Routing Link Record.
- */
-  LinkType GetLinkType(void) const;
-
-/**
- * @brief Set the Link Type field of the Global Routing Link Record.
- *
- * The Link Type describes the kind of link a given record represents.  The
- * values are defined by OSPF.
- *
- * @see LinkType
- * @param linkType The new LinkType for the current Global Routing Link Record.
- */
-  void SetLinkType(LinkType linkType);
-
-/**
- * @brief Get the Metric Data field of the Global Routing Link Record.
- *
- * The metric is an abstract cost associated with forwarding a packet across
- * a link.  A sum of metrics must have a well-defined meaning.  That is, you
- * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
- * two hops relate to the cost of sending a packet); rather you should use
- * something like delay.
- *
- * @returns The metric field of the Global Routing Link Record.
- */
-  uint16_t GetMetric(void) const;
-
-/**
- * @brief Set the Metric Data field of the Global Routing Link Record.
- *
- * The metric is an abstract cost associated with forwarding a packet across
- * a link.  A sum of metrics must have a well-defined meaning.  That is, you
- * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
- * two hops relate to the cost of sending a packet); rather you should use
- * something like delay.
- *
- * @param metric The new metric for the current Global Routing Link Record.
- */
-  void SetMetric(uint16_t metric);
-
-private:
-/**
- * m_linkId and m_linkData are defined by OSPF to have different meanings 
- * depending on the type of link a given link records represents.  They work
- * together.
- *
- * For Type 1 link (PointToPoint), set m_linkId to Router ID of 
- * neighboring router.
- *
- * For Type 3 link (Stub), set m_linkId to neighbor's IP address
- */
-  Ipv4Address m_linkId;         
-
-/**
- * m_linkId and m_linkData are defined by OSPF to have different meanings 
- * depending on the type of link a given link records represents.  They work
- * together.
- *
- * For Type 1 link (PointToPoint), set m_linkData to local IP address  
- *
- * For Type 3 link (Stub), set m_linkData to mask
- */
-  Ipv4Address m_linkData;    // for links to RouterLSA, 
-
-/**
- * The type of the Global Routing Link Record.  Defined in the OSPF spec.  
- * We currently only use PointToPoint and StubNetwork types.
- */
-  LinkType m_linkType;
-
-/**
- * The metric for a given link.
- *
- * A metric is abstract cost associated with forwarding a packet across a 
- * link.  A sum of metrics must have a well-defined meaning.  That is, you 
- * shouldn't use bandwidth as a metric (how does the sum of the bandwidth 
- * of two hops relate to the cost of sending a packet); rather you should
- * use something like delay.
- */
-  uint16_t m_metric;  
-};
-
-/**  
- * @brief a Link State Advertisement (LSA) for a router, used in global 
- * routing.
- * 
- * Roughly equivalent to a global incarnation of the OSPF link state header
- * combined with a list of Link Records.  Since it's global, there's
- * no need for age or sequence number.  See RFC 2328, Appendix A.
- */
-class GlobalRoutingLSA
-{
-public:
-/**
- * @enum LSType
- * @brief corresponds to LS type field of RFC 2328 OSPF LSA header
- */
-  enum LSType {
-    Unknown = 0,        /**< Uninitialized Type */
-    RouterLSA,
-    NetworkLSA,
-    SummaryLSA,
-    SummaryLSA_ASBR,
-    ASExternalLSAs
-  };
-/**
- * @enum SPFStatus
- * @brief Enumeration of the possible values of the status flag in the Routing 
- * Link State Advertisements.
- */
-  enum SPFStatus {
-    LSA_SPF_NOT_EXPLORED = 0,	/**< New vertex not yet considered */
-    LSA_SPF_CANDIDATE,		/**< Vertex is in the SPF candidate queue */
-    LSA_SPF_IN_SPFTREE		/**< Vertex is in the SPF tree */
-  };
-/**
- * @brief Create a blank Global Routing Link State Advertisement.  
- *
- * On completion Ipv4Address variables initialized to 0.0.0.0 and the 
- * list of Link State Records is empty.
- */
-  GlobalRoutingLSA();
-
-/**
- * @brief Create an initialized Global Routing Link State Advertisement.  
- *
- * On completion the list of Link State Records is empty.
- *
- * @param status The status to of the new LSA.
- * @param linkStateId The Ipv4Address for the link state ID field.
- * @param advertisingRtr The Ipv4Address for the advertising router field.
- */
-  GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId, 
-    Ipv4Address advertisingRtr);
-
-/**
- * @brief Copy constructor for a Global Routing Link State Advertisement.
- *
- * Takes a piece of memory and constructs a semantically identical copy of
- * the given LSA.
- *
- * @param lsa The existing LSA to be used as the source.
- */
-  GlobalRoutingLSA (GlobalRoutingLSA& lsa);
-
-/**
- * @brief Destroy an existing Global Routing Link State Advertisement.
- *
- * Any Global Routing Link Records present in the list are freed.
- */
-  ~GlobalRoutingLSA();
-
-/**
- * @brief Assignment operator for a Global Routing Link State Advertisement.
- *
- * Takes an existing Global Routing Link State Advertisement and overwrites
- * it to make a semantically identical copy of a given prototype LSA.
- *
- * If there are any Global Routing Link Records present in the existing 
- * LSA, they are freed before the assignment happens.
- *
- * @param lsa The existing LSA to be used as the source.
- * @returns Reference to the overwritten LSA.
- */
-  GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
-
-/**
- * @brief Copy any Global Routing Link Records in a given Global Routing Link
- * State Advertisement to the current LSA.  
- * 
- * Existing Link Records are not deleted -- this is a concatenation of Link 
- * Records.
- *
- * @see ClearLinkRecords ()
- * @param lsa The LSA to copy the Link Records from.
- */
-  void CopyLinkRecords (const GlobalRoutingLSA& lsa);
-
-/**
- * @brief Add a given Global Routing Link Record to the LSA.
- *
- * @param lr The Global Routing Link Record to be added.
- * @returns The number of link records in the list.
- */
-  uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
-
-/**
- * @brief Return the number of Global Routing Link Records in the LSA.
- *
- * @returns The number of link records in the list.
- */
-  uint32_t GetNLinkRecords (void) const;
-
-/**
- * @brief Return a pointer to the specified Global Routing Link Record.
- *
- * @param n The LSA number desired.
- * @returns The number of link records in the list.
- */
-  GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
-
-/**
- * @brief Release all of the Global Routing Link Records present in the Global
- * Routing Link State Advertisement and make the list of link records empty.
- */
-  void ClearLinkRecords(void);
-
-/**
- * @brief Check to see if the list of Global Routing Link Records present in the
- * Global Routing Link State Advertisement is empty.
- *
- * @returns True if the list is empty, false otherwise.
- */
-  bool IsEmpty(void) const;
-
-/**
- * @brief Print the contents of the Global Routing Link State Advertisement and
- * any Global Routing Link Records present in the list.  Quite verbose.
- */
-  void Print (std::ostream &os) const;
-
-/**
- * @brief Return the LSType field of the LSA 
- */
-  LSType GetLSType (void) const;
-/**
- * @brief Set the LS type field of the LSA
- */
-  void SetLSType (LSType typ);
-
-/**
- * @brief Get the Link State ID as defined by the OSPF spec.  We always set it
- * to the router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- * @returns The Ipv4Address stored as the link state ID.
- */
-  Ipv4Address GetLinkStateId (void) const;
-
-/**
- * @brief Set the Link State ID is defined by the OSPF spec.  We always set it
- * to the router ID of the router making the advertisement.
- * @param addr IPv4 address which will act as ID
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
-  void SetLinkStateId (Ipv4Address addr);
-
-/**
- * @brief Get the Advertising Router as defined by the OSPF spec.  We always
- * set it to the router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- * @returns The Ipv4Address stored as the advertising router.
- */
-  Ipv4Address GetAdvertisingRouter (void) const;
-
-/**
- * @brief Set the Advertising Router as defined by the OSPF spec.  We always
- * set it to the router ID of the router making the advertisement.
- *
- * @param rtr ID of the router making advertisement
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
-  void SetAdvertisingRouter (Ipv4Address  rtr);
-
-/**
- * @brief For a Network LSA, set the Network Mask field that precedes
- * the list of attached routers.
- */
-  void SetNetworkLSANetworkMask (Ipv4Mask mask);
-
-/**
- * @brief For a Network LSA, get the Network Mask field that precedes
- * the list of attached routers.
- * 
- * @returns the NetworkLSANetworkMask 
- */
-  Ipv4Mask GetNetworkLSANetworkMask (void) const;
-
-/**
- * @brief Add an attached router to the list in the NetworkLSA
- *
- * @param addr The Ipv4Address of the interface on the network link
- * @returns The number of addresses in the list.
- */
-  uint32_t AddAttachedRouter (Ipv4Address addr);
-
-/**
- * @brief Return the number of attached routers listed in the NetworkLSA
- *
- * @returns The number of attached routers.
- */
-  uint32_t GetNAttachedRouters (void) const;
-
-/**
- * @brief Return an Ipv4Address corresponding to the specified attached router
- *
- * @param n The attached router number desired (number in the list).
- * @returns The Ipv4Address of the requested router
- */
-  Ipv4Address GetAttachedRouter (uint32_t n) const;
-
-/**
- * @brief Get the SPF status of the advertisement.
- *
- * @see SPFStatus
- * @returns The SPFStatus of the LSA.
- */
-  SPFStatus GetStatus (void) const;
-
-/**
- * @brief Set the SPF status of the advertisement
- * @param status SPF status to set
- * @see SPFStatus
- */
-  void SetStatus (SPFStatus status);
-
-/**
- * @brief Get the Node pointer of the node that originated this LSA
- * @returns Node pointer
- */
-  Ptr<Node> GetNode (void) const;
-
-/**
- * @brief Set the Node pointer of the node that originated this LSA
- * @param node Node pointer
- */
-  void SetNode (Ptr<Node> node);
-
-private:
-/**
- * The type of the LSA.  Each LSA type has a separate advertisement
- * format.
- */
-  LSType m_lsType;
-/**
- * The Link State ID is defined by the OSPF spec.  We always set it to the
- * router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
-  Ipv4Address  m_linkStateId;
-
-/**
- * The Advertising Router is defined by the OSPF spec.  We always set it to 
- * the router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
-  Ipv4Address  m_advertisingRtr;
-
-/**
- * A convenience typedef to avoid too much writers cramp.
- */
-  typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
-
-/**
- * Each Link State Advertisement contains a number of Link Records that
- * describe the kinds of links that are attached to a given node.  We 
- * consider PointToPoint and StubNetwork links.
- *
- * m_linkRecords is an STL list container to hold the Link Records that have
- * been discovered and prepared for the advertisement.
- *
- * @see GlobalRouting::DiscoverLSAs ()
- */
-  ListOfLinkRecords_t m_linkRecords;
-
-/**
- * Each Network LSA contains the network mask of the attached network
- */
-  Ipv4Mask m_networkLSANetworkMask;
-
-/**
- * A convenience typedef to avoid too much writers cramp.
- */
-  typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
-
-/**
- * Each Network LSA contains a list of attached routers
- *
- * m_attachedRouters is an STL list container to hold the addresses that have
- * been discovered and prepared for the advertisement.
- *
- * @see GlobalRouting::DiscoverLSAs ()
- */
-  ListOfAttachedRouters_t m_attachedRouters;
-
-/**
- * This is a tristate flag used internally in the SPF computation to mark
- * if an SPFVertex (a data structure representing a vertex in the SPF tree
- * -- a router) is new, is a candidate for a shortest path, or is in its
- * proper position in the tree.
- */
-  SPFStatus m_status;
-  uint32_t m_node_id;
-};
-
-std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
-
-/**
- * @brief An interface aggregated to a node to provide global routing info
- *
- * An interface aggregated to a node that provides global routing information
- * to a global route manager.  The presence of the interface indicates that
- * the node is a router.  The interface is the mechanism by which the router
- * advertises its connections to neighboring routers.  We're basically 
- * allowing the route manager to query for link state advertisements.
- */
-class GlobalRouter : public Object
-{
-public:
-/**
- * @brief The Interface ID of the Global Router interface.
- *
- * @see Object::GetObject ()
- */
-  static TypeId GetTypeId (void);
-
-/**
- * @brief Create a Global Router class 
- */
-  GlobalRouter ();
-
-
-  void SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing);
-  Ptr<Ipv4GlobalRouting> GetRoutingProtocol (void);
-
-/**
- * @brief Get the Router ID associated with this Global Router.
- *
- * The Router IDs are allocated in the RoutingEnvironment -- one per Router, 
- * starting at 0.0.0.1 and incrementing with each instantiation of a router.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @returns The Router ID associated with the Global Router.
- */
-  Ipv4Address GetRouterId (void) const;
-
-/**
- * @brief Walk the connected channels, discover the adjacent routers and build
- * the associated number of Global Routing Link State Advertisements that 
- * this router can export.
- *
- * This is a fairly expensive operation in that every time it is called
- * the current list of LSAs is built by walking connected point-to-point
- * channels and peeking into adjacent IPV4 stacks to get address information.
- * This is done to allow for limited dynamics of the Global Routing 
- * environment.  By that we mean that you can discover new link state 
- * advertisements after a network topology change by calling DiscoverLSAs 
- * and then by reading those advertisements.
- *
- * @see GlobalRoutingLSA
- * @see GlobalRouter::GetLSA ()
- * @returns The number of Global Routing Link State Advertisements.
- */
-  uint32_t DiscoverLSAs (void);
-
-/**
- * @brief Get the Number of Global Routing Link State Advertisements that this
- * router can export.
- *
- * To get meaningful information you must have previously called DiscoverLSAs.
- * After you know how many LSAs are present in the router, you may call 
- * GetLSA () to retrieve the actual advertisement.
- *
- * @see GlobalRouterLSA
- * @see GlobalRouting::DiscoverLSAs ()
- * @see GlobalRouting::GetLSA ()
- * @returns The number of Global Routing Link State Advertisements.
- */
-  uint32_t GetNumLSAs (void) const;
-
-/**
- * @brief Get a Global Routing Link State Advertisements that this router has 
- * said that it can export.
- *
- * This is a fairly inexpensive expensive operation in that the hard work
- * was done in GetNumLSAs.  We just copy the indicated Global Routing Link
- * State Advertisement into the requested GlobalRoutingLSA object.
- *
- * You must call GlobalRouter::GetNumLSAs before calling this method in 
- * order to discover the adjacent routers and build the advertisements.
- * GetNumLSAs will return the number of LSAs this router advertises.  
- * The parameter n (requested LSA number) must be in the range 0 to 
- * GetNumLSAs() - 1.
- *
- * @see GlobalRoutingLSA
- * @see GlobalRouting::GetNumLSAs ()
- * @param n The index number of the LSA you want to read.
- * @param lsa The GlobalRoutingLSA class to receive the LSA information.
- * @returns The number of Global Router Link State Advertisements.
- */
-  bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
-
-/**
- * @brief Inject a route to be circulated to other routers as an external
- * route
- *
- * @param network The Network to inject
- * @param networkMask The Network Mask to inject
- */
-  void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
-
-/**
- * @brief Get the number of injected routes that have been added
- * to the routing table.
- * @return number of injected routes
- */
-  uint32_t GetNInjectedRoutes (void);
-
-/**
- * @brief Return the injected route indexed by i
- * @param i the index of the route
- * @return a pointer to that Ipv4RoutingTableEntry is returned
- *
- */
-  Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
-
-/**
- * @brief Withdraw a route from the global unicast routing table.
- *
- * Calling this function will cause all indexed routes numbered above
- * index i to have their index decremented.  For instance, it is possible to
- * remove N injected routes by calling RemoveInjectedRoute (0) N times.
- *
- * @param i The index (into the injected routing list) of the route to remove.  
- *
- * @see GlobalRouter::WithdrawRoute ()
- */
-  void RemoveInjectedRoute (uint32_t i);
-
-/**
- * @brief Withdraw a route from the global unicast routing table.
- *
- * @param network The Network to withdraw
- * @param networkMask The Network Mask to withdraw
- * @return whether the operation succeeded (will return false if no such route)
- *
- * @see GlobalRouter::RemoveInjectedRoute ()
- */
-  bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
-
-private:
-  virtual ~GlobalRouter ();
-  void ClearLSAs (void);
-
-  Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
-  bool FindInterfaceForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
-  Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const;
-  bool AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const;
-  void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
-  void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
-  void ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
-
-  void ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA);
-  void BuildNetworkLSAs (NetDeviceContainer c);
-  Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
-
-
-  typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t;
-  ListOfLSAs_t m_LSAs;
-
-  Ipv4Address m_routerId;
-  Ptr<Ipv4GlobalRouting> m_routingProtocol;
-
-  typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes;
-  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI;
-  typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI;
-  InjectedRoutes m_injectedRoutes; // Routes we are exporting
-
-  // inherited from Object
-  virtual void DoDispose (void);
-
-/**
- * @brief Global Router copy construction is disallowed.
- */
-  GlobalRouter (GlobalRouter& sr);
-
-/**
- * @brief Global Router assignment operator is disallowed.
- */
-  GlobalRouter& operator= (GlobalRouter& sr);
-};
-
-} // namespace ns3
-
-#endif /* GLOBAL_ROUTER_INTERFACE_H */
--- a/src/routing/global-routing/global-routing.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2008 University of Washington
- * 
- * 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
- *
- */
-
-/**
- * \ingroup routing
- * \defgroup globalrouting Global Routing
- *
- * \section model Model
- *
- * ns-3 global routing performs pre-simulation static route computation
- * on a layer-3 Ipv4 topology.  The user API from the script level is
- * fairly minimal; once a topology has been constructed and addresses
- * assigned, the user may call ns3::GlobalRouteManager::PopulateRoutingTables()
- * and the simulator will initialize the routing database and set up
- * static unicast forwarding tables for each node.
- *
- * The model assumes that all nodes on an ns-3 channel are reachable to
- * one another, regardless of whether the nodes can use the channel
- * successfully (in the case of wireless).  Therefore, this model
- * should typically be used only on wired topologies.  Layer-2 bridge
- * devices are supported.  API does not yet exist to control the subset 
- * of a topology to which this global static routing is applied.
- * 
- * If the topology changes during the simulation, by default, routing
- * will not adjust.  There are two ways to make it adjust.
- * - Set the attribute Ipv4GlobalRouting::RespondToInterfaceEvents to true 
- * - Manually call the sequence of GlobalRouteManager methods to delte global
- *   routes, build global routing database, and initialize routes.
- *   There is a helper method that encapsulates this 
- *   (Ipv4GlobalRoutingHelper::RecomputeRoutingTables())
- * 
- * \section api API and Usage
- * 
- * Users must include ns3/global-route-manager.h header file.  After the
- * IPv4 topology has been built and addresses assigned, users call
- * ns3::GlobalRouteManager::PopulateRoutingTables (), prior to the 
- * ns3::Simulator::Run() call.  
- *
- * There are two attributes of Ipv4GlobalRouting that govern behavior.
- * - Ipv4GlobalRouting::RandomEcmpRouting
- * - Ipv4GlobalRouting::RespondToInterfaceEvents  
- *
- * \section impl Implementation
- *
- * A singleton object, ns3::GlobalRouteManager, builds a global routing
- * database of information about the topology, and executes a Dijkstra
- * Shortest Path First (SPF) algorithm on the topology for each node, and
- * stores the computed routes in each node's IPv4 forwarding table by
- * making use of the routing API in class ns3::Ipv4.
- *
- * The nodes that export data are those that have had an ns3::GlobalRouter
- * object aggregated to them.  The ns3::GlobalRouter can be thought of
- * as a per-node agent that exports topology information to the 
- * ns3::GlobalRouteManager.  When it comes time to build the global
- * routing database, the list of nodes is iterated and each node with
- * an ns3::GlobalRouter object is asked to export routing information
- * concerning the links to which it is attached.
- *
- * The format of the data exported conforms to the OSPFv2 standard
- * (http://www.ietf.org/rfc/rfc2328.txt).  In particular, the
- * information is exported in the form of ns3::GlobalLSA objects that
- * semantically match the Link State Advertisements of OSPF.  
- *
- * By using a standard data format for reporting topology, existing 
- * OSPF route computation code can be reused, and that is what is done
- * by the ns3::GlobalRouteManager.  The main computation functions are
- * ported from the quagga routing suite (http://www.quagga.net).
- * 
- */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/helper/ipv4-global-routing-helper.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-global-routing-helper.h"
+#include "ns3/global-router-interface.h"
+#include "ns3/ipv4-global-routing.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE("GlobalRoutingHelper");
+
+namespace ns3 {
+
+Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper ()
+{}
+
+Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &o)
+{
+}
+
+Ipv4GlobalRoutingHelper* 
+Ipv4GlobalRoutingHelper::Copy (void) const 
+{
+  return new Ipv4GlobalRoutingHelper (*this); 
+}
+
+Ptr<Ipv4RoutingProtocol> 
+Ipv4GlobalRoutingHelper::Create (Ptr<Node> node) const
+{
+  NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << 
+		node->GetId ());
+
+  Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
+  node->AggregateObject (globalRouter);
+
+  NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
+  Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
+  globalRouter->SetRoutingProtocol (globalRouting);
+
+  return globalRouting;
+}
+
+void 
+Ipv4GlobalRoutingHelper::PopulateRoutingTables (void)
+{
+  GlobalRouteManager::BuildGlobalRoutingDatabase ();
+  GlobalRouteManager::InitializeRoutes ();
+}
+void 
+Ipv4GlobalRoutingHelper::RecomputeRoutingTables (void)
+{
+  GlobalRouteManager::DeleteGlobalRoutes ();
+  GlobalRouteManager::BuildGlobalRoutingDatabase ();
+  GlobalRouteManager::InitializeRoutes ();
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/helper/ipv4-global-routing-helper.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_GLOBAL_ROUTING_HELPER_H
+#define IPV4_GLOBAL_ROUTING_HELPER_H
+
+#include "ns3/node-container.h"
+#include "ns3/ipv4-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv4GlobalRouting objects
+ */
+class Ipv4GlobalRoutingHelper  : public Ipv4RoutingHelper
+{
+public:
+  /**
+   * \brief Construct a GlobalRoutingHelper to make life easier for managing
+   * global routing tasks.
+   */
+  Ipv4GlobalRoutingHelper ();
+
+  /**
+   * \brief Construct a GlobalRoutingHelper from another previously initialized
+   * instance (Copy Constructor).
+   */
+  Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &);
+
+  /**
+   * \internal
+   * \returns pointer to clone of this Ipv4GlobalRoutingHelper
+   *
+   * This method is mainly for internal use by the other helpers;
+   * clients are expected to free the dynamic memory allocated by this method
+   */
+  Ipv4GlobalRoutingHelper* Copy (void) const;
+
+  /**
+   * \param node the node on which the routing protocol will run
+   * \returns a newly-created routing protocol
+   *
+   * This method will be called by ns3::InternetStackHelper::Install
+   */
+  virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+
+  /**
+   * \brief Build a routing database and initialize the routing tables of
+   * the nodes in the simulation.  Makes all nodes in the simulation into
+   * routers.
+   *
+   * All this function does is call the functions
+   * BuildGlobalRoutingDatabase () and  InitializeRoutes ().
+   *
+   */
+  static void PopulateRoutingTables (void);
+  /**
+   * \brief Remove all routes that were previously installed in a prior call
+   * to either PopulateRoutingTables() or RecomputeRoutingTables(), and 
+   * add a new set of routes.  
+   * 
+   * This method does not change the set of nodes
+   * over which GlobalRouting is being used, but it will dynamically update
+   * its representation of the global topology before recomputing routes.
+   * Users must first call PopulateRoutingTables() and then may subsequently
+   * call RecomputeRoutingTables() at any later time in the simulation.
+   *
+   */
+  static void RecomputeRoutingTables (void);
+private:
+  /**
+   * \internal
+   * \brief Assignment operator declared private and not implemented to disallow
+   * assignment and prevent the compiler from happily inserting its own.
+   */
+  Ipv4GlobalRoutingHelper &operator = (const Ipv4GlobalRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV4_GLOBAL_ROUTING_HELPER_H */
--- a/src/routing/global-routing/ipv4-global-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,551 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2008 University of Washington
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/object.h"
-#include "ns3/packet.h"
-#include "ns3/net-device.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/ipv4-routing-table-entry.h"
-#include "ns3/boolean.h"
-#include "ipv4-global-routing.h"
-#include "global-route-manager.h"
-#include <vector>
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4GlobalRouting");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRouting);
-
-TypeId 
-Ipv4GlobalRouting::GetTypeId (void)
-{ 
-  static TypeId tid = TypeId ("ns3::Ipv4GlobalRouting")
-    .SetParent<Object> ()
-    .AddAttribute ("RandomEcmpRouting",
-                   "Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",
-                   BooleanValue(false),
-                   MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),
-                   MakeBooleanChecker ())
-    .AddAttribute ("RespondToInterfaceEvents",
-                   "Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
-                   BooleanValue(false),
-                   MakeBooleanAccessor (&Ipv4GlobalRouting::m_respondToInterfaceEvents),
-                   MakeBooleanChecker ())
-    ;
-  return tid;
-}
-
-Ipv4GlobalRouting::Ipv4GlobalRouting () 
-: m_randomEcmpRouting (false),
-  m_respondToInterfaceEvents (false) 
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv4GlobalRouting::~Ipv4GlobalRouting ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void 
-Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest, 
-                                   Ipv4Address nextHop, 
-                                   uint32_t interface)
-{
-  NS_LOG_FUNCTION (dest << nextHop << interface);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, nextHop, interface);
-  m_hostRoutes.push_back (route);
-}
-
-void 
-Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest, 
-                                   uint32_t interface)
-{
-  NS_LOG_FUNCTION (dest << interface);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, interface);
-  m_hostRoutes.push_back (route);
-}
-
-void 
-Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network, 
-                                      Ipv4Mask networkMask, 
-                                      Ipv4Address nextHop, 
-                                      uint32_t interface)
-{
-  NS_LOG_FUNCTION (network << networkMask << nextHop << interface);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            nextHop,
-                                            interface);
-  m_networkRoutes.push_back (route);
-}
-
-void 
-Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network, 
-                                      Ipv4Mask networkMask, 
-                                      uint32_t interface)
-{
-  NS_LOG_FUNCTION (network << networkMask << interface);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            interface);
-  m_networkRoutes.push_back (route);
-}
-
-void 
-Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network, 
-                                         Ipv4Mask networkMask,
-                                         Ipv4Address nextHop,
-                                         uint32_t interface)
-{
-  NS_LOG_FUNCTION (network << networkMask << nextHop);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-      networkMask,
-      nextHop,
-      interface);
-  m_ASexternalRoutes.push_back (route);
-}
-
-
-Ptr<Ipv4Route>
-Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC ("Looking for route for destination " << dest);
-  Ptr<Ipv4Route> rtentry = 0;
-  // store all available routes that bring packets to their destination
-  typedef std::vector<Ipv4RoutingTableEntry*> RouteVec_t;
-  RouteVec_t allRoutes;
-
-  NS_LOG_LOGIC ("Number of m_hostRoutes = " << m_hostRoutes.size ());
-  for (HostRoutesCI i = m_hostRoutes.begin (); 
-       i != m_hostRoutes.end (); 
-       i++) 
-    {
-      NS_ASSERT ((*i)->IsHost ());
-      if ((*i)->GetDest ().IsEqual (dest)) 
-        {
-          if (oif != 0)
-            {
-              if (oif != m_ipv4->GetNetDevice((*i)->GetInterface ()))
-                {
-                  NS_LOG_LOGIC ("Not on requested interface, skipping");
-                  continue;
-                }
-            }
-          allRoutes.push_back (*i);
-          NS_LOG_LOGIC (allRoutes.size () << "Found global host route" << *i); 
-        }
-    }
-  if (allRoutes.size () == 0) // if no host route is found
-    {
-      NS_LOG_LOGIC ("Number of m_networkRoutes" << m_networkRoutes.size ());
-      for (NetworkRoutesI j = m_networkRoutes.begin (); 
-           j != m_networkRoutes.end (); 
-           j++) 
-        {
-          Ipv4Mask mask = (*j)->GetDestNetworkMask ();
-          Ipv4Address entry = (*j)->GetDestNetwork ();
-          if (mask.IsMatch (dest, entry)) 
-            {
-              if (oif != 0)
-                {
-                  if (oif != m_ipv4->GetNetDevice((*j)->GetInterface ()))
-                    {
-                      NS_LOG_LOGIC ("Not on requested interface, skipping");
-                      continue;
-                    }
-                }
-              allRoutes.push_back (*j);
-              NS_LOG_LOGIC (allRoutes.size () << "Found global network route" << *j);
-            }
-        }
-    }
-  if (allRoutes.size () == 0)  // consider external if no host/network found
-    {
-      for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
-           k != m_ASexternalRoutes.end ();
-           k++)
-        {
-          Ipv4Mask mask = (*k)->GetDestNetworkMask ();
-          Ipv4Address entry = (*k)->GetDestNetwork ();
-          if (mask.IsMatch (dest, entry))
-            {
-              NS_LOG_LOGIC ("Found external route" << *k);
-              if (oif != 0)
-                {
-                  if (oif != m_ipv4->GetNetDevice((*k)->GetInterface ()))
-                    {
-                      NS_LOG_LOGIC ("Not on requested interface, skipping");
-                      continue;
-                    }
-                }
-              allRoutes.push_back (*k);
-              break;
-            }
-        }
-    }
-  if (allRoutes.size () > 0 ) // if route(s) is found
-    {
-      // pick up one of the routes uniformly at random if random
-      // ECMP routing is enabled, or always select the first route
-      // consistently if random ECMP routing is disabled
-      uint32_t selectIndex;
-      if (m_randomEcmpRouting)
-        {
-          selectIndex = m_rand.GetInteger (0, allRoutes.size ()-1);
-        }
-      else 
-        {
-          selectIndex = 0;
-        }
-      Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex); 
-      // create a Ipv4Route object from the selected routing table entry
-      rtentry = Create<Ipv4Route> ();
-      rtentry->SetDestination (route->GetDest ());
-      // XXX handle multi-address case
-      rtentry->SetSource (m_ipv4->GetAddress (route->GetInterface(), 0).GetLocal ());
-      rtentry->SetGateway (route->GetGateway ());
-      uint32_t interfaceIdx = route->GetInterface ();
-      rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
-      return rtentry;
-    }
-  else 
-    {
-      return 0;
-    }
-}
-
-uint32_t 
-Ipv4GlobalRouting::GetNRoutes (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t n = 0;
-  n += m_hostRoutes.size ();
-  n += m_networkRoutes.size ();
-  n += m_ASexternalRoutes.size ();
-  return n;
-}
-
-Ipv4RoutingTableEntry *
-Ipv4GlobalRouting::GetRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (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;
-  if (index < m_networkRoutes.size())
-    {
-      for (NetworkRoutesI j = m_networkRoutes.begin (); 
-          j != m_networkRoutes.end (); 
-          j++) 
-        {
-          if (tmp == index)
-            {
-              return *j;
-            }
-          tmp++;
-        }
-    }
-  index -= m_networkRoutes.size();
-  tmp = 0;
-  for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); 
-       k != m_ASexternalRoutes.end (); 
-       k++) 
-  {
-    if (tmp == index)
-    {
-      return *k;
-    }
-    tmp++;
-  }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-void 
-Ipv4GlobalRouting::RemoveRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (index);
-  if (index < m_hostRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (HostRoutesI i = m_hostRoutes.begin (); 
-           i != m_hostRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_hostRoutes.size());
-              delete *i;
-              m_hostRoutes.erase (i);
-              NS_LOG_LOGIC ("Done removing host route " << index << "; host route remaining size = " << m_hostRoutes.size());
-              return;
-            }
-          tmp++;
-        }
-    }
-  index -= m_hostRoutes.size ();
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_networkRoutes.size());
-          delete *j;
-          m_networkRoutes.erase (j);
-          NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
-          return;
-        }
-      tmp++;
-    }
-  index -= m_networkRoutes.size ();
-  tmp = 0;
-  for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); 
-         k != m_ASexternalRoutes.end (); 
-         k++) 
-    {
-      if (tmp == index)
-      {
-        NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size());
-        delete *k;
-        m_ASexternalRoutes.erase (k);
-        NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
-        return;
-      }
-      tmp++;
-    }
-  NS_ASSERT (false);
-}
-
-void
-Ipv4GlobalRouting::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  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);
-    }
-  for (ASExternalRoutesI l = m_ASexternalRoutes.begin (); 
-         l != m_ASexternalRoutes.end (); 
-         l = m_ASexternalRoutes.erase (l)) 
-    {
-      delete (*l);
-    }
-
-  Ipv4RoutingProtocol::DoDispose ();
-}
-
-Ptr<Ipv4Route>
-Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{      
-
-//
-// First, see if this is a multicast packet we have a route for.  If we
-// have a route, then send the packet down each of the specified interfaces.
-//
-  if (header.GetDestination().IsMulticast ())
-    {
-      NS_LOG_LOGIC ("Multicast destination-- returning false");
-      return 0; // Let other routing protocols try to handle this
-    }
-//
-// See if this is a unicast packet we have a route for.
-//
-  NS_LOG_LOGIC ("Unicast destination- looking up");
-  Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), oif);
-  if (rtentry)
-    {
-      sockerr = Socket::ERROR_NOTERROR;
-    }
-  else
-    {
-      sockerr = Socket::ERROR_NOROUTETOHOST;
-    }
-  return rtentry;
-}
-
-bool 
-Ipv4GlobalRouting::RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                             LocalDeliverCallback lcb, ErrorCallback ecb) 
-{ 
-
-  NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
-  // Check if input device supports IP
-  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
-  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
-
-  if (header.GetDestination ().IsMulticast ())
-    {
-      NS_LOG_LOGIC ("Multicast destination-- returning false");
-      return false; // Let other routing protocols try to handle this
-    }
-
-  if (header.GetDestination ().IsBroadcast ())
-    {
-      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
-      // TODO:  Local Deliver for broadcast
-      // TODO:  Forward broadcast
-    }
-
-  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
-  // Right now, we will be permissive and allow a source to send us
-  // a packet to one of our other interface addresses; that is, the
-  // destination unicast address does not match one of the iif addresses,
-  // but we check our other interfaces.  This could be an option
-  // (to remove the outer loop immediately below and just check iif).
-  for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
-    {
-      for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
-        {
-          Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
-          Ipv4Address addr = iaddr.GetLocal ();
-          if (addr.IsEqual (header.GetDestination ()))
-            {
-              if (j == iif)
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
-                }
-              else
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ());
-                }
-              lcb (p, header, iif);
-              return true;
-            }
-          if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
-            {
-              NS_LOG_LOGIC ("For me (interface broadcast address)");
-              lcb (p, header, iif);
-              return true;
-            }
-          NS_LOG_LOGIC ("Address "<< addr << " not a match");
-        }
-    }
-  // Check if input device supports IP forwarding
-  if (m_ipv4->IsForwarding (iif) == false)
-    {
-      NS_LOG_LOGIC ("Forwarding disabled for this interface");
-      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
-      return false;
-    }
-  // Next, try to find a route
-  NS_LOG_LOGIC ("Unicast destination- looking up global route");
-  Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination ());
-  if (rtentry != 0)
-    {
-      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
-      ucb (rtentry, p, header);
-      return true;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
-      return false; // Let other routing protocols try to handle this
-                    // route request.
-    }
-}
-void 
-Ipv4GlobalRouting::NotifyInterfaceUp (uint32_t i)
-{
-  NS_LOG_FUNCTION (this << i);
-  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
-    {
-      GlobalRouteManager::DeleteGlobalRoutes ();
-      GlobalRouteManager::BuildGlobalRoutingDatabase ();
-      GlobalRouteManager::InitializeRoutes ();
-    }
-}
-
-void 
-Ipv4GlobalRouting::NotifyInterfaceDown (uint32_t i)
-{
-  NS_LOG_FUNCTION (this << i);
-  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
-    {
-      GlobalRouteManager::DeleteGlobalRoutes ();
-      GlobalRouteManager::BuildGlobalRoutingDatabase ();
-      GlobalRouteManager::InitializeRoutes ();
-    }
-}
-
-void 
-Ipv4GlobalRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
-  NS_LOG_FUNCTION (this << interface << address);
-  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
-    {
-      GlobalRouteManager::DeleteGlobalRoutes ();
-      GlobalRouteManager::BuildGlobalRoutingDatabase ();
-      GlobalRouteManager::InitializeRoutes ();
-    }
-}
-
-void 
-Ipv4GlobalRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
-  NS_LOG_FUNCTION (this << interface << address);
-  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
-    {
-      GlobalRouteManager::DeleteGlobalRoutes ();
-      GlobalRouteManager::BuildGlobalRoutingDatabase ();
-      GlobalRouteManager::InitializeRoutes ();
-    }
-}
-
-void 
-Ipv4GlobalRouting::SetIpv4 (Ptr<Ipv4> ipv4)
-{
-  NS_LOG_FUNCTION(this << ipv4);
-  NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
-  m_ipv4 = ipv4;
-}
-
-
-}//namespace ns3
--- a/src/routing/global-routing/ipv4-global-routing.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2008 University of Washington
-//
-// 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 IPV4_GLOBAL_ROUTING_H
-#define IPV4_GLOBAL_ROUTING_H
-
-#include <list>
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-header.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/random-variable.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4RoutingTableEntry;
-class Ipv4MulticastRoutingTableEntry;
-class Node;
-
-
-/**
- * \brief Global routing protocol for IP version 4 stacks.
- *
- * In ns-3 we have the concept of a pluggable routing protocol.  Routing
- * protocols are added to a list maintained by the Ipv4L3Protocol.  Every 
- * stack gets one routing protocol for free -- the Ipv4StaticRouting routing
- * protocol is added in the constructor of the Ipv4L3Protocol (this is the 
- * piece of code that implements the functionality of the IP layer).
- *
- * As an option to running a dynamic routing protocol, a GlobalRouteManager
- * object has been created to allow users to build routes for all participating
- * nodes.  One can think of this object as a "routing oracle"; it has
- * an omniscient view of the topology, and can construct shortest path
- * routes between all pairs of nodes.  These routes must be stored 
- * somewhere in the node, so therefore this class Ipv4GlobalRouting
- * is used as one of the pluggable routing protocols.  It is kept distinct
- * from Ipv4StaticRouting because these routes may be dynamically cleared
- * and rebuilt in the middle of the simulation, while manually entered
- * routes into the Ipv4StaticRouting may need to be kept distinct.
- *
- * This class deals with Ipv4 unicast routes only.
- *
- * \see Ipv4RoutingProtocol
- * \see GlobalRouteManager
- */
-class Ipv4GlobalRouting : public Ipv4RoutingProtocol
-{
-public:
-  static TypeId GetTypeId (void);
-/**
- * \brief Construct an empty Ipv4GlobalRouting routing protocol,
- *
- * The Ipv4GlobalRouting class supports host and network unicast routes.
- * This method initializes the lists containing these routes to empty.
- *
- * \see Ipv4GlobalRouting
- */
-  Ipv4GlobalRouting ();
-  virtual ~Ipv4GlobalRouting ();
-
-  // These methods inherited from base class
-  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
-  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                             LocalDeliverCallback lcb, ErrorCallback ecb);
-  virtual void NotifyInterfaceUp (uint32_t interface);
-  virtual void NotifyInterfaceDown (uint32_t interface);
-  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
-  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
-  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
-
-/**
- * \brief Add a host route to the global routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param nextHop The Ipv4Address of the next hop in the route.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
-  void AddHostRouteTo (Ipv4Address dest, 
-                       Ipv4Address nextHop, 
-                       uint32_t interface);
-/**
- * \brief Add a host route to the global routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
-  void AddHostRouteTo (Ipv4Address dest, 
-                       uint32_t interface);
-
-/**
- * \brief Add a network route to the global routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param nextHop The next hop in the route to the destination network.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          Ipv4Address nextHop, 
-                          uint32_t interface);
-
-/**
- * \brief Add a network route to the global routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          uint32_t interface);
-
-/**
- * \brief Add an external route to the global routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param nextHop The next hop Ipv4Address
- * \param interface The network interface index used to send packets to the
- * destination.
- */
-  void AddASExternalRouteTo (Ipv4Address network,
-                             Ipv4Mask networkMask,
-                             Ipv4Address nextHop,
-                             uint32_t interface);
-
-/**
- * \brief Get the number of individual unicast routes that have been added
- * to the routing table.
- *
- * \warning The default route counts as one of the routes.
- */
-  uint32_t GetNRoutes (void);
-
-/**
- * \brief Get a route from the global unicast routing table.
- *
- * Externally, the unicast global routing table appears simply as a table with
- * n entries.  The one subtlety of note is that if a default route has been set
- * it will appear as the zeroth entry in the table.  This means that if you
- * add only a default route, the table will have one entry that can be accessed
- * either by explicitly calling GetDefaultRoute () or by calling GetRoute (0).
- * 
- * Similarly, if the default route has been set, calling RemoveRoute (0) will
- * remove the default route.
- *
- * \param i The index (into the routing table) of the route to retrieve.  If
- * the default route has been set, it will occupy index zero.
- * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
- * a zero pointer is returned.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4GlobalRouting::RemoveRoute
- */
-  Ipv4RoutingTableEntry *GetRoute (uint32_t i);
-
-/**
- * \brief Remove a route from the global unicast routing table.
- *
- * Externally, the unicast global routing table appears simply as a table with
- * n entries.  The one subtlety of note is that if a default route has been set
- * it will appear as the zeroth entry in the table.  This means that if the
- * default route has been set, calling RemoveRoute (0) will remove the
- * default route.
- *
- * \param i The index (into the routing table) of the route to remove.  If
- * the default route has been set, it will occupy index zero.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4GlobalRouting::GetRoute
- * \see Ipv4GlobalRouting::AddRoute
- */
-  void RemoveRoute (uint32_t i);
-
-protected:
-  void DoDispose (void);
-
-private:
-  /// Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently
-  bool m_randomEcmpRouting;
-  /// Set to true if this interface should respond to interface events by globallly recomputing routes 
-  bool m_respondToInterfaceEvents;
-  /// A uniform random number generator for randomly routing packets among ECMP 
-  UniformVariable m_rand;
-
-  typedef std::list<Ipv4RoutingTableEntry *> HostRoutes;
-  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator HostRoutesCI;
-  typedef std::list<Ipv4RoutingTableEntry *>::iterator HostRoutesI;
-  typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
-  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
-  typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
-  typedef std::list<Ipv4RoutingTableEntry *> ASExternalRoutes;
-  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator ASExternalRoutesCI;
-  typedef std::list<Ipv4RoutingTableEntry *>::iterator ASExternalRoutesI;
-
-  Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif = 0);
-
-  HostRoutes m_hostRoutes;
-  NetworkRoutes m_networkRoutes;
-  ASExternalRoutes m_ASexternalRoutes; // External routes imported
-  
-  Ptr<Ipv4> m_ipv4;
-};
-
-} // Namespace ns3
-
-#endif /* IPV4_GLOBAL_ROUTING_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/candidate-queue.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <algorithm>
+#include <iostream>
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "candidate-queue.h"
+#include "global-route-manager-impl.h"
+
+NS_LOG_COMPONENT_DEFINE ("CandidateQueue");
+
+namespace ns3 {
+
+std::ostream&
+operator<< (std::ostream& os, const SPFVertex::VertexType& t)
+{
+  switch (t)
+    {
+    case SPFVertex::VertexRouter:  os << "router"; break;
+    case SPFVertex::VertexNetwork: os << "network"; break;
+    default:                       os << "unknown"; break;
+    };
+  return os;
+}
+
+std::ostream& 
+operator<< (std::ostream& os, const CandidateQueue& q)
+{
+  typedef CandidateQueue::CandidateList_t List_t;
+  typedef List_t::const_iterator CIter_t;
+  const CandidateQueue::CandidateList_t& list = q.m_candidates;
+
+  os << "*** CandidateQueue Begin (<id, distance, LSA-type>) ***" << std::endl;
+  for (CIter_t iter = list.begin (); iter != list.end (); iter++)
+    {
+      os << "<" 
+         << (*iter)->GetVertexId () << ", " 
+         << (*iter)->GetDistanceFromRoot () << ", " 
+         << (*iter)->GetVertexType () << ">" << std::endl;
+    }
+  os << "*** CandidateQueue End ***";
+  return os;
+}
+
+CandidateQueue::CandidateQueue()
+  : m_candidates ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+CandidateQueue::~CandidateQueue()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Clear ();
+}
+
+  void
+CandidateQueue::Clear (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  while (!m_candidates.empty ())
+    {
+      SPFVertex *p = Pop ();
+      delete p;
+      p = 0;
+    }
+}
+
+  void
+CandidateQueue::Push (SPFVertex *vNew)
+{
+  NS_LOG_FUNCTION (this << vNew);
+
+  CandidateList_t::iterator i = std::upper_bound (
+    m_candidates.begin (), m_candidates.end (), vNew,
+    &CandidateQueue::CompareSPFVertex
+    );
+  m_candidates.insert (i, vNew);
+}
+
+  SPFVertex *
+CandidateQueue::Pop (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_candidates.empty ())
+    {
+      return 0;
+    }
+
+  SPFVertex *v = m_candidates.front ();
+  m_candidates.pop_front ();
+  return v;
+}
+
+  SPFVertex *
+CandidateQueue::Top (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_candidates.empty ())
+    {
+      return 0;
+    }
+
+  return m_candidates.front ();
+}
+
+  bool
+CandidateQueue::Empty (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_candidates.empty ();
+}
+
+  uint32_t
+CandidateQueue::Size (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_candidates.size ();
+}
+
+  SPFVertex *
+CandidateQueue::Find (const Ipv4Address addr) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  CandidateList_t::const_iterator i = m_candidates.begin ();
+
+  for (; i != m_candidates.end (); i++)
+    {
+      SPFVertex *v = *i;
+      if (v->GetVertexId() == addr)
+        {
+          return v;
+        }
+    }
+
+  return 0;
+}
+
+  void
+CandidateQueue::Reorder (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_candidates.sort (&CandidateQueue::CompareSPFVertex);
+  NS_LOG_LOGIC ("After reordering the CandidateQueue");
+  NS_LOG_LOGIC (*this);
+}
+
+/*
+ * In this implementation, SPFVertex follows the ordering where
+ * a vertex is ranked first if its GetDistanceFromRoot () is smaller;
+ * In case of a tie, NetworkLSA is always ranked before RouterLSA.
+ *
+ * This ordering is necessary for implementing ECMP
+ */
+bool 
+CandidateQueue::CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2)
+{
+  NS_LOG_FUNCTION (&v1 << &v2);
+
+  bool result = false;
+  if (v1->GetDistanceFromRoot () < v2->GetDistanceFromRoot ())
+    {  
+      result = true;
+    }
+  else if (v1->GetDistanceFromRoot () == v2->GetDistanceFromRoot ())
+    {
+      if (v1->GetVertexType () == SPFVertex::VertexNetwork 
+          && v2->GetVertexType () == SPFVertex::VertexRouter)
+        {
+          result = true;
+        }
+    }
+  return result;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/candidate-queue.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,200 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * 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:  Craig Dowell (craigdo@ee.washington.edu)
+ */
+
+#ifndef CANDIDATE_QUEUE_H
+#define CANDIDATE_QUEUE_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class SPFVertex;
+
+/**  
+ * \brief A Candidate Queue used in static routing.
+ *
+ * The CandidateQueue is used in the OSPF shortest path computations.  It
+ * is a priority queue used to store candidates for the shortest path to a
+ * given network.  
+ *
+ * The queue holds Shortest Path First Vertex pointers and orders them
+ * according to the lowest value of the field m_distanceFromRoot.  Remaining
+ * vertices are ordered according to increasing distance.  This implements a
+ * priority queue.
+ *
+ * Although a STL priority_queue almost does what we want, the requirement
+ * for a Find () operation, the dynamic nature of the data and the derived
+ * requirement for a Reorder () operation led us to implement this simple 
+ * enhanced priority queue.
+ */
+class CandidateQueue
+{
+public:
+/**
+ * @brief Create an empty SPF Candidate Queue.  
+ * @internal
+ *
+ * @see SPFVertex
+ */
+  CandidateQueue ();
+
+/**
+ * @internal Destroy an SPF Candidate Queue and release any resources held 
+ * by the contents.
+ * @internal
+ *
+ * @see SPFVertex
+ */
+  virtual ~CandidateQueue ();
+
+/**
+ * @brief Empty the Candidate Queue and release all of the resources 
+ * associated with the Shortest Path First Vertex pointers in the queue.
+ * @internal
+ *
+ * @see SPFVertex
+ */
+  void Clear (void);
+
+/**
+ * @brief Push a Shortest Path First Vertex pointer onto the queue according
+ * to the priority scheme.
+ * @internal
+ * 
+ * On completion, the top of the queue will hold the Shortest Path First
+ * Vertex pointer that points to a vertex having lowest value of the field
+ * m_distanceFromRoot.  Remaining vertices are ordered according to 
+ * increasing distance.
+ *
+ * @see SPFVertex
+ * @param vNew The Shortest Path First Vertex to add to the queue.
+ */
+  void Push (SPFVertex *vNew);
+
+/**
+ * @brief Pop the Shortest Path First Vertex pointer at the top of the queue.
+ * @internal
+ *
+ * The caller is given the responsibility for releasing the resources 
+ * associated with the vertex.
+ *
+ * @see SPFVertex
+ * @see Top ()
+ * @returns The Shortest Path First Vertex pointer at the top of the queue.
+ */
+  SPFVertex* Pop (void);
+
+/**
+ * @brief Return the Shortest Path First Vertex pointer at the top of the 
+ * queue.  
+ * @internal
+ *
+ * This method does not pop the SPFVertex* off of the queue, it simply 
+ * returns the pointer.
+ *
+ * @see SPFVertex
+ * @see Pop ()
+ * @returns The Shortest Path First Vertex pointer at the top of the queue.
+ */
+  SPFVertex* Top (void) const;
+
+/**
+ * @brief Test the Candidate Queue to determine if it is empty.
+ * @internal
+ *
+ * @returns True if the queue is empty, false otherwise.
+ */
+  bool Empty (void) const;
+
+/**
+ * @brief Return the number of Shortest Path First Vertex pointers presently
+ * stored in the Candidate Queue.
+ * @internal
+ *
+ * @see SPFVertex
+ * @returns The number of SPFVertex* pointers in the Candidate Queue.
+ */
+  uint32_t Size (void) const;
+
+/**
+ * @brief Searches the Candidate Queue for a Shortest Path First Vertex 
+ * pointer that points to a vertex having the given IP address.
+ * @internal
+ *
+ * @see SPFVertex
+ * @param addr The IP address to search for.
+ * @returns The SPFVertex* pointer corresponding to the given IP address.
+ */
+  SPFVertex* Find (const Ipv4Address addr) const;
+
+/**
+ * @brief Reorders the Candidate Queue according to the priority scheme.  
+ * @internal
+ * 
+ * On completion, the top of the queue will hold the Shortest Path First
+ * Vertex pointer that points to a vertex having lowest value of the field
+ * m_distanceFromRoot.  Remaining vertices are ordered according to 
+ * increasing distance.
+ *
+ * This method is provided in case the values of m_distanceFromRoot change
+ * during the routing calculations.
+ *
+ * @see SPFVertex
+ */
+  void Reorder (void);
+
+private:
+/**
+ * Candidate Queue copy construction is disallowed (not implemented) to 
+ * prevent the compiler from slipping in incorrect versions that don't
+ * properly deal with deep copies.
+ * \param sr object to copy
+ */
+  CandidateQueue (CandidateQueue& sr);
+
+/**
+ * Candidate Queue assignment operator is disallowed (not implemented) to
+ * prevent the compiler from slipping in incorrect versions that don't
+ * properly deal with deep copies.
+ * \param sr object to assign
+ */
+  CandidateQueue& operator= (CandidateQueue& sr);
+/**
+ * \brief return true if v1 < v2
+ *
+ * SPFVertexes are added into the queue according to the ordering
+ * defined by this method. If v1 should be popped before v2, this 
+ * method return true; false otherwise
+ *
+ * \return True if v1 should be popped before v2; false otherwise
+ */
+  static bool CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2);
+
+  typedef std::list<SPFVertex*> CandidateList_t;
+  CandidateList_t m_candidates;
+
+  friend std::ostream& operator<< (std::ostream& os, const CandidateQueue& q);
+};
+
+} // namespace ns3
+
+#endif /* CANDIDATE_QUEUE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager-impl.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,2402 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
+ * 
+ * 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:  Tom Henderson (tomhend@u.washington.edu)
+ * 
+ * Kunihiro Ishigura, Toshiaki Takada (GNU Zebra) are attributed authors
+ * of the quagga 0.99.7/src/ospfd/ospf_spf.c code which was ported here
+ */
+
+#include <utility>
+#include <vector>
+#include <queue>
+#include <algorithm>
+#include <iostream>
+#include "ns3/assert.h"
+#include "ns3/fatal-error.h"
+#include "ns3/log.h"
+#include "ns3/node-list.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/mpi-interface.h"
+#include "global-router-interface.h"
+#include "global-route-manager-impl.h"
+#include "candidate-queue.h"
+#include "ipv4-global-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("GlobalRouteManager");
+
+namespace ns3 {
+
+std::ostream& 
+operator<< (std::ostream& os, const SPFVertex::NodeExit_t& exit)
+{
+  os << "(" << exit.first << " ," << exit.second << ")";
+  return os;
+}
+
+std::ostream& 
+operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs)
+{
+  typedef SPFVertex::ListOfSPFVertex_t::const_iterator CIter_t;
+  os << "{";
+  for (CIter_t iter = vs.begin (); iter != vs.end ();)
+    {
+      os << (*iter)->m_vertexId;
+      if (++iter != vs.end ()) 
+        {
+          os << ", ";
+        }
+      else 
+        { 
+          break;
+        }
+    }
+  os << "}";
+  return os;
+}
+
+// ---------------------------------------------------------------------------
+//
+// SPFVertex Implementation
+//
+// ---------------------------------------------------------------------------
+
+SPFVertex::SPFVertex () : 
+  m_vertexType (VertexUnknown), 
+  m_vertexId ("255.255.255.255"), 
+  m_lsa (0),
+  m_distanceFromRoot (SPF_INFINITY), 
+  m_rootOif (SPF_INFINITY),
+  m_nextHop ("0.0.0.0"),
+  m_parents (),
+  m_children (),
+  m_vertexProcessed (false)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) : 
+  m_vertexId (lsa->GetLinkStateId ()),
+  m_lsa (lsa),
+  m_distanceFromRoot (SPF_INFINITY), 
+  m_rootOif (SPF_INFINITY),
+  m_nextHop ("0.0.0.0"),
+  m_parents (),
+  m_children (),
+  m_vertexProcessed (false)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) 
+    {
+      NS_LOG_LOGIC ("Setting m_vertexType to VertexRouter");
+      m_vertexType = SPFVertex::VertexRouter;
+    }
+  else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA) 
+    { 
+      NS_LOG_LOGIC ("Setting m_vertexType to VertexNetwork");
+      m_vertexType = SPFVertex::VertexNetwork;
+    }
+}
+
+SPFVertex::~SPFVertex ()
+{
+  NS_LOG_FUNCTION (m_vertexId);
+  
+  NS_LOG_LOGIC ("Children vertices - " << m_children);
+  NS_LOG_LOGIC ("Parent verteices - " << m_parents);
+
+  // find this node from all its parents and remove the entry of this node
+  // from all its parents
+  for (ListOfSPFVertex_t::iterator piter = m_parents.begin (); 
+      piter != m_parents.end (); 
+      piter++)
+    {
+      // remove the current vertex from its parent's children list. Check
+      // if the size of the list is reduced, or the child<->parent relation
+      // is not bidirectional
+      uint32_t orgCount = (*piter)->m_children.size ();
+      (*piter)->m_children.remove (this);
+      uint32_t newCount = (*piter)->m_children.size ();
+      if (orgCount > newCount)
+        {
+          NS_ASSERT_MSG (orgCount > newCount, "Unable to find the current vertex from its parents --- impossible!");
+        }
+    }
+
+  // delete children
+  while (m_children.size () > 0)
+    {
+      // pop out children one by one. Some children may disapper 
+      // when deleting some other children in the list. As a result,
+      // it is necessary to use pop to walk through all children, instead
+      // of using iterator.
+      //
+      // Note that m_children.pop_front () is not necessary as this
+      // p is removed from the children list when p is deleted
+      SPFVertex* p = m_children.front ();
+      // 'p' == 0, this child is already deleted by its other parent
+      if (p == 0) continue;
+      NS_LOG_LOGIC ("Parent vertex-" << m_vertexId << " deleting its child vertex-" << p->GetVertexId ());
+      delete p;
+      p = 0;
+    }
+  m_children.clear ();
+  // delete parents
+  m_parents.clear ();
+  // delete root exit direction
+  m_ecmpRootExits.clear ();
+
+  NS_LOG_LOGIC ("Vertex-" << m_vertexId << " completed deleted");
+}
+
+  void 
+SPFVertex::SetVertexType (SPFVertex::VertexType type)
+{
+  NS_LOG_FUNCTION (type);
+  m_vertexType = type;
+}
+
+  SPFVertex::VertexType 
+SPFVertex::GetVertexType (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_vertexType;
+}
+
+  void 
+SPFVertex::SetVertexId (Ipv4Address id)
+{
+  NS_LOG_FUNCTION (id);
+  m_vertexId = id;
+}
+
+  Ipv4Address
+SPFVertex::GetVertexId (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_vertexId;
+}
+
+  void 
+SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
+{
+  NS_LOG_FUNCTION (lsa);
+  m_lsa = lsa;
+}
+
+  GlobalRoutingLSA* 
+SPFVertex::GetLSA (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_lsa;
+}
+
+  void 
+SPFVertex::SetDistanceFromRoot (uint32_t distance)
+{
+  NS_LOG_FUNCTION (distance);
+  m_distanceFromRoot = distance;
+}
+
+  uint32_t
+SPFVertex::GetDistanceFromRoot (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_distanceFromRoot;
+}
+
+  void
+SPFVertex::SetParent (SPFVertex* parent)
+{
+  NS_LOG_FUNCTION (parent);
+
+  // always maintain only one parent when using setter/getter methods
+  m_parents.clear ();
+  m_parents.push_back (parent);
+}
+
+  SPFVertex* 
+SPFVertex::GetParent (uint32_t i) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  // If the index i is out-of-range, return 0 and do nothing
+  if (m_parents.size () <= i)
+    {
+      NS_LOG_LOGIC ("Index to SPFVertex's parent is out-of-range.");
+      return 0;
+    }
+  ListOfSPFVertex_t::const_iterator iter = m_parents.begin ();
+  while (i-- > 0) 
+    {
+      iter++;
+    }
+  return *iter;
+}
+
+void 
+SPFVertex::MergeParent (const SPFVertex* v)
+{
+  NS_LOG_FUNCTION (v);
+
+  NS_LOG_LOGIC ("Before merge, list of parents = " << m_parents);
+  // combine the two lists first, and then remove any duplicated after
+  m_parents.insert (m_parents.end (), 
+    v->m_parents.begin (), v->m_parents.end ());
+  // remove duplication
+  m_parents.sort ();
+  m_parents.unique ();
+  NS_LOG_LOGIC ("After merge, list of parents = " << m_parents);
+}
+
+void 
+SPFVertex::SetRootExitDirection (Ipv4Address nextHop, int32_t id)
+{
+  NS_LOG_FUNCTION (nextHop << id);
+  
+  // always maintain only one root's exit
+  m_ecmpRootExits.clear ();
+  m_ecmpRootExits.push_back (NodeExit_t (nextHop, id));
+  // update the following in order to be backward compatitable with
+  // GetNextHop and GetOutgoingInterface methods
+  m_nextHop = nextHop;
+  m_rootOif = id;
+}
+
+void 
+SPFVertex::SetRootExitDirection (SPFVertex::NodeExit_t exit)
+{
+  NS_LOG_FUNCTION (exit);
+  SetRootExitDirection (exit.first, exit.second);
+}
+
+SPFVertex::NodeExit_t
+SPFVertex::GetRootExitDirection (uint32_t i) const
+{
+  NS_LOG_FUNCTION (i);
+  typedef ListOfNodeExit_t::const_iterator CIter_t;
+
+  NS_ASSERT_MSG (i < m_ecmpRootExits.size (), "Index out-of-range when accessing SPFVertex::m_ecmpRootExits!");
+  CIter_t iter = m_ecmpRootExits.begin ();
+  while (i-- > 0) {iter++;}
+
+  return *iter;
+}
+
+SPFVertex::NodeExit_t 
+SPFVertex::GetRootExitDirection () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  NS_ASSERT_MSG (m_ecmpRootExits.size () <= 1, "Assumed there is at most one exit from the root to this vertex");
+  return GetRootExitDirection (0);
+}
+
+void 
+SPFVertex::MergeRootExitDirections (const SPFVertex* vertex)
+{
+  NS_LOG_FUNCTION (vertex);
+
+  // obtain the external list of exit directions
+  //
+  // Append the external list into 'this' and remove duplication afterward
+  const ListOfNodeExit_t& extList = vertex->m_ecmpRootExits;
+  m_ecmpRootExits.insert (m_ecmpRootExits.end (), 
+    extList.begin(), extList.end ());
+  m_ecmpRootExits.sort ();
+  m_ecmpRootExits.unique ();
+}
+
+void 
+SPFVertex::InheritAllRootExitDirections (const SPFVertex* vertex)
+{
+  NS_LOG_FUNCTION (vertex);
+
+  // discard all exit direction currently associated with this vertex,
+  // and copy all the exit directions from the given vertex
+  if (m_ecmpRootExits.size () > 0)
+    {
+      NS_LOG_WARN ("x root exit directions in this vertex are going to be discarded");
+    }
+  m_ecmpRootExits.clear ();
+  m_ecmpRootExits.insert (m_ecmpRootExits.end (), 
+      vertex->m_ecmpRootExits.begin (), vertex->m_ecmpRootExits.end ());
+}
+
+uint32_t 
+SPFVertex::GetNRootExitDirections () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_ecmpRootExits.size ();
+}
+
+uint32_t 
+SPFVertex::GetNChildren (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_children.size ();
+}
+
+  SPFVertex* 
+SPFVertex::GetChild (uint32_t n) const
+{
+  NS_LOG_FUNCTION (n);
+  uint32_t j = 0;
+
+  for ( ListOfSPFVertex_t::const_iterator i = m_children.begin ();
+        i != m_children.end ();
+        i++, j++)
+    {
+      if (j == n)
+        {
+          return *i;
+        }
+    }
+  NS_ASSERT_MSG (false, "Index <n> out of range.");
+  return 0;
+}
+
+  uint32_t 
+SPFVertex::AddChild (SPFVertex* child)
+{
+  NS_LOG_FUNCTION (child);
+  m_children.push_back (child);
+  return m_children.size ();
+}
+
+void 
+SPFVertex::SetVertexProcessed (bool value)
+{
+  m_vertexProcessed = value;
+}
+
+bool 
+SPFVertex::IsVertexProcessed (void) const
+{
+  return m_vertexProcessed;
+}
+
+void
+SPFVertex::ClearVertexProcessed (void)
+{
+  for (uint32_t i = 0; i < this->GetNChildren (); i++)
+    {
+      this->GetChild (i)->ClearVertexProcessed ();
+    }
+  this->SetVertexProcessed (false);
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouteManagerLSDB Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
+:
+  m_database (),
+  m_extdatabase ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  LSDBMap_t::iterator i;
+  for (i= m_database.begin (); i!= m_database.end (); i++)
+    {
+      NS_LOG_LOGIC ("free LSA");
+      GlobalRoutingLSA* temp = i->second;
+      delete temp;
+    }
+  for (uint32_t j = 0; j < m_extdatabase.size (); j++)
+    {
+      NS_LOG_LOGIC ("free ASexternalLSA");
+      GlobalRoutingLSA* temp = m_extdatabase.at (j);
+      delete temp;
+    }
+  NS_LOG_LOGIC ("clear map");
+  m_database.clear ();
+}
+
+  void
+GlobalRouteManagerLSDB::Initialize ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  LSDBMap_t::iterator i;
+  for (i= m_database.begin (); i!= m_database.end (); i++)
+    {
+      GlobalRoutingLSA* temp = i->second;
+      temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+    }
+}
+
+  void
+GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
+{
+  NS_LOG_FUNCTION (addr << lsa);
+  if (lsa->GetLSType () == GlobalRoutingLSA::ASExternalLSAs) 
+    {
+      m_extdatabase.push_back (lsa);
+    } 
+  else
+    {
+      m_database.insert (LSDBPair_t (addr, lsa));
+    }
+}
+
+  GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const
+{
+  return m_extdatabase.at (index);
+}
+
+  uint32_t
+GlobalRouteManagerLSDB::GetNumExtLSAs () const
+{
+  return m_extdatabase.size ();
+}
+
+  GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
+{
+  NS_LOG_FUNCTION (addr);
+//
+// Look up an LSA by its address.
+//
+  LSDBMap_t::const_iterator i;
+  for (i= m_database.begin (); i!= m_database.end (); i++)
+  {
+    if (i->first == addr)
+    {
+      return i->second;
+    }
+  }
+  return 0;
+}
+
+  GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
+{
+  NS_LOG_FUNCTION (addr);
+//
+// Look up an LSA by its address.
+//
+  LSDBMap_t::const_iterator i;
+  for (i= m_database.begin (); i!= m_database.end (); i++)
+    {
+      GlobalRoutingLSA* temp = i->second;
+// Iterate among temp's Link Records
+      for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
+        {
+          GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
+          if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
+               lr->GetLinkData () == addr)
+            {
+              return temp;
+            }
+        }
+    }
+  return 0;
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouteManagerImpl Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRouteManagerImpl::GlobalRouteManagerImpl () 
+: 
+  m_spfroot (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_lsdb = new GlobalRouteManagerLSDB ();
+}
+
+GlobalRouteManagerImpl::~GlobalRouteManagerImpl ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_lsdb)
+    {
+      delete m_lsdb;
+    }
+}
+
+  void
+GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb)
+{
+  NS_LOG_FUNCTION (lsdb);
+  if (m_lsdb)
+    {
+      delete m_lsdb;
+    }
+  m_lsdb = lsdb;
+}
+
+  void
+GlobalRouteManagerImpl::DeleteGlobalRoutes ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+      Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+      if (router == 0)
+        {
+          continue;
+        }
+      Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+      uint32_t j = 0;
+      uint32_t nRoutes = gr->GetNRoutes ();
+      NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ());
+      // Each time we delete route 0, the route index shifts downward
+      // We can delete all routes if we delete the route numbered 0
+      // nRoutes times
+      for (j = 0; j < nRoutes; j++)
+        {
+          NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ());
+          gr->RemoveRoute (0);        
+        }
+      NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ());
+    }
+  if (m_lsdb)
+    {
+      NS_LOG_LOGIC ("Deleting LSDB, creating new one");
+      delete m_lsdb;
+      m_lsdb = new GlobalRouteManagerLSDB ();
+    }
+}
+
+//
+// In order to build the routing database, we need to walk the list of nodes
+// in the system and look for those that support the GlobalRouter interface.
+// These routers will export a number of Link State Advertisements (LSAs)
+// that describe the links and networks that are "adjacent" (i.e., that are
+// on the other side of a point-to-point link).  We take these LSAs and put
+// add them to the Link State DataBase (LSDB) from which the routes will 
+// ultimately be computed.
+//
+  void
+GlobalRouteManagerImpl::BuildGlobalRoutingDatabase () 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+//
+// Walk the list of nodes looking for the GlobalRouter Interface.  Nodes with
+// global router interfaces are, not too surprisingly, our routers.
+//
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
+//      
+// Ignore nodes that aren't participating in routing.
+//
+      if (!rtr)
+        {
+          continue;
+        }
+//
+// You must call DiscoverLSAs () before trying to use any routing info or to
+// update LSAs.  DiscoverLSAs () drives the process of discovering routes in
+// the GlobalRouter.  Afterward, you may use GetNumLSAs (), which is a very
+// computationally inexpensive call.  If you call GetNumLSAs () before calling 
+// DiscoverLSAs () will get zero as the number since no routes have been 
+// found.
+//
+      Ptr<Ipv4GlobalRouting> grouting = rtr->GetRoutingProtocol ();
+      uint32_t numLSAs = rtr->DiscoverLSAs ();
+      NS_LOG_LOGIC ("Found " << numLSAs << " LSAs");
+
+      for (uint32_t j = 0; j < numLSAs; ++j)
+        {
+          GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
+//
+// This is the call to actually fetch a Link State Advertisement from the 
+// router.
+//
+          rtr->GetLSA (j, *lsa);
+          NS_LOG_LOGIC (*lsa);
+//
+// Write the newly discovered link state advertisement to the database.
+//
+          m_lsdb->Insert (lsa->GetLinkStateId (), lsa); 
+        }
+    }
+}
+
+//
+// For each node that is a global router (which is determined by the presence
+// of an aggregated GlobalRouter interface), run the Dijkstra SPF calculation
+// on the database rooted at that router, and populate the node forwarding
+// tables.
+//
+// This function parallels RFC2328, Section 16.1.1, and quagga ospfd
+//
+// This calculation yields the set of intra-area routes associated
+// with an area (called hereafter Area A).  A router calculates the
+// shortest-path tree using itself as the root.  The formation
+// of the shortest path tree is done here in two stages.  In the
+// first stage, only links between routers and transit networks are
+// considered.  Using the Dijkstra algorithm, a tree is formed from
+// this subset of the link state database.  In the second stage,
+// leaves are added to the tree by considering the links to stub
+// networks.
+//
+// The area's link state database is represented as a directed graph.  
+// The graph's vertices are routers, transit networks and stub networks.  
+//
+// The first stage of the procedure (i.e., the Dijkstra algorithm)
+// can now be summarized as follows. At each iteration of the
+// algorithm, there is a list of candidate vertices.  Paths from
+// the root to these vertices have been found, but not necessarily
+// the shortest ones.  However, the paths to the candidate vertex
+// that is closest to the root are guaranteed to be shortest; this
+// vertex is added to the shortest-path tree, removed from the
+// candidate list, and its adjacent vertices are examined for
+// possible addition to/modification of the candidate list.  The
+// algorithm then iterates again.  It terminates when the candidate
+// list becomes empty. 
+//
+  void
+GlobalRouteManagerImpl::InitializeRoutes ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+//
+// Walk the list of nodes in the system.
+//
+  NS_LOG_INFO ("About to start SPF calculation");
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+//
+// Look for the GlobalRouter interface that indicates that the node is
+// participating in routing.
+//
+      Ptr<GlobalRouter> rtr = 
+        node->GetObject<GlobalRouter> ();
+
+      // Ignore nodes that are not assigned to our systemId (distributed sim)
+      if (node->GetSystemId () != MpiInterface::GetSystemId ()) 
+        {
+          continue;
+        }
+      
+//
+// if the node has a global router interface, then run the global routing
+// algorithms.
+//
+      if (rtr && rtr->GetNumLSAs () )
+        {
+          SPFCalculate (rtr->GetRouterId ());
+        }
+    }
+  NS_LOG_INFO ("Finished SPF calculation");
+}
+
+//
+// This method is derived from quagga ospf_spf_next ().  See RFC2328 Section 
+// 16.1 (2) for further details.
+//
+// We're passed a parameter <v> that is a vertex which is already in the SPF
+// tree.  A vertex represents a router node.  We also get a reference to the
+// SPF candidate queue, which is a priority queue containing the shortest paths
+// to the networks we know about.
+//
+// We examine the links in v's LSA and update the list of candidates with any
+// vertices not already on the list.  If a lower-cost path is found to a
+// vertex already on the candidate list, store the new (lower) cost.
+//
+  void
+GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
+{
+  NS_LOG_FUNCTION (v << &candidate);
+
+  SPFVertex* w = 0;
+  GlobalRoutingLSA* w_lsa = 0;
+  GlobalRoutingLinkRecord *l = 0;
+  uint32_t distance = 0;
+  uint32_t numRecordsInVertex = 0;
+//
+// V points to a Router-LSA or Network-LSA
+// Loop over the links in router LSA or attached routers in Network LSA
+//
+  if (v->GetVertexType () == SPFVertex::VertexRouter)
+    {
+      numRecordsInVertex = v->GetLSA ()->GetNLinkRecords (); 
+    }
+  if (v->GetVertexType () == SPFVertex::VertexNetwork)
+    {
+      numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters (); 
+    }
+
+  for (uint32_t i = 0; i < numRecordsInVertex; i++)
+    {
+// Get w_lsa:  In case of V is Router-LSA
+      if (v->GetVertexType () == SPFVertex::VertexRouter) 
+        {
+          NS_LOG_LOGIC ("Examining link " << i << " of " << 
+            v->GetVertexId () << "'s " <<
+            v->GetLSA ()->GetNLinkRecords () << " link records");
+//
+// (a) If this is a link to a stub network, examine the next link in V's LSA.
+// Links to stub networks will be considered in the second stage of the
+// shortest path calculation.
+//
+          l = v->GetLSA ()->GetLinkRecord (i);
+          if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+            {
+              NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
+              continue;
+            }
+//
+// (b) Otherwise, W is a transit vertex (router or transit network).  Look up
+// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
+// database. 
+//
+          if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+            {
+//
+// Lookup the link state advertisement of the new link -- we call it <w> in
+// the link state database.
+//
+              w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+              NS_ASSERT (w_lsa);
+              NS_LOG_LOGIC ("Found a P2P record from " << 
+                v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+            }
+          else if (l->GetLinkType () == 
+            GlobalRoutingLinkRecord::TransitNetwork)
+            {
+              w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+              NS_ASSERT (w_lsa);
+              NS_LOG_LOGIC ("Found a Transit record from " << 
+                v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+            }
+          else 
+            {
+              NS_ASSERT_MSG (0, "illegal Link Type");
+            }
+        }
+// Get w_lsa:  In case of V is Network-LSA
+      if (v->GetVertexType () == SPFVertex::VertexNetwork) 
+        {
+          w_lsa = m_lsdb->GetLSAByLinkData 
+            (v->GetLSA ()->GetAttachedRouter (i)); 
+          if (!w_lsa)
+            {
+              continue;
+            }
+          NS_LOG_LOGIC ("Found a Network LSA from " << 
+            v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+        }
+
+// Note:  w_lsa at this point may be either RouterLSA or NetworkLSA
+//
+// (c) If vertex W is already on the shortest-path tree, examine the next
+// link in the LSA.
+//
+// If the link is to a router that is already in the shortest path first tree
+// then we have it covered -- ignore it.
+//
+      if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE) 
+        {
+          NS_LOG_LOGIC ("Skipping ->  LSA "<< 
+            w_lsa->GetLinkStateId () << " already in SPF tree");
+          continue;
+        }
+//
+// (d) Calculate the link state cost D of the resulting path from the root to 
+// vertex W.  D is equal to the sum of the link state cost of the (already 
+// calculated) shortest path to vertex V and the advertised cost of the link
+// between vertices V and W.  
+//
+      if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
+        {
+          distance = v->GetDistanceFromRoot () + l->GetMetric ();
+        }
+      else
+        {
+          distance = v->GetDistanceFromRoot ();
+        }
+
+      NS_LOG_LOGIC ("Considering w_lsa " << w_lsa->GetLinkStateId ());
+
+// Is there already vertex w in candidate list?
+      if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
+        {
+// Calculate nexthop to w
+// We need to figure out how to actually get to the new router represented
+// by <w>.  This will (among other things) find the next hop address to send
+// packets destined for this network to, and also find the outbound interface
+// used to forward the packets.
+
+// prepare vertex w
+          w = new SPFVertex (w_lsa);
+          if (SPFNexthopCalculation (v, w, l, distance))
+            {
+              w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
+//
+// Push this new vertex onto the priority queue (ordered by distance from the
+// root node).
+//
+              candidate.Push (w);
+              NS_LOG_LOGIC ("Pushing " << 
+                w->GetVertexId () << ", parent vertexId: " << 
+                v->GetVertexId () << ", distance: " <<
+                w->GetDistanceFromRoot ());
+            }
+          else
+            NS_ASSERT_MSG (0, "SPFNexthopCalculation never " 
+              << "return false, but it does now!");
+        }
+      else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
+        {
+//
+// We have already considered the link represented by <w>.  What wse have to
+// do now is to decide if this new router represents a route with a shorter
+// distance metric.
+//
+// So, locate the vertex in the candidate queue and take a look at the 
+// distance.
+
+/* (quagga-0.98.6) W is already on the candidate list; call it cw.
+* Compare the previously calculated cost (cw->distance)
+* with the cost we just determined (w->distance) to see
+* if we've found a shorter path.
+*/
+          SPFVertex* cw;
+          cw = candidate.Find (w_lsa->GetLinkStateId ());
+          if (cw->GetDistanceFromRoot () < distance)
+            {
+//
+// This is not a shorter path, so don't do anything.
+//
+              continue;
+            }
+          else if (cw->GetDistanceFromRoot () == distance)
+            {
+//
+// This path is one with an equal cost.  
+//
+              NS_LOG_LOGIC ("Equal cost multiple paths found.");
+
+// At this point, there are two instances 'w' and 'cw' of the
+// same vertex, the vertex that is currently being considered
+// for adding into the shortest path tree. 'w' is the instance
+// as seen from the root via vertex 'v', and 'cw' is the instance 
+// as seen from the root via some other vertices other than 'v'.
+// These two instances are being merged in the following code.
+// In particular, the parent nodes, the next hops, and the root's
+// output interfaces of the two instances are being merged.
+// 
+// Note that this is functionally equivalent to calling
+// ospf_nexthop_merge (cw->nexthop, w->nexthop) in quagga-0.98.6
+// (ospf_spf.c::859), although the detail implementation
+// is very different from quagga (blame ns3::GlobalRouteManagerImpl)
+
+// prepare vertex w
+              w = new SPFVertex (w_lsa);
+              SPFNexthopCalculation (v, w, l, distance);
+              cw->MergeRootExitDirections (w);
+              cw->MergeParent (w);
+// SPFVertexAddParent (w) is necessary as the destructor of 
+// SPFVertex checks if the vertex and its parent is linked
+// bidirectionally
+              SPFVertexAddParent (w);
+              delete w;
+            }
+          else // cw->GetDistanceFromRoot () > w->GetDistanceFromRoot ()
+            {
+// 
+// this path represents a new, lower-cost path to <w> (the vertex we found in
+// the current link record of the link state advertisement of the current root
+// (vertex <v>)
+//
+// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
+// it will call spf_add_parents, which will flush the old parents
+//
+              if (SPFNexthopCalculation (v, cw, l, distance))
+                {
+//
+// If we've changed the cost to get to the vertex represented by <w>, we 
+// must reorder the priority queue keyed to that cost.
+//
+                  candidate.Reorder ();
+                }
+            } // new lower cost path found  
+        } // end W is already on the candidate list
+    } // end loop over the links in V's LSA
+}
+
+//
+// This method is derived from quagga ospf_nexthop_calculation() 16.1.1.  
+//
+// Calculate nexthop from root through V (parent) to vertex W (destination)
+// with given distance from root->W.
+//
+// As appropriate, set w's parent, distance, and nexthop information
+//
+// For now, this is greatly simplified from the quagga code
+//                  
+  int
+GlobalRouteManagerImpl::SPFNexthopCalculation (
+  SPFVertex* v, 
+  SPFVertex* w,
+  GlobalRoutingLinkRecord* l,
+  uint32_t distance)
+{
+  NS_LOG_FUNCTION (v << w << l << distance);
+//
+// If w is a NetworkVertex, l should be null
+/*
+  if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
+    {
+        NS_ASSERT_MSG (0, "Error:  SPFNexthopCalculation parameter problem");
+    }
+*/
+
+//
+// The vertex m_spfroot is a distinguished vertex representing the node at
+// the root of the calculations.  That is, it is the node for which we are
+// calculating the routes.
+//
+// There are two distinct cases for calculating the next hop information.
+// First, if we're considering a hop from the root to an "adjacent" network
+// (one that is on the other side of a point-to-point link connected to the
+// root), then we need to store the information needed to forward down that
+// link.  The second case is if the network is not directly adjacent.  In that
+// case we need to use the forwarding information from the vertex on the path
+// to the destination that is directly adjacent [node 1] in both cases of the
+// diagram below.
+// 
+// (1) [root] -> [point-to-point] -> [node 1]
+// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2]
+//
+// We call the propagation of next hop information down vertices of a path
+// "inheriting" the next hop information.
+//
+// The point-to-point link information is only useful in this calculation when
+// we are examining the root node. 
+//
+  if (v == m_spfroot)
+    {
+//
+// In this case <v> is the root node, which means it is the starting point
+// for the packets forwarded by that node.  This also means that the next hop
+// address of packets headed for some arbitrary off-network destination must
+// be the destination at the other end of one of the links off of the root
+// node if this root node is a router.  We then need to see if this node <w>
+// is a router.
+//
+      if (w->GetVertexType () == SPFVertex::VertexRouter) 
+        {
+//
+// In the case of point-to-point links, the link data field (m_linkData) of a
+// Global Router Link Record contains the local IP address.  If we look at the
+// link record describing the link from the perspecive of <w> (the remote
+// node from the viewpoint of <v>) back to the root node, we can discover the
+// IP address of the router to which <v> is adjacent.  This is a distinguished
+// address -- the next hop address to get from <v> to <w> and all networks 
+// accessed through that path.
+//
+// SPFGetNextLink () is a little odd.  used in this way it is just going to
+// return the link record describing the link from <w> to <v>.  Think of it as
+// SPFGetLink.
+//
+          NS_ASSERT (l);
+          GlobalRoutingLinkRecord *linkRemote = 0;
+          linkRemote = SPFGetNextLink (w, v, linkRemote);
+// 
+// At this point, <l> is the Global Router Link Record describing the point-
+// to point link from <v> to <w> from the perspective of <v>; and <linkRemote>
+// is the Global Router Link Record describing that same link from the 
+// perspective of <w> (back to <v>).  Now we can just copy the next hop 
+// address from the m_linkData member variable.
+// 
+// The next hop member variable we put in <w> has the sense "in order to get
+// from the root node to the host represented by vertex <w>, you have to send
+// the packet to the next hop address specified in w->m_nextHop.
+//
+          Ipv4Address nextHop = linkRemote->GetLinkData ();
+// 
+// Now find the outgoing interface corresponding to the point to point link
+// from the perspective of <v> -- remember that <l> is the link "from"
+// <v> "to" <w>.
+//
+          uint32_t outIf = FindOutgoingInterfaceId (l->GetLinkData ());
+
+          w->SetRootExitDirection (nextHop, outIf);
+          w->SetDistanceFromRoot (distance);
+          w->SetParent (v);
+          NS_LOG_LOGIC ("Next hop from " << 
+            v->GetVertexId () << " to " << w->GetVertexId () << 
+            " goes through next hop " << nextHop <<
+            " via outgoing interface " << outIf <<
+            " with distance " << distance);
+        }  // end W is a router vertes
+      else 
+        {
+          NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
+// W is a directly connected network; no next hop is required
+          GlobalRoutingLSA* w_lsa = w->GetLSA ();
+          NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
+// Find outgoing interface ID for this network
+          uint32_t outIf = FindOutgoingInterfaceId (w_lsa->GetLinkStateId (), 
+            w_lsa->GetNetworkLSANetworkMask () );
+// Set the next hop to 0.0.0.0 meaning "not exist"
+          Ipv4Address nextHop = Ipv4Address::GetZero ();
+          w->SetRootExitDirection (nextHop, outIf);
+          w->SetDistanceFromRoot (distance);
+          w->SetParent (v);
+          NS_LOG_LOGIC ("Next hop from " << 
+            v->GetVertexId () << " to network " << w->GetVertexId () << 
+            " via outgoing interface " << outIf <<
+            " with distance " << distance);
+          return 1;
+        }
+    } // end v is the root
+  else if (v->GetVertexType () == SPFVertex::VertexNetwork) 
+    {
+// See if any of v's parents are the root
+      if (v->GetParent () == m_spfroot)
+        {
+// 16.1.1 para 5. ...the parent vertex is a network that
+// directly connects the calculating router to the destination
+// router.  The list of next hops is then determined by
+// examining the destination's router-LSA...
+          NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
+          GlobalRoutingLinkRecord *linkRemote = 0;
+          while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
+            {
+/* ...For each link in the router-LSA that points back to the
+ * parent network, the link's Link Data field provides the IP
+ * address of a next hop router.  The outgoing interface to
+ * use can then be derived from the next hop IP address (or 
+ * it can be inherited from the parent network).
+ */
+                Ipv4Address nextHop = linkRemote->GetLinkData ();
+                uint32_t outIf = v->GetRootExitDirection ().second;
+                w->SetRootExitDirection (nextHop, outIf);
+                NS_LOG_LOGIC ("Next hop from " << 
+                  v->GetVertexId () << " to " << w->GetVertexId () << 
+                  " goes through next hop " << nextHop <<
+                  " via outgoing interface " << outIf);
+            }
+        }
+      else 
+        {
+          w->SetRootExitDirection (v->GetRootExitDirection ());
+        }
+    }
+  else 
+    {
+//
+// If we're calculating the next hop information from a node (v) that is 
+// *not* the root, then we need to "inherit" the information needed to
+// forward the packet from the vertex closer to the root.  That is, we'll
+// still send packets to the next hop address of the router adjacent to the
+// root on the path toward <w>.
+//
+// Above, when we were considering the root node, we calculated the next hop
+// address and outgoing interface required to get off of the root network.  
+// At this point, we are further away from the root network along one of the
+// (shortest) paths.  So the next hop and outoing interface remain the same
+// (are inherited).
+//
+      w->InheritAllRootExitDirections (v);
+    }
+//
+// In all cases, we need valid values for the distance metric and a parent.
+//
+  w->SetDistanceFromRoot (distance);
+  w->SetParent (v);
+
+  return 1;
+}
+
+//
+// This method is derived from quagga ospf_get_next_link ()
+//
+// First search the Global Router Link Records of vertex <v> for one
+// representing a point-to point link to vertex <w>.
+//
+// What is done depends on prev_link.  Contrary to appearances, prev_link just
+// acts as a flag here.  If prev_link is NULL, we return the first Global
+// Router Link Record we find that describes a point-to-point link from <v> 
+// to <w>.  If prev_link is not NULL, we return a Global Router Link Record
+// representing a possible *second* link from <v> to <w>.
+//
+  GlobalRoutingLinkRecord* 
+GlobalRouteManagerImpl::SPFGetNextLink (
+  SPFVertex* v,
+  SPFVertex* w,
+  GlobalRoutingLinkRecord* prev_link) 
+{
+  NS_LOG_FUNCTION (v << w << prev_link);
+
+  bool skip = true;
+  bool found_prev_link = false;
+  GlobalRoutingLinkRecord* l;
+//
+// If prev_link is 0, we are really looking for the first link, not the next 
+// link.
+//
+  if (prev_link == 0)
+    {
+      skip = false;
+      found_prev_link = true;
+    }
+//  
+// Iterate through the Global Router Link Records advertised by the vertex
+// <v> looking for records representing the point-to-point links off of this
+// vertex.
+//
+  for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
+    {
+      l = v->GetLSA ()->GetLinkRecord (i);
+//
+// The link ID of a link record representing a point-to-point link is set to
+// the router ID of the neighboring router -- the router to which the link
+// connects from the perspective of <v> in this case.  The vertex ID is also
+// set to the router ID (using the link state advertisement of a router node).
+// We're just checking to see if the link <l> is actually the link from <v> to
+// <w>.
+//
+      if (l->GetLinkId () == w->GetVertexId ()) 
+        {
+          if (!found_prev_link)
+            {
+              NS_LOG_LOGIC ("Skipping links before prev_link found");
+              found_prev_link = true;
+              continue;
+            }
+        
+          NS_LOG_LOGIC ("Found matching link l:  linkId = " <<
+          l->GetLinkId () << " linkData = " << l->GetLinkData ());
+//
+// If skip is false, don't (not too surprisingly) skip the link found -- it's 
+// the one we're interested in.  That's either because we didn't pass in a 
+// previous link, and we're interested in the first one, or because we've 
+// skipped a previous link and moved forward to the next (which is then the
+// one we want).
+//
+        if (skip == false) 
+          {
+            NS_LOG_LOGIC ("Returning the found link");
+            return l;
+          }
+        else
+          {
+//
+// Skip is true and we've found a link from <v> to <w>.  We want the next one.
+// Setting skip to false gets us the next point-to-point global router link
+// record in the LSA from <v>.
+//
+            NS_LOG_LOGIC ("Skipping the found link");
+            skip = false;
+            continue;
+          }
+      }
+    }
+  return 0;
+}
+  
+//
+// Used for unit tests.
+//
+  void
+GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root)
+{
+  NS_LOG_FUNCTION (root);
+  SPFCalculate (root);
+}
+
+//
+// Used to test if a node is a stub, from an OSPF sense.
+// If there is only one link of type 1 or 2, then a default route
+// can safely be added to the next-hop router and SPF does not need
+// to be run
+//
+bool
+GlobalRouteManagerImpl::CheckForStubNode (Ipv4Address root)
+{
+  NS_LOG_FUNCTION (root);
+  GlobalRoutingLSA *rlsa = m_lsdb->GetLSA (root);
+  Ipv4Address myRouterId = rlsa->GetLinkStateId ();
+  int transits = 0;
+  GlobalRoutingLinkRecord *transitLink = 0;
+  for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
+    {
+      GlobalRoutingLinkRecord *l = rlsa->GetLinkRecord (i);
+      if (l->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
+        {
+          transits++;
+          transitLink = l;
+        }
+      else if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+        {
+          transits++;
+          transitLink = l;
+        }
+    }
+  if (transits == 0)
+    {
+      // This router is not connected to any router.  Probably, global
+      // routing should not be called for this node, but we can just raise
+      // a warning here and return true.
+      NS_LOG_WARN ("all nodes should have at least one transit link:" << root );
+      return true;
+    }
+  if (transits == 1)
+    {
+      if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
+        {
+          // Install default route to next hop router
+          // What is the next hop?  We need to check all neighbors on the link.
+          // If there is a single router that has two transit links, then
+          // that is the default next hop.  If there are more than one
+          // routers on link with multiple transit links, return false.
+          // Not yet implemented, so simply return false
+          NS_LOG_LOGIC ("TBD: Would have inserted default for transit");
+          return false;
+        }
+      else if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+        {
+          // Install default route to next hop
+          // The link record LinkID is the router ID of the peer.
+          // The Link Data is the local IP interface address
+          GlobalRoutingLSA *w_lsa = m_lsdb->GetLSA (transitLink->GetLinkId ());
+          uint32_t nLinkRecords = w_lsa->GetNLinkRecords ();
+          for (uint32_t j = 0; j < nLinkRecords; ++j)
+            {
+              //
+              // We are only concerned about point-to-point links
+              //
+              GlobalRoutingLinkRecord *lr = w_lsa->GetLinkRecord (j);
+              if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
+                {
+                  continue;
+                }
+              // Find the link record that corresponds to our routerId
+              if (lr->GetLinkId () == myRouterId)
+                {
+                  // Next hop is stored in the LinkID field of lr
+                  Ptr<GlobalRouter> router = rlsa->GetNode ()->GetObject<GlobalRouter> ();
+                  NS_ASSERT (router);
+                  Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+                  NS_ASSERT (gr);
+                  gr->AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask ("0.0.0.0"), lr->GetLinkData (), 
+                                         FindOutgoingInterfaceId (transitLink->GetLinkData ()));
+                  NS_LOG_LOGIC ("Inserting default route for node " << myRouterId << " to next hop " << 
+                                lr->GetLinkData () << " via interface " << 
+                                FindOutgoingInterfaceId(transitLink->GetLinkData()));
+                  return true;
+                }
+            }
+        }
+    }
+  return false;
+}
+
+// quagga ospf_spf_calculate
+  void
+GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
+{
+  NS_LOG_FUNCTION (this << root);
+
+  SPFVertex *v;
+//
+// Initialize the Link State Database.
+//
+  m_lsdb->Initialize ();
+//
+// The candidate queue is a priority queue of SPFVertex objects, with the top
+// of the queue being the closest vertex in terms of distance from the root
+// of the tree.  Initially, this queue is empty.
+//
+  CandidateQueue candidate;
+  NS_ASSERT (candidate.Size () == 0);
+//
+// Initialize the shortest-path tree to only contain the router doing the 
+// calculation.  Each router (and corresponding network) is a vertex in the
+// shortest path first (SPF) tree.
+//
+  v = new SPFVertex (m_lsdb->GetLSA (root));
+// 
+// This vertex is the root of the SPF tree and it is distance 0 from the root.
+// We also mark this vertex as being in the SPF tree.
+//
+  m_spfroot= v;
+  v->SetDistanceFromRoot (0);
+  v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
+  NS_LOG_LOGIC ("Starting SPFCalculate for node " << root);
+
+//
+// Optimize SPF calculation, for ns-3.
+// We do not need to calculate SPF for every node in the network if this
+// node has only one interface through which another router can be 
+// reached.  Instead, short-circuit this computation and just install
+// a default route in the CheckForStubNode() method.
+//
+  if (NodeList::GetNNodes () > 0 && CheckForStubNode (root))
+    {
+      NS_LOG_LOGIC ("SPFCalculate truncated for stub node " << root);
+      delete m_spfroot;
+      return;
+    }
+
+  for (;;)
+    {
+//
+// The operations we need to do are given in the OSPF RFC which we reference
+// as we go along.
+//
+// RFC2328 16.1. (2). 
+//
+// We examine the Global Router Link Records in the Link State 
+// Advertisements of the current vertex.  If there are any point-to-point
+// links to unexplored adjacent vertices we add them to the tree and update
+// the distance and next hop information on how to get there.  We also add
+// the new vertices to the candidate queue (the priority queue ordered by
+// shortest path).  If the new vertices represent shorter paths, we use them
+// and update the path cost.
+//
+      SPFNext (v, candidate);
+//
+// RFC2328 16.1. (3). 
+//
+// If at this step the candidate list is empty, the shortest-path tree (of
+// transit vertices) has been completely built and this stage of the
+// procedure terminates. 
+//
+      if (candidate.Size () == 0)
+        {
+          break;
+        }
+//
+// Choose the vertex belonging to the candidate list that is closest to the
+// root, and add it to the shortest-path tree (removing it from the candidate
+// list in the process).
+//
+// Recall that in the previous step, we created SPFVertex structures for each
+// of the routers found in the Global Router Link Records and added tehm to 
+// the candidate list.
+//
+      NS_LOG_LOGIC (candidate);
+      v = candidate.Pop ();
+      NS_LOG_LOGIC ("Popped vertex " << v->GetVertexId ());
+//
+// Update the status field of the vertex to indicate that it is in the SPF
+// tree.
+//
+      v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
+//
+// The current vertex has a parent pointer.  By calling this rather oddly 
+// named method (blame quagga) we add the current vertex to the list of 
+// children of that parent vertex.  In the next hop calculation called during
+// SPFNext, the parent pointer was set but the vertex has been orphaned up
+// to now.
+//
+      SPFVertexAddParent (v);
+//
+// Note that when there is a choice of vertices closest to the root, network
+// vertices must be chosen before router vertices in order to necessarily
+// find all equal-cost paths. 
+//
+// RFC2328 16.1. (4). 
+//
+// This is the method that actually adds the routes.  It'll walk the list
+// of nodes in the system, looking for the node corresponding to the router
+// ID of the root of the tree -- that is the router we're building the routes
+// for.  It looks for the Ipv4 interface of that node and remembers it.  So
+// we are only actually adding routes to that one node at the root of the SPF 
+// tree.
+//
+// We're going to pop of a pointer to every vertex in the tree except the 
+// root in order of distance from the root.  For each of the vertices, we call
+// SPFIntraAddRouter ().  Down in SPFIntraAddRouter, we look at all of the 
+// point-to-point Global Router Link Records (the links to nodes adjacent to
+// the node represented by the vertex).  We add a route to the IP address 
+// specified by the m_linkData field of each of those link records.  This will
+// be the *local* IP address associated with the interface attached to the 
+// link.  We use the outbound interface and next hop information present in 
+// the vertex <v> which have possibly been inherited from the root.
+//
+// To summarize, we're going to look at the node represented by <v> and loop
+// through its point-to-point links, adding a *host* route to the local IP
+// address (at the <v> side) for each of those links.
+//
+      if (v->GetVertexType () == SPFVertex::VertexRouter)
+        {
+          SPFIntraAddRouter (v);
+        }
+      else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+        {
+          SPFIntraAddTransit (v);
+        }
+      else
+        {
+          NS_ASSERT_MSG (0, "illegal SPFVertex type");
+        }
+//
+// RFC2328 16.1. (5). 
+//
+// Iterate the algorithm by returning to Step 2 until there are no more
+// candidate vertices.
+
+    }  // end for loop
+
+// Second stage of SPF calculation procedure  
+  SPFProcessStubs (m_spfroot);
+  for (uint32_t i = 0; i < m_lsdb->GetNumExtLSAs (); i++)
+    {
+      m_spfroot->ClearVertexProcessed ();
+      GlobalRoutingLSA *extlsa = m_lsdb->GetExtLSA (i);
+      NS_LOG_LOGIC ("Processing External LSA with id " << extlsa->GetLinkStateId ());
+      ProcessASExternals (m_spfroot, extlsa);
+    }
+
+//
+// We're all done setting the routing information for the node at the root of
+// the SPF tree.  Delete all of the vertices and corresponding resources.  Go
+// possibly do it again for the next router.
+//
+  delete m_spfroot;
+  m_spfroot = 0;
+}
+
+void
+GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("Processing external for destination " << 
+      extlsa->GetLinkStateId () <<
+      ", for router "  << v->GetVertexId () << 
+      ", advertised by " << extlsa->GetAdvertisingRouter ());
+  if (v->GetVertexType () == SPFVertex::VertexRouter)
+    {
+      GlobalRoutingLSA *rlsa = v->GetLSA ();
+      NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
+      if ((rlsa->GetLinkStateId ()) == (extlsa->GetAdvertisingRouter ()))
+        {
+          NS_LOG_LOGIC ("Found advertising router to destination");
+          SPFAddASExternal(extlsa,v);
+        }
+    }
+  for (uint32_t i = 0; i < v->GetNChildren (); i++)
+    {
+      if (!v->GetChild (i)->IsVertexProcessed ())
+        {
+          NS_LOG_LOGIC ("Vertex's child " << i << " not yet processed, processing...");
+          ProcessASExternals (v->GetChild (i), extlsa);
+          v->GetChild (i)->SetVertexProcessed (true);
+        }
+    }
+}
+
+//
+// Adding external routes to routing table - modeled after
+// SPFAddIntraAddStub()
+//
+
+void
+GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set");
+// Two cases to consider: We are advertising the external ourselves
+// => No need to add anything
+// OR find best path to the advertising router
+  if (v->GetVertexId () == m_spfroot->GetVertexId ())
+    {
+      NS_LOG_LOGIC ("External is on local host: " 
+        << v->GetVertexId () << "; returning");
+      return;
+    }
+  NS_LOG_LOGIC ("External is on remote host: " 
+    << extlsa->GetAdvertisingRouter () << "; installing");
+  
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+  NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex.  This is the one we're going to write
+// the routing information to.
+//
+  NodeList::Iterator i = NodeList::Begin (); 
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (; i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface.  If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+// 
+      Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
+
+      if (rtr == 0)
+        {
+          NS_LOG_LOGIC ("No GlobalRouter interface on node " << node->GetId ());
+          continue;
+        }
+//
+// If the router ID of the current node is equal to the router ID of the 
+// root of the SPF tree, then this node is the one for which we need to 
+// write the routing tables.
+//
+      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+      if (rtr->GetRouterId () == routerId)
+        {
+          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface.  We need to QI
+// for that interface.  If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+          NS_ASSERT_MSG (ipv4, 
+                     "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+                         "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to.  The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node.  We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+          NS_ASSERT_MSG (v->GetLSA (), 
+                     "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+                         "Expected valid LSA in SPFVertex* v");
+          Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask ();
+          Ipv4Address tempip = extlsa->GetLinkStateId ();
+          tempip = tempip.CombineMask (tempmask);
+
+//
+// Here's why we did all of that work.  We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record.  In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link.  Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets.  The vertex <v> 
+// (corresponding to the node that has these links and interfaces) has 
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+          Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+          if (router == 0)
+            {
+              continue;
+            }
+          Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+          NS_ASSERT (gr);
+          // walk through all next-hop-IPs and out-going-interfaces for reaching
+          // the stub network gateway 'v' from the root node
+          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+            {
+              SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+              Ipv4Address nextHop = exit.first;
+              int32_t outIf = exit.second;
+              if (outIf >= 0)
+                {
+                  gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf);
+                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                    " add external network route to " << tempip <<
+                    " using next hop " << nextHop <<
+                    " via interface " << outIf);
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                    " NOT able to add network route to " << tempip <<
+                    " using next hop " << nextHop <<
+                    " since outgoing interface id is negative");
+                }
+            }
+          return;
+        } // if
+    } // for
+}
+
+
+// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
+// stub link records will exist for point-to-point interfaces and for
+// broadcast interfaces for which no neighboring router can be found
+void
+GlobalRouteManagerImpl::SPFProcessStubs (SPFVertex* v)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("Processing stubs for " << v->GetVertexId ());
+  if (v->GetVertexType () == SPFVertex::VertexRouter)
+    {
+      GlobalRoutingLSA *rlsa = v->GetLSA ();
+      NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
+      for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
+        {
+          NS_LOG_LOGIC ("Examining link " << i << " of " << 
+            v->GetVertexId () << "'s " <<
+            v->GetLSA ()->GetNLinkRecords () << " link records");
+          GlobalRoutingLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
+          if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+            {
+              NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
+              SPFIntraAddStub (l, v);
+              continue;
+            }
+        }
+    }
+    for (uint32_t i = 0; i < v->GetNChildren (); i++)
+      {
+        if (!v->GetChild (i)->IsVertexProcessed ())
+          {
+            SPFProcessStubs (v->GetChild (i));
+            v->GetChild (i)->SetVertexProcessed (true);
+          }
+      }
+}
+
+// RFC2328 16.1. second stage. 
+void
+GlobalRouteManagerImpl::SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  NS_ASSERT_MSG (m_spfroot, 
+    "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set");
+
+  // XXX simplifed logic for the moment.  There are two cases to consider:
+  // 1) the stub network is on this router; do nothing for now
+  //    (already handled above)
+  // 2) the stub network is on a remote router, so I should use the
+  // same next hop that I use to get to vertex v
+  if (v->GetVertexId () == m_spfroot->GetVertexId ())
+    {
+      NS_LOG_LOGIC ("Stub is on local host: " << v->GetVertexId () << "; returning");
+      return;
+    }
+      NS_LOG_LOGIC ("Stub is on remote host: " << v->GetVertexId () << "; installing");
+//
+// The root of the Shortest Path First tree is the router to which we are 
+// going to write the actual routing table entries.  The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node.  We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+  NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex.  This is the one we're going to write
+// the routing information to.
+//
+  NodeList::Iterator i = NodeList::Begin (); 
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (; i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface.  If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+// 
+      Ptr<GlobalRouter> rtr = 
+        node->GetObject<GlobalRouter> ();
+
+      if (rtr == 0)
+        {
+          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
+            node->GetId ());
+          continue;
+        }
+//
+// If the router ID of the current node is equal to the router ID of the 
+// root of the SPF tree, then this node is the one for which we need to 
+// write the routing tables.
+//
+      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+      if (rtr->GetRouterId () == routerId)
+        {
+          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface.  We need to QI
+// for that interface.  If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+          NS_ASSERT_MSG (ipv4, 
+            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+            "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to.  The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node.  We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+          NS_ASSERT_MSG (v->GetLSA (), 
+            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+            "Expected valid LSA in SPFVertex* v");
+          Ipv4Mask tempmask (l->GetLinkData ().Get ());
+          Ipv4Address tempip = l->GetLinkId ();
+          tempip = tempip.CombineMask (tempmask);
+//
+// Here's why we did all of that work.  We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record.  In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link.  Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets.  The vertex <v> 
+// (corresponding to the node that has these links and interfaces) has 
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+          
+          Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+          if (router == 0)
+            {
+              continue;
+            }
+          Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+          NS_ASSERT (gr);
+          // walk through all next-hop-IPs and out-going-interfaces for reaching
+          // the stub network gateway 'v' from the root node
+          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+            {
+              SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+              Ipv4Address nextHop = exit.first;
+              int32_t outIf = exit.second;
+              if (outIf >= 0)
+                {
+                  gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
+                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                    " add network route to " << tempip <<
+                    " using next hop " << nextHop <<
+                    " via interface " << outIf);
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                    " NOT able to add network route to " << tempip <<
+                    " using next hop " << nextHop <<
+                    " since outgoing interface id is negative");
+                }
+            }
+          return;
+        } // if
+    } // for
+}
+
+//
+// Return the interface number corresponding to a given IP address and mask
+// This is a wrapper around GetInterfaceForPrefix(), but we first
+// have to find the right node pointer to pass to that function.
+// If no such interface is found, return -1 (note:  unit test framework
+// for routing assumes -1 to be a legal return value)
+//
+int32_t
+GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
+{
+  NS_LOG_FUNCTION (a << amask);
+//
+// We have an IP address <a> and a vertex ID of the root of the SPF tree.  
+// The question is what interface index does this address correspond to.
+// The answer is a little complicated since we have to find a pointer to
+// the node corresponding to the vertex ID, find the Ipv4 interface on that
+// node in order to iterate the interfaces and find the one corresponding to
+// the address in question.
+//
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+//
+// Walk the list of nodes in the system looking for the one corresponding to
+// the node at the root of the SPF tree.  This is the node for which we are
+// building the routing table.
+//
+  NodeList::Iterator i = NodeList::Begin (); 
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (; i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<GlobalRouter> rtr = 
+        node->GetObject<GlobalRouter> ();
+//
+// If the node doesn't have a GlobalRouter interface it can't be the one
+// we're interested in.
+//
+      if (rtr == 0)
+        {
+          continue;
+        }
+
+      if (rtr->GetRouterId () == routerId)
+        {
+//
+// This is the node we're building the routing table for.  We're going to need
+// the Ipv4 interface to look for the ipv4 interface index.  Since this node
+// is participating in routing IP version 4 packets, it certainly must have 
+// an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+          NS_ASSERT_MSG (ipv4, 
+            "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+            "GetObject for <Ipv4> interface failed");
+//
+// Look through the interfaces on this node for one that has the IP address
+// we're looking for.  If we find one, return the corresponding interface
+// index, or -1 if not found.
+//
+          int32_t interface = ipv4->GetInterfaceForPrefix (a, amask);
+
+#if 0
+          if (interface < 0)
+            {
+              NS_FATAL_ERROR ("GlobalRouteManagerImpl::FindOutgoingInterfaceId(): "
+                "Expected an interface associated with address a:" << a);
+            }
+#endif 
+          return interface;
+        }
+    }
+//
+// Couldn't find it.
+//
+  NS_LOG_LOGIC ("FindOutgoingInterfaceId():Can't find root node " << routerId);
+  return -1;
+}
+
+//
+// This method is derived from quagga ospf_intra_add_router ()
+//
+// This is where we are actually going to add the host routes to the routing
+// tables of the individual nodes.
+//
+// The vertex passed as a parameter has just been added to the SPF tree.
+// This vertex must have a valid m_root_oid, corresponding to the outgoing
+// interface on the root router of the tree that is the first hop on the path
+// to the vertex.  The vertex must also have a next hop address, corresponding
+// to the next hop on the path to the vertex.  The vertex has an m_lsa field
+// that has some number of link records.  For each point to point link record,
+// the m_linkData is the local IP address of the link.  This corresponds to
+// a destination IP address, reachable from the root, to which we add a host
+// route.
+//
+  void
+GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
+{
+  NS_LOG_FUNCTION (v);
+
+  NS_ASSERT_MSG (m_spfroot, 
+    "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set");
+//
+// The root of the Shortest Path First tree is the router to which we are 
+// going to write the actual routing table entries.  The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node.  We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+  NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex.  This is the one we're going to write
+// the routing information to.
+//
+  NodeList::Iterator i = NodeList::Begin (); 
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (; i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to GetObject for that interface.  If there's no GlobalRouter interface, 
+// the node in question cannot be the router we want, so we continue.
+// 
+      Ptr<GlobalRouter> rtr = 
+        node->GetObject<GlobalRouter> ();
+
+      if (rtr == 0)
+        {
+          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
+            node->GetId ());
+          continue;
+        }
+//
+// If the router ID of the current node is equal to the router ID of the 
+// root of the SPF tree, then this node is the one for which we need to 
+// write the routing tables.
+//
+      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+      if (rtr->GetRouterId () == routerId)
+        {
+          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface.  We need to 
+// GetObject for that interface.  If the node is acting as an IP version 4 
+// router, it should absolutely have an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+          NS_ASSERT_MSG (ipv4, 
+            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+            "GetObject for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to.  The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node.  We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+          GlobalRoutingLSA *lsa = v->GetLSA ();
+          NS_ASSERT_MSG (lsa, 
+            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+            "Expected valid LSA in SPFVertex* v");
+
+          uint32_t nLinkRecords = lsa->GetNLinkRecords ();
+//
+// Iterate through the link records on the vertex to which we're going to add
+// routes.  To make sure we're being clear, we're going to add routing table
+// entries to the tables on the node corresping to the root of the SPF tree.
+// These entries will have routes to the IP addresses we find from looking at
+// the local side of the point-to-point links found on the node described by
+// the vertex <v>.
+//
+          NS_LOG_LOGIC (" Node " << node->GetId () <<
+             " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ());
+          for (uint32_t j = 0; j < nLinkRecords; ++j)
+            {
+//
+// We are only concerned about point-to-point links
+//
+              GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
+              if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
+                {
+                  continue;
+                }
+//
+// Here's why we did all of that work.  We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record.  In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link.  Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets.  The vertex <v> 
+// (corresponding to the node that has these links and interfaces) has 
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+              Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+              if (router == 0)
+                {
+                  continue;
+                }
+              Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+              NS_ASSERT (gr);
+              // walk through all available exit directions due to ECMP,
+              // and add host route for each of the exit direction toward
+              // the vertex 'v'
+              for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+              {
+                SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+                Ipv4Address nextHop = exit.first;
+                int32_t outIf = exit.second;
+                if (outIf >= 0)
+                  {
+                    gr->AddHostRouteTo (lr->GetLinkData (), nextHop,
+                      outIf);
+                    NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                      " adding host route to " << lr->GetLinkData () <<
+                      " using next hop " << nextHop <<
+                      " and outgoing interface " << outIf);
+                  }
+                else
+                  {
+                    NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                      " NOT able to add host route to " << lr->GetLinkData () <<
+                      " using next hop " << nextHop <<
+                      " since outgoing interface id is negative " << outIf);
+                  }
+              } // for all routes from the root the vertex 'v'
+            }
+//
+// Done adding the routes for the selected node.
+//
+          return;
+        }
+    }
+}
+  void
+GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
+{
+  NS_LOG_FUNCTION (v);
+
+  NS_ASSERT_MSG (m_spfroot, 
+    "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
+//
+// The root of the Shortest Path First tree is the router to which we are 
+// going to write the actual routing table entries.  The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node.  We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+  NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex.  This is the one we're going to write
+// the routing information to.
+//
+  NodeList::Iterator i = NodeList::Begin (); 
+  NodeList::Iterator listEnd = NodeList::End ();
+  for (; i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to GetObject for that interface.  If there's no GlobalRouter interface, 
+// the node in question cannot be the router we want, so we continue.
+// 
+      Ptr<GlobalRouter> rtr = 
+        node->GetObject<GlobalRouter> ();
+
+      if (rtr == 0)
+        {
+          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
+            node->GetId ());
+          continue;
+        }
+//
+// If the router ID of the current node is equal to the router ID of the 
+// root of the SPF tree, then this node is the one for which we need to 
+// write the routing tables.
+//
+      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+      if (rtr->GetRouterId () == routerId)
+        {
+          NS_LOG_LOGIC ("setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface.  We need to 
+// GetObject for that interface.  If the node is acting as an IP version 4 
+// router, it should absolutely have an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+          NS_ASSERT_MSG (ipv4, 
+            "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+            "GetObject for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to.  The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node.  We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+          GlobalRoutingLSA *lsa = v->GetLSA ();
+          NS_ASSERT_MSG (lsa, 
+            "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+            "Expected valid LSA in SPFVertex* v");
+          Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
+          Ipv4Address tempip = lsa->GetLinkStateId ();
+          tempip = tempip.CombineMask (tempmask);
+          Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+          if (router == 0)
+            {
+              continue;
+            }
+          Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+          NS_ASSERT (gr);
+          // walk through all available exit directions due to ECMP,
+          // and add host route for each of the exit direction toward
+          // the vertex 'v'
+          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+          {
+            SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+            Ipv4Address nextHop = exit.first;
+            int32_t outIf = exit.second;
+
+            if (outIf >= 0)
+              {
+                gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
+                NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                  " add network route to " << tempip <<
+                  " using next hop " << nextHop <<
+                  " via interface " << outIf);
+              }
+            else
+              {
+                NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                  " NOT able to add network route to " << tempip <<
+                  " using next hop " << nextHop <<
+                  " since outgoing interface id is negative " << outIf);
+              }
+            }
+        }
+    } 
+}
+
+// Derived from quagga ospf_vertex_add_parents ()
+//
+// This is a somewhat oddly named method (blame quagga).  Although you might
+// expect it to add a parent *to* something, it actually adds a vertex
+// to the list of children *in* each of its parents. 
+//
+// Given a pointer to a vertex, it links back to the vertex's parent that it
+// already has set and adds itself to that vertex's list of children.
+//
+  void
+GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v)
+{
+  NS_LOG_FUNCTION (v);
+
+  for (uint32_t i=0;;)
+    {
+      SPFVertex* parent;
+      // check if all parents of vertex v
+      if ((parent = v->GetParent (i++)) == 0) break;
+      parent->AddChild (v);
+    }
+}
+
+} // namespace ns3
+
+
+#include "ns3/test.h"
+#include "ns3/simulator.h"
+#include <stdlib.h> // for rand()
+
+namespace ns3 {
+
+class GlobalRouteManagerImplTestCase : public TestCase
+{
+public:
+  GlobalRouteManagerImplTestCase();
+  virtual bool DoRun(void);
+};
+
+GlobalRouteManagerImplTestCase::GlobalRouteManagerImplTestCase()
+  : TestCase("GlobalRouteManagerImplTestCase")
+{}
+bool 
+GlobalRouteManagerImplTestCase::DoRun(void)
+{
+  CandidateQueue candidate;
+
+  for (int i = 0; i < 100; ++i)
+    {
+      SPFVertex *v = new SPFVertex;
+      v->SetDistanceFromRoot (rand () % 100);
+      candidate.Push (v);
+    }
+
+  uint32_t lastDistance = 0;
+
+  for (int i = 0; i < 100; ++i)
+    {
+      SPFVertex *v = candidate.Pop ();
+      if (v->GetDistanceFromRoot () < lastDistance)
+        {
+          // XXX does nothing.
+          UpdateErrorStatus (false);
+        }
+      lastDistance = v->GetDistanceFromRoot ();
+      delete v;
+      v = 0;
+    }
+
+  // Build fake link state database; four routers (0-3), 3 point-to-point
+  // links
+  //
+  //   n0
+  //      \ link 0
+  //       \          link 2
+  //        n2 -------------------------n3
+  //       /
+  //      / link 1
+  //    n1
+  //
+  //  link0:  10.1.1.1/30, 10.1.1.2/30
+  //  link1:  10.1.2.1/30, 10.1.2.2/30
+  //  link2:  10.1.3.1/30, 10.1.3.2/30
+  //
+  // Router 0
+  GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint, 
+    "0.0.0.2",  // router ID 0.0.0.2
+    "10.1.1.1", // local ID
+    1);         // metric
+
+  GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
+    "10.1.1.1",
+    "255.255.255.252",
+    1);
+
+  GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
+  lsa0->SetLSType (GlobalRoutingLSA::RouterLSA);
+  lsa0->SetLinkStateId ("0.0.0.0");
+  lsa0->SetAdvertisingRouter ("0.0.0.0");
+  lsa0->AddLinkRecord (lr0);
+  lsa0->AddLinkRecord (lr1);
+
+  // Router 1
+  GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
+    "0.0.0.2",
+    "10.1.2.1",
+    1);
+
+  GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
+    "10.1.2.1",
+    "255.255.255.252",
+    1);
+
+  GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
+  lsa1->SetLSType (GlobalRoutingLSA::RouterLSA);
+  lsa1->SetLinkStateId ("0.0.0.1");
+  lsa1->SetAdvertisingRouter ("0.0.0.1");
+  lsa1->AddLinkRecord (lr2);
+  lsa1->AddLinkRecord (lr3);
+  
+  // Router 2 
+  GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
+    "0.0.0.0",
+    "10.1.1.2",
+    1);
+
+  GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
+    "10.1.1.2",
+    "255.255.255.252",
+    1);
+
+  GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
+    "0.0.0.1",
+    "10.1.2.2",
+    1);
+
+  GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
+    "10.1.2.2",
+    "255.255.255.252",
+    1);
+
+  GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
+    "0.0.0.3",
+    "10.1.3.2",
+    1);
+
+  GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
+    "10.1.3.2",
+    "255.255.255.252",
+    1);
+
+  GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
+  lsa2->SetLSType (GlobalRoutingLSA::RouterLSA);
+  lsa2->SetLinkStateId ("0.0.0.2");
+  lsa2->SetAdvertisingRouter ("0.0.0.2");
+  lsa2->AddLinkRecord (lr4);
+  lsa2->AddLinkRecord (lr5);
+  lsa2->AddLinkRecord (lr6);
+  lsa2->AddLinkRecord (lr7);
+  lsa2->AddLinkRecord (lr8);
+  lsa2->AddLinkRecord (lr9);
+
+  // Router 3
+  GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
+    "0.0.0.2",
+    "10.1.2.1",
+    1);
+
+  GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
+    "10.1.2.1",
+    "255.255.255.252",
+    1);
+
+  GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
+  lsa3->SetLSType (GlobalRoutingLSA::RouterLSA);
+  lsa3->SetLinkStateId ("0.0.0.3");
+  lsa3->SetAdvertisingRouter ("0.0.0.3");
+  lsa3->AddLinkRecord (lr10);
+  lsa3->AddLinkRecord (lr11);
+
+  // Test the database 
+  GlobalRouteManagerLSDB* srmlsdb = new GlobalRouteManagerLSDB ();
+  srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0);
+  srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1);
+  srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2);
+  srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3);
+  NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ()));
+
+  // next, calculate routes based on the manually created LSDB
+  GlobalRouteManagerImpl* srm = new GlobalRouteManagerImpl ();
+  srm->DebugUseLsdb (srmlsdb);  // manually add in an LSDB
+  // Note-- this will succeed without any nodes in the topology
+  // because the NodeList is empty
+  srm->DebugSPFCalculate (lsa0->GetLinkStateId ());  // node n0
+
+  Simulator::Run ();
+
+// XXX here we should do some verification of the routes built
+
+  Simulator::Destroy ();
+
+  // This delete clears the srm, which deletes the LSDB, which clears 
+  // all of the LSAs, which each destroys the attached LinkRecords.
+  delete srm;
+
+  // XXX
+  // No testing has actually been done other than making sure that this code
+  // does not crash
+  return GetErrorStatus ();
+}
+
+
+static class GlobalRouteManagerImplTestSuite : public TestSuite
+{
+public:
+  GlobalRouteManagerImplTestSuite()
+    : TestSuite("global-route-manager-impl", UNIT)
+  {
+    AddTestCase(new GlobalRouteManagerImplTestCase());
+  }
+} g_globalRoutingManagerImplTestSuite;
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager-impl.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,781 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * 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:  Craig Dowell (craigdo@ee.washington.edu)
+ *           Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#ifndef GLOBAL_ROUTE_MANAGER_IMPL_H
+#define GLOBAL_ROUTE_MANAGER_IMPL_H
+
+#include <stdint.h>
+#include <list>
+#include <queue>
+#include <map>
+#include <vector>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "global-router-interface.h"
+
+namespace ns3 {
+
+const uint32_t SPF_INFINITY = 0xffffffff;
+
+class CandidateQueue;
+class Ipv4GlobalRouting;
+
+/**
+ * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328,
+ * Section 16.
+ *
+ * Each router in the simulation is associated with an SPFVertex object.  When
+ * calculating routes, each of these routers is, in turn, chosen as the "root"
+ * of the calculation and routes to all of the other routers are eventually
+ * saved in the routing tables of each of the chosen nodes.  Each of these 
+ * routers in the calculation has an associated SPFVertex.
+ *
+ * The "Root" vertex is the SPFVertex representing the router that is having
+ * its routing tables set.  The SPFVertex objects representing other routers
+ * or networks in the simulation are arranged in the SPF tree.  It is this 
+ * tree that represents the Shortest Paths to the other networks.
+ *
+ * Each SPFVertex has a pointer to the Global Router Link State Advertisement
+ * (LSA) that its underlying router has exported.  Within these LSAs are
+ * Global Router Link Records that describe the point to point links from the
+ * underlying router to other nodes (represented by other SPFVertex objects)
+ * in the simulation topology.  The combination of the arrangement of the 
+ * SPFVertex objects in the SPF tree, along with the details of the link
+ * records that connect them provide the information required to construct the
+ * required routes.
+ */
+class SPFVertex
+{
+public:
+/**
+ * @brief Enumeration of the possible types of SPFVertex objects.
+ * @internal
+ *
+ * Currently we use VertexRouter to identify objects that represent a router 
+ * in the simulation topology, and VertexNetwork to identify objects that 
+ * represent a network.
+ */
+  enum VertexType {
+    VertexUnknown = 0,  /**< Uninitialized Link Record */
+    VertexRouter,       /**< Vertex representing a router in the topology */
+    VertexNetwork       /**< Vertex representing a network in the topology */
+  };
+
+/**
+ * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First 
+ * Vertex).
+ * @internal
+ *
+ * The Vertex Type is set to VertexUnknown, the Vertex ID is set to 
+ * 255.255.255.255, and the distance from root is set to infinity 
+ * (UINT32_MAX).  The referenced Link State Advertisement (LSA) is set to 
+ * null as is the parent SPFVertex.  The outgoing interface index is set to
+ * infinity, the next hop address is set to 0.0.0.0 and the list of children
+ * of the SPFVertex is initialized to empty.
+ *
+ * @see VertexType
+ */
+  SPFVertex();
+
+/**
+ * @brief Construct an initialized SPFVertex (Shortest Path First Vertex).
+ * @internal
+ *
+ * The Vertex Type is initialized to VertexRouter and the Vertex ID is found
+ * from the Link State ID of the Link State Advertisement (LSA) passed as a
+ * parameter.  The Link State ID is set to the Router ID of the advertising
+ * router.  The referenced LSA (m_lsa) is set to the given LSA.  Other than 
+ * these members, initialization is as in the default constructor.
+ * of the SPFVertex is initialized to empty.
+ *
+ * @see SPFVertex::SPFVertex ()
+ * @see VertexType
+ * @see GlobalRoutingLSA
+ * @param lsa The Link State Advertisement used for finding initial values.
+ */
+  SPFVertex(GlobalRoutingLSA* lsa);
+
+/**
+ * @brief Destroy an SPFVertex (Shortest Path First Vertex).
+ * @internal
+ *
+ * The children vertices of the SPFVertex are recursively deleted.
+ *
+ * @see SPFVertex::SPFVertex ()
+ */
+  ~SPFVertex();
+
+/**
+ * @brief Get the Vertex Type field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex Type describes the kind of simulation object a given SPFVertex
+ * represents.
+ *
+ * @see VertexType
+ * @returns The VertexType of the current SPFVertex object.
+ */
+  VertexType GetVertexType (void) const;
+
+/**
+ * @brief Set the Vertex Type field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex Type describes the kind of simulation object a given SPFVertex
+ * represents.
+ *
+ * @see VertexType
+ * @param type The new VertexType for the current SPFVertex object.
+ */
+  void SetVertexType (VertexType type);
+
+/**
+ * @brief Get the Vertex ID field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex ID uniquely identifies the simulation object a given SPFVertex
+ * represents.  Typically, this is the Router ID for SPFVertex objects 
+ * representing routers, and comes from the Link State Advertisement of a 
+ * router aggregated to a node in the simulation.  These IDs are allocated
+ * automatically by the routing environment and look like IP addresses 
+ * beginning at 0.0.0.0 and monotonically increasing as new routers are
+ * instantiated.
+ *
+ * @returns The Ipv4Address Vertex ID of the current SPFVertex object.
+ */
+  Ipv4Address GetVertexId (void) const;
+
+/**
+ * @brief Set the Vertex ID field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex ID uniquely identifies the simulation object a given SPFVertex
+ * represents.  Typically, this is the Router ID for SPFVertex objects 
+ * representing routers, and comes from the Link State Advertisement of a 
+ * router aggregated to a node in the simulation.  These IDs are allocated
+ * automatically by the routing environment and look like IP addresses 
+ * beginning at 0.0.0.0 and monotonically increase as new routers are
+ * instantiated.  This method is an explicit override of the automatically
+ * generated value.
+ *
+ * @param id The new Ipv4Address Vertex ID for the current SPFVertex object.
+ */
+  void SetVertexId (Ipv4Address id);
+
+/**
+ * @brief Get the Global Router Link State Advertisement returned by the 
+ * Global Router represented by this SPFVertex during the route discovery 
+ * process.
+ * @internal
+ *
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRouter::DiscoverLSAs ()
+ * @returns A pointer to the GlobalRoutingLSA found by the router represented
+ * by this SPFVertex object.
+ */
+  GlobalRoutingLSA* GetLSA (void) const;
+
+/**
+ * @brief Set the Global Router Link State Advertisement returned by the 
+ * Global Router represented by this SPFVertex during the route discovery 
+ * process.
+ * @internal
+ *
+ * @see SPFVertex::GetLSA ()
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRouter::DiscoverLSAs ()
+ * @warning Ownership of the LSA is transferred to the "this" SPFVertex.  You
+ * must not delete the LSA after calling this method.
+ * @param lsa A pointer to the GlobalRoutingLSA.
+ */
+  void SetLSA (GlobalRoutingLSA* lsa);
+
+/**
+ * @brief Get the distance from the root vertex to "this" SPFVertex object.
+ * @internal
+ *
+ * Each router in the simulation is associated with an SPFVertex object.  When
+ * calculating routes, each of these routers is, in turn, chosen as the "root"
+ * of the calculation and routes to all of the other routers are eventually
+ * saved in the routing tables of each of the chosen nodes.  Each of these 
+ * routers in the calculation has an associated SPFVertex.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set.  The "this" SPFVertex is the vertex to which
+ * a route is being calculated from the root.  The distance from the root that
+ * we're asking for is the number of hops from the root vertex to the vertex
+ * in question.
+ *
+ * The distance is calculated during route discovery and is stored in a
+ * member variable.  This method simply fetches that value.
+ *
+ * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex.
+ */
+  uint32_t GetDistanceFromRoot (void) const;
+
+/**
+ * @brief Set the distance from the root vertex to "this" SPFVertex object.
+ * @internal
+ *
+ * Each router in the simulation is associated with an SPFVertex object.  When
+ * calculating routes, each of these routers is, in turn, chosen as the "root"
+ * of the calculation and routes to all of the other routers are eventually
+ * saved in the routing tables of each of the chosen nodes.  Each of these 
+ * routers in the calculation has an associated SPFVertex.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set.  The "this" SPFVertex is the vertex to which
+ * a route is being calculated from the root.  The distance from the root that
+ * we're asking for is the number of hops from the root vertex to the vertex
+ * in question.
+ *
+ * @param distance The distance, in hops, from the root SPFVertex to "this"
+ * SPFVertex.
+ */
+  void SetDistanceFromRoot (uint32_t distance);
+
+/**
+ * @brief Set the IP address and outgoing interface index that should be used 
+ * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set.  The "this" SPFVertex is the vertex that
+ * represents the host or network to which a route is being calculated from 
+ * the root.  The IP address that we're asking for is the address on the 
+ * remote side of a link off of the root node that should be used as the
+ * destination for packets along the path to "this" vertex.
+ *
+ * When initializing the root SPFVertex, the IP address used when forwarding
+ * packets is determined by examining the Global Router Link Records of the
+ * Link State Advertisement generated by the root node's GlobalRouter.  This
+ * address is used to forward packets off of the root's network down those
+ * links.  As other vertices / nodes are discovered which are further away
+ * from the root, they will be accessible down one of the paths via a link
+ * described by one of these Global Router Link Records.
+ * 
+ * To forward packets to these hosts or networks, the root node must begin
+ * the forwarding process by sending the packets to a first hop router down
+ * an interface.  This means that the first hop address and interface ID must
+ * be the same for all downstream SPFVertices.  We call this "inheriting"
+ * the interface and next hop.
+ *
+ * In this method we are telling the root node which exit direction it should send
+ * should I send a packet to the network or host represented by 'this' SPFVertex.
+ *
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
+ * @param nextHop The IP address to use when forwarding packets to the host
+ * or network represented by "this" SPFVertex.
+ * @param id The interface index to use when forwarding packets to the host or
+ * network represented by "this" SPFVertex.
+ */
+  void SetRootExitDirection (Ipv4Address nextHop, int32_t id = SPF_INFINITY);
+  typedef std::pair<Ipv4Address, int32_t> NodeExit_t;
+/**
+ * @brief Set the IP address and outgoing interface index that should be used 
+ * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set.  The "this" SPFVertex is the vertex that
+ * represents the host or network to which a route is being calculated from 
+ * the root.  The IP address that we're asking for is the address on the 
+ * remote side of a link off of the root node that should be used as the
+ * destination for packets along the path to "this" vertex.
+ *
+ * When initializing the root SPFVertex, the IP address used when forwarding
+ * packets is determined by examining the Global Router Link Records of the
+ * Link State Advertisement generated by the root node's GlobalRouter.  This
+ * address is used to forward packets off of the root's network down those
+ * links.  As other vertices / nodes are discovered which are further away
+ * from the root, they will be accessible down one of the paths via a link
+ * described by one of these Global Router Link Records.
+ * 
+ * To forward packets to these hosts or networks, the root node must begin
+ * the forwarding process by sending the packets to a first hop router down
+ * an interface.  This means that the first hop address and interface ID must
+ * be the same for all downstream SPFVertices.  We call this "inheriting"
+ * the interface and next hop.
+ *
+ * In this method we are telling the root node which exit direction it should send
+ * should I send a packet to the network or host represented by 'this' SPFVertex.
+ *
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
+ * @param nextHop The IP address to use when forwarding packets to the host
+ * or network represented by "this" SPFVertex.
+ * @param exit The pair of next-hop-IP and outgoing-interface-index to use when 
+ * forwarding packets to the host or network represented by "this" SPFVertex.
+ */
+  void SetRootExitDirection (SPFVertex::NodeExit_t exit);
+ /**
+  * \brief Obtain a pair indicating the exit direction from the root
+  *
+  * \param i An index to a pair
+  * \return A pair of next-hop-IP and outgoing-interface-index for 
+  * indicating an exit direction from the root. It is 0 if the index 'i'
+  * is out-of-range
+  */
+  NodeExit_t GetRootExitDirection (uint32_t i) const;
+  /**
+   * \brief Obtain a pair indicating the exit direction from the root
+   *
+   * This method assumes there is only a single exit direction from the root.
+   * Error occur if this assumption is invalid.
+   *
+   * \return The pair of next-hop-IP and outgoing-interface-index for reaching
+   * 'this' vertex from the root
+   */
+  NodeExit_t GetRootExitDirection () const;
+  /**
+   * \brief Merge into 'this' vertex the list of exit directions from
+   * another vertex
+   *
+   * This merge is necessary when ECMP are found. 
+   *
+   * \param vertex From which the list of exit directions are obtain
+   * and are merged into 'this' vertex
+   */
+  void MergeRootExitDirections (const SPFVertex* vertex);
+  /**
+   * \brief Inherit all root exit directions from a given vertex to 'this' vertex
+   * \param vertex The vertex from which all root exit directions are to be inherited
+   *
+   * After the call of this method, the original root exit directions
+   * in 'this' vertex are all lost.
+   */
+  void InheritAllRootExitDirections (const SPFVertex* vertex);
+  /**
+   * \brief Get the number of exit directions from root for reaching 'this' vertex
+   * \return The number of exit directions from root
+   */
+  uint32_t GetNRootExitDirections () const;
+
+/**
+ * @brief Get a pointer to the SPFVector that is the parent of "this" 
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.
+ *
+ * This method returns a pointer to the parent node of "this" SPFVertex
+ * (both of which reside in that SPF tree).
+ *
+ * @param i The index to one of the parents
+ * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex
+ * in the SPF tree.
+ */
+  SPFVertex* GetParent (uint32_t i = 0) const;
+
+/**
+ * @brief Set the pointer to the SPFVector that is the parent of "this" 
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.
+ *
+ * This method sets the parent pointer of "this" SPFVertex (both of which
+ * reside in that SPF tree).
+ *
+ * @param parent A pointer to the SPFVertex that is the parent of "this" 
+ * SPFVertex* in the SPF tree.
+ */
+  void SetParent (SPFVertex* parent);
+  /**
+   * \brief Merge the Parent list from the v into this vertex
+   *
+   * \param v The vertex from which its list of Parent is read
+   * and then merged into the list of Parent of *this* vertex.
+   * Note that the list in v remains intact
+   */
+  void MergeParent (const SPFVertex* v);
+
+/**
+ * @brief Get the number of children of "this" SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.  Each vertex
+ * in the SPF tree can have a number of children that represent host or 
+ * network routes available via that vertex.
+ *
+ * This method returns the number of children of "this" SPFVertex (which 
+ * reside in the SPF tree).
+ *
+ * @returns The number of children of "this" SPFVertex (which reside in the
+ * SPF tree).
+ */
+  uint32_t GetNChildren (void) const;
+
+/**
+ * @brief Get a borrowed SPFVertex pointer to the specified child of "this" 
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.  Each vertex
+ * in the SPF tree can have a number of children that represent host or 
+ * network routes available via that vertex.
+ *
+ * This method the number of children of "this" SPFVertex (which reside in
+ * the SPF tree.
+ *
+ * @see SPFVertex::GetNChildren
+ * @param n The index (from 0 to the number of children minus 1) of the 
+ * child SPFVertex to return.
+ * @warning The pointer returned by GetChild () is a borrowed pointer.  You
+ * do not have any ownership of the underlying object and must not delete
+ * that object.
+ * @returns A pointer to the specified child SPFVertex (which resides in the
+ * SPF tree).
+ */
+  SPFVertex* GetChild (uint32_t n) const;
+
+/**
+ * @brief Get a borrowed SPFVertex pointer to the specified child of "this" 
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the 
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.  Each vertex
+ * in the SPF tree can have a number of children that represent host or 
+ * network routes available via that vertex.
+ *
+ * This method the number of children of "this" SPFVertex (which reside in
+ * the SPF tree.
+ *
+ * @see SPFVertex::GetNChildren
+ * @warning Ownership of the pointer added to the children of "this" 
+ * SPFVertex is transferred to the "this" SPFVertex.  You must not delete the
+ * (now) child SPFVertex after calling this method.
+ * @param child A pointer to the SPFVertex (which resides in the SPF tree) to
+ * be added to the list of children of "this" SPFVertex.
+ * @returns The number of children of "this" SPFVertex after the addition of
+ * the new child.
+ */
+  uint32_t AddChild (SPFVertex* child);
+
+  /**
+   * @brief Set the value of the VertexProcessed flag
+   *
+   * Flag to note whether vertex has been processed in stage two of 
+   * SPF computation
+   * @param value boolean value to set the flag
+   */ 
+  void SetVertexProcessed (bool value);
+
+  /**
+   * @brief Check the value of the VertexProcessed flag
+   *
+   * Flag to note whether vertex has been processed in stage two of 
+   * SPF computation
+   * @returns value of underlying flag
+   */ 
+  bool IsVertexProcessed (void) const;
+  
+  void ClearVertexProcessed (void);
+      
+private:
+  VertexType m_vertexType;
+  Ipv4Address m_vertexId;
+  GlobalRoutingLSA* m_lsa;
+  uint32_t m_distanceFromRoot;
+  int32_t m_rootOif;
+  Ipv4Address m_nextHop;
+  typedef std::list< NodeExit_t > ListOfNodeExit_t;
+  /// store the multiple root's exits for supporting ECMP
+  ListOfNodeExit_t m_ecmpRootExits;
+  typedef std::list<SPFVertex*> ListOfSPFVertex_t;
+  ListOfSPFVertex_t m_parents;
+  ListOfSPFVertex_t m_children;
+  bool m_vertexProcessed; 
+
+/**
+ * @brief The SPFVertex copy construction is disallowed.  There's no need for
+ * it and a compiler provided shallow copy would be wrong.
+ */
+  SPFVertex (SPFVertex& v);
+
+/**
+ * @brief The SPFVertex copy assignment operator is disallowed.  There's no 
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+  SPFVertex& operator= (SPFVertex& v);
+
+  //friend std::ostream& operator<< (std::ostream& os, const ListOfIf_t& ifs);
+  //friend std::ostream& operator<< (std::ostream& os, const ListOfAddr_t& addrs);
+  friend std::ostream& operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs);
+};
+
+/**
+ * @brief The Link State DataBase (LSDB) of the Global Route Manager.
+ *
+ * Each node in the simulation participating in global routing has a
+ * GlobalRouter interface.  The primary job of this interface is to export
+ * Global Router Link State Advertisements (LSAs).  These advertisements in
+ * turn contain a number of Global Router Link Records that describe the 
+ * point to point links from the underlying node to other nodes (that will 
+ * also export their own LSAs.
+ *
+ * This class implements a searchable database of LSAs gathered from every
+ * router in the simulation.
+ */
+class GlobalRouteManagerLSDB
+{
+public:
+/**
+ * @brief Construct an empty Global Router Manager Link State Database.
+ * @internal
+ *
+ * The database map composing the Link State Database is initialized in
+ * this constructor.
+ */
+  GlobalRouteManagerLSDB ();
+
+/**
+ * @brief Destroy an empty Global Router Manager Link State Database.
+ * @internal
+ *
+ * The database map is walked and all of the Link State Advertisements stored
+ * in the database are freed; then the database map itself is clear ()ed to
+ * release any remaining resources.
+ */
+  ~GlobalRouteManagerLSDB ();
+
+/**
+ * @brief Insert an IP address / Link State Advertisement pair into the Link
+ * State Database.
+ * @internal
+ *
+ * The IPV4 address and the GlobalRoutingLSA given as parameters are converted
+ * to an STL pair and are inserted into the database map.
+ *
+ * @see GlobalRoutingLSA
+ * @see Ipv4Address
+ * @param addr The IP address associated with the LSA.  Typically the Router 
+ * ID.
+ * @param lsa A pointer to the Link State Advertisement for the router.
+ */
+  void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
+
+/**
+ * @brief Look up the Link State Advertisement associated with the given
+ * link state ID (address).
+ * @internal
+ *
+ * The database map is searched for the given IPV4 address and corresponding
+ * GlobalRoutingLSA is returned.
+ *
+ * @see GlobalRoutingLSA
+ * @see Ipv4Address
+ * @param addr The IP address associated with the LSA.  Typically the Router 
+ * ID.
+ * @returns A pointer to the Link State Advertisement for the router specified
+ * by the IP address addr.
+ */
+  GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
+/**
+ * @brief Look up the Link State Advertisement associated with the given
+ * link state ID (address).  This is a variation of the GetLSA call
+ * to allow the LSA to be found by matching addr with the LinkData field
+ * of the TransitNetwork link record.
+ * @internal
+ *
+ * @see GetLSA
+ * @param addr The IP address associated with the LSA.  Typically the Router 
+ * @returns A pointer to the Link State Advertisement for the router specified
+ * by the IP address addr.
+ * ID.
+ */
+  GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
+
+/**
+ * @brief Set all LSA flags to an initialized state, for SPF computation
+ * @internal
+ *
+ * This function walks the database and resets the status flags of all of the
+ * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED.  This is done
+ * prior to each SPF calculation to reset the state of the SPFVertex structures
+ * that will reference the LSAs during the calculation.
+ *
+ * @see GlobalRoutingLSA
+ * @see SPFVertex
+ */
+  void Initialize ();
+  
+  GlobalRoutingLSA* GetExtLSA (uint32_t index) const;
+  uint32_t GetNumExtLSAs () const;
+      
+
+private:
+  typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
+  typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
+
+  LSDBMap_t m_database;
+  std::vector<GlobalRoutingLSA*> m_extdatabase;
+  
+/**
+ * @brief GlobalRouteManagerLSDB copy construction is disallowed.  There's no 
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+  GlobalRouteManagerLSDB (GlobalRouteManagerLSDB& lsdb);
+
+/**
+ * @brief The SPFVertex copy assignment operator is disallowed.  There's no 
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+  GlobalRouteManagerLSDB& operator= (GlobalRouteManagerLSDB& lsdb);
+};
+
+/**
+ * @brief A global router implementation.
+ *
+ * This singleton object can query interface each node in the system
+ * for a GlobalRouter interface.  For those nodes, it fetches one or
+ * more Link State Advertisements and stores them in a local database.
+ * Then, it can compute shortest paths on a per-node basis to all routers, 
+ * and finally configure each of the node's forwarding tables.
+ *
+ * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
+ */
+class GlobalRouteManagerImpl
+{
+public:
+  GlobalRouteManagerImpl ();
+  virtual ~GlobalRouteManagerImpl ();
+/**
+ * @brief Delete all static routes on all nodes that have a
+ * GlobalRouterInterface
+ *
+ * TODO:  separate manually assigned static routes from static routes that
+ * the global routing code injects, and only delete the latter
+ * @internal
+ *
+ */
+  virtual void DeleteGlobalRoutes ();
+
+/**
+ * @brief Build the routing database by gathering Link State Advertisements
+ * from each node exporting a GlobalRouter interface.
+ * @internal
+ */
+  virtual void BuildGlobalRoutingDatabase ();
+
+/**
+ * @brief Compute routes using a Dijkstra SPF computation and populate
+ * per-node forwarding tables
+ * @internal
+ */
+  virtual void InitializeRoutes ();
+
+/**
+ * @brief Debugging routine; allow client code to supply a pre-built LSDB
+ * @internal
+ */
+  void DebugUseLsdb (GlobalRouteManagerLSDB*);
+
+/**
+ * @brief Debugging routine; call the core SPF from the unit tests
+ * @internal
+ */
+  void DebugSPFCalculate (Ipv4Address root);
+
+private:
+/**
+ * @brief GlobalRouteManagerImpl copy construction is disallowed.
+ * There's no  need for it and a compiler provided shallow copy would be 
+ * wrong.
+ */
+  GlobalRouteManagerImpl (GlobalRouteManagerImpl& srmi);
+
+/**
+ * @brief Global Route Manager Implementation assignment operator is
+ * disallowed.  There's no  need for it and a compiler provided shallow copy
+ * would be hopelessly wrong.
+ */
+  GlobalRouteManagerImpl& operator= (GlobalRouteManagerImpl& srmi);
+
+  SPFVertex* m_spfroot;
+  GlobalRouteManagerLSDB* m_lsdb;
+  bool CheckForStubNode (Ipv4Address root);
+  void SPFCalculate (Ipv4Address root);
+  void SPFProcessStubs (SPFVertex* v);
+  void ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa);
+  void SPFNext (SPFVertex*, CandidateQueue&);
+  int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, 
+    GlobalRoutingLinkRecord* l, uint32_t distance);
+  void SPFVertexAddParent (SPFVertex* v);
+  GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, 
+    GlobalRoutingLinkRecord* prev_link);
+  void SPFIntraAddRouter (SPFVertex* v);
+  void SPFIntraAddTransit (SPFVertex* v);
+  void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
+  void SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v);
+  int32_t FindOutgoingInterfaceId (Ipv4Address a, 
+    Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+};
+
+} // namespace ns3
+
+#endif /* GLOBAL_ROUTE_MANAGER_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * 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: Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulation-singleton.h"
+#include "global-route-manager.h"
+#include "global-route-manager-impl.h"
+
+namespace ns3 {
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouteManager Implementation
+//
+// ---------------------------------------------------------------------------
+
+  void
+GlobalRouteManager::DeleteGlobalRoutes ()
+{
+  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
+    DeleteGlobalRoutes ();
+}
+
+  void
+GlobalRouteManager::BuildGlobalRoutingDatabase (void) 
+{
+  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
+    BuildGlobalRoutingDatabase ();
+}
+
+  void
+GlobalRouteManager::InitializeRoutes (void)
+{
+  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
+    InitializeRoutes ();
+}
+
+  uint32_t
+GlobalRouteManager::AllocateRouterId (void)
+{
+  static uint32_t routerId = 0;
+  return routerId++;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * 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:  Craig Dowell (craigdo@ee.washington.edu)
+ *           Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#ifndef GLOBAL_ROUTE_MANAGER_H
+#define GLOBAL_ROUTE_MANAGER_H
+
+#include "ns3/deprecated.h"
+
+namespace ns3 {
+
+/**
+ * @brief A global global router
+ *
+ * This singleton object can query interface each node in the system
+ * for a GlobalRouter interface.  For those nodes, it fetches one or
+ * more Link State Advertisements and stores them in a local database.
+ * Then, it can compute shortest paths on a per-node basis to all routers, 
+ * and finally configure each of the node's forwarding tables.
+ *
+ * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
+ */
+class GlobalRouteManager
+{
+public:
+/**
+ * @brief Allocate a 32-bit router ID from monotonically increasing counter.
+ */
+  static uint32_t AllocateRouterId ();
+
+/**
+ * @brief Delete all static routes on all nodes that have a 
+ * GlobalRouterInterface
+ *
+ */
+  static void DeleteGlobalRoutes ();
+
+/**
+ * @brief Build the routing database by gathering Link State Advertisements
+ * from each node exporting a GlobalRouter interface.
+ * @internal
+ *
+ */
+  static void BuildGlobalRoutingDatabase ();
+
+/**
+ * @brief Compute routes using a Dijkstra SPF computation and populate
+ * per-node forwarding tables
+ * @internal
+ */
+  static void InitializeRoutes ();
+
+private:
+/**
+ * @brief Global Route Manager copy construction is disallowed.  There's no 
+ * need for it and a compiler provided shallow copy would be wrong.
+ *
+ */
+  GlobalRouteManager (GlobalRouteManager& srm);
+
+/**
+ * @brief Global Router copy assignment operator is disallowed.  There's no 
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+  GlobalRouteManager& operator= (GlobalRouteManager& srm);
+};
+
+} // namespace ns3
+
+#endif /* GLOBAL_ROUTE_MANAGER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-router-interface.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,1694 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * 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:  Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/abort.h"
+#include "ns3/channel.h"
+#include "ns3/net-device.h"
+#include "ns3/node.h"
+#include "ns3/node-list.h"
+#include "ns3/ipv4.h"
+#include "ns3/bridge-net-device.h"
+#include "ipv4-global-routing.h"
+#include "global-router-interface.h"
+#include <vector>
+
+NS_LOG_COMPONENT_DEFINE ("GlobalRouter");
+
+namespace ns3 {
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRoutingLinkRecord Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
+:
+  m_linkId ("0.0.0.0"),
+  m_linkData ("0.0.0.0"),
+  m_linkType (Unknown),
+  m_metric (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
+  LinkType    linkType, 
+  Ipv4Address linkId, 
+  Ipv4Address linkData, 
+  uint16_t    metric)
+:
+  m_linkId (linkId),
+  m_linkData (linkData),
+  m_linkType (linkType),
+  m_metric (metric)
+{
+  NS_LOG_FUNCTION (this << linkType << linkId << linkData << metric);
+}
+
+GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+  Ipv4Address
+GlobalRoutingLinkRecord::GetLinkId (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_linkId;
+}
+
+  void
+GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_linkId = addr;
+}
+
+  Ipv4Address
+GlobalRoutingLinkRecord::GetLinkData (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_linkData;
+}
+
+  void
+GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_linkData = addr;
+}
+
+  GlobalRoutingLinkRecord::LinkType
+GlobalRoutingLinkRecord::GetLinkType (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_linkType;
+}
+
+  void
+GlobalRoutingLinkRecord::SetLinkType (
+  GlobalRoutingLinkRecord::LinkType linkType)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_linkType = linkType;
+}
+
+  uint16_t
+GlobalRoutingLinkRecord::GetMetric (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_metric;
+}
+
+  void
+GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_metric = metric;
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRoutingLSA Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRoutingLSA::GlobalRoutingLSA()
+  : 
+  m_lsType (GlobalRoutingLSA::Unknown),
+  m_linkStateId("0.0.0.0"),
+  m_advertisingRtr("0.0.0.0"),
+  m_linkRecords(),
+  m_networkLSANetworkMask("0.0.0.0"),
+  m_attachedRouters(),
+  m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED),
+  m_node_id(0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+GlobalRoutingLSA::GlobalRoutingLSA (
+  GlobalRoutingLSA::SPFStatus status,
+  Ipv4Address linkStateId, 
+  Ipv4Address advertisingRtr)
+:
+  m_lsType (GlobalRoutingLSA::Unknown),
+  m_linkStateId(linkStateId),
+  m_advertisingRtr(advertisingRtr),
+  m_linkRecords(),
+  m_networkLSANetworkMask("0.0.0.0"),
+  m_attachedRouters(),
+  m_status(status),
+  m_node_id(0)
+{
+  NS_LOG_FUNCTION (this << status << linkStateId << advertisingRtr);
+}
+
+GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
+  : m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId), 
+    m_advertisingRtr(lsa.m_advertisingRtr), 
+    m_networkLSANetworkMask(lsa.m_networkLSANetworkMask), 
+    m_status(lsa.m_status),
+    m_node_id(lsa.m_node_id)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT_MSG(IsEmpty(), 
+    "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
+  CopyLinkRecords (lsa);
+}
+
+  GlobalRoutingLSA&
+GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_lsType = lsa.m_lsType;
+  m_linkStateId = lsa.m_linkStateId;
+  m_advertisingRtr = lsa.m_advertisingRtr;
+  m_networkLSANetworkMask = lsa.m_networkLSANetworkMask, 
+  m_status = lsa.m_status;
+  m_node_id = lsa.m_node_id;
+
+  ClearLinkRecords ();
+  CopyLinkRecords (lsa);
+  return *this;
+}
+
+  void
+GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
+       i != lsa.m_linkRecords.end (); 
+       i++)
+    {
+      GlobalRoutingLinkRecord *pSrc = *i;
+      GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
+
+      pDst->SetLinkType (pSrc->GetLinkType ());
+      pDst->SetLinkId (pSrc->GetLinkId ());
+      pDst->SetLinkData (pSrc->GetLinkData ());
+      pDst->SetMetric (pSrc->GetMetric ());
+
+      m_linkRecords.push_back(pDst);
+      pDst = 0;
+    }
+
+   m_attachedRouters = lsa.m_attachedRouters;
+}
+
+GlobalRoutingLSA::~GlobalRoutingLSA()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  ClearLinkRecords ();
+}
+
+  void
+GlobalRoutingLSA::ClearLinkRecords(void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
+        i != m_linkRecords.end (); 
+        i++)
+    {
+      NS_LOG_LOGIC ("Free link record");
+
+      GlobalRoutingLinkRecord *p = *i;
+      delete p;
+      p = 0;
+
+      *i = 0;
+    }
+  NS_LOG_LOGIC ("Clear list");
+  m_linkRecords.clear();
+}
+
+  uint32_t
+GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_linkRecords.push_back (lr);
+  return m_linkRecords.size ();
+}
+
+  uint32_t
+GlobalRoutingLSA::GetNLinkRecords (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_linkRecords.size ();
+}
+
+  GlobalRoutingLinkRecord *
+GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t j = 0;
+  for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
+        i != m_linkRecords.end (); 
+        i++, j++)
+    {
+      if (j == n) 
+        {
+          return *i;
+        }
+    }
+  NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
+  return 0;
+}
+
+  bool
+GlobalRoutingLSA::IsEmpty (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_linkRecords.size () == 0;
+}
+
+  GlobalRoutingLSA::LSType
+GlobalRoutingLSA::GetLSType (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_lsType;
+}
+
+  void 
+GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_lsType = typ;
+}
+
+  Ipv4Address
+GlobalRoutingLSA::GetLinkStateId (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_linkStateId;
+}
+
+  void
+GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_linkStateId = addr;
+}
+
+  Ipv4Address
+GlobalRoutingLSA::GetAdvertisingRouter (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_advertisingRtr;
+}
+
+  void
+GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_advertisingRtr = addr;
+}
+
+  void 
+GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_networkLSANetworkMask = mask;
+}
+
+  Ipv4Mask 
+GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_networkLSANetworkMask;
+}
+
+  GlobalRoutingLSA::SPFStatus
+GlobalRoutingLSA::GetStatus (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_status;
+}
+
+  uint32_t 
+GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_attachedRouters.push_back (addr);
+  return m_attachedRouters.size ();
+}
+
+  uint32_t 
+GlobalRoutingLSA::GetNAttachedRouters (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_attachedRouters.size (); 
+}
+
+  Ipv4Address 
+GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t j = 0;
+  for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
+        i != m_attachedRouters.end (); 
+        i++, j++)
+    {
+      if (j == n) 
+        {
+          return *i;
+        }
+    }
+  NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
+  return Ipv4Address("0.0.0.0");
+}
+
+  void
+GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_status = status;
+}
+
+  Ptr<Node>
+GlobalRoutingLSA::GetNode (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return NodeList::GetNode (m_node_id);
+}
+
+  void
+GlobalRoutingLSA::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (node);
+  m_node_id = node->GetId ();
+}
+
+  void 
+GlobalRoutingLSA::Print (std::ostream &os) const
+{
+  os << std::endl;
+  os << "========== Global Routing LSA ==========" << std::endl;
+  os << "m_lsType = " << m_lsType;
+  if (m_lsType == GlobalRoutingLSA::RouterLSA) 
+    {
+      os << " (GlobalRoutingLSA::RouterLSA)";
+    }
+  else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
+    {
+      os << " (GlobalRoutingLSA::NetworkLSA)";
+    }
+  else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
+    {
+      os << " (GlobalRoutingLSA::ASExternalLSA)";
+    }
+  else
+    {
+      os << "(Unknown LSType)";
+    }
+  os << std::endl;
+
+  os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl;
+  os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl;
+
+  if (m_lsType == GlobalRoutingLSA::RouterLSA) 
+    {
+      for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
+            i != m_linkRecords.end (); 
+            i++)
+        {
+          GlobalRoutingLinkRecord *p = *i;
+
+          os << "---------- RouterLSA Link Record ----------" << std::endl;
+          os << "m_linkType = " << p->m_linkType;
+          if (p->m_linkType == GlobalRoutingLinkRecord::PointToPoint)
+            {
+              os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << std::endl;
+              os << "m_linkData = " << p->m_linkData << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          else if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
+            {
+              os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
+              os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          else if (p->m_linkType == GlobalRoutingLinkRecord::StubNetwork)
+            {
+              os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
+              os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          else
+            {
+              os << " (Unknown LinkType)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << std::endl;
+              os << "m_linkData = " << p->m_linkData << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          os << "---------- End RouterLSA Link Record ----------" << std::endl;
+        }
+    }
+  else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
+    {
+      os << "---------- NetworkLSA Link Record ----------" << std::endl;
+      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
+      for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++)
+        {
+          Ipv4Address p = *i;
+          os << "attachedRouter = " << p << std::endl;
+        }
+      os << "---------- End NetworkLSA Link Record ----------" << std::endl;
+    }
+  else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
+    {
+      os << "---------- ASExternalLSA Link Record --------" << std::endl;
+      os << "m_linkStateId = " << m_linkStateId << std::endl;
+      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
+    }
+  else 
+    {
+      NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
+    }
+  os << "========== End Global Routing LSA ==========" << std::endl;
+}
+
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
+{
+  lsa.Print (os);
+  return os;
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouter Implementation
+//
+// ---------------------------------------------------------------------------
+
+NS_OBJECT_ENSURE_REGISTERED (GlobalRouter);
+
+TypeId 
+GlobalRouter::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::GlobalRouter")
+    .SetParent<Object> ();
+  return tid;
+}
+
+GlobalRouter::GlobalRouter ()
+  : m_LSAs()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_routerId.Set(GlobalRouteManager::AllocateRouterId ());
+}
+
+GlobalRouter::~GlobalRouter ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  ClearLSAs();
+}
+
+void 
+GlobalRouter::SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing)
+{
+  m_routingProtocol = routing;
+}
+Ptr<Ipv4GlobalRouting> 
+GlobalRouter::GetRoutingProtocol (void)
+{
+  return m_routingProtocol;
+}
+
+void
+GlobalRouter::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_routingProtocol = 0;
+  for (InjectedRoutesI k = m_injectedRoutes.begin ();
+         k != m_injectedRoutes.end ();
+         k = m_injectedRoutes.erase (k))
+    {
+      delete (*k);
+    }
+  Object::DoDispose ();
+}
+
+  void
+GlobalRouter::ClearLSAs ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
+        i != m_LSAs.end (); 
+        i++)
+    {
+      NS_LOG_LOGIC ("Free LSA");
+
+      GlobalRoutingLSA *p = *i;
+      delete p;
+      p = 0;
+
+      *i = 0;
+    }
+  NS_LOG_LOGIC ("Clear list of LSAs");
+  m_LSAs.clear();
+}
+
+  Ipv4Address
+GlobalRouter::GetRouterId (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_routerId;
+}
+
+//
+// DiscoverLSAs is called on all nodes in the system that have a GlobalRouter
+// interface aggregated.  We need to go out and discover any adjacent routers 
+// and build the Link State Advertisements that reflect them and their associated
+// networks.
+// 
+uint32_t 
+GlobalRouter::DiscoverLSAs ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<Node> node = GetObject<Node> ();
+  NS_ABORT_MSG_UNLESS (node, "GlobalRouter::DiscoverLSAs (): GetObject for <Node> interface failed");
+  NS_LOG_LOGIC ("For node " << node->GetId () );
+
+  ClearLSAs ();
+
+  //
+  // While building the Router-LSA, keep a list of those NetDevices for
+  // which the current node is the designated router and we will later build 
+  // a NetworkLSA for.
+  //
+  NetDeviceContainer c;
+
+  //
+  // We're aggregated to a node.  We need to ask the node for a pointer to its
+  // Ipv4 interface.  This is where the information regarding the attached 
+  // interfaces lives.  If we're a router, we had better have an Ipv4 interface.
+  //
+  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for <Ipv4> interface failed");
+
+  //
+  // Every router node originates a Router-LSA
+  //
+  GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+  pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
+  pLSA->SetLinkStateId (m_routerId);
+  pLSA->SetAdvertisingRouter (m_routerId);
+  pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+  pLSA->SetNode (node);
+
+  //
+  // Ask the node for the number of net devices attached. This isn't necessarily 
+  // equal to the number of links to adjacent nodes (other routers) as the number
+  // of devices may include those for stub networks (e.g., ethernets, etc.) and 
+  // bridge devices also take up an "extra" net device.
+  //
+  uint32_t numDevices = node->GetNDevices();
+
+  //
+  // Iterate through the devices on the node and walk the channel to see what's
+  // on the other side of the standalone devices..
+  //
+  for (uint32_t i = 0; i < numDevices; ++i)
+    {
+      Ptr<NetDevice> ndLocal = node->GetDevice(i);
+
+      //
+      // There is an assumption that bridge ports must never have an IP address 
+      // associated with them.  This turns out to be a very convenient place to
+      // check and make sure that this is the case.
+      //
+      if (NetDeviceIsBridged (ndLocal))
+        {
+          uint32_t interfaceBridge;
+          bool rc = FindInterfaceForDevice(node, ndLocal, interfaceBridge);
+          NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index");
+        }
+
+      //
+      // Check to see if the net device we just got has a corresponding IP 
+      // interface (could be a pure L2 NetDevice) -- for example a net device
+      // associated with a bridge.  We are only going to involve devices with 
+      // IP addresses in routing.
+      //
+      bool isForwarding = false;
+      for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
+        {
+          if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j) &&
+              ipv4Local->IsForwarding (j)) 
+            {
+              isForwarding = true;
+              break;
+            }
+        }
+
+      if (!isForwarding)
+        {
+          NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface or is not enabled for forwarding, skipping");
+          continue;
+        }
+
+      //
+      // We have a net device that we need to check out.  If it suports 
+      // broadcast and is not a point-point link, then it will be either a stub 
+      // network or a transit network depending on the number of routers on
+      // the segment.  We add the appropriate link record to the LSA.
+      //
+      // If the device is a point to point link, we treat it separately.  In
+      // that case, there may be zero, one, or two link records added.
+      //
+
+      if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
+        {
+          NS_LOG_LOGIC ("Broadcast link");
+          ProcessBroadcastLink (ndLocal, pLSA, c);
+        }
+      else if (ndLocal->IsPointToPoint () )
+        {
+          NS_LOG_LOGIC ("Point=to-point link");
+          ProcessPointToPointLink (ndLocal, pLSA);
+        }
+      else
+        {
+          NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
+        }
+    }
+
+  NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
+  NS_LOG_LOGIC (*pLSA);
+  m_LSAs.push_back (pLSA);
+  pLSA = 0;
+
+  // 
+  // Now, determine whether we need to build a NetworkLSA.  This is the case if
+  // we found at least one designated router.
+  //
+  uint32_t nDesignatedRouters = c.GetN ();
+  if (nDesignatedRouters > 0)
+    {
+      NS_LOG_LOGIC ("Build Network LSAs");
+      BuildNetworkLSAs (c);
+    }
+
+  //
+  // Build injected route LSAs as external routes
+  // RFC 2328, section 12.4.4
+  //
+  for (InjectedRoutesCI i = m_injectedRoutes.begin();
+       i != m_injectedRoutes.end();
+       i++)
+    {
+      GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+      pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs);
+      pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
+      pLSA->SetAdvertisingRouter (m_routerId);
+      pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
+      pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+      m_LSAs.push_back (pLSA); 
+    }
+  return m_LSAs.size ();
+}
+
+  void
+GlobalRouter::ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+  NS_LOG_FUNCTION (nd << pLSA << &c);
+
+  if (nd->IsBridge ())
+    {
+      ProcessBridgedBroadcastLink (nd, pLSA, c);
+    }
+  else
+    {
+      ProcessSingleBroadcastLink (nd, pLSA, c);
+    }
+}
+
+  void
+GlobalRouter::ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+  NS_LOG_FUNCTION (nd << pLSA << &c);
+
+  GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record");
+
+  //
+  // We have some preliminaries to do to get enough information to proceed.
+  // This information we need comes from the internet stack, so notice that
+  // there is an implied assumption that global routing is only going to 
+  // work with devices attached to the internet stack (have an ipv4 interface
+  // associated to them.
+  //
+  Ptr<Node> node = nd->GetNode ();
+
+  uint32_t interfaceLocal;
+  bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
+  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
+
+  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
+
+  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
+  NS_LOG_LOGIC ("Working with local address " << addrLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
+
+  //
+  // Check to see if the net device is connected to a channel/network that has
+  // another router on it.  If there is no other router on the link (but us) then
+  // this is a stub network.  If we find another router, then what we have here
+  // is a transit network.
+  //
+  if (AnotherRouterOnLink (nd, true) == false)
+    {
+      //
+      // This is a net device connected to a stub network
+      //
+      NS_LOG_LOGIC("Router-LSA Stub Network");
+      plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+
+      // 
+      // According to OSPF, the Link ID is the IP network number of 
+      // the attached network.
+      //
+      plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+
+      //
+      // and the Link Data is the network mask; converted to Ipv4Address
+      //
+      Ipv4Address maskLocalAddr;
+      maskLocalAddr.Set(maskLocal.Get ());
+      plr->SetLinkData (maskLocalAddr);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord(plr);
+      plr = 0;
+    }
+  else
+    {
+      //
+      // We have multiple routers on a broadcast interface, so this is
+      // a transit network.
+      //
+      NS_LOG_LOGIC ("Router-LSA Transit Network");
+      plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+
+      // 
+      // By definition, the router with the lowest IP address is the
+      // designated router for the network.  OSPF says that the Link ID
+      // gets the IP interface address of the designated router in this 
+      // case.
+      //
+      Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true);
+
+      //
+      // Let's double-check that any designated router we find out on our
+      // network is really on our network.
+      //
+      if (desigRtr != "255.255.255.255")
+        {
+          Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
+          Ipv4Address networkThere = desigRtr.CombineMask (maskLocal);
+          NS_ABORT_MSG_UNLESS (networkHere == networkThere, 
+                               "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
+        }
+      if (desigRtr == addrLocal) 
+        {
+          c.Add (nd);
+          NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
+        }
+      plr->SetLinkId (desigRtr);
+      
+      //
+      // OSPF says that the Link Data is this router's own IP address.
+      //
+      plr->SetLinkData (addrLocal);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord (plr);
+      plr = 0;
+    }
+}
+
+  void
+GlobalRouter::ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+  NS_LOG_FUNCTION (nd << pLSA << &c);
+  NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
+
+#if 0
+  //
+  // It is possible to admit the possibility that a bridge device on a node
+  // can also participate in routing.  This would surprise people who don't
+  // come from Microsoft-land where they do use such a construct.  Based on
+  // the principle of least-surprise, we will leave the relatively simple
+  // code in place to do this, but not enable it until someone really wants
+  // the capability.  Even then, we will not enable this code as a default
+  // but rather something you will have to go and turn on.
+  //
+
+  Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
+  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
+
+  //
+  // We have some preliminaries to do to get enough information to proceed.
+  // This information we need comes from the internet stack, so notice that
+  // there is an implied assumption that global routing is only going to 
+  // work with devices attached to the internet stack (have an ipv4 interface
+  // associated to them.
+  //
+  Ptr<Node> node = nd->GetNode ();
+
+  uint32_t interfaceLocal;
+  bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
+  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
+
+  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
+
+  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();;
+  NS_LOG_LOGIC ("Working with local address " << addrLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
+
+  //
+  // We need to handle a bridge on the router.  This means that we have been 
+  // given a net device that is a BridgeNetDevice.  It has an associated Ipv4
+  // interface index and address.  Some number of other net devices live "under"
+  // the bridge device as so-called bridge ports.  In a nutshell, what we have
+  // to do is to repeat what is done for a single broadcast link on all of 
+  // those net devices living under the bridge (trolls?)
+  //
+
+  bool areTransitNetwork = false;
+  Ipv4Address desigRtr ("255.255.255.255");
+
+  for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
+    {
+      Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
+
+      //
+      // We have to decide if we are a transit network.  This is characterized
+      // by the presence of another router on the network segment.  If we find
+      // another router on any of our bridged links, we are a transit network.
+      //
+      if (AnotherRouterOnLink (ndTemp, true))
+        {
+          areTransitNetwork = true;
+
+          //
+          // If we're going to be a transit network, then we have got to elect
+          // a designated router for the whole bridge.  This means finding the
+          // router with the lowest IP address on the whole bridge.  We ask 
+          // for the lowest address on each segment and pick the lowest of them
+          // all.
+          //
+          Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true);
+
+          //
+          // Let's double-check that any designated router we find out on our
+          // network is really on our network.
+          //
+          if (desigRtrTemp != "255.255.255.255")
+            {
+              Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
+              Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal);
+              NS_ABORT_MSG_UNLESS (networkHere == networkThere, 
+                                   "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
+            }
+          if (desigRtrTemp < desigRtr)
+            {
+              desigRtr = desigRtrTemp;
+            }
+        }
+    }
+  //
+  // That's all the information we need to put it all together, just like we did
+  // in the case of a single broadcast link.
+  //
+
+  GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
+
+  if (areTransitNetwork == false)
+    {
+      //
+      // This is a net device connected to a bridge of stub networks
+      //
+      NS_LOG_LOGIC("Router-LSA Stub Network");
+      plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+
+      // 
+      // According to OSPF, the Link ID is the IP network number of 
+      // the attached network.
+      //
+      plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+
+      //
+      // and the Link Data is the network mask; converted to Ipv4Address
+      //
+      Ipv4Address maskLocalAddr;
+      maskLocalAddr.Set(maskLocal.Get ());
+      plr->SetLinkData (maskLocalAddr);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord(plr);
+      plr = 0;
+    }
+  else
+    {
+      //
+      // We have multiple routers on a bridged broadcast interface, so this is
+      // a transit network.
+      //
+      NS_LOG_LOGIC ("Router-LSA Transit Network");
+      plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+
+      // 
+      // By definition, the router with the lowest IP address is the
+      // designated router for the network.  OSPF says that the Link ID
+      // gets the IP interface address of the designated router in this 
+      // case.
+      //
+      if (desigRtr == addrLocal) 
+        {
+          c.Add (nd);
+          NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
+        }
+      plr->SetLinkId (desigRtr);
+      
+      //
+      // OSPF says that the Link Data is this router's own IP address.
+      //
+      plr->SetLinkData (addrLocal);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord (plr);
+      plr = 0;
+    }
+#endif
+}
+
+  void
+GlobalRouter::ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA)
+{
+  NS_LOG_FUNCTION (ndLocal << pLSA);
+
+  //
+  // We have some preliminaries to do to get enough information to proceed.
+  // This information we need comes from the internet stack, so notice that
+  // there is an implied assumption that global routing is only going to 
+  // work with devices attached to the internet stack (have an ipv4 interface
+  // associated to them.
+  //
+  Ptr<Node> nodeLocal = ndLocal->GetNode ();
+
+  uint32_t interfaceLocal;
+  bool rc = FindInterfaceForDevice(nodeLocal, ndLocal, interfaceLocal);
+  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
+
+  Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
+  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
+
+  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
+  NS_LOG_LOGIC ("Working with local address " << addrLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
+
+  //
+  // Now, we're going to walk over to the remote net device on the other end of 
+  // the point-to-point channel we know we have.  This is where our adjacent 
+  // router (to use OSPF lingo) is running.  
+  //
+  Ptr<Channel> ch = ndLocal->GetChannel();
+
+  //
+  // Get the net device on the other side of the point-to-point channel.
+  //
+  Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
+
+  //
+  // The adjacent net device is aggregated to a node.  We need to ask that net 
+  // device for its node, then ask that node for its Ipv4 interface.  Note a
+  // requirement that nodes on either side of a point-to-point link must have 
+  // internet stacks; and an assumption that point-to-point links are incompatible 
+  // with bridging.
+  //
+  Ptr<Node> nodeRemote = ndRemote->GetNode();
+  Ptr<Ipv4> ipv4Remote = nodeRemote->GetObject<Ipv4> ();
+  NS_ABORT_MSG_UNLESS (ipv4Remote, 
+                       "GlobalRouter::ProcessPointToPointLink(): GetObject for remote <Ipv4> failed");
+
+  //
+  // Further note the requirement that nodes on either side of a point-to-point 
+  // link must participate in global routing and therefore have a GlobalRouter
+  // interface aggregated.
+  //
+  Ptr<GlobalRouter> rtrRemote = nodeRemote->GetObject<GlobalRouter> ();
+  if (rtrRemote == 0)
+    {
+      // This case is possible if the remote does not participate in global routing
+      return;
+    }
+  //
+  // We're going to need the remote router ID, so we might as well get it now.
+  //
+  Ipv4Address rtrIdRemote = rtrRemote->GetRouterId();
+  NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote);
+
+  //
+  // Now, just like we did above, we need to get the IP interface index for the 
+  // net device on the other end of the point-to-point channel.
+  //
+  uint32_t interfaceRemote;
+  rc = FindInterfaceForDevice(nodeRemote, ndRemote, interfaceRemote);
+  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
+
+  //
+  // Now that we have the Ipv4 interface, we can get the (remote) address and
+  // mask we need.
+  //
+  if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
+  Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
+  NS_LOG_LOGIC ("Working with remote address " << addrRemote);
+
+  //
+  // Now we can fill out the link records for this link.  There are always two
+  // link records; the first is a point-to-point record describing the link and
+  // the second is a stub network record with the network number.
+  //
+  GlobalRoutingLinkRecord *plr;
+  if (ipv4Remote->IsUp (interfaceRemote))
+    {
+      NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
+ 
+      plr  = new GlobalRoutingLinkRecord;
+      NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
+      plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
+      plr->SetLinkId (rtrIdRemote);
+      plr->SetLinkData (addrLocal);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord (plr);
+      plr = 0;
+    }
+
+  // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
+  plr = new GlobalRoutingLinkRecord;
+  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
+  plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+  plr->SetLinkId (addrRemote);
+  plr->SetLinkData (Ipv4Address(maskRemote.Get()));  // Frown
+  plr->SetMetric (metricLocal);
+  pLSA->AddLinkRecord (plr);
+  plr = 0;
+}
+
+  void
+GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c)
+{
+  NS_LOG_FUNCTION (&c);
+
+  uint32_t nDesignatedRouters = c.GetN ();
+      
+  for (uint32_t i = 0; i < nDesignatedRouters; ++i)
+    {
+      //
+      // Build one NetworkLSA for each net device talking to a network that we are the 
+      // designated router for.  These devices are in the provided container.
+      //
+      Ptr<NetDevice> ndLocal = c.Get (i);
+      Ptr<Node> node = ndLocal->GetNode ();
+
+      uint32_t interfaceLocal;
+      bool rc = FindInterfaceForDevice(node, ndLocal, interfaceLocal);
+      NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
+
+      Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+      NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
+
+      if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+        {
+          NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+        }
+      Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+      Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
+
+      GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+      NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
+
+      pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
+      pLSA->SetLinkStateId (addrLocal);
+      pLSA->SetAdvertisingRouter (m_routerId);
+      pLSA->SetNetworkLSANetworkMask (maskLocal);
+      pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+      pLSA->SetNode (node);
+
+      //
+      // Build a list of AttachedRouters by walking the devices in the channel
+      // and, if we find a node with a GlobalRouter interface and an IPv4 
+      // interface associated with that device, we call it an attached router.  
+      //
+      Ptr<Channel> ch = ndLocal->GetChannel();
+      uint32_t nDevices = ch->GetNDevices();
+      NS_ASSERT (nDevices);
+      
+      for (uint32_t i = 0; i < nDevices; i++)
+        {
+          Ptr<NetDevice> tempNd = ch->GetDevice (i);
+          NS_ASSERT (tempNd);
+          Ptr<Node> tempNode = tempNd->GetNode ();
+
+          //
+          // Does the node in question have a GlobalRouter interface?  If not it can
+          // hardly be considered an attached router.
+          //
+          Ptr<GlobalRouter> rtr = tempNode->GetObject<GlobalRouter> ();
+          if (rtr == 0)
+            { 
+              continue;
+            }
+
+          //
+          // Does the attached node have an ipv4 interface for the device we're probing?
+          // If not, it can't play router.
+          //
+          uint32_t tempInterface;
+          if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
+            {
+              Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
+              NS_ASSERT (tempIpv4);
+              if (!tempIpv4->IsUp (tempInterface))
+                {
+                  NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
+                }
+              else 
+                {
+                  if (tempIpv4->GetNAddresses (tempInterface) > 1)
+                    {
+                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+                    }
+                  Ipv4Address tempAddr = tempIpv4->GetAddress(tempInterface, 0).GetLocal ();
+                  pLSA->AddAttachedRouter (tempAddr);
+                }
+            }
+        }
+      m_LSAs.push_back (pLSA);
+      pLSA = 0;
+    }
+}
+
+//
+// Given a local net device, we need to walk the channel to which the net device is
+// attached and look for nodes with GlobalRouter interfaces on them (one of them 
+// will be us).  Of these, the router with the lowest IP address on the net device 
+// connecting to the channel becomes the designated router for the link.
+//
+  Ipv4Address
+GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const
+{
+  NS_LOG_FUNCTION (ndLocal << allowRecursion);
+
+  Ptr<Channel> ch = ndLocal->GetChannel();
+  uint32_t nDevices = ch->GetNDevices();
+  NS_ASSERT (nDevices);
+
+  NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " << 
+                ndLocal->GetNode ()->GetId ());
+
+  Ipv4Address desigRtr ("255.255.255.255");
+
+  //
+  // Look through all of the devices on the channel to which the net device
+  // in question is attached.
+  //
+  for (uint32_t i = 0; i < nDevices; i++)
+    {
+      Ptr<NetDevice> ndOther = ch->GetDevice (i);
+      NS_ASSERT (ndOther);
+
+      Ptr<Node> nodeOther = ndOther->GetNode ();
+
+      NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ());
+
+      //
+      // For all other net devices, we need to check and see if a router
+      // is present.  If the net device on the other side is a bridged
+      // device, we need to consider all of the other devices on the 
+      // bridge as well (all of the bridge ports.
+      //
+      NS_LOG_LOGIC ("checking to see if the device is bridged");
+      Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
+      if (bnd)
+        {
+          NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd);
+
+          //
+          // It is possible that the bridge net device is sitting under a
+          // router, so we have to check for the presence of that router
+          // before we run off and follow all the links
+          //
+          // We require a designated router to have a GlobalRouter interface and
+          // an internet stack that includes the Ipv4 interface.  If it doesn't
+          // it can't play router.
+          //
+          NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd);
+          Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
+          Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
+          if (rtr && ipv4)
+            {
+              uint32_t interfaceOther;
+              if (FindInterfaceForDevice(nodeOther, bnd, interfaceOther))
+                {
+                  NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
+                  if (!ipv4->IsUp (interfaceOther))
+                    {
+                      NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
+                      continue;
+                    }
+                  if (ipv4->GetNAddresses (interfaceOther) > 1)
+                    {
+                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+                    }
+                  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
+                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+                  NS_LOG_LOGIC ("designated router now " << desigRtr);
+                }
+            }
+
+          NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
+          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+            {
+              Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
+              NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
+              if (ndBridged == ndOther)
+                {
+                  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
+                  continue;
+                }
+
+              if (allowRecursion)
+                {
+                  NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged);
+                  Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false);
+                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+                  NS_LOG_LOGIC ("designated router now " << desigRtr);
+                }
+            }
+        }
+      else
+        {
+          NS_LOG_LOGIC ("This device is not bridged");
+          Ptr<Node> nodeOther = ndOther->GetNode ();
+          NS_ASSERT (nodeOther);
+
+          //
+          // We require a designated router to have a GlobalRouter interface and
+          // an internet stack that includes the Ipv4 interface.  If it doesn't
+          //
+          Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
+          Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
+          if (rtr && ipv4)
+            {
+              uint32_t interfaceOther;
+              if (FindInterfaceForDevice(nodeOther, ndOther, interfaceOther))
+                {
+                  if (!ipv4->IsUp (interfaceOther))
+                    {
+                      NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
+                      continue;
+                    }
+                  NS_LOG_LOGIC ("Found router on net device " << ndOther);
+                  if (ipv4->GetNAddresses (interfaceOther) > 1)
+                    {
+                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+                    }
+                  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
+                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+                  NS_LOG_LOGIC ("designated router now " << desigRtr);
+                }
+            }
+        }
+    }
+  return desigRtr;
+}
+
+//
+// Given a node and an attached net device, take a look off in the channel to 
+// which the net device is attached and look for a node on the other side
+// that has a GlobalRouter interface aggregated.  Life gets more complicated
+// when there is a bridged net device on the other side.
+//
+  bool
+GlobalRouter::AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const
+{
+  NS_LOG_FUNCTION (nd << allowRecursion);
+
+  Ptr<Channel> ch = nd->GetChannel();
+  if (!ch)
+    {
+      // It may be that this net device is a stub device, without a channel
+      return false;
+    }
+  uint32_t nDevices = ch->GetNDevices();
+  NS_ASSERT (nDevices);
+
+  NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
+
+  //
+  // Look through all of the devices on the channel to which the net device
+  // in question is attached.
+  //
+  for (uint32_t i = 0; i < nDevices; i++)
+    {
+      Ptr<NetDevice> ndOther = ch->GetDevice (i);
+      NS_ASSERT (ndOther);
+
+      NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
+
+      // 
+      // Ignore the net device itself.
+      //
+      if (ndOther == nd)
+        {
+          NS_LOG_LOGIC ("Myself, skip");
+          continue;
+        }
+
+      //
+      // For all other net devices, we need to check and see if a router
+      // is present.  If the net device on the other side is a bridged
+      // device, we need to consider all of the other devices on the 
+      // bridge.
+      //
+      NS_LOG_LOGIC ("checking to see if device is bridged");
+      Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
+      if (bnd)
+        {
+          NS_LOG_LOGIC ("Device is bridged by net device " << bnd);
+          NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
+          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+            {
+              Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
+              NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
+              if (ndBridged == ndOther)
+                {
+                  NS_LOG_LOGIC ("That bridge port is me, skip");
+                  continue;
+                }
+
+              if (allowRecursion)
+                {
+                  NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged);
+                  if (AnotherRouterOnLink (ndBridged, false))
+                    {
+                      NS_LOG_LOGIC ("Found routers on bridge port, return true");
+                      return true;
+                    }
+                }
+            }
+          NS_LOG_LOGIC ("No routers on bridged net device, return false");
+          return false;
+        }
+
+      NS_LOG_LOGIC ("This device is not bridged");
+      Ptr<Node> nodeTemp = ndOther->GetNode ();
+      NS_ASSERT (nodeTemp);
+
+      Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
+      if (rtr)
+        {
+          NS_LOG_LOGIC ("Found GlobalRouter interface, return true");
+          return true;
+        }
+      else 
+        {
+          NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search");
+        }
+    }
+  NS_LOG_LOGIC ("No routers found, return false");
+  return false;
+}
+
+  uint32_t 
+GlobalRouter::GetNumLSAs (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_LSAs.size ();
+}
+
+//
+// Get the nth link state advertisement from this router.
+//
+  bool
+GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
+//
+// All of the work was done in GetNumLSAs.  All we have to do here is to
+// walk the list of link state advertisements created there and return the 
+// one the client is interested in.
+//
+  ListOfLSAs_t::const_iterator i = m_LSAs.begin ();
+  uint32_t j = 0;
+
+  for (; i != m_LSAs.end (); i++, j++)
+    {
+      if (j == n)
+        {
+          GlobalRoutingLSA *p = *i;
+          lsa = *p;
+          return true;
+        }
+    }
+
+  return false;
+}
+
+void
+GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
+{
+  NS_LOG_FUNCTION (network << networkMask);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+//
+// Interface number does not matter here, using 1.
+//
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+      networkMask,
+      1);
+  m_injectedRoutes.push_back (route);
+}
+
+Ipv4RoutingTableEntry *
+GlobalRouter::GetInjectedRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (index);
+  if (index < m_injectedRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (InjectedRoutesCI i = m_injectedRoutes.begin ();
+           i != m_injectedRoutes.end ();
+           i++)
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          tmp++;
+        }
+     }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+
+uint32_t
+GlobalRouter::GetNInjectedRoutes ()
+{
+  return m_injectedRoutes.size ();
+}
+
+void
+GlobalRouter::RemoveInjectedRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (index);
+  NS_ASSERT (index < m_injectedRoutes.size ());
+  uint32_t tmp = 0;
+  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
+    {
+      if (tmp  == index)
+        {
+          NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size());
+          delete *i;
+          m_injectedRoutes.erase (i);
+          return;
+        }
+      tmp++;
+    }
+}
+
+bool
+GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
+{
+  NS_LOG_FUNCTION (network << networkMask);
+  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
+    {
+      if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
+        {
+          NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
+          delete *i;
+          m_injectedRoutes.erase (i);
+          return true;
+        }
+    }
+  return false;
+}
+
+
+//
+// Link through the given channel and find the net device that's on the
+// other end.  This only makes sense with a point-to-point channel.
+//
+  Ptr<NetDevice>
+GlobalRouter::GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT_MSG(ch->GetNDevices() == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices");
+//
+// This is a point to point channel with two endpoints.  Get both of them.
+//
+  Ptr<NetDevice> nd1 = ch->GetDevice(0);
+  Ptr<NetDevice> nd2 = ch->GetDevice(1);
+//
+// One of the endpoints is going to be "us" -- that is the net device attached
+// to the node on which we're running -- i.e., "nd".  The other endpoint (the
+// one to which we are connected via the channel) is the adjacent router.
+//
+  if (nd1 == nd)
+    {
+      return nd2;
+    }
+  else if (nd2 == nd)
+    {
+      return nd1;
+    }
+  else
+    {
+      NS_ASSERT_MSG(false,
+        "GlobalRouter::GetAdjacent (): Wrong or confused channel?");
+      return 0;
+    }
+}
+
+//
+// Given a node and a net device, find an IPV4 interface index that corresponds
+// to that net device.  This function may fail for various reasons.  If a node
+// does not have an internet stack (for example if it is a bridge) we won't have
+// an IPv4 at all.  If the node does have a stack, but the net device in question
+// is bridged, there will not be an interface associated directly with the device.
+//
+  bool
+GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd );
+
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  if (ipv4 == 0)
+    {
+      NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ());
+      return false;
+    }
+
+  for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i )
+    {
+      if (ipv4->GetNetDevice(i) == nd) 
+        {
+          NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i);
+          index = i;
+          return true;
+        }
+    }
+
+  NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index");
+  return false;
+}
+
+//
+// Decide whether or not a given net device is being bridged by a BridgeNetDevice.
+//
+  Ptr<BridgeNetDevice>
+GlobalRouter::NetDeviceIsBridged (Ptr<NetDevice> nd) const
+{
+  NS_LOG_FUNCTION (nd);
+
+  Ptr<Node> node = nd->GetNode ();
+  uint32_t nDevices = node->GetNDevices();
+
+  //
+  // There is no bit on a net device that says it is being bridged, so we have
+  // to look for bridges on the node to which the device is attached.  If we
+  // find a bridge, we need to look through its bridge ports (the devices it
+  // bridges) to see if we find the device in question.
+  //
+  for (uint32_t i = 0; i < nDevices; ++i)
+    {
+      Ptr<NetDevice> ndTest = node->GetDevice(i);
+      NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
+
+      if (ndTest->IsBridge ())
+        {
+          NS_LOG_LOGIC ("device " << i << " is a bridge net device");
+          Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
+          NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
+
+          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+            {
+              NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
+              if (bnd->GetBridgePort (j) == nd)
+                {
+                  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
+                  return bnd;
+                }
+            }
+        }
+    }
+  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
+  return 0;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-router-interface.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,754 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * 
+ * 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:  Craig Dowell (craigdo@ee.washington.edu)
+ *           Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#ifndef GLOBAL_ROUTER_INTERFACE_H
+#define GLOBAL_ROUTER_INTERFACE_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/node.h"
+#include "ns3/channel.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/net-device-container.h"
+#include "ns3/bridge-net-device.h"
+#include "ns3/global-route-manager.h"
+#include "ns3/ipv4-routing-table-entry.h"
+
+namespace ns3 {
+
+class GlobalRouter;
+class Ipv4GlobalRouting;
+
+/**
+ * @brief A single link record for a link state advertisement.
+ *
+ * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
+ * a Link State Advertisement.  Right now we will only see two types of link
+ * records corresponding to a stub network and a point-to-point link (channel).
+ */
+class GlobalRoutingLinkRecord
+{
+public:
+  friend class GlobalRoutingLSA;
+/**
+ * @enum LinkType
+ * @brief Enumeration of the possible types of Global Routing Link Records.
+ *
+ * These values are defined in the OSPF spec.  We currently only use 
+ * PointToPoint and StubNetwork types.
+ */
+  enum LinkType {
+    Unknown = 0,        /**< Uninitialized Link Record */
+    PointToPoint,       /**< Record representing a point to point channel */
+    TransitNetwork,     /**< Unused -- for future OSPF compatibility  */
+    StubNetwork,        /**< Record represents a leaf node network */
+    VirtualLink         /**< Unused -- for future OSPF compatibility  */
+  };
+
+/**
+ * @brief Construct an empty ("uninitialized") Global Routing Link Record.
+ *
+ * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
+ * The Link Type is set to Unknown;
+ * The metric is set to 0.
+ */
+  GlobalRoutingLinkRecord ();
+
+/**
+ * Construct an initialized Global Routing Link Record.
+ *
+ * @param linkType The type of link record to construct.
+ * @param linkId The link ID for the record.
+ * @param linkData The link data field for the record.
+ * @param metric The metric field for the record.
+ * @see LinkType
+ * @see SetLinkId
+ * @see SetLinkData
+ */
+  GlobalRoutingLinkRecord (
+    LinkType    linkType, 
+    Ipv4Address linkId, 
+    Ipv4Address linkData, 
+    uint16_t    metric);
+
+/**
+ * @brief Destroy a Global Routing Link Record.
+ *
+ * Currently does nothing.  Here as a placeholder only.
+ */
+  ~GlobalRoutingLinkRecord ();
+
+/**
+ * Get the Link ID field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
+ * of the neighboring router.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent
+ * neighbor's IP address
+ *
+ * @returns The Ipv4Address corresponding to the Link ID field of the record.
+ */
+  Ipv4Address GetLinkId(void) const;
+
+/**
+ * @brief Set the Link ID field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
+ * of the neighboring router.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent
+ * neighbor's IP address
+ *
+ * @param addr An Ipv4Address to store in the Link ID field of the record.
+ */
+  void SetLinkId(Ipv4Address addr);
+
+/**
+ * @brief Get the Link Data field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
+ * address of the node of the local side of the link.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link Data will be the
+ * network mask
+ *
+ * @returns The Ipv4Address corresponding to the Link Data field of the record.
+ */
+  Ipv4Address GetLinkData(void) const;
+
+/**
+ * @brief Set the Link Data field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
+ * address of the node of the local side of the link.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the
+ * network mask
+ *
+ * @param addr An Ipv4Address to store in the Link Data field of the record.
+ */
+  void SetLinkData(Ipv4Address addr);
+
+/**
+ * @brief Get the Link Type field of the Global Routing Link Record.
+ *
+ * The Link Type describes the kind of link a given record represents.  The
+ * values are defined by OSPF.
+ *
+ * @see LinkType
+ * @returns The LinkType of the current Global Routing Link Record.
+ */
+  LinkType GetLinkType(void) const;
+
+/**
+ * @brief Set the Link Type field of the Global Routing Link Record.
+ *
+ * The Link Type describes the kind of link a given record represents.  The
+ * values are defined by OSPF.
+ *
+ * @see LinkType
+ * @param linkType The new LinkType for the current Global Routing Link Record.
+ */
+  void SetLinkType(LinkType linkType);
+
+/**
+ * @brief Get the Metric Data field of the Global Routing Link Record.
+ *
+ * The metric is an abstract cost associated with forwarding a packet across
+ * a link.  A sum of metrics must have a well-defined meaning.  That is, you
+ * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
+ * two hops relate to the cost of sending a packet); rather you should use
+ * something like delay.
+ *
+ * @returns The metric field of the Global Routing Link Record.
+ */
+  uint16_t GetMetric(void) const;
+
+/**
+ * @brief Set the Metric Data field of the Global Routing Link Record.
+ *
+ * The metric is an abstract cost associated with forwarding a packet across
+ * a link.  A sum of metrics must have a well-defined meaning.  That is, you
+ * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
+ * two hops relate to the cost of sending a packet); rather you should use
+ * something like delay.
+ *
+ * @param metric The new metric for the current Global Routing Link Record.
+ */
+  void SetMetric(uint16_t metric);
+
+private:
+/**
+ * m_linkId and m_linkData are defined by OSPF to have different meanings 
+ * depending on the type of link a given link records represents.  They work
+ * together.
+ *
+ * For Type 1 link (PointToPoint), set m_linkId to Router ID of 
+ * neighboring router.
+ *
+ * For Type 3 link (Stub), set m_linkId to neighbor's IP address
+ */
+  Ipv4Address m_linkId;         
+
+/**
+ * m_linkId and m_linkData are defined by OSPF to have different meanings 
+ * depending on the type of link a given link records represents.  They work
+ * together.
+ *
+ * For Type 1 link (PointToPoint), set m_linkData to local IP address  
+ *
+ * For Type 3 link (Stub), set m_linkData to mask
+ */
+  Ipv4Address m_linkData;    // for links to RouterLSA, 
+
+/**
+ * The type of the Global Routing Link Record.  Defined in the OSPF spec.  
+ * We currently only use PointToPoint and StubNetwork types.
+ */
+  LinkType m_linkType;
+
+/**
+ * The metric for a given link.
+ *
+ * A metric is abstract cost associated with forwarding a packet across a 
+ * link.  A sum of metrics must have a well-defined meaning.  That is, you 
+ * shouldn't use bandwidth as a metric (how does the sum of the bandwidth 
+ * of two hops relate to the cost of sending a packet); rather you should
+ * use something like delay.
+ */
+  uint16_t m_metric;  
+};
+
+/**  
+ * @brief a Link State Advertisement (LSA) for a router, used in global 
+ * routing.
+ * 
+ * Roughly equivalent to a global incarnation of the OSPF link state header
+ * combined with a list of Link Records.  Since it's global, there's
+ * no need for age or sequence number.  See RFC 2328, Appendix A.
+ */
+class GlobalRoutingLSA
+{
+public:
+/**
+ * @enum LSType
+ * @brief corresponds to LS type field of RFC 2328 OSPF LSA header
+ */
+  enum LSType {
+    Unknown = 0,        /**< Uninitialized Type */
+    RouterLSA,
+    NetworkLSA,
+    SummaryLSA,
+    SummaryLSA_ASBR,
+    ASExternalLSAs
+  };
+/**
+ * @enum SPFStatus
+ * @brief Enumeration of the possible values of the status flag in the Routing 
+ * Link State Advertisements.
+ */
+  enum SPFStatus {
+    LSA_SPF_NOT_EXPLORED = 0,	/**< New vertex not yet considered */
+    LSA_SPF_CANDIDATE,		/**< Vertex is in the SPF candidate queue */
+    LSA_SPF_IN_SPFTREE		/**< Vertex is in the SPF tree */
+  };
+/**
+ * @brief Create a blank Global Routing Link State Advertisement.  
+ *
+ * On completion Ipv4Address variables initialized to 0.0.0.0 and the 
+ * list of Link State Records is empty.
+ */
+  GlobalRoutingLSA();
+
+/**
+ * @brief Create an initialized Global Routing Link State Advertisement.  
+ *
+ * On completion the list of Link State Records is empty.
+ *
+ * @param status The status to of the new LSA.
+ * @param linkStateId The Ipv4Address for the link state ID field.
+ * @param advertisingRtr The Ipv4Address for the advertising router field.
+ */
+  GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId, 
+    Ipv4Address advertisingRtr);
+
+/**
+ * @brief Copy constructor for a Global Routing Link State Advertisement.
+ *
+ * Takes a piece of memory and constructs a semantically identical copy of
+ * the given LSA.
+ *
+ * @param lsa The existing LSA to be used as the source.
+ */
+  GlobalRoutingLSA (GlobalRoutingLSA& lsa);
+
+/**
+ * @brief Destroy an existing Global Routing Link State Advertisement.
+ *
+ * Any Global Routing Link Records present in the list are freed.
+ */
+  ~GlobalRoutingLSA();
+
+/**
+ * @brief Assignment operator for a Global Routing Link State Advertisement.
+ *
+ * Takes an existing Global Routing Link State Advertisement and overwrites
+ * it to make a semantically identical copy of a given prototype LSA.
+ *
+ * If there are any Global Routing Link Records present in the existing 
+ * LSA, they are freed before the assignment happens.
+ *
+ * @param lsa The existing LSA to be used as the source.
+ * @returns Reference to the overwritten LSA.
+ */
+  GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
+
+/**
+ * @brief Copy any Global Routing Link Records in a given Global Routing Link
+ * State Advertisement to the current LSA.  
+ * 
+ * Existing Link Records are not deleted -- this is a concatenation of Link 
+ * Records.
+ *
+ * @see ClearLinkRecords ()
+ * @param lsa The LSA to copy the Link Records from.
+ */
+  void CopyLinkRecords (const GlobalRoutingLSA& lsa);
+
+/**
+ * @brief Add a given Global Routing Link Record to the LSA.
+ *
+ * @param lr The Global Routing Link Record to be added.
+ * @returns The number of link records in the list.
+ */
+  uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
+
+/**
+ * @brief Return the number of Global Routing Link Records in the LSA.
+ *
+ * @returns The number of link records in the list.
+ */
+  uint32_t GetNLinkRecords (void) const;
+
+/**
+ * @brief Return a pointer to the specified Global Routing Link Record.
+ *
+ * @param n The LSA number desired.
+ * @returns The number of link records in the list.
+ */
+  GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
+
+/**
+ * @brief Release all of the Global Routing Link Records present in the Global
+ * Routing Link State Advertisement and make the list of link records empty.
+ */
+  void ClearLinkRecords(void);
+
+/**
+ * @brief Check to see if the list of Global Routing Link Records present in the
+ * Global Routing Link State Advertisement is empty.
+ *
+ * @returns True if the list is empty, false otherwise.
+ */
+  bool IsEmpty(void) const;
+
+/**
+ * @brief Print the contents of the Global Routing Link State Advertisement and
+ * any Global Routing Link Records present in the list.  Quite verbose.
+ */
+  void Print (std::ostream &os) const;
+
+/**
+ * @brief Return the LSType field of the LSA 
+ */
+  LSType GetLSType (void) const;
+/**
+ * @brief Set the LS type field of the LSA
+ */
+  void SetLSType (LSType typ);
+
+/**
+ * @brief Get the Link State ID as defined by the OSPF spec.  We always set it
+ * to the router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ * @returns The Ipv4Address stored as the link state ID.
+ */
+  Ipv4Address GetLinkStateId (void) const;
+
+/**
+ * @brief Set the Link State ID is defined by the OSPF spec.  We always set it
+ * to the router ID of the router making the advertisement.
+ * @param addr IPv4 address which will act as ID
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+  void SetLinkStateId (Ipv4Address addr);
+
+/**
+ * @brief Get the Advertising Router as defined by the OSPF spec.  We always
+ * set it to the router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ * @returns The Ipv4Address stored as the advertising router.
+ */
+  Ipv4Address GetAdvertisingRouter (void) const;
+
+/**
+ * @brief Set the Advertising Router as defined by the OSPF spec.  We always
+ * set it to the router ID of the router making the advertisement.
+ *
+ * @param rtr ID of the router making advertisement
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+  void SetAdvertisingRouter (Ipv4Address  rtr);
+
+/**
+ * @brief For a Network LSA, set the Network Mask field that precedes
+ * the list of attached routers.
+ */
+  void SetNetworkLSANetworkMask (Ipv4Mask mask);
+
+/**
+ * @brief For a Network LSA, get the Network Mask field that precedes
+ * the list of attached routers.
+ * 
+ * @returns the NetworkLSANetworkMask 
+ */
+  Ipv4Mask GetNetworkLSANetworkMask (void) const;
+
+/**
+ * @brief Add an attached router to the list in the NetworkLSA
+ *
+ * @param addr The Ipv4Address of the interface on the network link
+ * @returns The number of addresses in the list.
+ */
+  uint32_t AddAttachedRouter (Ipv4Address addr);
+
+/**
+ * @brief Return the number of attached routers listed in the NetworkLSA
+ *
+ * @returns The number of attached routers.
+ */
+  uint32_t GetNAttachedRouters (void) const;
+
+/**
+ * @brief Return an Ipv4Address corresponding to the specified attached router
+ *
+ * @param n The attached router number desired (number in the list).
+ * @returns The Ipv4Address of the requested router
+ */
+  Ipv4Address GetAttachedRouter (uint32_t n) const;
+
+/**
+ * @brief Get the SPF status of the advertisement.
+ *
+ * @see SPFStatus
+ * @returns The SPFStatus of the LSA.
+ */
+  SPFStatus GetStatus (void) const;
+
+/**
+ * @brief Set the SPF status of the advertisement
+ * @param status SPF status to set
+ * @see SPFStatus
+ */
+  void SetStatus (SPFStatus status);
+
+/**
+ * @brief Get the Node pointer of the node that originated this LSA
+ * @returns Node pointer
+ */
+  Ptr<Node> GetNode (void) const;
+
+/**
+ * @brief Set the Node pointer of the node that originated this LSA
+ * @param node Node pointer
+ */
+  void SetNode (Ptr<Node> node);
+
+private:
+/**
+ * The type of the LSA.  Each LSA type has a separate advertisement
+ * format.
+ */
+  LSType m_lsType;
+/**
+ * The Link State ID is defined by the OSPF spec.  We always set it to the
+ * router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+  Ipv4Address  m_linkStateId;
+
+/**
+ * The Advertising Router is defined by the OSPF spec.  We always set it to 
+ * the router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+  Ipv4Address  m_advertisingRtr;
+
+/**
+ * A convenience typedef to avoid too much writers cramp.
+ */
+  typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
+
+/**
+ * Each Link State Advertisement contains a number of Link Records that
+ * describe the kinds of links that are attached to a given node.  We 
+ * consider PointToPoint and StubNetwork links.
+ *
+ * m_linkRecords is an STL list container to hold the Link Records that have
+ * been discovered and prepared for the advertisement.
+ *
+ * @see GlobalRouting::DiscoverLSAs ()
+ */
+  ListOfLinkRecords_t m_linkRecords;
+
+/**
+ * Each Network LSA contains the network mask of the attached network
+ */
+  Ipv4Mask m_networkLSANetworkMask;
+
+/**
+ * A convenience typedef to avoid too much writers cramp.
+ */
+  typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
+
+/**
+ * Each Network LSA contains a list of attached routers
+ *
+ * m_attachedRouters is an STL list container to hold the addresses that have
+ * been discovered and prepared for the advertisement.
+ *
+ * @see GlobalRouting::DiscoverLSAs ()
+ */
+  ListOfAttachedRouters_t m_attachedRouters;
+
+/**
+ * This is a tristate flag used internally in the SPF computation to mark
+ * if an SPFVertex (a data structure representing a vertex in the SPF tree
+ * -- a router) is new, is a candidate for a shortest path, or is in its
+ * proper position in the tree.
+ */
+  SPFStatus m_status;
+  uint32_t m_node_id;
+};
+
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
+
+/**
+ * @brief An interface aggregated to a node to provide global routing info
+ *
+ * An interface aggregated to a node that provides global routing information
+ * to a global route manager.  The presence of the interface indicates that
+ * the node is a router.  The interface is the mechanism by which the router
+ * advertises its connections to neighboring routers.  We're basically 
+ * allowing the route manager to query for link state advertisements.
+ */
+class GlobalRouter : public Object
+{
+public:
+/**
+ * @brief The Interface ID of the Global Router interface.
+ *
+ * @see Object::GetObject ()
+ */
+  static TypeId GetTypeId (void);
+
+/**
+ * @brief Create a Global Router class 
+ */
+  GlobalRouter ();
+
+
+  void SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing);
+  Ptr<Ipv4GlobalRouting> GetRoutingProtocol (void);
+
+/**
+ * @brief Get the Router ID associated with this Global Router.
+ *
+ * The Router IDs are allocated in the RoutingEnvironment -- one per Router, 
+ * starting at 0.0.0.1 and incrementing with each instantiation of a router.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @returns The Router ID associated with the Global Router.
+ */
+  Ipv4Address GetRouterId (void) const;
+
+/**
+ * @brief Walk the connected channels, discover the adjacent routers and build
+ * the associated number of Global Routing Link State Advertisements that 
+ * this router can export.
+ *
+ * This is a fairly expensive operation in that every time it is called
+ * the current list of LSAs is built by walking connected point-to-point
+ * channels and peeking into adjacent IPV4 stacks to get address information.
+ * This is done to allow for limited dynamics of the Global Routing 
+ * environment.  By that we mean that you can discover new link state 
+ * advertisements after a network topology change by calling DiscoverLSAs 
+ * and then by reading those advertisements.
+ *
+ * @see GlobalRoutingLSA
+ * @see GlobalRouter::GetLSA ()
+ * @returns The number of Global Routing Link State Advertisements.
+ */
+  uint32_t DiscoverLSAs (void);
+
+/**
+ * @brief Get the Number of Global Routing Link State Advertisements that this
+ * router can export.
+ *
+ * To get meaningful information you must have previously called DiscoverLSAs.
+ * After you know how many LSAs are present in the router, you may call 
+ * GetLSA () to retrieve the actual advertisement.
+ *
+ * @see GlobalRouterLSA
+ * @see GlobalRouting::DiscoverLSAs ()
+ * @see GlobalRouting::GetLSA ()
+ * @returns The number of Global Routing Link State Advertisements.
+ */
+  uint32_t GetNumLSAs (void) const;
+
+/**
+ * @brief Get a Global Routing Link State Advertisements that this router has 
+ * said that it can export.
+ *
+ * This is a fairly inexpensive expensive operation in that the hard work
+ * was done in GetNumLSAs.  We just copy the indicated Global Routing Link
+ * State Advertisement into the requested GlobalRoutingLSA object.
+ *
+ * You must call GlobalRouter::GetNumLSAs before calling this method in 
+ * order to discover the adjacent routers and build the advertisements.
+ * GetNumLSAs will return the number of LSAs this router advertises.  
+ * The parameter n (requested LSA number) must be in the range 0 to 
+ * GetNumLSAs() - 1.
+ *
+ * @see GlobalRoutingLSA
+ * @see GlobalRouting::GetNumLSAs ()
+ * @param n The index number of the LSA you want to read.
+ * @param lsa The GlobalRoutingLSA class to receive the LSA information.
+ * @returns The number of Global Router Link State Advertisements.
+ */
+  bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
+
+/**
+ * @brief Inject a route to be circulated to other routers as an external
+ * route
+ *
+ * @param network The Network to inject
+ * @param networkMask The Network Mask to inject
+ */
+  void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
+
+/**
+ * @brief Get the number of injected routes that have been added
+ * to the routing table.
+ * @return number of injected routes
+ */
+  uint32_t GetNInjectedRoutes (void);
+
+/**
+ * @brief Return the injected route indexed by i
+ * @param i the index of the route
+ * @return a pointer to that Ipv4RoutingTableEntry is returned
+ *
+ */
+  Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
+
+/**
+ * @brief Withdraw a route from the global unicast routing table.
+ *
+ * Calling this function will cause all indexed routes numbered above
+ * index i to have their index decremented.  For instance, it is possible to
+ * remove N injected routes by calling RemoveInjectedRoute (0) N times.
+ *
+ * @param i The index (into the injected routing list) of the route to remove.  
+ *
+ * @see GlobalRouter::WithdrawRoute ()
+ */
+  void RemoveInjectedRoute (uint32_t i);
+
+/**
+ * @brief Withdraw a route from the global unicast routing table.
+ *
+ * @param network The Network to withdraw
+ * @param networkMask The Network Mask to withdraw
+ * @return whether the operation succeeded (will return false if no such route)
+ *
+ * @see GlobalRouter::RemoveInjectedRoute ()
+ */
+  bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
+
+private:
+  virtual ~GlobalRouter ();
+  void ClearLSAs (void);
+
+  Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
+  bool FindInterfaceForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
+  Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const;
+  bool AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const;
+  void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+  void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+  void ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+
+  void ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA);
+  void BuildNetworkLSAs (NetDeviceContainer c);
+  Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
+
+
+  typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t;
+  ListOfLSAs_t m_LSAs;
+
+  Ipv4Address m_routerId;
+  Ptr<Ipv4GlobalRouting> m_routingProtocol;
+
+  typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes;
+  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI;
+  typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI;
+  InjectedRoutes m_injectedRoutes; // Routes we are exporting
+
+  // inherited from Object
+  virtual void DoDispose (void);
+
+/**
+ * @brief Global Router copy construction is disallowed.
+ */
+  GlobalRouter (GlobalRouter& sr);
+
+/**
+ * @brief Global Router assignment operator is disallowed.
+ */
+  GlobalRouter& operator= (GlobalRouter& sr);
+};
+
+} // namespace ns3
+
+#endif /* GLOBAL_ROUTER_INTERFACE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-routing.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2008 University of Washington
+ * 
+ * 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
+ *
+ */
+
+/**
+ * \ingroup routing
+ * \defgroup globalrouting Global Routing
+ *
+ * \section model Model
+ *
+ * ns-3 global routing performs pre-simulation static route computation
+ * on a layer-3 Ipv4 topology.  The user API from the script level is
+ * fairly minimal; once a topology has been constructed and addresses
+ * assigned, the user may call ns3::GlobalRouteManager::PopulateRoutingTables()
+ * and the simulator will initialize the routing database and set up
+ * static unicast forwarding tables for each node.
+ *
+ * The model assumes that all nodes on an ns-3 channel are reachable to
+ * one another, regardless of whether the nodes can use the channel
+ * successfully (in the case of wireless).  Therefore, this model
+ * should typically be used only on wired topologies.  Layer-2 bridge
+ * devices are supported.  API does not yet exist to control the subset 
+ * of a topology to which this global static routing is applied.
+ * 
+ * If the topology changes during the simulation, by default, routing
+ * will not adjust.  There are two ways to make it adjust.
+ * - Set the attribute Ipv4GlobalRouting::RespondToInterfaceEvents to true 
+ * - Manually call the sequence of GlobalRouteManager methods to delte global
+ *   routes, build global routing database, and initialize routes.
+ *   There is a helper method that encapsulates this 
+ *   (Ipv4GlobalRoutingHelper::RecomputeRoutingTables())
+ * 
+ * \section api API and Usage
+ * 
+ * Users must include ns3/global-route-manager.h header file.  After the
+ * IPv4 topology has been built and addresses assigned, users call
+ * ns3::GlobalRouteManager::PopulateRoutingTables (), prior to the 
+ * ns3::Simulator::Run() call.  
+ *
+ * There are two attributes of Ipv4GlobalRouting that govern behavior.
+ * - Ipv4GlobalRouting::RandomEcmpRouting
+ * - Ipv4GlobalRouting::RespondToInterfaceEvents  
+ *
+ * \section impl Implementation
+ *
+ * A singleton object, ns3::GlobalRouteManager, builds a global routing
+ * database of information about the topology, and executes a Dijkstra
+ * Shortest Path First (SPF) algorithm on the topology for each node, and
+ * stores the computed routes in each node's IPv4 forwarding table by
+ * making use of the routing API in class ns3::Ipv4.
+ *
+ * The nodes that export data are those that have had an ns3::GlobalRouter
+ * object aggregated to them.  The ns3::GlobalRouter can be thought of
+ * as a per-node agent that exports topology information to the 
+ * ns3::GlobalRouteManager.  When it comes time to build the global
+ * routing database, the list of nodes is iterated and each node with
+ * an ns3::GlobalRouter object is asked to export routing information
+ * concerning the links to which it is attached.
+ *
+ * The format of the data exported conforms to the OSPFv2 standard
+ * (http://www.ietf.org/rfc/rfc2328.txt).  In particular, the
+ * information is exported in the form of ns3::GlobalLSA objects that
+ * semantically match the Link State Advertisements of OSPF.  
+ *
+ * By using a standard data format for reporting topology, existing 
+ * OSPF route computation code can be reused, and that is what is done
+ * by the ns3::GlobalRouteManager.  The main computation functions are
+ * ported from the quagga routing suite (http://www.quagga.net).
+ * 
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/ipv4-global-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,551 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2008 University of Washington
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/object.h"
+#include "ns3/packet.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/ipv4-routing-table-entry.h"
+#include "ns3/boolean.h"
+#include "ipv4-global-routing.h"
+#include "global-route-manager.h"
+#include <vector>
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4GlobalRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRouting);
+
+TypeId 
+Ipv4GlobalRouting::GetTypeId (void)
+{ 
+  static TypeId tid = TypeId ("ns3::Ipv4GlobalRouting")
+    .SetParent<Object> ()
+    .AddAttribute ("RandomEcmpRouting",
+                   "Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",
+                   BooleanValue(false),
+                   MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),
+                   MakeBooleanChecker ())
+    .AddAttribute ("RespondToInterfaceEvents",
+                   "Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
+                   BooleanValue(false),
+                   MakeBooleanAccessor (&Ipv4GlobalRouting::m_respondToInterfaceEvents),
+                   MakeBooleanChecker ())
+    ;
+  return tid;
+}
+
+Ipv4GlobalRouting::Ipv4GlobalRouting () 
+: m_randomEcmpRouting (false),
+  m_respondToInterfaceEvents (false) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv4GlobalRouting::~Ipv4GlobalRouting ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void 
+Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest, 
+                                   Ipv4Address nextHop, 
+                                   uint32_t interface)
+{
+  NS_LOG_FUNCTION (dest << nextHop << interface);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, nextHop, interface);
+  m_hostRoutes.push_back (route);
+}
+
+void 
+Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest, 
+                                   uint32_t interface)
+{
+  NS_LOG_FUNCTION (dest << interface);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, interface);
+  m_hostRoutes.push_back (route);
+}
+
+void 
+Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      Ipv4Address nextHop, 
+                                      uint32_t interface)
+{
+  NS_LOG_FUNCTION (network << networkMask << nextHop << interface);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            nextHop,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+
+void 
+Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      uint32_t interface)
+{
+  NS_LOG_FUNCTION (network << networkMask << interface);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+
+void 
+Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network, 
+                                         Ipv4Mask networkMask,
+                                         Ipv4Address nextHop,
+                                         uint32_t interface)
+{
+  NS_LOG_FUNCTION (network << networkMask << nextHop);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+      networkMask,
+      nextHop,
+      interface);
+  m_ASexternalRoutes.push_back (route);
+}
+
+
+Ptr<Ipv4Route>
+Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("Looking for route for destination " << dest);
+  Ptr<Ipv4Route> rtentry = 0;
+  // store all available routes that bring packets to their destination
+  typedef std::vector<Ipv4RoutingTableEntry*> RouteVec_t;
+  RouteVec_t allRoutes;
+
+  NS_LOG_LOGIC ("Number of m_hostRoutes = " << m_hostRoutes.size ());
+  for (HostRoutesCI i = m_hostRoutes.begin (); 
+       i != m_hostRoutes.end (); 
+       i++) 
+    {
+      NS_ASSERT ((*i)->IsHost ());
+      if ((*i)->GetDest ().IsEqual (dest)) 
+        {
+          if (oif != 0)
+            {
+              if (oif != m_ipv4->GetNetDevice((*i)->GetInterface ()))
+                {
+                  NS_LOG_LOGIC ("Not on requested interface, skipping");
+                  continue;
+                }
+            }
+          allRoutes.push_back (*i);
+          NS_LOG_LOGIC (allRoutes.size () << "Found global host route" << *i); 
+        }
+    }
+  if (allRoutes.size () == 0) // if no host route is found
+    {
+      NS_LOG_LOGIC ("Number of m_networkRoutes" << m_networkRoutes.size ());
+      for (NetworkRoutesI j = m_networkRoutes.begin (); 
+           j != m_networkRoutes.end (); 
+           j++) 
+        {
+          Ipv4Mask mask = (*j)->GetDestNetworkMask ();
+          Ipv4Address entry = (*j)->GetDestNetwork ();
+          if (mask.IsMatch (dest, entry)) 
+            {
+              if (oif != 0)
+                {
+                  if (oif != m_ipv4->GetNetDevice((*j)->GetInterface ()))
+                    {
+                      NS_LOG_LOGIC ("Not on requested interface, skipping");
+                      continue;
+                    }
+                }
+              allRoutes.push_back (*j);
+              NS_LOG_LOGIC (allRoutes.size () << "Found global network route" << *j);
+            }
+        }
+    }
+  if (allRoutes.size () == 0)  // consider external if no host/network found
+    {
+      for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+           k != m_ASexternalRoutes.end ();
+           k++)
+        {
+          Ipv4Mask mask = (*k)->GetDestNetworkMask ();
+          Ipv4Address entry = (*k)->GetDestNetwork ();
+          if (mask.IsMatch (dest, entry))
+            {
+              NS_LOG_LOGIC ("Found external route" << *k);
+              if (oif != 0)
+                {
+                  if (oif != m_ipv4->GetNetDevice((*k)->GetInterface ()))
+                    {
+                      NS_LOG_LOGIC ("Not on requested interface, skipping");
+                      continue;
+                    }
+                }
+              allRoutes.push_back (*k);
+              break;
+            }
+        }
+    }
+  if (allRoutes.size () > 0 ) // if route(s) is found
+    {
+      // pick up one of the routes uniformly at random if random
+      // ECMP routing is enabled, or always select the first route
+      // consistently if random ECMP routing is disabled
+      uint32_t selectIndex;
+      if (m_randomEcmpRouting)
+        {
+          selectIndex = m_rand.GetInteger (0, allRoutes.size ()-1);
+        }
+      else 
+        {
+          selectIndex = 0;
+        }
+      Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex); 
+      // create a Ipv4Route object from the selected routing table entry
+      rtentry = Create<Ipv4Route> ();
+      rtentry->SetDestination (route->GetDest ());
+      // XXX handle multi-address case
+      rtentry->SetSource (m_ipv4->GetAddress (route->GetInterface(), 0).GetLocal ());
+      rtentry->SetGateway (route->GetGateway ());
+      uint32_t interfaceIdx = route->GetInterface ();
+      rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
+      return rtentry;
+    }
+  else 
+    {
+      return 0;
+    }
+}
+
+uint32_t 
+Ipv4GlobalRouting::GetNRoutes (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t n = 0;
+  n += m_hostRoutes.size ();
+  n += m_networkRoutes.size ();
+  n += m_ASexternalRoutes.size ();
+  return n;
+}
+
+Ipv4RoutingTableEntry *
+Ipv4GlobalRouting::GetRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (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;
+  if (index < m_networkRoutes.size())
+    {
+      for (NetworkRoutesI j = m_networkRoutes.begin (); 
+          j != m_networkRoutes.end (); 
+          j++) 
+        {
+          if (tmp == index)
+            {
+              return *j;
+            }
+          tmp++;
+        }
+    }
+  index -= m_networkRoutes.size();
+  tmp = 0;
+  for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); 
+       k != m_ASexternalRoutes.end (); 
+       k++) 
+  {
+    if (tmp == index)
+    {
+      return *k;
+    }
+    tmp++;
+  }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+void 
+Ipv4GlobalRouting::RemoveRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (index);
+  if (index < m_hostRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (HostRoutesI i = m_hostRoutes.begin (); 
+           i != m_hostRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_hostRoutes.size());
+              delete *i;
+              m_hostRoutes.erase (i);
+              NS_LOG_LOGIC ("Done removing host route " << index << "; host route remaining size = " << m_hostRoutes.size());
+              return;
+            }
+          tmp++;
+        }
+    }
+  index -= m_hostRoutes.size ();
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_networkRoutes.size());
+          delete *j;
+          m_networkRoutes.erase (j);
+          NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
+          return;
+        }
+      tmp++;
+    }
+  index -= m_networkRoutes.size ();
+  tmp = 0;
+  for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); 
+         k != m_ASexternalRoutes.end (); 
+         k++) 
+    {
+      if (tmp == index)
+      {
+        NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size());
+        delete *k;
+        m_ASexternalRoutes.erase (k);
+        NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
+        return;
+      }
+      tmp++;
+    }
+  NS_ASSERT (false);
+}
+
+void
+Ipv4GlobalRouting::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  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);
+    }
+  for (ASExternalRoutesI l = m_ASexternalRoutes.begin (); 
+         l != m_ASexternalRoutes.end (); 
+         l = m_ASexternalRoutes.erase (l)) 
+    {
+      delete (*l);
+    }
+
+  Ipv4RoutingProtocol::DoDispose ();
+}
+
+Ptr<Ipv4Route>
+Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{      
+
+//
+// First, see if this is a multicast packet we have a route for.  If we
+// have a route, then send the packet down each of the specified interfaces.
+//
+  if (header.GetDestination().IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination-- returning false");
+      return 0; // Let other routing protocols try to handle this
+    }
+//
+// See if this is a unicast packet we have a route for.
+//
+  NS_LOG_LOGIC ("Unicast destination- looking up");
+  Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), oif);
+  if (rtentry)
+    {
+      sockerr = Socket::ERROR_NOTERROR;
+    }
+  else
+    {
+      sockerr = Socket::ERROR_NOROUTETOHOST;
+    }
+  return rtentry;
+}
+
+bool 
+Ipv4GlobalRouting::RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                             LocalDeliverCallback lcb, ErrorCallback ecb) 
+{ 
+
+  NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
+  // Check if input device supports IP
+  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
+
+  if (header.GetDestination ().IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination-- returning false");
+      return false; // Let other routing protocols try to handle this
+    }
+
+  if (header.GetDestination ().IsBroadcast ())
+    {
+      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
+      // TODO:  Local Deliver for broadcast
+      // TODO:  Forward broadcast
+    }
+
+  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
+  // Right now, we will be permissive and allow a source to send us
+  // a packet to one of our other interface addresses; that is, the
+  // destination unicast address does not match one of the iif addresses,
+  // but we check our other interfaces.  This could be an option
+  // (to remove the outer loop immediately below and just check iif).
+  for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
+    {
+      for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
+        {
+          Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
+          Ipv4Address addr = iaddr.GetLocal ();
+          if (addr.IsEqual (header.GetDestination ()))
+            {
+              if (j == iif)
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ());
+                }
+              lcb (p, header, iif);
+              return true;
+            }
+          if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
+            {
+              NS_LOG_LOGIC ("For me (interface broadcast address)");
+              lcb (p, header, iif);
+              return true;
+            }
+          NS_LOG_LOGIC ("Address "<< addr << " not a match");
+        }
+    }
+  // Check if input device supports IP forwarding
+  if (m_ipv4->IsForwarding (iif) == false)
+    {
+      NS_LOG_LOGIC ("Forwarding disabled for this interface");
+      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+      return false;
+    }
+  // Next, try to find a route
+  NS_LOG_LOGIC ("Unicast destination- looking up global route");
+  Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination ());
+  if (rtentry != 0)
+    {
+      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+      ucb (rtentry, p, header);
+      return true;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+      return false; // Let other routing protocols try to handle this
+                    // route request.
+    }
+}
+void 
+Ipv4GlobalRouting::NotifyInterfaceUp (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
+    {
+      GlobalRouteManager::DeleteGlobalRoutes ();
+      GlobalRouteManager::BuildGlobalRoutingDatabase ();
+      GlobalRouteManager::InitializeRoutes ();
+    }
+}
+
+void 
+Ipv4GlobalRouting::NotifyInterfaceDown (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
+    {
+      GlobalRouteManager::DeleteGlobalRoutes ();
+      GlobalRouteManager::BuildGlobalRoutingDatabase ();
+      GlobalRouteManager::InitializeRoutes ();
+    }
+}
+
+void 
+Ipv4GlobalRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << interface << address);
+  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
+    {
+      GlobalRouteManager::DeleteGlobalRoutes ();
+      GlobalRouteManager::BuildGlobalRoutingDatabase ();
+      GlobalRouteManager::InitializeRoutes ();
+    }
+}
+
+void 
+Ipv4GlobalRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << interface << address);
+  if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0)  // avoid startup events
+    {
+      GlobalRouteManager::DeleteGlobalRoutes ();
+      GlobalRouteManager::BuildGlobalRoutingDatabase ();
+      GlobalRouteManager::InitializeRoutes ();
+    }
+}
+
+void 
+Ipv4GlobalRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+  NS_LOG_FUNCTION(this << ipv4);
+  NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
+  m_ipv4 = ipv4;
+}
+
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/ipv4-global-routing.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,245 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2008 University of Washington
+//
+// 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 IPV4_GLOBAL_ROUTING_H
+#define IPV4_GLOBAL_ROUTING_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4RoutingTableEntry;
+class Ipv4MulticastRoutingTableEntry;
+class Node;
+
+
+/**
+ * \brief Global routing protocol for IP version 4 stacks.
+ *
+ * In ns-3 we have the concept of a pluggable routing protocol.  Routing
+ * protocols are added to a list maintained by the Ipv4L3Protocol.  Every 
+ * stack gets one routing protocol for free -- the Ipv4StaticRouting routing
+ * protocol is added in the constructor of the Ipv4L3Protocol (this is the 
+ * piece of code that implements the functionality of the IP layer).
+ *
+ * As an option to running a dynamic routing protocol, a GlobalRouteManager
+ * object has been created to allow users to build routes for all participating
+ * nodes.  One can think of this object as a "routing oracle"; it has
+ * an omniscient view of the topology, and can construct shortest path
+ * routes between all pairs of nodes.  These routes must be stored 
+ * somewhere in the node, so therefore this class Ipv4GlobalRouting
+ * is used as one of the pluggable routing protocols.  It is kept distinct
+ * from Ipv4StaticRouting because these routes may be dynamically cleared
+ * and rebuilt in the middle of the simulation, while manually entered
+ * routes into the Ipv4StaticRouting may need to be kept distinct.
+ *
+ * This class deals with Ipv4 unicast routes only.
+ *
+ * \see Ipv4RoutingProtocol
+ * \see GlobalRouteManager
+ */
+class Ipv4GlobalRouting : public Ipv4RoutingProtocol
+{
+public:
+  static TypeId GetTypeId (void);
+/**
+ * \brief Construct an empty Ipv4GlobalRouting routing protocol,
+ *
+ * The Ipv4GlobalRouting class supports host and network unicast routes.
+ * This method initializes the lists containing these routes to empty.
+ *
+ * \see Ipv4GlobalRouting
+ */
+  Ipv4GlobalRouting ();
+  virtual ~Ipv4GlobalRouting ();
+
+  // These methods inherited from base class
+  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                             LocalDeliverCallback lcb, ErrorCallback ecb);
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+/**
+ * \brief Add a host route to the global routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param nextHop The Ipv4Address of the next hop in the route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+  void AddHostRouteTo (Ipv4Address dest, 
+                       Ipv4Address nextHop, 
+                       uint32_t interface);
+/**
+ * \brief Add a host route to the global routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+  void AddHostRouteTo (Ipv4Address dest, 
+                       uint32_t interface);
+
+/**
+ * \brief Add a network route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop in the route to the destination network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          Ipv4Address nextHop, 
+                          uint32_t interface);
+
+/**
+ * \brief Add a network route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          uint32_t interface);
+
+/**
+ * \brief Add an external route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop Ipv4Address
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ */
+  void AddASExternalRouteTo (Ipv4Address network,
+                             Ipv4Mask networkMask,
+                             Ipv4Address nextHop,
+                             uint32_t interface);
+
+/**
+ * \brief Get the number of individual unicast routes that have been added
+ * to the routing table.
+ *
+ * \warning The default route counts as one of the routes.
+ */
+  uint32_t GetNRoutes (void);
+
+/**
+ * \brief Get a route from the global unicast routing table.
+ *
+ * Externally, the unicast global routing table appears simply as a table with
+ * n entries.  The one subtlety of note is that if a default route has been set
+ * it will appear as the zeroth entry in the table.  This means that if you
+ * add only a default route, the table will have one entry that can be accessed
+ * either by explicitly calling GetDefaultRoute () or by calling GetRoute (0).
+ * 
+ * Similarly, if the default route has been set, calling RemoveRoute (0) will
+ * remove the default route.
+ *
+ * \param i The index (into the routing table) of the route to retrieve.  If
+ * the default route has been set, it will occupy index zero.
+ * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
+ * a zero pointer is returned.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4GlobalRouting::RemoveRoute
+ */
+  Ipv4RoutingTableEntry *GetRoute (uint32_t i);
+
+/**
+ * \brief Remove a route from the global unicast routing table.
+ *
+ * Externally, the unicast global routing table appears simply as a table with
+ * n entries.  The one subtlety of note is that if a default route has been set
+ * it will appear as the zeroth entry in the table.  This means that if the
+ * default route has been set, calling RemoveRoute (0) will remove the
+ * default route.
+ *
+ * \param i The index (into the routing table) of the route to remove.  If
+ * the default route has been set, it will occupy index zero.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4GlobalRouting::GetRoute
+ * \see Ipv4GlobalRouting::AddRoute
+ */
+  void RemoveRoute (uint32_t i);
+
+protected:
+  void DoDispose (void);
+
+private:
+  /// Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently
+  bool m_randomEcmpRouting;
+  /// Set to true if this interface should respond to interface events by globallly recomputing routes 
+  bool m_respondToInterfaceEvents;
+  /// A uniform random number generator for randomly routing packets among ECMP 
+  UniformVariable m_rand;
+
+  typedef std::list<Ipv4RoutingTableEntry *> HostRoutes;
+  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator HostRoutesCI;
+  typedef std::list<Ipv4RoutingTableEntry *>::iterator HostRoutesI;
+  typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
+  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
+  typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
+  typedef std::list<Ipv4RoutingTableEntry *> ASExternalRoutes;
+  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator ASExternalRoutesCI;
+  typedef std::list<Ipv4RoutingTableEntry *>::iterator ASExternalRoutesI;
+
+  Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif = 0);
+
+  HostRoutes m_hostRoutes;
+  NetworkRoutes m_networkRoutes;
+  ASExternalRoutes m_ASexternalRoutes; // External routes imported
+  
+  Ptr<Ipv4> m_ipv4;
+};
+
+} // Namespace ns3
+
+#endif /* IPV4_GLOBAL_ROUTING_H */
--- a/src/routing/global-routing/wscript	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/global-routing/wscript	Tue Oct 26 18:02:17 2010 +0100
@@ -3,17 +3,19 @@
 def build(bld):
     module = bld.create_ns3_module('global-routing', ['node'])
     module.source = [
-        'global-router-interface.cc',
-        'global-route-manager.cc',
-        'global-route-manager-impl.cc',
-        'candidate-queue.cc',
-        'ipv4-global-routing.cc',
+        'model/global-router-interface.cc',
+        'model/global-route-manager.cc',
+        'model/global-route-manager-impl.cc',
+        'model/candidate-queue.cc',
+        'model/ipv4-global-routing.cc',
+        'helper/ipv4-global-routing-helper.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'global-routing'
     headers.source = [
-        'global-router-interface.h',
-        'global-route-manager.h',
-        'ipv4-global-routing.h',
+        'model/global-router-interface.h',
+        'model/global-route-manager.h',
+        'model/ipv4-global-routing.h',
+	'helper/ipv4-global-routing-helper.h',
         ]
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv4-list-routing-helper.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-list-routing-helper.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+Ipv4ListRoutingHelper::Ipv4ListRoutingHelper()
+{}
+
+Ipv4ListRoutingHelper::~Ipv4ListRoutingHelper()
+{
+  for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
+       i != m_list.end (); ++i)
+    {
+      delete i->first;
+    }
+}
+
+Ipv4ListRoutingHelper::Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &o)
+{
+  std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i;
+  for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
+    {
+      m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (i->first->Copy ()), i->second));
+    }
+}
+
+Ipv4ListRoutingHelper* 
+Ipv4ListRoutingHelper::Copy (void) const 
+{
+  return new Ipv4ListRoutingHelper (*this); 
+}
+
+void 
+Ipv4ListRoutingHelper::Add (const Ipv4RoutingHelper &routing, int16_t priority)
+{
+  m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (routing.Copy ()), priority));
+}
+
+Ptr<Ipv4RoutingProtocol> 
+Ipv4ListRoutingHelper::Create (Ptr<Node> node) const
+{
+  Ptr<Ipv4ListRouting> list = CreateObject<Ipv4ListRouting> ();
+  for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i = m_list.begin ();
+       i != m_list.end (); ++i)
+    {
+      Ptr<Ipv4RoutingProtocol> prot = i->first->Create (node);
+      list->AddRoutingProtocol (prot,i->second);
+    }
+  return list;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv4-list-routing-helper.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_LIST_ROUTING_HELPER_H
+#define IPV4_LIST_ROUTING_HELPER_H
+
+#include "ns3/ipv4-routing-helper.h"
+#include <stdint.h>
+#include <list>
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv4ListRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
+{
+public:
+  /*
+   * Construct an Ipv4ListRoutingHelper used to make installing routing
+   * protocols easier.
+   */
+  Ipv4ListRoutingHelper ();
+
+  /*
+   * \internal
+   * Destroy an Ipv4ListRoutingHelper.
+   */
+  virtual ~Ipv4ListRoutingHelper ();
+
+  /**
+   * \brief Construct an Ipv4ListRoutingHelper from another previously 
+   * initialized instance (Copy Constructor).
+   */
+  Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &);
+
+  /**
+   * \internal
+   * \returns pointer to clone of this Ipv4ListRoutingHelper 
+   * 
+   * This method is mainly for internal use by the other helpers;
+   * clients are expected to free the dynamic memory allocated by this method
+   */
+  Ipv4ListRoutingHelper* Copy (void) const;
+
+  /**
+   * \param routing a routing helper
+   * \param priority the priority of the associated helper
+   *
+   * Store in the internal list a reference to the input routing helper
+   * and associated priority. These helpers will be used later by
+   * the ns3::Ipv4ListRoutingHelper::Create method to create
+   * an ns3::Ipv4ListRouting object and add in it routing protocols
+   * created with the helpers.
+   */
+  void Add (const Ipv4RoutingHelper &routing, int16_t priority);
+  /**
+   * \param node the node on which the routing protocol will run
+   * \returns a newly-created routing protocol
+   *
+   * This method will be called by ns3::InternetStackHelper::Install
+   */
+  virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+private:
+  /**
+   * \internal
+   * \brief Assignment operator declared private and not implemented to disallow
+   * assignment and prevent the compiler from happily inserting its own.
+   */
+  Ipv4ListRoutingHelper &operator = (const Ipv4ListRoutingHelper &o);
+
+  std::list<std::pair<const Ipv4RoutingHelper *,int16_t> > m_list;
+};
+
+} // namespace ns3
+
+#endif /* IPV4_LIST_ROUTING_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv6-list-routing-helper.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/node.h"
+
+#include "ipv6-list-routing-helper.h"
+
+namespace ns3 {
+
+Ipv6ListRoutingHelper::Ipv6ListRoutingHelper ()
+{}
+
+Ipv6ListRoutingHelper::~Ipv6ListRoutingHelper()
+{
+  for (std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
+       i != m_list.end (); ++i)
+    {
+      delete i->first;
+    }
+}
+Ipv6ListRoutingHelper::Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &o)
+{
+  std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::const_iterator i;
+  for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
+    {
+      m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (i->first->Copy ()), i->second));
+    }
+}
+
+Ipv6ListRoutingHelper* 
+Ipv6ListRoutingHelper::Copy (void) const 
+{
+  return new Ipv6ListRoutingHelper (*this); 
+}
+
+void 
+Ipv6ListRoutingHelper::Add (const Ipv6RoutingHelper &routing, int16_t priority)
+{
+  m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (routing.Copy ()), priority));
+}
+Ptr<Ipv6RoutingProtocol> 
+Ipv6ListRoutingHelper::Create (Ptr<Node> node) const
+{
+  Ptr<Ipv6ListRouting> list = CreateObject<Ipv6ListRouting> ();
+  for (std::list<std::pair<const Ipv6RoutingHelper *,int16_t> >::const_iterator i = m_list.begin ();
+       i != m_list.end (); ++i)
+    {
+      Ptr<Ipv6RoutingProtocol> prot = i->first->Create (node);
+      list->AddRoutingProtocol (prot,i->second);
+    }
+  return list;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv6-list-routing-helper.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,98 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV6_LIST_ROUTING_HELPER_H
+#define IPV6_LIST_ROUTING_HELPER_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/ipv6-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6ListRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6ListRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+  /**
+   * Construct an Ipv6 Ipv6ListRoutingHelper which is used to make life easier
+   * for people wanting to configure routing using Ipv6.
+   */
+  Ipv6ListRoutingHelper ();
+
+  /**
+   * \internal
+   * \brief Destroy an Ipv6 Ipv6ListRoutingHelper.
+   */
+  virtual ~Ipv6ListRoutingHelper ();
+
+  /**
+   * \brief Construct an Ipv6ListRoutingHelper from another previously 
+   * initialized instance (Copy Constructor).
+   */
+  Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &);
+
+  /**
+   * \returns pointer to clone of this Ipv6ListRoutingHelper 
+   * 
+   * This method is mainly for internal use by the other helpers;
+   * clients are expected to free the dynamic memory allocated by this method
+   */
+  Ipv6ListRoutingHelper* Copy (void) const;
+
+  /**
+   * \param routing a routing helper
+   * \param priority the priority of the associated helper
+   *
+   * Store in the internal list a reference to the input routing helper
+   * and associated priority. These helpers will be used later by
+   * the ns3::Ipv6ListRoutingHelper::Create method to create
+   * an ns3::Ipv6ListRouting object and add in it routing protocols
+   * created with the helpers.
+   */
+  void Add (const Ipv6RoutingHelper &routing, int16_t priority);
+  /**
+   * \param node the node on which the routing protocol will run
+   * \returns a newly-created routing protocol
+   *
+   * This method will be called by ns3::InternetStackHelper::Install
+   */
+  virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+private:
+  /**
+   * \internal
+   * \brief Assignment operator declared private and not implemented to disallow
+   * assignment and prevent the compiler from happily inserting its own.
+   */
+  Ipv6ListRoutingHelper &operator = (const Ipv6ListRoutingHelper &o);
+
+  std::list<std::pair<const Ipv6RoutingHelper *,int16_t> > m_list;
+};
+
+} // namespace ns3
+
+#endif /* IPV6_LIST_ROUTING_HELPER_H */
+
--- a/src/routing/list-routing/ipv4-list-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include "ns3/log.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/node.h"
-#include "ns3/ipv4-static-routing.h"
-#include "ipv4-list-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
-
-TypeId
-Ipv4ListRouting::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
-    .SetParent<Ipv4RoutingProtocol> ()
-    .AddConstructor<Ipv4ListRouting> ()
-    ;
-  return tid;
-}
-
-
-Ipv4ListRouting::Ipv4ListRouting () 
- : m_ipv4 (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv4ListRouting::~Ipv4ListRouting () 
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv4ListRouting::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end (); rprotoIter++)
-    {
-      // Note:  Calling dispose on these protocols causes memory leak
-      //        The routing protocols should not maintain a pointer to
-      //        this object, so Dispose() shouldn't be necessary.
-      (*rprotoIter).second = 0;
-    }
-  m_routingProtocols.clear ();
-  m_ipv4 = 0;
-}
-
-void
-Ipv4ListRouting::DoStart (void)
-{
-  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end (); rprotoIter++)
-    {
-      Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
-      protocol->Start ();
-    }
-  Ipv4RoutingProtocol::DoStart ();
-}
-
-
-Ptr<Ipv4Route>
-Ipv4ListRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
-{
-  NS_LOG_FUNCTION (this << header.GetDestination () << " " << header.GetSource () << " " << oif);
-  Ptr<Ipv4Route> route;
-
-  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
-       i != m_routingProtocols.end (); i++)
-    {
-      NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
-      NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
-      route = (*i).second->RouteOutput (p, header, oif, sockerr);
-      if (route)
-        {
-          NS_LOG_LOGIC ("Found route " << route);
-          sockerr = Socket::ERROR_NOTERROR;
-          return route;
-        }
-    }
-  NS_LOG_LOGIC ("Done checking " << GetTypeId ());
-  NS_LOG_LOGIC ("");
-  sockerr = Socket::ERROR_NOROUTETOHOST;
-  return 0;
-}
-
-// Patterned after Linux ip_route_input and ip_route_input_slow
-bool 
-Ipv4ListRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, 
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb, 
-                             LocalDeliverCallback lcb, ErrorCallback ecb)
-{
-  bool retVal = false;
-  NS_LOG_FUNCTION (p << header << idev);
-  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject<Node> ()->GetId ());
-
-  NS_ASSERT (m_ipv4 != 0);
-  // Check if input device supports IP 
-  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
-  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); 
-
-  retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif);
-  if (retVal == true)
-    {
-      NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery");
-      if (header.GetDestination ().IsMulticast ())
-        {
-          Ptr<Packet> packetCopy = p->Copy();
-          lcb (packetCopy, header, iif);
-          retVal = true;
-          // Fall through
-        }
-      else
-        {
-          lcb (p, header, iif);
-          return true;
-        }
-    }
-  // Check if input device supports IP forwarding
-  if (m_ipv4->IsForwarding (iif) == false)
-    {
-      NS_LOG_LOGIC ("Forwarding disabled for this interface");
-      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
-      return false;
-    }
-  // Next, try to find a route
-  // If we have already delivered a packet locally (e.g. multicast)
-  // we suppress further downstream local delivery by nulling the callback
-  LocalDeliverCallback downstreamLcb = lcb;
-  if (retVal == true)
-    {
-      downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > ();
-    }
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb))
-        {
-          NS_LOG_LOGIC ("Route found to forward packet in protocol " << (*rprotoIter).second->GetInstanceTypeId ().GetName ()); 
-          return true;
-        }
-    }
-  // No routing protocol has found a route.  
-  return retVal;
-}
-
-void 
-Ipv4ListRouting::NotifyInterfaceUp (uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << interface);
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyInterfaceUp (interface);
-    }  
-}
-void 
-Ipv4ListRouting::NotifyInterfaceDown (uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << interface);
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyInterfaceDown (interface);
-    }  
-}
-void 
-Ipv4ListRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
-  NS_LOG_FUNCTION(this << interface << address);
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyAddAddress (interface, address);
-    }  
-}
-void 
-Ipv4ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
-  NS_LOG_FUNCTION(this << interface << address);
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyRemoveAddress (interface, address);
-    }  
-}
-void 
-Ipv4ListRouting::SetIpv4 (Ptr<Ipv4> ipv4)
-{
-  NS_LOG_FUNCTION(this << ipv4);
-  NS_ASSERT (m_ipv4 == 0);
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->SetIpv4 (ipv4);
-    }  
-  m_ipv4 = ipv4;
-}
-
-void
-Ipv4ListRouting::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority)
-{
-  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
-  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
-  m_routingProtocols.sort ( Compare );
-  if (m_ipv4 != 0)
-    {
-      routingProtocol->SetIpv4 (m_ipv4);
-    }
-}
-
-uint32_t 
-Ipv4ListRouting::GetNRoutingProtocols (void) const
-{
-  NS_LOG_FUNCTION (this);
-  return m_routingProtocols.size (); 
-}
-
-Ptr<Ipv4RoutingProtocol> 
-Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
-{
-  NS_LOG_FUNCTION (index);
-  if (index > m_routingProtocols.size ())
-    {
-      NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol():  index " << index << " out of range");
-    }
-  uint32_t i = 0;
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
-    {
-      if (i == index)
-        {
-          priority = (*rprotoIter).first;
-          return (*rprotoIter).second;
-        }
-    }
-  return 0;
-}
-
-bool 
-Ipv4ListRouting::Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b)
-{
-  return a.first > b.first;
-}
-
-
-} // namespace ns3
-
-#include "ns3/test.h"
-#include "ipv4-list-routing.h"
-#include "ns3/ipv4-routing-protocol.h"
-
-namespace ns3 {
-
-class Ipv4ARouting : public Ipv4RoutingProtocol {
-public:
-  Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
-  bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                             LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
-  void NotifyInterfaceUp (uint32_t interface) {}
-  void NotifyInterfaceDown (uint32_t interface) {}
-  void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
-  void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
-  void SetIpv4 (Ptr<Ipv4> ipv4) {}
-};
-
-class Ipv4BRouting : public Ipv4RoutingProtocol {
-public:
-  Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
-  bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                             LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
-  void NotifyInterfaceUp (uint32_t interface) {}
-  void NotifyInterfaceDown (uint32_t interface) {}
-  void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
-  void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
-  void SetIpv4 (Ptr<Ipv4> ipv4) {}
-};
-
-class Ipv4ListRoutingNegativeTestCase : public TestCase
-{
-public:
-  Ipv4ListRoutingNegativeTestCase();
-  virtual bool DoRun (void);
-};
-
-Ipv4ListRoutingNegativeTestCase::Ipv4ListRoutingNegativeTestCase()
-  : TestCase("Check negative priorities")
-{}
-bool 
-Ipv4ListRoutingNegativeTestCase::DoRun (void)
-{
-  Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
-  Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
-  Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
-  // The Ipv4BRouting should be added with higher priority (larger integer value)
-  lr->AddRoutingProtocol (aRouting, -10);
-  lr->AddRoutingProtocol (bRouting, -5);
-  int16_t first = 3;
-  uint32_t num = lr->GetNRoutingProtocols ();
-  NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
-  Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
-  NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
-  NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
-
-  // XXX
-  return false;
-}
-
-class Ipv4ListRoutingPositiveTestCase : public TestCase
-{
-public:
-  Ipv4ListRoutingPositiveTestCase();
-  virtual bool DoRun (void);
-};
-
-Ipv4ListRoutingPositiveTestCase::Ipv4ListRoutingPositiveTestCase()
-  : TestCase("Check positive priorities")
-{}
-bool 
-Ipv4ListRoutingPositiveTestCase::DoRun (void)
-{
-  Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
-  Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
-  Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
-  // The Ipv4ARouting should be added with higher priority (larger integer 
-  // value) and will be fetched first below
-  lr->AddRoutingProtocol (aRouting, 10);
-  lr->AddRoutingProtocol (bRouting, 5);
-  int16_t first = 3;
-  int16_t second = 3;
-  uint32_t num = lr->GetNRoutingProtocols ();
-  NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
-  Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
-  NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
-  NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
-  Ptr<Ipv4RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
-  NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
-  NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
-  
-  // XXX
-  return false;
-}
-
-static class Ipv4ListRoutingTestSuite : public TestSuite
-{
-public:
-  Ipv4ListRoutingTestSuite()
-    : TestSuite("ipv4-list-routing", UNIT)
-  {
-    AddTestCase(new Ipv4ListRoutingPositiveTestCase());
-    AddTestCase(new Ipv4ListRoutingNegativeTestCase());
-  }
-
-} g_ipv4ListRoutingTestSuite;
-
-} // namespace ns3
-
-
--- a/src/routing/list-routing/ipv4-list-routing.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * 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 IPV4_LIST_ROUTING_H
-#define IPV4_LIST_ROUTING_H
-
-#include <list>
-#include "ns3/ipv4-routing-protocol.h"
-
-namespace ns3 {
-
-/**
- * \ingroup routing 
- * \defgroup ipv4ListRouting Ipv4 List Routing
- */
-/**
- * \ingroup ipv4ListRouting
- *
- * This class is a specialization of Ipv4RoutingProtocol that allows 
- * other instances of Ipv4RoutingProtocol to be inserted in a 
- * prioritized list.  Routing protocols in the list are consulted one
- * by one, from highest to lowest priority, until a routing protocol
- * is found that will take the packet (this corresponds to a non-zero
- * return value to RouteOutput, or a return value of true to RouteInput).
- * The order by which routing protocols with the same priority value 
- * are consulted is undefined.
- * 
- */
-class Ipv4ListRouting : public Ipv4RoutingProtocol
-{
-public:
-  static TypeId GetTypeId (void);
-
-  Ipv4ListRouting ();  
-  virtual ~Ipv4ListRouting ();  
-
-  /**
-   * \brief Register a new routing protocol to be used in this IPv4 stack
-   *
-   * \param routingProtocol new routing protocol implementation object
-   * \param priority priority to give to this routing protocol.
-   * Values may range between -32768 and +32767.  
-   */
-  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority);
-  /**
-   * \return number of routing protocols in the list
-   */
-  virtual uint32_t GetNRoutingProtocols (void) const;
-  /**
-   * Return pointer to routing protocol stored at index, with the
-   * first protocol (index 0) the highest priority, the next one (index 1)
-   * the second highest priority, and so on.  The priority parameter is an
-   * output parameter and it returns the integer priority of the protocol.
-   * 
-   * \return pointer to routing protocol indexed by 
-   * \param index index of protocol to return
-   * \param priority output parameter, set to the priority of the protocol
-            being returned
-   */
-  virtual Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
-
-  // Below are from Ipv4RoutingProtocol
-  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
-  virtual bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
-                           UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                           LocalDeliverCallback lcb, ErrorCallback ecb);
-  virtual void NotifyInterfaceUp (uint32_t interface);
-  virtual void NotifyInterfaceDown (uint32_t interface);
-  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
-  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
-  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
-
-protected:
-  void DoDispose (void);
-  void DoStart (void);
-private:
-  typedef std::pair<int16_t, Ptr<Ipv4RoutingProtocol> > Ipv4RoutingProtocolEntry;
-  typedef std::list<Ipv4RoutingProtocolEntry> Ipv4RoutingProtocolList;
-  Ipv4RoutingProtocolList m_routingProtocols;
-  static bool Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b);
-  Ptr<Ipv4> m_ipv4;
-
-};
-
-} //namespace ns3
-
-#endif /* IPV4_LIST_ROUTING_H */
--- a/src/routing/list-routing/ipv6-list-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,452 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include "ns3/log.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-route.h"
-#include "ns3/node.h"
-#include "ns3/ipv6-static-routing.h"
-#include "ipv6-list-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
-
-TypeId
-Ipv6ListRouting::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
-    .SetParent<Ipv6RoutingProtocol> ()
-    .AddConstructor<Ipv6ListRouting> ()
-    ;
-  return tid;
-}
-
-
-Ipv6ListRouting::Ipv6ListRouting () 
-  : m_ipv6 (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv6ListRouting::~Ipv6ListRouting () 
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv6ListRouting::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end (); rprotoIter++)
-    {
-      // Note:  Calling dispose on these protocols causes memory leak
-      //        The routing protocols should not maintain a pointer to
-      //        this object, so Dispose () shouldn't be necessary.
-      (*rprotoIter).second = 0;
-    }
-  m_routingProtocols.clear ();
-  m_ipv6 = 0;
-}
-
-Ptr<Ipv6Route>
-Ipv6ListRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
-{
-  NS_LOG_FUNCTION (this << header.GetDestinationAddress () << header.GetSourceAddress () << oif);
-  Ptr<Ipv6Route> route;
-
-  for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
-       i != m_routingProtocols.end (); i++)
-    {
-      NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
-      NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestinationAddress ());
-      route = (*i).second->RouteOutput (p, header, oif, sockerr);
-      if (route)
-        {
-          NS_LOG_LOGIC ("Found route " << route);
-          sockerr = Socket::ERROR_NOTERROR;
-          return route;
-        }
-    }
-  NS_LOG_LOGIC ("Done checking " << GetTypeId ());
-  NS_LOG_LOGIC ("");
-  sockerr = Socket::ERROR_NOROUTETOHOST;
-  return 0;
-}
-
-// Patterned after Linux ip_route_input and ip_route_input_slow
-bool 
-Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev, 
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb, 
-                             LocalDeliverCallback lcb, ErrorCallback ecb)
-{
-  bool retVal = false;
-  NS_LOG_FUNCTION (p << header << idev);
-  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
-
-  NS_ASSERT (m_ipv6 != 0);
-  // Check if input device supports IP 
-  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
-  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev); 
-  Ipv6Address dst = header.GetDestinationAddress ();
-
-  // Multicast recognition; handle local delivery here
-  //
-  if (dst.IsMulticast ())
-    {
-#ifdef NOTYET
-      if (m_ipv6->MulticastCheckGroup (iif, dst))
-#endif
-        if (true)
-          {
-            NS_LOG_LOGIC ("Multicast packet for me-- local deliver");
-            Ptr<Packet> packetCopy = p->Copy ();
-            // Here may want to disable lcb callback in recursive RouteInput
-            // call below
-            lcb (packetCopy, header, iif);
-            // Fall through-- we may also need to forward this
-            retVal = true;
-          }
-
-      /* do not forward link-local multicast address */
-      if (dst == Ipv6Address::GetAllNodesMulticast () || dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
-        {
-          return retVal;
-        }
-
-      for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-           m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end ();
-           rprotoIter++)
-        {
-          NS_LOG_LOGIC ("Multicast packet for me-- trying to forward");
-          if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
-            {
-              retVal = true;
-            }
-        }
-      return retVal;
-    }
-
-  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
-  // Right now, we will be permissive and allow a source to send us
-  // a packet to one of our other interface addresses; that is, the
-  // destination unicast address does not match one of the iif addresses,
-  // but we check our other interfaces.  This could be an option
-  // (to remove the outer loop immediately below and just check iif).
-  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
-    {
-      for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
-        {
-          Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
-          Ipv6Address addr = iaddr.GetAddress ();
-          if (addr.IsEqual (header.GetDestinationAddress ()))
-            {
-              if (j == iif)
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
-                }
-              else
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
-                }
-              lcb (p, header, iif);
-              return true;
-            }
-          NS_LOG_LOGIC ("Address "<< addr << " not a match");
-        }
-    }
-  // Check if input device supports IP forwarding
-  if (m_ipv6->IsForwarding (iif) == false)
-    {
-      NS_LOG_LOGIC ("Forwarding disabled for this interface");
-      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
-      return false;
-    }
-  // Next, try to find a route
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
-        {
-          return true;
-        }
-    }
-  // No routing protocol has found a route.  
-  return retVal;
-}
-
-void 
-Ipv6ListRouting::NotifyInterfaceUp (uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << interface);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyInterfaceUp (interface);
-    }  
-}
-void 
-Ipv6ListRouting::NotifyInterfaceDown (uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << interface);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyInterfaceDown (interface);
-    }  
-}
-void 
-Ipv6ListRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
-  NS_LOG_FUNCTION (this << interface << address);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyAddAddress (interface, address);
-    }  
-}
-void 
-Ipv6ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
-  NS_LOG_FUNCTION (this << interface << address);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyRemoveAddress (interface, address);
-    }  
-}
-
-void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
-  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
-    }
-}
-
-void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
-  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
-    }
-}
-
-void 
-Ipv6ListRouting::SetIpv6 (Ptr<Ipv6> ipv6)
-{
-  NS_LOG_FUNCTION (this << ipv6);
-  NS_ASSERT (m_ipv6 == 0);
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
-       m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end ();
-       rprotoIter++)
-    {
-      (*rprotoIter).second->SetIpv6 (ipv6);
-    }  
-  m_ipv6 = ipv6;
-}
-
-void
-Ipv6ListRouting::AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority)
-{
-  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
-  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
-  m_routingProtocols.sort ( Compare );
-  if (m_ipv6 != 0)
-    {
-      routingProtocol->SetIpv6 (m_ipv6);
-    }
-}
-
-uint32_t 
-Ipv6ListRouting::GetNRoutingProtocols (void) const
-{
-  NS_LOG_FUNCTION (this);
-  return m_routingProtocols.size (); 
-}
-
-Ptr<Ipv6RoutingProtocol> 
-Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
-{
-  NS_LOG_FUNCTION (index);
-  if (index > m_routingProtocols.size ())
-    {
-      NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol ():  index " << index << " out of range");
-    }
-  uint32_t i = 0;
-  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
-    {
-      if (i == index)
-        {
-          priority = (*rprotoIter).first;
-          return (*rprotoIter).second;
-        }
-    }
-  return 0;
-}
-
-bool 
-Ipv6ListRouting::Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b)
-{
-  return a.first > b.first;
-}
-
-
-} // namespace ns3
-
-
-#include "ns3/test.h"
-#include "ipv6-list-routing.h"
-#include "ns3/ipv6-routing-protocol.h"
-
-namespace ns3 {
-
-    class Ipv6ARouting : public Ipv6RoutingProtocol {
-    public:
-      Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
-      bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
-                        UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                        LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
-      void NotifyInterfaceUp (uint32_t interface) {}
-      void NotifyInterfaceDown (uint32_t interface) {}
-      void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
-      void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
-      void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
-                           GetZero ()) {}
-      void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
-      void SetIpv6 (Ptr<Ipv6> ipv6) {}
-    };
-
-    class Ipv6BRouting : public Ipv6RoutingProtocol {
-    public:
-      Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
-      bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
-                        UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                        LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
-      void NotifyInterfaceUp (uint32_t interface) {}
-      void NotifyInterfaceDown (uint32_t interface) {}
-      void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
-      void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
-      void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
-                           GetZero ()) {}
-      void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
-      void SetIpv6 (Ptr<Ipv6> ipv6) {}
-    };
-
-    class Ipv6ListRoutingNegativeTestCase : public TestCase
-    {
-  public:
-    Ipv6ListRoutingNegativeTestCase();
-    virtual bool DoRun (void);
-    };
-
-    Ipv6ListRoutingNegativeTestCase::Ipv6ListRoutingNegativeTestCase()
-      : TestCase("Check negative priorities")
-      {}
-    bool 
-      Ipv6ListRoutingNegativeTestCase::DoRun (void)
-        {
-          Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
-          Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
-          Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
-          // The Ipv6BRouting should be added with higher priority (larger integer value)
-          lr->AddRoutingProtocol (aRouting, -10);
-          lr->AddRoutingProtocol (bRouting, -5);
-          int16_t first = 3;
-          uint32_t num = lr->GetNRoutingProtocols ();
-          NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
-          Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
-          NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
-          NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
-
-          // XXX
-          return false;
-        }
-
-    class Ipv6ListRoutingPositiveTestCase : public TestCase
-    {
-  public:
-    Ipv6ListRoutingPositiveTestCase();
-    virtual bool DoRun (void);
-    };
-
-    Ipv6ListRoutingPositiveTestCase::Ipv6ListRoutingPositiveTestCase()
-      : TestCase("Check positive priorities")
-      {}
-    bool 
-      Ipv6ListRoutingPositiveTestCase::DoRun (void)
-        {
-          Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
-          Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
-          Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
-          // The Ipv6ARouting should be added with higher priority (larger integer 
-          // value) and will be fetched first below
-          lr->AddRoutingProtocol (aRouting, 10);
-          lr->AddRoutingProtocol (bRouting, 5);
-          int16_t first = 3;
-          int16_t second = 3;
-          uint32_t num = lr->GetNRoutingProtocols ();
-          NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
-          Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
-          NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
-          NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
-          Ptr<Ipv6RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
-          NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
-          NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
-
-          // XXX
-          return false;
-        }
-
-    static class Ipv6ListRoutingTestSuite : public TestSuite
-    {
-  public:
-    Ipv6ListRoutingTestSuite()
-      : TestSuite("ipv6-list-routing", UNIT)
-      {
-        AddTestCase(new Ipv6ListRoutingPositiveTestCase());
-        AddTestCase(new Ipv6ListRoutingNegativeTestCase());
-      }
-
-    } g_ipv6ListRoutingTestSuite;
-
-} // namespace ns3
--- a/src/routing/list-routing/ipv6-list-routing.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * 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 IPV6_LIST_ROUTING_H
-#define IPV6_LIST_ROUTING_H
-
-#include <list>
-#include "ns3/ipv6-routing-protocol.h"
-
-namespace ns3 {
-
-/**
- * \ingroup routing 
- * \defgroup ipv6ListRouting Ipv6 List Routing
- */
-
-/**
- * \ingroup ipv6ListRouting
- * \class Ipv6ListRouting
- * \brief Hold list of Ipv6RoutingProtocol objects.
- *
- * This class is a specialization of Ipv6RoutingProtocol that allows 
- * other instances of Ipv6RoutingProtocol to be inserted in a 
- * prioritized list.  Routing protocols in the list are consulted one
- * by one, from highest to lowest priority, until a routing protocol
- * is found that will take the packet (this corresponds to a non-zero
- * return value to RouteOutput, or a return value of true to RouteInput).
- * The order by which routing protocols with the same priority value 
- * are consulted is undefined.
- * 
- */
-class Ipv6ListRouting : public Ipv6RoutingProtocol
-{
-public:
-  /**
-   * \brief Get the type ID of this class.
-   * \return type ID
-   */
-  static TypeId GetTypeId (void);
-
-  /**
-   * \brief Constructor.
-   */
-  Ipv6ListRouting ();  
-
-  /**
-   * \brief Destructor.
-   */
-  virtual ~Ipv6ListRouting ();  
-
-  /**
-   * \brief Register a new routing protocol to be used in this IPv4 stack
-   * \param routingProtocol new routing protocol implementation object
-   * \param priority priority to give to this routing protocol.
-   * Values may range between -32768 and +32767.  
-   */
-  virtual void AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority);
-
-  /**
-   * \brief Get the number of routing protocols.
-   * \return number of routing protocols in the list
-   */
-  virtual uint32_t GetNRoutingProtocols (void) const;
-
-  /**
-   * \brief Get pointer to routing protocol stored at index, 
-   *
-   * The first protocol (index 0) the highest priority, the next one (index 1)
-   * the second highest priority, and so on.  The priority parameter is an
-   * output parameter and it returns the integer priority of the protocol.
-   * \param index index of protocol to return
-   * \param priority output parameter, set to the priority of the protocol
-   * being returned
-   * \return pointer to routing protocol indexed by 
-   */
-  virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
-
-  // Below are from Ipv6RoutingProtocol
-  virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
-  virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
-                           UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                           LocalDeliverCallback lcb, ErrorCallback ecb);
-  virtual void NotifyInterfaceUp (uint32_t interface);
-  virtual void NotifyInterfaceDown (uint32_t interface);
-  virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
-  virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
-  virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
-  virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
-  virtual void SetIpv6 (Ptr<Ipv6> ipv6);
-
-protected:
-  /**
-   * \brief Dispose this object.
-   */
-  void DoDispose (void);
-
-private:
-  typedef std::pair<int16_t, Ptr<Ipv6RoutingProtocol> > Ipv6RoutingProtocolEntry;
-  typedef std::list<Ipv6RoutingProtocolEntry> Ipv6RoutingProtocolList;
-
-  /**
-   * \brief Compare two routing protocols.
-   * \param a first object to compare
-   * \param b second object to compare
-   * \return true if they are the same, false otherwise
-   */
-  static bool Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b);
-
-  /**
-   * \brief List of routing protocols.
-   */
-  Ipv6RoutingProtocolList m_routingProtocols;
-
-  /**
-   * \brief Ipv6 reference.
-   */
-  Ptr<Ipv6> m_ipv6;
-};
-
-} //namespace ns3
-
-#endif /* IPV6_LIST_ROUTING_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv4-list-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,394 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/node.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ipv4-list-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
+
+TypeId
+Ipv4ListRouting::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
+    .SetParent<Ipv4RoutingProtocol> ()
+    .AddConstructor<Ipv4ListRouting> ()
+    ;
+  return tid;
+}
+
+
+Ipv4ListRouting::Ipv4ListRouting () 
+ : m_ipv4 (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv4ListRouting::~Ipv4ListRouting () 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv4ListRouting::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++)
+    {
+      // Note:  Calling dispose on these protocols causes memory leak
+      //        The routing protocols should not maintain a pointer to
+      //        this object, so Dispose() shouldn't be necessary.
+      (*rprotoIter).second = 0;
+    }
+  m_routingProtocols.clear ();
+  m_ipv4 = 0;
+}
+
+void
+Ipv4ListRouting::DoStart (void)
+{
+  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++)
+    {
+      Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
+      protocol->Start ();
+    }
+  Ipv4RoutingProtocol::DoStart ();
+}
+
+
+Ptr<Ipv4Route>
+Ipv4ListRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
+{
+  NS_LOG_FUNCTION (this << header.GetDestination () << " " << header.GetSource () << " " << oif);
+  Ptr<Ipv4Route> route;
+
+  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+       i != m_routingProtocols.end (); i++)
+    {
+      NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
+      NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
+      route = (*i).second->RouteOutput (p, header, oif, sockerr);
+      if (route)
+        {
+          NS_LOG_LOGIC ("Found route " << route);
+          sockerr = Socket::ERROR_NOTERROR;
+          return route;
+        }
+    }
+  NS_LOG_LOGIC ("Done checking " << GetTypeId ());
+  NS_LOG_LOGIC ("");
+  sockerr = Socket::ERROR_NOROUTETOHOST;
+  return 0;
+}
+
+// Patterned after Linux ip_route_input and ip_route_input_slow
+bool 
+Ipv4ListRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, 
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb, 
+                             LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+  bool retVal = false;
+  NS_LOG_FUNCTION (p << header << idev);
+  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject<Node> ()->GetId ());
+
+  NS_ASSERT (m_ipv4 != 0);
+  // Check if input device supports IP 
+  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); 
+
+  retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif);
+  if (retVal == true)
+    {
+      NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery");
+      if (header.GetDestination ().IsMulticast ())
+        {
+          Ptr<Packet> packetCopy = p->Copy();
+          lcb (packetCopy, header, iif);
+          retVal = true;
+          // Fall through
+        }
+      else
+        {
+          lcb (p, header, iif);
+          return true;
+        }
+    }
+  // Check if input device supports IP forwarding
+  if (m_ipv4->IsForwarding (iif) == false)
+    {
+      NS_LOG_LOGIC ("Forwarding disabled for this interface");
+      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+      return false;
+    }
+  // Next, try to find a route
+  // If we have already delivered a packet locally (e.g. multicast)
+  // we suppress further downstream local delivery by nulling the callback
+  LocalDeliverCallback downstreamLcb = lcb;
+  if (retVal == true)
+    {
+      downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > ();
+    }
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb))
+        {
+          NS_LOG_LOGIC ("Route found to forward packet in protocol " << (*rprotoIter).second->GetInstanceTypeId ().GetName ()); 
+          return true;
+        }
+    }
+  // No routing protocol has found a route.  
+  return retVal;
+}
+
+void 
+Ipv4ListRouting::NotifyInterfaceUp (uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyInterfaceUp (interface);
+    }  
+}
+void 
+Ipv4ListRouting::NotifyInterfaceDown (uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyInterfaceDown (interface);
+    }  
+}
+void 
+Ipv4ListRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION(this << interface << address);
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyAddAddress (interface, address);
+    }  
+}
+void 
+Ipv4ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION(this << interface << address);
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyRemoveAddress (interface, address);
+    }  
+}
+void 
+Ipv4ListRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+  NS_LOG_FUNCTION(this << ipv4);
+  NS_ASSERT (m_ipv4 == 0);
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->SetIpv4 (ipv4);
+    }  
+  m_ipv4 = ipv4;
+}
+
+void
+Ipv4ListRouting::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority)
+{
+  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
+  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
+  m_routingProtocols.sort ( Compare );
+  if (m_ipv4 != 0)
+    {
+      routingProtocol->SetIpv4 (m_ipv4);
+    }
+}
+
+uint32_t 
+Ipv4ListRouting::GetNRoutingProtocols (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_routingProtocols.size (); 
+}
+
+Ptr<Ipv4RoutingProtocol> 
+Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
+{
+  NS_LOG_FUNCTION (index);
+  if (index > m_routingProtocols.size ())
+    {
+      NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol():  index " << index << " out of range");
+    }
+  uint32_t i = 0;
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
+    {
+      if (i == index)
+        {
+          priority = (*rprotoIter).first;
+          return (*rprotoIter).second;
+        }
+    }
+  return 0;
+}
+
+bool 
+Ipv4ListRouting::Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b)
+{
+  return a.first > b.first;
+}
+
+
+} // namespace ns3
+
+#include "ns3/test.h"
+#include "ipv4-list-routing.h"
+#include "ns3/ipv4-routing-protocol.h"
+
+namespace ns3 {
+
+class Ipv4ARouting : public Ipv4RoutingProtocol {
+public:
+  Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
+  bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                             LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+  void NotifyInterfaceUp (uint32_t interface) {}
+  void NotifyInterfaceDown (uint32_t interface) {}
+  void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+  void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+  void SetIpv4 (Ptr<Ipv4> ipv4) {}
+};
+
+class Ipv4BRouting : public Ipv4RoutingProtocol {
+public:
+  Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
+  bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                             LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+  void NotifyInterfaceUp (uint32_t interface) {}
+  void NotifyInterfaceDown (uint32_t interface) {}
+  void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+  void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+  void SetIpv4 (Ptr<Ipv4> ipv4) {}
+};
+
+class Ipv4ListRoutingNegativeTestCase : public TestCase
+{
+public:
+  Ipv4ListRoutingNegativeTestCase();
+  virtual bool DoRun (void);
+};
+
+Ipv4ListRoutingNegativeTestCase::Ipv4ListRoutingNegativeTestCase()
+  : TestCase("Check negative priorities")
+{}
+bool 
+Ipv4ListRoutingNegativeTestCase::DoRun (void)
+{
+  Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
+  Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
+  Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
+  // The Ipv4BRouting should be added with higher priority (larger integer value)
+  lr->AddRoutingProtocol (aRouting, -10);
+  lr->AddRoutingProtocol (bRouting, -5);
+  int16_t first = 3;
+  uint32_t num = lr->GetNRoutingProtocols ();
+  NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+  Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+  NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
+  NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
+
+  // XXX
+  return false;
+}
+
+class Ipv4ListRoutingPositiveTestCase : public TestCase
+{
+public:
+  Ipv4ListRoutingPositiveTestCase();
+  virtual bool DoRun (void);
+};
+
+Ipv4ListRoutingPositiveTestCase::Ipv4ListRoutingPositiveTestCase()
+  : TestCase("Check positive priorities")
+{}
+bool 
+Ipv4ListRoutingPositiveTestCase::DoRun (void)
+{
+  Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
+  Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
+  Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
+  // The Ipv4ARouting should be added with higher priority (larger integer 
+  // value) and will be fetched first below
+  lr->AddRoutingProtocol (aRouting, 10);
+  lr->AddRoutingProtocol (bRouting, 5);
+  int16_t first = 3;
+  int16_t second = 3;
+  uint32_t num = lr->GetNRoutingProtocols ();
+  NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+  Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+  NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
+  NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
+  Ptr<Ipv4RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
+  NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
+  NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
+  
+  // XXX
+  return false;
+}
+
+static class Ipv4ListRoutingTestSuite : public TestSuite
+{
+public:
+  Ipv4ListRoutingTestSuite()
+    : TestSuite("ipv4-list-routing", UNIT)
+  {
+    AddTestCase(new Ipv4ListRoutingPositiveTestCase());
+    AddTestCase(new Ipv4ListRoutingNegativeTestCase());
+  }
+
+} g_ipv4ListRoutingTestSuite;
+
+} // namespace ns3
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv4-list-routing.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,103 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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 IPV4_LIST_ROUTING_H
+#define IPV4_LIST_ROUTING_H
+
+#include <list>
+#include "ns3/ipv4-routing-protocol.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing 
+ * \defgroup ipv4ListRouting Ipv4 List Routing
+ */
+/**
+ * \ingroup ipv4ListRouting
+ *
+ * This class is a specialization of Ipv4RoutingProtocol that allows 
+ * other instances of Ipv4RoutingProtocol to be inserted in a 
+ * prioritized list.  Routing protocols in the list are consulted one
+ * by one, from highest to lowest priority, until a routing protocol
+ * is found that will take the packet (this corresponds to a non-zero
+ * return value to RouteOutput, or a return value of true to RouteInput).
+ * The order by which routing protocols with the same priority value 
+ * are consulted is undefined.
+ * 
+ */
+class Ipv4ListRouting : public Ipv4RoutingProtocol
+{
+public:
+  static TypeId GetTypeId (void);
+
+  Ipv4ListRouting ();  
+  virtual ~Ipv4ListRouting ();  
+
+  /**
+   * \brief Register a new routing protocol to be used in this IPv4 stack
+   *
+   * \param routingProtocol new routing protocol implementation object
+   * \param priority priority to give to this routing protocol.
+   * Values may range between -32768 and +32767.  
+   */
+  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority);
+  /**
+   * \return number of routing protocols in the list
+   */
+  virtual uint32_t GetNRoutingProtocols (void) const;
+  /**
+   * Return pointer to routing protocol stored at index, with the
+   * first protocol (index 0) the highest priority, the next one (index 1)
+   * the second highest priority, and so on.  The priority parameter is an
+   * output parameter and it returns the integer priority of the protocol.
+   * 
+   * \return pointer to routing protocol indexed by 
+   * \param index index of protocol to return
+   * \param priority output parameter, set to the priority of the protocol
+            being returned
+   */
+  virtual Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
+
+  // Below are from Ipv4RoutingProtocol
+  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+  virtual bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+                           UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                           LocalDeliverCallback lcb, ErrorCallback ecb);
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+protected:
+  void DoDispose (void);
+  void DoStart (void);
+private:
+  typedef std::pair<int16_t, Ptr<Ipv4RoutingProtocol> > Ipv4RoutingProtocolEntry;
+  typedef std::list<Ipv4RoutingProtocolEntry> Ipv4RoutingProtocolList;
+  Ipv4RoutingProtocolList m_routingProtocols;
+  static bool Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b);
+  Ptr<Ipv4> m_ipv4;
+
+};
+
+} //namespace ns3
+
+#endif /* IPV4_LIST_ROUTING_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv6-list-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,452 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/node.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ipv6-list-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
+
+TypeId
+Ipv6ListRouting::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
+    .SetParent<Ipv6RoutingProtocol> ()
+    .AddConstructor<Ipv6ListRouting> ()
+    ;
+  return tid;
+}
+
+
+Ipv6ListRouting::Ipv6ListRouting () 
+  : m_ipv6 (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ListRouting::~Ipv6ListRouting () 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv6ListRouting::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++)
+    {
+      // Note:  Calling dispose on these protocols causes memory leak
+      //        The routing protocols should not maintain a pointer to
+      //        this object, so Dispose () shouldn't be necessary.
+      (*rprotoIter).second = 0;
+    }
+  m_routingProtocols.clear ();
+  m_ipv6 = 0;
+}
+
+Ptr<Ipv6Route>
+Ipv6ListRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
+{
+  NS_LOG_FUNCTION (this << header.GetDestinationAddress () << header.GetSourceAddress () << oif);
+  Ptr<Ipv6Route> route;
+
+  for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+       i != m_routingProtocols.end (); i++)
+    {
+      NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
+      NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestinationAddress ());
+      route = (*i).second->RouteOutput (p, header, oif, sockerr);
+      if (route)
+        {
+          NS_LOG_LOGIC ("Found route " << route);
+          sockerr = Socket::ERROR_NOTERROR;
+          return route;
+        }
+    }
+  NS_LOG_LOGIC ("Done checking " << GetTypeId ());
+  NS_LOG_LOGIC ("");
+  sockerr = Socket::ERROR_NOROUTETOHOST;
+  return 0;
+}
+
+// Patterned after Linux ip_route_input and ip_route_input_slow
+bool 
+Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev, 
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb, 
+                             LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+  bool retVal = false;
+  NS_LOG_FUNCTION (p << header << idev);
+  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
+
+  NS_ASSERT (m_ipv6 != 0);
+  // Check if input device supports IP 
+  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev); 
+  Ipv6Address dst = header.GetDestinationAddress ();
+
+  // Multicast recognition; handle local delivery here
+  //
+  if (dst.IsMulticast ())
+    {
+#ifdef NOTYET
+      if (m_ipv6->MulticastCheckGroup (iif, dst))
+#endif
+        if (true)
+          {
+            NS_LOG_LOGIC ("Multicast packet for me-- local deliver");
+            Ptr<Packet> packetCopy = p->Copy ();
+            // Here may want to disable lcb callback in recursive RouteInput
+            // call below
+            lcb (packetCopy, header, iif);
+            // Fall through-- we may also need to forward this
+            retVal = true;
+          }
+
+      /* do not forward link-local multicast address */
+      if (dst == Ipv6Address::GetAllNodesMulticast () || dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+        {
+          return retVal;
+        }
+
+      for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+           m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end ();
+           rprotoIter++)
+        {
+          NS_LOG_LOGIC ("Multicast packet for me-- trying to forward");
+          if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
+            {
+              retVal = true;
+            }
+        }
+      return retVal;
+    }
+
+  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
+  // Right now, we will be permissive and allow a source to send us
+  // a packet to one of our other interface addresses; that is, the
+  // destination unicast address does not match one of the iif addresses,
+  // but we check our other interfaces.  This could be an option
+  // (to remove the outer loop immediately below and just check iif).
+  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
+    {
+      for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
+        {
+          Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
+          Ipv6Address addr = iaddr.GetAddress ();
+          if (addr.IsEqual (header.GetDestinationAddress ()))
+            {
+              if (j == iif)
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
+                }
+              lcb (p, header, iif);
+              return true;
+            }
+          NS_LOG_LOGIC ("Address "<< addr << " not a match");
+        }
+    }
+  // Check if input device supports IP forwarding
+  if (m_ipv6->IsForwarding (iif) == false)
+    {
+      NS_LOG_LOGIC ("Forwarding disabled for this interface");
+      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+      return false;
+    }
+  // Next, try to find a route
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
+        {
+          return true;
+        }
+    }
+  // No routing protocol has found a route.  
+  return retVal;
+}
+
+void 
+Ipv6ListRouting::NotifyInterfaceUp (uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyInterfaceUp (interface);
+    }  
+}
+void 
+Ipv6ListRouting::NotifyInterfaceDown (uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyInterfaceDown (interface);
+    }  
+}
+void 
+Ipv6ListRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << interface << address);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyAddAddress (interface, address);
+    }  
+}
+void 
+Ipv6ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << interface << address);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyRemoveAddress (interface, address);
+    }  
+}
+
+void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
+    }
+}
+
+void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
+    }
+}
+
+void 
+Ipv6ListRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+  NS_LOG_FUNCTION (this << ipv6);
+  NS_ASSERT (m_ipv6 == 0);
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+       m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end ();
+       rprotoIter++)
+    {
+      (*rprotoIter).second->SetIpv6 (ipv6);
+    }  
+  m_ipv6 = ipv6;
+}
+
+void
+Ipv6ListRouting::AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority)
+{
+  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
+  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
+  m_routingProtocols.sort ( Compare );
+  if (m_ipv6 != 0)
+    {
+      routingProtocol->SetIpv6 (m_ipv6);
+    }
+}
+
+uint32_t 
+Ipv6ListRouting::GetNRoutingProtocols (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_routingProtocols.size (); 
+}
+
+Ptr<Ipv6RoutingProtocol> 
+Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
+{
+  NS_LOG_FUNCTION (index);
+  if (index > m_routingProtocols.size ())
+    {
+      NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol ():  index " << index << " out of range");
+    }
+  uint32_t i = 0;
+  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
+    {
+      if (i == index)
+        {
+          priority = (*rprotoIter).first;
+          return (*rprotoIter).second;
+        }
+    }
+  return 0;
+}
+
+bool 
+Ipv6ListRouting::Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b)
+{
+  return a.first > b.first;
+}
+
+
+} // namespace ns3
+
+
+#include "ns3/test.h"
+#include "ipv6-list-routing.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3 {
+
+    class Ipv6ARouting : public Ipv6RoutingProtocol {
+    public:
+      Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
+      bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                        UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                        LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+      void NotifyInterfaceUp (uint32_t interface) {}
+      void NotifyInterfaceDown (uint32_t interface) {}
+      void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+      void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+      void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
+                           GetZero ()) {}
+      void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
+      void SetIpv6 (Ptr<Ipv6> ipv6) {}
+    };
+
+    class Ipv6BRouting : public Ipv6RoutingProtocol {
+    public:
+      Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)  { return 0;}
+      bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                        UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                        LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+      void NotifyInterfaceUp (uint32_t interface) {}
+      void NotifyInterfaceDown (uint32_t interface) {}
+      void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+      void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+      void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
+                           GetZero ()) {}
+      void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
+      void SetIpv6 (Ptr<Ipv6> ipv6) {}
+    };
+
+    class Ipv6ListRoutingNegativeTestCase : public TestCase
+    {
+  public:
+    Ipv6ListRoutingNegativeTestCase();
+    virtual bool DoRun (void);
+    };
+
+    Ipv6ListRoutingNegativeTestCase::Ipv6ListRoutingNegativeTestCase()
+      : TestCase("Check negative priorities")
+      {}
+    bool 
+      Ipv6ListRoutingNegativeTestCase::DoRun (void)
+        {
+          Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
+          Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
+          Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
+          // The Ipv6BRouting should be added with higher priority (larger integer value)
+          lr->AddRoutingProtocol (aRouting, -10);
+          lr->AddRoutingProtocol (bRouting, -5);
+          int16_t first = 3;
+          uint32_t num = lr->GetNRoutingProtocols ();
+          NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+          Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+          NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
+          NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
+
+          // XXX
+          return false;
+        }
+
+    class Ipv6ListRoutingPositiveTestCase : public TestCase
+    {
+  public:
+    Ipv6ListRoutingPositiveTestCase();
+    virtual bool DoRun (void);
+    };
+
+    Ipv6ListRoutingPositiveTestCase::Ipv6ListRoutingPositiveTestCase()
+      : TestCase("Check positive priorities")
+      {}
+    bool 
+      Ipv6ListRoutingPositiveTestCase::DoRun (void)
+        {
+          Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
+          Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
+          Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
+          // The Ipv6ARouting should be added with higher priority (larger integer 
+          // value) and will be fetched first below
+          lr->AddRoutingProtocol (aRouting, 10);
+          lr->AddRoutingProtocol (bRouting, 5);
+          int16_t first = 3;
+          int16_t second = 3;
+          uint32_t num = lr->GetNRoutingProtocols ();
+          NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+          Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+          NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
+          NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
+          Ptr<Ipv6RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
+          NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
+          NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
+
+          // XXX
+          return false;
+        }
+
+    static class Ipv6ListRoutingTestSuite : public TestSuite
+    {
+  public:
+    Ipv6ListRoutingTestSuite()
+      : TestSuite("ipv6-list-routing", UNIT)
+      {
+        AddTestCase(new Ipv6ListRoutingPositiveTestCase());
+        AddTestCase(new Ipv6ListRoutingNegativeTestCase());
+      }
+
+    } g_ipv6ListRoutingTestSuite;
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv6-list-routing.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,139 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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 IPV6_LIST_ROUTING_H
+#define IPV6_LIST_ROUTING_H
+
+#include <list>
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing 
+ * \defgroup ipv6ListRouting Ipv6 List Routing
+ */
+
+/**
+ * \ingroup ipv6ListRouting
+ * \class Ipv6ListRouting
+ * \brief Hold list of Ipv6RoutingProtocol objects.
+ *
+ * This class is a specialization of Ipv6RoutingProtocol that allows 
+ * other instances of Ipv6RoutingProtocol to be inserted in a 
+ * prioritized list.  Routing protocols in the list are consulted one
+ * by one, from highest to lowest priority, until a routing protocol
+ * is found that will take the packet (this corresponds to a non-zero
+ * return value to RouteOutput, or a return value of true to RouteInput).
+ * The order by which routing protocols with the same priority value 
+ * are consulted is undefined.
+ * 
+ */
+class Ipv6ListRouting : public Ipv6RoutingProtocol
+{
+public:
+  /**
+   * \brief Get the type ID of this class.
+   * \return type ID
+   */
+  static TypeId GetTypeId (void);
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6ListRouting ();  
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6ListRouting ();  
+
+  /**
+   * \brief Register a new routing protocol to be used in this IPv4 stack
+   * \param routingProtocol new routing protocol implementation object
+   * \param priority priority to give to this routing protocol.
+   * Values may range between -32768 and +32767.  
+   */
+  virtual void AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority);
+
+  /**
+   * \brief Get the number of routing protocols.
+   * \return number of routing protocols in the list
+   */
+  virtual uint32_t GetNRoutingProtocols (void) const;
+
+  /**
+   * \brief Get pointer to routing protocol stored at index, 
+   *
+   * The first protocol (index 0) the highest priority, the next one (index 1)
+   * the second highest priority, and so on.  The priority parameter is an
+   * output parameter and it returns the integer priority of the protocol.
+   * \param index index of protocol to return
+   * \param priority output parameter, set to the priority of the protocol
+   * being returned
+   * \return pointer to routing protocol indexed by 
+   */
+  virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
+
+  // Below are from Ipv6RoutingProtocol
+  virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+  virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                           UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                           LocalDeliverCallback lcb, ErrorCallback ecb);
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+  virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+  virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+  virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+protected:
+  /**
+   * \brief Dispose this object.
+   */
+  void DoDispose (void);
+
+private:
+  typedef std::pair<int16_t, Ptr<Ipv6RoutingProtocol> > Ipv6RoutingProtocolEntry;
+  typedef std::list<Ipv6RoutingProtocolEntry> Ipv6RoutingProtocolList;
+
+  /**
+   * \brief Compare two routing protocols.
+   * \param a first object to compare
+   * \param b second object to compare
+   * \return true if they are the same, false otherwise
+   */
+  static bool Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b);
+
+  /**
+   * \brief List of routing protocols.
+   */
+  Ipv6RoutingProtocolList m_routingProtocols;
+
+  /**
+   * \brief Ipv6 reference.
+   */
+  Ptr<Ipv6> m_ipv6;
+};
+
+} //namespace ns3
+
+#endif /* IPV6_LIST_ROUTING_H */
+
--- a/src/routing/list-routing/wscript	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/list-routing/wscript	Tue Oct 26 18:02:17 2010 +0100
@@ -3,13 +3,17 @@
 def build(bld):
     module = bld.create_ns3_module('list-routing', ['node'])
     module.source = [
-        'ipv4-list-routing.cc',
-        'ipv6-list-routing.cc',
+        'model/ipv4-list-routing.cc',
+        'model/ipv6-list-routing.cc',
+        'helper/ipv4-list-routing-helper.cc',
+        'helper/ipv6-list-routing-helper.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'list-routing'
     headers.source = [
-        'ipv4-list-routing.h',
-        'ipv6-list-routing.h',
+        'model/ipv4-list-routing.h',
+        'model/ipv6-list-routing.h',
+        'helper/ipv4-list-routing-helper.h',
+        'helper/ipv6-list-routing-helper.h',
         ]
 
--- a/src/routing/olsr/examples/olsr-hna.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/olsr/examples/olsr-hna.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -60,6 +60,8 @@
 #include "ns3/ipv4-list-routing.h"
 #include "ns3/olsr-routing-protocol.h"
 #include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 #include <iostream>
 #include <fstream>
--- a/src/routing/olsr/examples/simple-point-to-point-olsr.cc	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/olsr/examples/simple-point-to-point-olsr.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -45,6 +45,8 @@
 #include "ns3/node-module.h"
 #include "ns3/helper-module.h"
 #include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
 
 using namespace ns3;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv4-static-routing-helper.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,210 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <vector>
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/assert.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ipv4-static-routing-helper.h"
+
+NS_LOG_COMPONENT_DEFINE("Ipv4StaticRoutingHelper");
+
+namespace ns3 {
+
+Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper()
+{}
+
+Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &o)
+{
+}
+
+Ipv4StaticRoutingHelper* 
+Ipv4StaticRoutingHelper::Copy (void) const 
+{
+  return new Ipv4StaticRoutingHelper (*this); 
+}
+
+Ptr<Ipv4RoutingProtocol> 
+Ipv4StaticRoutingHelper::Create (Ptr<Node> node) const
+{
+  return CreateObject<Ipv4StaticRouting> ();
+}
+
+
+Ptr<Ipv4StaticRouting>
+Ipv4StaticRoutingHelper::GetStaticRouting (Ptr<Ipv4> ipv4) const
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Ipv4RoutingProtocol> ipv4rp = ipv4->GetRoutingProtocol ();
+  NS_ASSERT_MSG (ipv4rp, "No routing protocol associated with Ipv4");
+  if (DynamicCast<Ipv4StaticRouting> (ipv4rp))
+    {
+      NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
+      return DynamicCast<Ipv4StaticRouting> (ipv4rp); 
+    } 
+  if (DynamicCast<Ipv4ListRouting> (ipv4rp))
+    {
+      Ptr<Ipv4ListRouting> lrp = DynamicCast<Ipv4ListRouting> (ipv4rp);
+      int16_t priority;
+      for (uint32_t i = 0; i < lrp->GetNRoutingProtocols ();  i++)
+        {
+          NS_LOG_LOGIC ("Searching for static routing in list");
+          Ptr<Ipv4RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
+          if (DynamicCast<Ipv4StaticRouting> (temp))
+            {
+              NS_LOG_LOGIC ("Found static routing in list");
+              return DynamicCast<Ipv4StaticRouting> (temp);
+            }
+        }
+    }
+  NS_LOG_LOGIC ("Static routing not found");
+  return 0;
+}
+
+void  
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+  Ptr<Node> n,
+  Ipv4Address source, 
+  Ipv4Address group,  
+  Ptr<NetDevice> input, 
+  NetDeviceContainer output)
+{
+  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
+
+  // We need to convert the NetDeviceContainer to an array of interface 
+  // numbers
+  std::vector<uint32_t> outputInterfaces;
+  for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
+    {
+      Ptr<NetDevice> nd = *i;
+      int32_t interface = ipv4->GetInterfaceForDevice (nd);
+      NS_ASSERT_MSG(interface >= 0, 
+        "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
+        "Expected an interface associated with the device nd");
+      outputInterfaces.push_back(interface);
+    }
+
+  int32_t inputInterface = ipv4->GetInterfaceForDevice (input);
+  NS_ASSERT_MSG(inputInterface >= 0, 
+    "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
+    "Expected an interface associated with the device input");
+  Ipv4StaticRoutingHelper helper;
+  Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
+  if (!ipv4StaticRouting)
+    {
+  NS_ASSERT_MSG (ipv4StaticRouting, 
+    "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
+    "Expected an Ipv4StaticRouting associated with this node");
+    }
+  ipv4StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
+}
+
+void  
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+  Ptr<Node> n,
+  Ipv4Address source, 
+  Ipv4Address group,  
+  std::string inputName, 
+  NetDeviceContainer output)
+{
+  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+  AddMulticastRoute (n, source, group, input, output);
+}
+
+void  
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+  std::string nName,
+  Ipv4Address source, 
+  Ipv4Address group,  
+  Ptr<NetDevice> input, 
+  NetDeviceContainer output)
+{
+  Ptr<Node> n = Names::Find<Node> (nName);
+  AddMulticastRoute (n, source, group, input, output);
+}
+
+void  
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+  std::string nName,
+  Ipv4Address source, 
+  Ipv4Address group,  
+  std::string inputName, 
+  NetDeviceContainer output)
+{
+  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+  Ptr<Node> n = Names::Find<Node> (nName);
+  AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+  Ptr<Node> n, 
+  Ptr<NetDevice> nd)
+{
+  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
+  int32_t interfaceSrc = ipv4->GetInterfaceForDevice (nd);
+  NS_ASSERT_MSG(interfaceSrc >= 0, 
+    "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
+    "Expected an interface associated with the device");
+  Ipv4StaticRoutingHelper helper;
+  Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
+  if (!ipv4StaticRouting)
+    {
+      NS_ASSERT_MSG (ipv4StaticRouting, 
+        "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
+        "Expected an Ipv4StaticRouting associated with this node");
+    }
+  ipv4StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+  Ptr<Node> n, 
+  std::string ndName)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+  std::string nName, 
+  Ptr<NetDevice> nd)
+{
+  Ptr<Node> n = Names::Find<Node> (nName);
+  SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+  std::string nName, 
+  std::string ndName)
+{
+  Ptr<Node> n = Names::Find<Node> (nName);
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  SetDefaultMulticastRoute (n, nd);
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv4-static-routing-helper.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,169 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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 IPV4_STATIC_ROUTING_HELPER_H
+#define IPV4_STATIC_ROUTING_HELPER_H
+
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv4-routing-helper.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv4StaticRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv4StaticRoutingHelper : public Ipv4RoutingHelper
+{
+public:
+  /*
+   * Construct an Ipv4StaticRoutingHelper object, used to make configuration
+   * of static routing easier.
+   */
+  Ipv4StaticRoutingHelper ();
+
+  /**
+   * \brief Construct an Ipv4StaticRoutingHelper from another previously 
+   * initialized instance (Copy Constructor).
+   */
+  Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &);
+
+  /**
+   * \internal
+   * \returns pointer to clone of this Ipv4StaticRoutingHelper
+   *
+   * This method is mainly for internal use by the other helpers;
+   * clients are expected to free the dynamic memory allocated by this method
+   */
+  Ipv4StaticRoutingHelper* Copy (void) const;
+
+  /**
+   * \param node the node on which the routing protocol will run
+   * \returns a newly-created routing protocol
+   *
+   * This method will be called by ns3::InternetStackHelper::Install
+   */
+  virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+
+  /**
+   * Try and find the static routing protocol as either the main routing
+   * protocol or in the list of routing protocols associated with the 
+   * Ipv4 provided.
+   *
+   * \param ipv4 the Ptr<Ipv4> to search for the static routing protocol
+   */
+  Ptr<Ipv4StaticRouting> GetStaticRouting (Ptr<Ipv4> ipv4) const;
+
+  /**
+   * \brief Add a multicast route to a node and net device using explicit 
+   * Ptr<Node> and Ptr<NetDevice>
+   */
+  void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,  
+    Ptr<NetDevice> input, NetDeviceContainer output);
+
+  /**
+   * \brief Add a multicast route to a node and device using a name string 
+   * previously associated to the node using the Object Name Service and a
+   * Ptr<NetDevice>
+   */
+  void AddMulticastRoute (std::string n, Ipv4Address source, Ipv4Address group,  
+    Ptr<NetDevice> input, NetDeviceContainer output);
+
+  /**
+   * \brief Add a multicast route to a node and device using a Ptr<Node> and a 
+   * name string previously associated to the device using the Object Name Service.
+   */
+  void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,  
+    std::string inputName, NetDeviceContainer output);
+
+  /**
+   * \brief Add a multicast route to a node and device using name strings
+   * previously associated to both the node and device using the Object Name 
+   * Service.
+   */
+  void AddMulticastRoute (std::string nName, Ipv4Address source, Ipv4Address group,  
+    std::string inputName, NetDeviceContainer output);
+
+  /**
+   * \brief Add a default route to the static routing protocol to forward
+   *        packets out a particular interface
+   *
+   * Functionally equivalent to:
+   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+   * \param n node
+   * \param nd device of the node to add default route
+   */
+  void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
+
+  /**
+   * \brief Add a default route to the static routing protocol to forward
+   *        packets out a particular interface
+   *
+   * Functionally equivalent to:
+   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+   * \param n node
+   * \param ndName string with name previously associated to device using the 
+   *        Object Name Service
+   */
+  void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
+
+  /**
+   * \brief Add a default route to the static routing protocol to forward
+   *        packets out a particular interface
+   *
+   * Functionally equivalent to:
+   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+   * \param nName string with name previously associated to node using the 
+   *        Object Name Service
+   * \param nd device of the node to add default route
+   */
+  void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
+
+  /**
+   * \brief Add a default route to the static routing protocol to forward
+   *        packets out a particular interface
+   *
+   * Functionally equivalent to:
+   * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+   * \param nName string with name previously associated to node using the 
+   *        Object Name Service
+   * \param ndName string with name previously associated to device using the 
+   *        Object Name Service
+   */
+  void SetDefaultMulticastRoute (std::string nName, std::string ndName);
+private:
+  /**
+   * \internal
+   * \brief Assignment operator declared private and not implemented to disallow
+   * assignment and prevent the compiler from happily inserting its own.
+   */
+  Ipv4StaticRoutingHelper &operator = (const Ipv4StaticRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv6-static-routing-helper.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,213 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <vector>
+
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/assert.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+#include "ipv6-static-routing-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRoutingHelper");
+
+namespace ns3 {
+
+Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper ()
+{}
+
+Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &o)
+{
+}
+
+Ipv6StaticRoutingHelper* 
+Ipv6StaticRoutingHelper::Copy (void) const 
+{
+  return new Ipv6StaticRoutingHelper (*this); 
+}
+
+Ptr<Ipv6RoutingProtocol> 
+Ipv6StaticRoutingHelper::Create (Ptr<Node> node) const
+{
+  return CreateObject<Ipv6StaticRouting> ();
+}
+
+Ptr<Ipv6StaticRouting>
+Ipv6StaticRoutingHelper::GetStaticRouting (Ptr<Ipv6> ipv6) const
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
+  NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
+  if (DynamicCast<Ipv6StaticRouting> (ipv6rp))
+    {
+      NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
+      return DynamicCast<Ipv6StaticRouting> (ipv6rp); 
+    } 
+  if (DynamicCast<Ipv6ListRouting> (ipv6rp))
+    {
+      Ptr<Ipv6ListRouting> lrp = DynamicCast<Ipv6ListRouting> (ipv6rp);
+      int16_t priority;
+      for (uint32_t i = 0; i < lrp->GetNRoutingProtocols ();  i++)
+        {
+          NS_LOG_LOGIC ("Searching for static routing in list");
+          Ptr<Ipv6RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
+          if (DynamicCast<Ipv6StaticRouting> (temp))
+            {
+              NS_LOG_LOGIC ("Found static routing in list");
+              return DynamicCast<Ipv6StaticRouting> (temp);
+            }
+        }
+    }
+  NS_LOG_LOGIC ("Static routing not found");
+  return 0;
+}
+
+void  
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+  Ptr<Node> n,
+  Ipv6Address source, 
+  Ipv6Address group,  
+  Ptr<NetDevice> input, 
+  NetDeviceContainer output)
+{
+  Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+
+  // We need to convert the NetDeviceContainer to an array of interface 
+  // numbers
+  std::vector<uint32_t> outputInterfaces;
+  for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
+    {
+      Ptr<NetDevice> nd = *i;
+      int32_t interface = ipv6->GetInterfaceForDevice (nd);
+      NS_ASSERT_MSG (interface >= 0, 
+        "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
+        "Expected an interface associated with the device nd");
+      outputInterfaces.push_back (interface);
+    }
+
+  int32_t inputInterface = ipv6->GetInterfaceForDevice (input);
+  NS_ASSERT_MSG (inputInterface >= 0, 
+    "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
+    "Expected an interface associated with the device input");
+  Ipv6StaticRoutingHelper helper;
+  Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
+  if (!ipv6StaticRouting)
+    {
+  NS_ASSERT_MSG (ipv6StaticRouting, 
+    "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+    "Expected an Ipv6StaticRouting associated with this node");
+    }
+  ipv6StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
+}
+
+void  
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+  Ptr<Node> n,
+  Ipv6Address source, 
+  Ipv6Address group,  
+  std::string inputName, 
+  NetDeviceContainer output)
+{
+  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+  AddMulticastRoute (n, source, group, input, output);
+}
+
+void  
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+  std::string nName,
+  Ipv6Address source, 
+  Ipv6Address group,  
+  Ptr<NetDevice> input, 
+  NetDeviceContainer output)
+{
+  Ptr<Node> n = Names::Find<Node> (nName);
+  AddMulticastRoute (n, source, group, input, output);
+}
+
+void  
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+  std::string nName,
+  Ipv6Address source, 
+  Ipv6Address group,  
+  std::string inputName, 
+  NetDeviceContainer output)
+{
+  Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+  Ptr<Node> n = Names::Find<Node> (nName);
+  AddMulticastRoute (n, source, group, input, output);
+}
+
+#if 0
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+  Ptr<Node> n, 
+  Ptr<NetDevice> nd)
+{
+  Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+  int32_t interfaceSrc = ipv6->GetInterfaceForDevice (nd);
+  NS_ASSERT_MSG (interfaceSrc >= 0, 
+    "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+    "Expected an interface associated with the device");
+  Ipv6StaticRoutingHelper helper;
+  Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
+  if (!ipv6StaticRouting)
+    {
+      NS_ASSERT_MSG (ipv6StaticRouting, 
+        "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+        "Expected an Ipv6StaticRouting associated with this node");
+    }
+  ipv6StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+  Ptr<Node> n, 
+  std::string ndName)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+  std::string nName, 
+  Ptr<NetDevice> nd)
+{
+  Ptr<Node> n = Names::Find<Node> (nName);
+  SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+  std::string nName, 
+  std::string ndName)
+{
+  Ptr<Node> n = Names::Find<Node> (nName);
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  SetDefaultMulticastRoute (n, nd);
+}
+#endif
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv6-static-routing-helper.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,131 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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 IPV6_STATIC_ROUTING_HELPER_H
+#define IPV6_STATIC_ROUTING_HELPER_H
+
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/ipv6-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6StaticRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6StaticRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+  /**
+   * \brief Constructor.
+   */
+  Ipv6StaticRoutingHelper ();
+
+  /**
+   * \brief Construct an Ipv6ListRoutingHelper from another previously 
+   * initialized instance (Copy Constructor).
+   */
+  Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &);
+
+  /**
+   * \internal
+   * \returns pointer to clone of this Ipv6StaticRoutingHelper
+   *
+   * This method is mainly for internal use by the other helpers;
+   * clients are expected to free the dynamic memory allocated by this method
+   */
+  Ipv6StaticRoutingHelper* Copy (void) const;
+
+  /**
+   * \param node the node on which the routing protocol will run
+   * \returns a newly-created routing protocol
+   *
+   * This method will be called by ns3::InternetStackHelper::Install
+   */
+  virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+
+  /**
+   * \brief Get Ipv6StaticRouting pointer from IPv6 stack.
+   * \param ipv6 Ipv6 pointer
+   * \return Ipv6StaticRouting pointer or 0 if not exist
+   */
+  Ptr<Ipv6StaticRouting> GetStaticRouting (Ptr<Ipv6> ipv6) const;
+
+  /**
+   * \brief Add a multicast route to a node and net device using explicit 
+   * Ptr<Node> and Ptr<NetDevice>
+   */
+  void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,  
+    Ptr<NetDevice> input, NetDeviceContainer output);
+
+  /**
+   * \brief Add a multicast route to a node and device using a name string 
+   * previously associated to the node using the Object Name Service and a
+   * Ptr<NetDevice>
+   */
+  void AddMulticastRoute (std::string n, Ipv6Address source, Ipv6Address group,  
+    Ptr<NetDevice> input, NetDeviceContainer output);
+
+  /**
+   * \brief Add a multicast route to a node and device using a Ptr<Node> and a 
+   * name string previously associated to the device using the Object Name Service.
+   */
+  void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,  
+    std::string inputName, NetDeviceContainer output);
+
+  /**
+   * \brief Add a multicast route to a node and device using name strings
+   * previously associated to both the node and device using the Object Name 
+   * Service.
+   */
+  void AddMulticastRoute (std::string nName, Ipv6Address source, Ipv6Address group,  
+    std::string inputName, NetDeviceContainer output);
+
+#if 0
+  /**
+   * \brief Add a default route to the static routing protocol to forward
+   *        packets out a particular interface
+   */
+  void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
+  void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
+  void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
+  void SetDefaultMulticastRoute (std::string nName, std::string ndName);
+#endif
+private:
+  /**
+   * \internal
+   * \brief Assignment operator declared private and not implemented to disallow
+   * assignment and prevent the compiler from happily inserting its own.
+   */
+  Ipv6StaticRoutingHelper &operator = (const Ipv6StaticRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV6_STATIC_ROUTING_HELPER_H */
+
--- a/src/routing/static-routing/ipv4-routing-table-entry.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ipv4-routing-table-entry.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-/*****************************************************
- *     Network Ipv4RoutingTableEntry
- *****************************************************/
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry ()
-{}
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route)
-  : m_dest (route.m_dest),
-    m_destNetworkMask (route.m_destNetworkMask),
-    m_gateway (route.m_gateway),
-    m_interface (route.m_interface)
-{}
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route)
-  : m_dest (route->m_dest),
-    m_destNetworkMask (route->m_destNetworkMask),
-    m_gateway (route->m_gateway),
-    m_interface (route->m_interface)
-{}
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
-                      Ipv4Address gateway,
-                      uint32_t interface)
-  : m_dest (dest),
-    m_destNetworkMask (Ipv4Mask::GetOnes ()),
-    m_gateway (gateway),
-    m_interface (interface)
-{}
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
-                      uint32_t interface)
-  : m_dest (dest),
-    m_destNetworkMask (Ipv4Mask::GetOnes ()),
-    m_gateway (Ipv4Address::GetZero ()),
-    m_interface (interface)
-{}
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
-                      Ipv4Mask networkMask,
-                      Ipv4Address gateway,
-                      uint32_t interface)
-  : m_dest (network),
-    m_destNetworkMask (networkMask),
-    m_gateway (gateway),
-    m_interface (interface)
-{}
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
-                      Ipv4Mask networkMask,
-                      uint32_t interface)
-  : m_dest (network),
-    m_destNetworkMask (networkMask),
-    m_gateway (Ipv4Address::GetZero ()),
-    m_interface (interface)
-{}
-
-bool 
-Ipv4RoutingTableEntry::IsHost (void) const
-{
-  if (m_destNetworkMask.IsEqual (Ipv4Mask::GetOnes ())) 
-    {
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-Ipv4Address 
-Ipv4RoutingTableEntry::GetDest (void) const
-{
-  return m_dest;
-}
-bool 
-Ipv4RoutingTableEntry::IsNetwork (void) const
-{
-  return !IsHost ();
-}
-bool 
-Ipv4RoutingTableEntry::IsDefault (void) const
-{
-  if (m_dest.IsEqual (Ipv4Address::GetZero ())) 
-    {
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-Ipv4Address 
-Ipv4RoutingTableEntry::GetDestNetwork (void) const
-{
-  return m_dest;
-}
-Ipv4Mask 
-Ipv4RoutingTableEntry::GetDestNetworkMask (void) const
-{
-  return m_destNetworkMask;
-}
-bool 
-Ipv4RoutingTableEntry::IsGateway (void) const
-{
-  if (m_gateway.IsEqual (Ipv4Address::GetZero ())) 
-    {
-      return false;
-    } 
-  else 
-    {
-      return true;
-    }
-}
-Ipv4Address 
-Ipv4RoutingTableEntry::GetGateway (void) const
-{
-  return m_gateway;
-}
-uint32_t
-Ipv4RoutingTableEntry::GetInterface (void) const
-{
-  return m_interface;
-}
-
-Ipv4RoutingTableEntry 
-Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest, 
-			      Ipv4Address nextHop, 
-			      uint32_t interface)
-{
-  return Ipv4RoutingTableEntry (dest, nextHop, interface);
-}
-Ipv4RoutingTableEntry 
-Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest,
-			      uint32_t interface)
-{
-  return Ipv4RoutingTableEntry (dest, interface);
-}
-Ipv4RoutingTableEntry 
-Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network, 
-				 Ipv4Mask networkMask, 
-				 Ipv4Address nextHop, 
-				 uint32_t interface)
-{
-  return Ipv4RoutingTableEntry (network, networkMask, 
-                    nextHop, interface);
-}
-Ipv4RoutingTableEntry 
-Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network, 
-				 Ipv4Mask networkMask, 
-				 uint32_t interface)
-{
-  return Ipv4RoutingTableEntry (network, networkMask, 
-                    interface);
-}
-Ipv4RoutingTableEntry 
-Ipv4RoutingTableEntry::CreateDefaultRoute (Ipv4Address nextHop, 
-			       uint32_t interface)
-{
-  return Ipv4RoutingTableEntry (Ipv4Address::GetZero (), nextHop, interface);
-}
-
-
-std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route)
-{
-  if (route.IsDefault ())
-    {
-      NS_ASSERT (route.IsGateway ());
-      os << "default out=" << route.GetInterface () << ", next hop=" << route.GetGateway ();
-    }
-  else if (route.IsHost ())
-    {
-      if (route.IsGateway ())
-        {
-          os << "host="<< route.GetDest () << 
-            ", out=" << route.GetInterface () << 
-            ", next hop=" << route.GetGateway ();
-        }
-      else
-        {
-          os << "host="<< route.GetDest () << 
-            ", out=" << route.GetInterface ();
-        }
-    }
-  else if (route.IsNetwork ()) 
-    {
-      if (route.IsGateway ())
-        {
-          os << "network=" << route.GetDestNetwork () <<
-            ", mask=" << route.GetDestNetworkMask () <<
-            ",out=" << route.GetInterface () <<
-            ", next hop=" << route.GetGateway ();
-        }
-      else
-        {
-          os << "network=" << route.GetDestNetwork () <<
-            ", mask=" << route.GetDestNetworkMask () <<
-            ",out=" << route.GetInterface ();
-        }
-    }
-  else
-    {
-      NS_ASSERT (false);
-    }
-  return os;
-}
-
-/*****************************************************
- *     Ipv4MulticastRoutingTableEntry
- *****************************************************/
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry ()
-{
-}
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route)
-: 
-  m_origin (route.m_origin),
-  m_group (route.m_group),
-  m_inputInterface (route.m_inputInterface),
-  m_outputInterfaces (route.m_outputInterfaces)
-{
-}
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route)
-: 
-  m_origin (route->m_origin),
-  m_group (route->m_group),
-  m_inputInterface (route->m_inputInterface),
-  m_outputInterfaces (route->m_outputInterfaces)
-{
-}
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (
-  Ipv4Address origin, 
-  Ipv4Address group, 
-  uint32_t inputInterface, 
-  std::vector<uint32_t> outputInterfaces)
-{
-  m_origin = origin;
-  m_group = group;
-  m_inputInterface = inputInterface;
-  m_outputInterfaces = outputInterfaces;
-}
-
-Ipv4Address 
-Ipv4MulticastRoutingTableEntry::GetOrigin (void) const
-{
-  return m_origin;
-}
-
-Ipv4Address 
-Ipv4MulticastRoutingTableEntry::GetGroup (void) const
-{
-  return m_group;
-}
-
-uint32_t 
-Ipv4MulticastRoutingTableEntry::GetInputInterface (void) const
-{
-  return m_inputInterface;
-}
-
-uint32_t
-Ipv4MulticastRoutingTableEntry::GetNOutputInterfaces (void) const
-{
-  return m_outputInterfaces.size ();
-}
-
-uint32_t
-Ipv4MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
-{
-  NS_ASSERT_MSG(n < m_outputInterfaces.size (), 
-    "Ipv4MulticastRoutingTableEntry::GetOutputInterface (): index out of bounds");
-
-  return m_outputInterfaces[n];
-}
-
-std::vector<uint32_t>
-Ipv4MulticastRoutingTableEntry::GetOutputInterfaces (void) const
-{
-  return m_outputInterfaces;
-}
-
-Ipv4MulticastRoutingTableEntry 
-Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (
-  Ipv4Address origin, 
-  Ipv4Address group, 
-  uint32_t inputInterface,
-  std::vector<uint32_t> outputInterfaces)
-{
-  return Ipv4MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
-}
-
-std::ostream& 
-operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route)
-{
-  os << "origin=" << route.GetOrigin () << 
-    ", group=" << route.GetGroup () <<
-    ", input interface=" << route.GetInputInterface () <<
-    ", output interfaces=";
-
-  for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
-    {
-      os << route.GetOutputInterface (i) << " ";
-
-    }
-
-  return os;
-}
-
-}//namespace ns3
--- a/src/routing/static-routing/ipv4-routing-table-entry.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_ROUTING_TABLE_ENTRY_H
-#define IPV4_ROUTING_TABLE_ENTRY_H
-
-#include <list>
-#include <vector>
-#include <ostream>
-
-#include "ns3/ipv4-address.h"
-
-namespace ns3 {
-
-/**
- * \ingroup routing
- *
- * A record of an IPv4 routing table entry for Ipv4GlobalRouting and 
- * Ipv4StaticRouting.  This is not a reference counted object.
- */
-class Ipv4RoutingTableEntry {
-public:
-  /**
-   * \brief This constructor does nothing
-   */
-  Ipv4RoutingTableEntry ();
-  /**
-   * \brief Copy Constructor
-   * \param route The route to copy
-   */
-  Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route);
-  /**
-   * \brief Copy Constructor
-   * \param route The route to copy
-   */
-  Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route);
-  /**
-   * \return True if this route is a host route (mask of all ones); false otherwise
-   */
-  bool IsHost (void) const;
-  /**
-   * \return True if this route is not a host route (mask is not all ones); false otherwise
-   *
-   * This method is implemented as !IsHost ().
-   */
-  bool IsNetwork (void) const;
-  /**
-   * \return True if this route is a default route; false otherwise
-   */
-  bool IsDefault (void) const;
-  /**
-   * \return True if this route is a gateway route; false otherwise
-   */
-  bool IsGateway (void) const;
-  /**
-   * \return address of the gateway stored in this entry
-   */
-  Ipv4Address GetGateway (void) const;
-  /**
-   * \return The IPv4 address of the destination of this route
-   */
-  Ipv4Address GetDest (void) const;
-  /**
-   * \return The IPv4 network number of the destination of this route
-   */
-  Ipv4Address GetDestNetwork (void) const;
-  /**
-   * \return The IPv4 network mask of the destination of this route
-   */
-  Ipv4Mask GetDestNetworkMask (void) const;
-  /**
-   * \return The Ipv4 interface number used for sending outgoing packets
-   */
-  uint32_t GetInterface (void) const;
-  /**
-   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
-   * \param dest Ipv4Address of the destination
-   * \param nextHop Ipv4Address of the next hop
-   * \param interface Outgoing interface 
-   */
-  static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest, 
-				      Ipv4Address nextHop, 
-				      uint32_t interface);
-  /**
-   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
-   * \param dest Ipv4Address of the destination
-   * \param interface Outgoing interface 
-   */
-  static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest, 
-				      uint32_t interface);
-  /**
-   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
-   * \param network Ipv4Address of the destination network
-   * \param networkMask Ipv4Mask of the destination network mask
-   * \param nextHop Ipv4Address of the next hop
-   * \param interface Outgoing interface 
-   */
-  static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network, 
-					 Ipv4Mask networkMask, 
-					 Ipv4Address nextHop, 
-					 uint32_t interface);
-  /**
-   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
-   * \param network Ipv4Address of the destination network
-   * \param networkMask Ipv4Mask of the destination network mask
-   * \param interface Outgoing interface 
-   */
-  static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network, 
-					 Ipv4Mask networkMask, 
-					 uint32_t interface);
-  /**
-   * \return An Ipv4RoutingTableEntry object corresponding to the input 
-   * parameters.  This route is distinguished; it will match any 
-   * destination for which a more specific route does not exist.
-   * \param nextHop Ipv4Address of the next hop
-   * \param interface Outgoing interface 
-   */
-  static Ipv4RoutingTableEntry CreateDefaultRoute (Ipv4Address nextHop, 
-				       uint32_t interface);
-  
-private:
-  Ipv4RoutingTableEntry (Ipv4Address network,
-	     Ipv4Mask mask,
-	     Ipv4Address gateway,
-	     uint32_t interface);
-  Ipv4RoutingTableEntry (Ipv4Address dest,
-	     Ipv4Mask mask,
-	     uint32_t interface);
-  Ipv4RoutingTableEntry (Ipv4Address dest,
-	     Ipv4Address gateway,
-	     uint32_t interface);
-  Ipv4RoutingTableEntry (Ipv4Address dest,
-	     uint32_t interface);
-
-  Ipv4Address m_dest;
-  Ipv4Mask m_destNetworkMask;
-  Ipv4Address m_gateway;
-  uint32_t m_interface;
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route);
-
-/**
- * \ingroup routing
- *
- * \brief A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting
- */
-class Ipv4MulticastRoutingTableEntry {
-public:
-  /**
-   * \brief This constructor does nothing
-   */
-  Ipv4MulticastRoutingTableEntry ();
-
-  /**
-   * \brief Copy Constructor
-   * \param route The route to copy
-   */
-  Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route);
-  /**
-   * \brief Copy Constructor
-   * \param route The route to copy
-   */
-  Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route);
-  /**
-   * \return The IPv4 address of the source of this route
-   */
-  Ipv4Address GetOrigin (void) const;
-  /**
-   * \return The IPv4 address of the multicast group of this route
-   */
-  Ipv4Address GetGroup (void) const;
-  /**
-   * \return The IPv4 address of the input interface of this route
-   */
-  uint32_t GetInputInterface (void) const;
-  /**
-   * \return The number of output interfaces of this route
-   */
-  uint32_t GetNOutputInterfaces (void) const;
-  /**
-   * \param n interface index
-   * \return A specified output interface.
-   */
-  uint32_t GetOutputInterface (uint32_t n) const;
-  /**
-   * \return A vector of all of the output interfaces of this route.
-   */
-  std::vector<uint32_t> GetOutputInterfaces (void) const;
-  /**
-   * \return Ipv4MulticastRoutingTableEntry corresponding to the input parameters.
-   * \param origin Source address for the multicast route 
-   * \param group Group destination address for the multicast route
-   * \param inputInterface Input interface that multicast datagram must be received on
-   * \param outputInterfaces vector of output interfaces to copy and forward the datagram to
-   */
-  static Ipv4MulticastRoutingTableEntry CreateMulticastRoute (Ipv4Address origin, 
-    Ipv4Address group, uint32_t inputInterface,
-    std::vector<uint32_t> outputInterfaces);
-
-private:
-  Ipv4MulticastRoutingTableEntry (Ipv4Address origin, Ipv4Address group, 
-    uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
-  Ipv4Address m_origin;
-  Ipv4Address m_group;
-  uint32_t m_inputInterface;
-  std::vector<uint32_t> m_outputInterfaces;
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route);
-
-}//namespace ns3
-
-#endif /* IPV4_ROUTING_TABLE_ENTRY_H */
--- a/src/routing/static-routing/ipv4-static-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,729 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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>
-
-#define NS_LOG_APPEND_CONTEXT                                   \
-    if (m_ipv4 && m_ipv4->GetObject<Node> ()) { \
-      std::clog << Simulator::Now ().GetSeconds () \
-      << " [node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
-
-#include "ns3/log.h"
-#include "ns3/packet.h"
-#include "ns3/node.h"
-#include "ns3/simulator.h"
-#include "ns3/ipv4-route.h"
-#include "ipv4-static-routing.h"
-#include "ipv4-routing-table-entry.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
-
-using std::make_pair;
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4StaticRouting);
-
-TypeId
-Ipv4StaticRouting::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4StaticRouting")
-    .SetParent<Ipv4RoutingProtocol> ()
-    .AddConstructor<Ipv4StaticRouting> ()
-    ;
-  return tid;
-}
-
-Ipv4StaticRouting::Ipv4StaticRouting () 
-: m_ipv4 (0)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void 
-Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
-                                      Ipv4Mask networkMask, 
-                                      Ipv4Address nextHop, 
-                                      uint32_t interface,
-                                      uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << network << " " << networkMask << " " << nextHop << " " << interface << " " << metric);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            nextHop,
-                                            interface);
-  m_networkRoutes.push_back (make_pair(route,metric));
-}
-
-void 
-Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
-                                      Ipv4Mask networkMask, 
-                                      uint32_t interface,
-                                      uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << network << " " << networkMask << " " << interface << " " << metric);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            interface);
-  m_networkRoutes.push_back (make_pair (route,metric));
-}
-
-void 
-Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
-                                     Ipv4Address nextHop, 
-                                     uint32_t interface,
-                                     uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << dest << " " << nextHop << " " << interface << " " << metric);
-  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), nextHop, interface, metric);
-}
-
-void 
-Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
-                                     uint32_t interface,
-                                     uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << dest << " " << interface << " " << metric);
-  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), interface, metric);
-}
-
-void 
-Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
-                                    uint32_t interface,
-                                    uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << nextHop << " " << interface << " " << metric);
-  AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface, metric);
-}
-
-void 
-Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
-                                     Ipv4Address group,
-                                     uint32_t inputInterface,
-                                     std::vector<uint32_t> outputInterfaces)
-{
-  NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
-  Ipv4MulticastRoutingTableEntry *route = new Ipv4MulticastRoutingTableEntry ();
-  *route = Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, 
-    inputInterface, outputInterfaces);
-  m_multicastRoutes.push_back (route);
-}
-
-// default multicast routes are stored as a network route
-// these routes are _not_ consulted in the forwarding process-- only
-// for originating packets
-void 
-Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
-{
-  NS_LOG_FUNCTION (this << outputInterface);
-  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-  Ipv4Address network = Ipv4Address ("224.0.0.0");
-  Ipv4Mask networkMask = Ipv4Mask ("240.0.0.0");
-  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            outputInterface);
-  m_networkRoutes.push_back (make_pair(route,0));
-}
-
-uint32_t 
-Ipv4StaticRouting::GetNMulticastRoutes (void) const
-{
-  NS_LOG_FUNCTION (this);
-  return m_multicastRoutes.size ();
-}
-
-Ipv4MulticastRoutingTableEntry
-Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
-{
-  NS_LOG_FUNCTION (this << index);
-  NS_ASSERT_MSG(index < m_multicastRoutes.size (),
-    "Ipv4StaticRouting::GetMulticastRoute ():  Index out of range");
-
-  if (index < m_multicastRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (MulticastRoutesCI i = m_multicastRoutes.begin (); 
-           i != m_multicastRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              return *i;
-            }
-          tmp++;
-        }
-    }
-  return 0;
-}
-
-bool
-Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
-                                        Ipv4Address group,
-                                        uint32_t inputInterface)
-{
-  NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      Ipv4MulticastRoutingTableEntry *route = *i;
-      if (origin == route->GetOrigin () &&
-          group == route->GetGroup () &&
-          inputInterface == route->GetInputInterface ())
-        {
-          delete *i;
-          m_multicastRoutes.erase (i);
-          return true;
-        }
-    }
-  return false;
-}
-
-void 
-Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      if (tmp  == index)
-        {
-          delete *i;
-          m_multicastRoutes.erase (i);
-          return;
-        }
-      tmp++;
-    }
-}
-
-Ptr<Ipv4Route>
-Ipv4StaticRouting::LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif)
-{
-  NS_LOG_FUNCTION (this << dest << " " << oif);
-  Ptr<Ipv4Route> rtentry = 0;
-  uint16_t longest_mask = 0;
-  uint32_t shortest_metric = 0xffffffff;
-  /* when sending on local multicast, there have to be interface specified */
-  if (dest.IsLocalMulticast ())
-    {
-      NS_ASSERT_MSG (oif, "Try to send on link-local multicast address, and no interface index is given!");
-
-      rtentry = Create<Ipv4Route> ();
-      rtentry->SetDestination (dest);
-      rtentry->SetGateway (Ipv4Address::GetZero ());
-      rtentry->SetOutputDevice (oif);
-      rtentry->SetSource (m_ipv4->GetAddress (oif->GetIfIndex (), 0).GetLocal ());
-      return rtentry;
-    }
-
-
-  for (NetworkRoutesI i = m_networkRoutes.begin (); 
-       i != m_networkRoutes.end (); 
-       i++) 
-    {
-      Ipv4RoutingTableEntry *j=i->first;
-      uint32_t metric =i->second;
-      Ipv4Mask mask = (j)->GetDestNetworkMask ();
-      uint16_t masklen = mask.GetPrefixLength ();
-      Ipv4Address entry = (j)->GetDestNetwork ();
-      NS_LOG_LOGIC ("Searching for route to " << dest << ", checking against route to " << entry << "/" << masklen);
-      if (mask.IsMatch (dest, entry)) 
-        {
-          NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << masklen << ", metric " << metric);
-          if (oif != 0)
-            {
-              if (oif != m_ipv4->GetNetDevice (j->GetInterface ()))
-                {
-                  NS_LOG_LOGIC ("Not on requested interface, skipping");
-                  continue;
-                }
-            }
-          if (masklen < longest_mask) // Not interested if got shorter mask
-            {
-              NS_LOG_LOGIC ("Previous match longer, skipping");
-              continue;
-            }
-          if (masklen > longest_mask) // Reset metric if longer masklen
-            {
-              shortest_metric = 0xffffffff;
-            }
-          longest_mask = masklen;
-          if (metric > shortest_metric)
-            {
-              NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
-              continue;
-            }
-          shortest_metric = metric;
-          Ipv4RoutingTableEntry* route = (j);
-          uint32_t interfaceIdx = route->GetInterface ();
-          rtentry = Create<Ipv4Route> ();
-          rtentry->SetDestination (route->GetDest ());
-          rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
-          rtentry->SetGateway (route->GetGateway ());
-          rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
-        }
-    }
-  if (rtentry != 0)
-    {
-      NS_LOG_LOGIC ("Matching route via " << rtentry->GetGateway () << " at the end");
-    }
-  else
-    {
-      NS_LOG_LOGIC ("No matching route to " << dest << " found");
-    }
-  return rtentry;
-}
-
-Ptr<Ipv4MulticastRoute>
-Ipv4StaticRouting::LookupStatic (
-  Ipv4Address origin, 
-  Ipv4Address group,
-  uint32_t    interface)
-{
-  NS_LOG_FUNCTION (this << origin << " " << group << " " << interface);
-  Ptr<Ipv4MulticastRoute> mrtentry = 0;
-
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      Ipv4MulticastRoutingTableEntry *route = *i;
-//
-// We've been passed an origin address, a multicast group address and an 
-// interface index.  We have to decide if the current route in the list is
-// a match.
-//
-// The first case is the restrictive case where the origin, group and index
-// matches.  
-//
-      if (origin == route->GetOrigin () && group == route->GetGroup ())
-        {
-          // Skipping this case (SSM) for now
-          NS_LOG_LOGIC ("Found multicast source specific route" << *i);
-        }
-      if (group == route->GetGroup ())
-        {
-          if (interface == Ipv4::IF_ANY || 
-              interface == route->GetInputInterface ())
-            {
-              NS_LOG_LOGIC ("Found multicast route" << *i);
-              mrtentry = Create<Ipv4MulticastRoute> ();
-              mrtentry->SetGroup (route->GetGroup ());
-              mrtentry->SetOrigin (route->GetOrigin ());
-              mrtentry->SetParent (route->GetInputInterface ());
-              for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
-                {
-                  if (route->GetOutputInterface (j))
-                    {
-                      NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
-                      mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv4MulticastRoute::MAX_TTL - 1);
-                    }
-                }
-              return mrtentry;
-            }
-        }
-    }
-  return mrtentry;
-}
-
-uint32_t 
-Ipv4StaticRouting::GetNRoutes (void)
-{
-  NS_LOG_FUNCTION (this);
-  return m_networkRoutes.size ();;
-}
-
-Ipv4RoutingTableEntry
-Ipv4StaticRouting::GetDefaultRoute ()
-{
-  NS_LOG_FUNCTION (this);
-  // Basically a repeat of LookupStatic, retained for backward compatibility
-  Ipv4Address dest ("0.0.0.0");
-  uint32_t shortest_metric = 0xffffffff;
-  Ipv4RoutingTableEntry *result = 0;
-  for (NetworkRoutesI i = m_networkRoutes.begin (); 
-       i != m_networkRoutes.end (); 
-       i++) 
-    {
-    Ipv4RoutingTableEntry *j = i->first;
-    uint32_t metric = i->second;
-    Ipv4Mask mask = (j)->GetDestNetworkMask ();
-    uint16_t masklen = mask.GetPrefixLength ();
-    Ipv4Address entry = (j)->GetDestNetwork ();
-    if (masklen != 0)
-      {
-        continue;
-      }
-    if (metric > shortest_metric)
-      {
-        continue;
-      }
-    shortest_metric = metric;
-    result = j;
-  }
-  if (result)
-    {
-      return result;
-    }
-  else
-    {
-      return Ipv4RoutingTableEntry ();
-    }
-}
-
-Ipv4RoutingTableEntry 
-Ipv4StaticRouting::GetRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-        {
-          if (tmp  == index)
-            {
-          return j->first;
-            }
-          tmp++;
-        }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-
-uint32_t
-Ipv4StaticRouting::GetMetric (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          return j->second;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-void 
-Ipv4StaticRouting::RemoveRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          delete j->first;
-          m_networkRoutes.erase (j);
-          return;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-}
-
-Ptr<Ipv4Route> 
-Ipv4StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
-  NS_LOG_FUNCTION (this << header << oif);
-  Ipv4Address destination = header.GetDestination ();
-  Ptr<Ipv4Route> rtentry = 0;
-
-  // Multicast goes here
-  if (destination.IsMulticast ())
-    {
-      // Note:  Multicast routes for outbound packets are stored in the
-      // normal unicast table.  An implication of this is that it is not
-      // possible to source multicast datagrams on multiple interfaces.
-      // This is a well-known property of sockets implementation on 
-      // many Unix variants.
-      // So, we just log it and fall through to LookupStatic ()
-      NS_LOG_LOGIC ("RouteOutput()::Multicast destination");
-    }
-  rtentry = LookupStatic (destination, oif);
-  if (rtentry)
-    { 
-      sockerr = Socket::ERROR_NOTERROR;
-    }
-  else
-    { 
-      sockerr = Socket::ERROR_NOROUTETOHOST;
-    }
-  return rtentry;
-}
-
-bool 
-Ipv4StaticRouting::RouteInput  (Ptr<const Packet> p, const Ipv4Header &ipHeader, Ptr<const NetDevice> idev,
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                             LocalDeliverCallback lcb, ErrorCallback ecb)
-{
-  NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev);
-
-  NS_ASSERT (m_ipv4 != 0);
-  // Check if input device supports IP 
-  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
-  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); 
-
-  // Multicast recognition; handle local delivery here
-  //
-  if (ipHeader.GetDestination ().IsMulticast ())
-    {
-      NS_LOG_LOGIC ("Multicast destination");
-      Ptr<Ipv4MulticastRoute> mrtentry =  LookupStatic(ipHeader.GetSource (),
-        ipHeader.GetDestination (), m_ipv4->GetInterfaceForDevice (idev));
-
-      if (mrtentry)
-        {
-          NS_LOG_LOGIC ("Multicast route found");
-          mcb (mrtentry, p, ipHeader); // multicast forwarding callback
-          return true;
-        }
-      else
-        {
-          NS_LOG_LOGIC ("Multicast route not found");
-          return false; // Let other routing protocols try to handle this
-        }
-    }
-  if (ipHeader.GetDestination ().IsBroadcast ())
-    {
-      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
-      // TODO:  Local Deliver for broadcast
-      // TODO:  Forward broadcast
-    }
-
-  NS_LOG_LOGIC ("Unicast destination");
- // TODO:  Configurable option to enable RFC 1222 Strong End System Model
- // Right now, we will be permissive and allow a source to send us
- // a packet to one of our other interface addresses; that is, the
- // destination unicast address does not match one of the iif addresses,
- // but we check our other interfaces.  This could be an option
- // (to remove the outer loop immediately below and just check iif).
-  for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
-    {
-      for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
-        {
-          Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
-          Ipv4Address addr = iaddr.GetLocal ();
-          if (addr.IsEqual (ipHeader.GetDestination ()))
-            {
-              if (j == iif)
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
-                }
-              else
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << ipHeader.GetDestination ());
-                }
-              lcb (p, ipHeader, iif);
-              return true;
-            }
-          if (ipHeader.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
-            {
-              NS_LOG_LOGIC ("For me (interface broadcast address)");
-              lcb (p, ipHeader, iif);
-              return true;
-            }
-          NS_LOG_LOGIC ("Address "<< addr << " not a match");
-        }
-    }
-  // Check if input device supports IP forwarding
-  if (m_ipv4->IsForwarding (iif) == false)
-    {
-      NS_LOG_LOGIC ("Forwarding disabled for this interface");
-      ecb (p, ipHeader, Socket::ERROR_NOROUTETOHOST);
-      return false;
-    }
-  // Next, try to find a route
-  Ptr<Ipv4Route> rtentry = LookupStatic (ipHeader.GetDestination ());
-  if (rtentry != 0)
-    {
-      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
-      ucb (rtentry, p, ipHeader);  // unicast forwarding callback
-      return true;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
-      return false; // Let other routing protocols try to handle this
-    }
-}
-
-Ipv4StaticRouting::~Ipv4StaticRouting ()
-{
-}
-
-void
-Ipv4StaticRouting::DoDispose (void)
-{
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j = m_networkRoutes.erase (j)) 
-    {
-      delete (j->first);
-    }
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i = m_multicastRoutes.erase (i)) 
-    {
-      delete (*i);
-    }
-  m_ipv4 = 0;
-  Ipv4RoutingProtocol::DoDispose ();
-}
-
-void 
-Ipv4StaticRouting::NotifyInterfaceUp (uint32_t i)
-{
-  NS_LOG_FUNCTION (this << i);
-  // If interface address and network mask have been set, add a route
-  // to the network of the interface (like e.g. ifconfig does on a
-  // Linux box)
-  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
-    {
-      if (m_ipv4->GetAddress (i,j).GetLocal () != Ipv4Address () &&
-          m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask () &&
-          m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask::GetOnes())
-        {
-          AddNetworkRouteTo (m_ipv4->GetAddress (i,j).GetLocal ().CombineMask (m_ipv4->GetAddress (i,j).GetMask ()),
-                             m_ipv4->GetAddress (i,j).GetMask (), i);
-        }
-    }
-}
-
-void 
-Ipv4StaticRouting::NotifyInterfaceDown (uint32_t i)
-{
-  NS_LOG_FUNCTION (this << i);
-  // Remove all static routes that are going through this interface
-  uint32_t j = 0;
-  while (j < GetNRoutes())
-    {
-      Ipv4RoutingTableEntry route = GetRoute (j);
-      if (route.GetInterface () == i)
-        {
-          RemoveRoute (j);
-        }
-      else
-        {
-          j++;
-        }
-    }
-}
-
-void 
-Ipv4StaticRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
-  NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
-  if (!m_ipv4->IsUp (interface))
-    {
-      return;
-    }
-
-  Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
-  Ipv4Mask networkMask = address.GetMask ();
-  if (address.GetLocal () != Ipv4Address () &&
-      address.GetMask () != Ipv4Mask ())
-    {
-      AddNetworkRouteTo (networkAddress,
-                         networkMask, interface);
-    }
-}
-void 
-Ipv4StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
-  NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
-  if (!m_ipv4->IsUp (interface))
-    {
-      return;
-    }
-  Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
-  Ipv4Mask networkMask = address.GetMask ();
-  // Remove all static routes that are going through this interface
-  // which reference this network
-  for (uint32_t j = 0; j < GetNRoutes (); j++)
-    {
-      Ipv4RoutingTableEntry route = GetRoute (j);
-      if (route.GetInterface () == interface &&
-          route.IsNetwork () && 
-          route.GetDestNetwork () == networkAddress &&
-          route.GetDestNetworkMask () == networkMask)
-        {
-          RemoveRoute (j);
-        }
-    }
-}
-
-void 
-Ipv4StaticRouting::SetIpv4 (Ptr<Ipv4> ipv4)
-{
-  NS_LOG_FUNCTION (this << ipv4);
-  NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
-  m_ipv4 = ipv4;
-  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
-    {
-      if (m_ipv4->IsUp (i))
-        {
-          NotifyInterfaceUp (i);
-        }
-      else
-        {
-          NotifyInterfaceDown (i);
-        }
-    }
-}
-
-Ipv4Address
-Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
-{
-  NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
-  if (m_ipv4->GetNAddresses (interfaceIdx) == 1)  // common case
-    {
-      return m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
-    }
-  // no way to determine the scope of the destination, so adopt the
-  // following rule:  pick the first available address (index 0) unless
-  // a subsequent address is on link (in which case, pick the primary
-  // address if there are multiple)
-  Ipv4Address candidate = m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
-  for (uint32_t i = 0; i < m_ipv4->GetNAddresses (interfaceIdx); i++)
-    {
-      Ipv4InterfaceAddress test = m_ipv4->GetAddress (interfaceIdx, i);
-      if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
-        {
-          if (test.IsSecondary () == false) 
-            {
-              return test.GetLocal ();
-            }
-        }
-    }
-  return candidate;
-}
-
-}//namespace ns3
--- a/src/routing/static-routing/ipv4-static-routing.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,399 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 Georgia Tech Research Corporation
- *
- * 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 <utility>
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-header.h"
-#include "ns3/socket.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-protocol.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4RoutingTableEntry;
-class Ipv4MulticastRoutingTableEntry;
-class Node;
-
-/**
- * \ingroup routing
- * \defgroup ipv4StaticRouting Ipv4StaticRouting
- */
-/**
- * \ingroup ipv4StaticRouting
- * 
- * \brief Static routing protocol for IP version 4 stacks.
- *
- * This class provides a basic set of methods for inserting static
- * unicast and multicast routes into the Ipv4 routing system.  
- * This particular protocol is designed to be inserted into an 
- * Ipv4ListRouting protocol but can be used also as a standalone
- * protocol.
- * 
- * The Ipv4StaticRouting class inherits from the abstract base class 
- * Ipv4RoutingProtocol that defines the interface methods that a routing 
- * protocol must support.
- *
- * \see Ipv4RoutingProtocol
- * \see Ipv4ListRouting
- * \see Ipv4ListRouting::AddRoutingProtocol
- */
-class Ipv4StaticRouting : public Ipv4RoutingProtocol
-{
-public:
-  static TypeId GetTypeId (void);
-
-  Ipv4StaticRouting ();
-  virtual ~Ipv4StaticRouting ();
-
-  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
-  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
-                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                             LocalDeliverCallback lcb, ErrorCallback ecb);
-
-  virtual void NotifyInterfaceUp (uint32_t interface);
-  virtual void NotifyInterfaceDown (uint32_t interface);
-  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
-  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
-  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
-
-/**
- * \brief Add a network route to the static routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param nextHop The next hop in the route to the destination network.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          Ipv4Address nextHop, 
-                          uint32_t interface,
-                          uint32_t metric = 0);
-
-/**
- * \brief Add a network route to the static routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          uint32_t interface,
-                          uint32_t metric = 0);
-
-/**
- * \brief Add a host route to the static routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param nextHop The Ipv4Address of the next hop in the route.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
-  void AddHostRouteTo (Ipv4Address dest, 
-                       Ipv4Address nextHop, 
-                       uint32_t interface,
-                       uint32_t metric = 0);
-/**
- * \brief Add a host route to the static routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
-  void AddHostRouteTo (Ipv4Address dest, 
-                       uint32_t interface,
-                       uint32_t metric = 0);
-/**
- * \brief Add a default route to the static routing table.
- *
- * This method tells the routing system what to do in the case where a specific
- * route to a destination is not found.  The system forwards packets to the
- * specified node in the hope that it knows better how to route the packet.
- * 
- * If the default route is set, it is returned as the selected route from 
- * LookupStatic irrespective of destination address if no specific route is
- * found.
- *
- * \param nextHop The Ipv4Address to send packets to in the hope that they
- * will be forwarded correctly.
- * \param interface The network interface index used to send packets.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- * \see Ipv4StaticRouting::Lookup
- */
-  void SetDefaultRoute (Ipv4Address nextHop, 
-                        uint32_t interface,
-                        uint32_t metric = 0);
-
-/**
- * \brief Get the number of individual unicast routes that have been added
- * to the routing table.
- *
- * \warning The default route counts as one of the routes.
- */
-  uint32_t GetNRoutes (void);
-
-/**
- * \brief Get the default route with lowest metric from the static routing table.
- *
- * \return If the default route is set, a pointer to that Ipv4RoutingTableEntry is
- * returned, otherwise an empty routing table entry is returned. 
-*  If multiple default routes exist, the one with lowest metric is returned.
- *
- * \see Ipv4RoutingTableEntry
- */
-  Ipv4RoutingTableEntry GetDefaultRoute (void);
-
-/**
- * \brief Get a route from the static unicast routing table.
- *
- * Externally, the unicast static routing table appears simply as a table with
- * n entries.  
- *
- * \param i The index (into the routing table) of the route to retrieve.  
- * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
- * a zero pointer is returned.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4StaticRouting::RemoveRoute
- */
-  Ipv4RoutingTableEntry GetRoute (uint32_t i);
-
-/**
- * \brief Get a metric for route from the static unicast routing table.
- *
- * \param index The index (into the routing table) of the route to retrieve.  
- * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
- *
- */
-  uint32_t GetMetric (uint32_t index);
-  
-/**
- * \brief Remove a route from the static unicast routing table.
- *
- * Externally, the unicast static routing table appears simply as a table with
- * n entries.  
- *
- * \param i The index (into the routing table) of the route to remove.  
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4StaticRouting::GetRoute
- * \see Ipv4StaticRouting::AddRoute
- */
-  void RemoveRoute (uint32_t i);
-
-/**
- * \brief Add a multicast route to the static routing table.
- *
- * A multicast route must specify an origin IP address, a multicast group and
- * an input network interface index as conditions and provide a vector of
- * output network interface indices over which packets matching the conditions
- * are sent.
- *
- * Typically there are two main types of multicast routes:  routes of the 
- * first kind are used during forwarding.  All of the conditions must be
- * explicitly provided.  The second kind of routes are used to get packets off
- * of a local node.  The difference is in the input interface.  Routes for
- * forwarding will always have an explicit input interface specified.  Routes
- * off of a node will always set the input interface to a wildcard specified
- * by the index Ipv4RoutingProtocol::INTERFACE_ANY.
- *
- * For routes off of a local node wildcards may be used in the origin and
- * multicast group addresses.  The wildcard used for Ipv4Adresses is that 
- * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0".  Usage
- * of a wildcard allows one to specify default behavior to varying degrees.
- *
- * For example, making the origin address a wildcard, but leaving the 
- * multicast group specific allows one (in the case of a node with multiple
- * interfaces) to create different routes using different output interfaces
- * for each multicast group.
- *
- * If the origin and multicast addresses are made wildcards, you have created
- * essentially a default multicast address that can forward to multiple 
- * interfaces.  Compare this to the actual default multicast address that is
- * limited to specifying a single output interface for compatibility with
- * existing functionality in other systems.
- * 
- * \param origin The Ipv4Address of the origin of packets for this route.  May
- * be Ipv4Address:GetAny for open groups.
- * \param group The Ipv4Address of the multicast group or this route.
- * \param inputInterface The input network interface index over which to 
- * expect packets destined for this route.  May be
- * Ipv4RoutingProtocol::INTERFACE_ANY for packets of local origin.
- * \param outputInterfaces A vector of network interface indices used to specify
- * how to send packets to the destination(s).
- *
- * \see Ipv4Address
- */
-  void AddMulticastRoute (Ipv4Address origin,
-                          Ipv4Address group,
-                          uint32_t inputInterface,
-                          std::vector<uint32_t> outputInterfaces);
-
-/**
- * \brief Add a default multicast route to the static routing table.
- *
- * This is the multicast equivalent of the unicast version SetDefaultRoute.
- * We tell the routing system what to do in the case where a specific route
- * to a destination multicast group is not found.  The system forwards 
- * packets out the specified interface in the hope that "something out there"
- * knows better how to route the packet.  This method is only used in 
- * initially sending packets off of a host.  The default multicast route is
- * not consulted during forwarding -- exact routes must be specified using
- * AddMulticastRoute for that case.
- *
- * Since we're basically sending packets to some entity we think may know
- * better what to do, we don't pay attention to "subtleties" like origin
- * address, nor do we worry about forwarding out multiple  interfaces.  If the
- * default multicast route is set, it is returned as the selected route from 
- * LookupStatic irrespective of origin or multicast group if another specific
- * route is not found.
- *
- * \param outputInterface The network interface index used to specify where
- * to send packets in the case of unknown routes.
- *
- * \see Ipv4Address
- */
-  void SetDefaultMulticastRoute (uint32_t outputInterface);
-
-/**
- * \brief Get the number of individual multicast routes that have been added
- * to the routing table.
- *
- * \warning The default multicast route counts as one of the routes.
- */
-  uint32_t GetNMulticastRoutes (void) const;
-
-/**
- * \brief Get a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table 
- * with n entries.  
- * 
- * \param i The index (into the routing table) of the multicast route to
- * retrieve.  
- * \return If route \e i is set, a pointer to that Ipv4MulticastRoutingTableEntry is
- * returned, otherwise a zero pointer is returned.
- *
- * \see Ipv4MulticastRoutingTableEntry
- * \see Ipv4StaticRouting::RemoveRoute
- */
-  Ipv4MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
-
-/**
- * \brief Remove a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table 
- * with n entries.  
- * This method causes the multicast routing table to be searched for the first
- * route that matches the parameters and removes it.
- *
- * Wildcards may be provided to this function, but the wildcards are used to
- * exactly match wildcards in the routes (see AddMulticastRoute).  That is,
- * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
- * remove routes with any address in the origin, but will only remove routes
- * with "0.0.0.0" set as the the origin.
- *
- * \param origin The IP address specified as the origin of packets for the
- * route.
- * \param group The IP address specified as the multicast group address of
- * the route.
- * \param inputInterface The network interface index specified as the expected
- * input interface for the route.
- * \returns true if a route was found and removed, false otherwise.
- *
- * \see Ipv4MulticastRoutingTableEntry
- * \see Ipv4StaticRouting::AddMulticastRoute
- */
-  bool RemoveMulticastRoute (Ipv4Address origin,
-                             Ipv4Address group,
-                             uint32_t inputInterface);
-
-/**
- * \brief Remove a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table 
- * with n entries.  
- *
- * \param index The index (into the multicast routing table) of the route to
- * remove.  
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4StaticRouting::GetRoute
- * \see Ipv4StaticRouting::AddRoute
- */
-  void RemoveMulticastRoute (uint32_t index);
-
-protected:
-  virtual void DoDispose (void);
-
-private:
-  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> > NetworkRoutes;
-  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
-  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
-
-  typedef std::list<Ipv4MulticastRoutingTableEntry *> MulticastRoutes;
-  typedef std::list<Ipv4MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
-  typedef std::list<Ipv4MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
-  
-  Ptr<Ipv4Route> LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif = 0);
-  Ptr<Ipv4MulticastRoute> LookupStatic (Ipv4Address origin, Ipv4Address group,
-                                    uint32_t interface);
-
-  Ipv4Address SourceAddressSelection (uint32_t interface, Ipv4Address dest);
-
-  NetworkRoutes m_networkRoutes;
-  MulticastRoutes m_multicastRoutes;
-
-  Ptr<Ipv4> m_ipv4;
-};
-
-} // Namespace ns3
-
-#endif /* IPV4_STATIC_ROUTING_H */
--- a/src/routing/static-routing/ipv6-routing-table-entry.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#include "ns3/assert.h"
-
-#include "ipv6-routing-table-entry.h"
-
-namespace ns3
-{
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry ()
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const& route)
-  : m_dest (route.m_dest),
-  m_destNetworkPrefix (route.m_destNetworkPrefix),
-  m_gateway (route.m_gateway),
-  m_interface (route.m_interface),
-  m_prefixToUse (route.m_prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route) 
-  : m_dest (route->m_dest),
-  m_destNetworkPrefix (route->m_destNetworkPrefix),
-  m_gateway (route->m_gateway),
-  m_interface (route->m_interface),
-  m_prefixToUse (route->m_prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface)
-  : m_dest (dest),
-  m_destNetworkPrefix (Ipv6Prefix::GetZero ()),
-  m_gateway (gateway),
-  m_interface (interface),
-  m_prefixToUse (Ipv6Address ("::"))
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
-  : m_dest (dest),
-  m_destNetworkPrefix (Ipv6Prefix::GetOnes ()),
-  m_gateway (Ipv6Address::GetZero ()),
-  m_interface (interface),
-  m_prefixToUse (Ipv6Address ("::"))
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse)
-  : m_dest (network),
-  m_destNetworkPrefix (networkPrefix),
-  m_gateway (gateway),
-  m_interface (interface),
-  m_prefixToUse (prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface)
-  : m_dest (network),
-  m_destNetworkPrefix (networkPrefix),
-  m_gateway (gateway),
-  m_interface (interface),
-  m_prefixToUse (Ipv6Address::GetZero ())
-{
-}
-
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, Ipv6Address prefixToUse)
-  : m_dest (network),
-  m_destNetworkPrefix (networkPrefix),
-  m_gateway (Ipv6Address::GetZero ()),
-  m_interface (interface),
-  m_prefixToUse (prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
-  : m_dest (network),
-  m_destNetworkPrefix (networkPrefix),
-  m_gateway (Ipv6Address::GetZero ()),
-  m_interface (interface),
-  m_prefixToUse (Ipv6Address ("::"))
-{
-}
-
-Ipv6RoutingTableEntry::~Ipv6RoutingTableEntry ()
-{
-}
-
-bool Ipv6RoutingTableEntry::IsHost () const
-{
-  if (m_destNetworkPrefix.IsEqual (Ipv6Prefix::GetOnes ()))
-    {
-      return true;
-    }
-  return false;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetDest () const
-{
-  return m_dest;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetPrefixToUse () const
-{
-  return m_prefixToUse;
-}
-
-void Ipv6RoutingTableEntry::SetPrefixToUse (Ipv6Address prefix)
-{
-  m_prefixToUse = prefix;
-}
-
-bool Ipv6RoutingTableEntry::IsNetwork () const
-{
-  return !IsHost ();
-}
-
-bool Ipv6RoutingTableEntry::IsDefault () const
-{
-  if (m_dest.IsEqual (Ipv6Address::GetZero ()))
-    {
-      return true;
-    }
-  return false;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetDestNetwork () const
-{
-  return m_dest;
-}
-
-Ipv6Prefix Ipv6RoutingTableEntry::GetDestNetworkPrefix () const
-{
-  return m_destNetworkPrefix;
-}
-
-bool Ipv6RoutingTableEntry::IsGateway () const
-{
-  if (m_gateway.IsEqual (Ipv6Address::GetZero ()))
-    {
-      return false;
-    }
-  return true;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetGateway () const
-{
-  return m_gateway;
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
-  return Ipv6RoutingTableEntry (dest, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
-{
-  return Ipv6RoutingTableEntry (dest, interface);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
-{
-  return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
-  return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface, prefixToUse);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
-{
-  return Ipv6RoutingTableEntry (network, networkPrefix, interface, network);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface)
-{
-  return Ipv6RoutingTableEntry (Ipv6Address::GetZero (), nextHop, interface);
-}
-
-uint32_t Ipv6RoutingTableEntry::GetInterface () const
-{
-  return m_interface;
-}
-
-std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route)
-{
-  if (route.IsDefault ())
-    {
-      NS_ASSERT (route.IsGateway ());
-      os << "default out =" << route.GetInterface () << ", next hop =" << route.GetGateway ();
-    }
-  else if (route.IsHost ())
-    {
-      if (route.IsGateway ())
-        {
-          os << "host ="<< route.GetDest () <<
-            ", out =" << route.GetInterface () <<
-            ", next hop =" << route.GetGateway ();
-        }
-      else
-        {
-          os << "host =" << route.GetDest () <<
-            ", out =" << route.GetInterface ();
-        }
-    }
-  else if (route.IsNetwork ())
-    {
-      if (route.IsGateway ())
-        {
-          os << "network =" << route.GetDestNetwork () <<
-            ", mask =" << route.GetDestNetworkPrefix () <<
-            ",out =" << route.GetInterface () <<
-            ", next hop =" << route.GetGateway ();
-        }
-      else
-        {
-          os << "network =" << route.GetDestNetwork () <<
-            ", mask =" << route.GetDestNetworkPrefix () <<
-            ",out =" << route.GetInterface ();
-        }
-    }
-  else
-    {
-      NS_ASSERT (false);
-    }
-  return os;
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry ()
-{
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route) 
-  : m_origin (route.m_origin),
-  m_group (route.m_group),
-  m_inputInterface (route.m_inputInterface),
-  m_outputInterfaces (route.m_outputInterfaces)
-{
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route)
-  : m_origin (route->m_origin),
-  m_group (route->m_group),
-  m_inputInterface (route->m_inputInterface),
-  m_outputInterfaces (route->m_outputInterfaces)
-{
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
-  : m_origin (origin),
-  m_group (group),
-  m_inputInterface (inputInterface),
-  m_outputInterfaces (outputInterfaces)
-{
-}
-
-Ipv6Address Ipv6MulticastRoutingTableEntry::GetOrigin () const
-{
-  return m_origin;
-}
-
-Ipv6Address Ipv6MulticastRoutingTableEntry::GetGroup () const
-{
-  return m_group;
-}
-
-uint32_t Ipv6MulticastRoutingTableEntry::GetInputInterface () const
-{
-  return m_inputInterface;
-}
-
-uint32_t Ipv6MulticastRoutingTableEntry::GetNOutputInterfaces () const
-{
-  return m_outputInterfaces.size ();
-}
-
-uint32_t Ipv6MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
-{
-  NS_ASSERT_MSG (n < m_outputInterfaces.size (), "Ipv6MulticastRoutingTableEntry::GetOutputInterface () : index out of bounds");
-
-  return m_outputInterfaces[n];
-}
-
-std::vector <uint32_t> Ipv6MulticastRoutingTableEntry::GetOutputInterfaces () const
-{
-  return m_outputInterfaces;
-}
-
-Ipv6MulticastRoutingTableEntry Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
-{
-  return Ipv6MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
-}
-
-std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route)
-{
-  os << "origin =" << route.GetOrigin () <<
-    ", group =" << route.GetGroup () <<
-    ", input interface =" << route.GetInputInterface () <<
-    ", output interfaces =";
-
-  for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
-    {
-      os << route.GetOutputInterface (i) << " ";
-    }
-
-  return os;
-}
-
-} /* namespace ns3 */
-
--- a/src/routing/static-routing/ipv6-routing-table-entry.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,372 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#ifndef IPV6_ROUTING_TABLE_ENTRY_H
-#define IPV6_ROUTING_TABLE_ENTRY_H
-
-#include <list>
-#include <vector>
-#include <ostream>
-
-#include "ns3/ipv6-address.h"
-
-namespace ns3
-{
-
-/**
- * \class Ipv6RoutingTableEntry
- * \brief A record of an IPv6 route.
- */
-class Ipv6RoutingTableEntry 
-{
-public:
-  /**
-   * \brief Constructor.
-   */
-  Ipv6RoutingTableEntry ();
-
-  /**
-   * \brief Copy constructor.
-   * \param route the route to copy
-   */
-  Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const & route);
-
-  /**
-   * \brief Copy constructor.
-   * \param route the route to copy
-   */
-  Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route);
-
-  /**
-   * \brief Destructor
-   */
-  ~Ipv6RoutingTableEntry ();
-
-  /**
-   * \brief Is the route entry correspond to a host ?
-   * \return true if the route is a host, false otherwise
-   */
-  bool IsHost () const;
-
-  /**
-   * \brief Get the destination.
-   * \return the IPv6 address of the destination of this route
-   */
-  Ipv6Address GetDest () const;
-
-  /**
-   * \brief Get the prefix to use (for multihomed link).
-   * \return prefix address to use
-   */
-  Ipv6Address GetPrefixToUse () const;
-
-  /**
-   * \brief Set the prefix to use.
-   * \param prefix prefix to use
-   */
-  void SetPrefixToUse (Ipv6Address prefix);
-
-  /**
-   * \brief Is the route entry correspond to a network ? 
-   * \return true if the route is a network, false otherwise
-   */
-  bool IsNetwork () const;
-
-  /**
-   * \brief Get the destination network.
-   * \return the destination network
-   */
-  Ipv6Address GetDestNetwork () const;
-
-  /**
-   * \brief Get the destination prefix.
-   * \return the destination prefix
-   */
-  Ipv6Prefix GetDestNetworkPrefix () const;
-
-  /**
-   * \brief Is it the default route ?
-   * \return true if this route is a default route, false otherwise
-   */
-  bool IsDefault () const;
-
-  /**
-   * \brief Is it the gateway ? 
-   * \return true if this route is a gateway, false otherwise
-   */
-  bool IsGateway () const;
-
-  /**
-   * \brief Get the gateway.
-   * \return the IPv6 address of the gateway
-   */
-  Ipv6Address GetGateway () const;
-
-  /**
-   * \brief Get the interface index.
-   * \return the index of the interface
-   */
-  uint32_t GetInterface () const;
-
-  /**
-   * \brief Create a route to a host.
-   * \param dest destination address
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \param prefixToUse prefix that should be used for source address for this destination
-   * \return IPv6Route object
-   */
-  static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address ());
-
-  /**
-   * \brief Create a route to a host.
-   * \param dest destination address
-   * \param interface interface index
-   * \return IPv6Route object
-   */
-  static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, uint32_t interface);
-
-  /**
-   * \brief Create a route to a network.
-   * \param network network address
-   * \param networkPrefix network prefix
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \return IPv6Route object
-   */
-  static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
-
-  /**
-   * \brief Create a route to a network.
-   * \param network network address
-   * \param networkPrefix network prefix
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \param prefixToUse prefix that should be used for source address for this destination
-   * \return IPv6Route object
-   */
-  static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
-
-  /**
-   * \brief Create a route to a network.
-   * \param network network address
-   * \param networkPrefix network prefix
-   * \param interface interface index
-   * \return IPv6Route object
-   */
-  static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
-
-  /**
-   * \brief Create a default route.
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \return IPv6Route object
-   */
-  static Ipv6RoutingTableEntry CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface);
-
-private:
-  /**
-   * \brief Constructor.
-   * \param network network address
-   * \param prefix network prefix
-   * \param gateway the gateway
-   * \param interface the interface index
-   */
-  Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface);
-
-  /**
-   * \brief Constructor.
-   * \param network network address
-   * \param prefix network prefix
-   * \param interface the interface index
-   * \param prefixToUse prefix to use
-   */
-  Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, uint32_t interface, Ipv6Address prefixToUse);
-
-  /**
-   * \brief Constructor.
-   * \param network network address
-   * \param prefix network prefix
-   * \param gateway the gateway
-   * \param interface the interface index
-   * \param prefixToUse prefix to use
-   */
-  Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse);  
-
-  /**
-   * \brief Constructor.
-   * \param dest destination address
-   * \param prefix destination prefix
-   * \param interface interface index
-   */
-  Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Prefix prefix, uint32_t interface);
-
-  /**
-   * \brief Constructor.
-   * \param dest destination address
-   * \param gateway the gateway
-   * \param interface interface index
-   */
-  Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface);
-
-  /**
-   * \brief Constructor.
-   * \param dest destination address
-   * \param interface interface index
-   */
-  Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface);
-
-  /**
-   * \brief IPv6 address of the destination.
-   */
-  Ipv6Address m_dest;
-
-  /**
-   * \brief IPv6 prefix of the destination
-   */
-  Ipv6Prefix m_destNetworkPrefix;
-
-  /**
-   * \brief IPv6 address of the gateway.
-   */
-  Ipv6Address m_gateway;
-
-  /**
-   * \brief The interface index.
-   */
-  uint32_t m_interface;
-
-  /**
-   * \brief Prefix to use.
-   */
-  Ipv6Address m_prefixToUse;
-
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route);
-
-/**
- * \class Ipv6MulticastRoutingTableEntry
- * \brief A record of an IPv6 multicast route.
- */
-class Ipv6MulticastRoutingTableEntry
-{
-public:
-  /**
-   * \brief Constructor.
-   */
-  Ipv6MulticastRoutingTableEntry ();
-
-  /**
-   * \brief Copy constructor.
-   * \param route the route to copy
-   */
-  Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route);
-
-  /**
-   * \brief Copy constructor.
-   * \param route the route to copy
-   */
-  Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route);
-
-  /**
-   * \brief Get the source of this route
-   * \return IPv6 address of the source of this route
-   */
-  Ipv6Address GetOrigin () const;
-
-  /**
-   * \brief Get the group.
-   * \return IPv6 address of the multicast group of this route
-   */
-  Ipv6Address GetGroup () const;
-
-  /**
-   * \brief Get the input interface address.
-   * \return input interface index
-   */
-  uint32_t GetInputInterface () const;
-
-  /**
-   * \brief Get the number of output interfaces of this route.
-   * \return number of output interfaces of this route.
-   */
-  uint32_t GetNOutputInterfaces () const;
-
-  /**
-   * \brief Get a specified output interface.
-   * \param n index
-   * \return a specified output interface
-   */
-  uint32_t GetOutputInterface (uint32_t n) const;
-
-  /**
-   * \brief Get all of the output interfaces of this route.
-   * \return a vector of all output interfaces of this route
-   */
-  std::vector<uint32_t> GetOutputInterfaces () const;
-
-  /**
-   * \brief Create a multicast route.
-   * \param origin IPv6 address of the origin source
-   * \param group Ipv6Address of the group
-   * \param inputInterface interface number
-   * \param outputInterfaces list of output interface number
-   * \return a multicast route
-   */
-  static Ipv6MulticastRoutingTableEntry CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
-private:
-  /**
-   * \brief Constructor.
-   * \param origin IPv6 address of the source
-   * \param group IPv6 address of the group
-   * \param inputInterface interface number
-   * \param outputInterfaces list of output interface number
-   */
-  Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
-  /**
-   * \brief The IPv6 address of the source.
-   */
-  Ipv6Address m_origin;
-
-  /**
-   * \brief The IPv6 address of the group.
-   */
-  Ipv6Address m_group;
-
-  /**
-   * \brief The input interface.
-   */
-  uint32_t m_inputInterface;
-
-  /**
-   * \brief The output interfaces.
-   */
-  std::vector<uint32_t> m_outputInterfaces;
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route);
-
-} /* namespace ns3 */
-
-#endif /* IPV6_ROUTING_TABLE_ENTRY_H */
-
--- a/src/routing/static-routing/ipv6-static-routing.cc	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,758 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#include "ns3/log.h"
-#include "ns3/packet.h"
-#include "ns3/ipv6-route.h"
-#include "ns3/net-device.h"
-
-#include "ipv6-static-routing.h"
-#include "ipv6-routing-table-entry.h"
-
-namespace ns3
-{
-
-NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
-NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
-
-TypeId Ipv6StaticRouting::GetTypeId ()
-{
-  static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
-    .SetParent<Ipv6RoutingProtocol> ()
-    .AddConstructor<Ipv6StaticRouting> ()
-    ;
-  return tid;
-}
-
-Ipv6StaticRouting::Ipv6StaticRouting ()
-  : m_ipv6 (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv6StaticRouting::~Ipv6StaticRouting ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
-{
-  NS_LOG_FUNCTION (this << ipv6);
-  NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
-  uint32_t i = 0; 
-  m_ipv6 = ipv6;
-
-  for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
-    {
-      if (m_ipv6->IsUp (i))
-        {
-          NotifyInterfaceUp (i);
-        }
-      else
-        {
-          NotifyInterfaceDown (i);
-        }
-    }
-}
-
-void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
-  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
-}
-
-void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << dst << interface << metric);
-  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
-}
-
-void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
-  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
-  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
-  m_networkRoutes.push_back (std::make_pair (route, metric));
-}
-
-void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
-  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
-  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
-  m_networkRoutes.push_back (std::make_pair (route, metric));
-}
-
-void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
-  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
-  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
-  m_networkRoutes.push_back (std::make_pair (route, metric));
-}
-
-void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
-{
-  NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
-  AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
-}
-
-void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
-{
-  NS_LOG_FUNCTION (this << origin << group << inputInterface);
-  Ipv6MulticastRoutingTableEntry* route = new Ipv6MulticastRoutingTableEntry ();
-  *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
-  m_multicastRoutes.push_back (route);
-}
-
-void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
-{
-  NS_LOG_FUNCTION (this << outputInterface);
-  Ipv6RoutingTableEntry *route = new Ipv6RoutingTableEntry ();
-  Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
-  Ipv6Prefix networkMask = Ipv6Prefix (8);
-  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
-  m_networkRoutes.push_back (std::make_pair (route, 0));
-}
-
-uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_multicastRoutes.size ();
-}
-
-Ipv6MulticastRoutingTableEntry Ipv6StaticRouting::GetMulticastRoute (uint32_t index) const
-{
-  NS_LOG_FUNCTION (this << index);
-  NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
-
-  if (index < m_multicastRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (MulticastRoutesCI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
-        {
-          if (tmp  == index)
-            {
-              return *i;
-            }
-          tmp++;
-        }
-    }
-  return 0;
-}
-
-bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
-{
-  NS_LOG_FUNCTION (this << origin << group << inputInterface);
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
-    {
-      Ipv6MulticastRoutingTableEntry *route = *i;
-      if (origin == route->GetOrigin () &&
-          group == route->GetGroup () &&
-          inputInterface == route->GetInputInterface ())
-        {
-          delete *i;
-          m_multicastRoutes.erase (i);
-          return true;
-        }
-    }
-  return false;
-}
-
-void Ipv6StaticRouting::RemoveMulticastRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-
-  for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
-    {
-      if (tmp == index)
-        {
-          delete *i;
-          m_multicastRoutes.erase (i);
-          return;
-        }
-      tmp++;
-    }
-}
-
-bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
-{
-  NS_LOG_FUNCTION (this << network << interfaceIndex);
-
-  /* in the network table */
-  for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
-    {
-      Ipv6RoutingTableEntry* rtentry = j->first;
-      Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
-      Ipv6Address entry = rtentry->GetDestNetwork ();
-
-      if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
-        {
-          return true;
-        }
-    }
-
-  /* beuh!!! not route at all */
-  return false;
-}
-
-Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, Ptr<NetDevice> interface)
-{
-  NS_LOG_FUNCTION (this << dst << interface);
-  Ptr<Ipv6Route> rtentry = 0;
-  uint16_t longestMask = 0;
-  uint32_t shortestMetric = 0xffffffff;
-
-  /* when sending on link-local multicast, there have to be interface specified */
-  if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () || 
-      dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
-    {
-      NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
-      rtentry = Create<Ipv6Route> ();
-      rtentry->SetSource (SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
-      rtentry->SetDestination (dst);
-      rtentry->SetGateway (Ipv6Address::GetZero ());
-      rtentry->SetOutputDevice (interface);
-      return rtentry;
-    }
-
-  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
-    {
-      Ipv6RoutingTableEntry* j = it->first;
-      uint32_t metric = it->second;
-      Ipv6Prefix mask = j->GetDestNetworkPrefix ();
-      uint16_t maskLen = mask.GetPrefixLength ();
-      Ipv6Address entry = j->GetDestNetwork ();
-
-      NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
-
-      if (mask.IsMatch (dst, entry))
-        {
-          NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
-
-          /* if interface is given, check the route will output on this interface */
-          if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
-            {
-              if (maskLen < longestMask)
-                {
-                  NS_LOG_LOGIC ("Previous match longer, skipping");
-                  continue;
-                }
-
-              if (maskLen > longestMask)
-                {
-                  shortestMetric = 0xffffffff;
-                }
-
-              longestMask = maskLen;
-              if (metric > shortestMetric)
-                {
-                  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
-                  continue;
-                }
-
-              shortestMetric = metric;
-              Ipv6RoutingTableEntry* route = j;
-              uint32_t interfaceIdx = route->GetInterface ();
-              rtentry = Create<Ipv6Route> ();
-
-              if (route->GetGateway ().IsAny ())
-                {
-                  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
-                }
-              else if (route->GetDest ().IsAny ()) /* default route */
-                {
-                  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
-                }
-              else
-                {
-                  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
-                }
-
-              rtentry->SetDestination (route->GetDest ());
-              rtentry->SetGateway (route->GetGateway ());
-              rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
-            }
-        }
-    }
-
-  if(rtentry)
-    {
-      NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
-    }
-  return rtentry;
-}
-
-void Ipv6StaticRouting::DoDispose ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  for (NetworkRoutesI j = m_networkRoutes.begin () ;  j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
-    {
-      delete j->first;
-    }
-  m_networkRoutes.clear ();
-
-  for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
-    {
-      delete (*i);
-    }
-  m_multicastRoutes.clear ();
-
-  m_ipv6 = 0;
-  Ipv6RoutingProtocol::DoDispose ();
-}
-
-Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << origin << group << interface);
-  Ptr<Ipv6MulticastRoute> mrtentry = 0;
-
-  for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
-    {
-      Ipv6MulticastRoutingTableEntry* route = *i;
-
-      /*
-         We've been passed an origin address, a multicast group address and an
-         interface index.  We have to decide if the current route in the list is
-         a match.
-
-         The first case is the restrictive case where the origin, group and index
-         matches.  This picks up exact routes during forwarded and exact routes from
-         the local node (in which case the ifIndex is a wildcard).
-         */
-
-      if (origin == route->GetOrigin () && group == route->GetGroup ())
-        {
-          /* skipping SSM case */
-          NS_LOG_LOGIC ("Find source specific multicast route" << *i);
-        }
-
-      if (group == route->GetGroup ())
-        {
-          if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
-            {
-              NS_LOG_LOGIC ("Found multicast route" << *i);
-              mrtentry = Create<Ipv6MulticastRoute> ();
-              mrtentry->SetGroup (route->GetGroup ());
-              mrtentry->SetOrigin (route->GetOrigin ());
-              mrtentry->SetParent (route->GetInputInterface ());
-              for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
-                {
-                  if (route->GetOutputInterface (j))
-                    {
-                      NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
-                      mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
-                    }
-                }
-              return mrtentry;
-            } 
-        }
-    }
-  return mrtentry;
-}
-
-uint32_t Ipv6StaticRouting::GetNRoutes ()
-{
-  return m_networkRoutes.size ();
-}
-
-Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv6Address dst ("::");
-  uint32_t shortestMetric = 0xffffffff;
-  Ipv6RoutingTableEntry* result = 0;
-
-  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
-    {
-      Ipv6RoutingTableEntry* j = it->first;
-      uint32_t metric = it->second;
-      Ipv6Prefix mask = j->GetDestNetworkPrefix ();
-      uint16_t maskLen = mask.GetPrefixLength ();
-      Ipv6Address entry = j->GetDestNetwork ();
-
-      if (maskLen)
-        {
-          continue;
-        }
-
-      if (metric > shortestMetric)
-        {
-          continue;
-        }
-      shortestMetric = metric;
-      result = j;
-    }
-
-  if (result)
-    {
-      return result;
-    }
-  else
-    {
-      return Ipv6RoutingTableEntry ();
-    }
-}
-
-Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-
-  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
-    {
-      if (tmp == index)
-        {
-          return it->first;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-
-uint32_t Ipv6StaticRouting::GetMetric (uint32_t index)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t tmp = 0;
-
-  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
-    {
-      if (tmp == index)
-        {
-          return it->second;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-
-void Ipv6StaticRouting::RemoveRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-
-  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
-    {
-      if (tmp == index)
-        {
-          delete it->first;
-          m_networkRoutes.erase (it);
-          return;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-}
-
-void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
-{
-  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
-
-  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
-    {
-      Ipv6RoutingTableEntry* rtentry = it->first;
-      if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex && 
-          rtentry->GetPrefixToUse () == prefixToUse)
-        {
-          delete it->first;
-          m_networkRoutes.erase (it);
-          return;
-        }
-    }
-}
-
-Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
-  NS_LOG_FUNCTION (this << header << oif);
-  Ipv6Address destination = header.GetDestinationAddress ();
-  Ptr<Ipv6Route> rtentry = 0;
-
-  if (destination.IsMulticast ())
-    {
-      // Note:  Multicast routes for outbound packets are stored in the
-      // normal unicast table.  An implication of this is that it is not
-      // possible to source multicast datagrams on multiple interfaces.
-      // This is a well-known property of sockets implementation on
-      // many Unix variants.
-      // So, we just log it and fall through to LookupStatic ()
-      NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
-    }
-
-  rtentry = LookupStatic (destination, oif);
-  if (rtentry)
-    {
-      sockerr = Socket::ERROR_NOTERROR;
-    }
-  else
-    {
-      sockerr = Socket::ERROR_NOROUTETOHOST;
-    }
-  return rtentry;
-}
-
-bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
-                                    UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                                    LocalDeliverCallback lcb, ErrorCallback ecb)
-{
-  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
-  NS_ASSERT (m_ipv6 != 0);
-  // Check if input device supports IP
-  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
-  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
-  Ipv6Address dst = header.GetDestinationAddress ();
-
-  if (dst.IsMulticast ())
-    {
-      NS_LOG_LOGIC ("Multicast destination");
-      Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (header.GetSourceAddress (),
-                                                       header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
-
-      if (mrtentry)
-        {
-          NS_LOG_LOGIC ("Multicast route found");
-          mcb (mrtentry, p, header); // multicast forwarding callback
-          return true;
-        }
-      else
-        {
-          NS_LOG_LOGIC ("Multicast route not found");
-          return false; // Let other routing protocols try to handle this
-        }
-    }
-
-  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
-  // Right now, we will be permissive and allow a source to send us
-  // a packet to one of our other interface addresses; that is, the
-  // destination unicast address does not match one of the iif addresses,
-  // but we check our other interfaces.  This could be an option
-  // (to remove the outer loop immediately below and just check iif).
-  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
-    {
-      for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
-        {
-          Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
-          Ipv6Address addr = iaddr.GetAddress ();
-          if (addr.IsEqual (header.GetDestinationAddress ()))
-            {
-              if (j == iif)
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
-                }
-              else
-                {
-                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
-                }
-              lcb (p, header, iif);
-              return true;
-            }
-          NS_LOG_LOGIC ("Address "<< addr << " not a match");
-        }
-    }
-  // Check if input device supports IP forwarding
-  if (m_ipv6->IsForwarding (iif) == false)
-    {
-      NS_LOG_LOGIC ("Forwarding disabled for this interface");
-      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
-      return false;
-    }
-  // Next, try to find a route
-  NS_LOG_LOGIC ("Unicast destination");
-  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
-
-  if (rtentry != 0)
-    {
-      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
-      ucb (rtentry, p, header);  // unicast forwarding callback
-      return true;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
-      return false; // Let other routing protocols try to handle this
-    }
-}
-
-void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
-{
-  for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
-    {
-      if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
-          m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
-        {
-          if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
-            {
-              /* host route */
-              AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
-            }
-          else
-            {
-              AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
-                                 m_ipv6->GetAddress (i, j).GetPrefix (), i);
-            }
-        }
-    }
-}
-
-void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
-{
-  NS_LOG_FUNCTION (this << i);
-  uint32_t j = 0;
-  uint32_t max = GetNRoutes ();
-
-  /* remove all static routes that are going through this interface */
-  while (j < max)
-    {
-      Ipv6RoutingTableEntry route = GetRoute (j);
-
-      if (route.GetInterface () == i)
-        {
-          RemoveRoute (j);
-        }
-      else
-        {
-          j++;
-        }
-    }
-}
-
-void Ipv6StaticRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
-  if (!m_ipv6->IsUp (interface))
-    {
-      return;
-    }
-
-  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
-  Ipv6Prefix networkMask = address.GetPrefix ();
-
-  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
-    {
-      AddNetworkRouteTo (networkAddress, networkMask, interface);
-    }
-}
-
-void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
-  if (!m_ipv6->IsUp (interface))
-    {
-      return;
-    }
-
-  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
-  Ipv6Prefix networkMask = address.GetPrefix ();
-
-  // Remove all static routes that are going through this interface
-  // which reference this network
-  for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
-    {
-      Ipv6RoutingTableEntry route = GetRoute (j);
-
-      if (route.GetInterface () == interface &&
-          route.IsNetwork () &&
-          route.GetDestNetwork () == networkAddress &&
-          route.GetDestNetworkPrefix () == networkMask)
-        {
-          RemoveRoute (j);
-        }
-    }
-}
-
-void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
-  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
-  if (dst != Ipv6Address::GetZero ())
-    {
-      AddNetworkRouteTo (dst, mask, nextHop, interface);
-    }
-  else /* default route */
-    {
-      /* this case is mainly used by configuring default route following RA processing,
-       * in case of multipe prefix in RA, the first will configured default route
-       */
-
-      /* for the moment, all default route has the same metric
-       * so according to the longest prefix algorithm,
-       * the default route choosen will be the last added
-       */
-      SetDefaultRoute (nextHop, interface, prefixToUse);
-    }
-}
-
-void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
-  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
-  if (dst != Ipv6Address::GetZero ())
-    {
-      for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
-        {
-          Ipv6RoutingTableEntry* rtentry = j->first;
-          Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
-          Ipv6Address entry = rtentry->GetDestNetwork ();
-
-          if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
-            {
-              delete j->first;
-              m_networkRoutes.erase (j);
-            } 
-        }
-    }
-  else
-    {
-      /* default route case */
-      RemoveRoute (dst, mask, interface, prefixToUse);
-    }
-}
-
-Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6Address dest)
-{
-  NS_LOG_FUNCTION (this << interface << dest);
-  Ipv6Address ret;
-
-  /* first address of an IPv6 interface is link-local ones */
-  ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
-
-  if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
-    {
-      return ret; 
-    }
-
-  /* useally IPv6 interfaces have one link-local address and one global address */
-
-  for (uint32_t i = 1 ; i < m_ipv6->GetNAddresses (interface) ; i++)
-    {
-      Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
-
-      if (test.GetAddress ().CombinePrefix (test.GetPrefix ()) == dest.CombinePrefix (test.GetPrefix ()))
-        {
-          return test.GetAddress ();
-        }
-    }
-
-  return ret;
-}
-
-} /* namespace ns3 */
-
--- a/src/routing/static-routing/ipv6-static-routing.h	Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#ifndef IPV6_STATIC_ROUTING_H
-#define IPV6_STATIC_ROUTING_H
-
-#include <stdint.h>
-
-#include <list>
-
-#include "ns3/ptr.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-header.h"
-#include "ns3/ipv6-routing-protocol.h"
-
-namespace ns3
-{
-
-class Packet;
-class NetDevice;
-class Ipv6Interface;
-class Ipv6Route;
-class Node;
-class Ipv6RoutingTableEntry;
-class Ipv6MulticastRoutingTableEntry;
-
-/**
- * \ingroup routing
- * \defgroup ipv6StaticRouting Ipv6StaticRouting
- */
-/**
- * \ingroup ipv6StaticRouting
- * \class Ipv6StaticRouting
- * \brief Static routing protocol for IP version 6 stack.
- * \see Ipv6RoutingProtocol
- * \see Ipv6ListRouting
- */
-class Ipv6StaticRouting : public Ipv6RoutingProtocol
-{
-public:
-  /**
-   * \brief The interface Id associated with this class.
-   * \return type identifier
-   */
-  static TypeId GetTypeId ();
-
-  /**
-   * \brief Constructor.
-   */
-  Ipv6StaticRouting ();
-
-  /**
-   * \brief Destructor.
-   */
-  virtual ~Ipv6StaticRouting ();
-
-  /**
-   * \brief Add route to host.
-   * \param dest destination address
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \param prefixToUse prefix that should be used for source address for this destination
-   * \param metric metric of route in case of multiple routes to same destination
-   */
-  void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
-
-  /**
-   * \brief Add route to host.
-   * \param dest destination address.
-   * \param interface interface index
-   * \param metric metric of route in case of multiple routes to same destination
-   */
-  void AddHostRouteTo (Ipv6Address dest, uint32_t interface, uint32_t metric = 0);
-
-  /**
-   * \brief Add route to network.
-   * \param network network address
-   * \param networkPrefix network prefix*
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \param metric metric of route in case of multiple routes to same destination
-   */
-  void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
-
-  /**
-   * \brief Add route to network.
-   * \param network network address
-   * \param networkPrefix network prefix*
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \param prefixToUse prefix that should be used for source address for this destination
-   * \param metric metric of route in case of multiple routes to same destination
-   */
-  void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
-
-  /**
-   * \brief Add route to network.
-   * \param network network address
-   * \param networkPrefix network prefix
-   * \param interface interface index
-   * \param metric metric of route in case of multiple routes to same destination
-   */
-  void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
-
-  /**
-   * \brief Set the default route.
-   * \param nextHop next hop address to route the packet
-   * \param interface interface index
-   * \param prefixToUse prefix to use (i.e for multihoming)
-   * \param metric metric of route in case of multiple routes to same destination
-   */
-  void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
-
-  /**
-   * \brief Get the number or entries in the routing table.
-   * \return number of entries
-   */
-  uint32_t GetNRoutes ();
-
-  /**
-   * \brief Get the default route.
-   *
-   * If multiple default routes exist, the one with lowest metric is returned.
-   * \return default Ipv6Route
-   */
-  Ipv6RoutingTableEntry GetDefaultRoute ();
-
-  /**
-   * \brief Get a specified route.
-   * \param i index
-   * \return the route whose index is i
-   */
-  Ipv6RoutingTableEntry GetRoute (uint32_t i);
-
-  /**
-   * \brief Get a metric for route from the static unicast routing table.
-   * \param index The index (into the routing table) of the route to retrieve.  
-   * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
-   */
-  uint32_t GetMetric (uint32_t index);
-
-  /**
-   * \brief Remove a route from the routing table.
-   * \param i index
-   */
-  void RemoveRoute (uint32_t i);
-
-  /**
-   * \brief Remove a route from the routing table.
-   * \param network IPv6 network
-   * \param prefix IPv6 prefix
-   * \param ifIndex interface index
-   * \param prefixToUse IPv6 prefix to use with this route (multihoming)
-   */
-  void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
-
-  /**
-   * \brief Add a multicast route for a given multicast source and group.
-   * \param origin IPv6 address of the source
-   * \param group the multicast group address.
-   * \param inputInterface the interface index
-   * \param outputInterfaces the list of output interface indices over which the packet
-   * should be sent (excluding the inputInterface).
-   */
-  void AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
-  /**
-   * \brief Set the default multicast route.
-   * \param outputInterface default output interface
-   */
-  void SetDefaultMulticastRoute (uint32_t outputInterface);
-
-  /**
-   * \brief Get the number of entries in the multicast routing table.
-   * \return number of entries
-   */
-  uint32_t GetNMulticastRoutes () const;
-
-  /**
-   * \brief Get the specified multicast route.
-   * \param i index
-   * \return the route whose index is i
-   */
-  Ipv6MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
-
-  /**
-   * \brief Remove a static multicast route.
-   * \param origin IPv6 address of the source
-   * \param group the multicast group address.
-   * \param inputInterface the input interface index
-   */
-  bool RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface);
-
-  /**
-   * \brief Remove a multicast route.
-   * \param i index of route to remove
-   */
-  void RemoveMulticastRoute (uint32_t i);
-
-  /**
-   * \brief If the destination is already present in network destination list.
-   * \param dest destination address
-   * \param interfaceIndex interface index
-   * \return true if dest is already in list, false otherwise
-   */
-  bool HasNetworkDest (Ipv6Address dest, uint32_t interfaceIndex);
-
-  virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
-  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
-                            UnicastForwardCallback ucb, MulticastForwardCallback mcb,
-                            LocalDeliverCallback lcb, ErrorCallback ecb);
-
-  virtual void NotifyInterfaceUp (uint32_t interface);
-  virtual void NotifyInterfaceDown (uint32_t interface);
-  virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
-  virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
-  virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
-  virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
-  virtual void SetIpv6 (Ptr<Ipv6> ipv6);
-
-protected:
-  /**
-   * \brief Dispose this object.
-   */
-  void DoDispose ();
-
-private:
-  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
-  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
-  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
-
-  typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
-  typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
-  typedef std::list<Ipv6MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
-
-  /**
-   * \brief Lookup in the forwarding table for destination.
-   * \param dest destination address
-   * \param interface output interface if any (put 0 otherwise)
-   * \return Ipv6Route to route the packet to reach dest address
-   */
-  Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, Ptr<NetDevice> = 0);
-
-  /**
-   * \brief Lookup in the multicast forwarding table for destination.
-   * \param origin source address
-   * \param group group multicast address
-   * \param ifIndex interface index
-   * \return Ipv6MulticastRoute to route the packet to reach dest address
-   */
-  Ptr<Ipv6MulticastRoute> LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t ifIndex);
-
-  /**
-   * \brief Choose the source address to use with destination address.
-   * \param interface interface index
-   * \param dest IPv6 destination address
-   * \return IPv6 source address to use
-   */
-  Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
-
-  /**
-   * \brief the forwarding table for network.
-   */
-  NetworkRoutes m_networkRoutes;
-
-  /**
-   * \brief the forwarding table for multicast.
-   */
-  MulticastRoutes m_multicastRoutes;
-
-  /**
-   * \brief Ipv6 reference.
-   */
-  Ptr<Ipv6> m_ipv6;
-};
-
-} /* namespace ns3 */
-
-#endif /* IPV6_STATIC_ROUTING_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-routing-table-entry.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,333 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv4-routing-table-entry.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+/*****************************************************
+ *     Network Ipv4RoutingTableEntry
+ *****************************************************/
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry ()
+{}
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route)
+  : m_dest (route.m_dest),
+    m_destNetworkMask (route.m_destNetworkMask),
+    m_gateway (route.m_gateway),
+    m_interface (route.m_interface)
+{}
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route)
+  : m_dest (route->m_dest),
+    m_destNetworkMask (route->m_destNetworkMask),
+    m_gateway (route->m_gateway),
+    m_interface (route->m_interface)
+{}
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
+                      Ipv4Address gateway,
+                      uint32_t interface)
+  : m_dest (dest),
+    m_destNetworkMask (Ipv4Mask::GetOnes ()),
+    m_gateway (gateway),
+    m_interface (interface)
+{}
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
+                      uint32_t interface)
+  : m_dest (dest),
+    m_destNetworkMask (Ipv4Mask::GetOnes ()),
+    m_gateway (Ipv4Address::GetZero ()),
+    m_interface (interface)
+{}
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
+                      Ipv4Mask networkMask,
+                      Ipv4Address gateway,
+                      uint32_t interface)
+  : m_dest (network),
+    m_destNetworkMask (networkMask),
+    m_gateway (gateway),
+    m_interface (interface)
+{}
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
+                      Ipv4Mask networkMask,
+                      uint32_t interface)
+  : m_dest (network),
+    m_destNetworkMask (networkMask),
+    m_gateway (Ipv4Address::GetZero ()),
+    m_interface (interface)
+{}
+
+bool 
+Ipv4RoutingTableEntry::IsHost (void) const
+{
+  if (m_destNetworkMask.IsEqual (Ipv4Mask::GetOnes ())) 
+    {
+      return true;
+    } 
+  else 
+    {
+      return false;
+    }
+}
+Ipv4Address 
+Ipv4RoutingTableEntry::GetDest (void) const
+{
+  return m_dest;
+}
+bool 
+Ipv4RoutingTableEntry::IsNetwork (void) const
+{
+  return !IsHost ();
+}
+bool 
+Ipv4RoutingTableEntry::IsDefault (void) const
+{
+  if (m_dest.IsEqual (Ipv4Address::GetZero ())) 
+    {
+      return true;
+    } 
+  else 
+    {
+      return false;
+    }
+}
+Ipv4Address 
+Ipv4RoutingTableEntry::GetDestNetwork (void) const
+{
+  return m_dest;
+}
+Ipv4Mask 
+Ipv4RoutingTableEntry::GetDestNetworkMask (void) const
+{
+  return m_destNetworkMask;
+}
+bool 
+Ipv4RoutingTableEntry::IsGateway (void) const
+{
+  if (m_gateway.IsEqual (Ipv4Address::GetZero ())) 
+    {
+      return false;
+    } 
+  else 
+    {
+      return true;
+    }
+}
+Ipv4Address 
+Ipv4RoutingTableEntry::GetGateway (void) const
+{
+  return m_gateway;
+}
+uint32_t
+Ipv4RoutingTableEntry::GetInterface (void) const
+{
+  return m_interface;
+}
+
+Ipv4RoutingTableEntry 
+Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest, 
+			      Ipv4Address nextHop, 
+			      uint32_t interface)
+{
+  return Ipv4RoutingTableEntry (dest, nextHop, interface);
+}
+Ipv4RoutingTableEntry 
+Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest,
+			      uint32_t interface)
+{
+  return Ipv4RoutingTableEntry (dest, interface);
+}
+Ipv4RoutingTableEntry 
+Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network, 
+				 Ipv4Mask networkMask, 
+				 Ipv4Address nextHop, 
+				 uint32_t interface)
+{
+  return Ipv4RoutingTableEntry (network, networkMask, 
+                    nextHop, interface);
+}
+Ipv4RoutingTableEntry 
+Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network, 
+				 Ipv4Mask networkMask, 
+				 uint32_t interface)
+{
+  return Ipv4RoutingTableEntry (network, networkMask, 
+                    interface);
+}
+Ipv4RoutingTableEntry 
+Ipv4RoutingTableEntry::CreateDefaultRoute (Ipv4Address nextHop, 
+			       uint32_t interface)
+{
+  return Ipv4RoutingTableEntry (Ipv4Address::GetZero (), nextHop, interface);
+}
+
+
+std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route)
+{
+  if (route.IsDefault ())
+    {
+      NS_ASSERT (route.IsGateway ());
+      os << "default out=" << route.GetInterface () << ", next hop=" << route.GetGateway ();
+    }
+  else if (route.IsHost ())
+    {
+      if (route.IsGateway ())
+        {
+          os << "host="<< route.GetDest () << 
+            ", out=" << route.GetInterface () << 
+            ", next hop=" << route.GetGateway ();
+        }
+      else
+        {
+          os << "host="<< route.GetDest () << 
+            ", out=" << route.GetInterface ();
+        }
+    }
+  else if (route.IsNetwork ()) 
+    {
+      if (route.IsGateway ())
+        {
+          os << "network=" << route.GetDestNetwork () <<
+            ", mask=" << route.GetDestNetworkMask () <<
+            ",out=" << route.GetInterface () <<
+            ", next hop=" << route.GetGateway ();
+        }
+      else
+        {
+          os << "network=" << route.GetDestNetwork () <<
+            ", mask=" << route.GetDestNetworkMask () <<
+            ",out=" << route.GetInterface ();
+        }
+    }
+  else
+    {
+      NS_ASSERT (false);
+    }
+  return os;
+}
+
+/*****************************************************
+ *     Ipv4MulticastRoutingTableEntry
+ *****************************************************/
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry ()
+{
+}
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route)
+: 
+  m_origin (route.m_origin),
+  m_group (route.m_group),
+  m_inputInterface (route.m_inputInterface),
+  m_outputInterfaces (route.m_outputInterfaces)
+{
+}
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route)
+: 
+  m_origin (route->m_origin),
+  m_group (route->m_group),
+  m_inputInterface (route->m_inputInterface),
+  m_outputInterfaces (route->m_outputInterfaces)
+{
+}
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (
+  Ipv4Address origin, 
+  Ipv4Address group, 
+  uint32_t inputInterface, 
+  std::vector<uint32_t> outputInterfaces)
+{
+  m_origin = origin;
+  m_group = group;
+  m_inputInterface = inputInterface;
+  m_outputInterfaces = outputInterfaces;
+}
+
+Ipv4Address 
+Ipv4MulticastRoutingTableEntry::GetOrigin (void) const
+{
+  return m_origin;
+}
+
+Ipv4Address 
+Ipv4MulticastRoutingTableEntry::GetGroup (void) const
+{
+  return m_group;
+}
+
+uint32_t 
+Ipv4MulticastRoutingTableEntry::GetInputInterface (void) const
+{
+  return m_inputInterface;
+}
+
+uint32_t
+Ipv4MulticastRoutingTableEntry::GetNOutputInterfaces (void) const
+{
+  return m_outputInterfaces.size ();
+}
+
+uint32_t
+Ipv4MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
+{
+  NS_ASSERT_MSG(n < m_outputInterfaces.size (), 
+    "Ipv4MulticastRoutingTableEntry::GetOutputInterface (): index out of bounds");
+
+  return m_outputInterfaces[n];
+}
+
+std::vector<uint32_t>
+Ipv4MulticastRoutingTableEntry::GetOutputInterfaces (void) const
+{
+  return m_outputInterfaces;
+}
+
+Ipv4MulticastRoutingTableEntry 
+Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (
+  Ipv4Address origin, 
+  Ipv4Address group, 
+  uint32_t inputInterface,
+  std::vector<uint32_t> outputInterfaces)
+{
+  return Ipv4MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
+}
+
+std::ostream& 
+operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route)
+{
+  os << "origin=" << route.GetOrigin () << 
+    ", group=" << route.GetGroup () <<
+    ", input interface=" << route.GetInputInterface () <<
+    ", output interfaces=";
+
+  for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
+    {
+      os << route.GetOutputInterface (i) << " ";
+
+    }
+
+  return os;
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-routing-table-entry.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,231 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_ROUTING_TABLE_ENTRY_H
+#define IPV4_ROUTING_TABLE_ENTRY_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing
+ *
+ * A record of an IPv4 routing table entry for Ipv4GlobalRouting and 
+ * Ipv4StaticRouting.  This is not a reference counted object.
+ */
+class Ipv4RoutingTableEntry {
+public:
+  /**
+   * \brief This constructor does nothing
+   */
+  Ipv4RoutingTableEntry ();
+  /**
+   * \brief Copy Constructor
+   * \param route The route to copy
+   */
+  Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route);
+  /**
+   * \brief Copy Constructor
+   * \param route The route to copy
+   */
+  Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route);
+  /**
+   * \return True if this route is a host route (mask of all ones); false otherwise
+   */
+  bool IsHost (void) const;
+  /**
+   * \return True if this route is not a host route (mask is not all ones); false otherwise
+   *
+   * This method is implemented as !IsHost ().
+   */
+  bool IsNetwork (void) const;
+  /**
+   * \return True if this route is a default route; false otherwise
+   */
+  bool IsDefault (void) const;
+  /**
+   * \return True if this route is a gateway route; false otherwise
+   */
+  bool IsGateway (void) const;
+  /**
+   * \return address of the gateway stored in this entry
+   */
+  Ipv4Address GetGateway (void) const;
+  /**
+   * \return The IPv4 address of the destination of this route
+   */
+  Ipv4Address GetDest (void) const;
+  /**
+   * \return The IPv4 network number of the destination of this route
+   */
+  Ipv4Address GetDestNetwork (void) const;
+  /**
+   * \return The IPv4 network mask of the destination of this route
+   */
+  Ipv4Mask GetDestNetworkMask (void) const;
+  /**
+   * \return The Ipv4 interface number used for sending outgoing packets
+   */
+  uint32_t GetInterface (void) const;
+  /**
+   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+   * \param dest Ipv4Address of the destination
+   * \param nextHop Ipv4Address of the next hop
+   * \param interface Outgoing interface 
+   */
+  static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest, 
+				      Ipv4Address nextHop, 
+				      uint32_t interface);
+  /**
+   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+   * \param dest Ipv4Address of the destination
+   * \param interface Outgoing interface 
+   */
+  static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest, 
+				      uint32_t interface);
+  /**
+   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+   * \param network Ipv4Address of the destination network
+   * \param networkMask Ipv4Mask of the destination network mask
+   * \param nextHop Ipv4Address of the next hop
+   * \param interface Outgoing interface 
+   */
+  static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network, 
+					 Ipv4Mask networkMask, 
+					 Ipv4Address nextHop, 
+					 uint32_t interface);
+  /**
+   * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+   * \param network Ipv4Address of the destination network
+   * \param networkMask Ipv4Mask of the destination network mask
+   * \param interface Outgoing interface 
+   */
+  static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network, 
+					 Ipv4Mask networkMask, 
+					 uint32_t interface);
+  /**
+   * \return An Ipv4RoutingTableEntry object corresponding to the input 
+   * parameters.  This route is distinguished; it will match any 
+   * destination for which a more specific route does not exist.
+   * \param nextHop Ipv4Address of the next hop
+   * \param interface Outgoing interface 
+   */
+  static Ipv4RoutingTableEntry CreateDefaultRoute (Ipv4Address nextHop, 
+				       uint32_t interface);
+  
+private:
+  Ipv4RoutingTableEntry (Ipv4Address network,
+	     Ipv4Mask mask,
+	     Ipv4Address gateway,
+	     uint32_t interface);
+  Ipv4RoutingTableEntry (Ipv4Address dest,
+	     Ipv4Mask mask,
+	     uint32_t interface);
+  Ipv4RoutingTableEntry (Ipv4Address dest,
+	     Ipv4Address gateway,
+	     uint32_t interface);
+  Ipv4RoutingTableEntry (Ipv4Address dest,
+	     uint32_t interface);
+
+  Ipv4Address m_dest;
+  Ipv4Mask m_destNetworkMask;
+  Ipv4Address m_gateway;
+  uint32_t m_interface;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route);
+
+/**
+ * \ingroup routing
+ *
+ * \brief A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting
+ */
+class Ipv4MulticastRoutingTableEntry {
+public:
+  /**
+   * \brief This constructor does nothing
+   */
+  Ipv4MulticastRoutingTableEntry ();
+
+  /**
+   * \brief Copy Constructor
+   * \param route The route to copy
+   */
+  Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route);
+  /**
+   * \brief Copy Constructor
+   * \param route The route to copy
+   */
+  Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route);
+  /**
+   * \return The IPv4 address of the source of this route
+   */
+  Ipv4Address GetOrigin (void) const;
+  /**
+   * \return The IPv4 address of the multicast group of this route
+   */
+  Ipv4Address GetGroup (void) const;
+  /**
+   * \return The IPv4 address of the input interface of this route
+   */
+  uint32_t GetInputInterface (void) const;
+  /**
+   * \return The number of output interfaces of this route
+   */
+  uint32_t GetNOutputInterfaces (void) const;
+  /**
+   * \param n interface index
+   * \return A specified output interface.
+   */
+  uint32_t GetOutputInterface (uint32_t n) const;
+  /**
+   * \return A vector of all of the output interfaces of this route.
+   */
+  std::vector<uint32_t> GetOutputInterfaces (void) const;
+  /**
+   * \return Ipv4MulticastRoutingTableEntry corresponding to the input parameters.
+   * \param origin Source address for the multicast route 
+   * \param group Group destination address for the multicast route
+   * \param inputInterface Input interface that multicast datagram must be received on
+   * \param outputInterfaces vector of output interfaces to copy and forward the datagram to
+   */
+  static Ipv4MulticastRoutingTableEntry CreateMulticastRoute (Ipv4Address origin, 
+    Ipv4Address group, uint32_t inputInterface,
+    std::vector<uint32_t> outputInterfaces);
+
+private:
+  Ipv4MulticastRoutingTableEntry (Ipv4Address origin, Ipv4Address group, 
+    uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+  Ipv4Address m_origin;
+  Ipv4Address m_group;
+  uint32_t m_inputInterface;
+  std::vector<uint32_t> m_outputInterfaces;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route);
+
+}//namespace ns3
+
+#endif /* IPV4_ROUTING_TABLE_ENTRY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-static-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,729 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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>
+
+#define NS_LOG_APPEND_CONTEXT                                   \
+    if (m_ipv4 && m_ipv4->GetObject<Node> ()) { \
+      std::clog << Simulator::Now ().GetSeconds () \
+      << " [node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/simulator.h"
+#include "ns3/ipv4-route.h"
+#include "ipv4-static-routing.h"
+#include "ipv4-routing-table-entry.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
+
+using std::make_pair;
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4StaticRouting);
+
+TypeId
+Ipv4StaticRouting::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4StaticRouting")
+    .SetParent<Ipv4RoutingProtocol> ()
+    .AddConstructor<Ipv4StaticRouting> ()
+    ;
+  return tid;
+}
+
+Ipv4StaticRouting::Ipv4StaticRouting () 
+: m_ipv4 (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void 
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      Ipv4Address nextHop, 
+                                      uint32_t interface,
+                                      uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << " " << networkMask << " " << nextHop << " " << interface << " " << metric);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            nextHop,
+                                            interface);
+  m_networkRoutes.push_back (make_pair(route,metric));
+}
+
+void 
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      uint32_t interface,
+                                      uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << " " << networkMask << " " << interface << " " << metric);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            interface);
+  m_networkRoutes.push_back (make_pair (route,metric));
+}
+
+void 
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
+                                     Ipv4Address nextHop, 
+                                     uint32_t interface,
+                                     uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << dest << " " << nextHop << " " << interface << " " << metric);
+  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), nextHop, interface, metric);
+}
+
+void 
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
+                                     uint32_t interface,
+                                     uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << dest << " " << interface << " " << metric);
+  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), interface, metric);
+}
+
+void 
+Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
+                                    uint32_t interface,
+                                    uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << nextHop << " " << interface << " " << metric);
+  AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface, metric);
+}
+
+void 
+Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
+                                     Ipv4Address group,
+                                     uint32_t inputInterface,
+                                     std::vector<uint32_t> outputInterfaces)
+{
+  NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
+  Ipv4MulticastRoutingTableEntry *route = new Ipv4MulticastRoutingTableEntry ();
+  *route = Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, 
+    inputInterface, outputInterfaces);
+  m_multicastRoutes.push_back (route);
+}
+
+// default multicast routes are stored as a network route
+// these routes are _not_ consulted in the forwarding process-- only
+// for originating packets
+void 
+Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
+{
+  NS_LOG_FUNCTION (this << outputInterface);
+  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+  Ipv4Address network = Ipv4Address ("224.0.0.0");
+  Ipv4Mask networkMask = Ipv4Mask ("240.0.0.0");
+  *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            outputInterface);
+  m_networkRoutes.push_back (make_pair(route,0));
+}
+
+uint32_t 
+Ipv4StaticRouting::GetNMulticastRoutes (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_multicastRoutes.size ();
+}
+
+Ipv4MulticastRoutingTableEntry
+Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  NS_ASSERT_MSG(index < m_multicastRoutes.size (),
+    "Ipv4StaticRouting::GetMulticastRoute ():  Index out of range");
+
+  if (index < m_multicastRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (MulticastRoutesCI i = m_multicastRoutes.begin (); 
+           i != m_multicastRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          tmp++;
+        }
+    }
+  return 0;
+}
+
+bool
+Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
+                                        Ipv4Address group,
+                                        uint32_t inputInterface)
+{
+  NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      Ipv4MulticastRoutingTableEntry *route = *i;
+      if (origin == route->GetOrigin () &&
+          group == route->GetGroup () &&
+          inputInterface == route->GetInputInterface ())
+        {
+          delete *i;
+          m_multicastRoutes.erase (i);
+          return true;
+        }
+    }
+  return false;
+}
+
+void 
+Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      if (tmp  == index)
+        {
+          delete *i;
+          m_multicastRoutes.erase (i);
+          return;
+        }
+      tmp++;
+    }
+}
+
+Ptr<Ipv4Route>
+Ipv4StaticRouting::LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif)
+{
+  NS_LOG_FUNCTION (this << dest << " " << oif);
+  Ptr<Ipv4Route> rtentry = 0;
+  uint16_t longest_mask = 0;
+  uint32_t shortest_metric = 0xffffffff;
+  /* when sending on local multicast, there have to be interface specified */
+  if (dest.IsLocalMulticast ())
+    {
+      NS_ASSERT_MSG (oif, "Try to send on link-local multicast address, and no interface index is given!");
+
+      rtentry = Create<Ipv4Route> ();
+      rtentry->SetDestination (dest);
+      rtentry->SetGateway (Ipv4Address::GetZero ());
+      rtentry->SetOutputDevice (oif);
+      rtentry->SetSource (m_ipv4->GetAddress (oif->GetIfIndex (), 0).GetLocal ());
+      return rtentry;
+    }
+
+
+  for (NetworkRoutesI i = m_networkRoutes.begin (); 
+       i != m_networkRoutes.end (); 
+       i++) 
+    {
+      Ipv4RoutingTableEntry *j=i->first;
+      uint32_t metric =i->second;
+      Ipv4Mask mask = (j)->GetDestNetworkMask ();
+      uint16_t masklen = mask.GetPrefixLength ();
+      Ipv4Address entry = (j)->GetDestNetwork ();
+      NS_LOG_LOGIC ("Searching for route to " << dest << ", checking against route to " << entry << "/" << masklen);
+      if (mask.IsMatch (dest, entry)) 
+        {
+          NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << masklen << ", metric " << metric);
+          if (oif != 0)
+            {
+              if (oif != m_ipv4->GetNetDevice (j->GetInterface ()))
+                {
+                  NS_LOG_LOGIC ("Not on requested interface, skipping");
+                  continue;
+                }
+            }
+          if (masklen < longest_mask) // Not interested if got shorter mask
+            {
+              NS_LOG_LOGIC ("Previous match longer, skipping");
+              continue;
+            }
+          if (masklen > longest_mask) // Reset metric if longer masklen
+            {
+              shortest_metric = 0xffffffff;
+            }
+          longest_mask = masklen;
+          if (metric > shortest_metric)
+            {
+              NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
+              continue;
+            }
+          shortest_metric = metric;
+          Ipv4RoutingTableEntry* route = (j);
+          uint32_t interfaceIdx = route->GetInterface ();
+          rtentry = Create<Ipv4Route> ();
+          rtentry->SetDestination (route->GetDest ());
+          rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
+          rtentry->SetGateway (route->GetGateway ());
+          rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
+        }
+    }
+  if (rtentry != 0)
+    {
+      NS_LOG_LOGIC ("Matching route via " << rtentry->GetGateway () << " at the end");
+    }
+  else
+    {
+      NS_LOG_LOGIC ("No matching route to " << dest << " found");
+    }
+  return rtentry;
+}
+
+Ptr<Ipv4MulticastRoute>
+Ipv4StaticRouting::LookupStatic (
+  Ipv4Address origin, 
+  Ipv4Address group,
+  uint32_t    interface)
+{
+  NS_LOG_FUNCTION (this << origin << " " << group << " " << interface);
+  Ptr<Ipv4MulticastRoute> mrtentry = 0;
+
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      Ipv4MulticastRoutingTableEntry *route = *i;
+//
+// We've been passed an origin address, a multicast group address and an 
+// interface index.  We have to decide if the current route in the list is
+// a match.
+//
+// The first case is the restrictive case where the origin, group and index
+// matches.  
+//
+      if (origin == route->GetOrigin () && group == route->GetGroup ())
+        {
+          // Skipping this case (SSM) for now
+          NS_LOG_LOGIC ("Found multicast source specific route" << *i);
+        }
+      if (group == route->GetGroup ())
+        {
+          if (interface == Ipv4::IF_ANY || 
+              interface == route->GetInputInterface ())
+            {
+              NS_LOG_LOGIC ("Found multicast route" << *i);
+              mrtentry = Create<Ipv4MulticastRoute> ();
+              mrtentry->SetGroup (route->GetGroup ());
+              mrtentry->SetOrigin (route->GetOrigin ());
+              mrtentry->SetParent (route->GetInputInterface ());
+              for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
+                {
+                  if (route->GetOutputInterface (j))
+                    {
+                      NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
+                      mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv4MulticastRoute::MAX_TTL - 1);
+                    }
+                }
+              return mrtentry;
+            }
+        }
+    }
+  return mrtentry;
+}
+
+uint32_t 
+Ipv4StaticRouting::GetNRoutes (void)
+{
+  NS_LOG_FUNCTION (this);
+  return m_networkRoutes.size ();;
+}
+
+Ipv4RoutingTableEntry
+Ipv4StaticRouting::GetDefaultRoute ()
+{
+  NS_LOG_FUNCTION (this);
+  // Basically a repeat of LookupStatic, retained for backward compatibility
+  Ipv4Address dest ("0.0.0.0");
+  uint32_t shortest_metric = 0xffffffff;
+  Ipv4RoutingTableEntry *result = 0;
+  for (NetworkRoutesI i = m_networkRoutes.begin (); 
+       i != m_networkRoutes.end (); 
+       i++) 
+    {
+    Ipv4RoutingTableEntry *j = i->first;
+    uint32_t metric = i->second;
+    Ipv4Mask mask = (j)->GetDestNetworkMask ();
+    uint16_t masklen = mask.GetPrefixLength ();
+    Ipv4Address entry = (j)->GetDestNetwork ();
+    if (masklen != 0)
+      {
+        continue;
+      }
+    if (metric > shortest_metric)
+      {
+        continue;
+      }
+    shortest_metric = metric;
+    result = j;
+  }
+  if (result)
+    {
+      return result;
+    }
+  else
+    {
+      return Ipv4RoutingTableEntry ();
+    }
+}
+
+Ipv4RoutingTableEntry 
+Ipv4StaticRouting::GetRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+        {
+          if (tmp  == index)
+            {
+          return j->first;
+            }
+          tmp++;
+        }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+
+uint32_t
+Ipv4StaticRouting::GetMetric (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          return j->second;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+void 
+Ipv4StaticRouting::RemoveRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          delete j->first;
+          m_networkRoutes.erase (j);
+          return;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+}
+
+Ptr<Ipv4Route> 
+Ipv4StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+  NS_LOG_FUNCTION (this << header << oif);
+  Ipv4Address destination = header.GetDestination ();
+  Ptr<Ipv4Route> rtentry = 0;
+
+  // Multicast goes here
+  if (destination.IsMulticast ())
+    {
+      // Note:  Multicast routes for outbound packets are stored in the
+      // normal unicast table.  An implication of this is that it is not
+      // possible to source multicast datagrams on multiple interfaces.
+      // This is a well-known property of sockets implementation on 
+      // many Unix variants.
+      // So, we just log it and fall through to LookupStatic ()
+      NS_LOG_LOGIC ("RouteOutput()::Multicast destination");
+    }
+  rtentry = LookupStatic (destination, oif);
+  if (rtentry)
+    { 
+      sockerr = Socket::ERROR_NOTERROR;
+    }
+  else
+    { 
+      sockerr = Socket::ERROR_NOROUTETOHOST;
+    }
+  return rtentry;
+}
+
+bool 
+Ipv4StaticRouting::RouteInput  (Ptr<const Packet> p, const Ipv4Header &ipHeader, Ptr<const NetDevice> idev,
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                             LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+  NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev);
+
+  NS_ASSERT (m_ipv4 != 0);
+  // Check if input device supports IP 
+  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); 
+
+  // Multicast recognition; handle local delivery here
+  //
+  if (ipHeader.GetDestination ().IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination");
+      Ptr<Ipv4MulticastRoute> mrtentry =  LookupStatic(ipHeader.GetSource (),
+        ipHeader.GetDestination (), m_ipv4->GetInterfaceForDevice (idev));
+
+      if (mrtentry)
+        {
+          NS_LOG_LOGIC ("Multicast route found");
+          mcb (mrtentry, p, ipHeader); // multicast forwarding callback
+          return true;
+        }
+      else
+        {
+          NS_LOG_LOGIC ("Multicast route not found");
+          return false; // Let other routing protocols try to handle this
+        }
+    }
+  if (ipHeader.GetDestination ().IsBroadcast ())
+    {
+      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
+      // TODO:  Local Deliver for broadcast
+      // TODO:  Forward broadcast
+    }
+
+  NS_LOG_LOGIC ("Unicast destination");
+ // TODO:  Configurable option to enable RFC 1222 Strong End System Model
+ // Right now, we will be permissive and allow a source to send us
+ // a packet to one of our other interface addresses; that is, the
+ // destination unicast address does not match one of the iif addresses,
+ // but we check our other interfaces.  This could be an option
+ // (to remove the outer loop immediately below and just check iif).
+  for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
+    {
+      for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
+        {
+          Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
+          Ipv4Address addr = iaddr.GetLocal ();
+          if (addr.IsEqual (ipHeader.GetDestination ()))
+            {
+              if (j == iif)
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << ipHeader.GetDestination ());
+                }
+              lcb (p, ipHeader, iif);
+              return true;
+            }
+          if (ipHeader.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
+            {
+              NS_LOG_LOGIC ("For me (interface broadcast address)");
+              lcb (p, ipHeader, iif);
+              return true;
+            }
+          NS_LOG_LOGIC ("Address "<< addr << " not a match");
+        }
+    }
+  // Check if input device supports IP forwarding
+  if (m_ipv4->IsForwarding (iif) == false)
+    {
+      NS_LOG_LOGIC ("Forwarding disabled for this interface");
+      ecb (p, ipHeader, Socket::ERROR_NOROUTETOHOST);
+      return false;
+    }
+  // Next, try to find a route
+  Ptr<Ipv4Route> rtentry = LookupStatic (ipHeader.GetDestination ());
+  if (rtentry != 0)
+    {
+      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+      ucb (rtentry, p, ipHeader);  // unicast forwarding callback
+      return true;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+      return false; // Let other routing protocols try to handle this
+    }
+}
+
+Ipv4StaticRouting::~Ipv4StaticRouting ()
+{
+}
+
+void
+Ipv4StaticRouting::DoDispose (void)
+{
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j = m_networkRoutes.erase (j)) 
+    {
+      delete (j->first);
+    }
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i = m_multicastRoutes.erase (i)) 
+    {
+      delete (*i);
+    }
+  m_ipv4 = 0;
+  Ipv4RoutingProtocol::DoDispose ();
+}
+
+void 
+Ipv4StaticRouting::NotifyInterfaceUp (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  // If interface address and network mask have been set, add a route
+  // to the network of the interface (like e.g. ifconfig does on a
+  // Linux box)
+  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
+    {
+      if (m_ipv4->GetAddress (i,j).GetLocal () != Ipv4Address () &&
+          m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask () &&
+          m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask::GetOnes())
+        {
+          AddNetworkRouteTo (m_ipv4->GetAddress (i,j).GetLocal ().CombineMask (m_ipv4->GetAddress (i,j).GetMask ()),
+                             m_ipv4->GetAddress (i,j).GetMask (), i);
+        }
+    }
+}
+
+void 
+Ipv4StaticRouting::NotifyInterfaceDown (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  // Remove all static routes that are going through this interface
+  uint32_t j = 0;
+  while (j < GetNRoutes())
+    {
+      Ipv4RoutingTableEntry route = GetRoute (j);
+      if (route.GetInterface () == i)
+        {
+          RemoveRoute (j);
+        }
+      else
+        {
+          j++;
+        }
+    }
+}
+
+void 
+Ipv4StaticRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
+  if (!m_ipv4->IsUp (interface))
+    {
+      return;
+    }
+
+  Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
+  Ipv4Mask networkMask = address.GetMask ();
+  if (address.GetLocal () != Ipv4Address () &&
+      address.GetMask () != Ipv4Mask ())
+    {
+      AddNetworkRouteTo (networkAddress,
+                         networkMask, interface);
+    }
+}
+void 
+Ipv4StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
+  if (!m_ipv4->IsUp (interface))
+    {
+      return;
+    }
+  Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
+  Ipv4Mask networkMask = address.GetMask ();
+  // Remove all static routes that are going through this interface
+  // which reference this network
+  for (uint32_t j = 0; j < GetNRoutes (); j++)
+    {
+      Ipv4RoutingTableEntry route = GetRoute (j);
+      if (route.GetInterface () == interface &&
+          route.IsNetwork () && 
+          route.GetDestNetwork () == networkAddress &&
+          route.GetDestNetworkMask () == networkMask)
+        {
+          RemoveRoute (j);
+        }
+    }
+}
+
+void 
+Ipv4StaticRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+  NS_LOG_FUNCTION (this << ipv4);
+  NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
+  m_ipv4 = ipv4;
+  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
+    {
+      if (m_ipv4->IsUp (i))
+        {
+          NotifyInterfaceUp (i);
+        }
+      else
+        {
+          NotifyInterfaceDown (i);
+        }
+    }
+}
+
+Ipv4Address
+Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
+{
+  NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
+  if (m_ipv4->GetNAddresses (interfaceIdx) == 1)  // common case
+    {
+      return m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
+    }
+  // no way to determine the scope of the destination, so adopt the
+  // following rule:  pick the first available address (index 0) unless
+  // a subsequent address is on link (in which case, pick the primary
+  // address if there are multiple)
+  Ipv4Address candidate = m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
+  for (uint32_t i = 0; i < m_ipv4->GetNAddresses (interfaceIdx); i++)
+    {
+      Ipv4InterfaceAddress test = m_ipv4->GetAddress (interfaceIdx, i);
+      if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
+        {
+          if (test.IsSecondary () == false) 
+            {
+              return test.GetLocal ();
+            }
+        }
+    }
+  return candidate;
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-static-routing.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,399 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ *
+ * 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 <utility>
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/socket.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4RoutingTableEntry;
+class Ipv4MulticastRoutingTableEntry;
+class Node;
+
+/**
+ * \ingroup routing
+ * \defgroup ipv4StaticRouting Ipv4StaticRouting
+ */
+/**
+ * \ingroup ipv4StaticRouting
+ * 
+ * \brief Static routing protocol for IP version 4 stacks.
+ *
+ * This class provides a basic set of methods for inserting static
+ * unicast and multicast routes into the Ipv4 routing system.  
+ * This particular protocol is designed to be inserted into an 
+ * Ipv4ListRouting protocol but can be used also as a standalone
+ * protocol.
+ * 
+ * The Ipv4StaticRouting class inherits from the abstract base class 
+ * Ipv4RoutingProtocol that defines the interface methods that a routing 
+ * protocol must support.
+ *
+ * \see Ipv4RoutingProtocol
+ * \see Ipv4ListRouting
+ * \see Ipv4ListRouting::AddRoutingProtocol
+ */
+class Ipv4StaticRouting : public Ipv4RoutingProtocol
+{
+public:
+  static TypeId GetTypeId (void);
+
+  Ipv4StaticRouting ();
+  virtual ~Ipv4StaticRouting ();
+
+  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+                             UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                             LocalDeliverCallback lcb, ErrorCallback ecb);
+
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+/**
+ * \brief Add a network route to the static routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop in the route to the destination network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          Ipv4Address nextHop, 
+                          uint32_t interface,
+                          uint32_t metric = 0);
+
+/**
+ * \brief Add a network route to the static routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          uint32_t interface,
+                          uint32_t metric = 0);
+
+/**
+ * \brief Add a host route to the static routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param nextHop The Ipv4Address of the next hop in the route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+  void AddHostRouteTo (Ipv4Address dest, 
+                       Ipv4Address nextHop, 
+                       uint32_t interface,
+                       uint32_t metric = 0);
+/**
+ * \brief Add a host route to the static routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+  void AddHostRouteTo (Ipv4Address dest, 
+                       uint32_t interface,
+                       uint32_t metric = 0);
+/**
+ * \brief Add a default route to the static routing table.
+ *
+ * This method tells the routing system what to do in the case where a specific
+ * route to a destination is not found.  The system forwards packets to the
+ * specified node in the hope that it knows better how to route the packet.
+ * 
+ * If the default route is set, it is returned as the selected route from 
+ * LookupStatic irrespective of destination address if no specific route is
+ * found.
+ *
+ * \param nextHop The Ipv4Address to send packets to in the hope that they
+ * will be forwarded correctly.
+ * \param interface The network interface index used to send packets.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ * \see Ipv4StaticRouting::Lookup
+ */
+  void SetDefaultRoute (Ipv4Address nextHop, 
+                        uint32_t interface,
+                        uint32_t metric = 0);
+
+/**
+ * \brief Get the number of individual unicast routes that have been added
+ * to the routing table.
+ *
+ * \warning The default route counts as one of the routes.
+ */
+  uint32_t GetNRoutes (void);
+
+/**
+ * \brief Get the default route with lowest metric from the static routing table.
+ *
+ * \return If the default route is set, a pointer to that Ipv4RoutingTableEntry is
+ * returned, otherwise an empty routing table entry is returned. 
+*  If multiple default routes exist, the one with lowest metric is returned.
+ *
+ * \see Ipv4RoutingTableEntry
+ */
+  Ipv4RoutingTableEntry GetDefaultRoute (void);
+
+/**
+ * \brief Get a route from the static unicast routing table.
+ *
+ * Externally, the unicast static routing table appears simply as a table with
+ * n entries.  
+ *
+ * \param i The index (into the routing table) of the route to retrieve.  
+ * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
+ * a zero pointer is returned.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4StaticRouting::RemoveRoute
+ */
+  Ipv4RoutingTableEntry GetRoute (uint32_t i);
+
+/**
+ * \brief Get a metric for route from the static unicast routing table.
+ *
+ * \param index The index (into the routing table) of the route to retrieve.  
+ * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
+ *
+ */
+  uint32_t GetMetric (uint32_t index);
+  
+/**
+ * \brief Remove a route from the static unicast routing table.
+ *
+ * Externally, the unicast static routing table appears simply as a table with
+ * n entries.  
+ *
+ * \param i The index (into the routing table) of the route to remove.  
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4StaticRouting::GetRoute
+ * \see Ipv4StaticRouting::AddRoute
+ */
+  void RemoveRoute (uint32_t i);
+
+/**
+ * \brief Add a multicast route to the static routing table.
+ *
+ * A multicast route must specify an origin IP address, a multicast group and
+ * an input network interface index as conditions and provide a vector of
+ * output network interface indices over which packets matching the conditions
+ * are sent.
+ *
+ * Typically there are two main types of multicast routes:  routes of the 
+ * first kind are used during forwarding.  All of the conditions must be
+ * explicitly provided.  The second kind of routes are used to get packets off
+ * of a local node.  The difference is in the input interface.  Routes for
+ * forwarding will always have an explicit input interface specified.  Routes
+ * off of a node will always set the input interface to a wildcard specified
+ * by the index Ipv4RoutingProtocol::INTERFACE_ANY.
+ *
+ * For routes off of a local node wildcards may be used in the origin and
+ * multicast group addresses.  The wildcard used for Ipv4Adresses is that 
+ * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0".  Usage
+ * of a wildcard allows one to specify default behavior to varying degrees.
+ *
+ * For example, making the origin address a wildcard, but leaving the 
+ * multicast group specific allows one (in the case of a node with multiple
+ * interfaces) to create different routes using different output interfaces
+ * for each multicast group.
+ *
+ * If the origin and multicast addresses are made wildcards, you have created
+ * essentially a default multicast address that can forward to multiple 
+ * interfaces.  Compare this to the actual default multicast address that is
+ * limited to specifying a single output interface for compatibility with
+ * existing functionality in other systems.
+ * 
+ * \param origin The Ipv4Address of the origin of packets for this route.  May
+ * be Ipv4Address:GetAny for open groups.
+ * \param group The Ipv4Address of the multicast group or this route.
+ * \param inputInterface The input network interface index over which to 
+ * expect packets destined for this route.  May be
+ * Ipv4RoutingProtocol::INTERFACE_ANY for packets of local origin.
+ * \param outputInterfaces A vector of network interface indices used to specify
+ * how to send packets to the destination(s).
+ *
+ * \see Ipv4Address
+ */
+  void AddMulticastRoute (Ipv4Address origin,
+                          Ipv4Address group,
+                          uint32_t inputInterface,
+                          std::vector<uint32_t> outputInterfaces);
+
+/**
+ * \brief Add a default multicast route to the static routing table.
+ *
+ * This is the multicast equivalent of the unicast version SetDefaultRoute.
+ * We tell the routing system what to do in the case where a specific route
+ * to a destination multicast group is not found.  The system forwards 
+ * packets out the specified interface in the hope that "something out there"
+ * knows better how to route the packet.  This method is only used in 
+ * initially sending packets off of a host.  The default multicast route is
+ * not consulted during forwarding -- exact routes must be specified using
+ * AddMulticastRoute for that case.
+ *
+ * Since we're basically sending packets to some entity we think may know
+ * better what to do, we don't pay attention to "subtleties" like origin
+ * address, nor do we worry about forwarding out multiple  interfaces.  If the
+ * default multicast route is set, it is returned as the selected route from 
+ * LookupStatic irrespective of origin or multicast group if another specific
+ * route is not found.
+ *
+ * \param outputInterface The network interface index used to specify where
+ * to send packets in the case of unknown routes.
+ *
+ * \see Ipv4Address
+ */
+  void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+/**
+ * \brief Get the number of individual multicast routes that have been added
+ * to the routing table.
+ *
+ * \warning The default multicast route counts as one of the routes.
+ */
+  uint32_t GetNMulticastRoutes (void) const;
+
+/**
+ * \brief Get a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table 
+ * with n entries.  
+ * 
+ * \param i The index (into the routing table) of the multicast route to
+ * retrieve.  
+ * \return If route \e i is set, a pointer to that Ipv4MulticastRoutingTableEntry is
+ * returned, otherwise a zero pointer is returned.
+ *
+ * \see Ipv4MulticastRoutingTableEntry
+ * \see Ipv4StaticRouting::RemoveRoute
+ */
+  Ipv4MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
+
+/**
+ * \brief Remove a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table 
+ * with n entries.  
+ * This method causes the multicast routing table to be searched for the first
+ * route that matches the parameters and removes it.
+ *
+ * Wildcards may be provided to this function, but the wildcards are used to
+ * exactly match wildcards in the routes (see AddMulticastRoute).  That is,
+ * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
+ * remove routes with any address in the origin, but will only remove routes
+ * with "0.0.0.0" set as the the origin.
+ *
+ * \param origin The IP address specified as the origin of packets for the
+ * route.
+ * \param group The IP address specified as the multicast group address of
+ * the route.
+ * \param inputInterface The network interface index specified as the expected
+ * input interface for the route.
+ * \returns true if a route was found and removed, false otherwise.
+ *
+ * \see Ipv4MulticastRoutingTableEntry
+ * \see Ipv4StaticRouting::AddMulticastRoute
+ */
+  bool RemoveMulticastRoute (Ipv4Address origin,
+                             Ipv4Address group,
+                             uint32_t inputInterface);
+
+/**
+ * \brief Remove a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table 
+ * with n entries.  
+ *
+ * \param index The index (into the multicast routing table) of the route to
+ * remove.  
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4StaticRouting::GetRoute
+ * \see Ipv4StaticRouting::AddRoute
+ */
+  void RemoveMulticastRoute (uint32_t index);
+
+protected:
+  virtual void DoDispose (void);
+
+private:
+  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> > NetworkRoutes;
+  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
+  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
+
+  typedef std::list<Ipv4MulticastRoutingTableEntry *> MulticastRoutes;
+  typedef std::list<Ipv4MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
+  typedef std::list<Ipv4MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
+  
+  Ptr<Ipv4Route> LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif = 0);
+  Ptr<Ipv4MulticastRoute> LookupStatic (Ipv4Address origin, Ipv4Address group,
+                                    uint32_t interface);
+
+  Ipv4Address SourceAddressSelection (uint32_t interface, Ipv4Address dest);
+
+  NetworkRoutes m_networkRoutes;
+  MulticastRoutes m_multicastRoutes;
+
+  Ptr<Ipv4> m_ipv4;
+};
+
+} // Namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-routing-table-entry.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,331 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/assert.h"
+
+#include "ipv6-routing-table-entry.h"
+
+namespace ns3
+{
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry ()
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const& route)
+  : m_dest (route.m_dest),
+  m_destNetworkPrefix (route.m_destNetworkPrefix),
+  m_gateway (route.m_gateway),
+  m_interface (route.m_interface),
+  m_prefixToUse (route.m_prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route) 
+  : m_dest (route->m_dest),
+  m_destNetworkPrefix (route->m_destNetworkPrefix),
+  m_gateway (route->m_gateway),
+  m_interface (route->m_interface),
+  m_prefixToUse (route->m_prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface)
+  : m_dest (dest),
+  m_destNetworkPrefix (Ipv6Prefix::GetZero ()),
+  m_gateway (gateway),
+  m_interface (interface),
+  m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
+  : m_dest (dest),
+  m_destNetworkPrefix (Ipv6Prefix::GetOnes ()),
+  m_gateway (Ipv6Address::GetZero ()),
+  m_interface (interface),
+  m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse)
+  : m_dest (network),
+  m_destNetworkPrefix (networkPrefix),
+  m_gateway (gateway),
+  m_interface (interface),
+  m_prefixToUse (prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface)
+  : m_dest (network),
+  m_destNetworkPrefix (networkPrefix),
+  m_gateway (gateway),
+  m_interface (interface),
+  m_prefixToUse (Ipv6Address::GetZero ())
+{
+}
+
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, Ipv6Address prefixToUse)
+  : m_dest (network),
+  m_destNetworkPrefix (networkPrefix),
+  m_gateway (Ipv6Address::GetZero ()),
+  m_interface (interface),
+  m_prefixToUse (prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+  : m_dest (network),
+  m_destNetworkPrefix (networkPrefix),
+  m_gateway (Ipv6Address::GetZero ()),
+  m_interface (interface),
+  m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::~Ipv6RoutingTableEntry ()
+{
+}
+
+bool Ipv6RoutingTableEntry::IsHost () const
+{
+  if (m_destNetworkPrefix.IsEqual (Ipv6Prefix::GetOnes ()))
+    {
+      return true;
+    }
+  return false;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetDest () const
+{
+  return m_dest;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetPrefixToUse () const
+{
+  return m_prefixToUse;
+}
+
+void Ipv6RoutingTableEntry::SetPrefixToUse (Ipv6Address prefix)
+{
+  m_prefixToUse = prefix;
+}
+
+bool Ipv6RoutingTableEntry::IsNetwork () const
+{
+  return !IsHost ();
+}
+
+bool Ipv6RoutingTableEntry::IsDefault () const
+{
+  if (m_dest.IsEqual (Ipv6Address::GetZero ()))
+    {
+      return true;
+    }
+  return false;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetDestNetwork () const
+{
+  return m_dest;
+}
+
+Ipv6Prefix Ipv6RoutingTableEntry::GetDestNetworkPrefix () const
+{
+  return m_destNetworkPrefix;
+}
+
+bool Ipv6RoutingTableEntry::IsGateway () const
+{
+  if (m_gateway.IsEqual (Ipv6Address::GetZero ()))
+    {
+      return false;
+    }
+  return true;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetGateway () const
+{
+  return m_gateway;
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  return Ipv6RoutingTableEntry (dest, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
+{
+  return Ipv6RoutingTableEntry (dest, interface);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
+{
+  return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface, prefixToUse);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+{
+  return Ipv6RoutingTableEntry (network, networkPrefix, interface, network);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface)
+{
+  return Ipv6RoutingTableEntry (Ipv6Address::GetZero (), nextHop, interface);
+}
+
+uint32_t Ipv6RoutingTableEntry::GetInterface () const
+{
+  return m_interface;
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route)
+{
+  if (route.IsDefault ())
+    {
+      NS_ASSERT (route.IsGateway ());
+      os << "default out =" << route.GetInterface () << ", next hop =" << route.GetGateway ();
+    }
+  else if (route.IsHost ())
+    {
+      if (route.IsGateway ())
+        {
+          os << "host ="<< route.GetDest () <<
+            ", out =" << route.GetInterface () <<
+            ", next hop =" << route.GetGateway ();
+        }
+      else
+        {
+          os << "host =" << route.GetDest () <<
+            ", out =" << route.GetInterface ();
+        }
+    }
+  else if (route.IsNetwork ())
+    {
+      if (route.IsGateway ())
+        {
+          os << "network =" << route.GetDestNetwork () <<
+            ", mask =" << route.GetDestNetworkPrefix () <<
+            ",out =" << route.GetInterface () <<
+            ", next hop =" << route.GetGateway ();
+        }
+      else
+        {
+          os << "network =" << route.GetDestNetwork () <<
+            ", mask =" << route.GetDestNetworkPrefix () <<
+            ",out =" << route.GetInterface ();
+        }
+    }
+  else
+    {
+      NS_ASSERT (false);
+    }
+  return os;
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry ()
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route) 
+  : m_origin (route.m_origin),
+  m_group (route.m_group),
+  m_inputInterface (route.m_inputInterface),
+  m_outputInterfaces (route.m_outputInterfaces)
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route)
+  : m_origin (route->m_origin),
+  m_group (route->m_group),
+  m_inputInterface (route->m_inputInterface),
+  m_outputInterfaces (route->m_outputInterfaces)
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+  : m_origin (origin),
+  m_group (group),
+  m_inputInterface (inputInterface),
+  m_outputInterfaces (outputInterfaces)
+{
+}
+
+Ipv6Address Ipv6MulticastRoutingTableEntry::GetOrigin () const
+{
+  return m_origin;
+}
+
+Ipv6Address Ipv6MulticastRoutingTableEntry::GetGroup () const
+{
+  return m_group;
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetInputInterface () const
+{
+  return m_inputInterface;
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetNOutputInterfaces () const
+{
+  return m_outputInterfaces.size ();
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
+{
+  NS_ASSERT_MSG (n < m_outputInterfaces.size (), "Ipv6MulticastRoutingTableEntry::GetOutputInterface () : index out of bounds");
+
+  return m_outputInterfaces[n];
+}
+
+std::vector <uint32_t> Ipv6MulticastRoutingTableEntry::GetOutputInterfaces () const
+{
+  return m_outputInterfaces;
+}
+
+Ipv6MulticastRoutingTableEntry Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+{
+  return Ipv6MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route)
+{
+  os << "origin =" << route.GetOrigin () <<
+    ", group =" << route.GetGroup () <<
+    ", input interface =" << route.GetInputInterface () <<
+    ", output interfaces =";
+
+  for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
+    {
+      os << route.GetOutputInterface (i) << " ";
+    }
+
+  return os;
+}
+
+} /* namespace ns3 */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-routing-table-entry.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,372 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_ROUTING_TABLE_ENTRY_H
+#define IPV6_ROUTING_TABLE_ENTRY_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6RoutingTableEntry
+ * \brief A record of an IPv6 route.
+ */
+class Ipv6RoutingTableEntry 
+{
+public:
+  /**
+   * \brief Constructor.
+   */
+  Ipv6RoutingTableEntry ();
+
+  /**
+   * \brief Copy constructor.
+   * \param route the route to copy
+   */
+  Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const & route);
+
+  /**
+   * \brief Copy constructor.
+   * \param route the route to copy
+   */
+  Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route);
+
+  /**
+   * \brief Destructor
+   */
+  ~Ipv6RoutingTableEntry ();
+
+  /**
+   * \brief Is the route entry correspond to a host ?
+   * \return true if the route is a host, false otherwise
+   */
+  bool IsHost () const;
+
+  /**
+   * \brief Get the destination.
+   * \return the IPv6 address of the destination of this route
+   */
+  Ipv6Address GetDest () const;
+
+  /**
+   * \brief Get the prefix to use (for multihomed link).
+   * \return prefix address to use
+   */
+  Ipv6Address GetPrefixToUse () const;
+
+  /**
+   * \brief Set the prefix to use.
+   * \param prefix prefix to use
+   */
+  void SetPrefixToUse (Ipv6Address prefix);
+
+  /**
+   * \brief Is the route entry correspond to a network ? 
+   * \return true if the route is a network, false otherwise
+   */
+  bool IsNetwork () const;
+
+  /**
+   * \brief Get the destination network.
+   * \return the destination network
+   */
+  Ipv6Address GetDestNetwork () const;
+
+  /**
+   * \brief Get the destination prefix.
+   * \return the destination prefix
+   */
+  Ipv6Prefix GetDestNetworkPrefix () const;
+
+  /**
+   * \brief Is it the default route ?
+   * \return true if this route is a default route, false otherwise
+   */
+  bool IsDefault () const;
+
+  /**
+   * \brief Is it the gateway ? 
+   * \return true if this route is a gateway, false otherwise
+   */
+  bool IsGateway () const;
+
+  /**
+   * \brief Get the gateway.
+   * \return the IPv6 address of the gateway
+   */
+  Ipv6Address GetGateway () const;
+
+  /**
+   * \brief Get the interface index.
+   * \return the index of the interface
+   */
+  uint32_t GetInterface () const;
+
+  /**
+   * \brief Create a route to a host.
+   * \param dest destination address
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix that should be used for source address for this destination
+   * \return IPv6Route object
+   */
+  static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address ());
+
+  /**
+   * \brief Create a route to a host.
+   * \param dest destination address
+   * \param interface interface index
+   * \return IPv6Route object
+   */
+  static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, uint32_t interface);
+
+  /**
+   * \brief Create a route to a network.
+   * \param network network address
+   * \param networkPrefix network prefix
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \return IPv6Route object
+   */
+  static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
+
+  /**
+   * \brief Create a route to a network.
+   * \param network network address
+   * \param networkPrefix network prefix
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix that should be used for source address for this destination
+   * \return IPv6Route object
+   */
+  static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
+
+  /**
+   * \brief Create a route to a network.
+   * \param network network address
+   * \param networkPrefix network prefix
+   * \param interface interface index
+   * \return IPv6Route object
+   */
+  static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
+
+  /**
+   * \brief Create a default route.
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \return IPv6Route object
+   */
+  static Ipv6RoutingTableEntry CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface);
+
+private:
+  /**
+   * \brief Constructor.
+   * \param network network address
+   * \param prefix network prefix
+   * \param gateway the gateway
+   * \param interface the interface index
+   */
+  Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface);
+
+  /**
+   * \brief Constructor.
+   * \param network network address
+   * \param prefix network prefix
+   * \param interface the interface index
+   * \param prefixToUse prefix to use
+   */
+  Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, uint32_t interface, Ipv6Address prefixToUse);
+
+  /**
+   * \brief Constructor.
+   * \param network network address
+   * \param prefix network prefix
+   * \param gateway the gateway
+   * \param interface the interface index
+   * \param prefixToUse prefix to use
+   */
+  Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse);  
+
+  /**
+   * \brief Constructor.
+   * \param dest destination address
+   * \param prefix destination prefix
+   * \param interface interface index
+   */
+  Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Prefix prefix, uint32_t interface);
+
+  /**
+   * \brief Constructor.
+   * \param dest destination address
+   * \param gateway the gateway
+   * \param interface interface index
+   */
+  Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface);
+
+  /**
+   * \brief Constructor.
+   * \param dest destination address
+   * \param interface interface index
+   */
+  Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface);
+
+  /**
+   * \brief IPv6 address of the destination.
+   */
+  Ipv6Address m_dest;
+
+  /**
+   * \brief IPv6 prefix of the destination
+   */
+  Ipv6Prefix m_destNetworkPrefix;
+
+  /**
+   * \brief IPv6 address of the gateway.
+   */
+  Ipv6Address m_gateway;
+
+  /**
+   * \brief The interface index.
+   */
+  uint32_t m_interface;
+
+  /**
+   * \brief Prefix to use.
+   */
+  Ipv6Address m_prefixToUse;
+
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route);
+
+/**
+ * \class Ipv6MulticastRoutingTableEntry
+ * \brief A record of an IPv6 multicast route.
+ */
+class Ipv6MulticastRoutingTableEntry
+{
+public:
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MulticastRoutingTableEntry ();
+
+  /**
+   * \brief Copy constructor.
+   * \param route the route to copy
+   */
+  Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route);
+
+  /**
+   * \brief Copy constructor.
+   * \param route the route to copy
+   */
+  Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route);
+
+  /**
+   * \brief Get the source of this route
+   * \return IPv6 address of the source of this route
+   */
+  Ipv6Address GetOrigin () const;
+
+  /**
+   * \brief Get the group.
+   * \return IPv6 address of the multicast group of this route
+   */
+  Ipv6Address GetGroup () const;
+
+  /**
+   * \brief Get the input interface address.
+   * \return input interface index
+   */
+  uint32_t GetInputInterface () const;
+
+  /**
+   * \brief Get the number of output interfaces of this route.
+   * \return number of output interfaces of this route.
+   */
+  uint32_t GetNOutputInterfaces () const;
+
+  /**
+   * \brief Get a specified output interface.
+   * \param n index
+   * \return a specified output interface
+   */
+  uint32_t GetOutputInterface (uint32_t n) const;
+
+  /**
+   * \brief Get all of the output interfaces of this route.
+   * \return a vector of all output interfaces of this route
+   */
+  std::vector<uint32_t> GetOutputInterfaces () const;
+
+  /**
+   * \brief Create a multicast route.
+   * \param origin IPv6 address of the origin source
+   * \param group Ipv6Address of the group
+   * \param inputInterface interface number
+   * \param outputInterfaces list of output interface number
+   * \return a multicast route
+   */
+  static Ipv6MulticastRoutingTableEntry CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+private:
+  /**
+   * \brief Constructor.
+   * \param origin IPv6 address of the source
+   * \param group IPv6 address of the group
+   * \param inputInterface interface number
+   * \param outputInterfaces list of output interface number
+   */
+  Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+  /**
+   * \brief The IPv6 address of the source.
+   */
+  Ipv6Address m_origin;
+
+  /**
+   * \brief The IPv6 address of the group.
+   */
+  Ipv6Address m_group;
+
+  /**
+   * \brief The input interface.
+   */
+  uint32_t m_inputInterface;
+
+  /**
+   * \brief The output interfaces.
+   */
+  std::vector<uint32_t> m_outputInterfaces;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route);
+
+} /* namespace ns3 */
+
+#endif /* IPV6_ROUTING_TABLE_ENTRY_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-static-routing.cc	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,758 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/net-device.h"
+
+#include "ipv6-static-routing.h"
+#include "ipv6-routing-table-entry.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
+NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
+
+TypeId Ipv6StaticRouting::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
+    .SetParent<Ipv6RoutingProtocol> ()
+    .AddConstructor<Ipv6StaticRouting> ()
+    ;
+  return tid;
+}
+
+Ipv6StaticRouting::Ipv6StaticRouting ()
+  : m_ipv6 (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6StaticRouting::~Ipv6StaticRouting ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+  NS_LOG_FUNCTION (this << ipv6);
+  NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
+  uint32_t i = 0; 
+  m_ipv6 = ipv6;
+
+  for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
+    {
+      if (m_ipv6->IsUp (i))
+        {
+          NotifyInterfaceUp (i);
+        }
+      else
+        {
+          NotifyInterfaceDown (i);
+        }
+    }
+}
+
+void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
+  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
+}
+
+void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << dst << interface << metric);
+  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
+  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
+  m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
+  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
+  m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
+  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
+  m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
+  AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
+}
+
+void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+{
+  NS_LOG_FUNCTION (this << origin << group << inputInterface);
+  Ipv6MulticastRoutingTableEntry* route = new Ipv6MulticastRoutingTableEntry ();
+  *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
+  m_multicastRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
+{
+  NS_LOG_FUNCTION (this << outputInterface);
+  Ipv6RoutingTableEntry *route = new Ipv6RoutingTableEntry ();
+  Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
+  Ipv6Prefix networkMask = Ipv6Prefix (8);
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
+  m_networkRoutes.push_back (std::make_pair (route, 0));
+}
+
+uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_multicastRoutes.size ();
+}
+
+Ipv6MulticastRoutingTableEntry Ipv6StaticRouting::GetMulticastRoute (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
+
+  if (index < m_multicastRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (MulticastRoutesCI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          tmp++;
+        }
+    }
+  return 0;
+}
+
+bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
+{
+  NS_LOG_FUNCTION (this << origin << group << inputInterface);
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
+    {
+      Ipv6MulticastRoutingTableEntry *route = *i;
+      if (origin == route->GetOrigin () &&
+          group == route->GetGroup () &&
+          inputInterface == route->GetInputInterface ())
+        {
+          delete *i;
+          m_multicastRoutes.erase (i);
+          return true;
+        }
+    }
+  return false;
+}
+
+void Ipv6StaticRouting::RemoveMulticastRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+
+  for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+    {
+      if (tmp == index)
+        {
+          delete *i;
+          m_multicastRoutes.erase (i);
+          return;
+        }
+      tmp++;
+    }
+}
+
+bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
+{
+  NS_LOG_FUNCTION (this << network << interfaceIndex);
+
+  /* in the network table */
+  for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+    {
+      Ipv6RoutingTableEntry* rtentry = j->first;
+      Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
+      Ipv6Address entry = rtentry->GetDestNetwork ();
+
+      if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
+        {
+          return true;
+        }
+    }
+
+  /* beuh!!! not route at all */
+  return false;
+}
+
+Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, Ptr<NetDevice> interface)
+{
+  NS_LOG_FUNCTION (this << dst << interface);
+  Ptr<Ipv6Route> rtentry = 0;
+  uint16_t longestMask = 0;
+  uint32_t shortestMetric = 0xffffffff;
+
+  /* when sending on link-local multicast, there have to be interface specified */
+  if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () || 
+      dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+    {
+      NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
+      rtentry = Create<Ipv6Route> ();
+      rtentry->SetSource (SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
+      rtentry->SetDestination (dst);
+      rtentry->SetGateway (Ipv6Address::GetZero ());
+      rtentry->SetOutputDevice (interface);
+      return rtentry;
+    }
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      Ipv6RoutingTableEntry* j = it->first;
+      uint32_t metric = it->second;
+      Ipv6Prefix mask = j->GetDestNetworkPrefix ();
+      uint16_t maskLen = mask.GetPrefixLength ();
+      Ipv6Address entry = j->GetDestNetwork ();
+
+      NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
+
+      if (mask.IsMatch (dst, entry))
+        {
+          NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
+
+          /* if interface is given, check the route will output on this interface */
+          if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
+            {
+              if (maskLen < longestMask)
+                {
+                  NS_LOG_LOGIC ("Previous match longer, skipping");
+                  continue;
+                }
+
+              if (maskLen > longestMask)
+                {
+                  shortestMetric = 0xffffffff;
+                }
+
+              longestMask = maskLen;
+              if (metric > shortestMetric)
+                {
+                  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
+                  continue;
+                }
+
+              shortestMetric = metric;
+              Ipv6RoutingTableEntry* route = j;
+              uint32_t interfaceIdx = route->GetInterface ();
+              rtentry = Create<Ipv6Route> ();
+
+              if (route->GetGateway ().IsAny ())
+                {
+                  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
+                }
+              else if (route->GetDest ().IsAny ()) /* default route */
+                {
+                  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
+                }
+              else
+                {
+                  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
+                }
+
+              rtentry->SetDestination (route->GetDest ());
+              rtentry->SetGateway (route->GetGateway ());
+              rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
+            }
+        }
+    }
+
+  if(rtentry)
+    {
+      NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
+    }
+  return rtentry;
+}
+
+void Ipv6StaticRouting::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (NetworkRoutesI j = m_networkRoutes.begin () ;  j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
+    {
+      delete j->first;
+    }
+  m_networkRoutes.clear ();
+
+  for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
+    {
+      delete (*i);
+    }
+  m_multicastRoutes.clear ();
+
+  m_ipv6 = 0;
+  Ipv6RoutingProtocol::DoDispose ();
+}
+
+Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << origin << group << interface);
+  Ptr<Ipv6MulticastRoute> mrtentry = 0;
+
+  for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+    {
+      Ipv6MulticastRoutingTableEntry* route = *i;
+
+      /*
+         We've been passed an origin address, a multicast group address and an
+         interface index.  We have to decide if the current route in the list is
+         a match.
+
+         The first case is the restrictive case where the origin, group and index
+         matches.  This picks up exact routes during forwarded and exact routes from
+         the local node (in which case the ifIndex is a wildcard).
+         */
+
+      if (origin == route->GetOrigin () && group == route->GetGroup ())
+        {
+          /* skipping SSM case */
+          NS_LOG_LOGIC ("Find source specific multicast route" << *i);
+        }
+
+      if (group == route->GetGroup ())
+        {
+          if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
+            {
+              NS_LOG_LOGIC ("Found multicast route" << *i);
+              mrtentry = Create<Ipv6MulticastRoute> ();
+              mrtentry->SetGroup (route->GetGroup ());
+              mrtentry->SetOrigin (route->GetOrigin ());
+              mrtentry->SetParent (route->GetInputInterface ());
+              for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
+                {
+                  if (route->GetOutputInterface (j))
+                    {
+                      NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
+                      mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
+                    }
+                }
+              return mrtentry;
+            } 
+        }
+    }
+  return mrtentry;
+}
+
+uint32_t Ipv6StaticRouting::GetNRoutes ()
+{
+  return m_networkRoutes.size ();
+}
+
+Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv6Address dst ("::");
+  uint32_t shortestMetric = 0xffffffff;
+  Ipv6RoutingTableEntry* result = 0;
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      Ipv6RoutingTableEntry* j = it->first;
+      uint32_t metric = it->second;
+      Ipv6Prefix mask = j->GetDestNetworkPrefix ();
+      uint16_t maskLen = mask.GetPrefixLength ();
+      Ipv6Address entry = j->GetDestNetwork ();
+
+      if (maskLen)
+        {
+          continue;
+        }
+
+      if (metric > shortestMetric)
+        {
+          continue;
+        }
+      shortestMetric = metric;
+      result = j;
+    }
+
+  if (result)
+    {
+      return result;
+    }
+  else
+    {
+      return Ipv6RoutingTableEntry ();
+    }
+}
+
+Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      if (tmp == index)
+        {
+          return it->first;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+
+uint32_t Ipv6StaticRouting::GetMetric (uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t tmp = 0;
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      if (tmp == index)
+        {
+          return it->second;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+
+void Ipv6StaticRouting::RemoveRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      if (tmp == index)
+        {
+          delete it->first;
+          m_networkRoutes.erase (it);
+          return;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+}
+
+void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
+{
+  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      Ipv6RoutingTableEntry* rtentry = it->first;
+      if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex && 
+          rtentry->GetPrefixToUse () == prefixToUse)
+        {
+          delete it->first;
+          m_networkRoutes.erase (it);
+          return;
+        }
+    }
+}
+
+Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+  NS_LOG_FUNCTION (this << header << oif);
+  Ipv6Address destination = header.GetDestinationAddress ();
+  Ptr<Ipv6Route> rtentry = 0;
+
+  if (destination.IsMulticast ())
+    {
+      // Note:  Multicast routes for outbound packets are stored in the
+      // normal unicast table.  An implication of this is that it is not
+      // possible to source multicast datagrams on multiple interfaces.
+      // This is a well-known property of sockets implementation on
+      // many Unix variants.
+      // So, we just log it and fall through to LookupStatic ()
+      NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
+    }
+
+  rtentry = LookupStatic (destination, oif);
+  if (rtentry)
+    {
+      sockerr = Socket::ERROR_NOTERROR;
+    }
+  else
+    {
+      sockerr = Socket::ERROR_NOROUTETOHOST;
+    }
+  return rtentry;
+}
+
+bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                                    UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                                    LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
+  NS_ASSERT (m_ipv6 != 0);
+  // Check if input device supports IP
+  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
+  Ipv6Address dst = header.GetDestinationAddress ();
+
+  if (dst.IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination");
+      Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (header.GetSourceAddress (),
+                                                       header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
+
+      if (mrtentry)
+        {
+          NS_LOG_LOGIC ("Multicast route found");
+          mcb (mrtentry, p, header); // multicast forwarding callback
+          return true;
+        }
+      else
+        {
+          NS_LOG_LOGIC ("Multicast route not found");
+          return false; // Let other routing protocols try to handle this
+        }
+    }
+
+  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
+  // Right now, we will be permissive and allow a source to send us
+  // a packet to one of our other interface addresses; that is, the
+  // destination unicast address does not match one of the iif addresses,
+  // but we check our other interfaces.  This could be an option
+  // (to remove the outer loop immediately below and just check iif).
+  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
+    {
+      for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
+        {
+          Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
+          Ipv6Address addr = iaddr.GetAddress ();
+          if (addr.IsEqual (header.GetDestinationAddress ()))
+            {
+              if (j == iif)
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
+                }
+              lcb (p, header, iif);
+              return true;
+            }
+          NS_LOG_LOGIC ("Address "<< addr << " not a match");
+        }
+    }
+  // Check if input device supports IP forwarding
+  if (m_ipv6->IsForwarding (iif) == false)
+    {
+      NS_LOG_LOGIC ("Forwarding disabled for this interface");
+      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+      return false;
+    }
+  // Next, try to find a route
+  NS_LOG_LOGIC ("Unicast destination");
+  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
+
+  if (rtentry != 0)
+    {
+      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+      ucb (rtentry, p, header);  // unicast forwarding callback
+      return true;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+      return false; // Let other routing protocols try to handle this
+    }
+}
+
+void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
+{
+  for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
+    {
+      if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
+          m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
+        {
+          if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
+            {
+              /* host route */
+              AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
+            }
+          else
+            {
+              AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
+                                 m_ipv6->GetAddress (i, j).GetPrefix (), i);
+            }
+        }
+    }
+}
+
+void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  uint32_t j = 0;
+  uint32_t max = GetNRoutes ();
+
+  /* remove all static routes that are going through this interface */
+  while (j < max)
+    {
+      Ipv6RoutingTableEntry route = GetRoute (j);
+
+      if (route.GetInterface () == i)
+        {
+          RemoveRoute (j);
+        }
+      else
+        {
+          j++;
+        }
+    }
+}
+
+void Ipv6StaticRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+  if (!m_ipv6->IsUp (interface))
+    {
+      return;
+    }
+
+  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
+  Ipv6Prefix networkMask = address.GetPrefix ();
+
+  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
+    {
+      AddNetworkRouteTo (networkAddress, networkMask, interface);
+    }
+}
+
+void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+  if (!m_ipv6->IsUp (interface))
+    {
+      return;
+    }
+
+  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
+  Ipv6Prefix networkMask = address.GetPrefix ();
+
+  // Remove all static routes that are going through this interface
+  // which reference this network
+  for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
+    {
+      Ipv6RoutingTableEntry route = GetRoute (j);
+
+      if (route.GetInterface () == interface &&
+          route.IsNetwork () &&
+          route.GetDestNetwork () == networkAddress &&
+          route.GetDestNetworkPrefix () == networkMask)
+        {
+          RemoveRoute (j);
+        }
+    }
+}
+
+void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
+  if (dst != Ipv6Address::GetZero ())
+    {
+      AddNetworkRouteTo (dst, mask, nextHop, interface);
+    }
+  else /* default route */
+    {
+      /* this case is mainly used by configuring default route following RA processing,
+       * in case of multipe prefix in RA, the first will configured default route
+       */
+
+      /* for the moment, all default route has the same metric
+       * so according to the longest prefix algorithm,
+       * the default route choosen will be the last added
+       */
+      SetDefaultRoute (nextHop, interface, prefixToUse);
+    }
+}
+
+void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+  if (dst != Ipv6Address::GetZero ())
+    {
+      for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+        {
+          Ipv6RoutingTableEntry* rtentry = j->first;
+          Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
+          Ipv6Address entry = rtentry->GetDestNetwork ();
+
+          if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
+            {
+              delete j->first;
+              m_networkRoutes.erase (j);
+            } 
+        }
+    }
+  else
+    {
+      /* default route case */
+      RemoveRoute (dst, mask, interface, prefixToUse);
+    }
+}
+
+Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6Address dest)
+{
+  NS_LOG_FUNCTION (this << interface << dest);
+  Ipv6Address ret;
+
+  /* first address of an IPv6 interface is link-local ones */
+  ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
+
+  if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
+    {
+      return ret; 
+    }
+
+  /* useally IPv6 interfaces have one link-local address and one global address */
+
+  for (uint32_t i = 1 ; i < m_ipv6->GetNAddresses (interface) ; i++)
+    {
+      Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
+
+      if (test.GetAddress ().CombinePrefix (test.GetPrefix ()) == dest.CombinePrefix (test.GetPrefix ()))
+        {
+          return test.GetAddress ();
+        }
+    }
+
+  return ret;
+}
+
+} /* namespace ns3 */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-static-routing.h	Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,299 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_STATIC_ROUTING_H
+#define IPV6_STATIC_ROUTING_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3
+{
+
+class Packet;
+class NetDevice;
+class Ipv6Interface;
+class Ipv6Route;
+class Node;
+class Ipv6RoutingTableEntry;
+class Ipv6MulticastRoutingTableEntry;
+
+/**
+ * \ingroup routing
+ * \defgroup ipv6StaticRouting Ipv6StaticRouting
+ */
+/**
+ * \ingroup ipv6StaticRouting
+ * \class Ipv6StaticRouting
+ * \brief Static routing protocol for IP version 6 stack.
+ * \see Ipv6RoutingProtocol
+ * \see Ipv6ListRouting
+ */
+class Ipv6StaticRouting : public Ipv6RoutingProtocol
+{
+public:
+  /**
+   * \brief The interface Id associated with this class.
+   * \return type identifier
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6StaticRouting ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6StaticRouting ();
+
+  /**
+   * \brief Add route to host.
+   * \param dest destination address
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix that should be used for source address for this destination
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
+
+  /**
+   * \brief Add route to host.
+   * \param dest destination address.
+   * \param interface interface index
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddHostRouteTo (Ipv6Address dest, uint32_t interface, uint32_t metric = 0);
+
+  /**
+   * \brief Add route to network.
+   * \param network network address
+   * \param networkPrefix network prefix*
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
+
+  /**
+   * \brief Add route to network.
+   * \param network network address
+   * \param networkPrefix network prefix*
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix that should be used for source address for this destination
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
+
+  /**
+   * \brief Add route to network.
+   * \param network network address
+   * \param networkPrefix network prefix
+   * \param interface interface index
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
+
+  /**
+   * \brief Set the default route.
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix to use (i.e for multihoming)
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
+
+  /**
+   * \brief Get the number or entries in the routing table.
+   * \return number of entries
+   */
+  uint32_t GetNRoutes ();
+
+  /**
+   * \brief Get the default route.
+   *
+   * If multiple default routes exist, the one with lowest metric is returned.
+   * \return default Ipv6Route
+   */
+  Ipv6RoutingTableEntry GetDefaultRoute ();
+
+  /**
+   * \brief Get a specified route.
+   * \param i index
+   * \return the route whose index is i
+   */
+  Ipv6RoutingTableEntry GetRoute (uint32_t i);
+
+  /**
+   * \brief Get a metric for route from the static unicast routing table.
+   * \param index The index (into the routing table) of the route to retrieve.  
+   * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
+   */
+  uint32_t GetMetric (uint32_t index);
+
+  /**
+   * \brief Remove a route from the routing table.
+   * \param i index
+   */
+  void RemoveRoute (uint32_t i);
+
+  /**
+   * \brief Remove a route from the routing table.
+   * \param network IPv6 network
+   * \param prefix IPv6 prefix
+   * \param ifIndex interface index
+   * \param prefixToUse IPv6 prefix to use with this route (multihoming)
+   */
+  void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
+
+  /**
+   * \brief Add a multicast route for a given multicast source and group.
+   * \param origin IPv6 address of the source
+   * \param group the multicast group address.
+   * \param inputInterface the interface index
+   * \param outputInterfaces the list of output interface indices over which the packet
+   * should be sent (excluding the inputInterface).
+   */
+  void AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+  /**
+   * \brief Set the default multicast route.
+   * \param outputInterface default output interface
+   */
+  void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+  /**
+   * \brief Get the number of entries in the multicast routing table.
+   * \return number of entries
+   */
+  uint32_t GetNMulticastRoutes () const;
+
+  /**
+   * \brief Get the specified multicast route.
+   * \param i index
+   * \return the route whose index is i
+   */
+  Ipv6MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
+
+  /**
+   * \brief Remove a static multicast route.
+   * \param origin IPv6 address of the source
+   * \param group the multicast group address.
+   * \param inputInterface the input interface index
+   */
+  bool RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface);
+
+  /**
+   * \brief Remove a multicast route.
+   * \param i index of route to remove
+   */
+  void RemoveMulticastRoute (uint32_t i);
+
+  /**
+   * \brief If the destination is already present in network destination list.
+   * \param dest destination address
+   * \param interfaceIndex interface index
+   * \return true if dest is already in list, false otherwise
+   */
+  bool HasNetworkDest (Ipv6Address dest, uint32_t interfaceIndex);
+
+  virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                            UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                            LocalDeliverCallback lcb, ErrorCallback ecb);
+
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+  virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+  virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+  virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+protected:
+  /**
+   * \brief Dispose this object.
+   */
+  void DoDispose ();
+
+private:
+  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
+  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
+  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
+
+  typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
+  typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
+  typedef std::list<Ipv6MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
+
+  /**
+   * \brief Lookup in the forwarding table for destination.
+   * \param dest destination address
+   * \param interface output interface if any (put 0 otherwise)
+   * \return Ipv6Route to route the packet to reach dest address
+   */
+  Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, Ptr<NetDevice> = 0);
+
+  /**
+   * \brief Lookup in the multicast forwarding table for destination.
+   * \param origin source address
+   * \param group group multicast address
+   * \param ifIndex interface index
+   * \return Ipv6MulticastRoute to route the packet to reach dest address
+   */
+  Ptr<Ipv6MulticastRoute> LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t ifIndex);
+
+  /**
+   * \brief Choose the source address to use with destination address.
+   * \param interface interface index
+   * \param dest IPv6 destination address
+   * \return IPv6 source address to use
+   */
+  Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
+
+  /**
+   * \brief the forwarding table for network.
+   */
+  NetworkRoutes m_networkRoutes;
+
+  /**
+   * \brief the forwarding table for multicast.
+   */
+  MulticastRoutes m_multicastRoutes;
+
+  /**
+   * \brief Ipv6 reference.
+   */
+  Ptr<Ipv6> m_ipv6;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_STATIC_ROUTING_H */
+
--- a/src/routing/static-routing/wscript	Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/static-routing/wscript	Tue Oct 26 18:02:17 2010 +0100
@@ -3,17 +3,21 @@
 def build(bld):
     module = bld.create_ns3_module('static-routing', ['node'])
     module.source = [
-        'ipv4-static-routing.cc',
-        'ipv4-routing-table-entry.cc',
-        'ipv6-static-routing.cc',
-        'ipv6-routing-table-entry.cc',
+        'model/ipv4-static-routing.cc',
+        'model/ipv4-routing-table-entry.cc',
+        'model/ipv6-static-routing.cc',
+        'model/ipv6-routing-table-entry.cc',
+        'helper/ipv4-static-routing-helper.cc',
+        'helper/ipv6-static-routing-helper.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'static-routing'
     headers.source = [
-        'ipv4-static-routing.h',
-        'ipv4-routing-table-entry.h',
-        'ipv6-static-routing.h',
-        'ipv6-routing-table-entry.h',
+        'model/ipv4-static-routing.h',
+        'model/ipv4-routing-table-entry.h',
+        'model/ipv6-static-routing.h',
+        'model/ipv6-routing-table-entry.h',
+        'helper/ipv4-static-routing-helper.h',
+        'helper/ipv6-static-routing-helper.h',
         ]