checkpoint
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 09 Jul 2007 15:16:27 -0700
changeset 1048 9bbf68fe9c09
parent 1047 9c3940d40698
child 1049 b572b65faba3
child 1050 ff779ca8ccb6
checkpoint
examples/simple-static-routing.cc
src/devices/p2p/p2p-channel.cc
src/devices/p2p/p2p-channel.h
src/node/channel.h
src/routing/static-route-manager.cc
src/routing/static-router.cc
src/routing/static-router.h
--- a/examples/simple-static-routing.cc	Sun Jul 08 15:30:17 2007 -0700
+++ b/examples/simple-static-routing.cc	Mon Jul 09 15:16:27 2007 -0700
@@ -42,6 +42,8 @@
 #include <string>
 #include <cassert>
 
+#include "ns3/debug.h"
+
 #include "ns3/command-line.h"
 #include "ns3/default-value.h"
 #include "ns3/ptr.h"
@@ -80,6 +82,7 @@
   DebugComponentEnable("PointToPointChannel");
   DebugComponentEnable("PointToPointNetDevice");
 #endif
+  DebugComponentEnable("StaticRouter");
 
   // Set up some default values for the simulation.  Use the Bind()
   // technique to tell the system what subclass of Queue to use,
@@ -152,7 +155,6 @@
   PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
   PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
 
-
   // Create the OnOff application to send UDP datagrams of size
   // 210 bytes at a rate of 448 Kb/s
   Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
--- a/src/devices/p2p/p2p-channel.cc	Sun Jul 08 15:30:17 2007 -0700
+++ b/src/devices/p2p/p2p-channel.cc	Mon Jul 09 15:16:27 2007 -0700
@@ -1,8 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2007 University of Washington
- * All rights reserved.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation;
@@ -15,8 +12,6 @@
  * 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>
  */
 
 #include "p2p-channel.h"
@@ -32,6 +27,7 @@
 //
 // By default, you get a channel with the name "PointToPoint Channel" that 
 // has an "infitely" fast transmission speed and zero delay.
+//
 PointToPointChannel::PointToPointChannel()
 : 
   Channel ("PointToPoint Channel"), 
@@ -91,7 +87,7 @@
     }
 }
 
-bool
+  bool
 PointToPointChannel::TransmitStart(Packet& p, Ptr<PointToPointNetDevice> src)
 {
   NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << 
@@ -116,7 +112,7 @@
   return true;
 }
 
-bool
+  bool
 PointToPointChannel::TransmitEnd(Packet& p, Ptr<PointToPointNetDevice> src)
 {
   NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")");
@@ -144,7 +140,7 @@
   return true;
 }
 
-void
+  void
 PointToPointChannel::PropagationCompleteEvent(
   Packet p, 
   Ptr<PointToPointNetDevice> src)
@@ -162,20 +158,25 @@
   m_link[wire].m_dst->Receive (p);
 }
 
-
-uint32_t 
+  uint32_t 
 PointToPointChannel::GetNDevices (void) const
 {
   return m_nDevices;
 }
 
-Ptr<NetDevice>
+  Ptr<NetDevice>
 PointToPointChannel::GetDevice (uint32_t i) const
 {
   NS_ASSERT(i < 2);
   return m_link[i].m_src;
 }
 
+  Channel::ChannelType 
+PointToPointChannel::GetType (void) const
+{
+  return Channel::PointToPoint;
+}
+
   DataRate
 PointToPointChannel::GetDataRate (void)
 {
@@ -188,5 +189,4 @@
   return m_delay;
 }
 
-
 } // namespace ns3
--- a/src/devices/p2p/p2p-channel.h	Sun Jul 08 15:30:17 2007 -0700
+++ b/src/devices/p2p/p2p-channel.h	Mon Jul 09 15:16:27 2007 -0700
@@ -1,7 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 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;
@@ -96,6 +94,8 @@
   virtual uint32_t GetNDevices (void) const;
   virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
 
+  virtual ChannelType GetType (void) const;
+
   virtual DataRate GetDataRate (void);
   virtual Time GetDelay (void);
 
--- a/src/node/channel.h	Sun Jul 08 15:30:17 2007 -0700
+++ b/src/node/channel.h	Mon Jul 09 15:16:27 2007 -0700
@@ -1,7 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 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;
@@ -14,11 +12,8 @@
  * 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.washingon.edu>
- *
- *      Wed Feb 14 16:05:46 PST 2007 craigdo:  Created
  */
+
 #ifndef CHANNEL_H
 #define CHANNEL_H
 
@@ -41,6 +36,13 @@
 {
 public:
   static const InterfaceId iid;
+  enum ChannelType
+    {
+      Unknown = 0,
+      PointToPoint,
+      Multipoint
+    };
+
   Channel ();
   Channel (std::string name);
 
@@ -61,9 +63,18 @@
    */
   virtual Ptr<NetDevice> GetDevice (uint32_t i) const = 0;
 
+  /**
+   * \returns the abstract type of this channel.  Right now this is only
+   * PointToPoint (p2p) or Multipoint (Ethernet).
+   *
+   * This method must be implemented by subclasses.
+   */
+  virtual ChannelType GetType (void) const = 0;
+
 protected:
-  virtual ~Channel ();
-  std::string m_name;
+  virtual      ~Channel ();
+  std::string   m_name;
+  ChannelType   m_channelType;
 
 private:
 };
--- a/src/routing/static-route-manager.cc	Sun Jul 08 15:30:17 2007 -0700
+++ b/src/routing/static-route-manager.cc	Mon Jul 09 15:16:27 2007 -0700
@@ -44,6 +44,13 @@
     {
       Ptr<Node> node = *i;
       NS_DEBUG_UNCOND ("node="<< node->GetId () );
+
+      Ptr<StaticRouter> rtr = 
+        node->QueryInterface<StaticRouter> (StaticRouter::iid);
+      NS_ASSERT_MSG(rtr, "QI for <StaticRouter> interface failed");
+
+      uint32_t numLSAs = rtr->GetNumLSAs();
+      NS_DEBUG_UNCOND (numLSAs << "LSAs");
     }
 }
 
@@ -84,6 +91,7 @@
 {
   DebugComponentEnable("StaticRouteManager");
   bool ok = true;
+#if 0
   StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord();
   lr1->m_linkId.Set(1);
   lr1->m_linkData.Set(0xffffffff);
@@ -95,6 +103,7 @@
   lsa1->Add(lr1);
   
   delete lsa1;
+#endif
   return ok;
 }
 
--- a/src/routing/static-router.cc	Sun Jul 08 15:30:17 2007 -0700
+++ b/src/routing/static-router.cc	Mon Jul 09 15:16:27 2007 -0700
@@ -15,44 +15,61 @@
  */
 
 #include "ns3/debug.h"
+#include "ns3/assert.h"
+#include "ns3/channel.h"
+#include "ns3/net-device.h"
 #include "ns3/internet-node.h"
+#include "ns3/ipv4.h"
 #include "static-router.h"
 
 NS_DEBUG_COMPONENT_DEFINE ("StaticRouter");
 
 namespace ns3 {
 
-StaticRouterLSA::StaticRouterLSA () : 
-  m_linkStateId(0x66666666), m_advertisingRtr(0x66666666)
+StaticRouterLSA::StaticRouterLSA()
+  : 
+  m_linkStateId("0.0.0.0"),
+  m_advertisingRtr("0.0.0.0"),
+  m_linkRecords()
 {
   NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()");
 }
-StaticRouterLSA::~StaticRouterLSA ()
+
+StaticRouterLSA::~StaticRouterLSA()
 {
   NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ()");
-  for (m_iter = m_listOfLinkRecords.begin(); 
-    m_iter != m_listOfLinkRecords.end(); m_iter++)
-  {
-    StaticRouterLinkRecord* temp = *m_iter;
-    delete temp;
-  }
+
+  for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
+        i != m_linkRecords.end (); 
+        i++)
+    {
+      NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ():  free link record");
+
+      StaticRouterLinkRecord *p = *i;
+      delete p;
+      p = 0;
+
+      *i = 0;
+    }
+  NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ():  clear list");
+  m_linkRecords.clear();
 }
 
-uint32_t
-StaticRouterLSA::Add (StaticRouterLinkRecord* lr)
+  uint32_t
+StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr)
 {
-  m_listOfLinkRecords.push_back (lr);
-  return m_listOfLinkRecords.size ();
+  m_linkRecords.push_back (lr);
+  return m_linkRecords.size ();
 }
 
 const InterfaceId StaticRouter::iid = 
   MakeInterfaceId ("StaticRouter", Object::iid);
 
 StaticRouter::StaticRouter (Ptr<Node> node)
-  : m_node(node)
+  : m_node(node), m_numLSAs(0)
 {
+  NS_DEBUG("StaticRouter::StaticRouter ()");
   SetInterfaceId (StaticRouter::iid);
-  NS_DEBUG("StaticRouter::StaticRouter ()");
 }
 
 StaticRouter::~StaticRouter ()
@@ -60,4 +77,118 @@
   NS_DEBUG("StaticRouter::~StaticRouter ()");
 }
 
+//
+// Return the number of Link State Advertisements this node has to advertise.
+// 
+  uint32_t 
+StaticRouter::GetNumLSAs (void)
+{
+  NS_DEBUG("StaticRouter::GetNumLSAs ()");
+  NS_ASSERT_MSG(m_node, "<Node> interface not set");
+//
+// 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.
+//
+  Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+  NS_ASSERT_MSG(ipv4, "QI for <Ipv4> interface failed");
+//
+// Now, we need to ask Ipv4 for the number of interfaces attached to this 
+// node. This isn't necessarily equal to the number of links to adjacent 
+// nodes (other routers); the number of interfaces may include interfaces
+// connected to stub networks (e.g., ethernets, etc.).  So we have to walk
+// through the list of net devices and see if they are directly connected
+// to another router.
+//
+// We'll start out at the maximum possible number of LSAs and reduce that
+// number if we discover a link that's not actually connected to another
+// router.
+//
+  m_numLSAs = ipv4->GetNInterfaces();
+
+  NS_DEBUG("StaticRouter::GetNumLSAs (): m_numLSAs = " << m_numLSAs);
+
+  for (uint32_t i = 0; i < m_numLSAs; ++i)
+    {
+      Ptr<NetDevice> nd = ipv4->GetNetDevice(i);
+      Ptr<Channel> ch = nd->GetChannel();
+
+      if (!nd->IsPointToPoint ())
+        {
+          NS_DEBUG("StaticRouter::GetNumLSAs (): non-point-to-point device");
+          --m_numLSAs;
+          continue;
+        }
+
+      NS_DEBUG("StaticRouter::GetNumLSAs (): point-to-point device");
+//
+// Find the net device on the other end of the point-to-point channel.  This
+// is where our adjacent router is running.  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 and then ask the Ipv4 for the IP
+// address.  To do this, we have to get the interface index associated with 
+// that net device in order to find the correct interface on the adjacent node.
+//
+      Ptr<NetDevice> ndAdjacent = GetAdjacent(nd, ch);
+      uint32_t ifIndexAdjacent = ndAdjacent->GetIfIndex();
+      Ptr<Node> nodeAdjacent = ndAdjacent->GetNode();
+      Ptr<Ipv4> ipv4Adjacent = nodeAdjacent->QueryInterface<Ipv4> (Ipv4::iid);
+      NS_ASSERT_MSG(ipv4Adjacent, "QI for adjacent <Ipv4> interface failed");
+//
+// Okay, all of the preliminaries are done.  We can get the IP address and
+// net mask for the adjacent router.
+//
+      Ipv4Address addrAdjacent = ipv4Adjacent->GetAddress(ifIndexAdjacent);
+      Ipv4Mask maskAdjacent = ipv4->GetNetworkMask(ifIndexAdjacent);
+
+      NS_DEBUG("StaticRouter::GetNumLSAs (): Adjacent to " << addrAdjacent <<
+        " & " << maskAdjacent);
+    }
+
+  return m_numLSAs;
+}
+
+  bool
+StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa)
+{
+  return false;
+}
+
+  Ptr<NetDevice>
+StaticRouter::GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch)
+{
+//
+// Double-check that channel agrees with device that it's a point-to-point
+//
+  NS_ASSERT(ch->GetType () == Channel::PointToPoint);
+
+  uint32_t nDevices = ch->GetNDevices();
+  NS_ASSERT_MSG(nDevices == 2, 
+    "Point to point channel with other than two devices is not expected");
+//
+// 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(0, 
+        "Neither channel endpoint thinks it is connected to this net device");
+      return 0;
+    }
+}
+
 } // namespace ns3
--- a/src/routing/static-router.h	Sun Jul 08 15:30:17 2007 -0700
+++ b/src/routing/static-router.h	Mon Jul 09 15:16:27 2007 -0700
@@ -21,6 +21,7 @@
 #include "ns3/object.h"
 #include "ns3/ptr.h"
 #include "ns3/node.h"
+#include "ns3/channel.h"
 #include "ns3/ipv4-address.h"
 
 namespace ns3 {
@@ -69,16 +70,15 @@
 {
 public:
   StaticRouterLSA();
-  virtual ~StaticRouterLSA ();
-  uint32_t Add (StaticRouterLinkRecord* lr);
+  ~StaticRouterLSA();
 
-public:
+  uint32_t AddLinkRecord (StaticRouterLinkRecord* lr);
+
   Ipv4Address  m_linkStateId;     // set to the NodeId
   Ipv4Address  m_advertisingRtr;  // set to the NodeId
 
-  typedef std::list<StaticRouterLinkRecord*> type_listOfLinkRecords;
-  type_listOfLinkRecords m_listOfLinkRecords;
-  type_listOfLinkRecords::iterator m_iter;
+  typedef std::list<StaticRouterLinkRecord*> ListOfLinkRecords_t;
+  ListOfLinkRecords_t m_linkRecords;
 };
 
 /**
@@ -102,8 +102,12 @@
 protected:
   virtual ~StaticRouter ();
 
+  Ptr<Node>     m_node;
+  uint32_t      m_numLSAs;
+
+  Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch);
+
 private:
-  Ptr<Node> m_node;
 };
 
 } // namespace ns3