diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 86726f827..bb9dcf21e 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -42,6 +42,8 @@ #include #include +#include "ns3/debug.h" + #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" @@ -80,6 +82,7 @@ int main (int argc, char *argv[]) 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 @@ int main (int argc, char *argv[]) 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 ooff = Create ( diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/p2p/p2p-channel.cc index 2833c8bb1..c91fe368c 100644 --- a/src/devices/p2p/p2p-channel.cc +++ b/src/devices/p2p/p2p-channel.cc @@ -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 */ #include "p2p-channel.h" @@ -32,6 +27,7 @@ namespace ns3 { // // 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 @@ PointToPointChannel::Attach(Ptr device) } } -bool + bool PointToPointChannel::TransmitStart(Packet& p, Ptr src) { NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << @@ -116,7 +112,7 @@ PointToPointChannel::TransmitStart(Packet& p, Ptr src) return true; } -bool + bool PointToPointChannel::TransmitEnd(Packet& p, Ptr src) { NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")"); @@ -144,7 +140,7 @@ PointToPointChannel::TransmitEnd(Packet& p, Ptr src) return true; } -void + void PointToPointChannel::PropagationCompleteEvent( Packet p, Ptr src) @@ -162,20 +158,25 @@ PointToPointChannel::PropagationCompleteEvent( m_link[wire].m_dst->Receive (p); } - -uint32_t + uint32_t PointToPointChannel::GetNDevices (void) const { return m_nDevices; } -Ptr + Ptr 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 @@ PointToPointChannel::GetDelay (void) return m_delay; } - } // namespace ns3 diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/p2p/p2p-channel.h index 97a251177..6bd849741 100644 --- a/src/devices/p2p/p2p-channel.h +++ b/src/devices/p2p/p2p-channel.h @@ -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 @@ public: virtual uint32_t GetNDevices (void) const; virtual Ptr GetDevice (uint32_t i) const; + virtual ChannelType GetType (void) const; + virtual DataRate GetDataRate (void); virtual Time GetDelay (void); diff --git a/src/node/channel.h b/src/node/channel.h index b2feb280b..0fa8d9656 100644 --- a/src/node/channel.h +++ b/src/node/channel.h @@ -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 - * - * Wed Feb 14 16:05:46 PST 2007 craigdo: Created */ + #ifndef CHANNEL_H #define CHANNEL_H @@ -41,6 +36,13 @@ class Channel : public Object { public: static const InterfaceId iid; + enum ChannelType + { + Unknown = 0, + PointToPoint, + Multipoint + }; + Channel (); Channel (std::string name); @@ -61,9 +63,18 @@ public: */ virtual Ptr 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: }; diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index f9e56a841..6e9eb67a3 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -44,6 +44,13 @@ StaticRouteManager::BuildStaticRoutingDatabase () { Ptr node = *i; NS_DEBUG_UNCOND ("node="<< node->GetId () ); + + Ptr rtr = + node->QueryInterface (StaticRouter::iid); + NS_ASSERT_MSG(rtr, "QI for interface failed"); + + uint32_t numLSAs = rtr->GetNumLSAs(); + NS_DEBUG_UNCOND (numLSAs << "LSAs"); } } @@ -84,6 +91,7 @@ StaticRouteManagerTest::RunTests (void) { 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 @@ StaticRouteManagerTest::RunTests (void) lsa1->Add(lr1); delete lsa1; +#endif return ok; } diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 7b9d8f143..6c8f0fc28 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -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) - : m_node(node) + : m_node(node), m_numLSAs(0) { - SetInterfaceId (StaticRouter::iid); NS_DEBUG("StaticRouter::StaticRouter ()"); + SetInterfaceId (StaticRouter::iid); } StaticRouter::~StaticRouter () @@ -60,4 +77,118 @@ StaticRouter::~StaticRouter () 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, " 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 = m_node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4, "QI for 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 nd = ipv4->GetNetDevice(i); + Ptr 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 ndAdjacent = GetAdjacent(nd, ch); + uint32_t ifIndexAdjacent = ndAdjacent->GetIfIndex(); + Ptr nodeAdjacent = ndAdjacent->GetNode(); + Ptr ipv4Adjacent = nodeAdjacent->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4Adjacent, "QI for adjacent 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 +StaticRouter::GetAdjacent(Ptr nd, Ptr 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 nd1 = ch->GetDevice(0); + Ptr 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 diff --git a/src/routing/static-router.h b/src/routing/static-router.h index bacdfcf57..9d2b4cc6a 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -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 @@ class StaticRouterLSA { public: StaticRouterLSA(); - virtual ~StaticRouterLSA (); - uint32_t Add (StaticRouterLinkRecord* lr); + ~StaticRouterLSA(); + + uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); -public: Ipv4Address m_linkStateId; // set to the NodeId Ipv4Address m_advertisingRtr; // set to the NodeId - typedef std::list type_listOfLinkRecords; - type_listOfLinkRecords m_listOfLinkRecords; - type_listOfLinkRecords::iterator m_iter; + typedef std::list ListOfLinkRecords_t; + ListOfLinkRecords_t m_linkRecords; }; /** @@ -102,8 +102,12 @@ public: protected: virtual ~StaticRouter (); + Ptr m_node; + uint32_t m_numLSAs; + + Ptr GetAdjacent(Ptr nd, Ptr ch); + private: - Ptr m_node; }; } // namespace ns3