[bug 947] Pretty-print IPv4 routing tables (patch originated by Hemanth Narra)
authorTom Henderson <tomh@tomh.org>
Mon, 20 Dec 2010 16:34:59 -0800
changeset 6701 a590022a1536
parent 6700 1b4afd56648f
child 6702 af154b7ea2a2
[bug 947] Pretty-print IPv4 routing tables (patch originated by Hemanth Narra)
.hgignore
examples/routing/aodv.cc
examples/routing/dynamic-global-routing.cc
examples/routing/nix-simple.cc
examples/wireless/wifi-simple-adhoc-grid.cc
src/helper/ipv4-routing-helper.cc
src/helper/ipv4-routing-helper.h
src/node/ipv4-routing-protocol.h
src/routing/aodv/aodv-routing-protocol.cc
src/routing/aodv/aodv-routing-protocol.h
src/routing/aodv/aodv-rtable.cc
src/routing/aodv/aodv-rtable.h
src/routing/global-routing/model/ipv4-global-routing.cc
src/routing/global-routing/model/ipv4-global-routing.h
src/routing/list-routing/model/ipv4-list-routing.cc
src/routing/list-routing/model/ipv4-list-routing.h
src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc
src/routing/nix-vector-routing/ipv4-nix-vector-routing.h
src/routing/olsr/model/olsr-routing-protocol.cc
src/routing/olsr/model/olsr-routing-protocol.h
src/routing/static-routing/model/ipv4-static-routing.cc
src/routing/static-routing/model/ipv4-static-routing.h
--- a/.hgignore	Mon Dec 20 16:21:50 2010 -0800
+++ b/.hgignore	Mon Dec 20 16:34:59 2010 -0800
@@ -13,6 +13,7 @@
 .*\.py[co]$
 \.pcap$
 \.mob$
+\.routes$
 ^doc/manual/manual/
 doc/manual/manual.aux
 doc/manual/manual.cp
@@ -34,4 +35,4 @@
 \.patch$
 \.diff$
 \.tr$
-\#[^\#/]+\#$
\ No newline at end of file
+\#[^\#/]+\#$
--- a/examples/routing/aodv.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/examples/routing/aodv.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -65,6 +65,8 @@
   double totalTime;
   /// Write per-device PCAP traces if true
   bool pcap;
+  /// Print routes if true
+  bool printRoutes;
   //\}
   
   ///\name network
@@ -97,7 +99,8 @@
   size (10),
   step (100),
   totalTime (10),
-  pcap (true)
+  pcap (true),
+  printRoutes (true)
 {
 }
 
@@ -111,6 +114,7 @@
   CommandLine cmd;
   
   cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
+  cmd.AddValue ("printRoutes", "Print routing table dumps.", printRoutes);
   cmd.AddValue ("size", "Number of nodes.", size);
   cmd.AddValue ("time", "Simulation time, s.", totalTime);
   cmd.AddValue ("step", "Grid step, m", step);
@@ -194,6 +198,12 @@
   Ipv4AddressHelper address;
   address.SetBase ("10.0.0.0", "255.0.0.0");
   interfaces = address.Assign (devices);
+
+  if (printRoutes)
+    {
+      Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("aodv.routes", std::ios::out);
+      aodv.PrintRoutingTableAllAt (Seconds (8), routingStream);
+    }
 }
 
 void
--- a/examples/routing/dynamic-global-routing.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/examples/routing/dynamic-global-routing.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -214,6 +214,11 @@
   Simulator::Schedule (Seconds (12),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
   Simulator::Schedule (Seconds (14),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
 
+  // Trace routing tables 
+  Ipv4GlobalRoutingHelper g;
+  Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("dynamic-global-routing.routes", std::ios::out);
+  g.PrintRoutingTableAllAt (Seconds (12), routingStream);
+
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/routing/nix-simple.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/examples/routing/nix-simple.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -109,6 +109,9 @@
   clientApps.Start (Seconds (2.0));
   clientApps.Stop (Seconds (10.0));
 
+  // Trace routing tables
+  Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-simple.routes", std::ios::out);
+  nixRouting.PrintRoutingTableAllAt (Seconds (8), routingStream);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/wireless/wifi-simple-adhoc-grid.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/examples/wireless/wifi-simple-adhoc-grid.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -223,6 +223,9 @@
       AsciiTraceHelper ascii;
       wifiPhy.EnableAsciiAll (ascii.CreateFileStream ("wifi-simple-adhoc-grid.tr"));
       wifiPhy.EnablePcap ("wifi-simple-adhoc-grid", devices);
+      // Trace routing tables
+      Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("wifi-simple-adhoc-grid.routes", std::ios::out);
+      olsr.PrintRoutingTableAllEvery (Seconds (2), routingStream);
 
       // To do-- enable an IP-level trace that shows forwarding events only
     }
--- a/src/helper/ipv4-routing-helper.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/helper/ipv4-routing-helper.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -17,11 +17,67 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
+#include "ns3/node.h"
+#include "ns3/node-list.h"
+#include "ns3/simulator.h"
+#include "ns3/ipv4-routing-protocol.h"
 #include "ipv4-routing-helper.h"
 
 namespace ns3 {
 
 Ipv4RoutingHelper::~Ipv4RoutingHelper ()
-{}
+{
+}
+
+void
+Ipv4RoutingHelper::PrintRoutingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const
+{
+  for (uint32_t i = 0; i < NodeList::GetNNodes (); i++)
+    {
+      Ptr<Node> node = NodeList::GetNode (i);
+      Simulator::Schedule (printTime, &Ipv4RoutingHelper::Print, this, node, stream);
+    }
+}
+
+void
+Ipv4RoutingHelper::PrintRoutingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const
+{
+  for (uint32_t i = 0; i < NodeList::GetNNodes (); i++)
+    {
+      Ptr<Node> node = NodeList::GetNode (i);
+      Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintEvery, this, printInterval, node, stream);
+    }
+}
+
+void
+Ipv4RoutingHelper::PrintRoutingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const
+{
+  Simulator::Schedule (printTime, &Ipv4RoutingHelper::Print, this, node, stream);
+}
+
+void
+Ipv4RoutingHelper::PrintRoutingTableEvery (Time printInterval,Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const
+{
+  Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintEvery, this, printInterval, node, stream);
+}
+
+void
+Ipv4RoutingHelper::Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const
+{
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Ptr<Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
+  NS_ASSERT (rp);
+  rp->PrintRoutingTable (stream);
+}
+
+void
+Ipv4RoutingHelper::PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const
+{
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Ptr<Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
+  NS_ASSERT (rp);
+  rp->PrintRoutingTable (stream);
+  Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintEvery, this, printInterval, node, stream);
+}
 
 } // namespace ns3
--- a/src/helper/ipv4-routing-helper.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/helper/ipv4-routing-helper.h	Mon Dec 20 16:34:59 2010 -0800
@@ -21,6 +21,8 @@
 #define IPV4_ROUTING_HELPER_H
 
 #include "ns3/ptr.h"
+#include "ns3/nstime.h"
+#include "ns3/output-stream-wrapper.h"
 
 namespace ns3 {
 
@@ -58,6 +60,56 @@
    * \returns a newly-created routing protocol
    */
   virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const = 0;
+
+  /**
+   * \brief prints the routing tables of all nodes at a particular time.
+   * \param printTime the time at which the routing table is supposed to be printed.
+   * \param stream The output stream object to use 
+   *
+   * This method calls the PrintRoutingTable() method of the 
+   * Ipv4RoutingProtocol stored in the Ipv4 object, for all nodes at the
+   * specified time; the output format is routing protocol-specific.
+   */
+  void PrintRoutingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const;
+
+  /**
+   * \brief prints the routing tables of all nodes at regular intervals specified by user.
+   * \param printInterval the time interval for which the routing table is supposed to be printed.
+   * \param stream The output stream object to use
+   *
+   * This method calls the PrintRoutingTable() method of the 
+   * Ipv4RoutingProtocol stored in the Ipv4 object, for all nodes at the
+   * specified time interval; the output format is routing protocol-specific.
+   */
+  void PrintRoutingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const;
+
+  /**
+   * \brief prints the routing tables of a node at a particular time.
+   * \param printTime the time at which the routing table is supposed to be printed.
+   * \param node The node ptr for which we need the routing table to be printed
+   * \param stream The output stream object to use
+   *
+   * This method calls the PrintRoutingTable() method of the 
+   * Ipv4RoutingProtocol stored in the Ipv4 object, for the selected node 
+   * at the specified time; the output format is routing protocol-specific.
+   */
+  void PrintRoutingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+
+  /**
+   * \brief prints the routing tables of a node at regular intervals specified by user.
+   * \param printInterval the time interval for which the routing table is supposed to be printed.
+   * \param node The node ptr for which we need the routing table to be printed
+   * \param stream The output stream object to use
+   *
+   * This method calls the PrintRoutingTable() method of the 
+   * Ipv4RoutingProtocol stored in the Ipv4 object, for the selected node 
+   * at the specified interval; the output format is routing protocol-specific.
+   */
+  void PrintRoutingTableEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+
+private:
+  void Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+  void PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
 };
 
 } // namespace ns3
--- a/src/node/ipv4-routing-protocol.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/node/ipv4-routing-protocol.h	Mon Dec 20 16:34:59 2010 -0800
@@ -25,6 +25,7 @@
 #include "ipv4-header.h"
 #include "ipv4-interface-address.h"
 #include "ipv4.h"
+#include "ns3/output-stream-wrapper.h"
 
 namespace ns3 {
 
@@ -140,6 +141,8 @@
    * Typically, invoked directly or indirectly from ns3::Ipv4::SetRoutingProtocol
    */
   virtual void SetIpv4 (Ptr<Ipv4> ipv4) = 0;
+
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const = 0;
 };
 
 } //namespace ns3
--- a/src/routing/aodv/aodv-routing-protocol.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/aodv/aodv-routing-protocol.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -261,6 +261,13 @@
 }
 
 void
+RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now().GetSeconds () << "s ";
+  m_routingTable.Print (stream);
+}
+
+void
 RoutingProtocol::Start ()
 {
   NS_LOG_FUNCTION (this);
--- a/src/routing/aodv/aodv-routing-protocol.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/aodv/aodv-routing-protocol.h	Mon Dec 20 16:34:59 2010 -0800
@@ -34,6 +34,7 @@
 #include "aodv-neighbor.h"
 #include "aodv-dpd.h"
 #include "ns3/node.h"
+#include "ns3/output-stream-wrapper.h"
 #include "ns3/ipv4-routing-protocol.h"
 #include "ns3/ipv4-interface.h"
 #include "ns3/ipv4-l3-protocol.h"
@@ -58,7 +59,7 @@
   RoutingProtocol ();
   virtual ~RoutingProtocol();
   virtual void DoDispose ();
-  
+
   ///\name From Ipv4RoutingProtocol
   //\{
   Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
@@ -70,6 +71,7 @@
   virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
   //\}
   
   ///\name Handle protocol parameters
--- a/src/routing/aodv/aodv-rtable.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/aodv/aodv-rtable.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -28,6 +28,7 @@
 
 #include "aodv-rtable.h"
 #include <algorithm>
+#include <iomanip>
 #include "ns3/simulator.h"
 #include "ns3/log.h"
 
@@ -155,30 +156,34 @@
 }
 
 void
-RoutingTableEntry::Print (std::ostream & os) const
+RoutingTableEntry::Print (Ptr<OutputStreamWrapper> stream) const
 {
-  os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
+  std::ostream* os = stream->GetStream();
+  *os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
       << "\t" << m_iface.GetLocal () << "\t";
   switch (m_flag)
     {
     case VALID:
       {
-        os << "UP";
+        *os << "UP";
         break;
       }
     case INVALID:
       {
-        os << "DOWN";
+        *os << "DOWN";
         break;
       }
     case IN_SEARCH:
       {
-        os << "IN_SEARCH";
+        *os << "IN_SEARCH";
         break;
       }
     }
-  os << "\t" << (m_lifeTime - Simulator::Now ()).GetSeconds () << "\t"
-      << m_hops << "\n";
+  *os << "\t";
+  *os << std::setiosflags (std::ios::fixed) << 
+    std::setiosflags (std::ios::left) << std::setprecision (2) << 
+    std::setw (14) << (m_lifeTime - Simulator::Now ()).GetSeconds (); 
+  *os << "\t" << m_hops << "\n";
 }
 
 /*
@@ -378,6 +383,39 @@
     }
 }
 
+void
+RoutingTable::Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const
+{
+  NS_LOG_FUNCTION (this);
+  if (table.empty ())
+    return;
+  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
+      table.begin (); i != table.end ();)
+    {
+      if (i->second.GetLifeTime () < Seconds (0))
+        {
+          if (i->second.GetFlag () == INVALID)
+            {
+              std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
+              ++i;
+              table.erase (tmp);
+            }
+          else if (i->second.GetFlag () == VALID)
+            {
+              NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
+              i->second.Invalidate (m_badLinkLifetime);
+              ++i;
+            }
+          else
+            ++i;
+        }
+      else 
+        {
+          ++i;
+        }
+    }
+}
+
 bool
 RoutingTable::MarkLinkAsUnidirectional (Ipv4Address neighbor, Time blacklistTimeout)
 {
@@ -397,17 +435,18 @@
 }
 
 void
-RoutingTable::Print (std::ostream &os)
+RoutingTable::Print (Ptr<OutputStreamWrapper> stream) const
 {
-  Purge ();
-  os << "\nAODV Routing table\n"
-      << "Destination\tGateway\t\tInterface\tFlag\tExpire\tHops\n";
+  std::map<Ipv4Address, RoutingTableEntry> table = m_ipv4AddressEntry;
+  Purge (table);
+  *stream->GetStream () << "\nAODV Routing table\n"
+      << "Destination\tGateway\t\tInterface\tFlag\tExpire\t\tHops\n";
   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
-      m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
+      table.begin (); i != table.end (); ++i)
     {
-      i->second.Print (os);
+      i->second.Print (stream);
     }
-  os << "\n";
+  *stream->GetStream () << "\n";
 }
 
 }
--- a/src/routing/aodv/aodv-rtable.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/aodv/aodv-rtable.h	Mon Dec 20 16:34:59 2010 -0800
@@ -36,6 +36,7 @@
 #include "ns3/ipv4-route.h"
 #include "ns3/timer.h"
 #include "ns3/net-device.h"
+#include "ns3/output-stream-wrapper.h"
 
 namespace ns3 {
 namespace aodv {
@@ -140,7 +141,7 @@
   {
     return (m_ipv4Route->GetDestination () == dst);
   }
-  void Print(std::ostream & os) const;
+  void Print(Ptr<OutputStreamWrapper> stream) const;
 
 private:
   /// Valid Destination Sequence Number flag
@@ -242,12 +243,14 @@
    */
   bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout);
   /// Print routing table
-  void Print(std::ostream &os);
+  void Print(Ptr<OutputStreamWrapper> stream) const;
 
 private:
   std::map<Ipv4Address, RoutingTableEntry> m_ipv4AddressEntry;
   /// Deletion time for invalid routes
   Time m_badLinkLifetime;
+  /// const version of Purge, for use by Print() method
+  void Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const;
 };
 
 }}
--- a/src/routing/global-routing/model/ipv4-global-routing.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/global-routing/model/ipv4-global-routing.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -16,6 +16,9 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 //
 
+#include <vector>
+#include <iomanip>
+#include "ns3/names.h"
 #include "ns3/log.h"
 #include "ns3/simulator.h"
 #include "ns3/object.h"
@@ -26,7 +29,6 @@
 #include "ns3/boolean.h"
 #include "ipv4-global-routing.h"
 #include "global-route-manager.h"
-#include <vector>
 
 NS_LOG_COMPONENT_DEFINE ("Ipv4GlobalRouting");
 
@@ -240,7 +242,7 @@
 }
 
 uint32_t 
-Ipv4GlobalRouting::GetNRoutes (void)
+Ipv4GlobalRouting::GetNRoutes (void) const
 {
   NS_LOG_FUNCTION_NOARGS ();
   uint32_t n = 0;
@@ -251,7 +253,7 @@
 }
 
 Ipv4RoutingTableEntry *
-Ipv4GlobalRouting::GetRoute (uint32_t index)
+Ipv4GlobalRouting::GetRoute (uint32_t index) const
 {
   NS_LOG_FUNCTION (index);
   if (index < m_hostRoutes.size ())
@@ -272,7 +274,7 @@
   uint32_t tmp = 0;
   if (index < m_networkRoutes.size())
     {
-      for (NetworkRoutesI j = m_networkRoutes.begin (); 
+      for (NetworkRoutesCI j = m_networkRoutes.begin (); 
           j != m_networkRoutes.end (); 
           j++) 
         {
@@ -285,7 +287,7 @@
     }
   index -= m_networkRoutes.size();
   tmp = 0;
-  for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); 
+  for (ASExternalRoutesCI k = m_ASexternalRoutes.begin (); 
        k != m_ASexternalRoutes.end (); 
        k++) 
   {
@@ -382,6 +384,53 @@
   Ipv4RoutingProtocol::DoDispose ();
 }
 
+// Formatted like output of "route -n" command
+void
+Ipv4GlobalRouting::PrintRoutingTable(Ptr<OutputStreamWrapper> stream) const
+{
+  std::ostream* os = stream->GetStream();
+  if (GetNRoutes () > 0)
+    {
+      *os << "Destination     Gateway         Genmask         Flags Metric Ref    Use Iface" << std::endl;
+      for (uint32_t j = 0; j < GetNRoutes (); j++)
+        {
+          std::ostringstream dest, gw, mask, flags;
+          Ipv4RoutingTableEntry route = GetRoute (j);
+          dest << route.GetDest ();
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
+          gw << route.GetGateway ();
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str();
+          mask << route.GetDestNetworkMask ();
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << mask.str();
+          flags << "U";
+          if (route.IsHost ())
+            {
+              flags << "H";
+            }
+          else if (route.IsGateway ())
+            {
+              flags << "G";
+            }
+          *os << std::setiosflags (std::ios::left) << std::setw (6) << flags.str();
+          // Metric not implemented
+          *os << "-" << "      ";
+          // Ref ct not implemented
+          *os << "-" << "      ";
+          // Use not implemented
+          *os << "-" << "   ";
+          if (Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ())) != "")
+            {
+              *os << Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ()));
+            }
+          else
+            {
+              *os << route.GetInterface();
+            }
+          *os << std::endl;
+        }
+    }
+}
+
 Ptr<Ipv4Route>
 Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
 {      
--- a/src/routing/global-routing/model/ipv4-global-routing.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/global-routing/model/ipv4-global-routing.h	Mon Dec 20 16:34:59 2010 -0800
@@ -92,6 +92,7 @@
   virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
 
 /**
  * \brief Add a host route to the global routing table.
@@ -168,7 +169,7 @@
  *
  * \warning The default route counts as one of the routes.
  */
-  uint32_t GetNRoutes (void);
+  uint32_t GetNRoutes (void) const;
 
 /**
  * \brief Get a route from the global unicast routing table.
@@ -190,7 +191,7 @@
  * \see Ipv4RoutingTableEntry
  * \see Ipv4GlobalRouting::RemoveRoute
  */
-  Ipv4RoutingTableEntry *GetRoute (uint32_t i);
+  Ipv4RoutingTableEntry *GetRoute (uint32_t i) const;
 
 /**
  * \brief Remove a route from the global unicast routing table.
--- a/src/routing/list-routing/model/ipv4-list-routing.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/list-routing/model/ipv4-list-routing.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -69,6 +69,21 @@
 }
 
 void
+Ipv4ListRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () 
+    << " Time: " << Simulator::Now().GetSeconds () << "s " 
+    << "Ipv4ListRouting table" << std::endl;
+  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+      i != m_routingProtocols.end (); i++)
+      {
+        *stream->GetStream () << "  Priority: " << (*i).first << " Protocol: " << (*i).second->GetInstanceTypeId () << std::endl;
+        (*i).second->PrintRoutingTable (stream);
+      }
+  *stream->GetStream () << std::endl;
+}
+
+void
 Ipv4ListRouting::DoStart (void)
 {
   for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
@@ -297,6 +312,7 @@
   void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
   void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
   void SetIpv4 (Ptr<Ipv4> ipv4) {}
+  void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const {}
 };
 
 class Ipv4BRouting : public Ipv4RoutingProtocol {
@@ -310,6 +326,7 @@
   void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
   void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
   void SetIpv4 (Ptr<Ipv4> ipv4) {}
+  void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const {}
 };
 
 class Ipv4ListRoutingNegativeTestCase : public TestCase
--- a/src/routing/list-routing/model/ipv4-list-routing.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/list-routing/model/ipv4-list-routing.h	Mon Dec 20 16:34:59 2010 -0800
@@ -21,6 +21,7 @@
 
 #include <list>
 #include "ns3/ipv4-routing-protocol.h"
+#include "ns3/simulator.h"
 
 namespace ns3 {
 
@@ -85,6 +86,7 @@
   virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
 
 protected:
   void DoDispose (void);
--- a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -19,9 +19,11 @@
  */
 
 #include <queue>
+#include <iomanip>
 
 #include "ns3/log.h"
 #include "ns3/abort.h"
+#include "ns3/names.h"
 #include "ns3/ipv4-list-routing.h"
 
 #include "ipv4-nix-vector-routing.h"
@@ -657,6 +659,50 @@
   return true;
 }
 
+void
+Ipv4NixVectorRouting::PrintRoutingTable(Ptr<OutputStreamWrapper> stream) const
+{
+
+  std::ostream* os = stream->GetStream();
+  *os << "NixCache:" << std::endl;
+  if (m_nixCache.size () > 0)
+    {
+      *os << "Destination     NixVector" << std::endl;
+      for (NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
+        {
+          std::ostringstream dest;
+          dest << it->first;
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
+          *os << *(it->second) << std::endl;
+        }
+    }
+  *os << "Ipv4RouteCache:" << std::endl;
+  if (m_ipv4RouteCache.size () > 0)
+    {
+      *os  << "Destination     Gateway         Source            OutputDevice" << std::endl;
+      for (Ipv4RouteMap_t::const_iterator it = m_ipv4RouteCache.begin (); it != m_ipv4RouteCache.end (); it++)
+        {
+          std::ostringstream dest, gw, src;
+          dest << it->second->GetDestination ();
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
+          gw << it->second->GetGateway ();
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str();
+          src << it->second->GetSource ();
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << src.str();
+          *os << "  ";
+          if (Names::FindName (it->second->GetOutputDevice ()) != "")
+            {
+              *os << Names::FindName (it->second->GetOutputDevice ());
+            }
+          else
+            {
+              *os << it->second->GetOutputDevice ()->GetIfIndex ();
+            }
+          *os << std::endl;
+        }
+    }
+}
+
 // virtual functions from Ipv4RoutingProtocol 
 void
 Ipv4NixVectorRouting::NotifyInterfaceUp (uint32_t i)
--- a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/nix-vector-routing/ipv4-nix-vector-routing.h	Mon Dec 20 16:34:59 2010 -0800
@@ -29,6 +29,7 @@
 #include "ns3/net-device-container.h"
 #include "ns3/ipv4-routing-protocol.h"
 #include "ns3/ipv4-route.h"
+#include "ns3/nix-vector.h"
 #include "ns3/bridge-net-device.h"
 
 namespace ns3 {
@@ -149,6 +150,7 @@
     virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address); 
     virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address); 
     virtual void SetIpv4 (Ptr<Ipv4> ipv4); 
+    virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
 
 
     /* cache stores nix-vectors based on destination ip */
--- a/src/routing/olsr/model/olsr-routing-protocol.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/olsr/model/olsr-routing-protocol.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -38,6 +38,7 @@
 #include "ns3/udp-socket-factory.h"
 #include "ns3/simulator.h"
 #include "ns3/log.h"
+#include "ns3/names.h"
 #include "ns3/random-variable.h"
 #include "ns3/inet-socket-address.h"
 #include "ns3/ipv4-routing-protocol.h"
@@ -244,6 +245,31 @@
   Ipv4RoutingProtocol::DoDispose ();
 }
 
+void
+RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+  std::ostream* os = stream->GetStream();
+  *os << "Destination\tNextHop\t\tInterface\tDistance\n";
+
+  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
+    iter != m_table.end (); iter++)
+    {
+      *os << iter->first << "\t";
+      *os << iter->second.nextAddr << "\t";
+      if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
+            {
+              *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
+            }
+          else
+            {
+              *os << iter->second.interface << "\t\t";
+            }
+
+      *os << iter->second.distance << "\t";
+      *os << "\n";
+    }
+}
+
 void RoutingProtocol::DoStart ()
 {
   if (m_mainAddress == Ipv4Address ())
--- a/src/routing/olsr/model/olsr-routing-protocol.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/olsr/model/olsr-routing-protocol.h	Mon Dec 20 16:34:59 2010 -0800
@@ -184,6 +184,7 @@
   virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
 
 
   void DoDispose ();
--- a/src/routing/static-routing/model/ipv4-static-routing.cc	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/static-routing/model/ipv4-static-routing.cc	Mon Dec 20 16:34:59 2010 -0800
@@ -23,11 +23,14 @@
       std::clog << Simulator::Now ().GetSeconds () \
       << " [node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
 
+#include <iomanip>
 #include "ns3/log.h"
+#include "ns3/names.h"
 #include "ns3/packet.h"
 #include "ns3/node.h"
 #include "ns3/simulator.h"
 #include "ns3/ipv4-route.h"
+#include "ns3/output-stream-wrapper.h"
 #include "ipv4-static-routing.h"
 #include "ipv4-routing-table-entry.h"
 
@@ -346,7 +349,7 @@
 }
 
 uint32_t 
-Ipv4StaticRouting::GetNRoutes (void)
+Ipv4StaticRouting::GetNRoutes (void) const
 {
   NS_LOG_FUNCTION (this);
   return m_networkRoutes.size ();;
@@ -391,11 +394,11 @@
 }
 
 Ipv4RoutingTableEntry 
-Ipv4StaticRouting::GetRoute (uint32_t index)
+Ipv4StaticRouting::GetRoute (uint32_t index) const
 {
   NS_LOG_FUNCTION (this << index);
   uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+  for (NetworkRoutesCI j = m_networkRoutes.begin (); 
        j != m_networkRoutes.end (); 
        j++) 
         {
@@ -699,6 +702,53 @@
     }
 }
 
+// Formatted like output of "route -n" command
+void
+Ipv4StaticRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+  std::ostream* os = stream->GetStream();
+  if (GetNRoutes () > 0)
+    {
+      *os  << "Destination     Gateway         Genmask         Flags Metric Ref    Use Iface" << std::endl;
+      for (uint32_t j = 0; j < GetNRoutes (); j++)
+        {
+          std::ostringstream dest, gw, mask, flags;
+          Ipv4RoutingTableEntry route = GetRoute (j);
+          dest << route.GetDest (); 
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str();
+          gw << route.GetGateway (); 
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str();
+          mask << route.GetDestNetworkMask (); 
+          *os << std::setiosflags (std::ios::left) << std::setw (16) << mask.str();
+          flags << "U";
+          if (route.IsHost ())
+            {
+              flags << "HS";
+            }
+          else if (route.IsGateway ())
+            {
+              flags << "GS";
+            }
+          *os << std::setiosflags (std::ios::left) << std::setw (6) << flags.str();
+          // Metric not implemented
+          *os << "-" << "      ";
+          // Ref ct not implemented
+          *os << "-" << "      ";
+          // Use not implemented
+          *os << "-" << "   ";
+          if (Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ())) != "")
+            {
+              *os << Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ()));
+            }
+          else
+            {
+              *os << route.GetInterface();
+            }
+          *os << std::endl;
+        }
+    }
+}
+
 Ipv4Address
 Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
 {
--- a/src/routing/static-routing/model/ipv4-static-routing.h	Mon Dec 20 16:21:50 2010 -0800
+++ b/src/routing/static-routing/model/ipv4-static-routing.h	Mon Dec 20 16:34:59 2010 -0800
@@ -85,6 +85,7 @@
   virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
 
 /**
  * \brief Add a network route to the static routing table.
@@ -177,7 +178,7 @@
  *
  * \warning The default route counts as one of the routes.
  */
-  uint32_t GetNRoutes (void);
+  uint32_t GetNRoutes (void) const;
 
 /**
  * \brief Get the default route with lowest metric from the static routing table.
@@ -203,7 +204,7 @@
  * \see Ipv4RoutingTableEntry
  * \see Ipv4StaticRouting::RemoveRoute
  */
-  Ipv4RoutingTableEntry GetRoute (uint32_t i);
+  Ipv4RoutingTableEntry GetRoute (uint32_t i) const;
 
 /**
  * \brief Get a metric for route from the static unicast routing table.