From 5099a91a214677ce7a4c82f278b7b10aa5a4779b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 12 Aug 2007 13:59:49 -0700 Subject: [PATCH 01/23] untested multicast support --- examples/csma-multicast.cc | 173 +++++++++++++++++++++++ examples/wscript | 5 + src/internet-node/ipv4-impl.cc | 48 +++++++ src/internet-node/ipv4-impl.h | 18 +++ src/internet-node/ipv4-l3-protocol.cc | 88 +++++++++++- src/internet-node/ipv4-l3-protocol.h | 23 ++- src/internet-node/ipv4-static-routing.cc | 126 ++++++++++++++++- src/internet-node/ipv4-static-routing.h | 22 ++- src/node/ipv4-route.cc | 96 ++++++++++++- src/node/ipv4-route.h | 62 ++++++++ src/node/ipv4.h | 60 ++++++++ 11 files changed, 709 insertions(+), 12 deletions(-) create mode 100644 examples/csma-multicast.cc diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc new file mode 100644 index 000000000..a36f11b64 --- /dev/null +++ b/examples/csma-multicast.cc @@ -0,0 +1,173 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + */ + +// Network topology +// +// n0 n1 n2 n3 +// | | | | +// ===================== +// +// - CBR/UDP flows from n0 to n1, and from n3 to n0 +// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +// (i.e., DataRate of 448,000 bps) +// - DropTail queues +// - Tracing of queues and packet receptions to file "csma-one-subnet.tr" + +#include +#include +#include +#include + +#include "ns3/command-line.h" +#include "ns3/default-value.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" +#include "ns3/debug.h" + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/internet-node.h" +#include "ns3/csma-channel.h" +#include "ns3/csma-net-device.h" +#include "ns3/csma-topology.h" +#include "ns3/csma-ipv4-topology.h" +#include "ns3/eui48-address.h" +#include "ns3/ipv4-address.h" +#include "ns3/inet-socket-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/ipv4-route.h" +#include "ns3/onoff-application.h" + +using namespace ns3; + +int +main (int argc, char *argv[]) +{ + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this +#if 0 + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("NetDevice"); + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("PacketSocket"); +#endif + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, + // and what the queue limit is + + // The below Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + DefaultValue::Bind ("Queue", "DropTailQueue"); + + // Allow the user to override any of the defaults and the above + // Bind()s at run-time, via command-line arguments + CommandLine::Parse (argc, argv); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information + Ptr channel0 = + CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); + + uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, + Eui48Address("10:54:23:54:23:50")); + uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, + Eui48Address("10:54:23:54:23:51")); + uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0, + Eui48Address("10:54:23:54:23:52")); + uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0, + Eui48Address("10:54:23:54:23:53")); + + // Later, we add IP addresses. + CsmaIpv4Topology::AddIpv4Address ( + n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); + + CsmaIpv4Topology::AddIpv4Address ( + n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); + + CsmaIpv4Topology::AddIpv4Address ( + n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); + + CsmaIpv4Topology::AddIpv4Address ( + n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); + + // Configure multicasting + Ipv4Address multicastSource ("10.1.1.1"); + Ipv4Address multicastGroup ("225.0.0.0"); + + Ptr ipv4; + ipv4 = n0->QueryInterface (Ipv4::iid); + + std::vector outputInterfaces (1); + outputInterfaces[0] = n0ifIndex; + + ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, + outputInterfaces); + + ipv4 = n1->QueryInterface (Ipv4::iid); + ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + + ipv4 = n2->QueryInterface (Ipv4::iid); + ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + + ipv4 = n3->QueryInterface (Ipv4::iid); + ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + + // Create the OnOff application to send UDP datagrams of size + // 210 bytes at a rate of 448 Kb/s + // from n0 to n1 + Ptr ooff = Create ( + n0, + InetSocketAddress (multicastGroup, 80), + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.0)); + ooff->Stop (Seconds(10.0)); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the csma-one-subnet.tr file + AsciiTrace asciitrace ("csma-one-subnet.tr"); + asciitrace.TraceAllNetDeviceRx (); + asciitrace.TraceAllQueues (); + + // Also configure some tcpdump traces; each interface will be traced + // The output files will be named + // simple-point-to-point.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + PcapTrace pcaptrace ("csma-one-subnet.pcap"); + pcaptrace.TraceAllIp (); + + Simulator::Run (); + + Simulator::Destroy (); +} diff --git a/examples/wscript b/examples/wscript index e7559756f..a38656c0f 100644 --- a/examples/wscript +++ b/examples/wscript @@ -17,3 +17,8 @@ def build(bld): obj = bld.create_ns3_program('csma-packet-socket', ['csma', 'internet-node']) obj.source = 'csma-packet-socket.cc' + + obj = bld.create_ns3_program('csma-multicast', + ['csma', 'internet-node']) + obj.source = 'csma-multicast.cc' + diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 307425114..c1dbc2c49 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -95,6 +95,42 @@ Ipv4Impl::RemoveRoute (uint32_t i) { return m_ipv4->RemoveRoute (i); } + +void +Ipv4Impl::AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces); +} + +uint32_t +Ipv4Impl::GetNMulticastRoutes (void) const +{ + return m_ipv4->GetNMulticastRoutes (); +} + +Ipv4MulticastRoute +Ipv4Impl::GetMulticastRoute (uint32_t i) const +{ + return *m_ipv4->GetMulticastRoute (i); +} + +void +Ipv4Impl::RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface) +{ + m_ipv4->RemoveMulticastRoute (origin, group, inputInterface); +} + +void +Ipv4Impl::RemoveMulticastRoute (uint32_t i) +{ + return m_ipv4->RemoveMulticastRoute (i); +} + uint32_t Ipv4Impl::AddInterface (Ptr device) { @@ -111,6 +147,18 @@ Ipv4Impl::GetNetDevice (uint32_t i) return m_ipv4->GetInterface (i)-> GetDevice (); } +void +Ipv4Impl::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) +{ + m_ipv4->JoinMulticastGroup(origin, group); +} + +void +Ipv4Impl::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) +{ + m_ipv4->LeaveMulticastGroup(origin, group); +} + void Ipv4Impl::SetAddress (uint32_t i, Ipv4Address address) { diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 445c10454..5ad9b3e0c 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -55,10 +55,28 @@ public: virtual uint32_t GetNRoutes (void); virtual Ipv4Route GetRoute (uint32_t i); virtual void RemoveRoute (uint32_t i); + + + virtual void AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); + + virtual uint32_t GetNMulticastRoutes (void) const; + virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const; + + virtual void RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface); + virtual void RemoveMulticastRoute (uint32_t i); + virtual uint32_t AddInterface (Ptr device); virtual uint32_t GetNInterfaces (void); virtual Ptr GetNetDevice(uint32_t i); + virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); + virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); + virtual void SetAddress (uint32_t i, Ipv4Address address); virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); virtual Ipv4Mask GetNetworkMask (uint32_t t) const; diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index be483dfa0..f7506c59b 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -17,6 +17,7 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Author: George F. Riley +// Craig Dowell // #include "ns3/packet.h" @@ -131,7 +132,8 @@ Ipv4L3Protocol::~Ipv4L3Protocol () void Ipv4L3Protocol::DoDispose (void) { - for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); + i != m_interfaces.end (); i++) { delete (*i); } @@ -224,12 +226,15 @@ Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, Packet packet, Ipv4RoutingProtocol::RouteReplyCallback routeReply) { - for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); - rprotoIter != m_routingProtocols.end (); rprotoIter++) + for (Ipv4RoutingProtocolList::const_iterator rprotoIter = + m_routingProtocols.begin (); + rprotoIter != m_routingProtocols.end (); + rprotoIter++) { if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) return; } + // No route found routeReply (false, Ipv4Route (), packet, ipHeader); } @@ -261,6 +266,41 @@ Ipv4L3Protocol::RemoveRoute (uint32_t index) m_staticRouting->RemoveRoute (index); } +void +Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + m_staticRouting->AddMulticastRoute (origin, group, inputInterface, + outputInterfaces); +} + +uint32_t +Ipv4L3Protocol::GetNMulticastRoutes (void) const +{ + return m_staticRouting->GetNMulticastRoutes (); +} + +Ipv4MulticastRoute * +Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const +{ + return m_staticRouting->GetMulticastRoute (index); +} + +void +Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface) +{ + m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface); +} + +void +Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index) +{ + m_staticRouting->RemoveMulticastRoute (index); +} uint32_t Ipv4L3Protocol::AddInterface (Ptr device) @@ -463,13 +503,29 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, PtrReceive (p, ip.GetSource (), ip.GetDestination ()); } +void +Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) +{ + m_multicastGroups.push_back( + std::pair (origin, group)); +} + +void +Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) +{ + for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin (); + i != m_multicastGroups.end (); + i++) + { + if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group)) + { + m_multicastGroups.erase (i); + return; + } + } +} + void Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address) { diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index 2cce3efa3..9269a80fa 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -158,11 +158,26 @@ public: Ipv4Route *GetRoute (uint32_t i); void RemoveRoute (uint32_t i); + void AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); + + uint32_t GetNMulticastRoutes (void) const; + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + + void RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface); + void RemoveMulticastRoute (uint32_t i); + uint32_t AddInterface (Ptr device); Ipv4Interface * GetInterface (uint32_t i) const; uint32_t GetNInterfaces (void) const; - + virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); + virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); + void SetAddress (uint32_t i, Ipv4Address address); void SetNetworkMask (uint32_t i, Ipv4Mask mask); Ipv4Mask GetNetworkMask (uint32_t t) const; @@ -192,7 +207,10 @@ private: TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const; typedef std::list Ipv4InterfaceList; - typedef std::list< std::pair< int, Ptr > > Ipv4RoutingProtocolList; + typedef std::list > + Ipv4MulticastGroupList; + typedef std::list > > + Ipv4RoutingProtocolList; Ipv4InterfaceList m_interfaces; uint32_t m_nInterfaces; @@ -206,6 +224,7 @@ private: Ipv4RoutingProtocolList m_routingProtocols; Ptr m_staticRouting; + Ipv4MulticastGroupList m_multicastGroups; }; } // Namespace ns3 diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index b70c1c1af..27962bd40 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -18,11 +18,11 @@ // // Author: George F. Riley // Gustavo Carneiro +// Craig Dowell #include "ipv4-static-routing.h" #include "ns3/packet.h" - namespace ns3 { @@ -77,6 +77,83 @@ Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, m_defaultRoute = route; } +void +Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + Ipv4MulticastRoute *route = new Ipv4MulticastRoute (); + *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, + inputInterface, outputInterfaces); + m_multicastRoutes.push_back (route); +} + +uint32_t +Ipv4StaticRouting::GetNMulticastRoutes (void) const +{ + return m_multicastRoutes.size (); +} + +Ipv4MulticastRoute * +Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const +{ + NS_ASSERT_MSG(index < m_multicastRoutes.size (), + "Ipv4StaticRouting::GetMulticastRoute (): Index out of range"); + + uint32_t tmp = 0; + for (MulticastRoutesCI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) + { + if (tmp == index) + { + return *i; + } + tmp++; + } + return 0; +} + +void +Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface) +{ + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) + { + Ipv4MulticastRoute *route = *i; + if (origin == route->GetOrigin () && + group == route->GetGroup () && + inputInterface == route->GetInputInterface ()) + { + delete *i; + m_multicastRoutes.erase (i); + return; + } + } +} + +void +Ipv4StaticRouting::RemoveMulticastRoute(uint32_t 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++; + } +} + Ipv4Route * Ipv4StaticRouting::LookupStatic (Ipv4Address dest) { @@ -110,6 +187,25 @@ Ipv4StaticRouting::LookupStatic (Ipv4Address dest) return 0; } +Ipv4MulticastRoute * +Ipv4StaticRouting::LookupStatic ( + Ipv4Address origin, + Ipv4Address group) +{ + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) + { + Ipv4MulticastRoute *route = *i; + if (origin == route->GetOrigin () && + group == route->GetGroup ()) + { + return *i; + } + } + return 0; +} + uint32_t Ipv4StaticRouting::GetNRoutes (void) { @@ -213,6 +309,27 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, Packet packet, RouteReplyCallback routeReply) { +// +// 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. +// + Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), + ipHeader.GetDestination ()); + if (mRoute) + { + for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) + { + Packet p = packet; + Ipv4Route route = + Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), + mRoute->GetOutputInterface(i)); + routeReply (true, route, p, ipHeader); + return true; + } + } +// +// See if this is a unicast packet we have a route for. +// Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); if (route != 0) { @@ -246,8 +363,13 @@ Ipv4StaticRouting::DoDispose (void) delete m_defaultRoute; m_defaultRoute = 0; } + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i = m_multicastRoutes.erase (i)) + { + delete (*i); + } Ipv4RoutingProtocol::DoDispose (); } - }//namespace ns3 diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index 8462f55a7..24a228048 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -75,6 +75,20 @@ public: Ipv4Route *GetRoute (uint32_t i); void RemoveRoute (uint32_t i); + void AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); + + uint32_t GetNMulticastRoutes (void) const; + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + + void RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface); + + void RemoveMulticastRoute (uint32_t index); + protected: void DoDispose (void); @@ -86,15 +100,19 @@ private: typedef std::list::const_iterator NetworkRoutesCI; typedef std::list::iterator NetworkRoutesI; + typedef std::list MulticastRoutes; + typedef std::list::const_iterator MulticastRoutesCI; + typedef std::list::iterator MulticastRoutesI; + Ipv4Route *LookupStatic (Ipv4Address dest); + Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group); HostRoutes m_hostRoutes; NetworkRoutes m_networkRoutes; Ipv4Route *m_defaultRoute; + MulticastRoutes m_multicastRoutes; }; - - } // Namespace ns3 #endif /* IPV4_STATIC_ROUTING_H */ diff --git a/src/node/ipv4-route.cc b/src/node/ipv4-route.cc index bcc556894..9d6a2286b 100644 --- a/src/node/ipv4-route.cc +++ b/src/node/ipv4-route.cc @@ -137,7 +137,6 @@ Ipv4Route::GetInterface (void) const return m_interface; } - Ipv4Route Ipv4Route::CreateHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, @@ -220,4 +219,99 @@ std::ostream& operator<< (std::ostream& os, Ipv4Route const& route) return os; } +/***************************************************** + * Ipv4MulticastRoute + *****************************************************/ + +Ipv4MulticastRoute::Ipv4MulticastRoute () +{ +} + +Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const &route) +: + m_origin (route.m_origin), + m_group (route.m_group), + m_inputInterface (route.m_inputInterface), + m_outputInterfaces (route.m_outputInterfaces) +{ +} + +Ipv4MulticastRoute::Ipv4MulticastRoute ( + Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + m_origin = origin; + m_group = group; + m_inputInterface = inputInterface; + m_outputInterfaces = outputInterfaces; +} + +Ipv4Address +Ipv4MulticastRoute::GetOrigin (void) const +{ + return m_origin; +} + +Ipv4Address +Ipv4MulticastRoute::GetGroup (void) const +{ + return m_group; +} + +uint32_t +Ipv4MulticastRoute::GetInputInterface (void) const +{ + return m_inputInterface; +} + +uint32_t +Ipv4MulticastRoute::GetNOutputInterfaces (void) const +{ + return m_outputInterfaces.size (); +} + +uint32_t +Ipv4MulticastRoute::GetOutputInterface (uint32_t n) const +{ + NS_ASSERT_MSG(n < m_outputInterfaces.size (), + "Ipv4MulticastRoute::GetOutputInterface (): index out of bounds"); + + return m_outputInterfaces[n]; +} + +std::vector +Ipv4MulticastRoute::GetOutputInterfaces (void) const +{ + return m_outputInterfaces; +} + +Ipv4MulticastRoute +Ipv4MulticastRoute::CreateMulticastRoute ( + Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + return Ipv4MulticastRoute (origin, group, inputInterface, outputInterfaces); +} + +std::ostream& +operator<< (std::ostream& os, Ipv4MulticastRoute 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 diff --git a/src/node/ipv4-route.h b/src/node/ipv4-route.h index efe9b52e2..f80a1ae00 100644 --- a/src/node/ipv4-route.h +++ b/src/node/ipv4-route.h @@ -22,6 +22,7 @@ #define IPV4_ROUTE_H #include +#include #include #include "ipv4-address.h" @@ -98,6 +99,67 @@ private: std::ostream& operator<< (std::ostream& os, Ipv4Route const& route); +/** + * \brief A record of an IPv4 multicast route + */ +class Ipv4MulticastRoute { +public: + /** + * \brief This constructor does nothing + */ + Ipv4MulticastRoute (); + /** + * \brief Copy Constructor + * \param route The route to copy + */ + Ipv4MulticastRoute (Ipv4MulticastRoute 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; + + /** + * \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 GetOutputInterfaces (void) const; + + static Ipv4MulticastRoute CreateMulticastRoute (Ipv4Address origin, + Ipv4Address group, uint32_t inputInterface, + std::vector outputInterfaces); + +private: + Ipv4MulticastRoute (Ipv4Address origin, Ipv4Address group, + uint32_t inputInterface, std::vector outputInterfaces); + + Ipv4Address m_origin; + Ipv4Address m_group; + uint32_t m_inputInterface; + std::vector m_outputInterfaces; +}; + +std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoute const& route); + }//namespace ns3 #endif /* IPV4_ROUTE_H */ diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 76d88faea..06cf5c130 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -202,7 +202,49 @@ public: * \param i index of route to remove from routing table. */ virtual void RemoveRoute (uint32_t i) = 0; + + /** + * \brief Add a static multicast route for a given multicast source and + * group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + * \param inputInterface The interface index over which the packet arrived. + * \param outputInterfaces The list of output interface indices over which + * the packet should be sent (excluding the inputInterface). + */ + virtual void AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) = 0; + /** + * \brief Remove a static multicast route for a given multicast source and + * group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + * \param inputInterface The interface index over which the packet arrived. + */ + virtual void RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface) = 0; + /** + * \returns the number of entries in the multicast routing table. + */ + virtual uint32_t GetNMulticastRoutes (void) const = 0; + + /** + * \param i index of route to return + * \returns the route whose index is i + */ + virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const = 0; + + /** + * \param i index of route to remove from routing table. + */ + virtual void RemoveMulticastRoute (uint32_t i) = 0; + /** * \param device device to add to the list of ipv4 interfaces * which can be used as output interfaces during packet forwarding. @@ -224,6 +266,24 @@ public: */ virtual Ptr GetNetDevice (uint32_t i) = 0; + /** + * \brief Join a multicast group for a given multicast source and + * group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + */ + virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0; + + /** + * \brief Leave a multicast group for a given multicast source and + * group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + */ + virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0; + /** * \param i index of ipv4 interface * \param address address to associate to the underlying ipv4 interface From bc8ee80491136cd010c59d3c50f937a24c0d4108 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 12 Aug 2007 15:51:12 -0700 Subject: [PATCH 02/23] debug prints to make validation easier --- examples/csma-multicast.cc | 34 +++++++-- src/applications/onoff-application.cc | 37 ++++++++-- src/internet-node/ipv4-l3-protocol.cc | 88 +++++++++++++++++++++++- src/internet-node/ipv4-static-routing.cc | 21 +++++- src/internet-node/udp-l4-protocol.cc | 31 ++++++++- src/internet-node/udp-socket.cc | 46 ++++++++++++- 6 files changed, 240 insertions(+), 17 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index a36f11b64..19e01be7e 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -58,20 +58,37 @@ using namespace ns3; +NS_DEBUG_COMPONENT_DEFINE ("Me"); + int main (int argc, char *argv[]) { // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this #if 0 + DebugComponentEnable("Me"); DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("Ipv4L3Protocol"); DebugComponentEnable("NetDevice"); DebugComponentEnable("Channel"); DebugComponentEnable("CsmaChannel"); DebugComponentEnable("PacketSocket"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); #endif + DebugComponentEnable("Me"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("CsmaChannel"); + // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, // and what the queue limit is @@ -86,16 +103,19 @@ main (int argc, char *argv[]) // Here, we will explicitly create four nodes. In more sophisticated // topologies, we could configure a node factory. + NS_DEBUG("Create nodes."); Ptr n0 = Create (); Ptr n1 = Create (); Ptr n2 = Create (); Ptr n3 = Create (); + NS_DEBUG("Create channels."); // We create the channels first without any IP addressing information Ptr channel0 = CsmaTopology::CreateCsmaChannel( DataRate(5000000), MilliSeconds(2)); + NS_DEBUG("Build Topology."); uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, Eui48Address("10:54:23:54:23:50")); uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, @@ -106,6 +126,8 @@ main (int argc, char *argv[]) Eui48Address("10:54:23:54:23:53")); // Later, we add IP addresses. + NS_DEBUG("Assign IP Addresses."); + CsmaIpv4Topology::AddIpv4Address ( n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); @@ -119,6 +141,7 @@ main (int argc, char *argv[]) n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); // Configure multicasting + NS_DEBUG("Configure multicasting."); Ipv4Address multicastSource ("10.1.1.1"); Ipv4Address multicastGroup ("225.0.0.0"); @@ -142,7 +165,8 @@ main (int argc, char *argv[]) // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s - // from n0 to n1 + // from n0 to the multicast group + NS_DEBUG("Create Applications."); Ptr ooff = Create ( n0, InetSocketAddress (multicastGroup, 80), @@ -155,7 +179,8 @@ main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the csma-one-subnet.tr file - AsciiTrace asciitrace ("csma-one-subnet.tr"); + NS_DEBUG("Configure Tracing."); + AsciiTrace asciitrace ("csma-multicast.tr"); asciitrace.TraceAllNetDeviceRx (); asciitrace.TraceAllQueues (); @@ -164,10 +189,11 @@ main (int argc, char *argv[]) // simple-point-to-point.pcap-- // and can be read by the "tcpdump -r" command (use "-tt" option to // display timestamps correctly) - PcapTrace pcaptrace ("csma-one-subnet.pcap"); + PcapTrace pcaptrace ("csma-multicast.pcap"); pcaptrace.TraceAllIp (); + NS_DEBUG("Run Simulation."); Simulator::Run (); - Simulator::Destroy (); + NS_DEBUG("Done."); } diff --git a/src/applications/onoff-application.cc b/src/applications/onoff-application.cc index 32bcd7564..297d57e3e 100644 --- a/src/applications/onoff-application.cc +++ b/src/applications/onoff-application.cc @@ -22,6 +22,7 @@ // George F. Riley, Georgia Tech, Spring 2007 // Adapted from ApplicationOnOff in GTNetS. +#include "ns3/debug.h" #include "ns3/address.h" #include "ns3/node.h" #include "ns3/nstime.h" @@ -34,6 +35,8 @@ #include "ns3/packet.h" #include "onoff-application.h" +NS_DEBUG_COMPONENT_DEFINE ("OnOffApplication"); + using namespace std; namespace ns3 { @@ -95,30 +98,37 @@ OnOffApplication::Construct (Ptr n, m_iid = iid; } - OnOffApplication::~OnOffApplication() -{} +{ + NS_DEBUG("OnOffApplication::~OnOffApplication()"); +} void OnOffApplication::SetMaxBytes(uint32_t maxBytes) { + NS_DEBUG("OnOffApplication::SetMaxBytes(" << maxBytes << ")"); m_maxBytes = maxBytes; } void OnOffApplication::SetDefaultRate (const DataRate &rate) { + NS_DEBUG("OnOffApplication::SetDefaultRate(" << &rate << ")"); g_defaultRate.SetValue (rate); } + void OnOffApplication::SetDefaultSize (uint32_t size) { + NS_DEBUG("OnOffApplication::SetDefaultSize(" << size << ")"); g_defaultSize.SetValue (size); } void OnOffApplication::DoDispose (void) { + NS_DEBUG("OnOffApplication::DoDispose()"); + m_socket = 0; delete m_onTime; delete m_offTime; @@ -130,10 +140,11 @@ OnOffApplication::DoDispose (void) Application::DoDispose (); } - // Application Methods -void OnOffApplication::StartApplication() // Called at time specified by Start +void OnOffApplication::StartApplication() // Called at time specified by Start { + NS_DEBUG("OnOffApplication::StartApplication()"); + // Create the socket if not already if (!m_socket) { @@ -151,8 +162,10 @@ void OnOffApplication::StartApplication() // Called at time specified by Star ScheduleStartEvent(); } -void OnOffApplication::StopApplication() // Called at time specified by Stop +void OnOffApplication::StopApplication() // Called at time specified by Stop { + NS_DEBUG("OnOffApplication::StopApplication()"); + if (m_sendEvent.IsRunning ()) { // Cancel the pending send packet event // Calculate residual bits since last packet sent @@ -166,17 +179,23 @@ void OnOffApplication::StopApplication() // Called at time specified by Stop // Event handlers void OnOffApplication::StartSending() { + NS_DEBUG("OnOffApplication::StartSending ()"); + ScheduleNextTx(); // Schedule the send packet event } void OnOffApplication::StopSending() { + NS_DEBUG("OnOffApplication::StopSending ()"); + Simulator::Cancel(m_sendEvent); } // Private helpers void OnOffApplication::ScheduleNextTx() { + NS_DEBUG("OnOffApplication::ScheduleNextTx ()"); + if (m_totBytes < m_maxBytes) { uint32_t bits = m_pktSize * 8 - m_residualBits; @@ -192,12 +211,16 @@ void OnOffApplication::ScheduleNextTx() void OnOffApplication::ScheduleStartEvent() { // Schedules the event to start sending data (switch to the "On" state) + NS_DEBUG("OnOffApplication::ScheduleStartEvent ()"); + Time offInterval = Seconds(m_offTime->GetValue()); m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this); } void OnOffApplication::ScheduleStopEvent() { // Schedules the event to stop sending data (switch to "Off" state) + NS_DEBUG("OnOffApplication::ScheduleStopEvent ()"); + Time onInterval = Seconds(m_onTime->GetValue()); Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this); } @@ -205,6 +228,8 @@ void OnOffApplication::ScheduleStopEvent() void OnOffApplication::SendPacket() { + NS_DEBUG("OnOffApplication::SendPacket ()"); + NS_ASSERT (m_sendEvent.IsExpired ()); m_socket->Send(Packet (m_pktSize)); m_totBytes += m_pktSize; @@ -215,6 +240,8 @@ void OnOffApplication::SendPacket() void OnOffApplication::ConnectionSucceeded(Ptr) { + NS_DEBUG("OnOffApplication::ConnectionSucceeded ()"); + m_connected = true; ScheduleStartEvent(); } diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index f7506c59b..8ccadb05e 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -17,7 +17,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Author: George F. Riley -// Craig Dowell // #include "ns3/packet.h" @@ -121,17 +120,24 @@ Ipv4L3Protocol::Ipv4L3Protocol(Ptr node) m_identification (0), m_node (node) { + NS_DEBUG("Ipv4L3Protocol::Ipv4L3Protocol ()"); + SetInterfaceId (Ipv4L3Protocol::iid); m_staticRouting = Create (); AddRoutingProtocol (m_staticRouting, 0); SetupLoopback (); } + Ipv4L3Protocol::~Ipv4L3Protocol () -{} +{ + NS_DEBUG("Ipv4L3Protocol::~Ipv4L3Protocol ()"); +} void Ipv4L3Protocol::DoDispose (void) { + NS_DEBUG("Ipv4L3Protocol::DoDispose ()"); + for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) { @@ -147,6 +153,8 @@ Ipv4L3Protocol::DoDispose (void) void Ipv4L3Protocol::SetupLoopback (void) { + NS_DEBUG("Ipv4L3Protocol::SetupLoopback ()"); + Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node); interface->SetAddress (Ipv4Address::GetLoopback ()); interface->SetNetworkMask (Ipv4Mask::GetLoopback ()); @@ -158,6 +166,8 @@ Ipv4L3Protocol::SetupLoopback (void) TraceResolver * Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context) { + NS_DEBUG("Ipv4L3Protocol::CreateTraceResolver ()"); + CompositeTraceResolver *resolver = new CompositeTraceResolver (context); resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX)); resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX)); @@ -170,6 +180,8 @@ Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context) TraceResolver * Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const { + NS_DEBUG("Ipv4L3Protocol::InterfacesCreateTraceResolver ()"); + ArrayTraceResolver *resolver = new ArrayTraceResolver (context, @@ -181,6 +193,7 @@ Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) cons void Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl) { + NS_DEBUG("Ipv4L3Protocol::SetDefaultTtl ()"); m_defaultTtl = ttl; } @@ -190,20 +203,28 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, uint32_t interface) { + NS_DEBUG("Ipv4L3Protocol::AddHostRouteTo (" << dest << ", " << nextHop << + ", " << interface << ")"); m_staticRouting->AddHostRouteTo (dest, nextHop, interface); } + void Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, uint32_t interface) { + NS_DEBUG("Ipv4L3Protocol::AddHostRouteTo (" << dest << ", " << + interface << ")"); m_staticRouting->AddHostRouteTo (dest, interface); } + void Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface) { + NS_DEBUG("Ipv4L3Protocol::AddNetworkRouteTo (" << network << ", " << + networkMask << ", " << nextHop << ", " << interface << ")"); m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface); } void @@ -211,26 +232,33 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, uint32_t interface) { + NS_DEBUG("Ipv4L3Protocol::AddNetworkRouteTo (" << network << ", " << + networkMask << ", " << interface << ")"); m_staticRouting->AddNetworkRouteTo (network, networkMask, interface); } void Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, uint32_t interface) { + NS_DEBUG("Ipv4L3Protocol::SetDefaultRoute (" << nextHop << ", " << + interface << ")"); m_staticRouting->SetDefaultRoute (nextHop, interface); } - void Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, Packet packet, Ipv4RoutingProtocol::RouteReplyCallback routeReply) { + NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ", " << &packet << + &routeReply << ")"); + for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); rprotoIter++) { + NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route"); if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) return; } @@ -243,6 +271,8 @@ void Ipv4L3Protocol::AddRoutingProtocol (Ptr routingProtocol, int priority) { + NS_DEBUG("Ipv4L3Protocol::AddRoutingProtocol (" << &routingProtocol << + ", " << priority << ")"); m_routingProtocols.push_back (std::pair > (-priority, routingProtocol)); m_routingProtocols.sort (); @@ -251,18 +281,21 @@ Ipv4L3Protocol::AddRoutingProtocol (Ptr routingProtocol, uint32_t Ipv4L3Protocol::GetNRoutes (void) { + NS_DEBUG("Ipv4L3Protocol::GetNRoutes ()"); return m_staticRouting->GetNRoutes (); } Ipv4Route * Ipv4L3Protocol::GetRoute (uint32_t index) { + NS_DEBUG("Ipv4L3Protocol::GetRoute ()"); return m_staticRouting->GetRoute (index); } void Ipv4L3Protocol::RemoveRoute (uint32_t index) { + NS_DEBUG("Ipv4L3Protocol::RemoveRoute (" << index << ")"); m_staticRouting->RemoveRoute (index); } @@ -272,6 +305,9 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin, uint32_t inputInterface, std::vector outputInterfaces) { + NS_DEBUG("Ipv4L3Protocol::AddMulticastRoute (" << origin << ", " << + group << ", " << inputInterface << ", " << &outputInterfaces << ")"); + m_staticRouting->AddMulticastRoute (origin, group, inputInterface, outputInterfaces); } @@ -279,12 +315,14 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin, uint32_t Ipv4L3Protocol::GetNMulticastRoutes (void) const { + NS_DEBUG("Ipv4L3Protocol::GetNMulticastRoutes ()"); return m_staticRouting->GetNMulticastRoutes (); } Ipv4MulticastRoute * Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const { + NS_DEBUG("Ipv4L3Protocol::GetMulticastRoute (" << index << ")"); return m_staticRouting->GetMulticastRoute (index); } @@ -293,32 +331,40 @@ Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin, Ipv4Address group, uint32_t inputInterface) { + NS_DEBUG("Ipv4L3Protocol::RemoveMulticastRoute (" << origin << ", " << + group << ", " << inputInterface << ")"); m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface); } void Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index) { + NS_DEBUG("Ipv4L3Protocol::RemoveMulticastRoute (" << index << ")"); m_staticRouting->RemoveMulticastRoute (index); } uint32_t Ipv4L3Protocol::AddInterface (Ptr device) { + NS_DEBUG("Ipv4L3Protocol::AddInterface (" << &device << ")"); Ipv4Interface *interface = new ArpIpv4Interface (m_node, device); return AddIpv4Interface (interface); } + uint32_t Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface) { + NS_DEBUG("Ipv4L3Protocol::AddIpv4Interface (" << interface << ")"); uint32_t index = m_nInterfaces; m_interfaces.push_back (interface); m_nInterfaces++; return index; } + Ipv4Interface * Ipv4L3Protocol::GetInterface (uint32_t index) const { + NS_DEBUG("Ipv4L3Protocol::GetInterface (" << index << ")"); uint32_t tmp = 0; for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) { @@ -330,15 +376,18 @@ Ipv4L3Protocol::GetInterface (uint32_t index) const } return 0; } + uint32_t Ipv4L3Protocol::GetNInterfaces (void) const { + NS_DEBUG("Ipv4L3Protocol::GetNInterface ()"); return m_nInterfaces; } Ipv4Interface * Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) { + NS_DEBUG("Ipv4L3Protocol::FindInterfaceForDevice (" << &device << ")"); for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) { if ((*i)->GetDevice () == device) @@ -352,6 +401,9 @@ Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) void Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protocol, const Address &from) { + NS_DEBUG("Ipv4L3Protocol::Receive (" << &device << ", " << &p << ", " << + protocol << ", " << from << ")"); + uint32_t index = 0; for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) { @@ -386,6 +438,9 @@ Ipv4L3Protocol::Send (Packet const &packet, Ipv4Address destination, uint8_t protocol) { + NS_DEBUG("Ipv4L3Protocol::Send (" << &packet << ", " << source << ", " << + ", " << destination << ", " << protocol << ")"); + Ipv4Header ipHeader; ipHeader.SetSource (source); @@ -434,6 +489,9 @@ Ipv4L3Protocol::SendRealOut (bool found, Packet packet, Ipv4Header const &ipHeader) { + NS_DEBUG("Ipv4L3Protocol::SendRealOut (" << found << ", " << &route << + ", " << &packet << &ipHeader << ")"); + if (!found) { NS_DEBUG ("no route to host. drop."); @@ -458,6 +516,9 @@ Ipv4L3Protocol::SendRealOut (bool found, bool Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) { + NS_DEBUG("Ipv4L3Protocol::Forwarding (" << &packet << ", " << &ipHeader << + ", " << device << ")"); + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) { @@ -529,6 +590,7 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr demux = m_node->QueryInterface (Ipv4L4Demux::iid); Ptr protocol = demux->GetProtocol (ip.GetProtocol ()); protocol->Receive (p, ip.GetSource (), ip.GetDestination ()); @@ -537,6 +599,8 @@ Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip) void Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) { + NS_DEBUG("Ipv4L3Protocol::JoinMulticastGroup (" << origin << ", " << + group << ")"); m_multicastGroups.push_back( std::pair (origin, group)); } @@ -544,6 +608,9 @@ Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) void Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) { + NS_DEBUG("Ipv4L3Protocol::LeaveMulticastGroup (" << origin << ", " << + group << ")"); + for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin (); i != m_multicastGroups.end (); i++) @@ -559,42 +626,55 @@ Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) void Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address) { + NS_DEBUG("Ipv4L3Protocol::SetAddress (" << i << ", " << address << ")"); Ipv4Interface *interface = GetInterface (i); interface->SetAddress (address); } + void Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask) { + NS_DEBUG("Ipv4L3Protocol::SetNetworkMask (" << i << ", " << mask << ")"); Ipv4Interface *interface = GetInterface (i); interface->SetNetworkMask (mask); } + Ipv4Mask Ipv4L3Protocol::GetNetworkMask (uint32_t i) const { + NS_DEBUG("Ipv4L3Protocol::GetNetworkMask (" << i << ")"); Ipv4Interface *interface = GetInterface (i); return interface->GetNetworkMask (); } + Ipv4Address Ipv4L3Protocol::GetAddress (uint32_t i) const { + NS_DEBUG("Ipv4L3Protocol::GetAddress (" << i << ")"); Ipv4Interface *interface = GetInterface (i); return interface->GetAddress (); } + uint16_t Ipv4L3Protocol::GetMtu (uint32_t i) const { + NS_DEBUG("Ipv4L3Protocol::GetMtu (" << i << ")"); Ipv4Interface *interface = GetInterface (i); return interface->GetMtu (); } + bool Ipv4L3Protocol::IsUp (uint32_t i) const { + NS_DEBUG("Ipv4L3Protocol::IsUp (" << i << ")"); Ipv4Interface *interface = GetInterface (i); return interface->IsUp (); } + void Ipv4L3Protocol::SetUp (uint32_t i) { + NS_DEBUG("Ipv4L3Protocol::SetUp (" << i << ")"); Ipv4Interface *interface = GetInterface (i); interface->SetUp (); @@ -608,9 +688,11 @@ Ipv4L3Protocol::SetUp (uint32_t i) interface->GetNetworkMask (), i); } } + void Ipv4L3Protocol::SetDown (uint32_t ifaceIndex) { + NS_DEBUG("Ipv4L3Protocol::SetDown (" << ifaceIndex << ")"); Ipv4Interface *interface = GetInterface (ifaceIndex); interface->SetDown (); diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index 27962bd40..a7cc93bac 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -18,11 +18,13 @@ // // Author: George F. Riley // Gustavo Carneiro -// Craig Dowell +#include "ns3/debug.h" #include "ipv4-static-routing.h" #include "ns3/packet.h" +NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting"); + namespace ns3 { @@ -31,10 +33,12 @@ Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, uint32_t interface) { + Ipv4Route *route = new Ipv4Route (); *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface); m_hostRoutes.push_back (route); } + void Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, uint32_t interface) @@ -43,6 +47,7 @@ Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, *route = Ipv4Route::CreateHostRouteTo (dest, interface); m_hostRoutes.push_back (route); } + void Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, @@ -56,6 +61,7 @@ Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, interface); m_networkRoutes.push_back (route); } + void Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, @@ -67,6 +73,7 @@ Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, interface); m_networkRoutes.push_back (route); } + void Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, uint32_t interface) @@ -197,7 +204,8 @@ Ipv4StaticRouting::LookupStatic ( i++) { Ipv4MulticastRoute *route = *i; - if (origin == route->GetOrigin () && + if ( (origin == route->GetOrigin () || + origin == Ipv4Address::GetAny ()) && group == route->GetGroup ()) { return *i; @@ -309,6 +317,15 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, Packet packet, RouteReplyCallback routeReply) { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " << + &packet << ", " << &routeReply << ")"); + + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): source = " << + ipHeader.GetSource ()); + + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " << + ipHeader.GetDestination ()); + // // 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. diff --git a/src/internet-node/udp-l4-protocol.cc b/src/internet-node/udp-l4-protocol.cc index f0ef8569b..2626866b8 100644 --- a/src/internet-node/udp-l4-protocol.cc +++ b/src/internet-node/udp-l4-protocol.cc @@ -19,6 +19,7 @@ * Author: Mathieu Lacage */ +#include "ns3/debug.h" #include "ns3/assert.h" #include "ns3/packet.h" #include "ns3/empty-trace-resolver.h" @@ -31,6 +32,8 @@ #include "ipv4-l3-protocol.h" #include "udp-socket.h" +NS_DEBUG_COMPONENT_DEFINE ("UdpL4Protocol"); + namespace ns3 { /* see http://www.iana.org/assignments/protocol-numbers */ @@ -40,20 +43,26 @@ UdpL4Protocol::UdpL4Protocol (Ptr node) : Ipv4L4Protocol (PROT_NUMBER, 2), m_node (node), m_endPoints (new Ipv4EndPointDemux ()) -{} +{ + NS_DEBUG("UdpL4Protocol::UdpL4Protocol ()"); +} UdpL4Protocol::~UdpL4Protocol () -{} +{ + NS_DEBUG("UdpL4Protocol::~UdpL4Protocol ()"); +} TraceResolver * UdpL4Protocol::CreateTraceResolver (TraceContext const &context) { + NS_DEBUG("UdpL4Protocol::CreateTraceResolver ()"); return new EmptyTraceResolver (context); } void UdpL4Protocol::DoDispose (void) { + NS_DEBUG("UdpL4Protocol::DoDispose ()"); if (m_endPoints != 0) { delete m_endPoints; @@ -66,6 +75,7 @@ UdpL4Protocol::DoDispose (void) Ptr UdpL4Protocol::CreateSocket (void) { + NS_DEBUG("UdpL4Protocol::CreateSocket ()"); Ptr socket = Create (m_node, this); return socket; } @@ -73,27 +83,36 @@ UdpL4Protocol::CreateSocket (void) Ipv4EndPoint * UdpL4Protocol::Allocate (void) { + NS_DEBUG("UdpL4Protocol::Allocate ()"); return m_endPoints->Allocate (); } + Ipv4EndPoint * UdpL4Protocol::Allocate (Ipv4Address address) { + NS_DEBUG("UdpL4Protocol::Allocate (" << address << ")"); return m_endPoints->Allocate (address); } + Ipv4EndPoint * UdpL4Protocol::Allocate (uint16_t port) { + NS_DEBUG("UdpL4Protocol::Allocate (" << port << ")"); return m_endPoints->Allocate (port); } + Ipv4EndPoint * UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port) { + NS_DEBUG("UdpL4Protocol::Allocate (" << address << ", " << port << ")"); return m_endPoints->Allocate (address, port); } Ipv4EndPoint * UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort, Ipv4Address peerAddress, uint16_t peerPort) { + NS_DEBUG("UdpL4Protocol::Allocate (" << localAddress << ", " << localPort << + ", " << peerAddress << ", " << peerPort << ")"); return m_endPoints->Allocate (localAddress, localPort, peerAddress, peerPort); } @@ -101,6 +120,7 @@ UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort, void UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint) { + NS_DEBUG("UdpL4Protocol::Deallocate (" << endPoint << ")"); m_endPoints->DeAllocate (endPoint); } @@ -109,6 +129,9 @@ UdpL4Protocol::Receive(Packet& packet, Ipv4Address const &source, Ipv4Address const &destination) { + NS_DEBUG("UdpL4Protocol::Receive (" << &packet << ", " << source << + ", " << destination << ")"); + UdpHeader udpHeader; packet.RemoveHeader (udpHeader); Ipv4EndPointDemux::EndPoints endPoints = @@ -126,6 +149,9 @@ UdpL4Protocol::Send (Packet packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport, uint16_t dport) { + NS_DEBUG("UdpL4Protocol::Send (" << &packet << ", " << saddr << + ", " << daddr << ", " << sport << ", " << dport << ")"); + UdpHeader udpHeader; udpHeader.SetDestination (dport); udpHeader.SetSource (sport); @@ -139,6 +165,7 @@ UdpL4Protocol::Send (Packet packet, Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); if (ipv4 != 0) { + NS_DEBUG("UdpL4Protocol::Send (): Sending to IP"); ipv4->Send (packet, saddr, daddr, PROT_NUMBER); } } diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index a2bde3224..1442e1d11 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -18,6 +18,8 @@ * * Author: Mathieu Lacage */ + +#include "ns3/debug.h" #include "ns3/node.h" #include "ns3/inet-socket-address.h" #include "udp-socket.h" @@ -25,6 +27,8 @@ #include "ipv4-end-point.h" #include "ipv4-l4-demux.h" +NS_DEBUG_COMPONENT_DEFINE ("UdpSocket"); + namespace ns3 { UdpSocket::UdpSocket (Ptr node, Ptr udp) @@ -35,9 +39,14 @@ UdpSocket::UdpSocket (Ptr node, Ptr udp) m_shutdownSend (false), m_shutdownRecv (false), m_connected (false) -{} +{ + NS_DEBUG("UdpSocket::UdpSocket ()"); +} + UdpSocket::~UdpSocket () { + NS_DEBUG("UdpSocket::~UdpSocket ()"); + m_node = 0; if (m_endPoint != 0) { @@ -60,25 +69,32 @@ UdpSocket::~UdpSocket () enum Socket::SocketErrno UdpSocket::GetErrno (void) const { + NS_DEBUG("UdpSocket::GetErrno ()"); + return m_errno; } Ptr UdpSocket::GetNode (void) const { + NS_DEBUG("UdpSocket::GetNode ()"); return m_node; } void UdpSocket::Destroy (void) { + NS_DEBUG("UdpSocket::Destroy ()"); m_node = 0; m_endPoint = 0; m_udp = 0; } + int UdpSocket::FinishBind (void) { + NS_DEBUG("UdpSocket::FinishBind ()"); + if (m_endPoint == 0) { return -1; @@ -91,14 +107,20 @@ UdpSocket::FinishBind (void) int UdpSocket::Bind (void) { + NS_DEBUG("UdpSocket::Bind ()"); + m_endPoint = m_udp->Allocate (); return FinishBind (); } + int UdpSocket::Bind (const Address &address) { + NS_DEBUG("UdpSocket::Bind (" << address << ")"); + if (!InetSocketAddress::IsMatchingType (address)) { + NS_DEBUG("UdpSocket::Bind (): Not IsMatchingType"); return ERROR_INVAL; } InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); @@ -127,12 +149,15 @@ UdpSocket::Bind (const Address &address) int UdpSocket::ShutdownSend (void) { + NS_DEBUG("UdpSocket::ShutDownSend ()"); m_shutdownSend = true; return 0; } + int UdpSocket::ShutdownRecv (void) { + NS_DEBUG("UdpSocket::ShutDownRecv ()"); m_shutdownRecv = false; return 0; } @@ -140,6 +165,7 @@ UdpSocket::ShutdownRecv (void) int UdpSocket::Close(void) { + NS_DEBUG("UdpSocket::Close ()"); NotifyCloseCompleted (); return 0; } @@ -147,6 +173,8 @@ UdpSocket::Close(void) int UdpSocket::Connect(const Address & address) { + NS_DEBUG("UdpSocket::Connect (" << address << ")"); + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_defaultAddress = transport.GetIpv4 (); m_defaultPort = transport.GetPort (); @@ -154,9 +182,12 @@ UdpSocket::Connect(const Address & address) m_connected = true; return 0; } + int UdpSocket::Send (const Packet &p) { + NS_DEBUG("UdpSocket::Send (" << &p << ")"); + if (!m_connected) { m_errno = ERROR_NOTCONN; @@ -164,17 +195,23 @@ UdpSocket::Send (const Packet &p) } return DoSendTo (p, m_defaultAddress, m_defaultPort); } + int UdpSocket::DoSendTo (const Packet &p, const Address &address) { + NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << address << ")"); InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); return DoSendTo (p, ipv4, port); } + int UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port) { + NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << ipv4 << ", " << + port << ")"); + if (m_endPoint == 0) { if (Bind () == -1) @@ -189,14 +226,18 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port) m_errno = ERROR_SHUTDOWN; return -1; } + + NS_DEBUG("UdpSocket::DoSendTo (): Send to UDP"); m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4, m_endPoint->GetLocalPort (), port); NotifyDataSent (p.GetSize ()); return 0; } + int UdpSocket::SendTo(const Address &address, const Packet &p) { + NS_DEBUG("UdpSocket::SendTo (" << address << ", " << &p << ")"); if (m_connected) { m_errno = ERROR_ISCONN; @@ -211,6 +252,9 @@ UdpSocket::SendTo(const Address &address, const Packet &p) void UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port) { + NS_DEBUG("UdpSocket::ForwardUp (" << &packet << ", " << ipv4 << ", " << + port << ")"); + if (m_shutdownRecv) { return; From d62a38e533db8466d0183da51bec9195d3b0707c Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 12 Aug 2007 22:41:24 -0700 Subject: [PATCH 03/23] many debug prints --- examples/csma-multicast.cc | 13 +++++- examples/csma-one-subnet.cc | 43 +++++++++++++++--- examples/simple-point-to-point.cc | 48 ++++++++++++++++---- src/devices/csma/csma-ipv4-topology.cc | 44 +++++++++--------- src/internet-node/arp-ipv4-interface.cc | 28 ++++++++++-- src/internet-node/ipv4-interface.cc | 40 +++++++++++++--- src/internet-node/ipv4-l3-protocol.cc | 35 ++++++++++---- src/internet-node/ipv4-loopback-interface.cc | 24 ++++++++-- src/internet-node/ipv4-static-routing.cc | 6 ++- 9 files changed, 213 insertions(+), 68 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 19e01be7e..207d611b9 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -67,17 +67,23 @@ main (int argc, char *argv[]) // for selected modules; the below lines suggest how to do this #if 0 DebugComponentEnable("Me"); + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("Ipv4L3Protocol"); DebugComponentEnable("NetDevice"); - DebugComponentEnable("Channel"); - DebugComponentEnable("CsmaChannel"); DebugComponentEnable("PacketSocket"); DebugComponentEnable("OnOffApplication"); DebugComponentEnable("UdpSocket"); DebugComponentEnable("UdpL4Protocol"); DebugComponentEnable("Ipv4L3Protocol"); DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); #endif DebugComponentEnable("Me"); @@ -88,6 +94,9 @@ main (int argc, char *argv[]) DebugComponentEnable("Ipv4StaticRouting"); DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, diff --git a/examples/csma-one-subnet.cc b/examples/csma-one-subnet.cc index dc1bd58c0..033a0135d 100644 --- a/examples/csma-one-subnet.cc +++ b/examples/csma-one-subnet.cc @@ -58,24 +58,48 @@ #include "ns3/ipv4-route.h" #include "ns3/onoff-application.h" - using namespace ns3; +NS_DEBUG_COMPONENT_DEFINE ("Me"); -int main (int argc, char *argv[]) +int +main (int argc, char *argv[]) { - // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this #if 0 + DebugComponentEnable("Me"); + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("Ipv4L3Protocol"); DebugComponentEnable("NetDevice"); - DebugComponentEnable("Channel"); - DebugComponentEnable("CsmaChannel"); DebugComponentEnable("PacketSocket"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); #endif + DebugComponentEnable("Me"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, // and what the queue limit is @@ -90,16 +114,19 @@ int main (int argc, char *argv[]) // Here, we will explicitly create four nodes. In more sophisticated // topologies, we could configure a node factory. + NS_DEBUG("Create nodes."); Ptr n0 = Create (); Ptr n1 = Create (); Ptr n2 = Create (); Ptr n3 = Create (); // We create the channels first without any IP addressing information + NS_DEBUG("Create channels."); Ptr channel0 = CsmaTopology::CreateCsmaChannel( DataRate(5000000), MilliSeconds(2)); + NS_DEBUG("Build Topology."); uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, Eui48Address("10:54:23:54:23:50")); uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, @@ -110,6 +137,7 @@ int main (int argc, char *argv[]) Eui48Address("10:54:23:54:23:53")); // Later, we add IP addresses. + NS_DEBUG("Assign IP Addresses."); CsmaIpv4Topology::AddIpv4Address ( n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); @@ -125,6 +153,7 @@ int main (int argc, char *argv[]) // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s // from n0 to n1 + NS_DEBUG("Create Applications."); Ptr ooff = Create ( n0, InetSocketAddress ("10.1.1.2", 80), @@ -148,6 +177,7 @@ int main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the csma-one-subnet.tr file + NS_DEBUG("Configure Tracing."); AsciiTrace asciitrace ("csma-one-subnet.tr"); asciitrace.TraceAllNetDeviceRx (); asciitrace.TraceAllQueues (); @@ -160,7 +190,8 @@ int main (int argc, char *argv[]) PcapTrace pcaptrace ("csma-one-subnet.pcap"); pcaptrace.TraceAllIp (); + NS_DEBUG("Run Simulation."); Simulator::Run (); - Simulator::Destroy (); + NS_DEBUG("Done."); } diff --git a/examples/simple-point-to-point.cc b/examples/simple-point-to-point.cc index 9b185143b..14838a18e 100644 --- a/examples/simple-point-to-point.cc +++ b/examples/simple-point-to-point.cc @@ -38,11 +38,7 @@ // - Tracing of queues and packet receptions to file // "simple-point-to-point.tr" -#include -#include -#include -#include - +#include "ns3/debug.h" #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" @@ -67,20 +63,47 @@ using namespace ns3; -int main (int argc, char *argv[]) +NS_DEBUG_COMPONENT_DEFINE ("Me"); + +int +main (int argc, char *argv[]) { // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this #if 0 + DebugComponentEnable("Me"); DebugComponentEnable("Object"); DebugComponentEnable("Queue"); DebugComponentEnable("DropTailQueue"); DebugComponentEnable("Channel"); DebugComponentEnable("PointToPointChannel"); DebugComponentEnable("PointToPointNetDevice"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("NetDevice"); + DebugComponentEnable("PacketSocket"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); #endif + DebugComponentEnable("Me"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("PointToPointChannel"); + DebugComponentEnable("PointToPointNetDevice"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, // and what the queue limit is @@ -100,12 +123,14 @@ int main (int argc, char *argv[]) // Here, we will explicitly create four nodes. In more sophisticated // topologies, we could configure a node factory. + NS_DEBUG("Create nodes."); Ptr n0 = Create (); Ptr n1 = Create (); Ptr n2 = Create (); Ptr n3 = Create (); // We create the channels first without any IP addressing information + NS_DEBUG("Create channels."); Ptr channel0 = PointToPointTopology::AddPointToPointLink ( n0, n2, DataRate(5000000), MilliSeconds(2)); @@ -119,6 +144,7 @@ int main (int argc, char *argv[]) n2, n3, DataRate(1500000), MilliSeconds(10)); // Later, we add IP addresses. + NS_DEBUG("Assign IP Addresses."); PointToPointTopology::AddIpv4Addresses ( channel0, n0, Ipv4Address("10.1.1.1"), n2, Ipv4Address("10.1.1.2")); @@ -135,13 +161,14 @@ int main (int argc, char *argv[]) // NetDevice creation, IP Address assignment, and routing) are // separated because there may be a need to postpone IP Address // assignment (emulation) or modify to use dynamic routing + NS_DEBUG("Add Static Routes."); PointToPointTopology::AddIpv4Routes(n0, n2, channel0); 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 + NS_DEBUG("Create Applications."); Ptr ooff = Create ( n0, InetSocketAddress ("10.1.3.2", 80), @@ -165,6 +192,7 @@ int main (int argc, char *argv[]) // Here, finish off packet routing configuration // This will likely set by some global StaticRouting object in the future + NS_DEBUG("Set Default Routes."); Ptr ipv4; ipv4 = n0->QueryInterface (Ipv4::iid); ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); @@ -173,6 +201,7 @@ int main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-point-to-point.tr file + NS_DEBUG("Configure Tracing."); AsciiTrace asciitrace ("simple-point-to-point.tr"); asciitrace.TraceAllQueues (); asciitrace.TraceAllNetDeviceRx (); @@ -185,7 +214,8 @@ int main (int argc, char *argv[]) PcapTrace pcaptrace ("simple-point-to-point.pcap"); pcaptrace.TraceAllIp (); - Simulator::Run (); - + NS_DEBUG("Run Simulation."); + Simulator::Run (); Simulator::Destroy (); + NS_DEBUG("Done."); } diff --git a/src/devices/csma/csma-ipv4-topology.cc b/src/devices/csma/csma-ipv4-topology.cc index 02cd0e487..8e102af0b 100644 --- a/src/devices/csma/csma-ipv4-topology.cc +++ b/src/devices/csma/csma-ipv4-topology.cc @@ -36,15 +36,15 @@ namespace ns3 { uint32_t CsmaIpv4Topology::AddIpv4CsmaNode(Ptr n1, - Ptr ch, - Eui48Address addr) + Ptr ch, + Eui48Address addr) { Ptr q = Queue::CreateDefault (); // assume full-duplex Ptr nd0 = Create (n1, addr, - ns3::CsmaNetDevice::IP_ARP, - true, true); + ns3::CsmaNetDevice::IP_ARP, + true, true); nd0->AddQueue(q); nd0->Attach (ch); return nd0->GetIfIndex (); @@ -53,51 +53,50 @@ CsmaIpv4Topology::AddIpv4CsmaNode(Ptr n1, void CsmaIpv4Topology::AddIpv4LlcCsmaNode(Ptr n1, - Ptr ch, - Eui48Address addr) + Ptr ch, + Eui48Address addr) { Ptr q = Queue::CreateDefault (); Ptr nd0 = Create (n1, addr, - ns3::CsmaNetDevice::LLC, - true, false); + ns3::CsmaNetDevice::LLC, + true, false); nd0->AddQueue(q); nd0->Attach (ch); Ptr nd1 = Create (n1, addr, - ns3::CsmaNetDevice::LLC, - false, true); + ns3::CsmaNetDevice::LLC, + false, true); nd1->AddQueue(q); nd1->Attach (ch); } void CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr n1, - Ptr ch, - Eui48Address addr) + Ptr ch, + Eui48Address addr) { Ptr q = Queue::CreateDefault (); Ptr nd0 = Create (n1, addr, - ns3::CsmaNetDevice::RAW, - true, false); + ns3::CsmaNetDevice::RAW, + true, false); nd0->AddQueue(q); nd0->Attach (ch); Ptr nd1 = Create (n1, addr, - ns3::CsmaNetDevice::RAW, - false, true); + ns3::CsmaNetDevice::RAW, + false, true); nd1->AddQueue(q); nd1->Attach (ch); } void CsmaIpv4Topology::AddIpv4Address(Ptr n1, - int ndNum, - const Ipv4Address& addr1, - const Ipv4Mask& netmask1) + int ndNum, + const Ipv4Address& addr1, + const Ipv4Mask& netmask1) { - // Duplex link is assumed to be subnetted as a /30 // May run this unnumbered in the future? Ipv4Mask netmask(netmask1); @@ -110,7 +109,6 @@ CsmaIpv4Topology::AddIpv4Address(Ptr n1, ip1->SetAddress (index1, addr1); ip1->SetNetworkMask (index1, netmask); ip1->SetUp (index1); - } void @@ -133,7 +131,7 @@ CsmaIpv4Topology::AddIpv4Routes ( found = true; } } - NS_ASSERT(found); + NS_ASSERT (found); uint32_t index2 = 0; found = false; @@ -145,7 +143,7 @@ CsmaIpv4Topology::AddIpv4Routes ( found = true; } } - NS_ASSERT(found); + NS_ASSERT (found); ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1); ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index efe767531..2e9d375b7 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -31,18 +31,26 @@ #include "ipv4-l3-protocol.h" #include "arp-l3-protocol.h" +NS_DEBUG_COMPONENT_DEFINE ("ArpIpv4Interface"); + namespace ns3 { ArpIpv4Interface::ArpIpv4Interface (Ptr node, Ptr device) : Ipv4Interface (device), m_node (node) -{} +{ + NS_DEBUG ("ArpIpv4Interface::ArpIpv4Interface ()"); +} + ArpIpv4Interface::~ArpIpv4Interface () -{} +{ + NS_DEBUG ("ArpIpv4Interface::~ArpIpv4Interface ()"); +} TraceResolver * ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) { + NS_DEBUG ("ArpIpv4Interface::DoCreateTraceResolver ()"); CompositeTraceResolver *resolver = new CompositeTraceResolver (context); if (GetDevice () != 0) { @@ -56,31 +64,41 @@ ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) void ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) { + NS_DEBUG ("ArpIpv4Interface::SendTo (" << &p << ", " << dest << ")"); + NS_ASSERT (GetDevice () != 0); if (GetDevice ()->NeedsArp ()) { - Ptr arp = m_node->QueryInterface (ArpL3Protocol::iid); + NS_DEBUG ("ArpIpv4Interface::SendTo (): Needs ARP"); + Ptr arp = + m_node->QueryInterface (ArpL3Protocol::iid); Address hardwareDestination; bool found; if (dest.IsBroadcast ()) { + NS_DEBUG ("ArpIpv4Interface::SendTo (): IsBroadcast"); hardwareDestination = GetDevice ()->GetBroadcast (); found = true; } else { + NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup"); found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination); } if (found) { - GetDevice ()->Send (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER); + NS_DEBUG ("ArpIpv4Interface::SendTo (): Address Resolved. Send."); + GetDevice ()->Send (p, hardwareDestination, + Ipv4L3Protocol::PROT_NUMBER); } } else { - GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER); + NS_DEBUG ("ArpIpv4Interface::SendTo (): Doesn't need ARP"); + GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), + Ipv4L3Protocol::PROT_NUMBER); } } diff --git a/src/internet-node/ipv4-interface.cc b/src/internet-node/ipv4-interface.cc index cfc398582..c22a1e783 100644 --- a/src/internet-node/ipv4-interface.cc +++ b/src/internet-node/ipv4-interface.cc @@ -22,6 +22,9 @@ #include "ipv4-interface.h" #include "ns3/ipv4-address.h" #include "ns3/net-device.h" +#include "ns3/debug.h" + +NS_DEBUG_COMPONENT_DEFINE ("Ipv4Interface"); namespace ns3 { @@ -34,56 +37,72 @@ namespace ns3 { Ipv4Interface::Ipv4Interface (Ptr nd) : m_netdevice (nd), m_ifup(false) -{} +{ + NS_DEBUG ("Ipv4Interface::Ipv4Interface (" << &nd << ")"); +} Ipv4Interface::~Ipv4Interface () -{} +{ + NS_DEBUG ("Ipv4Interface::~Ipv4Interface ()"); +} Ptr Ipv4Interface::GetDevice (void) const { + NS_DEBUG ("Ipv4Interface::GetDevice ()"); return m_netdevice; } TraceResolver * Ipv4Interface::CreateTraceResolver (TraceContext const &context) { + NS_DEBUG ("Ipv4Interface::CreateTraceResolver (" << &context << ")"); return DoCreateTraceResolver (context); } void Ipv4Interface::SetAddress (Ipv4Address a) { + NS_DEBUG ("Ipv4Interface::SetAddress (" << a << ")"); m_address = a; } + void Ipv4Interface::SetNetworkMask (Ipv4Mask mask) { + NS_DEBUG ("Ipv4Interface::SetMask (" << mask << ")"); m_netmask = mask; } Ipv4Address Ipv4Interface::GetBroadcast (void) const { + NS_DEBUG ("Ipv4Interface::GetBroadcast ()"); + uint32_t mask = m_netmask.GetHostOrder (); uint32_t address = m_address.GetHostOrder (); Ipv4Address broadcast = Ipv4Address (address | (~mask)); return broadcast; } + Ipv4Mask Ipv4Interface::GetNetworkMask (void) const { + NS_DEBUG ("Ipv4Interface::GetNetworkMask ()"); return m_netmask; } + Ipv4Address Ipv4Interface::GetAddress (void) const { + NS_DEBUG ("Ipv4Interface::Address ()"); return m_address; } uint16_t Ipv4Interface::GetMtu (void) const { + NS_DEBUG ("Ipv4Interface::GetMtu ()"); if (m_netdevice == 0) { uint32_t mtu = (1<<16) - 1; @@ -92,32 +111,36 @@ Ipv4Interface::GetMtu (void) const return m_netdevice->GetMtu (); } - /** - * These are IP interface states and may be distinct from - * NetDevice states, such as found in real implementations - * (where the device may be down but IP interface state is still up). - */ +/** + * These are IP interface states and may be distinct from + * NetDevice states, such as found in real implementations + * (where the device may be down but IP interface state is still up). + */ bool Ipv4Interface::IsUp (void) const { + NS_DEBUG ("Ipv4Interface::IsUp ()"); return m_ifup; } bool Ipv4Interface::IsDown (void) const { + NS_DEBUG ("Ipv4Interface::IsDown ()"); return !m_ifup; } void Ipv4Interface::SetUp (void) { + NS_DEBUG ("Ipv4Interface::SetUp ()"); m_ifup = true; } void Ipv4Interface::SetDown (void) { + NS_DEBUG ("Ipv4Interface::SetDown ()"); m_ifup = false; } @@ -125,7 +148,10 @@ Ipv4Interface::SetDown (void) void Ipv4Interface::Send(Packet p, Ipv4Address dest) { + NS_DEBUG ("Ipv4Interface::Send ()"); + if (IsUp()) { + NS_DEBUG ("Ipv4Interface::Send (): SendTo ()"); SendTo(p, dest); } } diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 8ccadb05e..d140febe0 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -494,25 +494,32 @@ Ipv4L3Protocol::SendRealOut (bool found, if (!found) { - NS_DEBUG ("no route to host. drop."); + NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): No route to host. Drop."); m_dropTrace (packet); return; } + + NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send via interface " << + route.GetInterface ()); + packet.AddHeader (ipHeader); Ipv4Interface *outInterface = GetInterface (route.GetInterface ()); NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ()); m_txTrace (packet, route.GetInterface ()); if (route.IsGateway ()) { + NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send to gateway " << + route.GetGateway ()); outInterface->Send (packet, route.GetGateway ()); } else { + NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send to destination " << + ipHeader.GetDestination ()); outInterface->Send (packet, ipHeader.GetDestination ()); } } - bool Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) { @@ -524,7 +531,8 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, PtrGetAddress ().IsEqual (ipHeader.GetDestination ())) { - NS_DEBUG ("for me 1"); + NS_DEBUG("Ipv4L3Protocol::Forwarding (): " + "For me (destination match)"); return false; } } @@ -537,7 +545,8 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, PtrGetBroadcast ())) { - NS_DEBUG ("for me 2"); + NS_DEBUG("Ipv4L3Protocol::Forwarding (): " + "For me (interface broadcast address)"); return false; } break; @@ -546,25 +555,30 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr, */ + +#include "ns3/debug.h" #include "ns3/empty-trace-resolver.h" #include "ns3/net-device.h" #include "ns3/node.h" @@ -26,26 +28,40 @@ #include "ipv4-loopback-interface.h" #include "ipv4-l3-protocol.h" +NS_DEBUG_COMPONENT_DEFINE ("Ipv4LoopbackInterface"); + namespace ns3 { Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr node) : Ipv4Interface (0), m_node (node) -{} +{ + NS_DEBUG("Ipv4LoopbackInterface::Ipv4LoopbackInterface ()"); +} + Ipv4LoopbackInterface::~Ipv4LoopbackInterface () -{} +{ + NS_DEBUG("Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()"); +} TraceResolver * Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context) { + NS_DEBUG("Ipv4LoopbackInterface::DoCreateTraceResolver ()"); return new EmptyTraceResolver (context); } void Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest) { - Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); - ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, Eui48Address ("ff:ff:ff:ff:ff:ff")); + NS_DEBUG("Ipv4LoopbackInterface::SendTo (" << &packet << ", " << + dest << ")"); + + Ptr ipv4 = + m_node->QueryInterface (Ipv4L3Protocol::iid); + + ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, + Eui48Address ("ff:ff:ff:ff:ff:ff")); } }//namespace ns3 diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index a7cc93bac..785e817ff 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -27,7 +27,6 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting"); namespace ns3 { - void Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, @@ -325,7 +324,6 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " << ipHeader.GetDestination ()); - // // 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. @@ -334,12 +332,15 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, ipHeader.GetDestination ()); if (mRoute) { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast route"); for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) { Packet p = packet; Ipv4Route route = Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), mRoute->GetOutputInterface(i)); + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " + "Send via interface " << mRoute->GetOutputInterface(i)); routeReply (true, route, p, ipHeader); return true; } @@ -347,6 +348,7 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, // // See if this is a unicast packet we have a route for. // + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast route"); Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); if (route != 0) { From e567af9b24e78a2b58c7044399af2b2bd89d8eef Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 13 Aug 2007 12:08:01 -0700 Subject: [PATCH 04/23] more multicast plumbing --- examples/csma-multicast.cc | 84 ++++++++++++++---------- src/applications/onoff-application.cc | 7 +- src/devices/csma/csma-ipv4-topology.cc | 28 ++++---- src/devices/csma/csma-ipv4-topology.h | 23 ++++--- src/internet-node/arp-ipv4-interface.cc | 8 +++ src/internet-node/ipv4-l3-protocol.cc | 45 +++++++++---- src/internet-node/ipv4-l3-protocol.h | 9 ++- src/internet-node/ipv4-static-routing.cc | 51 +++++++++----- src/internet-node/ipv4-static-routing.h | 6 +- src/node/ipv4-address.cc | 7 +- src/node/ipv4.h | 6 +- 11 files changed, 177 insertions(+), 97 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 207d611b9..3af6fc937 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -65,7 +65,7 @@ main (int argc, char *argv[]) { // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this -#if 0 +#if 0 DebugComponentEnable("Me"); DebugComponentEnable("Object"); DebugComponentEnable("Queue"); @@ -87,16 +87,9 @@ main (int argc, char *argv[]) #endif DebugComponentEnable("Me"); - DebugComponentEnable("OnOffApplication"); - DebugComponentEnable("UdpSocket"); - DebugComponentEnable("UdpL4Protocol"); - DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("Ipv4StaticRouting"); - DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("CsmaChannel"); - DebugComponentEnable("Ipv4Interface"); - DebugComponentEnable("ArpIpv4Interface"); - DebugComponentEnable("Ipv4LoopbackInterface"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("UdpL4Protocol"); // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, @@ -125,29 +118,47 @@ main (int argc, char *argv[]) DataRate(5000000), MilliSeconds(2)); NS_DEBUG("Build Topology."); - uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, - Eui48Address("10:54:23:54:23:50")); - uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, - Eui48Address("10:54:23:54:23:51")); - uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0, - Eui48Address("10:54:23:54:23:52")); - uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0, - Eui48Address("10:54:23:54:23:53")); + uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, + channel0, Eui48Address("10:54:23:54:23:50")); + uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, + channel0, Eui48Address("10:54:23:54:23:51")); + uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, + channel0, Eui48Address("10:54:23:54:23:52")); + uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, + channel0, Eui48Address("10:54:23:54:23:53")); + + NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0); + NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1); + NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2); + NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3); // Later, we add IP addresses. NS_DEBUG("Assign IP Addresses."); + // XXX BUGBUG + // Need a better way to get the interface index. The point-to-point topology + // as implemented can't return the index since it creates interfaces on both + // sides (i.e., AddIpv4Addresses, not AddIpv4Address). Need a method on + // Ipv4 to find the interface index corresponding to a given ipv4 address. + uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, + netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), + Ipv4Mask ("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); + uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, + netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), + Ipv4Mask ("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); - - CsmaIpv4Topology::AddIpv4Address ( - n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); + uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, + netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), + Ipv4Mask ("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); + uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, + netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), + Ipv4Mask ("255.255.255.0")); + + NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0); + NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1); + NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2); + NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3); // Configure multicasting NS_DEBUG("Configure multicasting."); @@ -158,22 +169,21 @@ main (int argc, char *argv[]) ipv4 = n0->QueryInterface (Ipv4::iid); std::vector outputInterfaces (1); - outputInterfaces[0] = n0ifIndex; + outputInterfaces[0] = ifIndexNode0; ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, outputInterfaces); ipv4 = n1->QueryInterface (Ipv4::iid); - ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ipv4 = n2->QueryInterface (Ipv4::iid); - ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ipv4 = n3->QueryInterface (Ipv4::iid); - ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); - // Create the OnOff application to send UDP datagrams of size - // 210 bytes at a rate of 448 Kb/s + // Create the OnOff application to send UDP datagrams // from n0 to the multicast group NS_DEBUG("Create Applications."); Ptr ooff = Create ( @@ -181,10 +191,12 @@ main (int argc, char *argv[]) InetSocketAddress (multicastGroup, 80), "Udp", ConstantVariable(1), - ConstantVariable(0)); + ConstantVariable(0), + DataRate ("128b/s"), + 128); // Start the application - ooff->Start(Seconds(1.0)); - ooff->Stop (Seconds(10.0)); + ooff->Start(Seconds(1.)); + ooff->Stop (Seconds(10.)); // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the csma-one-subnet.tr file diff --git a/src/applications/onoff-application.cc b/src/applications/onoff-application.cc index 297d57e3e..9df4274bc 100644 --- a/src/applications/onoff-application.cc +++ b/src/applications/onoff-application.cc @@ -199,9 +199,12 @@ void OnOffApplication::ScheduleNextTx() if (m_totBytes < m_maxBytes) { uint32_t bits = m_pktSize * 8 - m_residualBits; + NS_DEBUG("OnOffApplication::ScheduleNextTx (): bits = " << bits); Time nextTime(Seconds (bits / static_cast(m_cbrRate.GetBitRate()))); // Time till next packet - m_sendEvent = Simulator::Schedule(nextTime, &OnOffApplication::SendPacket, this); + NS_DEBUG("OnOffApplication::ScheduleNextTx (): nextTime = " << nextTime); + m_sendEvent = Simulator::Schedule(nextTime, + &OnOffApplication::SendPacket, this); } else { // All done, cancel any pending events @@ -214,6 +217,8 @@ void OnOffApplication::ScheduleStartEvent() NS_DEBUG("OnOffApplication::ScheduleStartEvent ()"); Time offInterval = Seconds(m_offTime->GetValue()); + NS_DEBUG("OnOffApplication::ScheduleStartEvent (): " + "start at " << offInterval); m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this); } diff --git a/src/devices/csma/csma-ipv4-topology.cc b/src/devices/csma/csma-ipv4-topology.cc index 8e102af0b..ff36b5502 100644 --- a/src/devices/csma/csma-ipv4-topology.cc +++ b/src/devices/csma/csma-ipv4-topology.cc @@ -91,24 +91,22 @@ CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr n1, nd1->Attach (ch); } -void -CsmaIpv4Topology::AddIpv4Address(Ptr n1, - int ndNum, - const Ipv4Address& addr1, - const Ipv4Mask& netmask1) +uint32_t +CsmaIpv4Topology::AddIpv4Address( + Ptr node, + uint32_t netDeviceNumber, + const Ipv4Address address, + const Ipv4Mask mask) { - // Duplex link is assumed to be subnetted as a /30 - // May run this unnumbered in the future? - Ipv4Mask netmask(netmask1); + Ptr nd = node->GetDevice(netDeviceNumber); - Ptr nd1 = n1->GetDevice(ndNum); + Ptr ipv4 = node->QueryInterface (Ipv4::iid); + uint32_t ifIndex = ipv4->AddInterface (nd); - Ptr ip1 = n1->QueryInterface (Ipv4::iid); - uint32_t index1 = ip1->AddInterface (nd1); - - ip1->SetAddress (index1, addr1); - ip1->SetNetworkMask (index1, netmask); - ip1->SetUp (index1); + ipv4->SetAddress (ifIndex, address); + ipv4->SetNetworkMask (ifIndex, mask); + ipv4->SetUp (ifIndex); + return ifIndex; } void diff --git a/src/devices/csma/csma-ipv4-topology.h b/src/devices/csma/csma-ipv4-topology.h index 37f546118..ca4aa982b 100644 --- a/src/devices/csma/csma-ipv4-topology.h +++ b/src/devices/csma/csma-ipv4-topology.h @@ -94,18 +94,23 @@ public: /** - * \param n1 Node - * \param ndNum NetDevice number with which to associate address - * \param addr1 Ipv4 Address for ndNum of n1 - * \param network network mask for ndNum of node n1 + * \brief Create an Ipv4 interface for a net device and assign an + * Ipv4Address to that interface. + * + * \param node The node to which to add the new address and corresponding + * interface. + * \param netDeviceNumber The NetDevice index number with which to associate + * the address. + * \param address The Ipv4 Address for the interface. + * \param network The network mask for the interface * * Add an Ipv4Address to the Ipv4 interface associated with the - * ndNum CsmaIpv4NetDevices on the provided - * CsmaIpv4Channel + * ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel */ - static void AddIpv4Address(Ptr n1, int ndNum, - const Ipv4Address& addr1, - const Ipv4Mask& netmask1); + static uint32_t AddIpv4Address(Ptr node, + uint32_t netDeviceNumber, + const Ipv4Address address, + const Ipv4Mask mask); /** * \param nd1 Node diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index 2e9d375b7..b5f87f0b6 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -81,6 +81,14 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) hardwareDestination = GetDevice ()->GetBroadcast (); found = true; } + else if (dest.IsMulticast ()) + { + NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast"); + // XXX BUGBUG + // Need real multicast addresses + hardwareDestination = GetDevice ()->GetBroadcast (); + found = true; + } else { NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup"); diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index d140febe0..2326d1021 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -246,12 +246,26 @@ Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, } void -Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, - Packet packet, - Ipv4RoutingProtocol::RouteReplyCallback routeReply) +Ipv4L3Protocol::Lookup ( + Ipv4Header const &ipHeader, + Packet packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) { - NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ", " << &packet << - &routeReply << ")"); + NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << + ", " << &packet << &routeReply << ")"); + + Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply); +} + +void +Ipv4L3Protocol::Lookup ( + uint32_t ifIndex, + Ipv4Header const &ipHeader, + Packet packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) +{ + NS_DEBUG("Ipv4L3Protocol::Lookup (" << ifIndex << ", " << &ipHeader << + ", " << &packet << &routeReply << ")"); for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); @@ -259,7 +273,8 @@ Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, rprotoIter++) { NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route"); - if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) + if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet, + routeReply)) return; } @@ -405,7 +420,9 @@ Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protoc protocol << ", " << from << ")"); uint32_t index = 0; - for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); + i != m_interfaces.end (); + i++) { if ((*i)->GetDevice () == device) { @@ -423,7 +440,7 @@ Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protoc return; } - if (Forwarding (packet, ipHeader, device)) + if (Forwarding (index, packet, ipHeader, device)) { return; } @@ -521,10 +538,14 @@ Ipv4L3Protocol::SendRealOut (bool found, } bool -Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) +Ipv4L3Protocol::Forwarding ( + uint32_t ifIndex, + Packet const &packet, + Ipv4Header &ipHeader, + Ptr device) { - NS_DEBUG("Ipv4L3Protocol::Forwarding (" << &packet << ", " << &ipHeader << - ", " << device << ")"); + NS_DEBUG("Ipv4L3Protocol::Forwarding (" << ifIndex << ", " << &packet << + ", " << &ipHeader << ", " << device << ")"); for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) @@ -579,7 +600,7 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device); + bool Forwarding (uint32_t ifIndex, + Packet const &packet, + Ipv4Header &ipHeader, + Ptr device); void ForwardUp (Packet p, Ipv4Header const&ip); uint32_t AddIpv4Interface (Ipv4Interface *interface); void SetupLoopback (void); diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index 785e817ff..e6e67b516 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -196,7 +196,8 @@ Ipv4StaticRouting::LookupStatic (Ipv4Address dest) Ipv4MulticastRoute * Ipv4StaticRouting::LookupStatic ( Ipv4Address origin, - Ipv4Address group) + Ipv4Address group, + uint32_t ifIndex) { for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); @@ -207,7 +208,11 @@ Ipv4StaticRouting::LookupStatic ( origin == Ipv4Address::GetAny ()) && group == route->GetGroup ()) { - return *i; + if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || + ifIndex == route->GetInputInterface ()) + { + return *i; + } } } return 0; @@ -312,9 +317,11 @@ Ipv4StaticRouting::RemoveRoute (uint32_t index) } bool -Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, - Packet packet, - RouteReplyCallback routeReply) +Ipv4StaticRouting::RequestRoute ( + uint32_t ifIndex, + Ipv4Header const &ipHeader, + Packet packet, + RouteReplyCallback routeReply) { NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " << &packet << ", " << &routeReply << ")"); @@ -328,27 +335,35 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, // 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. // - Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), - ipHeader.GetDestination ()); - if (mRoute) + if (ipHeader.GetDestination ().IsMulticast ()) { - NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast route"); - for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination"); + + Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), + ipHeader.GetDestination (), ifIndex); + + if (mRoute) { - Packet p = packet; - Ipv4Route route = - Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), - mRoute->GetOutputInterface(i)); NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " - "Send via interface " << mRoute->GetOutputInterface(i)); - routeReply (true, route, p, ipHeader); - return true; + "Multicast route found"); + for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) + { + Packet p = packet; + Ipv4Route route = + Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), + mRoute->GetOutputInterface(i)); + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " + "Send via interface " << mRoute->GetOutputInterface(i)); + routeReply (true, route, p, ipHeader); + return true; + } } + return false; // Let other routing protocols try to handle this } // // See if this is a unicast packet we have a route for. // - NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast route"); + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination"); Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); if (route != 0) { diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index 24a228048..76bb80c40 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -51,7 +51,8 @@ class Ipv4StaticRouting : public Ipv4RoutingProtocol public: Ipv4StaticRouting () : m_defaultRoute (0) {} - virtual bool RequestRoute (Ipv4Header const &ipHeader, + virtual bool RequestRoute (uint32_t ifIndex, + Ipv4Header const &ipHeader, Packet packet, RouteReplyCallback routeReply); @@ -105,7 +106,8 @@ private: typedef std::list::iterator MulticastRoutesI; Ipv4Route *LookupStatic (Ipv4Address dest); - Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group); + Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group, + uint32_t ifIndex); HostRoutes m_hostRoutes; NetworkRoutes m_networkRoutes; diff --git a/src/node/ipv4-address.cc b/src/node/ipv4-address.cc index 34b15372d..4e1e344c5 100644 --- a/src/node/ipv4-address.cc +++ b/src/node/ipv4-address.cc @@ -171,8 +171,11 @@ Ipv4Address::IsBroadcast (void) const bool Ipv4Address::IsMulticast (void) const { - // XXX - return false; +// +// Multicast addresses are defined as ranging from 224.0.0.0 through +// 239.255.255.255 (which is E0000000 through EFFFFFFF in hex). +// + return (m_address >= 0xe0000000 && m_address <= 0xefffffff); } uint32_t diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 06cf5c130..d56a70c70 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -70,6 +70,7 @@ public: /** * \brief Asynchronously requests a route for a given packet and IP header * + * \param ifIndex The interface index on which the packet was received. * \param ipHeader IP header of the packet * \param packet packet that is being sent or forwarded * \param routeReply callback that will receive the route reply @@ -99,9 +100,12 @@ public: * immediately after the IP header, although most routing do not * insert any extra header. */ - virtual bool RequestRoute (const Ipv4Header &ipHeader, + virtual bool RequestRoute (uint32_t ifIndex, + const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply) = 0; + + static const uint32_t IF_INDEX_ANY = 0xffffffff; }; /** From 90451d96358365efaca576a1bd03b97ce69e1809 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 13 Aug 2007 14:58:06 -0700 Subject: [PATCH 05/23] cleanup. more complex multicast example --- examples/csma-multicast.cc | 278 ++++++++++++++++--------- examples/csma-one-subnet.cc | 181 +++++++++------- examples/mixed-global-routing.cc | 8 +- src/devices/csma/csma-ipv4-topology.cc | 19 +- src/devices/csma/csma-ipv4-topology.h | 6 +- 5 files changed, 297 insertions(+), 195 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 3af6fc937..ae4c3c4cf 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -16,31 +16,27 @@ // Network topology // -// n0 n1 n2 n3 -// | | | | -// ===================== +// Lan1 +// =========== +// | | | +// n0 n1 n2 n3 n4 +// | | | +// =========== +// Lan0 // -// - CBR/UDP flows from n0 to n1, and from n3 to n0 -// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. -// (i.e., DataRate of 448,000 bps) -// - DropTail queues -// - Tracing of queues and packet receptions to file "csma-one-subnet.tr" - -#include -#include -#include -#include +// - Multicast source is at node n0; +// - Multicast forwarded by node n2 onto LAN1; +// - Nodes n0, n1, n2, n3, and n4 receive the multicast frame. +// - Node n4 listens for the data (actual listener not yet implementted) #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" #include "ns3/debug.h" - #include "ns3/simulator.h" #include "ns3/nstime.h" #include "ns3/data-rate.h" - #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/internet-node.h" @@ -58,15 +54,18 @@ using namespace ns3; -NS_DEBUG_COMPONENT_DEFINE ("Me"); +NS_DEBUG_COMPONENT_DEFINE ("CsmaMulticast"); int main (int argc, char *argv[]) { - // Users may find it convenient to turn on explicit debugging - // for selected modules; the below lines suggest how to do this +// +// Users may find it convenient to turn on explicit debugging +// for selected modules; the below lines suggest how to do this +// #if 0 - DebugComponentEnable("Me"); + DebugComponentEnable("CsmaMulticast"); + DebugComponentEnable("Object"); DebugComponentEnable("Queue"); DebugComponentEnable("DropTailQueue"); @@ -86,105 +85,182 @@ main (int argc, char *argv[]) DebugComponentEnable("Ipv4LoopbackInterface"); #endif - DebugComponentEnable("Me"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + + DebugComponentEnable("CsmaMulticast"); DebugComponentEnable("CsmaChannel"); DebugComponentEnable("CsmaNetDevice"); - DebugComponentEnable("UdpL4Protocol"); - - // Set up some default values for the simulation. Use the Bind() - // technique to tell the system what subclass of Queue to use, - // and what the queue limit is - - // The below Bind command tells the queue factory which class to - // instantiate, when the queue factory is invoked in the topology code +// +// Set up default values for the simulation. Use the DefaultValue::Bind() +// technique to tell the system what subclass of Queue to use. The Bind +// command command tells the queue factory which class to instantiate when the +// queue factory is invoked in the topology code +// DefaultValue::Bind ("Queue", "DropTailQueue"); - - // Allow the user to override any of the defaults and the above - // Bind()s at run-time, via command-line arguments +// +// Allow the user to override any of the defaults and the above Bind() at +// run-time, via command-line arguments +// CommandLine::Parse (argc, argv); - - // Here, we will explicitly create four nodes. In more sophisticated - // topologies, we could configure a node factory. +// +// Explicitly create the nodes required by the topology (shown above). +// NS_DEBUG("Create nodes."); Ptr n0 = Create (); Ptr n1 = Create (); Ptr n2 = Create (); Ptr n3 = Create (); + Ptr n4 = Create (); NS_DEBUG("Create channels."); - // We create the channels first without any IP addressing information - Ptr channel0 = +// +// Explicitly create the channels required by the topology (shown above). +// + Ptr lan0 = + CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); + + Ptr lan1 = CsmaTopology::CreateCsmaChannel( DataRate(5000000), MilliSeconds(2)); NS_DEBUG("Build Topology."); - uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, - channel0, Eui48Address("10:54:23:54:23:50")); - uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, - channel0, Eui48Address("10:54:23:54:23:51")); - uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, - channel0, Eui48Address("10:54:23:54:23:52")); - uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, - channel0, Eui48Address("10:54:23:54:23:53")); +// +// Now fill out the topology by creating the net devices required to connect +// the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will +// create a net device, add a MAC address (in memory of the pink flamingo) and +// connect the net device to a nodes and also to a channel. the +// AddIpv4CsmaNetDevice method returns a net device index for the net device +// created on the node. Interpret nd0 as the net device we created for node +// zero. Interpret nd2Lan0 as the net device we created for node two to +// connect to Lan0. +// + uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan0, + Eui48Address("08:00:2e:00:00:00")); + uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan0, + Eui48Address("08:00:2e:00:00:01")); + uint32_t nd2Lan0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan0, + Eui48Address("08:00:2e:00:00:02")); - NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0); - NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1); - NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2); - NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3); + uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, + Eui48Address("08:00:2e:00:00:00")); + uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, + Eui48Address("08:00:2e:00:00:01")); + uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, + Eui48Address("08:00:2e:00:00:02")); - // Later, we add IP addresses. + NS_DEBUG ("nd0 = " << nd0); + NS_DEBUG ("nd1 = " << nd1); + NS_DEBUG ("nd2Lan0 = " << nd2Lan0); + NS_DEBUG ("nd2Lan1 = " << nd2Lan1); + NS_DEBUG ("nd3 = " << nd3); + NS_DEBUG ("nd4 = " << nd3); +// +// We've got the "hardware" in place. Now we need to add IP addresses. +// NS_DEBUG("Assign IP Addresses."); - // XXX BUGBUG - // Need a better way to get the interface index. The point-to-point topology - // as implemented can't return the index since it creates interfaces on both - // sides (i.e., AddIpv4Addresses, not AddIpv4Address). Need a method on - // Ipv4 to find the interface index corresponding to a given ipv4 address. - uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, - netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), - Ipv4Mask ("255.255.255.0")); +// +// XXX BUGBUG +// Need a better way to get the interface index. The point-to-point topology +// as implemented can't return the index since it creates interfaces on both +// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a +// method on Ipv4 to find the interface index corresponding to a given ipv4 +// address. +// +// First, assign IP addresses to the net devices and associated interfaces +// on Lan0. The AddIpv4Address method returns an Ipv4 interface index. +// Interpret ifIndexNd0 as the interface index to use to reference the +// net device we created on node zero when coming in from the Ipv4 interface. +// Net device numbers and interface indices are distinct. Interpret +// ifIndexNd2Lan0 as the interface index to use to reference the +// net device we created that connects node two to lan zero. +// + uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, + Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0")); - uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, - netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), - Ipv4Mask ("255.255.255.0")); + uint32_t ifIndexNd1 = CsmaIpv4Topology::AddIpv4Address (n1, nd1, + Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0")); - uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, - netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), - Ipv4Mask ("255.255.255.0")); - - uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, - netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), - Ipv4Mask ("255.255.255.0")); + uint32_t ifIndexNd2Lan0 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, + Ipv4Address ("10.1.1.3"), Ipv4Mask ("255.255.255.0")); +// +// Assign IP addresses to the net devices and associated interfaces on Lan1 +// + uint32_t ifIndexNd2Lan1 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, + Ipv4Address ("10.1.2.1"), Ipv4Mask ("255.255.255.0")); - NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0); - NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1); - NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2); - NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3); + uint32_t ifIndexNd3 = CsmaIpv4Topology::AddIpv4Address (n3, nd1, + Ipv4Address ("10.1.2.2"), Ipv4Mask ("255.255.255.0")); - // Configure multicasting + uint32_t ifIndexNd4 = CsmaIpv4Topology::AddIpv4Address (n4, nd4, + Ipv4Address ("10.1.2.3"), Ipv4Mask ("255.255.255.0")); + + NS_DEBUG ("ifIndexNd0 = " << ifIndexNd0); + NS_DEBUG ("ifIndexNd1 = " << ifIndexNd1); + NS_DEBUG ("ifIndexNd2Lan0 = " << ifIndexNd2Lan0); + NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); + NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); + NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); NS_DEBUG("Configure multicasting."); +// +// Now we can configure multicasting. As described above, the multicast +// source is at node zero, which we assigned the IP address of 10.1.1.1 +// earlier. We need to define a multicast group to send packets to. This +// can be any multicast address from 224.0.0.0 through 239.255.255.255 +// (avoiding the reserved routing protocol addresses). We just pick a +// convenient number. +// Ipv4Address multicastSource ("10.1.1.1"); Ipv4Address multicastGroup ("225.0.0.0"); - +// +// We are going to manually configure multicast routing. This means telling +// node two that it should expect multicast data coming from IP address +// 10.1.1.1 over its IP interface connected to Lan0. These are called +// multicastSource and ifIndexNd2Lan0 respectively. When node two receives +// these packets, they should be forwarded out the interface that connects it +// to Lan1 which is called ifIndexNd2Lan1. All we need to do is to call the +// AddMulticastRoute method on node two's Ipv4 interface and provide this +// information. (Note: the vector of output interfaces is in case there are +// multiple net devices on a node). +// Ptr ipv4; - ipv4 = n0->QueryInterface (Ipv4::iid); + ipv4 = n2->QueryInterface (Ipv4::iid); std::vector outputInterfaces (1); - outputInterfaces[0] = ifIndexNode0; + outputInterfaces[0] = ifIndexNd2Lan1; - ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, + ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0, outputInterfaces); +// +// We also need to explain to the node zero forwarding code that when it sees +// a packet destined for the multicast group it needs to send it out its +// one and only interface. The 0xffffffff in the call means that the input +// interface qualification is not applicable in this case (the packet has +// not been received over an interface, it has been created locally). +// + ipv4 = n0->QueryInterface (Ipv4::iid); - ipv4 = n1->QueryInterface (Ipv4::iid); - // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + outputInterfaces[0] = ifIndexNd0;; - ipv4 = n2->QueryInterface (Ipv4::iid); - // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); - - ipv4 = n3->QueryInterface (Ipv4::iid); - // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); - - // Create the OnOff application to send UDP datagrams - // from n0 to the multicast group + ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0xffffffff, + outputInterfaces); +// +// As described above, node four will be the only node listening for the +// multicast data. To enable forwarding bits up the protocol stack, we need +// to tell the stack to join the multicast group. +// + ipv4 = n4->QueryInterface (Ipv4::iid); + ipv4->JoinMulticastGroup (multicastSource, multicastGroup); +// +// Create an OnOff application to send UDP datagrams from node zero to the +// multicast group (node four will be listening). +// NS_DEBUG("Create Applications."); Ptr ooff = Create ( n0, @@ -192,27 +268,33 @@ main (int argc, char *argv[]) "Udp", ConstantVariable(1), ConstantVariable(0), - DataRate ("128b/s"), + DataRate ("255b/s"), 128); - // Start the application +// +// Tell the application when to start and stop. +// ooff->Start(Seconds(1.)); ooff->Stop (Seconds(10.)); - - // Configure tracing of all enqueue, dequeue, and NetDevice receive events - // Trace output will be sent to the csma-one-subnet.tr file +// +// Configure tracing of all enqueue, dequeue, and NetDevice receive events. +// Trace output will be sent to the file "csma-multicast.tr" +// NS_DEBUG("Configure Tracing."); AsciiTrace asciitrace ("csma-multicast.tr"); asciitrace.TraceAllNetDeviceRx (); asciitrace.TraceAllQueues (); - - // Also configure some tcpdump traces; each interface will be traced - // The output files will be named - // simple-point-to-point.pcap-- - // and can be read by the "tcpdump -r" command (use "-tt" option to - // display timestamps correctly) +// +// Also configure some tcpdump traces; each interface will be traced. +// The output files will be named: +// csma-multicast.pcap-- +// and can be read by the "tcpdump -r" command (use "-tt" option to +// display timestamps correctly) +// PcapTrace pcaptrace ("csma-multicast.pcap"); pcaptrace.TraceAllIp (); - +// +// Now, do the actual simulation. +// NS_DEBUG("Run Simulation."); Simulator::Run (); Simulator::Destroy (); diff --git a/examples/csma-one-subnet.cc b/examples/csma-one-subnet.cc index 033a0135d..b7926c0db 100644 --- a/examples/csma-one-subnet.cc +++ b/examples/csma-one-subnet.cc @@ -14,35 +14,25 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -// Port of ns-2/tcl/ex/simple.tcl to ns-3 -// // Network topology // // n0 n1 n2 n3 // | | | | -// ===================== +// ================= +// LAN // -// - CBR/UDP flows from n0 to n1, and from n3 to n0 -// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. -// (i.e., DataRate of 448,000 bps) +// - CBR/UDP flows from n0 to n1 and from n3 to n0 // - DropTail queues // - Tracing of queues and packet receptions to file "csma-one-subnet.tr" -#include -#include -#include -#include - #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" #include "ns3/debug.h" - #include "ns3/simulator.h" #include "ns3/nstime.h" #include "ns3/data-rate.h" - #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/internet-node.h" @@ -60,15 +50,18 @@ using namespace ns3; -NS_DEBUG_COMPONENT_DEFINE ("Me"); +NS_DEBUG_COMPONENT_DEFINE ("CsmaOneSubnet"); int main (int argc, char *argv[]) { - // Users may find it convenient to turn on explicit debugging - // for selected modules; the below lines suggest how to do this +// +// Users may find it convenient to turn on explicit debugging +// for selected modules; the below lines suggest how to do this +// #if 0 - DebugComponentEnable("Me"); + DebugComponentEnable("CsmaOneSubnet"); + DebugComponentEnable("Object"); DebugComponentEnable("Queue"); DebugComponentEnable("DropTailQueue"); @@ -88,71 +81,90 @@ main (int argc, char *argv[]) DebugComponentEnable("Ipv4LoopbackInterface"); #endif - DebugComponentEnable("Me"); - DebugComponentEnable("OnOffApplication"); - DebugComponentEnable("UdpSocket"); - DebugComponentEnable("UdpL4Protocol"); - DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("Ipv4StaticRouting"); - DebugComponentEnable("CsmaNetDevice"); - DebugComponentEnable("CsmaChannel"); - DebugComponentEnable("Ipv4Interface"); - DebugComponentEnable("ArpIpv4Interface"); - DebugComponentEnable("Ipv4LoopbackInterface"); - - // Set up some default values for the simulation. Use the Bind() - // technique to tell the system what subclass of Queue to use, - // and what the queue limit is - - // The below Bind command tells the queue factory which class to - // instantiate, when the queue factory is invoked in the topology code +// +// Set up default values for the simulation. Use the DefaultValue::Bind() +// technique to tell the system what subclass of Queue to use. The Bind +// command command tells the queue factory which class to instantiate when the +// queue factory is invoked in the topology code +// DefaultValue::Bind ("Queue", "DropTailQueue"); - - // Allow the user to override any of the defaults and the above - // Bind()s at run-time, via command-line arguments +// +// Allow the user to override any of the defaults and the above Bind() at +// run-time, via command-line arguments +// CommandLine::Parse (argc, argv); - - // Here, we will explicitly create four nodes. In more sophisticated - // topologies, we could configure a node factory. +// +// Explicitly create the nodes required by the topology (shown above). +// NS_DEBUG("Create nodes."); Ptr n0 = Create (); Ptr n1 = Create (); Ptr n2 = Create (); Ptr n3 = Create (); - // We create the channels first without any IP addressing information NS_DEBUG("Create channels."); - Ptr channel0 = - CsmaTopology::CreateCsmaChannel( - DataRate(5000000), MilliSeconds(2)); +// +// Explicitly create the channels required by the topology (shown above). +// + Ptr lan = CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); NS_DEBUG("Build Topology."); - uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, - Eui48Address("10:54:23:54:23:50")); - uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, - Eui48Address("10:54:23:54:23:51")); - uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0, - Eui48Address("10:54:23:54:23:52")); - uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0, - Eui48Address("10:54:23:54:23:53")); +// +// Now fill out the topology by creating the net devices required to connect +// the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will +// create a net device, add a MAC address (in memory of the pink flamingo) and +// connect the net device to a nodes and also to a channel. the +// AddIpv4CsmaNetDevice method returns a net device index for the net device +// created on the node. Interpret nd0 as the net device we created for node +// zero. +// + uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, + Eui48Address("08:00:2e:00:00:00")); - // Later, we add IP addresses. + uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, + Eui48Address("08:00:2e:00:00:01")); + + uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, + Eui48Address("08:00:2e:00:00:02")); + + uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, + Eui48Address("08:00:2e:00:00:03")); + + NS_DEBUG ("nd0 = " << nd0); + NS_DEBUG ("nd1 = " << nd1); + NS_DEBUG ("nd2 = " << nd2); + NS_DEBUG ("nd3 = " << nd3); +// +// We've got the "hardware" in place. Now we need to add IP addresses. +// NS_DEBUG("Assign IP Addresses."); - CsmaIpv4Topology::AddIpv4Address ( - n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); +// +// XXX BUGBUG +// Need a better way to get the interface index. The point-to-point topology +// as implemented can't return the index since it creates interfaces on both +// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a +// method on Ipv4 to find the interface index corresponding to a given ipv4 +// address. +// +// Assign IP addresses to the net devices and associated interfaces +// on the lan. The AddIpv4Address method returns an Ipv4 interface index +// which we do not need here. +// + CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address("10.1.1.1"), + Ipv4Mask("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); + CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address("10.1.1.2"), + Ipv4Mask("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); + CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address("10.1.1.3"), + Ipv4Mask("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); - - // Create the OnOff application to send UDP datagrams of size - // 210 bytes at a rate of 448 Kb/s - // from n0 to n1 + CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address("10.1.1.4"), + Ipv4Mask("255.255.255.0")); +// +// Create an OnOff application to send UDP datagrams from node zero to node 1. +// NS_DEBUG("Create Applications."); Ptr ooff = Create ( n0, @@ -160,36 +172,43 @@ main (int argc, char *argv[]) "Udp", ConstantVariable(1), ConstantVariable(0)); - // Start the application +// +// Tell the application when to start and stop. +// ooff->Start(Seconds(1.0)); ooff->Stop (Seconds(10.0)); - - // Create a similar flow from n3 to n0, starting at time 1.1 seconds +// +// Create a similar flow from n3 to n0, starting at time 1.1 seconds +// ooff = Create ( n3, InetSocketAddress ("10.1.1.1", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); - // Start the application + ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); - - // Configure tracing of all enqueue, dequeue, and NetDevice receive events - // Trace output will be sent to the csma-one-subnet.tr file - NS_DEBUG("Configure Tracing."); +// +// Configure tracing of all enqueue, dequeue, and NetDevice receive events. +// Trace output will be sent to the file "csma-one-subnet.tr" +// + NS_DEBUG("Configure Tracing."); AsciiTrace asciitrace ("csma-one-subnet.tr"); asciitrace.TraceAllNetDeviceRx (); asciitrace.TraceAllQueues (); - - // Also configure some tcpdump traces; each interface will be traced - // The output files will be named - // simple-point-to-point.pcap-- - // and can be read by the "tcpdump -r" command (use "-tt" option to - // display timestamps correctly) +// +// Also configure some tcpdump traces; each interface will be traced. +// The output files will be named: +// csma-one-subnet.pcap-- +// and can be read by the "tcpdump -r" command (use "-tt" option to +// display timestamps correctly) +// PcapTrace pcaptrace ("csma-one-subnet.pcap"); pcaptrace.TraceAllIp (); - +// +// Now, do the actual simulation. +// NS_DEBUG("Run Simulation."); Simulator::Run (); Simulator::Destroy (); diff --git a/examples/mixed-global-routing.cc b/examples/mixed-global-routing.cc index b3017e029..07dcdcaad 100644 --- a/examples/mixed-global-routing.cc +++ b/examples/mixed-global-routing.cc @@ -128,13 +128,13 @@ int main (int argc, char *argv[]) CsmaTopology::CreateCsmaChannel( DataRate(5000000), MilliSeconds(2)); - uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0, + uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, channelc0, Eui48Address("10:54:23:54:23:50")); - uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0, + uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, channelc0, Eui48Address("10:54:23:54:23:51")); - uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0, + uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, channelc0, Eui48Address("10:54:23:54:23:52")); - uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0, + uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, channelc0, Eui48Address("10:54:23:54:23:53")); // Later, we add IP addresses. diff --git a/src/devices/csma/csma-ipv4-topology.cc b/src/devices/csma/csma-ipv4-topology.cc index ff36b5502..80aa1c10a 100644 --- a/src/devices/csma/csma-ipv4-topology.cc +++ b/src/devices/csma/csma-ipv4-topology.cc @@ -35,19 +35,20 @@ namespace ns3 { uint32_t -CsmaIpv4Topology::AddIpv4CsmaNode(Ptr n1, - Ptr ch, - Eui48Address addr) +CsmaIpv4Topology::AddIpv4CsmaNetDevice( + Ptr node, + Ptr channel, + Eui48Address addr) { Ptr q = Queue::CreateDefault (); // assume full-duplex - Ptr nd0 = Create (n1, addr, - ns3::CsmaNetDevice::IP_ARP, - true, true); - nd0->AddQueue(q); - nd0->Attach (ch); - return nd0->GetIfIndex (); + Ptr nd = Create (node, addr, + ns3::CsmaNetDevice::IP_ARP, true, true); + + nd->AddQueue(q); + nd->Attach (channel); + return nd->GetIfIndex (); } diff --git a/src/devices/csma/csma-ipv4-topology.h b/src/devices/csma/csma-ipv4-topology.h index ca4aa982b..8ee60a9df 100644 --- a/src/devices/csma/csma-ipv4-topology.h +++ b/src/devices/csma/csma-ipv4-topology.h @@ -61,9 +61,9 @@ public: * * \return ifIndex of the device */ - static uint32_t AddIpv4CsmaNode( Ptr n1, - Ptr ch, - Eui48Address addr); + static uint32_t AddIpv4CsmaNetDevice(Ptr node, + Ptr channel, + Eui48Address addr); /** * \param n1 Node to be attached to the Csma channel From 87c9e523c729646d8abe2cf6251cbbc82d198785 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 13 Aug 2007 16:21:39 -0700 Subject: [PATCH 06/23] set source address in socket --- examples/csma-multicast.cc | 6 +-- src/internet-node/ipv4-end-point.cc | 7 ++++ src/internet-node/ipv4-end-point.h | 2 + src/internet-node/ipv4-impl.cc | 17 ++++++++ src/internet-node/ipv4-impl.h | 2 + src/internet-node/ipv4-l3-protocol.cc | 22 +++++++++++ src/internet-node/ipv4-l3-protocol.h | 2 + src/internet-node/ipv4-static-routing.cc | 49 ++++++++++++++++++++++++ src/internet-node/ipv4-static-routing.h | 1 + src/internet-node/udp-socket.cc | 5 +++ src/node/ipv4.h | 16 ++++++++ 11 files changed, 125 insertions(+), 4 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index ae4c3c4cf..5017805aa 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -123,12 +123,10 @@ main (int argc, char *argv[]) // Explicitly create the channels required by the topology (shown above). // Ptr lan0 = - CsmaTopology::CreateCsmaChannel( - DataRate(5000000), MilliSeconds(2)); + CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2)); Ptr lan1 = - CsmaTopology::CreateCsmaChannel( - DataRate(5000000), MilliSeconds(2)); + CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2)); NS_DEBUG("Build Topology."); // diff --git a/src/internet-node/ipv4-end-point.cc b/src/internet-node/ipv4-end-point.cc index 69faf523e..a71ee47b2 100644 --- a/src/internet-node/ipv4-end-point.cc +++ b/src/internet-node/ipv4-end-point.cc @@ -42,6 +42,13 @@ Ipv4EndPoint::GetLocalAddress (void) { return m_localAddr; } + +void +Ipv4EndPoint::SetLocalAddress (Ipv4Address address) +{ + m_localAddr = address; +} + uint16_t Ipv4EndPoint::GetLocalPort (void) { diff --git a/src/internet-node/ipv4-end-point.h b/src/internet-node/ipv4-end-point.h index f606aa63b..abc5182a7 100644 --- a/src/internet-node/ipv4-end-point.h +++ b/src/internet-node/ipv4-end-point.h @@ -37,6 +37,8 @@ public: ~Ipv4EndPoint (); Ipv4Address GetLocalAddress (void); + void SetLocalAddress (Ipv4Address address); + uint16_t GetLocalPort (void); Ipv4Address GetPeerAddress (void); uint16_t GetPeerPort (void); diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index c1dbc2c49..96f7af1e4 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -174,11 +174,28 @@ Ipv4Impl::GetNetworkMask (uint32_t i) const { return m_ipv4->GetNetworkMask (i); } + Ipv4Address Ipv4Impl::GetAddress (uint32_t i) const { return m_ipv4->GetAddress (i); } + +Ipv4Address +Ipv4Impl::GetSourceAddress (Ipv4Address destination) const +{ + uint32_t ifIndex; + bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex); + if (result) + { + return m_ipv4->GetAddress (ifIndex); + } + else + { + return Ipv4Address::GetAny (); + } +} + uint16_t Ipv4Impl::GetMtu (uint32_t i) const { diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 5ad9b3e0c..e7036f0d3 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -81,6 +81,8 @@ public: virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); virtual Ipv4Mask GetNetworkMask (uint32_t t) const; virtual Ipv4Address GetAddress (uint32_t i) const; + virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const; + virtual uint16_t GetMtu (uint32_t i) const; virtual bool IsUp (uint32_t i) const; virtual void SetUp (uint32_t i); diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 2326d1021..615985674 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -691,6 +691,28 @@ Ipv4L3Protocol::GetAddress (uint32_t i) const return interface->GetAddress (); } +bool +Ipv4L3Protocol::GetIfIndexForDestination ( + Ipv4Address destination, uint32_t& ifIndex) const +{ + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (" << destination << + ", " << &ifIndex << ")"); + + for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin (); + i != m_routingProtocols.end (); + i++) + { + NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting Source Address"); + uint32_t ifIndex; + + if ((*i).second->RequestIfIndex (destination, ifIndex)) + { + return true; + } + } + return false; +} + uint16_t Ipv4L3Protocol::GetMtu (uint32_t i) const { diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index 7848bf738..c5f066314 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -182,6 +182,8 @@ public: void SetNetworkMask (uint32_t i, Ipv4Mask mask); Ipv4Mask GetNetworkMask (uint32_t t) const; Ipv4Address GetAddress (uint32_t i) const; + bool GetIfIndexForDestination (Ipv4Address destination, + uint32_t& ifIndex) const; uint16_t GetMtu (uint32_t i) const; bool IsUp (uint32_t i) const; void SetUp (uint32_t i); diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index e6e67b516..3ead3fcec 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -377,6 +377,55 @@ Ipv4StaticRouting::RequestRoute ( } } +bool +Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex) +{ + NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (" << destination << ", " << + &ifIndex << ")"); +// +// 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 (destination.IsMulticast ()) + { + NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): Multicast destination"); + + Ipv4MulticastRoute *mRoute = LookupStatic(Ipv4Address::GetAny (), + destination, Ipv4RoutingProtocol::IF_INDEX_ANY); + + if (mRoute) + { + NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): " + "Multicast route found"); + + if (mRoute->GetNOutputInterfaces () != 1) + { + NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): " + "Route is to multiple interfaces. Ignoring."); + return false; + } + + ifIndex = mRoute->GetOutputInterface(0); + return true; + } + return false; // Let other routing protocols try to handle this + } +// +// See if this is a unicast packet we have a route for. +// + NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): Unicast destination"); + Ipv4Route *route = LookupStatic (destination); + if (route) + { + ifIndex = route->GetInterface (); + return true; + } + else + { + return false; + } +} + void Ipv4StaticRouting::DoDispose (void) { diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index 76bb80c40..b63e6ef1f 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -56,6 +56,7 @@ public: Packet packet, RouteReplyCallback routeReply); + virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex); void AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 1442e1d11..bb3046c68 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -26,6 +26,7 @@ #include "udp-l4-protocol.h" #include "ipv4-end-point.h" #include "ipv4-l4-demux.h" +#include "ns3/ipv4.h" NS_DEBUG_COMPONENT_DEFINE ("UdpSocket"); @@ -180,6 +181,10 @@ UdpSocket::Connect(const Address & address) m_defaultPort = transport.GetPort (); NotifyConnectionSucceeded (); m_connected = true; + + Ptr ipv4; + ipv4 = m_node->QueryInterface (Ipv4::iid); + m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress)); return 0; } diff --git a/src/node/ipv4.h b/src/node/ipv4.h index d56a70c70..7d28f012f 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -104,6 +104,16 @@ public: const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply) = 0; + /** + * \brief Synchronously request the interface index that will be used to + * send a packet to a hypothetical destination. + * + * \param destination IP address of a hypothetical destination packet + * \param ifIndex Reference to interface index. + * \returns True if the protocol has a route, false otherwise. + */ + virtual bool RequestIfIndex (Ipv4Address destination, + uint32_t& ifIndex) = 0; static const uint32_t IF_INDEX_ANY = 0xffffffff; }; @@ -308,6 +318,12 @@ public: * \returns the address associated to the underlying ipv4 interface */ virtual Ipv4Address GetAddress (uint32_t i) const = 0; + /** + * \param destination The IP address of a hypothetical destination. + * \returns The IP address assigned to the interface that will be used + * if we were to send a packet to destination. + */ + virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0; /** * \param i index of ipv4 interface * \returns the Maximum Transmission Unit (in bytes) associated From aecc283cb5044e95a548471f7720a066851f74eb Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 13 Aug 2007 19:54:47 -0700 Subject: [PATCH 07/23] set source IP address in udp-socket packets --- examples/csma-multicast.cc | 16 ++-------------- examples/csma-one-subnet.cc | 1 - src/internet-node/ipv4-impl.cc | 4 +++- src/internet-node/ipv4-l3-protocol.cc | 7 +++++-- src/internet-node/ipv4-static-routing.cc | 2 ++ src/internet-node/udp-socket.cc | 6 ++++-- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 5017805aa..9d7b5f8f6 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -71,11 +71,11 @@ main (int argc, char *argv[]) DebugComponentEnable("DropTailQueue"); DebugComponentEnable("Channel"); DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("NetDevice"); DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("NetDevice"); - DebugComponentEnable("PacketSocket"); DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("PacketSocket"); DebugComponentEnable("UdpSocket"); DebugComponentEnable("UdpL4Protocol"); DebugComponentEnable("Ipv4L3Protocol"); @@ -84,18 +84,6 @@ main (int argc, char *argv[]) DebugComponentEnable("ArpIpv4Interface"); DebugComponentEnable("Ipv4LoopbackInterface"); #endif - - DebugComponentEnable("UdpSocket"); - DebugComponentEnable("UdpL4Protocol"); - DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("Ipv4StaticRouting"); - DebugComponentEnable("Ipv4Interface"); - DebugComponentEnable("ArpIpv4Interface"); - DebugComponentEnable("Ipv4LoopbackInterface"); - - DebugComponentEnable("CsmaMulticast"); - DebugComponentEnable("CsmaChannel"); - DebugComponentEnable("CsmaNetDevice"); // // Set up default values for the simulation. Use the DefaultValue::Bind() // technique to tell the system what subclass of Queue to use. The Bind diff --git a/examples/csma-one-subnet.cc b/examples/csma-one-subnet.cc index b7926c0db..19d9200ff 100644 --- a/examples/csma-one-subnet.cc +++ b/examples/csma-one-subnet.cc @@ -80,7 +80,6 @@ main (int argc, char *argv[]) DebugComponentEnable("ArpIpv4Interface"); DebugComponentEnable("Ipv4LoopbackInterface"); #endif - // // Set up default values for the simulation. Use the DefaultValue::Bind() // technique to tell the system what subclass of Queue to use. The Bind diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 96f7af1e4..49a126547 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -184,8 +184,10 @@ Ipv4Impl::GetAddress (uint32_t i) const Ipv4Address Ipv4Impl::GetSourceAddress (Ipv4Address destination) const { - uint32_t ifIndex; + uint32_t ifIndex = 0xffffffff; + bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex); + if (result) { return m_ipv4->GetAddress (ifIndex); diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 615985674..de1ca314b 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -703,10 +703,13 @@ Ipv4L3Protocol::GetIfIndexForDestination ( i++) { NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting Source Address"); - uint32_t ifIndex; + uint32_t ifIndexTmp; - if ((*i).second->RequestIfIndex (destination, ifIndex)) + if ((*i).second->RequestIfIndex (destination, ifIndexTmp)) { + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " + "Found ifIndex " << ifIndexTmp); + ifIndex = ifIndexTmp; return true; } } diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index 3ead3fcec..9013769dd 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -406,6 +406,8 @@ Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex) } ifIndex = mRoute->GetOutputInterface(0); + NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): " + "Found ifIndex " << ifIndex); return true; } return false; // Let other routing protocols try to handle this diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index bb3046c68..576239964 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -174,7 +174,7 @@ UdpSocket::Close(void) int UdpSocket::Connect(const Address & address) { - NS_DEBUG("UdpSocket::Connect (" << address << ")"); + NS_DEBUG ("UdpSocket::Connect (" << address << ")"); InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_defaultAddress = transport.GetIpv4 (); @@ -185,6 +185,8 @@ UdpSocket::Connect(const Address & address) Ptr ipv4; ipv4 = m_node->QueryInterface (Ipv4::iid); m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress)); + NS_DEBUG ("UdpSocket::Connect (): Local address is" << + m_endPoint->GetLocalAddress()); return 0; } @@ -270,4 +272,4 @@ UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port) NotifyDataReceived (p, address); } -}//namespace ns3 +} //namespace ns3 From caab4a3f41efbbf993ad576d3099c286075423d1 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 13 Aug 2007 20:14:36 -0700 Subject: [PATCH 08/23] Silliness for optimized version --- examples/csma-multicast.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 9d7b5f8f6..18f39a3d7 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -193,6 +193,15 @@ main (int argc, char *argv[]) NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); +// +// A little silliness to let optimized code work while still printing all +// results in debug code (without attribute). +// + nd3 = nd3; + ifIndexNd1 = ifIndexNd1; + ifIndexNd3 = ifIndexNd3; + ifIndexNd4 = ifIndexNd4; + NS_DEBUG("Configure multicasting."); // // Now we can configure multicasting. As described above, the multicast From 6b1765219719df2e296e34fa0ae64b56de1bc1f2 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 13 Aug 2007 23:40:51 -0700 Subject: [PATCH 09/23] fix non-unique ethernet addresses --- examples/csma-multicast.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 18f39a3d7..a00393374 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -135,11 +135,11 @@ main (int argc, char *argv[]) Eui48Address("08:00:2e:00:00:02")); uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, - Eui48Address("08:00:2e:00:00:00")); + Eui48Address("08:00:2e:00:00:03")); uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, - Eui48Address("08:00:2e:00:00:01")); + Eui48Address("08:00:2e:00:00:04")); uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, - Eui48Address("08:00:2e:00:00:02")); + Eui48Address("08:00:2e:00:00:05")); NS_DEBUG ("nd0 = " << nd0); NS_DEBUG ("nd1 = " << nd1); From 217edad33c13830f4f3b6d3b436af12a6a048065 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 24 Aug 2007 16:57:54 -0700 Subject: [PATCH 10/23] add ipv4 methods, remove source multicast route requirement, fix udp socket source address prob --- examples/csma-multicast.cc | 122 +++++++++++------------ src/internet-node/ipv4-impl.cc | 14 +++ src/internet-node/ipv4-impl.h | 5 + src/internet-node/ipv4-l3-protocol.cc | 105 ++++++++++++++++++- src/internet-node/ipv4-l3-protocol.h | 7 +- src/internet-node/ipv4-static-routing.cc | 54 ++++++++-- src/internet-node/ipv4-static-routing.h | 1 + src/internet-node/udp-socket.cc | 20 +++- src/node/ipv4.h | 30 ++++++ 9 files changed, 277 insertions(+), 81 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index a00393374..c22e4604c 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -84,6 +84,21 @@ main (int argc, char *argv[]) DebugComponentEnable("ArpIpv4Interface"); DebugComponentEnable("Ipv4LoopbackInterface"); #endif + + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("CsmaMulticast"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("PacketSocket"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + // // Set up default values for the simulation. Use the DefaultValue::Bind() // technique to tell the system what subclass of Queue to use. The Bind @@ -151,56 +166,32 @@ main (int argc, char *argv[]) // We've got the "hardware" in place. Now we need to add IP addresses. // NS_DEBUG("Assign IP Addresses."); -// -// XXX BUGBUG -// Need a better way to get the interface index. The point-to-point topology -// as implemented can't return the index since it creates interfaces on both -// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a -// method on Ipv4 to find the interface index corresponding to a given ipv4 -// address. -// -// First, assign IP addresses to the net devices and associated interfaces -// on Lan0. The AddIpv4Address method returns an Ipv4 interface index. -// Interpret ifIndexNd0 as the interface index to use to reference the -// net device we created on node zero when coming in from the Ipv4 interface. -// Net device numbers and interface indices are distinct. Interpret -// ifIndexNd2Lan0 as the interface index to use to reference the -// net device we created that connects node two to lan zero. -// - uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, - Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0")); - uint32_t ifIndexNd1 = CsmaIpv4Topology::AddIpv4Address (n1, nd1, - Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0")); + CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), + Ipv4Mask ("255.255.255.0")); - uint32_t ifIndexNd2Lan0 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, - Ipv4Address ("10.1.1.3"), Ipv4Mask ("255.255.255.0")); + CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), + Ipv4Mask ("255.255.255.0")); + +// +// We'll need these addresses later +// + Ipv4Address n2Lan0Addr ("10.1.1.3"); + Ipv4Address n2Lan1Addr ("10.1.2.1"); + + CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, n2Lan0Addr, + Ipv4Mask ("255.255.255.0")); // // Assign IP addresses to the net devices and associated interfaces on Lan1 // - uint32_t ifIndexNd2Lan1 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, - Ipv4Address ("10.1.2.1"), Ipv4Mask ("255.255.255.0")); + CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, n2Lan1Addr, + Ipv4Mask ("255.255.255.0")); - uint32_t ifIndexNd3 = CsmaIpv4Topology::AddIpv4Address (n3, nd1, - Ipv4Address ("10.1.2.2"), Ipv4Mask ("255.255.255.0")); + CsmaIpv4Topology::AddIpv4Address (n3, nd1, Ipv4Address ("10.1.2.2"), + Ipv4Mask ("255.255.255.0")); - uint32_t ifIndexNd4 = CsmaIpv4Topology::AddIpv4Address (n4, nd4, - Ipv4Address ("10.1.2.3"), Ipv4Mask ("255.255.255.0")); - - NS_DEBUG ("ifIndexNd0 = " << ifIndexNd0); - NS_DEBUG ("ifIndexNd1 = " << ifIndexNd1); - NS_DEBUG ("ifIndexNd2Lan0 = " << ifIndexNd2Lan0); - NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); - NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); - NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); -// -// A little silliness to let optimized code work while still printing all -// results in debug code (without attribute). -// - nd3 = nd3; - ifIndexNd1 = ifIndexNd1; - ifIndexNd3 = ifIndexNd3; - ifIndexNd4 = ifIndexNd4; + CsmaIpv4Topology::AddIpv4Address (n4, nd4, Ipv4Address ("10.1.2.3"), + Ipv4Mask ("255.255.255.0")); NS_DEBUG("Configure multicasting."); // @@ -216,34 +207,35 @@ main (int argc, char *argv[]) // // We are going to manually configure multicast routing. This means telling // node two that it should expect multicast data coming from IP address -// 10.1.1.1 over its IP interface connected to Lan0. These are called -// multicastSource and ifIndexNd2Lan0 respectively. When node two receives -// these packets, they should be forwarded out the interface that connects it -// to Lan1 which is called ifIndexNd2Lan1. All we need to do is to call the -// AddMulticastRoute method on node two's Ipv4 interface and provide this -// information. (Note: the vector of output interfaces is in case there are -// multiple net devices on a node). +// 10.1.1.1 originally. It should expect these data coming in over its IP +// interface connected to Lan0. When node two receives these packets, they +// should be forwarded out the interface that connects it to Lan1. +// +// We're going to need the interface indices on node two corresponding to +// these interfaces, which we call ifIndexLan0 and ifIndexLan1. The most +// general way to get these interfaces is to look them up by IP address. +// Looking back to the topology creation calls above, we saved the addresses +// assigned to the interface connecting node two to Lan0 and Lan1. Now is +// a fine time to find the interface indices on node two. // Ptr ipv4; ipv4 = n2->QueryInterface (Ipv4::iid); + uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr(n2Lan0Addr); + uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr(n2Lan1Addr); +// +// Now, we need to do is to call the AddMulticastRoute () method on node +// two's Ipv4 interface and tell it that whenever it receives a packet on +// the interface from Lan0, with the packet from the multicast source, +// destined for the multicast group, it should forward these packets down +// the interface connecting it to Lan1. (Note: the vector of output +// interfaces is in case there are multiple net devices on a node -- not +// true in this case). +// std::vector outputInterfaces (1); - outputInterfaces[0] = ifIndexNd2Lan1; + outputInterfaces[0] = ifIndexLan1; - ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0, - outputInterfaces); -// -// We also need to explain to the node zero forwarding code that when it sees -// a packet destined for the multicast group it needs to send it out its -// one and only interface. The 0xffffffff in the call means that the input -// interface qualification is not applicable in this case (the packet has -// not been received over an interface, it has been created locally). -// - ipv4 = n0->QueryInterface (Ipv4::iid); - - outputInterfaces[0] = ifIndexNd0;; - - ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0xffffffff, + ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0, outputInterfaces); // // As described above, node four will be the only node listening for the diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 49a126547..8c7f9ce4b 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -136,11 +136,25 @@ Ipv4Impl::AddInterface (Ptr device) { return m_ipv4->AddInterface (device); } + uint32_t Ipv4Impl::GetNInterfaces (void) { return m_ipv4->GetNInterfaces (); } + +uint32_t +Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr) const +{ + return m_ipv4->FindInterfaceForAddr (addr); +} + +uint32_t +Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const +{ + return m_ipv4->FindInterfaceForAddr (addr, mask); +} + Ptr Ipv4Impl::GetNetDevice (uint32_t i) { diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index e7036f0d3..2f267a392 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -72,6 +72,11 @@ public: virtual uint32_t AddInterface (Ptr device); virtual uint32_t GetNInterfaces (void); + + virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const; + virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, + Ipv4Mask mask) const; + virtual Ptr GetNetDevice(uint32_t i); virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index de1ca314b..262c261a1 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -278,6 +278,33 @@ Ipv4L3Protocol::Lookup ( return; } + if (ipHeader.GetDestination ().IsMulticast () && + ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY) + { + NS_DEBUG ("Ipv4L3Protocol::Lookup (): " + "Multicast destination with local source"); +// +// We have a multicast packet originating from the current node. We didn't +// want to force users to construct a route in order to get packets out of a +// node, so there will have been no route found and it is left to us to send +// the packet. What we'll do is to send the multicast out all of the +// interfaces on this node. +// + NS_DEBUG ("Ipv4StaticRouting::Lookup (): " + "Local source. Flooding multicast packet"); + + for (uint32_t i = 0; i < GetNInterfaces (); ++i) + { + Packet p = packet; + Ipv4Header h = ipHeader; + Ipv4Route route = + Ipv4Route::CreateHostRouteTo(h.GetDestination (), i); + NS_DEBUG ("Ipv4StaticRouting::Lookup (): " + "Send via interface " << i); + routeReply (true, route, p, h); + } + return; + } // No route found routeReply (false, Ipv4Route (), packet, ipHeader); } @@ -399,6 +426,49 @@ Ipv4L3Protocol::GetNInterfaces (void) const return m_nInterfaces; } +uint32_t +Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const +{ + NS_DEBUG("Ipv4L3Protocol::FindInterfaceForAddr (" << addr << ")"); + + uint32_t ifIndex = 0; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); + i != m_interfaces.end (); + i++, ifIndex++) + { + if ((*i)->GetAddress () == addr) + { + return ifIndex; + } + } + + NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): " + "Interface not found for IP address"); + return 0; +} + +uint32_t +Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const +{ + NS_DEBUG("Ipv4L3Protocol::FindInterfaceForAddr (" << addr << ", " << + mask << ")"); + + uint32_t ifIndex = 0; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); + i != m_interfaces.end (); + i++, ifIndex++) + { + if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask)) + { + return ifIndex; + } + } + + NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): " + "Interface not found for masked IP address"); + return 0; +} + Ipv4Interface * Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) { @@ -713,7 +783,40 @@ Ipv4L3Protocol::GetIfIndexForDestination ( return true; } } - return false; +// +// If there's no routing table entry telling us what single interface will be +// used to send a packet to this destination, we'll have to just pick one. +// If there's only one interface on this node, a good answer isn't very hard +// to come up with. Before jumping to any conclusions, remember that the +// zeroth interface is the loopback interface, so what we actually want is +// a situation where there are exactly two interfaces on the node, in which +// case interface one is the "single" interface. +// + if (GetNInterfaces () == 2) + { + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " + "One Interface. Using interface 1."); + ifIndex = 1; + return true; + } +// +// If we fall through to here, we have a node with multiple interfaces and +// no routes to guide us in determining what interface to choose. The last +// choice is to use the one set in the default route. +// + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " + "Using default route"); + Ipv4Route *route = m_staticRouting->GetDefaultRoute (); + + NS_ASSERT_MSG(route, + "Ipv4L3Protocol::GetIfIndexForDestination (): " + "Unable to determine outbound interface. No default route set"); + + ifIndex = route->GetInterface (); + + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " + "Default route specifies interface " << ifIndex); + return true; } uint16_t diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index c5f066314..2114558b3 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -174,9 +174,12 @@ public: uint32_t AddInterface (Ptr device); Ipv4Interface * GetInterface (uint32_t i) const; uint32_t GetNInterfaces (void) const; + + uint32_t FindInterfaceForAddr (Ipv4Address addr) const; + uint32_t FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const; - virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); - virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); + void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); + void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); void SetAddress (uint32_t i, Ipv4Address address); void SetNetworkMask (uint32_t i, Ipv4Mask mask); diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index 9013769dd..cfd2a7046 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -230,6 +230,20 @@ Ipv4StaticRouting::GetNRoutes (void) n += m_networkRoutes.size (); return n; } + +Ipv4Route * +Ipv4StaticRouting::GetDefaultRoute () +{ + if (m_defaultRoute != 0) + { + return m_defaultRoute; + } + else + { + return 0; + } +} + Ipv4Route * Ipv4StaticRouting::GetRoute (uint32_t index) { @@ -331,14 +345,37 @@ Ipv4StaticRouting::RequestRoute ( NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " << ipHeader.GetDestination ()); -// -// 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 (ipHeader.GetDestination ().IsMulticast ()) { NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination"); - +// +// We have a multicast packet we're going to send. There are two distinct +// cases we need to support. The first is if the current node is the source +// of the packet. In that case, we don't want to have to consult multicast +// routing tables (nor build them) in order to send multicasts. The interface +// index (ifIndex) is Ipv4RoutingProtocol::IF_INDEX_ANY if we're the source. +// +// The second case is if the current packet has gotten to us by being +// received over one of our interfaces. In this case, ifIndex is set to the +// index over which we received the packet. For these packets, we need to +// consult the multicast routing table for a disposition. +// +// So, first let's see if we're the source. In this case, we don't consult +// the routing tables, but just return false and let the caller (up in +// ipv4-l3-protocol) flood the multicast packet out of all of its interfaces. +// We can't really do it here even if we wanted to since we have no easy way +// to get to the Ipv4 interface which we would need. +// + if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY) + { + return false; + } +// +// If we fall through to this point, we have a multicast packet that has +// not originated at this node. We need to deal with forwarding. Let's +// see if we have a route, and if so go ahead and forward this puppy. +// Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), ipHeader.GetDestination (), ifIndex); @@ -349,14 +386,15 @@ Ipv4StaticRouting::RequestRoute ( for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) { Packet p = packet; + Ipv4Header h = ipHeader; Ipv4Route route = - Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), + Ipv4Route::CreateHostRouteTo(h.GetDestination (), mRoute->GetOutputInterface(i)); NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " "Send via interface " << mRoute->GetOutputInterface(i)); - routeReply (true, route, p, ipHeader); - return true; + routeReply (true, route, p, h); } + return true; } return false; // Let other routing protocols try to handle this } diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index b63e6ef1f..ac1351e1d 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -74,6 +74,7 @@ public: void SetDefaultRoute (Ipv4Address nextHop, uint32_t interface); uint32_t GetNRoutes (void); + Ipv4Route *GetDefaultRoute (void); Ipv4Route *GetRoute (uint32_t i); void RemoveRoute (uint32_t i); diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 576239964..202590aa5 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -182,10 +182,11 @@ UdpSocket::Connect(const Address & address) NotifyConnectionSucceeded (); m_connected = true; + NS_DEBUG ("UdpSocket::Connect (): Updating local address"); Ptr ipv4; ipv4 = m_node->QueryInterface (Ipv4::iid); m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress)); - NS_DEBUG ("UdpSocket::Connect (): Local address is" << + NS_DEBUG ("UdpSocket::Connect (): Local address is " << m_endPoint->GetLocalAddress()); return 0; } @@ -214,9 +215,9 @@ UdpSocket::DoSendTo (const Packet &p, const Address &address) } int -UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port) +UdpSocket::DoSendTo (const Packet &p, Ipv4Address addr, uint16_t port) { - NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << ipv4 << ", " << + NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << addr << ", " << port << ")"); if (m_endPoint == 0) @@ -234,9 +235,16 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port) return -1; } + NS_DEBUG ("UdpSocket::DoSendTo (): Finding source address"); + Ptr ipv4; + ipv4 = m_node->QueryInterface (Ipv4::iid); + + Ipv4Address source = ipv4->GetSourceAddress(m_defaultAddress); + NS_DEBUG ("UdpSocket::DoSendTo (): Source address is " << source); + NS_DEBUG("UdpSocket::DoSendTo (): Send to UDP"); - m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4, - m_endPoint->GetLocalPort (), port); + m_udp->Send (p, source, addr, m_endPoint->GetLocalPort (), port); + NotifyDataSent (p.GetSize ()); return 0; } @@ -245,11 +253,13 @@ int UdpSocket::SendTo(const Address &address, const Packet &p) { NS_DEBUG("UdpSocket::SendTo (" << address << ", " << &p << ")"); +#if 0 if (m_connected) { m_errno = ERROR_ISCONN; return -1; } +#endif InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 7d28f012f..b79a29d89 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -274,6 +274,36 @@ public: */ virtual uint32_t GetNInterfaces (void) = 0; + /** + * \brief Find and return the interface ID of the interface that has been + * assigned the specified IP address. + * \param addr The IP address assigned to the interface of interest. + * \returns The index of the ipv4 interface with the given address. + * + * Each IP interface has an IP address associated with it. It is often + * useful to search the list of interfaces for one that corresponds to + * a known IP Address. This call takes an IP address as a parameter and + * returns the interface index of the first interface that has been assigned + * that address. If the address is not found, this function asserts. + */ + virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const = 0; + + /** + * \brief Find and return the interface ID of the interface that has been + * assigned the specified (masked) IP address. + * \param addr The IP address assigned to the interface of interest. + * \param mask The address mask to be used in address matching. + * \returns The index of the ipv4 interface with the given address. + * + * Each IP interface has an IP address associated with it. It is often + * useful to search the list of interfaces for one that corresponds to + * a known IP Address. This call takes an IP address and an IP address + * mask as parameters and returns the interface index of the first interface + * that matches the masked IP address. + */ + virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, + Ipv4Mask mask) const = 0; + /** * \param i index of ipv4 interface * \returns the NetDevice associated with the ipv4 interface index From 4e486b1f59b1031692f76fbf338fb8f10022f49d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 24 Aug 2007 17:38:49 -0700 Subject: [PATCH 11/23] semi-real multicast hardware addresses --- src/devices/csma/csma-net-device.cc | 20 ++++++++++++++++--- .../point-to-point-net-device.cc | 11 ++++++---- src/internet-node/arp-ipv4-interface.cc | 15 +++++++++++--- src/internet-node/ipv4-l3-protocol.cc | 5 +++-- src/node/net-device.cc | 11 +++++++++- src/node/net-device.h | 17 ++++++++++++++-- 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 531bf7314..bb1dbbd08 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -132,7 +132,7 @@ CsmaNetDevice::Init(bool sendEnable, bool receiveEnable) m_queue = 0; EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); - EnableMulticast(); + EnableMulticast (Eui48Address ("01:00:5e:00:00:00")); SetSendEnable (sendEnable); SetReceiveEnable (receiveEnable); @@ -500,10 +500,11 @@ CsmaNetDevice::Receive (const Packet& packet) EthernetHeader header (false); EthernetTrailer trailer; Eui48Address broadcast; + Eui48Address multicast; Eui48Address destination; Packet p = packet; - NS_DEBUG ("CsmaNetDevice::Receive UID is (" << p.GetUid() << ")"); + NS_DEBUG ("CsmaNetDevice::Receive (): UID is " << p.GetUid()); // Only receive if send side of net device is enabled if (!IsReceiveEnabled()) @@ -522,12 +523,25 @@ CsmaNetDevice::Receive (const Packet& packet) trailer.CheckFcs(p); p.RemoveHeader(header); + NS_DEBUG ("CsmaNetDevice::Receive (): Pkt destination is " << + header.GetDestination ()); +// +// XXX BUGBUG +// +// An IP host group address is mapped to an Ethernet multicast address +// by placing the low-order 23-bits of the IP address into the low-order +// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). +// +// Need to mask off the appropriate multicast bits. +// + multicast = Eui48Address::ConvertFrom (GetMulticast ()); broadcast = Eui48Address::ConvertFrom (GetBroadcast ()); destination = Eui48Address::ConvertFrom (GetAddress ()); if ((header.GetDestination() != broadcast) && + (header.GetDestination() != multicast) && (header.GetDestination() != destination)) { - // not for us. + NS_DEBUG ("CsmaNetDevice::Receive (): Dropping pkt "); m_dropTrace (p); return; } diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index a071f9246..ada429621 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -68,11 +68,14 @@ PointToPointNetDevice::PointToPointNetDevice (Ptr node, { NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")"); - // BUGBUG FIXME - // - // You _must_ support broadcast to get any sort of packet from the ARP layer. +// BUGBUG FIXME +// +// You _must_ support broadcast to get any sort of packet from the ARP layer. EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); - EnableMulticast(); +// +// Randomly pick the ethernet multicast address base +// + EnableMulticast (Eui48Address ("01:00:5e:00:00:00")); EnablePointToPoint(); } diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index b5f87f0b6..e6012cde9 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -84,9 +84,18 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) else if (dest.IsMulticast ()) { NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast"); - // XXX BUGBUG - // Need real multicast addresses - hardwareDestination = GetDevice ()->GetBroadcast (); + NS_ASSERT_MSG(GetDevice ()->IsMulticast (), + "ArpIpv4Interface::SendTo (): Sending multicast packet over " + "non-multicast device"); +// XXX +// +// An IP host group address is mapped to an Ethernet multicast address +// by placing the low-order 23-bits of the IP address into the low-order +// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). +// +// Currently no easy way to or bit from Ipv4Address into Address +// + hardwareDestination = GetDevice ()->GetMulticast (); found = true; } else diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 262c261a1..28a612ac8 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -288,12 +288,13 @@ Ipv4L3Protocol::Lookup ( // want to force users to construct a route in order to get packets out of a // node, so there will have been no route found and it is left to us to send // the packet. What we'll do is to send the multicast out all of the -// interfaces on this node. +// interfaces on this node. Note that we start with interface 1 since we +// don't particularly want to send the packet out the loopback. // NS_DEBUG ("Ipv4StaticRouting::Lookup (): " "Local source. Flooding multicast packet"); - for (uint32_t i = 0; i < GetNInterfaces (); ++i) + for (uint32_t i = 1; i < GetNInterfaces (); ++i) { Packet p = packet; Ipv4Header h = ipHeader; diff --git a/src/node/net-device.cc b/src/node/net-device.cc index e3b9537aa..72d610924 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -113,6 +113,7 @@ NetDevice::IsBroadcast (void) const { return m_isBroadcast; } + Address const & NetDevice::GetBroadcast (void) const { @@ -139,10 +140,18 @@ NetDevice::IsMulticast (void) const return m_isMulticast; } +Address const & +NetDevice::GetMulticast (void) const +{ + NS_ASSERT (m_isMulticast); + return m_multicast; +} + void -NetDevice::EnableMulticast (void) +NetDevice::EnableMulticast (Address multicast) { m_isMulticast = true; + m_multicast = multicast; } void diff --git a/src/node/net-device.h b/src/node/net-device.h index cc93e6420..98c527e4b 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -138,10 +138,21 @@ public: * not true. */ Address const &GetBroadcast (void) const; + /** * \return value of m_isMulticast flag */ bool IsMulticast (void) const; + + /** + * \return the multicast address supported by + * this netdevice. + * + * Calling this method is invalid if IsMulticast returns + * not true. + */ + Address const &GetMulticast (void) const; + /** * \return value of m_isPointToPoint flag */ @@ -212,9 +223,10 @@ public: */ void DisableBroadcast (void); /** - * Set m_isMulticast flag to true + * Enable multicast support. This method should be + * called by subclasses from their constructor */ - void EnableMulticast (void); + void EnableMulticast (Address multicast); /** * Set m_isMulticast flag to false */ @@ -303,6 +315,7 @@ public: uint16_t m_ifIndex; Address m_address; Address m_broadcast; + Address m_multicast; uint16_t m_mtu; bool m_isUp; bool m_isBroadcast; From 551fe6ebc539818e40bd181add5691e17ab849af Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 27 Aug 2007 23:46:14 -0700 Subject: [PATCH 12/23] real multicast enet addr, more source routes, default multicast route --- examples/csma-multicast.cc | 6 +- src/devices/csma/csma-channel.cc | 2 +- src/devices/csma/csma-net-device.cc | 21 +++-- src/internet-node/arp-ipv4-interface.cc | 79 ++++++++++++++-- src/internet-node/arp-ipv4-interface.h | 2 + src/internet-node/ipv4-impl.cc | 13 +++ src/internet-node/ipv4-impl.h | 4 + src/internet-node/ipv4-l3-protocol.cc | 44 +++++++-- src/internet-node/ipv4-l3-protocol.h | 5 + src/internet-node/ipv4-static-routing.cc | 114 +++++++++++++++++++++-- src/internet-node/ipv4-static-routing.h | 9 +- src/node/ipv4.h | 13 +++ 12 files changed, 275 insertions(+), 37 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index c22e4604c..504c4fc26 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -98,7 +98,6 @@ main (int argc, char *argv[]) DebugComponentEnable("Ipv4Interface"); DebugComponentEnable("ArpIpv4Interface"); DebugComponentEnable("Ipv4LoopbackInterface"); - // // Set up default values for the simulation. Use the DefaultValue::Bind() // technique to tell the system what subclass of Queue to use. The Bind @@ -200,10 +199,11 @@ main (int argc, char *argv[]) // earlier. We need to define a multicast group to send packets to. This // can be any multicast address from 224.0.0.0 through 239.255.255.255 // (avoiding the reserved routing protocol addresses). We just pick a -// convenient number. +// convenient number (225.0.0.0) and or in some bits to let us verify that +// correct Ethernet multicast addresses are constructed down in the system. // Ipv4Address multicastSource ("10.1.1.1"); - Ipv4Address multicastGroup ("225.0.0.0"); + Ipv4Address multicastGroup ("225.1.2.4"); // // We are going to manually configure multicast routing. This means telling // node two that it should expect multicast data coming from IP address diff --git a/src/devices/csma/csma-channel.cc b/src/devices/csma/csma-channel.cc index 9ba42d854..f9bb9fe48 100644 --- a/src/devices/csma/csma-channel.cc +++ b/src/devices/csma/csma-channel.cc @@ -250,7 +250,7 @@ CsmaChannel::TransmitEnd() } NS_DEBUG ("CsmaChannel::TransmitEnd (): Schedule event in " << - m_delay.GetSeconds () << "sec"); + m_delay.GetSeconds () << " sec"); Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent, diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index bb1dbbd08..ca6a693a5 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -526,20 +526,29 @@ CsmaNetDevice::Receive (const Packet& packet) NS_DEBUG ("CsmaNetDevice::Receive (): Pkt destination is " << header.GetDestination ()); // -// XXX BUGBUG -// // An IP host group address is mapped to an Ethernet multicast address // by placing the low-order 23-bits of the IP address into the low-order // 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). // -// Need to mask off the appropriate multicast bits. +// We are going to receive all packets destined to any multicast address, +// which means clearing the low-order 23 bits the header destination // + Eui48Address mcDest; + uint8_t mcBuf[6]; + + header.GetDestination ().CopyTo (mcBuf); + mcBuf[3] &= 0x80; + mcBuf[4] = 0; + mcBuf[5] = 0; + mcDest.CopyFrom (mcBuf); + multicast = Eui48Address::ConvertFrom (GetMulticast ()); broadcast = Eui48Address::ConvertFrom (GetBroadcast ()); destination = Eui48Address::ConvertFrom (GetAddress ()); - if ((header.GetDestination() != broadcast) && - (header.GetDestination() != multicast) && - (header.GetDestination() != destination)) + + if ((header.GetDestination () != broadcast) && + (mcDest != multicast) && + (header.GetDestination () != destination)) { NS_DEBUG ("CsmaNetDevice::Receive (): Dropping pkt "); m_dropTrace (p); diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index e6012cde9..29ccb19f2 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -61,6 +61,74 @@ ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) return resolver; } +// +// RFC 1112 says that an IP host group address is mapped to an Ethernet +// multicast address by placing the low-order 23-bits of the IP address into +// the low-order 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 +// (hex). These are completely different animals and they're encapsulated +// very nicely. Translation: This isn't going to be very pretty. +// +Address +ArpIpv4Interface::MakeMulticastAddress(Ipv4Address multicastGroup) +{ + NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (" << multicastGroup << + ")"); +// +// First, get the generic multicast address from the device. Since it is +// connected to this object, and this object is an IPV4 stack, we hope that +// it is really an Eui48Address. If it's not, then we don't know what to do. +// + Address hardwareDestination = GetDevice ()->GetMulticast (); + + NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " + "Device multicast address: " << hardwareDestination); + + Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination); +// +// We now have the multicast address in an abstract 48-bit container. We +// need to pull it out so we can play with it. When we're done, we have the +// high order bits in etherBuffer[0], etc. +// + uint8_t etherBuffer[6]; + etherAddr.CopyTo (etherBuffer); +// +// If the device is playing the game correctly, the low order 23 bits of the +// multicast base address will be zero. +// + NS_ASSERT_MSG((etherBuffer[4] & 0x7f) == 0, + "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); + NS_ASSERT_MSG(etherBuffer[5] == 0, + "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); + NS_ASSERT_MSG(etherBuffer[6] == 0, + "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); +// +// Now we need to pull the raw bits out of the Ipv4 destination address. +// + uint8_t ipBuffer[4]; + multicastGroup.Serialize (ipBuffer); +// +// We need to place the low order 23 bits of the IP address into the low order +// 23 bits of the ethernet address. +// + etherBuffer[3] |= ipBuffer[1] & 0x7f; + etherBuffer[4] = ipBuffer[2]; + etherBuffer[5] = ipBuffer[3]; +// +// Now, etherBuffer has the desired ethernet multicast address. We have to +// suck these bits back into the Eui48Address; and then suck those bits back +// into the abstract hardwareAddress. +// + etherAddr.CopyFrom (etherBuffer); +// +// Implicit conversion (operator Address ()) is defined for Eui48Address, so +// use it. +// + NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " + "multicast address is " << etherAddr); + + return etherAddr; +} + void ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) { @@ -87,15 +155,8 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) NS_ASSERT_MSG(GetDevice ()->IsMulticast (), "ArpIpv4Interface::SendTo (): Sending multicast packet over " "non-multicast device"); -// XXX -// -// An IP host group address is mapped to an Ethernet multicast address -// by placing the low-order 23-bits of the IP address into the low-order -// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). -// -// Currently no easy way to or bit from Ipv4Address into Address -// - hardwareDestination = GetDevice ()->GetMulticast (); + + hardwareDestination = MakeMulticastAddress(dest); found = true; } else diff --git a/src/internet-node/arp-ipv4-interface.h b/src/internet-node/arp-ipv4-interface.h index 7df522e01..dd73ff2b0 100644 --- a/src/internet-node/arp-ipv4-interface.h +++ b/src/internet-node/arp-ipv4-interface.h @@ -24,6 +24,7 @@ #include "ipv4-interface.h" #include "ns3/ptr.h" +#include "ns3/eui48-address.h" namespace ns3 { @@ -46,6 +47,7 @@ class ArpIpv4Interface : public Ipv4Interface virtual void SendTo (Packet p, Ipv4Address dest); virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); Ptr m_node; + Address MakeMulticastAddress (Ipv4Address multicastGroup); }; }//namespace ns3 diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 8c7f9ce4b..0b557eeaf 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -105,6 +105,16 @@ Ipv4Impl::AddMulticastRoute (Ipv4Address origin, m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces); } +void +Ipv4Impl::SetDefaultMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + m_ipv4->SetDefaultMulticastRoute (origin, group, inputInterface, + outputInterfaces); +} + uint32_t Ipv4Impl::GetNMulticastRoutes (void) const { @@ -208,6 +218,9 @@ Ipv4Impl::GetSourceAddress (Ipv4Address destination) const } else { +// +// If we can't find any address, just leave it 0.0.0.0 +// return Ipv4Address::GetAny (); } } diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 2f267a392..8848c9f7e 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -62,6 +62,10 @@ public: uint32_t inputInterface, std::vector outputInterfaces); + virtual void SetDefaultMulticastRoute (Ipv4Address origin, + Ipv4Address group, uint32_t inputInterface, + std::vector outputInterfaces); + virtual uint32_t GetNMulticastRoutes (void) const; virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const; diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 28a612ac8..b5faf663b 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -355,6 +355,20 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin, outputInterfaces); } +void +Ipv4L3Protocol::SetDefaultMulticastRoute ( + Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << origin << ", " << + group << ", " << inputInterface << ", " << &outputInterfaces << ")"); + + m_staticRouting->SetDefaultMulticastRoute (origin, group, inputInterface, + outputInterfaces); +} + uint32_t Ipv4L3Protocol::GetNMulticastRoutes (void) const { @@ -768,7 +782,11 @@ Ipv4L3Protocol::GetIfIndexForDestination ( { NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (" << destination << ", " << &ifIndex << ")"); - +// +// The first thing we do in trying to determine a source address is to +// consult the routing protocols. These will also check for a default route +// if one has been set. +// for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin (); i != m_routingProtocols.end (); i++) @@ -785,13 +803,13 @@ Ipv4L3Protocol::GetIfIndexForDestination ( } } // -// If there's no routing table entry telling us what single interface will be -// used to send a packet to this destination, we'll have to just pick one. +// If there's no routing table entry telling us what *single* interface will +// be used to send a packet to this destination, we'll have to just pick one. // If there's only one interface on this node, a good answer isn't very hard // to come up with. Before jumping to any conclusions, remember that the // zeroth interface is the loopback interface, so what we actually want is // a situation where there are exactly two interfaces on the node, in which -// case interface one is the "single" interface. +// case interface one is the "single" interface connected to the outside world. // if (GetNInterfaces () == 2) { @@ -802,11 +820,21 @@ Ipv4L3Protocol::GetIfIndexForDestination ( } // // If we fall through to here, we have a node with multiple interfaces and -// no routes to guide us in determining what interface to choose. The last -// choice is to use the one set in the default route. -// +// no routes to guide us in determining what interface to choose. Either +// no default route was found (for unicast or multicast), or in the case of a +// multicast, the default route contained multiple outbound interfaces. +// +// The fallback position is to just get the unicast default route and use +// the outgoing interface specified there. We don't want to leave the source +// address unset, so we just assert here. +// +// N.B. that in the case of a multicast with a route containing multiple +// outgoing interfaces, the source address of packets from that node will be +// set to the IP address of the interface set in the default unicast route. +// Also, in the case of a broadcast, the same will be true. +// NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " - "Using default route"); + "Using default unicast route"); Ipv4Route *route = m_staticRouting->GetDefaultRoute (); NS_ASSERT_MSG(route, diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index 2114558b3..b93a2be5d 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -163,6 +163,11 @@ public: uint32_t inputInterface, std::vector outputInterfaces); + void SetDefaultMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); + uint32_t GetNMulticastRoutes (void) const; Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index cfd2a7046..37790a79a 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -27,6 +27,11 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting"); namespace ns3 { +Ipv4StaticRouting::Ipv4StaticRouting () +: m_defaultRoute (0), m_defaultMulticastRoute (0) +{ +} + void Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, @@ -95,10 +100,24 @@ Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin, m_multicastRoutes.push_back (route); } +void +Ipv4StaticRouting::SetDefaultMulticastRoute( + Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) +{ + Ipv4MulticastRoute *route = new Ipv4MulticastRoute (); + *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, + inputInterface, outputInterfaces); + delete m_defaultMulticastRoute; + m_defaultMulticastRoute = route; +} + uint32_t Ipv4StaticRouting::GetNMulticastRoutes (void) const { - return m_multicastRoutes.size (); + return m_multicastRoutes.size () + m_defaultMulticastRoute ? 1 : 0; } Ipv4MulticastRoute * @@ -106,17 +125,54 @@ Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const { NS_ASSERT_MSG(index < m_multicastRoutes.size (), "Ipv4StaticRouting::GetMulticastRoute (): Index out of range"); - - uint32_t tmp = 0; - for (MulticastRoutesCI i = m_multicastRoutes.begin (); - i != m_multicastRoutes.end (); - i++) +// +// From an external point of view the default route appears to be in slot 0 +// of the routing table. The implementation, however, puts it in a separate +// place. So, if a client asks for index 0 and we have a default multicast +// route, we have to return it from that different place +// (m_defaultMulticastRoute). +// + if (index == 0 && m_defaultMulticastRoute != 0) { - if (tmp == index) + return m_defaultMulticastRoute; + } +// +// If there is a default multicast route present, a client will just assume +// that it is in slot zero and there is one "extra" zeroth route in the table. +// To return the correct indexed entry in our list, we have to decrement the +// index to take into account the default route not being in the actual list. +// Since we fell through to here, we've taken care of the case where the +// index was zero. +// + if (m_defaultMulticastRoute != 0) + { + NS_ASSERT(index > 0); + index--; + } + + if (index < m_multicastRoutes.size ()) + { + uint32_t tmp = 0; + for (MulticastRoutesCI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) { - return *i; + if (tmp == index) + { + return *i; + } + tmp++; } - tmp++; + } + return 0; +} + +Ipv4MulticastRoute * +Ipv4StaticRouting::GetDefaultMulticastRoute () const +{ + if (m_defaultMulticastRoute != 0) + { + return m_defaultMulticastRoute; } return 0; } @@ -126,6 +182,9 @@ Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, Ipv4Address group, uint32_t inputInterface) { +// +// This method does not attempt to delete the multicast route. +// for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++) @@ -145,6 +204,32 @@ Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, void Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index) { +// +// From an external point of view the default route appears to be in slot 0 +// of the routing table. The implementation, however, puts it in a separate +// place. So, if a client asks to delete index 0 and we have a default +// multicast route set, we have to delete it from that different place +// (m_defaultMulticastRoute). +// + if (index == 0 && m_defaultMulticastRoute != 0) + { + delete m_defaultMulticastRoute; + m_defaultMulticastRoute = 0; + } +// +// If there is a default multicast route present, a client will just assume +// that it is in slot zero and there is one "extra" zeroth route in the table. +// To return the correct indexed entry in our list, we have to decrement the +// index to take into account the default route not being in the actual list. +// Since we fell through to here, we've taken care of the case where the +// index was zero. +// + if (m_defaultMulticastRoute != 0) + { + NS_ASSERT(index > 0); + index--; + } + uint32_t tmp = 0; for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); @@ -215,6 +300,12 @@ Ipv4StaticRouting::LookupStatic ( } } } + + if (m_defaultMulticastRoute != 0) + { + return m_defaultMulticastRoute; + } + return 0; } @@ -492,6 +583,11 @@ Ipv4StaticRouting::DoDispose (void) { delete (*i); } + if (m_defaultMulticastRoute != 0) + { + delete m_defaultMulticastRoute; + m_defaultMulticastRoute = 0; + } Ipv4RoutingProtocol::DoDispose (); } diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index ac1351e1d..8b0420f27 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -49,7 +49,7 @@ class Ipv4StaticRouting : public Ipv4RoutingProtocol { public: - Ipv4StaticRouting () : m_defaultRoute (0) {} + Ipv4StaticRouting (); virtual bool RequestRoute (uint32_t ifIndex, Ipv4Header const &ipHeader, @@ -83,8 +83,14 @@ public: uint32_t inputInterface, std::vector outputInterfaces); + void SetDefaultMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); + uint32_t GetNMulticastRoutes (void) const; Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const; void RemoveMulticastRoute (Ipv4Address origin, Ipv4Address group, @@ -114,6 +120,7 @@ private: HostRoutes m_hostRoutes; NetworkRoutes m_networkRoutes; Ipv4Route *m_defaultRoute; + Ipv4MulticastRoute *m_defaultMulticastRoute; MulticastRoutes m_multicastRoutes; }; diff --git a/src/node/ipv4.h b/src/node/ipv4.h index b79a29d89..7d386a493 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -243,6 +243,19 @@ public: Ipv4Address group, uint32_t inputInterface) = 0; + /** + * \brief Set the default static multicast route for a given multicast + * source and group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + * \param inputInterface The interface index over which the packet arrived. + * \param outputInterfaces The list of output interface indices over which + * the packet should be sent (excluding the inputInterface). + */ + virtual void SetDefaultMulticastRoute (Ipv4Address origin, + Ipv4Address group, uint32_t inputInterface, + std::vector outputInterfaces) = 0; /** * \returns the number of entries in the multicast routing table. */ From 2d73bd99275da4420132d475ff390634fd741ea7 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 29 Aug 2007 12:11:11 -0700 Subject: [PATCH 13/23] Move MakeMulticastAddress to NetDevice --- src/devices/csma/csma-net-device.cc | 64 +++++++++++++++-- src/devices/csma/csma-net-device.h | 31 ++++++++ .../point-to-point-net-device.cc | 6 +- src/internet-node/arp-ipv4-interface.cc | 70 +------------------ src/internet-node/arp-ipv4-interface.h | 1 - src/internet-node/ipv4-l3-protocol.cc | 2 + src/node/net-device.cc | 13 +++- src/node/net-device.h | 59 ++++++++++++++-- 8 files changed, 160 insertions(+), 86 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index ca6a693a5..7cdcd455c 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -19,8 +19,6 @@ * Author: Emmanuelle Laprise */ -#include -#include #include "ns3/debug.h" #include "ns3/queue.h" #include "ns3/simulator.h" @@ -60,7 +58,6 @@ CsmaTraceType::GetUid (void) return uid; } - CsmaNetDevice::CsmaNetDevice (Ptr node) : NetDevice (node, Eui48Address::Allocate ()), m_bps (DataRate (0xffffffff)) @@ -71,7 +68,7 @@ CsmaNetDevice::CsmaNetDevice (Ptr node) } CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, - CsmaEncapsulationMode encapMode) + CsmaEncapsulationMode encapMode) : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) { @@ -82,8 +79,8 @@ CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, } CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, - CsmaEncapsulationMode encapMode, - bool sendEnable, bool receiveEnable) + CsmaEncapsulationMode encapMode, + bool sendEnable, bool receiveEnable) : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) { @@ -582,6 +579,61 @@ CsmaNetDevice::Receive (const Packet& packet) return; } +Address +CsmaNetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const +{ + NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (" << multicastGroup << + ")"); +// +// First, get the generic multicast address. +// + Address hardwareDestination = GetMulticast (); + + NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): " + "Device multicast address: " << hardwareDestination); +// +// It's our address, and we know we're playing with an EUI-48 address here +// primarily since we know that by construction, but also since the parameter +// is an Ipv4Address. +// + Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination); +// +// We now have the multicast address in an abstract 48-bit container. We +// need to pull it out so we can play with it. When we're done, we have the +// high order bits in etherBuffer[0], etc. +// + uint8_t etherBuffer[6]; + etherAddr.CopyTo (etherBuffer); +// +// Now we need to pull the raw bits out of the Ipv4 destination address. +// + uint8_t ipBuffer[4]; + multicastGroup.Serialize (ipBuffer); +// +// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48 +// multicast address by placing the low-order 23-bits of the IP address into +// the low-order 23 bits of the Ethernet multicast address +// 01-00-5E-00-00-00 (hex). +// + etherBuffer[3] |= ipBuffer[1] & 0x7f; + etherBuffer[4] = ipBuffer[2]; + etherBuffer[5] = ipBuffer[3]; +// +// Now, etherBuffer has the desired ethernet multicast address. We have to +// suck these bits back into the Eui48Address, +// + etherAddr.CopyFrom (etherBuffer); +// +// Implicit conversion (operator Address ()) is defined for Eui48Address, so +// use it by just returning the EUI-48 address which is automagically converted +// to an Address. +// + NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): " + "multicast address is " << etherAddr); + + return etherAddr; +} + Ptr CsmaNetDevice::GetQueue(void) const { diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 441ea04cd..b0442ac94 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -197,6 +197,37 @@ enum CsmaEncapsulationMode { */ void Receive (const Packet& p); + /** + * @brief Make and return a MAC multicast address using the provided + * multicast group + * + * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet + * multicast address by placing the low-order 23-bits of the IP address into + * the low-order 23 bits of the Ethernet multicast address + * 01-00-5E-00-00-00 (hex). + * + * This method performs the multicast address creation function appropriate + * to an EUI-48-based CSMA device. This MAC address is encapsulated in an + * abstract Address to avoid dependencies on the exact address format. + * + * A default imlementation of MakeMulticastAddress is provided, but this + * method simply NS_ASSERTS. In the case of net devices that do not support + * multicast, clients are expected to test NetDevice::IsMulticast and avoid + * attempting to map multicast packets. Subclasses of NetDevice that do + * support multicasting are expected to override this method and provide an + * implementation appropriate to the particular device. + * + * @param multicastGroup The IP address for the multicast group destination + * of the packet. + * @return The MAC multicast Address used to send packets to the provided + * multicast group. + * + * @see Ipv4Address + * @see Eui48Address + * @see Address + */ + Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + bool IsSendEnabled (void); bool IsReceiveEnabled (void); diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index ada429621..ae4da905b 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -20,8 +20,6 @@ * Revised: George Riley */ -#include -#include #include "ns3/debug.h" #include "ns3/queue.h" #include "ns3/simulator.h" @@ -73,7 +71,7 @@ PointToPointNetDevice::PointToPointNetDevice (Ptr node, // You _must_ support broadcast to get any sort of packet from the ARP layer. EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); // -// Randomly pick the ethernet multicast address base +// We want to allow multicast packets to flow across this link // EnableMulticast (Eui48Address ("01:00:5e:00:00:00")); EnablePointToPoint(); @@ -214,6 +212,8 @@ bool PointToPointNetDevice::Attach (Ptr ch) m_bps = m_channel->GetDataRate (); // GFR Comment. Below is definitely wrong. Interframe gap // is unrelated to channel delay. + // -- unlesss you want to introduce a default gap which is there to avoid + // parts of multiple packets flowing on the "wire" at the same time. //m_tInterframeGap = m_channel->GetDelay (); /* diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index 29ccb19f2..63533ff58 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -61,74 +61,6 @@ ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) return resolver; } -// -// RFC 1112 says that an IP host group address is mapped to an Ethernet -// multicast address by placing the low-order 23-bits of the IP address into -// the low-order 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 -// (hex). These are completely different animals and they're encapsulated -// very nicely. Translation: This isn't going to be very pretty. -// -Address -ArpIpv4Interface::MakeMulticastAddress(Ipv4Address multicastGroup) -{ - NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (" << multicastGroup << - ")"); -// -// First, get the generic multicast address from the device. Since it is -// connected to this object, and this object is an IPV4 stack, we hope that -// it is really an Eui48Address. If it's not, then we don't know what to do. -// - Address hardwareDestination = GetDevice ()->GetMulticast (); - - NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " - "Device multicast address: " << hardwareDestination); - - Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination); -// -// We now have the multicast address in an abstract 48-bit container. We -// need to pull it out so we can play with it. When we're done, we have the -// high order bits in etherBuffer[0], etc. -// - uint8_t etherBuffer[6]; - etherAddr.CopyTo (etherBuffer); -// -// If the device is playing the game correctly, the low order 23 bits of the -// multicast base address will be zero. -// - NS_ASSERT_MSG((etherBuffer[4] & 0x7f) == 0, - "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); - NS_ASSERT_MSG(etherBuffer[5] == 0, - "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); - NS_ASSERT_MSG(etherBuffer[6] == 0, - "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); -// -// Now we need to pull the raw bits out of the Ipv4 destination address. -// - uint8_t ipBuffer[4]; - multicastGroup.Serialize (ipBuffer); -// -// We need to place the low order 23 bits of the IP address into the low order -// 23 bits of the ethernet address. -// - etherBuffer[3] |= ipBuffer[1] & 0x7f; - etherBuffer[4] = ipBuffer[2]; - etherBuffer[5] = ipBuffer[3]; -// -// Now, etherBuffer has the desired ethernet multicast address. We have to -// suck these bits back into the Eui48Address; and then suck those bits back -// into the abstract hardwareAddress. -// - etherAddr.CopyFrom (etherBuffer); -// -// Implicit conversion (operator Address ()) is defined for Eui48Address, so -// use it. -// - NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " - "multicast address is " << etherAddr); - - return etherAddr; -} - void ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) { @@ -156,7 +88,7 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) "ArpIpv4Interface::SendTo (): Sending multicast packet over " "non-multicast device"); - hardwareDestination = MakeMulticastAddress(dest); + hardwareDestination = GetDevice ()->MakeMulticastAddress(dest); found = true; } else diff --git a/src/internet-node/arp-ipv4-interface.h b/src/internet-node/arp-ipv4-interface.h index dd73ff2b0..130a52256 100644 --- a/src/internet-node/arp-ipv4-interface.h +++ b/src/internet-node/arp-ipv4-interface.h @@ -47,7 +47,6 @@ class ArpIpv4Interface : public Ipv4Interface virtual void SendTo (Packet p, Ipv4Address dest); virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); Ptr m_node; - Address MakeMulticastAddress (Ipv4Address multicastGroup); }; }//namespace ns3 diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index b5faf663b..b45046783 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -504,6 +504,8 @@ Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protoc NS_DEBUG("Ipv4L3Protocol::Receive (" << &device << ", " << &p << ", " << protocol << ", " << from << ")"); + NS_DEBUG("Ipv4L3Protocol::Receive (): Packet from " << from); + uint32_t index = 0; for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 72d610924..4e6710758 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -140,10 +140,19 @@ NetDevice::IsMulticast (void) const return m_isMulticast; } -Address const & +Address NetDevice::GetMulticast (void) const { - NS_ASSERT (m_isMulticast); + NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): " + "Invalid operation when not IsMulticast ()"); + return m_multicast; +} + +Address +NetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const +{ + NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): " + "Invalid operation when not IsMulticast ()"); return m_multicast; } diff --git a/src/node/net-device.h b/src/node/net-device.h index 98c527e4b..dd622ae90 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -29,6 +29,7 @@ #include "ns3/object.h" #include "ns3/ptr.h" #include "address.h" +#include "ipv4-address.h" namespace ns3 { @@ -145,13 +146,61 @@ public: bool IsMulticast (void) const; /** - * \return the multicast address supported by - * this netdevice. + * \brief Return the MAC multicast base address used when mapping multicast + * groups to MAC multicast addresses. * - * Calling this method is invalid if IsMulticast returns - * not true. + * Typically when one constructs a multicast MAC addresses, some bits from + * the IP multicast group are copied into a corresponding MAC multicast + * group. In EUI-48, for example, the low order 23 bits of the multicast + * group are copied to the MAC multicast group base address. + * + * This method allows access to the underlying MAC multicast group base + * address. It is expected that in most cases, a net device client will + * allow the net device to perform the actual construction of the multicast + * address. Use of this method is discouraged unless you have a good reason + * to perform a custom mapping. You should prefer + * NetDevice::MakeMulticastAddress which will do the RFC-specified mapping + * for the net device in question. + * + * \return The multicast address supported by this net device. + * + * \warning Calling this method is invalid if IsMulticast returns not true. + * The method NS_ASSERTs if the device is not a multicast device. + * \see NetDevice::MakeMulticastAddress */ - Address const &GetMulticast (void) const; + Address GetMulticast (void) const; + + /** + * \brief Make and return a MAC multicast address using the provided + * multicast group + * + * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet + * multicast address by placing the low-order 23-bits of the IP address into + * the low-order 23 bits of the Ethernet multicast address + * 01-00-5E-00-00-00 (hex). Similar RFCs exist for Ipv6 and Eui64 mappings. + * This method performs the multicast address creation function appropriate + * to the underlying MAC address of the device. This MAC address is + * encapsulated in an abstract Address to avoid dependencies on the exact + * MAC address format. + * + * A default imlementation of MakeMulticastAddress is provided, but this + * method simply NS_ASSERTS. In the case of net devices that do not support + * multicast, clients are expected to test NetDevice::IsMulticast and avoid + * attempting to map multicast packets. Subclasses of NetDevice that do + * support multicasting are expected to override this method and provide an + * implementation appropriate to the particular device. + * + * \param multicastGroup The IP address for the multicast group destination + * of the packet. + * \return The MAC multicast Address used to send packets to the provided + * multicast group. + * + * \warning Calling this method is invalid if IsMulticast returns not true. + * \see Ipv4Address + * \see Address + * \see NetDevice::IsMulticast + */ + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; /** * \return value of m_isPointToPoint flag From 65c0b60e5f586e62323616bb40c8e82f03bc0316 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 4 Sep 2007 14:38:40 -0700 Subject: [PATCH 14/23] piles of doxygen, changes to SetDefaultMulticastRoute plumbing --- src/internet-node/ipv4-impl.cc | 8 +- src/internet-node/ipv4-impl.h | 4 +- src/internet-node/ipv4-l3-protocol.cc | 13 +- src/internet-node/ipv4-l3-protocol.h | 5 +- src/internet-node/ipv4-static-routing.cc | 19 +- src/internet-node/ipv4-static-routing.h | 373 ++++++++++++++++++++++- src/node/ipv4.h | 67 ++-- 7 files changed, 435 insertions(+), 54 deletions(-) diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 0b557eeaf..b105d5a41 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -106,13 +106,9 @@ Ipv4Impl::AddMulticastRoute (Ipv4Address origin, } void -Ipv4Impl::SetDefaultMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector outputInterfaces) +Ipv4Impl::SetDefaultMulticastRoute (uint32_t outputInterface) { - m_ipv4->SetDefaultMulticastRoute (origin, group, inputInterface, - outputInterfaces); + m_ipv4->SetDefaultMulticastRoute (outputInterface); } uint32_t diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 8848c9f7e..ab17c16f4 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -62,9 +62,7 @@ public: uint32_t inputInterface, std::vector outputInterfaces); - virtual void SetDefaultMulticastRoute (Ipv4Address origin, - Ipv4Address group, uint32_t inputInterface, - std::vector outputInterfaces); + virtual void SetDefaultMulticastRoute (uint32_t outputInterface); virtual uint32_t GetNMulticastRoutes (void) const; virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const; diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index b45046783..d93d97459 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -356,17 +356,12 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin, } void -Ipv4L3Protocol::SetDefaultMulticastRoute ( - Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector outputInterfaces) +Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface) { - NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << origin << ", " << - group << ", " << inputInterface << ", " << &outputInterfaces << ")"); + NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << outputInterface << + ")"); - m_staticRouting->SetDefaultMulticastRoute (origin, group, inputInterface, - outputInterfaces); + m_staticRouting->SetDefaultMulticastRoute (outputInterface); } uint32_t diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index b93a2be5d..fdc2456f5 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -163,10 +163,7 @@ public: uint32_t inputInterface, std::vector outputInterfaces); - void SetDefaultMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector outputInterfaces); + void SetDefaultMulticastRoute (uint32_t onputInterface); uint32_t GetNMulticastRoutes (void) const; Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index 37790a79a..d584ce0c3 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -101,15 +101,19 @@ Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin, } void -Ipv4StaticRouting::SetDefaultMulticastRoute( - Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector outputInterfaces) +Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface) { + Ipv4Address origin = Ipv4Address::GetAny (); + Ipv4Address group = Ipv4Address::GetAny (); + uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY; + + std::vector outputInterfaces (1); + outputInterfaces[0] = outputInterface; + Ipv4MulticastRoute *route = new Ipv4MulticastRoute (); *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces); + delete m_defaultMulticastRoute; m_defaultMulticastRoute = route; } @@ -177,7 +181,7 @@ Ipv4StaticRouting::GetDefaultMulticastRoute () const return 0; } -void +bool Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, Ipv4Address group, uint32_t inputInterface) @@ -196,9 +200,10 @@ Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, { delete *i; m_multicastRoutes.erase (i); - return; + return true; } } + return false; } void diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index 8b0420f27..76c028c2a 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -45,57 +45,418 @@ class TraceResolver; class TraceContext; +/** + * @brief Static 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). + * + * The Ipv4StaticRouting class inherits from the abstract base class + * Ipv4RoutingProtocol that defines the interface methods that a routing + * protocol must support. + * + * When a packet arrives in the Ipv4L3Protocol for transmission, it comes + * either from a local source via Ipv4L3Protocol::Send or from a remote + * source via Ipv4L3Protocol::Forwarding. In both cases, a function is called + * (Ipv4L3Protocol::Lookup) to look up the routing information for the packet. + * + * The lookup function iterates through the list of routing protocols asking + * each to see if it can find a route and send the packet. A callback is + * provided during each of these calls that should be considered a pre- + * packaged send call. This is done to allow asynchronous calls into + * routing subsystems in order to support on-demand routing, for example. The + * method for requesting this operation is Ipv4StaticRouting::RequestRoute for + * the static routing protocol. + * + * Each routing protocol is also free to implement its own methods for managing + * routes which you will find below. This class manages a set of "static" or + * manually configured routes for host, network and multicast routes. + * + * @see Ipv4RoutingProtocol + * @see Ipv4L3Protocol::AddRoutingProtocol + * @see Ipv4L3Protocol::Ipv4L3Protocol + */ class Ipv4StaticRouting : public Ipv4RoutingProtocol { - public: +/** + * @brief Construct an empty Ipv4StaticRouting routing protocol, + * @internal + * + * The Ipv4StaticRouting class supports host, network and multicast routes. + * This method initializes the lists containing these routes to empty. + * + * @see Ipv4StaticRouting + */ Ipv4StaticRouting (); +/** + * @brief Request that a check for a route bw performed and if a route is found + * that the packet be sent on its way using the pre-packaged send callback. + * + * The source and destination IP addresses for the packet in question are found + * in the provided Ipv4Header. There are two major processing forks depending + * on the type of destination address. + * + * If the destination address is unicast then the routing table is consulted + * for a route to the destination and if it is found, the routeReply callback + * is executed to send the packet (with the found route). + * + * If the destination address is a multicast, then the exact processing steps + * depend on whether or not the packet has been sourced locally. This is + * determined by the parameter ifIndex. This is the interface index over which + * this packet was received. If the packet has not been received over a + * network interface, this index will be set to + * Ipv4RoutingProtocol::IF_INDEX_ANY (a very large number). In that case, + * we want to avoid the requirement that an explicit route out of each node + * must be set, so we don't do anything here. + * + * If the packet is a multicast destination and has been received over a + * network interface, a call to this method implies that the packet is being + * forwarded. In that case, there must be an explicit route out of the node. + * A multicast route references the source address, the destination address + * (the multicast group) and the input interface in order to find a route. + * We consult the multicast routing table and, if a route is found, send the + * packet out of as many interfaces as required using the provided callback + * (think of it as a pre-packaged send call). + * + * @param ifIndex The network interface index over which the packed was + * received. If the packet is from a local source, ifIndex will be set to + * Ipv4RoutingProtocol::IF_INDEX_ANY. + * @param ipHeader the Ipv4Header containing the source and destination IP + * addresses for the packet. + * @param packet The packet to be sent if a route is found. + * @param routeReply A callback that packaged up the call to actually send the + * packet. + * @return Returns true if a route is found and the packet has been sent, + * otherwise returns false indicating that the next routing protocol should + * be consulted. In practice, the static routing protocol is the last chance + * protocol. + * + * @see Ipv4StaticRouting + * @see Ipv4RoutingProtocol + */ virtual bool RequestRoute (uint32_t ifIndex, Ipv4Header const &ipHeader, Packet packet, RouteReplyCallback routeReply); +/** + * @brief Check to see if we can determine the interface index that will be + * used if a packet is sent to this destination. + * + * This method addresses a problem in the IP stack where a destination address + * must be present and checksummed into the IP header before the actual + * interface over which the packet is sent can be determined. The answer is + * to implement a known and intentional cross-layer violation. This is the + * endpoint of a call chain that started up quite high in the stack (sockets) + * and has found its way down to the Ipv4L3Protocol which is consulting the + * routing protocols for what they would do if presented with a packet of the + * given destination. + * + * Note that the a single interface index is returned. This means that if + * the destination address is a multicast, and an explicit route is present + * that includeds multiple output interfaces, that route cannot be used. + * + * If there are multiple paths out of the node, the resolution is performed + * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more + * contextual information that is useful for making a determination. + * + * @param destination The Ipv4Address if the destination of a hypothetical + * packet. This may be a multicast group address. + * @param ifIndex A reference to the interface index over which a packet + * sent to this destination would be sent. + * @return Returns true if a route is found to the destination that involves + * a single output interface index, otherwise returns false indicating that + * the next routing protocol should be consulted. In practice, the static + * routing protocol is the last chance protocol. + * + * @see Ipv4StaticRouting + * @see Ipv4RoutingProtocol + * @see Ipv4L3Protocol + */ virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex); +/** + * @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. + * + * @see Ipv4Address + */ void AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, uint32_t interface); +/** + * @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. + * + * @see Ipv4Address + */ void AddHostRouteTo (Ipv4Address dest, uint32_t interface); +/** + * @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. + * + * @see Ipv4Address + */ void AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface); + +/** + * @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. + * + * @see Ipv4Address + */ void AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, uint32_t interface); + +/** + * @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. + * + * @see Ipv4Address + * @see Ipv4StaticRouting::Lookup + */ void SetDefaultRoute (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 the default route from the static routing table. + * + * @return If the default route is set, a pointer to that Ipv4Route is + * returned, otherwise a zero pointer is returned. + * + * @see Ipv4Route + */ Ipv4Route *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. The one sublety 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 explicity 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 Ipv4Route is returned, otherwise + * a zero pointer is returned. + * + * @see Ipv4Route + * @see Ipv4StaticRouting::RemoveRoute + */ Ipv4Route *GetRoute (uint32_t i); + +/** + * @brief Remove a route from the static unicast routing table. + * + * Externally, the unicast static routing table appears simply as a table with + * n entries. The one sublety 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 Ipv4Route + * @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 -- the address of the + * node that originates packets destined for a given multicast group. This + * address may be Ipv4Address::GetAny (typically 0.0.0.0) if the multicast + * group is open, or it may specify a single IP address if the multicast + * group is closed. The route must also specify the multicast group address. + * + * For each route, the input nework interface must be specified. For + * forwarding operations, this is the interface index that you expect multicast + * packets to arrive over. If you want to specify routes off of a local node + * for given multicast groups, this index may be set to + * Ipv4RoutingProtocol::IF_INDEX_ANY. + * + * For each route, a vector of output network interfaces must also be + * specified. When the RequestRoute operation is performed, copies of a + * packet are sent out all of the specified interfaces. + * + * @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::IF_INDEX_ANY for packets of local origin. + * @param outputInterface 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 outputInterfaces); - void SetDefaultMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector 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. + * + * Since we're basically forwarding packets to some entity we think may know + * better what to do, we don't pay attention to subleties like origin address + * and input interface, 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, multicast group or + * input interface 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. The one sublety 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 explicity calling GetDefaultMulticastRoute () or by + * calling GetMulticastRoute (0). + * + * Similarly, if the default route has been set, calling + * RemoveMulticastRoute (0) will remove the default route. + * + * @param i The index (into the routing table) of the multicast route to + * retrieve. If the default route has been set, it will occupy index zero. + * @return If route is set, a pointer to that Ipv4MulticastRoute is + * returned, otherwise a zero pointer is returned. + * + * @see Ipv4MulticastRoute + * @see Ipv4StaticRouting::RemoveRoute + */ Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + +/** + * @brief Get the default multicast route from the static routing table. + * + * @return If the default route is set, a pointer to that Ipv4MulticastRoute is + * returned, otherwise a zero pointer is returned. + * + * @see Ipv4Route + */ Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const; - void RemoveMulticastRoute (Ipv4Address origin, +/** + * @brief Remove a route from the static multicast routing table. + * + * Externally, the multicast static routing table appears simply as a table + * with n entries. The one sublety of note is that if a default multicast + * route has been set it will appear as the zeroth entry in the table. This + * means that the default route may be removed by calling this method with + * appropriate wildcard parameters. + * + * This method causes the multicast routing table to be searched for the first + * route that matches the parameters and removes it. + * + * @param origin The IP address specified as the origin of packets for the + * route. + * @param origin The IP address specified as the multicast group addres of + * the route. + * @param inputInterfade 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 Ipv4Route + * @see Ipv4StaticRouting::GetRoute + * @see Ipv4StaticRouting::AddRoute + */ + 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. The one sublety of note is that if a default multicast + * 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 + * RemoveMulticastRoute (0) will remove the default route. + * + * @param index The index (into the multicast routing table) of the route to + * remove. If the default route has been set, it will occupy index zero. + * + * @see Ipv4Route + * @see Ipv4StaticRouting::GetRoute + * @see Ipv4StaticRouting::AddRoute + */ void RemoveMulticastRoute (uint32_t index); protected: diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 7d386a493..ff46fc268 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -104,14 +104,38 @@ public: const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply) = 0; - /** - * \brief Synchronously request the interface index that will be used to - * send a packet to a hypothetical destination. - * - * \param destination IP address of a hypothetical destination packet - * \param ifIndex Reference to interface index. - * \returns True if the protocol has a route, false otherwise. - */ +/** + * \brief Synchronously check to see if we can determine the interface index + * that will be used if a packet is sent to this destination. + * + * This method addresses a problem in the IP stack where a destination address + * must be present and checksummed into the IP header before the actual + * interface over which the packet is sent can be determined. The answer is + * to implement a known and intentional cross-layer violation. This is the + * endpoint of a call chain that started up quite high in the stack (sockets) + * and has found its way down to the Ipv4L3Protocol which is consulting the + * routing protocols for what they would do if presented with a packet of the + * given destination. + * + * Note that the a single interface index is returned. This means that if + * the destination address is a multicast, and an explicit route is present + * that includeds multiple output interfaces, that route cannot be used. + * + * If there are multiple paths out of the node, the resolution is performed + * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more + * contextual information that is useful for making a determination. + * + * \param destination The Ipv4Address if the destination of a hypothetical + * packet. This may be a multicast group address. + * \param ifIndex A reference to the interface index over which a packet + * sent to this destination would be sent. + * \return Returns true if a route is found to the destination that involves + * a single output interface index, otherwise false. + * + * \see Ipv4StaticRouting + * \see Ipv4RoutingProtocol + * \see Ipv4L3Protocol + */ virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex) = 0; @@ -207,11 +231,13 @@ public: * \returns the number of entries in the routing table. */ virtual uint32_t GetNRoutes (void) = 0; + /** * \param i index of route to return * \returns the route whose index is i */ virtual Ipv4Route GetRoute (uint32_t i) = 0; + /** * \param i index of route to remove from routing table. */ @@ -244,18 +270,13 @@ public: uint32_t inputInterface) = 0; /** - * \brief Set the default static multicast route for a given multicast - * source and group. + * \brief Set the default static multicast route. * - * \param origin The Ipv4 address of the multicast source. - * \param group The multicast group address. - * \param inputInterface The interface index over which the packet arrived. - * \param outputInterfaces The list of output interface indices over which - * the packet should be sent (excluding the inputInterface). + * \param outputInterface The network output interface index over which + * packets without specific routes should be sent. */ - virtual void SetDefaultMulticastRoute (Ipv4Address origin, - Ipv4Address group, uint32_t inputInterface, - std::vector outputInterfaces) = 0; + virtual void SetDefaultMulticastRoute (uint32_t outputInterface) = 0; + /** * \returns the number of entries in the multicast routing table. */ @@ -282,6 +303,7 @@ public: * make sure that it is never used during packet forwarding. */ virtual uint32_t AddInterface (Ptr device) = 0; + /** * \returns the number of interfaces added by the user. */ @@ -346,39 +368,46 @@ public: * \param address address to associate to the underlying ipv4 interface */ virtual void SetAddress (uint32_t i, Ipv4Address address) = 0; + /** * \param i index of ipv4 interface * \param mask mask to associate to the underlying ipv4 interface */ virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0; + /** * \param i index of ipv4 interface * \returns the mask associated to the underlying ipv4 interface */ virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0; + /** * \param i index of ipv4 interface * \returns the address associated to the underlying ipv4 interface */ virtual Ipv4Address GetAddress (uint32_t i) const = 0; + /** * \param destination The IP address of a hypothetical destination. * \returns The IP address assigned to the interface that will be used * if we were to send a packet to destination. */ virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0; + /** * \param i index of ipv4 interface * \returns the Maximum Transmission Unit (in bytes) associated * to the underlying ipv4 interface */ virtual uint16_t GetMtu (uint32_t i) const = 0; + /** * \param i index of ipv4 interface * \returns true if the underlying interface is in the "up" state, * false otherwise. */ virtual bool IsUp (uint32_t i) const = 0; + /** * \param i index of ipv4 interface * @@ -386,6 +415,7 @@ public: * considered valid during ipv4 forwarding. */ virtual void SetUp (uint32_t i) = 0; + /** * \param i index of ipv4 interface * @@ -393,7 +423,6 @@ public: * ignored during ipv4 forwarding. */ virtual void SetDown (uint32_t i) = 0; - }; } // namespace ns3 From f6529699369a02bb9854f7df35bae708eeab9d74 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 4 Sep 2007 15:10:47 -0700 Subject: [PATCH 15/23] Don't flood multicasts if no route found --- src/internet-node/ipv4-l3-protocol.cc | 34 +++++++++++++-------------- src/node/ipv4-route.cc | 17 ++++++++++++++ src/node/ipv4-route.h | 14 +++++++++++ 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index d93d97459..80fefecfe 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -284,29 +284,29 @@ Ipv4L3Protocol::Lookup ( NS_DEBUG ("Ipv4L3Protocol::Lookup (): " "Multicast destination with local source"); // -// We have a multicast packet originating from the current node. We didn't -// want to force users to construct a route in order to get packets out of a -// node, so there will have been no route found and it is left to us to send -// the packet. What we'll do is to send the multicast out all of the -// interfaces on this node. Note that we start with interface 1 since we -// don't particularly want to send the packet out the loopback. +// We have a multicast packet originating from the current node and were not +// able to send it using the usual RequestRoute process. Since the usual +// process includes trying to use a default multicast route, this means that +// there was no specific route out of the node found, and there was no default +// multicast route set. // - NS_DEBUG ("Ipv4StaticRouting::Lookup (): " - "Local source. Flooding multicast packet"); +// The fallback position is to look for a default unicast route and use that +// to get the packet off the node if we have one. +// + Ipv4Route *route = m_staticRouting->GetDefaultRoute (); - for (uint32_t i = 1; i < GetNInterfaces (); ++i) + if (route) { - Packet p = packet; - Ipv4Header h = ipHeader; - Ipv4Route route = - Ipv4Route::CreateHostRouteTo(h.GetDestination (), i); NS_DEBUG ("Ipv4StaticRouting::Lookup (): " - "Send via interface " << i); - routeReply (true, route, p, h); + "Local source. Using unicast default route for multicast packet"); + + routeReply (true, *route, packet, ipHeader); + return; } - return; } - // No route found +// +// No route found +// routeReply (false, Ipv4Route (), packet, ipHeader); } diff --git a/src/node/ipv4-route.cc b/src/node/ipv4-route.cc index 9d6a2286b..1c56c972e 100644 --- a/src/node/ipv4-route.cc +++ b/src/node/ipv4-route.cc @@ -30,6 +30,7 @@ namespace ns3 { Ipv4Route::Ipv4Route () {} + Ipv4Route::Ipv4Route (Ipv4Route const &route) : m_dest (route.m_dest), m_destNetworkMask (route.m_destNetworkMask), @@ -37,6 +38,13 @@ Ipv4Route::Ipv4Route (Ipv4Route const &route) m_interface (route.m_interface) {} +Ipv4Route::Ipv4Route (Ipv4Route const *route) + : m_dest (route->m_dest), + m_destNetworkMask (route->m_destNetworkMask), + m_gateway (route->m_gateway), + m_interface (route->m_interface) +{} + Ipv4Route::Ipv4Route (Ipv4Address dest, Ipv4Address gateway, uint32_t interface) @@ -236,6 +244,15 @@ Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const &route) { } +Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const *route) +: + m_origin (route->m_origin), + m_group (route->m_group), + m_inputInterface (route->m_inputInterface), + m_outputInterfaces (route->m_outputInterfaces) +{ +} + Ipv4MulticastRoute::Ipv4MulticastRoute ( Ipv4Address origin, Ipv4Address group, diff --git a/src/node/ipv4-route.h b/src/node/ipv4-route.h index f80a1ae00..933e3534e 100644 --- a/src/node/ipv4-route.h +++ b/src/node/ipv4-route.h @@ -37,12 +37,19 @@ public: * \brief This constructor does nothing */ Ipv4Route (); + /** * \brief Copy Constructor * \param route The route to copy */ Ipv4Route (Ipv4Route const &route); + /** + * \brief Copy Constructor + * \param route The route to copy + */ + Ipv4Route (Ipv4Route const *route); + bool IsHost (void) const; /** * \return The IPv4 address of the destination of this route @@ -108,12 +115,19 @@ public: * \brief This constructor does nothing */ Ipv4MulticastRoute (); + /** * \brief Copy Constructor * \param route The route to copy */ Ipv4MulticastRoute (Ipv4MulticastRoute const &route); + /** + * \brief Copy Constructor + * \param route The route to copy + */ + Ipv4MulticastRoute (Ipv4MulticastRoute const *route); + /** * \return The IPv4 address of the source of this route */ From 07fb4b1e5b2507cbb05e37903a78a1aa301ec7e8 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 4 Sep 2007 18:06:06 -0700 Subject: [PATCH 16/23] clarify use of wildcards in multicast routes versus default mulicast routes. --- examples/csma-multicast.cc | 39 +++++++- src/internet-node/ipv4-static-routing.cc | 110 ++++++++++++++++------- src/internet-node/ipv4-static-routing.h | 50 +++++++---- 3 files changed, 150 insertions(+), 49 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 504c4fc26..9b964abec 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -221,8 +221,8 @@ main (int argc, char *argv[]) Ptr ipv4; ipv4 = n2->QueryInterface (Ipv4::iid); - uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr(n2Lan0Addr); - uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr(n2Lan1Addr); + uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr (n2Lan0Addr); + uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr (n2Lan1Addr); // // Now, we need to do is to call the AddMulticastRoute () method on node // two's Ipv4 interface and tell it that whenever it receives a packet on @@ -238,6 +238,41 @@ main (int argc, char *argv[]) ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0, outputInterfaces); // +// We need to specify how the source node handles multicasting. There are a +// number of ways we can deal with this, we just need to pick one. The first +// method is to add an explicit route out of the source node, just as we did +// for the forwarding node. Use this method when you want to send packets out +// multiple interfaces or send packets out different interfaces based on the +// differing multicast groups. Since the source is local, there will be no +// input interface over which packets are received, so use +// Ipv4RoutingProtocol::IF_INDEX_ANY as a wildcard. +// +// A second way is to specify a multicast route using wildcards. If you +// want to send multicasts out differing sets of interfaces based on the +// multicast group, you can use AddMulticastRoute () but specify the origin +// as a wildcard. If you want all multicasts to go out a single set of +// interfaces, you can make both the origin and group a wildcard. +// +// If you have a simple system, where the source has a single interface, this +// can be done via the SetDefaultMulticastRoute () method on the Ipv4 +// interface. This tells the system to send all multicasts out a single +// specified network interface index. +// +// A last way is to specify a (or use an existing) default unicast route. The +// multicast routing code uses the unicast default route as a multicast "route +// of last resort." this method for is also on Ipv4 and is called +// SetDefaultRoute (). +// +// Since this is a simple multicast example, we use the +// SetDefaultMulticastRoute () approach. We are going to first need the +// Ipv4 interface for node 0 which is the multicast source. We use this +// interface to find the output interface index, and tell node zero to send +// its multicast traffic out that interface. +// + ipv4 = n0->QueryInterface (Ipv4::iid); + uint32_t ifIndexSrc = ipv4->FindInterfaceForAddr (multicastSource); + ipv4->SetDefaultMulticastRoute (ifIndexSrc); +// // As described above, node four will be the only node listening for the // multicast data. To enable forwarding bits up the protocol stack, we need // to tell the stack to join the multicast group. diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc index d584ce0c3..c181dde29 100644 --- a/src/internet-node/ipv4-static-routing.cc +++ b/src/internet-node/ipv4-static-routing.cc @@ -289,14 +289,27 @@ Ipv4StaticRouting::LookupStatic ( Ipv4Address group, uint32_t ifIndex) { +// +// We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching +// scheme. +// + Ipv4Address wildcard = Ipv4Address::GetAny (); + for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++) { Ipv4MulticastRoute *route = *i; - if ( (origin == route->GetOrigin () || - origin == Ipv4Address::GetAny ()) && - group == route->GetGroup ()) +// +// 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 ()) { if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || ifIndex == route->GetInputInterface ()) @@ -305,7 +318,67 @@ Ipv4StaticRouting::LookupStatic ( } } } +// +// If the input interface index is not a wildcard (that means that the packet +// did not originally come from this node), we're done. We don't +// just happily forward packets we don't really know what to do with. +// Multicast storms are not generally considered a good thing. +// + if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY) + { + return 0; + } +// +// Now, we're going to get a litle less restricive. This only applies in the +// case where the packet in question is coming from the local node. In order +// to avoid dependencies on the order in which routes were added, we will +// actually walk the list two more times, the first time looking for routes +// with a single wildcard, and the last time looking for the first route +// with two wildcards. +// + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) + { + Ipv4MulticastRoute *route = *i; +// +// Here we will ignore the origin. We know that a single source address must +// be picked for a packet, but we may want to send multicast packets out +// multiple interfaces. To support this case, a user would need to add +// a Multicast route with the route's origin set to wildcard. N.B As a +// result, packets sourced from a node with multiple interface may have a +// source IP address different from that of the interface actually used to +// send the packet. +// + if (route->GetOrigin () == wildcard && group == route->GetGroup ()) + { + return *i; + } + } +// +// Finally we want to allow users to specify a default route that specifies +// sending all multicast packets out multiple interfaces. The standard +// default multicast route is patterned after other systems and limits the +// number of outputs to one. If, however a client manually adds a multicast +// route with the origin, the multicast group and the input interface index +// all set to wildcard, she has created a default route with multiple output +// interfaces. +// + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) + { + Ipv4MulticastRoute *route = *i; + if (route->GetOrigin () == wildcard && route->GetGroup () == wildcard) + { + return *i; + } + } +// +// We also allow users to specify a typical default multicast route. This +// default route is limited to specifying a single output interface. +// if (m_defaultMulticastRoute != 0) { return m_defaultMulticastRoute; @@ -445,33 +518,7 @@ Ipv4StaticRouting::RequestRoute ( if (ipHeader.GetDestination ().IsMulticast ()) { NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination"); -// -// We have a multicast packet we're going to send. There are two distinct -// cases we need to support. The first is if the current node is the source -// of the packet. In that case, we don't want to have to consult multicast -// routing tables (nor build them) in order to send multicasts. The interface -// index (ifIndex) is Ipv4RoutingProtocol::IF_INDEX_ANY if we're the source. -// -// The second case is if the current packet has gotten to us by being -// received over one of our interfaces. In this case, ifIndex is set to the -// index over which we received the packet. For these packets, we need to -// consult the multicast routing table for a disposition. -// -// So, first let's see if we're the source. In this case, we don't consult -// the routing tables, but just return false and let the caller (up in -// ipv4-l3-protocol) flood the multicast packet out of all of its interfaces. -// We can't really do it here even if we wanted to since we have no easy way -// to get to the Ipv4 interface which we would need. -// - if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY) - { - return false; - } -// -// If we fall through to this point, we have a multicast packet that has -// not originated at this node. We need to deal with forwarding. Let's -// see if we have a route, and if so go ahead and forward this puppy. -// + Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), ipHeader.GetDestination (), ifIndex); @@ -479,6 +526,7 @@ Ipv4StaticRouting::RequestRoute ( { NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " "Multicast route found"); + for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) { Packet p = packet; @@ -495,7 +543,7 @@ Ipv4StaticRouting::RequestRoute ( return false; // Let other routing protocols try to handle this } // -// See if this is a unicast packet we have a route for. +// This is a unicast packet. Check to see if we have a route for it. // NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination"); Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index 76c028c2a..c7bf1a652 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -317,21 +317,34 @@ public: /** * @brief Add a multicast route to the static routing table. * - * A multicast route must specify an origin IP address -- the address of the - * node that originates packets destined for a given multicast group. This - * address may be Ipv4Address::GetAny (typically 0.0.0.0) if the multicast - * group is open, or it may specify a single IP address if the multicast - * group is closed. The route must also specify the multicast group address. + * 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. * - * For each route, the input nework interface must be specified. For - * forwarding operations, this is the interface index that you expect multicast - * packets to arrive over. If you want to specify routes off of a local node - * for given multicast groups, this index may be set to - * Ipv4RoutingProtocol::IF_INDEX_ANY. + * Typically there are two main types of multicast routes: routes of the + * first kind are used during forwarding. All of the conditions must be + * exlicitly 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::IF_INDEX_ANY. * - * For each route, a vector of output network interfaces must also be - * specified. When the RequestRoute operation is performed, copies of a - * packet are sent out all of the specified interfaces. + * 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. @@ -425,6 +438,12 @@ public: * 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 + * exacly 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 origin The IP address specified as the multicast group addres of @@ -433,9 +452,8 @@ public: * input interface for the route. * @returns True if a route was found and removed, false otherwise. * - * @see Ipv4Route - * @see Ipv4StaticRouting::GetRoute - * @see Ipv4StaticRouting::AddRoute + * @see Ipv4MulticastRoute + * @see Ipv4StaticRouting::AddMulticastRoute */ bool RemoveMulticastRoute (Ipv4Address origin, Ipv4Address group, From a39d25f6c1a5c3f4082573dde1b8bf1d92974664 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 6 Sep 2007 15:57:53 -0700 Subject: [PATCH 17/23] readme file includes APIs --- README.multicast-routing | 213 ++++++++++++++++++++++++ src/internet-node/ipv4-static-routing.h | 17 +- 2 files changed, 223 insertions(+), 7 deletions(-) create mode 100644 README.multicast-routing diff --git a/README.multicast-routing b/README.multicast-routing new file mode 100644 index 000000000..a5afda564 --- /dev/null +++ b/README.multicast-routing @@ -0,0 +1,213 @@ +Static multicast routing overview +-------------------------------- + +This is brief documentation of a proposal to add static multicast +routing to ns-3. + +This extension allows the simulation user to: + +- manually add an Ipv4 multicast route to a router +- specify a default outgoing interface for multicast sources (hosts) in + various ways +- allow a multicast receiver (hosts) to join a multicast group, to enable + reception of that group's datagrams + +1. Code location: + +- http://code.nsnam.org/craigdo/ns-3-mc + +- the main source code is found in src/internet-node/ipv4-static-routing.{cc,h} + +also touched are: +- src/internet-node/ipv4-l3-protocol.cc (forwarding methods for the + static routing API) +- src/node/net-device.cc (provides virtual NetDevice::MakeMulticastAddress) +- src/arp-ipv4-interface.cc (calls NetDevice::MakeMulticastAddress) +- src/devices/csma/csma-net-device.cc (handles multicast addressing and + reception). +- src/devices/point-to-point/point-to-point-net-device.cc (implements required + virtual methods. +- src/internet-node/ (several files have added tracing) + +- an example script is in examples/csma-multicast.cc + +2. API: + +The API for adding a multicast route is: + +/** + * @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 + * exlicitly 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::IF_INDEX_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::IF_INDEX_ANY for packets of local origin. + * @param outputInterface A vector of network interface indices used to specify + * how to send packets to the destination(s). + * + * @see Ipv4Address + */ + Ipv4::AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces) + +To remove a route, one uses: + +/** + * @brief Remove a route from the static multicast routing table. + * + * Externally, the multicast static routing table appears simply as a table + * with n entries. The one sublety of note is that if a default multicast + * route has been set it will appear as the zeroth entry in the table. This + * means that the default route may be removed by calling this method with + * appropriate wildcard parameters. + * + * 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 + * exacly 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 origin The IP address specified as the multicast group addres of + * the route. + * @param inputInterfade 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 Ipv4MulticastRoute + * @see Ipv4StaticRouting::AddMulticastRoute + */ + Ipv4::RemoveMulticastRoute (Ipv4Address origin, Ipv4Address group, + uint32_t inputInterface) + +For compatibility, and to provide simplicity, one can set a default multicast +route for a host originating data: + +/** + * @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 + */ + Ipv4::SetDefaultMulticastRoute (uint32_t outputInterface) + +For a host wanting to receive multicast data, the following function is used +to join each multicast group. + + /** + * \brief Join a multicast group for a given multicast source and + * group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + */ + Ipv4::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); + +To stop receiving multicast data, the following function is used: + + /** + * \brief Leave a multicast group for a given multicast source and + * group. + * + * \param origin The Ipv4 address of the multicast source. + * \param group The multicast group address. + */ + LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); + +There are new lookup functions implemented in Ipv4: + + /** + * \brief Find and return the interface ID of the interface that has been + * assigned the specified IP address. + * \param addr The IP address assigned to the interface of interest. + * \returns The index of the ipv4 interface with the given address. + * + * Each IP interface has an IP address associated with it. It is often + * useful to search the list of interfaces for one that corresponds to + * a known IP Address. This call takes an IP address as a parameter and + * returns the interface index of the first interface that has been assigned + * that address. If the address is not found, this function asserts. + */ + Ipv4::FindInterfaceForAddr (Ipv4Address addr) const; + + /** + * \brief Find and return the interface ID of the interface that has been + * assigned the specified (masked) IP address. + * \param addr The IP address assigned to the interface of interest. + * \param mask The address mask to be used in address matching. + * \returns The index of the ipv4 interface with the given address. + * + * Each IP interface has an IP address associated with it. It is often + * useful to search the list of interfaces for one that corresponds to + * a known IP Address. This call takes an IP address and an IP address + * mask as parameters and returns the interface index of the first interface + * that matches the masked IP address. + */ + Ipv4::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const; + +Also, there are various methods to lookup and iterate the static multicast +routes of a node, in the Ipv4StaticRouting class. + +3. Dependencies: + +- fix for bug 69 (source Ipv4 address is set correctly for UDP) +- fix for OnOffApplication that receives data + +4. Open issues or features not included + +- choose source interface on a per-group basis when a host is multihomed diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index c7bf1a652..764d0016b 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -369,14 +369,17 @@ public: * 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. + * 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 forwarding packets to some entity we think may know - * better what to do, we don't pay attention to subleties like origin address - * and input interface, 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, multicast group or - * input interface if another specific route is not found. + * 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. From 4e92674be7d2640ceb44284c1ee7ee9f0cd1f2b9 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 6 Sep 2007 16:24:17 -0700 Subject: [PATCH 18/23] monster changeset --- README.multicast-routing | 28 +- changeset.txt | 12278 +++++++++++++++++++++++++++++++++++++ 2 files changed, 12303 insertions(+), 3 deletions(-) create mode 100644 changeset.txt diff --git a/README.multicast-routing b/README.multicast-routing index a5afda564..2fe30532e 100644 --- a/README.multicast-routing +++ b/README.multicast-routing @@ -6,7 +6,7 @@ routing to ns-3. This extension allows the simulation user to: -- manually add an Ipv4 multicast route to a router +- manually add Ipv4 multicast routes to a router - specify a default outgoing interface for multicast sources (hosts) in various ways - allow a multicast receiver (hosts) to join a multicast group, to enable @@ -29,7 +29,7 @@ also touched are: virtual methods. - src/internet-node/ (several files have added tracing) -- an example script is in examples/csma-multicast.cc +- a heavily commented example script is in examples/csma-multicast.cc 2. API: @@ -114,9 +114,31 @@ To remove a route, one uses: * @see Ipv4MulticastRoute * @see Ipv4StaticRouting::AddMulticastRoute */ - Ipv4::RemoveMulticastRoute (Ipv4Address origin, Ipv4Address group, + Ipv4::RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, uint32_t inputInterface) +For symmetry with the unicast routing interface, a method is provided to +remove routes by index: + +/** + * @brief Remove a route from the static multicast routing table. + * + * Externally, the multicast static routing table appears simply as a table + * with n entries. The one sublety of note is that if a default multicast + * 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 + * RemoveMulticastRoute (0) will remove the default route. + * + * @param index The index (into the multicast routing table) of the route to + * remove. If the default route has been set, it will occupy index zero. + * + * @see Ipv4Route + * @see Ipv4StaticRouting::GetRoute + * @see Ipv4StaticRouting::AddRoute + */ + void RemoveMulticastRoute (uint32_t index); + For compatibility, and to provide simplicity, one can set a default multicast route for a host originating data: diff --git a/changeset.txt b/changeset.txt new file mode 100644 index 000000000..837107a48 --- /dev/null +++ b/changeset.txt @@ -0,0 +1,12278 @@ +searching for changes +changeset: 1278:a8f3d01d4a2c +user: Craig Dowell +date: Sun Aug 12 13:59:49 2007 -0700 +summary: untested multicast support + +diff -r c26bf0511078 -r a8f3d01d4a2c examples/csma-multicast.cc +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/examples/csma-multicast.cc Sun Aug 12 13:59:49 2007 -0700 +@@ -0,0 +1,173 @@ ++/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ ++/* ++ * 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 ++ */ ++ ++// Network topology ++// ++// n0 n1 n2 n3 ++// | | | | ++// ===================== ++// ++// - CBR/UDP flows from n0 to n1, and from n3 to n0 ++// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. ++// (i.e., DataRate of 448,000 bps) ++// - DropTail queues ++// - Tracing of queues and packet receptions to file "csma-one-subnet.tr" ++ ++#include ++#include ++#include ++#include ++ ++#include "ns3/command-line.h" ++#include "ns3/default-value.h" ++#include "ns3/ptr.h" ++#include "ns3/random-variable.h" ++#include "ns3/debug.h" ++ ++#include "ns3/simulator.h" ++#include "ns3/nstime.h" ++#include "ns3/data-rate.h" ++ ++#include "ns3/ascii-trace.h" ++#include "ns3/pcap-trace.h" ++#include "ns3/internet-node.h" ++#include "ns3/csma-channel.h" ++#include "ns3/csma-net-device.h" ++#include "ns3/csma-topology.h" ++#include "ns3/csma-ipv4-topology.h" ++#include "ns3/eui48-address.h" ++#include "ns3/ipv4-address.h" ++#include "ns3/inet-socket-address.h" ++#include "ns3/ipv4.h" ++#include "ns3/socket.h" ++#include "ns3/ipv4-route.h" ++#include "ns3/onoff-application.h" ++ ++using namespace ns3; ++ ++int ++main (int argc, char *argv[]) ++{ ++ // Users may find it convenient to turn on explicit debugging ++ // for selected modules; the below lines suggest how to do this ++#if 0 ++ DebugComponentEnable("CsmaNetDevice"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("NetDevice"); ++ DebugComponentEnable("Channel"); ++ DebugComponentEnable("CsmaChannel"); ++ DebugComponentEnable("PacketSocket"); ++#endif ++ ++ // Set up some default values for the simulation. Use the Bind() ++ // technique to tell the system what subclass of Queue to use, ++ // and what the queue limit is ++ ++ // The below Bind command tells the queue factory which class to ++ // instantiate, when the queue factory is invoked in the topology code ++ DefaultValue::Bind ("Queue", "DropTailQueue"); ++ ++ // Allow the user to override any of the defaults and the above ++ // Bind()s at run-time, via command-line arguments ++ CommandLine::Parse (argc, argv); ++ ++ // Here, we will explicitly create four nodes. In more sophisticated ++ // topologies, we could configure a node factory. ++ Ptr n0 = Create (); ++ Ptr n1 = Create (); ++ Ptr n2 = Create (); ++ Ptr n3 = Create (); ++ ++ // We create the channels first without any IP addressing information ++ Ptr channel0 = ++ CsmaTopology::CreateCsmaChannel( ++ DataRate(5000000), MilliSeconds(2)); ++ ++ uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, ++ Eui48Address("10:54:23:54:23:50")); ++ uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, ++ Eui48Address("10:54:23:54:23:51")); ++ uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0, ++ Eui48Address("10:54:23:54:23:52")); ++ uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0, ++ Eui48Address("10:54:23:54:23:53")); ++ ++ // Later, we add IP addresses. ++ CsmaIpv4Topology::AddIpv4Address ( ++ n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); ++ ++ // Configure multicasting ++ Ipv4Address multicastSource ("10.1.1.1"); ++ Ipv4Address multicastGroup ("225.0.0.0"); ++ ++ Ptr ipv4; ++ ipv4 = n0->QueryInterface (Ipv4::iid); ++ ++ std::vector outputInterfaces (1); ++ outputInterfaces[0] = n0ifIndex; ++ ++ ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, ++ outputInterfaces); ++ ++ ipv4 = n1->QueryInterface (Ipv4::iid); ++ ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++ ++ ipv4 = n2->QueryInterface (Ipv4::iid); ++ ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++ ++ ipv4 = n3->QueryInterface (Ipv4::iid); ++ ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++ ++ // Create the OnOff application to send UDP datagrams of size ++ // 210 bytes at a rate of 448 Kb/s ++ // from n0 to n1 ++ Ptr ooff = Create ( ++ n0, ++ InetSocketAddress (multicastGroup, 80), ++ "Udp", ++ ConstantVariable(1), ++ ConstantVariable(0)); ++ // Start the application ++ ooff->Start(Seconds(1.0)); ++ ooff->Stop (Seconds(10.0)); ++ ++ // Configure tracing of all enqueue, dequeue, and NetDevice receive events ++ // Trace output will be sent to the csma-one-subnet.tr file ++ AsciiTrace asciitrace ("csma-one-subnet.tr"); ++ asciitrace.TraceAllNetDeviceRx (); ++ asciitrace.TraceAllQueues (); ++ ++ // Also configure some tcpdump traces; each interface will be traced ++ // The output files will be named ++ // simple-point-to-point.pcap-- ++ // and can be read by the "tcpdump -r" command (use "-tt" option to ++ // display timestamps correctly) ++ PcapTrace pcaptrace ("csma-one-subnet.pcap"); ++ pcaptrace.TraceAllIp (); ++ ++ Simulator::Run (); ++ ++ Simulator::Destroy (); ++} +diff -r c26bf0511078 -r a8f3d01d4a2c examples/wscript +--- a/examples/wscript Fri Aug 10 13:49:41 2007 -0700 ++++ b/examples/wscript Sun Aug 12 13:59:49 2007 -0700 +@@ -17,3 +17,8 @@ def build(bld): + obj = bld.create_ns3_program('csma-packet-socket', + ['csma', 'internet-node']) + obj.source = 'csma-packet-socket.cc' ++ ++ obj = bld.create_ns3_program('csma-multicast', ++ ['csma', 'internet-node']) ++ obj.source = 'csma-multicast.cc' ++ +diff -r c26bf0511078 -r a8f3d01d4a2c src/internet-node/ipv4-impl.cc +--- a/src/internet-node/ipv4-impl.cc Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/internet-node/ipv4-impl.cc Sun Aug 12 13:59:49 2007 -0700 +@@ -95,6 +95,42 @@ Ipv4Impl::RemoveRoute (uint32_t i) + { + return m_ipv4->RemoveRoute (i); + } ++ ++void ++Ipv4Impl::AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces); ++} ++ ++uint32_t ++Ipv4Impl::GetNMulticastRoutes (void) const ++{ ++ return m_ipv4->GetNMulticastRoutes (); ++} ++ ++Ipv4MulticastRoute ++Ipv4Impl::GetMulticastRoute (uint32_t i) const ++{ ++ return *m_ipv4->GetMulticastRoute (i); ++} ++ ++void ++Ipv4Impl::RemoveMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface) ++{ ++ m_ipv4->RemoveMulticastRoute (origin, group, inputInterface); ++} ++ ++void ++Ipv4Impl::RemoveMulticastRoute (uint32_t i) ++{ ++ return m_ipv4->RemoveMulticastRoute (i); ++} ++ + uint32_t + Ipv4Impl::AddInterface (Ptr device) + { +@@ -112,6 +148,18 @@ Ipv4Impl::GetNetDevice (uint32_t i) + } + + void ++Ipv4Impl::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) ++{ ++ m_ipv4->JoinMulticastGroup(origin, group); ++} ++ ++void ++Ipv4Impl::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) ++{ ++ m_ipv4->LeaveMulticastGroup(origin, group); ++} ++ ++void + Ipv4Impl::SetAddress (uint32_t i, Ipv4Address address) + { + m_ipv4->SetAddress (i, address); +diff -r c26bf0511078 -r a8f3d01d4a2c src/internet-node/ipv4-impl.h +--- a/src/internet-node/ipv4-impl.h Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/internet-node/ipv4-impl.h Sun Aug 12 13:59:49 2007 -0700 +@@ -55,9 +55,27 @@ public: + virtual uint32_t GetNRoutes (void); + virtual Ipv4Route GetRoute (uint32_t i); + virtual void RemoveRoute (uint32_t i); ++ ++ ++ virtual void AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces); ++ ++ virtual uint32_t GetNMulticastRoutes (void) const; ++ virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const; ++ ++ virtual void RemoveMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface); ++ virtual void RemoveMulticastRoute (uint32_t i); ++ + virtual uint32_t AddInterface (Ptr device); + virtual uint32_t GetNInterfaces (void); + virtual Ptr GetNetDevice(uint32_t i); ++ ++ virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); + + virtual void SetAddress (uint32_t i, Ipv4Address address); + virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); +diff -r c26bf0511078 -r a8f3d01d4a2c src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 13:59:49 2007 -0700 +@@ -17,6 +17,7 @@ + // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + // + // Author: George F. Riley ++// Craig Dowell + // + + #include "ns3/packet.h" +@@ -131,7 +132,8 @@ void + void + Ipv4L3Protocol::DoDispose (void) + { +- for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) ++ for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); ++ i != m_interfaces.end (); i++) + { + delete (*i); + } +@@ -224,12 +226,15 @@ Ipv4L3Protocol::Lookup (Ipv4Header const + Packet packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) + { +- for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); +- rprotoIter != m_routingProtocols.end (); rprotoIter++) ++ for (Ipv4RoutingProtocolList::const_iterator rprotoIter = ++ m_routingProtocols.begin (); ++ rprotoIter != m_routingProtocols.end (); ++ rprotoIter++) + { + if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) + return; + } ++ + // No route found + routeReply (false, Ipv4Route (), packet, ipHeader); + } +@@ -261,6 +266,41 @@ Ipv4L3Protocol::RemoveRoute (uint32_t in + m_staticRouting->RemoveRoute (index); + } + ++void ++Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ m_staticRouting->AddMulticastRoute (origin, group, inputInterface, ++ outputInterfaces); ++} ++ ++uint32_t ++Ipv4L3Protocol::GetNMulticastRoutes (void) const ++{ ++ return m_staticRouting->GetNMulticastRoutes (); ++} ++ ++Ipv4MulticastRoute * ++Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const ++{ ++ return m_staticRouting->GetMulticastRoute (index); ++} ++ ++void ++Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface) ++{ ++ m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface); ++} ++ ++void ++Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index) ++{ ++ m_staticRouting->RemoveMulticastRoute (index); ++} + + uint32_t + Ipv4L3Protocol::AddInterface (Ptr device) +@@ -463,12 +503,28 @@ Ipv4L3Protocol::Forwarding (Packet const + } + ipHeader.SetTtl (ipHeader.GetTtl () - 1); + +- NS_DEBUG ("not for me -- forwarding."); ++ NS_DEBUG ("forwarding."); + Lookup (ipHeader, packet, + MakeCallback (&Ipv4L3Protocol::SendRealOut, this)); ++// ++// If this is a to a multicast address and this node is a member of the ++// indicated group we need to return false so the multicast is forwarded up. ++// Note that we may have just forwarded this packet too. ++// ++ for (Ipv4MulticastGroupList::const_iterator i = m_multicastGroups.begin (); ++ i != m_multicastGroups.end (); i++) ++ { ++ if ((*i).first.IsEqual (ipHeader.GetSource ()) && ++ (*i).second.IsEqual (ipHeader.GetDestination ())) ++ { ++ NS_DEBUG ("for me 5"); ++ return false; ++ } ++ } ++ ++ NS_DEBUG ("not for me."); + return true; + } +- + + void + Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip) +@@ -476,6 +532,28 @@ Ipv4L3Protocol::ForwardUp (Packet p, Ipv + Ptr demux = m_node->QueryInterface (Ipv4L4Demux::iid); + Ptr protocol = demux->GetProtocol (ip.GetProtocol ()); + protocol->Receive (p, ip.GetSource (), ip.GetDestination ()); ++} ++ ++void ++Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) ++{ ++ m_multicastGroups.push_back( ++ std::pair (origin, group)); ++} ++ ++void ++Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) ++{ ++ for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin (); ++ i != m_multicastGroups.end (); ++ i++) ++ { ++ if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group)) ++ { ++ m_multicastGroups.erase (i); ++ return; ++ } ++ } + } + + void +diff -r c26bf0511078 -r a8f3d01d4a2c src/internet-node/ipv4-l3-protocol.h +--- a/src/internet-node/ipv4-l3-protocol.h Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.h Sun Aug 12 13:59:49 2007 -0700 +@@ -158,11 +158,26 @@ public: + Ipv4Route *GetRoute (uint32_t i); + void RemoveRoute (uint32_t i); + ++ void AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces); ++ ++ uint32_t GetNMulticastRoutes (void) const; ++ Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; ++ ++ void RemoveMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface); ++ void RemoveMulticastRoute (uint32_t i); ++ + uint32_t AddInterface (Ptr device); + Ipv4Interface * GetInterface (uint32_t i) const; + uint32_t GetNInterfaces (void) const; +- + ++ virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ + void SetAddress (uint32_t i, Ipv4Address address); + void SetNetworkMask (uint32_t i, Ipv4Mask mask); + Ipv4Mask GetNetworkMask (uint32_t t) const; +@@ -192,7 +207,10 @@ private: + TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const; + + typedef std::list Ipv4InterfaceList; +- typedef std::list< std::pair< int, Ptr > > Ipv4RoutingProtocolList; ++ typedef std::list > ++ Ipv4MulticastGroupList; ++ typedef std::list > > ++ Ipv4RoutingProtocolList; + + Ipv4InterfaceList m_interfaces; + uint32_t m_nInterfaces; +@@ -206,6 +224,7 @@ private: + Ipv4RoutingProtocolList m_routingProtocols; + + Ptr m_staticRouting; ++ Ipv4MulticastGroupList m_multicastGroups; + }; + + } // Namespace ns3 +diff -r c26bf0511078 -r a8f3d01d4a2c src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Sun Aug 12 13:59:49 2007 -0700 +@@ -18,10 +18,10 @@ + // + // Author: George F. Riley + // Gustavo Carneiro ++// Craig Dowell + + #include "ipv4-static-routing.h" + #include "ns3/packet.h" +- + + namespace ns3 { + +@@ -77,6 +77,83 @@ Ipv4StaticRouting::SetDefaultRoute (Ipv4 + m_defaultRoute = route; + } + ++void ++Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ Ipv4MulticastRoute *route = new Ipv4MulticastRoute (); ++ *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, ++ inputInterface, outputInterfaces); ++ m_multicastRoutes.push_back (route); ++} ++ ++uint32_t ++Ipv4StaticRouting::GetNMulticastRoutes (void) const ++{ ++ return m_multicastRoutes.size (); ++} ++ ++Ipv4MulticastRoute * ++Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const ++{ ++ NS_ASSERT_MSG(index < m_multicastRoutes.size (), ++ "Ipv4StaticRouting::GetMulticastRoute (): Index out of range"); ++ ++ uint32_t tmp = 0; ++ for (MulticastRoutesCI i = m_multicastRoutes.begin (); ++ i != m_multicastRoutes.end (); ++ i++) ++ { ++ if (tmp == index) ++ { ++ return *i; ++ } ++ tmp++; ++ } ++ return 0; ++} ++ ++void ++Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface) ++{ ++ for (MulticastRoutesI i = m_multicastRoutes.begin (); ++ i != m_multicastRoutes.end (); ++ i++) ++ { ++ Ipv4MulticastRoute *route = *i; ++ if (origin == route->GetOrigin () && ++ group == route->GetGroup () && ++ inputInterface == route->GetInputInterface ()) ++ { ++ delete *i; ++ m_multicastRoutes.erase (i); ++ return; ++ } ++ } ++} ++ ++void ++Ipv4StaticRouting::RemoveMulticastRoute(uint32_t 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++; ++ } ++} ++ + Ipv4Route * + Ipv4StaticRouting::LookupStatic (Ipv4Address dest) + { +@@ -106,6 +183,25 @@ Ipv4StaticRouting::LookupStatic (Ipv4Add + { + NS_ASSERT (m_defaultRoute->IsDefault ()); + return m_defaultRoute; ++ } ++ return 0; ++} ++ ++Ipv4MulticastRoute * ++Ipv4StaticRouting::LookupStatic ( ++ Ipv4Address origin, ++ Ipv4Address group) ++{ ++ for (MulticastRoutesI i = m_multicastRoutes.begin (); ++ i != m_multicastRoutes.end (); ++ i++) ++ { ++ Ipv4MulticastRoute *route = *i; ++ if (origin == route->GetOrigin () && ++ group == route->GetGroup ()) ++ { ++ return *i; ++ } + } + return 0; + } +@@ -213,6 +309,27 @@ Ipv4StaticRouting::RequestRoute (Ipv4Hea + Packet packet, + RouteReplyCallback routeReply) + { ++// ++// 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. ++// ++ Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), ++ ipHeader.GetDestination ()); ++ if (mRoute) ++ { ++ for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) ++ { ++ Packet p = packet; ++ Ipv4Route route = ++ Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), ++ mRoute->GetOutputInterface(i)); ++ routeReply (true, route, p, ipHeader); ++ return true; ++ } ++ } ++// ++// See if this is a unicast packet we have a route for. ++// + Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); + if (route != 0) + { +@@ -246,8 +363,13 @@ Ipv4StaticRouting::DoDispose (void) + delete m_defaultRoute; + m_defaultRoute = 0; + } ++ for (MulticastRoutesI i = m_multicastRoutes.begin (); ++ i != m_multicastRoutes.end (); ++ i = m_multicastRoutes.erase (i)) ++ { ++ delete (*i); ++ } + Ipv4RoutingProtocol::DoDispose (); + } + +- + }//namespace ns3 +diff -r c26bf0511078 -r a8f3d01d4a2c src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Sun Aug 12 13:59:49 2007 -0700 +@@ -75,6 +75,20 @@ public: + Ipv4Route *GetRoute (uint32_t i); + void RemoveRoute (uint32_t i); + ++ void AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces); ++ ++ uint32_t GetNMulticastRoutes (void) const; ++ Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; ++ ++ void RemoveMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface); ++ ++ void RemoveMulticastRoute (uint32_t index); ++ + protected: + void DoDispose (void); + +@@ -86,14 +100,18 @@ private: + typedef std::list::const_iterator NetworkRoutesCI; + typedef std::list::iterator NetworkRoutesI; + ++ typedef std::list MulticastRoutes; ++ typedef std::list::const_iterator MulticastRoutesCI; ++ typedef std::list::iterator MulticastRoutesI; ++ + Ipv4Route *LookupStatic (Ipv4Address dest); ++ Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group); + + HostRoutes m_hostRoutes; + NetworkRoutes m_networkRoutes; + Ipv4Route *m_defaultRoute; ++ MulticastRoutes m_multicastRoutes; + }; +- +- + + } // Namespace ns3 + +diff -r c26bf0511078 -r a8f3d01d4a2c src/node/ipv4-route.cc +--- a/src/node/ipv4-route.cc Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/node/ipv4-route.cc Sun Aug 12 13:59:49 2007 -0700 +@@ -137,7 +137,6 @@ Ipv4Route::GetInterface (void) const + return m_interface; + } + +- + Ipv4Route + Ipv4Route::CreateHostRouteTo (Ipv4Address dest, + Ipv4Address nextHop, +@@ -220,4 +219,99 @@ std::ostream& operator<< (std::ostream& + return os; + } + ++/***************************************************** ++ * Ipv4MulticastRoute ++ *****************************************************/ ++ ++Ipv4MulticastRoute::Ipv4MulticastRoute () ++{ ++} ++ ++Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const &route) ++: ++ m_origin (route.m_origin), ++ m_group (route.m_group), ++ m_inputInterface (route.m_inputInterface), ++ m_outputInterfaces (route.m_outputInterfaces) ++{ ++} ++ ++Ipv4MulticastRoute::Ipv4MulticastRoute ( ++ Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ m_origin = origin; ++ m_group = group; ++ m_inputInterface = inputInterface; ++ m_outputInterfaces = outputInterfaces; ++} ++ ++Ipv4Address ++Ipv4MulticastRoute::GetOrigin (void) const ++{ ++ return m_origin; ++} ++ ++Ipv4Address ++Ipv4MulticastRoute::GetGroup (void) const ++{ ++ return m_group; ++} ++ ++uint32_t ++Ipv4MulticastRoute::GetInputInterface (void) const ++{ ++ return m_inputInterface; ++} ++ ++uint32_t ++Ipv4MulticastRoute::GetNOutputInterfaces (void) const ++{ ++ return m_outputInterfaces.size (); ++} ++ ++uint32_t ++Ipv4MulticastRoute::GetOutputInterface (uint32_t n) const ++{ ++ NS_ASSERT_MSG(n < m_outputInterfaces.size (), ++ "Ipv4MulticastRoute::GetOutputInterface (): index out of bounds"); ++ ++ return m_outputInterfaces[n]; ++} ++ ++std::vector ++Ipv4MulticastRoute::GetOutputInterfaces (void) const ++{ ++ return m_outputInterfaces; ++} ++ ++Ipv4MulticastRoute ++Ipv4MulticastRoute::CreateMulticastRoute ( ++ Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ return Ipv4MulticastRoute (origin, group, inputInterface, outputInterfaces); ++} ++ ++std::ostream& ++operator<< (std::ostream& os, Ipv4MulticastRoute 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 +diff -r c26bf0511078 -r a8f3d01d4a2c src/node/ipv4-route.h +--- a/src/node/ipv4-route.h Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/node/ipv4-route.h Sun Aug 12 13:59:49 2007 -0700 +@@ -22,6 +22,7 @@ + #define IPV4_ROUTE_H + + #include ++#include + #include + + #include "ipv4-address.h" +@@ -98,6 +99,67 @@ private: + + std::ostream& operator<< (std::ostream& os, Ipv4Route const& route); + ++/** ++ * \brief A record of an IPv4 multicast route ++ */ ++class Ipv4MulticastRoute { ++public: ++ /** ++ * \brief This constructor does nothing ++ */ ++ Ipv4MulticastRoute (); ++ /** ++ * \brief Copy Constructor ++ * \param route The route to copy ++ */ ++ Ipv4MulticastRoute (Ipv4MulticastRoute 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; ++ ++ /** ++ * \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 GetOutputInterfaces (void) const; ++ ++ static Ipv4MulticastRoute CreateMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, uint32_t inputInterface, ++ std::vector outputInterfaces); ++ ++private: ++ Ipv4MulticastRoute (Ipv4Address origin, Ipv4Address group, ++ uint32_t inputInterface, std::vector outputInterfaces); ++ ++ Ipv4Address m_origin; ++ Ipv4Address m_group; ++ uint32_t m_inputInterface; ++ std::vector m_outputInterfaces; ++}; ++ ++std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoute const& route); ++ + }//namespace ns3 + + #endif /* IPV4_ROUTE_H */ +diff -r c26bf0511078 -r a8f3d01d4a2c src/node/ipv4.h +--- a/src/node/ipv4.h Fri Aug 10 13:49:41 2007 -0700 ++++ b/src/node/ipv4.h Sun Aug 12 13:59:49 2007 -0700 +@@ -202,7 +202,49 @@ public: + * \param i index of route to remove from routing table. + */ + virtual void RemoveRoute (uint32_t i) = 0; ++ ++ /** ++ * \brief Add a static multicast route for a given multicast source and ++ * group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ * \param inputInterface The interface index over which the packet arrived. ++ * \param outputInterfaces The list of output interface indices over which ++ * the packet should be sent (excluding the inputInterface). ++ */ ++ virtual void AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) = 0; ++ /** ++ * \brief Remove a static multicast route for a given multicast source and ++ * group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ * \param inputInterface The interface index over which the packet arrived. ++ */ ++ virtual void RemoveMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface) = 0; + ++ /** ++ * \returns the number of entries in the multicast routing table. ++ */ ++ virtual uint32_t GetNMulticastRoutes (void) const = 0; ++ ++ /** ++ * \param i index of route to return ++ * \returns the route whose index is i ++ */ ++ virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const = 0; ++ ++ /** ++ * \param i index of route to remove from routing table. ++ */ ++ virtual void RemoveMulticastRoute (uint32_t i) = 0; ++ + /** + * \param device device to add to the list of ipv4 interfaces + * which can be used as output interfaces during packet forwarding. +@@ -225,6 +267,24 @@ public: + virtual Ptr GetNetDevice (uint32_t i) = 0; + + /** ++ * \brief Join a multicast group for a given multicast source and ++ * group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ */ ++ virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0; ++ ++ /** ++ * \brief Leave a multicast group for a given multicast source and ++ * group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ */ ++ virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0; ++ ++ /** + * \param i index of ipv4 interface + * \param address address to associate to the underlying ipv4 interface + */ + +changeset: 1279:31cb0668defd +user: Craig Dowell +date: Sun Aug 12 15:51:12 2007 -0700 +summary: debug prints to make validation easier + +diff -r a8f3d01d4a2c -r 31cb0668defd examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Sun Aug 12 13:59:49 2007 -0700 ++++ b/examples/csma-multicast.cc Sun Aug 12 15:51:12 2007 -0700 +@@ -58,19 +58,36 @@ + + using namespace ns3; + ++NS_DEBUG_COMPONENT_DEFINE ("Me"); ++ + int + main (int argc, char *argv[]) + { + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this + #if 0 ++ DebugComponentEnable("Me"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("NetDevice"); + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("PacketSocket"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); + #endif ++ ++ DebugComponentEnable("Me"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("CsmaNetDevice"); ++ DebugComponentEnable("CsmaChannel"); + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, +@@ -86,16 +103,19 @@ main (int argc, char *argv[]) + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. ++ NS_DEBUG("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + ++ NS_DEBUG("Create channels."); + // We create the channels first without any IP addressing information + Ptr channel0 = + CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); + ++ NS_DEBUG("Build Topology."); + uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, + Eui48Address("10:54:23:54:23:50")); + uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, +@@ -106,6 +126,8 @@ main (int argc, char *argv[]) + Eui48Address("10:54:23:54:23:53")); + + // Later, we add IP addresses. ++ NS_DEBUG("Assign IP Addresses."); ++ + CsmaIpv4Topology::AddIpv4Address ( + n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); + +@@ -119,6 +141,7 @@ main (int argc, char *argv[]) + n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); + + // Configure multicasting ++ NS_DEBUG("Configure multicasting."); + Ipv4Address multicastSource ("10.1.1.1"); + Ipv4Address multicastGroup ("225.0.0.0"); + +@@ -142,7 +165,8 @@ main (int argc, char *argv[]) + + // Create the OnOff application to send UDP datagrams of size + // 210 bytes at a rate of 448 Kb/s +- // from n0 to n1 ++ // from n0 to the multicast group ++ NS_DEBUG("Create Applications."); + Ptr ooff = Create ( + n0, + InetSocketAddress (multicastGroup, 80), +@@ -155,7 +179,8 @@ main (int argc, char *argv[]) + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the csma-one-subnet.tr file +- AsciiTrace asciitrace ("csma-one-subnet.tr"); ++ NS_DEBUG("Configure Tracing."); ++ AsciiTrace asciitrace ("csma-multicast.tr"); + asciitrace.TraceAllNetDeviceRx (); + asciitrace.TraceAllQueues (); + +@@ -164,10 +189,11 @@ main (int argc, char *argv[]) + // simple-point-to-point.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) +- PcapTrace pcaptrace ("csma-one-subnet.pcap"); ++ PcapTrace pcaptrace ("csma-multicast.pcap"); + pcaptrace.TraceAllIp (); + ++ NS_DEBUG("Run Simulation."); + Simulator::Run (); +- + Simulator::Destroy (); ++ NS_DEBUG("Done."); + } +diff -r a8f3d01d4a2c -r 31cb0668defd src/applications/onoff-application.cc +--- a/src/applications/onoff-application.cc Sun Aug 12 13:59:49 2007 -0700 ++++ b/src/applications/onoff-application.cc Sun Aug 12 15:51:12 2007 -0700 +@@ -22,6 +22,7 @@ + // George F. Riley, Georgia Tech, Spring 2007 + // Adapted from ApplicationOnOff in GTNetS. + ++#include "ns3/debug.h" + #include "ns3/address.h" + #include "ns3/node.h" + #include "ns3/nstime.h" +@@ -34,6 +35,8 @@ + #include "ns3/packet.h" + #include "onoff-application.h" + ++NS_DEBUG_COMPONENT_DEFINE ("OnOffApplication"); ++ + using namespace std; + + namespace ns3 { +@@ -95,30 +98,37 @@ OnOffApplication::Construct (Ptr n + m_iid = iid; + } + +- + OnOffApplication::~OnOffApplication() +-{} ++{ ++ NS_DEBUG("OnOffApplication::~OnOffApplication()"); ++} + + void + OnOffApplication::SetMaxBytes(uint32_t maxBytes) + { ++ NS_DEBUG("OnOffApplication::SetMaxBytes(" << maxBytes << ")"); + m_maxBytes = maxBytes; + } + + void + OnOffApplication::SetDefaultRate (const DataRate &rate) + { ++ NS_DEBUG("OnOffApplication::SetDefaultRate(" << &rate << ")"); + g_defaultRate.SetValue (rate); + } ++ + void + OnOffApplication::SetDefaultSize (uint32_t size) + { ++ NS_DEBUG("OnOffApplication::SetDefaultSize(" << size << ")"); + g_defaultSize.SetValue (size); + } + + void + OnOffApplication::DoDispose (void) + { ++ NS_DEBUG("OnOffApplication::DoDispose()"); ++ + m_socket = 0; + delete m_onTime; + delete m_offTime; +@@ -130,10 +140,11 @@ OnOffApplication::DoDispose (void) + Application::DoDispose (); + } + +- + // Application Methods +-void OnOffApplication::StartApplication() // Called at time specified by Start +-{ ++void OnOffApplication::StartApplication() // Called at time specified by Start ++{ ++ NS_DEBUG("OnOffApplication::StartApplication()"); ++ + // Create the socket if not already + if (!m_socket) + { +@@ -151,8 +162,10 @@ void OnOffApplication::StartApplication( + ScheduleStartEvent(); + } + +-void OnOffApplication::StopApplication() // Called at time specified by Stop +-{ ++void OnOffApplication::StopApplication() // Called at time specified by Stop ++{ ++ NS_DEBUG("OnOffApplication::StopApplication()"); ++ + if (m_sendEvent.IsRunning ()) + { // Cancel the pending send packet event + // Calculate residual bits since last packet sent +@@ -166,17 +179,23 @@ void OnOffApplication::StopApplication() + // Event handlers + void OnOffApplication::StartSending() + { ++ NS_DEBUG("OnOffApplication::StartSending ()"); ++ + ScheduleNextTx(); // Schedule the send packet event + } + + void OnOffApplication::StopSending() + { ++ NS_DEBUG("OnOffApplication::StopSending ()"); ++ + Simulator::Cancel(m_sendEvent); + } + + // Private helpers + void OnOffApplication::ScheduleNextTx() + { ++ NS_DEBUG("OnOffApplication::ScheduleNextTx ()"); ++ + if (m_totBytes < m_maxBytes) + { + uint32_t bits = m_pktSize * 8 - m_residualBits; +@@ -192,12 +211,16 @@ void OnOffApplication::ScheduleNextTx() + + void OnOffApplication::ScheduleStartEvent() + { // Schedules the event to start sending data (switch to the "On" state) ++ NS_DEBUG("OnOffApplication::ScheduleStartEvent ()"); ++ + Time offInterval = Seconds(m_offTime->GetValue()); + m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this); + } + + void OnOffApplication::ScheduleStopEvent() + { // Schedules the event to stop sending data (switch to "Off" state) ++ NS_DEBUG("OnOffApplication::ScheduleStopEvent ()"); ++ + Time onInterval = Seconds(m_onTime->GetValue()); + Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this); + } +@@ -205,6 +228,8 @@ void OnOffApplication::ScheduleStopEvent + + void OnOffApplication::SendPacket() + { ++ NS_DEBUG("OnOffApplication::SendPacket ()"); ++ + NS_ASSERT (m_sendEvent.IsExpired ()); + m_socket->Send(Packet (m_pktSize)); + m_totBytes += m_pktSize; +@@ -215,6 +240,8 @@ void OnOffApplication::SendPacket() + + void OnOffApplication::ConnectionSucceeded(Ptr) + { ++ NS_DEBUG("OnOffApplication::ConnectionSucceeded ()"); ++ + m_connected = true; + ScheduleStartEvent(); + } +diff -r a8f3d01d4a2c -r 31cb0668defd src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 13:59:49 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 15:51:12 2007 -0700 +@@ -17,7 +17,6 @@ + // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + // + // Author: George F. Riley +-// Craig Dowell + // + + #include "ns3/packet.h" +@@ -121,17 +120,24 @@ Ipv4L3Protocol::Ipv4L3Protocol(Ptr + m_identification (0), + m_node (node) + { ++ NS_DEBUG("Ipv4L3Protocol::Ipv4L3Protocol ()"); ++ + SetInterfaceId (Ipv4L3Protocol::iid); + m_staticRouting = Create (); + AddRoutingProtocol (m_staticRouting, 0); + SetupLoopback (); + } ++ + Ipv4L3Protocol::~Ipv4L3Protocol () +-{} ++{ ++ NS_DEBUG("Ipv4L3Protocol::~Ipv4L3Protocol ()"); ++} + + void + Ipv4L3Protocol::DoDispose (void) + { ++ NS_DEBUG("Ipv4L3Protocol::DoDispose ()"); ++ + for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); + i != m_interfaces.end (); i++) + { +@@ -147,6 +153,8 @@ void + void + Ipv4L3Protocol::SetupLoopback (void) + { ++ NS_DEBUG("Ipv4L3Protocol::SetupLoopback ()"); ++ + Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node); + interface->SetAddress (Ipv4Address::GetLoopback ()); + interface->SetNetworkMask (Ipv4Mask::GetLoopback ()); +@@ -158,6 +166,8 @@ TraceResolver * + TraceResolver * + Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context) + { ++ NS_DEBUG("Ipv4L3Protocol::CreateTraceResolver ()"); ++ + CompositeTraceResolver *resolver = new CompositeTraceResolver (context); + resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX)); + resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX)); +@@ -170,6 +180,8 @@ TraceResolver * + TraceResolver * + Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const + { ++ NS_DEBUG("Ipv4L3Protocol::InterfacesCreateTraceResolver ()"); ++ + ArrayTraceResolver *resolver = + new ArrayTraceResolver + (context, +@@ -181,6 +193,7 @@ void + void + Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl) + { ++ NS_DEBUG("Ipv4L3Protocol::SetDefaultTtl ()"); + m_defaultTtl = ttl; + } + +@@ -190,20 +203,28 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Addr + Ipv4Address nextHop, + uint32_t interface) + { ++ NS_DEBUG("Ipv4L3Protocol::AddHostRouteTo (" << dest << ", " << nextHop << ++ ", " << interface << ")"); + m_staticRouting->AddHostRouteTo (dest, nextHop, interface); + } ++ + void + Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, + uint32_t interface) + { ++ NS_DEBUG("Ipv4L3Protocol::AddHostRouteTo (" << dest << ", " << ++ interface << ")"); + m_staticRouting->AddHostRouteTo (dest, interface); + } ++ + void + Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + Ipv4Address nextHop, + uint32_t interface) + { ++ NS_DEBUG("Ipv4L3Protocol::AddNetworkRouteTo (" << network << ", " << ++ networkMask << ", " << nextHop << ", " << interface << ")"); + m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface); + } + void +@@ -211,26 +232,33 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4A + Ipv4Mask networkMask, + uint32_t interface) + { ++ NS_DEBUG("Ipv4L3Protocol::AddNetworkRouteTo (" << network << ", " << ++ networkMask << ", " << interface << ")"); + m_staticRouting->AddNetworkRouteTo (network, networkMask, interface); + } + void + Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, + uint32_t interface) + { ++ NS_DEBUG("Ipv4L3Protocol::SetDefaultRoute (" << nextHop << ", " << ++ interface << ")"); + m_staticRouting->SetDefaultRoute (nextHop, interface); + } +- + + void + Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, + Packet packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) + { ++ NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ", " << &packet << ++ &routeReply << ")"); ++ + for (Ipv4RoutingProtocolList::const_iterator rprotoIter = + m_routingProtocols.begin (); + rprotoIter != m_routingProtocols.end (); + rprotoIter++) + { ++ NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route"); + if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) + return; + } +@@ -243,6 +271,8 @@ Ipv4L3Protocol::AddRoutingProtocol (Ptr< + Ipv4L3Protocol::AddRoutingProtocol (Ptr routingProtocol, + int priority) + { ++ NS_DEBUG("Ipv4L3Protocol::AddRoutingProtocol (" << &routingProtocol << ++ ", " << priority << ")"); + m_routingProtocols.push_back + (std::pair > (-priority, routingProtocol)); + m_routingProtocols.sort (); +@@ -251,18 +281,21 @@ uint32_t + uint32_t + Ipv4L3Protocol::GetNRoutes (void) + { ++ NS_DEBUG("Ipv4L3Protocol::GetNRoutes ()"); + return m_staticRouting->GetNRoutes (); + } + + Ipv4Route * + Ipv4L3Protocol::GetRoute (uint32_t index) + { ++ NS_DEBUG("Ipv4L3Protocol::GetRoute ()"); + return m_staticRouting->GetRoute (index); + } + + void + Ipv4L3Protocol::RemoveRoute (uint32_t index) + { ++ NS_DEBUG("Ipv4L3Protocol::RemoveRoute (" << index << ")"); + m_staticRouting->RemoveRoute (index); + } + +@@ -272,6 +305,9 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4A + uint32_t inputInterface, + std::vector outputInterfaces) + { ++ NS_DEBUG("Ipv4L3Protocol::AddMulticastRoute (" << origin << ", " << ++ group << ", " << inputInterface << ", " << &outputInterfaces << ")"); ++ + m_staticRouting->AddMulticastRoute (origin, group, inputInterface, + outputInterfaces); + } +@@ -279,12 +315,14 @@ uint32_t + uint32_t + Ipv4L3Protocol::GetNMulticastRoutes (void) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetNMulticastRoutes ()"); + return m_staticRouting->GetNMulticastRoutes (); + } + + Ipv4MulticastRoute * + Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetMulticastRoute (" << index << ")"); + return m_staticRouting->GetMulticastRoute (index); + } + +@@ -293,32 +331,40 @@ Ipv4L3Protocol::RemoveMulticastRoute (Ip + Ipv4Address group, + uint32_t inputInterface) + { ++ NS_DEBUG("Ipv4L3Protocol::RemoveMulticastRoute (" << origin << ", " << ++ group << ", " << inputInterface << ")"); + m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface); + } + + void + Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index) + { ++ NS_DEBUG("Ipv4L3Protocol::RemoveMulticastRoute (" << index << ")"); + m_staticRouting->RemoveMulticastRoute (index); + } + + uint32_t + Ipv4L3Protocol::AddInterface (Ptr device) + { ++ NS_DEBUG("Ipv4L3Protocol::AddInterface (" << &device << ")"); + Ipv4Interface *interface = new ArpIpv4Interface (m_node, device); + return AddIpv4Interface (interface); + } ++ + uint32_t + Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface) + { ++ NS_DEBUG("Ipv4L3Protocol::AddIpv4Interface (" << interface << ")"); + uint32_t index = m_nInterfaces; + m_interfaces.push_back (interface); + m_nInterfaces++; + return index; + } ++ + Ipv4Interface * + Ipv4L3Protocol::GetInterface (uint32_t index) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetInterface (" << index << ")"); + uint32_t tmp = 0; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + { +@@ -330,15 +376,18 @@ Ipv4L3Protocol::GetInterface (uint32_t i + } + return 0; + } ++ + uint32_t + Ipv4L3Protocol::GetNInterfaces (void) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetNInterface ()"); + return m_nInterfaces; + } + + Ipv4Interface * + Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) + { ++ NS_DEBUG("Ipv4L3Protocol::FindInterfaceForDevice (" << &device << ")"); + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + { + if ((*i)->GetDevice () == device) +@@ -352,6 +401,9 @@ void + void + Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protocol, const Address &from) + { ++ NS_DEBUG("Ipv4L3Protocol::Receive (" << &device << ", " << &p << ", " << ++ protocol << ", " << from << ")"); ++ + uint32_t index = 0; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + { +@@ -386,6 +438,9 @@ Ipv4L3Protocol::Send (Packet const &pack + Ipv4Address destination, + uint8_t protocol) + { ++ NS_DEBUG("Ipv4L3Protocol::Send (" << &packet << ", " << source << ", " << ++ ", " << destination << ", " << protocol << ")"); ++ + Ipv4Header ipHeader; + + ipHeader.SetSource (source); +@@ -434,6 +489,9 @@ Ipv4L3Protocol::SendRealOut (bool found, + Packet packet, + Ipv4Header const &ipHeader) + { ++ NS_DEBUG("Ipv4L3Protocol::SendRealOut (" << found << ", " << &route << ++ ", " << &packet << &ipHeader << ")"); ++ + if (!found) + { + NS_DEBUG ("no route to host. drop."); +@@ -458,6 +516,9 @@ bool + bool + Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) + { ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (" << &packet << ", " << &ipHeader << ++ ", " << device << ")"); ++ + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); + i != m_interfaces.end (); i++) + { +@@ -529,6 +590,7 @@ void + void + Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip) + { ++ NS_DEBUG("Ipv4L3Protocol::ForwardUp (" << &p << ", " << &ip << ")"); + Ptr demux = m_node->QueryInterface (Ipv4L4Demux::iid); + Ptr protocol = demux->GetProtocol (ip.GetProtocol ()); + protocol->Receive (p, ip.GetSource (), ip.GetDestination ()); +@@ -537,6 +599,8 @@ void + void + Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) + { ++ NS_DEBUG("Ipv4L3Protocol::JoinMulticastGroup (" << origin << ", " << ++ group << ")"); + m_multicastGroups.push_back( + std::pair (origin, group)); + } +@@ -544,6 +608,9 @@ void + void + Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) + { ++ NS_DEBUG("Ipv4L3Protocol::LeaveMulticastGroup (" << origin << ", " << ++ group << ")"); ++ + for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin (); + i != m_multicastGroups.end (); + i++) +@@ -559,42 +626,55 @@ void + void + Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address) + { ++ NS_DEBUG("Ipv4L3Protocol::SetAddress (" << i << ", " << address << ")"); + Ipv4Interface *interface = GetInterface (i); + interface->SetAddress (address); + } ++ + void + Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask) + { ++ NS_DEBUG("Ipv4L3Protocol::SetNetworkMask (" << i << ", " << mask << ")"); + Ipv4Interface *interface = GetInterface (i); + interface->SetNetworkMask (mask); + } ++ + Ipv4Mask + Ipv4L3Protocol::GetNetworkMask (uint32_t i) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetNetworkMask (" << i << ")"); + Ipv4Interface *interface = GetInterface (i); + return interface->GetNetworkMask (); + } ++ + Ipv4Address + Ipv4L3Protocol::GetAddress (uint32_t i) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetAddress (" << i << ")"); + Ipv4Interface *interface = GetInterface (i); + return interface->GetAddress (); + } ++ + uint16_t + Ipv4L3Protocol::GetMtu (uint32_t i) const + { ++ NS_DEBUG("Ipv4L3Protocol::GetMtu (" << i << ")"); + Ipv4Interface *interface = GetInterface (i); + return interface->GetMtu (); + } ++ + bool + Ipv4L3Protocol::IsUp (uint32_t i) const + { ++ NS_DEBUG("Ipv4L3Protocol::IsUp (" << i << ")"); + Ipv4Interface *interface = GetInterface (i); + return interface->IsUp (); + } ++ + void + Ipv4L3Protocol::SetUp (uint32_t i) + { ++ NS_DEBUG("Ipv4L3Protocol::SetUp (" << i << ")"); + Ipv4Interface *interface = GetInterface (i); + interface->SetUp (); + +@@ -608,9 +688,11 @@ Ipv4L3Protocol::SetUp (uint32_t i) + interface->GetNetworkMask (), i); + } + } ++ + void + Ipv4L3Protocol::SetDown (uint32_t ifaceIndex) + { ++ NS_DEBUG("Ipv4L3Protocol::SetDown (" << ifaceIndex << ")"); + Ipv4Interface *interface = GetInterface (ifaceIndex); + interface->SetDown (); + +diff -r a8f3d01d4a2c -r 31cb0668defd src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Sun Aug 12 13:59:49 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Sun Aug 12 15:51:12 2007 -0700 +@@ -18,10 +18,12 @@ + // + // Author: George F. Riley + // Gustavo Carneiro +-// Craig Dowell +- ++ ++#include "ns3/debug.h" + #include "ipv4-static-routing.h" + #include "ns3/packet.h" ++ ++NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting"); + + namespace ns3 { + +@@ -31,10 +33,12 @@ Ipv4StaticRouting::AddHostRouteTo (Ipv4A + Ipv4Address nextHop, + uint32_t interface) + { ++ + Ipv4Route *route = new Ipv4Route (); + *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface); + m_hostRoutes.push_back (route); + } ++ + void + Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, + uint32_t interface) +@@ -43,6 +47,7 @@ Ipv4StaticRouting::AddHostRouteTo (Ipv4A + *route = Ipv4Route::CreateHostRouteTo (dest, interface); + m_hostRoutes.push_back (route); + } ++ + void + Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, +@@ -56,6 +61,7 @@ Ipv4StaticRouting::AddNetworkRouteTo (Ip + interface); + m_networkRoutes.push_back (route); + } ++ + void + Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, +@@ -67,6 +73,7 @@ Ipv4StaticRouting::AddNetworkRouteTo (Ip + interface); + m_networkRoutes.push_back (route); + } ++ + void + Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, + uint32_t interface) +@@ -197,7 +204,8 @@ Ipv4StaticRouting::LookupStatic ( + i++) + { + Ipv4MulticastRoute *route = *i; +- if (origin == route->GetOrigin () && ++ if ( (origin == route->GetOrigin () || ++ origin == Ipv4Address::GetAny ()) && + group == route->GetGroup ()) + { + return *i; +@@ -309,6 +317,15 @@ Ipv4StaticRouting::RequestRoute (Ipv4Hea + Packet packet, + RouteReplyCallback routeReply) + { ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " << ++ &packet << ", " << &routeReply << ")"); ++ ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): source = " << ++ ipHeader.GetSource ()); ++ ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " << ++ ipHeader.GetDestination ()); ++ + // + // 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. +diff -r a8f3d01d4a2c -r 31cb0668defd src/internet-node/udp-l4-protocol.cc +--- a/src/internet-node/udp-l4-protocol.cc Sun Aug 12 13:59:49 2007 -0700 ++++ b/src/internet-node/udp-l4-protocol.cc Sun Aug 12 15:51:12 2007 -0700 +@@ -19,6 +19,7 @@ + * Author: Mathieu Lacage + */ + ++#include "ns3/debug.h" + #include "ns3/assert.h" + #include "ns3/packet.h" + #include "ns3/empty-trace-resolver.h" +@@ -31,6 +32,8 @@ + #include "ipv4-l3-protocol.h" + #include "udp-socket.h" + ++NS_DEBUG_COMPONENT_DEFINE ("UdpL4Protocol"); ++ + namespace ns3 { + + /* see http://www.iana.org/assignments/protocol-numbers */ +@@ -40,20 +43,26 @@ UdpL4Protocol::UdpL4Protocol (Ptr + : Ipv4L4Protocol (PROT_NUMBER, 2), + m_node (node), + m_endPoints (new Ipv4EndPointDemux ()) +-{} ++{ ++ NS_DEBUG("UdpL4Protocol::UdpL4Protocol ()"); ++} + + UdpL4Protocol::~UdpL4Protocol () +-{} ++{ ++ NS_DEBUG("UdpL4Protocol::~UdpL4Protocol ()"); ++} + + TraceResolver * + UdpL4Protocol::CreateTraceResolver (TraceContext const &context) + { ++ NS_DEBUG("UdpL4Protocol::CreateTraceResolver ()"); + return new EmptyTraceResolver (context); + } + + void + UdpL4Protocol::DoDispose (void) + { ++ NS_DEBUG("UdpL4Protocol::DoDispose ()"); + if (m_endPoints != 0) + { + delete m_endPoints; +@@ -66,6 +75,7 @@ Ptr + Ptr + UdpL4Protocol::CreateSocket (void) + { ++ NS_DEBUG("UdpL4Protocol::CreateSocket ()"); + Ptr socket = Create (m_node, this); + return socket; + } +@@ -73,27 +83,36 @@ Ipv4EndPoint * + Ipv4EndPoint * + UdpL4Protocol::Allocate (void) + { ++ NS_DEBUG("UdpL4Protocol::Allocate ()"); + return m_endPoints->Allocate (); + } ++ + Ipv4EndPoint * + UdpL4Protocol::Allocate (Ipv4Address address) + { ++ NS_DEBUG("UdpL4Protocol::Allocate (" << address << ")"); + return m_endPoints->Allocate (address); + } ++ + Ipv4EndPoint * + UdpL4Protocol::Allocate (uint16_t port) + { ++ NS_DEBUG("UdpL4Protocol::Allocate (" << port << ")"); + return m_endPoints->Allocate (port); + } ++ + Ipv4EndPoint * + UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port) + { ++ NS_DEBUG("UdpL4Protocol::Allocate (" << address << ", " << port << ")"); + return m_endPoints->Allocate (address, port); + } + Ipv4EndPoint * + UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort, + Ipv4Address peerAddress, uint16_t peerPort) + { ++ NS_DEBUG("UdpL4Protocol::Allocate (" << localAddress << ", " << localPort << ++ ", " << peerAddress << ", " << peerPort << ")"); + return m_endPoints->Allocate (localAddress, localPort, + peerAddress, peerPort); + } +@@ -101,6 +120,7 @@ void + void + UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint) + { ++ NS_DEBUG("UdpL4Protocol::Deallocate (" << endPoint << ")"); + m_endPoints->DeAllocate (endPoint); + } + +@@ -109,6 +129,9 @@ UdpL4Protocol::Receive(Packet& packet, + Ipv4Address const &source, + Ipv4Address const &destination) + { ++ NS_DEBUG("UdpL4Protocol::Receive (" << &packet << ", " << source << ++ ", " << destination << ")"); ++ + UdpHeader udpHeader; + packet.RemoveHeader (udpHeader); + Ipv4EndPointDemux::EndPoints endPoints = +@@ -126,6 +149,9 @@ UdpL4Protocol::Send (Packet packet, + Ipv4Address saddr, Ipv4Address daddr, + uint16_t sport, uint16_t dport) + { ++ NS_DEBUG("UdpL4Protocol::Send (" << &packet << ", " << saddr << ++ ", " << daddr << ", " << sport << ", " << dport << ")"); ++ + UdpHeader udpHeader; + udpHeader.SetDestination (dport); + udpHeader.SetSource (sport); +@@ -139,6 +165,7 @@ UdpL4Protocol::Send (Packet packet, + Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); + if (ipv4 != 0) + { ++ NS_DEBUG("UdpL4Protocol::Send (): Sending to IP"); + ipv4->Send (packet, saddr, daddr, PROT_NUMBER); + } + } +diff -r a8f3d01d4a2c -r 31cb0668defd src/internet-node/udp-socket.cc +--- a/src/internet-node/udp-socket.cc Sun Aug 12 13:59:49 2007 -0700 ++++ b/src/internet-node/udp-socket.cc Sun Aug 12 15:51:12 2007 -0700 +@@ -18,12 +18,16 @@ + * + * Author: Mathieu Lacage + */ ++ ++#include "ns3/debug.h" + #include "ns3/node.h" + #include "ns3/inet-socket-address.h" + #include "udp-socket.h" + #include "udp-l4-protocol.h" + #include "ipv4-end-point.h" + #include "ipv4-l4-demux.h" ++ ++NS_DEBUG_COMPONENT_DEFINE ("UdpSocket"); + + namespace ns3 { + +@@ -35,9 +39,14 @@ UdpSocket::UdpSocket (Ptr node, Pt + m_shutdownSend (false), + m_shutdownRecv (false), + m_connected (false) +-{} ++{ ++ NS_DEBUG("UdpSocket::UdpSocket ()"); ++} ++ + UdpSocket::~UdpSocket () + { ++ NS_DEBUG("UdpSocket::~UdpSocket ()"); ++ + m_node = 0; + if (m_endPoint != 0) + { +@@ -60,25 +69,32 @@ enum Socket::SocketErrno + enum Socket::SocketErrno + UdpSocket::GetErrno (void) const + { ++ NS_DEBUG("UdpSocket::GetErrno ()"); ++ + return m_errno; + } + + Ptr + UdpSocket::GetNode (void) const + { ++ NS_DEBUG("UdpSocket::GetNode ()"); + return m_node; + } + + void + UdpSocket::Destroy (void) + { ++ NS_DEBUG("UdpSocket::Destroy ()"); + m_node = 0; + m_endPoint = 0; + m_udp = 0; + } ++ + int + UdpSocket::FinishBind (void) + { ++ NS_DEBUG("UdpSocket::FinishBind ()"); ++ + if (m_endPoint == 0) + { + return -1; +@@ -91,14 +107,20 @@ int + int + UdpSocket::Bind (void) + { ++ NS_DEBUG("UdpSocket::Bind ()"); ++ + m_endPoint = m_udp->Allocate (); + return FinishBind (); + } ++ + int + UdpSocket::Bind (const Address &address) + { ++ NS_DEBUG("UdpSocket::Bind (" << address << ")"); ++ + if (!InetSocketAddress::IsMatchingType (address)) + { ++ NS_DEBUG("UdpSocket::Bind (): Not IsMatchingType"); + return ERROR_INVAL; + } + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); +@@ -127,12 +149,15 @@ int + int + UdpSocket::ShutdownSend (void) + { ++ NS_DEBUG("UdpSocket::ShutDownSend ()"); + m_shutdownSend = true; + return 0; + } ++ + int + UdpSocket::ShutdownRecv (void) + { ++ NS_DEBUG("UdpSocket::ShutDownRecv ()"); + m_shutdownRecv = false; + return 0; + } +@@ -140,6 +165,7 @@ int + int + UdpSocket::Close(void) + { ++ NS_DEBUG("UdpSocket::Close ()"); + NotifyCloseCompleted (); + return 0; + } +@@ -147,6 +173,8 @@ int + int + UdpSocket::Connect(const Address & address) + { ++ NS_DEBUG("UdpSocket::Connect (" << address << ")"); ++ + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + m_defaultAddress = transport.GetIpv4 (); + m_defaultPort = transport.GetPort (); +@@ -154,9 +182,12 @@ UdpSocket::Connect(const Address & addre + m_connected = true; + return 0; + } ++ + int + UdpSocket::Send (const Packet &p) + { ++ NS_DEBUG("UdpSocket::Send (" << &p << ")"); ++ + if (!m_connected) + { + m_errno = ERROR_NOTCONN; +@@ -164,17 +195,23 @@ UdpSocket::Send (const Packet &p) + } + return DoSendTo (p, m_defaultAddress, m_defaultPort); + } ++ + int + UdpSocket::DoSendTo (const Packet &p, const Address &address) + { ++ NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << address << ")"); + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + Ipv4Address ipv4 = transport.GetIpv4 (); + uint16_t port = transport.GetPort (); + return DoSendTo (p, ipv4, port); + } ++ + int + UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port) + { ++ NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << ipv4 << ", " << ++ port << ")"); ++ + if (m_endPoint == 0) + { + if (Bind () == -1) +@@ -189,14 +226,18 @@ UdpSocket::DoSendTo (const Packet &p, Ip + m_errno = ERROR_SHUTDOWN; + return -1; + } ++ ++ NS_DEBUG("UdpSocket::DoSendTo (): Send to UDP"); + m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4, + m_endPoint->GetLocalPort (), port); + NotifyDataSent (p.GetSize ()); + return 0; + } ++ + int + UdpSocket::SendTo(const Address &address, const Packet &p) + { ++ NS_DEBUG("UdpSocket::SendTo (" << address << ", " << &p << ")"); + if (m_connected) + { + m_errno = ERROR_ISCONN; +@@ -211,6 +252,9 @@ void + void + UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port) + { ++ NS_DEBUG("UdpSocket::ForwardUp (" << &packet << ", " << ipv4 << ", " << ++ port << ")"); ++ + if (m_shutdownRecv) + { + return; + +changeset: 1280:25fa26a6533e +user: Craig Dowell +date: Sun Aug 12 22:41:24 2007 -0700 +summary: many debug prints + +diff -r 31cb0668defd -r 25fa26a6533e examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/examples/csma-multicast.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -67,17 +67,23 @@ main (int argc, char *argv[]) + // for selected modules; the below lines suggest how to do this + #if 0 + DebugComponentEnable("Me"); +- DebugComponentEnable("CsmaNetDevice"); +- DebugComponentEnable("Ipv4L3Protocol"); +- DebugComponentEnable("NetDevice"); ++ DebugComponentEnable("Object"); ++ DebugComponentEnable("Queue"); ++ DebugComponentEnable("DropTailQueue"); + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); ++ DebugComponentEnable("CsmaNetDevice"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("NetDevice"); + DebugComponentEnable("PacketSocket"); + DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); + #endif + + DebugComponentEnable("Me"); +@@ -88,6 +94,9 @@ main (int argc, char *argv[]) + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("CsmaChannel"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, +diff -r 31cb0668defd -r 25fa26a6533e examples/csma-one-subnet.cc +--- a/examples/csma-one-subnet.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/examples/csma-one-subnet.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -58,23 +58,47 @@ + #include "ns3/ipv4-route.h" + #include "ns3/onoff-application.h" + +- + using namespace ns3; + ++NS_DEBUG_COMPONENT_DEFINE ("Me"); + +-int main (int argc, char *argv[]) ++int ++main (int argc, char *argv[]) + { +- + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this + #if 0 ++ DebugComponentEnable("Me"); ++ DebugComponentEnable("Object"); ++ DebugComponentEnable("Queue"); ++ DebugComponentEnable("DropTailQueue"); ++ DebugComponentEnable("Channel"); ++ DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("NetDevice"); +- DebugComponentEnable("Channel"); ++ DebugComponentEnable("PacketSocket"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); ++#endif ++ ++ DebugComponentEnable("Me"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("CsmaChannel"); +- DebugComponentEnable("PacketSocket"); +-#endif ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, +@@ -90,16 +114,19 @@ int main (int argc, char *argv[]) + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. ++ NS_DEBUG("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information ++ NS_DEBUG("Create channels."); + Ptr channel0 = + CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); + ++ NS_DEBUG("Build Topology."); + uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, + Eui48Address("10:54:23:54:23:50")); + uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, +@@ -110,6 +137,7 @@ int main (int argc, char *argv[]) + Eui48Address("10:54:23:54:23:53")); + + // Later, we add IP addresses. ++ NS_DEBUG("Assign IP Addresses."); + CsmaIpv4Topology::AddIpv4Address ( + n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); + +@@ -125,6 +153,7 @@ int main (int argc, char *argv[]) + // Create the OnOff application to send UDP datagrams of size + // 210 bytes at a rate of 448 Kb/s + // from n0 to n1 ++ NS_DEBUG("Create Applications."); + Ptr ooff = Create ( + n0, + InetSocketAddress ("10.1.1.2", 80), +@@ -148,6 +177,7 @@ int main (int argc, char *argv[]) + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the csma-one-subnet.tr file ++ NS_DEBUG("Configure Tracing."); + AsciiTrace asciitrace ("csma-one-subnet.tr"); + asciitrace.TraceAllNetDeviceRx (); + asciitrace.TraceAllQueues (); +@@ -160,7 +190,8 @@ int main (int argc, char *argv[]) + PcapTrace pcaptrace ("csma-one-subnet.pcap"); + pcaptrace.TraceAllIp (); + ++ NS_DEBUG("Run Simulation."); + Simulator::Run (); +- + Simulator::Destroy (); ++ NS_DEBUG("Done."); + } +diff -r 31cb0668defd -r 25fa26a6533e examples/simple-point-to-point.cc +--- a/examples/simple-point-to-point.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/examples/simple-point-to-point.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -38,11 +38,7 @@ + // - Tracing of queues and packet receptions to file + // "simple-point-to-point.tr" + +-#include +-#include +-#include +-#include +- ++#include "ns3/debug.h" + #include "ns3/command-line.h" + #include "ns3/default-value.h" + #include "ns3/ptr.h" +@@ -67,19 +63,46 @@ + + using namespace ns3; + +-int main (int argc, char *argv[]) ++NS_DEBUG_COMPONENT_DEFINE ("Me"); ++ ++int ++main (int argc, char *argv[]) + { + + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this + #if 0 ++ DebugComponentEnable("Me"); + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); + DebugComponentEnable("Channel"); + DebugComponentEnable("PointToPointChannel"); + DebugComponentEnable("PointToPointNetDevice"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("NetDevice"); ++ DebugComponentEnable("PacketSocket"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); + #endif ++ ++ DebugComponentEnable("Me"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("PointToPointChannel"); ++ DebugComponentEnable("PointToPointNetDevice"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, +@@ -100,12 +123,14 @@ int main (int argc, char *argv[]) + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. ++ NS_DEBUG("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information ++ NS_DEBUG("Create channels."); + Ptr channel0 = + PointToPointTopology::AddPointToPointLink ( + n0, n2, DataRate(5000000), MilliSeconds(2)); +@@ -119,6 +144,7 @@ int main (int argc, char *argv[]) + n2, n3, DataRate(1500000), MilliSeconds(10)); + + // Later, we add IP addresses. ++ NS_DEBUG("Assign IP Addresses."); + PointToPointTopology::AddIpv4Addresses ( + channel0, n0, Ipv4Address("10.1.1.1"), + n2, Ipv4Address("10.1.1.2")); +@@ -135,13 +161,14 @@ int main (int argc, char *argv[]) + // NetDevice creation, IP Address assignment, and routing) are + // separated because there may be a need to postpone IP Address + // assignment (emulation) or modify to use dynamic routing ++ NS_DEBUG("Add Static Routes."); + PointToPointTopology::AddIpv4Routes(n0, n2, channel0); + 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 ++ NS_DEBUG("Create Applications."); + Ptr ooff = Create ( + n0, + InetSocketAddress ("10.1.3.2", 80), +@@ -165,6 +192,7 @@ int main (int argc, char *argv[]) + + // Here, finish off packet routing configuration + // This will likely set by some global StaticRouting object in the future ++ NS_DEBUG("Set Default Routes."); + Ptr ipv4; + ipv4 = n0->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); +@@ -173,6 +201,7 @@ int main (int argc, char *argv[]) + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-point-to-point.tr file ++ NS_DEBUG("Configure Tracing."); + AsciiTrace asciitrace ("simple-point-to-point.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); +@@ -185,7 +214,8 @@ int main (int argc, char *argv[]) + PcapTrace pcaptrace ("simple-point-to-point.pcap"); + pcaptrace.TraceAllIp (); + +- Simulator::Run (); +- ++ NS_DEBUG("Run Simulation."); ++ Simulator::Run (); + Simulator::Destroy (); ++ NS_DEBUG("Done."); + } +diff -r 31cb0668defd -r 25fa26a6533e src/devices/csma/csma-ipv4-topology.cc +--- a/src/devices/csma/csma-ipv4-topology.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/src/devices/csma/csma-ipv4-topology.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -36,15 +36,15 @@ namespace ns3 { + + uint32_t + CsmaIpv4Topology::AddIpv4CsmaNode(Ptr n1, +- Ptr ch, +- Eui48Address addr) ++ Ptr ch, ++ Eui48Address addr) + { + Ptr q = Queue::CreateDefault (); + + // assume full-duplex + Ptr nd0 = Create (n1, addr, +- ns3::CsmaNetDevice::IP_ARP, +- true, true); ++ ns3::CsmaNetDevice::IP_ARP, ++ true, true); + nd0->AddQueue(q); + nd0->Attach (ch); + return nd0->GetIfIndex (); +@@ -53,51 +53,50 @@ CsmaIpv4Topology::AddIpv4CsmaNode(Ptr n1, +- Ptr ch, +- Eui48Address addr) ++ Ptr ch, ++ Eui48Address addr) + { + Ptr q = Queue::CreateDefault (); + + Ptr nd0 = Create (n1, addr, +- ns3::CsmaNetDevice::LLC, +- true, false); ++ ns3::CsmaNetDevice::LLC, ++ true, false); + nd0->AddQueue(q); + nd0->Attach (ch); + + Ptr nd1 = Create (n1, addr, +- ns3::CsmaNetDevice::LLC, +- false, true); ++ ns3::CsmaNetDevice::LLC, ++ false, true); + nd1->AddQueue(q); + nd1->Attach (ch); + } + + void + CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr n1, +- Ptr ch, +- Eui48Address addr) ++ Ptr ch, ++ Eui48Address addr) + { + Ptr q = Queue::CreateDefault (); + + Ptr nd0 = Create (n1, addr, +- ns3::CsmaNetDevice::RAW, +- true, false); ++ ns3::CsmaNetDevice::RAW, ++ true, false); + nd0->AddQueue(q); + nd0->Attach (ch); + + Ptr nd1 = Create (n1, addr, +- ns3::CsmaNetDevice::RAW, +- false, true); ++ ns3::CsmaNetDevice::RAW, ++ false, true); + nd1->AddQueue(q); + nd1->Attach (ch); + } + + void + CsmaIpv4Topology::AddIpv4Address(Ptr n1, +- int ndNum, +- const Ipv4Address& addr1, +- const Ipv4Mask& netmask1) ++ int ndNum, ++ const Ipv4Address& addr1, ++ const Ipv4Mask& netmask1) + { +- + // Duplex link is assumed to be subnetted as a /30 + // May run this unnumbered in the future? + Ipv4Mask netmask(netmask1); +@@ -110,7 +109,6 @@ CsmaIpv4Topology::AddIpv4Address(PtrSetAddress (index1, addr1); + ip1->SetNetworkMask (index1, netmask); + ip1->SetUp (index1); +- + } + + void +@@ -133,7 +131,7 @@ CsmaIpv4Topology::AddIpv4Routes ( + found = true; + } + } +- NS_ASSERT(found); ++ NS_ASSERT (found); + + uint32_t index2 = 0; + found = false; +@@ -145,7 +143,7 @@ CsmaIpv4Topology::AddIpv4Routes ( + found = true; + } + } +- NS_ASSERT(found); ++ NS_ASSERT (found); + + ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1); + ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); +diff -r 31cb0668defd -r 25fa26a6533e src/internet-node/arp-ipv4-interface.cc +--- a/src/internet-node/arp-ipv4-interface.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -31,18 +31,26 @@ + #include "ipv4-l3-protocol.h" + #include "arp-l3-protocol.h" + ++NS_DEBUG_COMPONENT_DEFINE ("ArpIpv4Interface"); ++ + namespace ns3 { + + ArpIpv4Interface::ArpIpv4Interface (Ptr node, Ptr device) + : Ipv4Interface (device), + m_node (node) +-{} ++{ ++ NS_DEBUG ("ArpIpv4Interface::ArpIpv4Interface ()"); ++} ++ + ArpIpv4Interface::~ArpIpv4Interface () +-{} ++{ ++ NS_DEBUG ("ArpIpv4Interface::~ArpIpv4Interface ()"); ++} + + TraceResolver * + ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) + { ++ NS_DEBUG ("ArpIpv4Interface::DoCreateTraceResolver ()"); + CompositeTraceResolver *resolver = new CompositeTraceResolver (context); + if (GetDevice () != 0) + { +@@ -56,31 +64,41 @@ void + void + ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) + { ++ NS_DEBUG ("ArpIpv4Interface::SendTo (" << &p << ", " << dest << ")"); ++ + NS_ASSERT (GetDevice () != 0); + if (GetDevice ()->NeedsArp ()) + { +- Ptr arp = m_node->QueryInterface (ArpL3Protocol::iid); ++ NS_DEBUG ("ArpIpv4Interface::SendTo (): Needs ARP"); ++ Ptr arp = ++ m_node->QueryInterface (ArpL3Protocol::iid); + Address hardwareDestination; + bool found; + + if (dest.IsBroadcast ()) + { ++ NS_DEBUG ("ArpIpv4Interface::SendTo (): IsBroadcast"); + hardwareDestination = GetDevice ()->GetBroadcast (); + found = true; + } + else + { ++ NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup"); + found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination); + } + + if (found) + { +- GetDevice ()->Send (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER); ++ NS_DEBUG ("ArpIpv4Interface::SendTo (): Address Resolved. Send."); ++ GetDevice ()->Send (p, hardwareDestination, ++ Ipv4L3Protocol::PROT_NUMBER); + } + } + else + { +- GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER); ++ NS_DEBUG ("ArpIpv4Interface::SendTo (): Doesn't need ARP"); ++ GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), ++ Ipv4L3Protocol::PROT_NUMBER); + } + } + +diff -r 31cb0668defd -r 25fa26a6533e src/internet-node/ipv4-interface.cc +--- a/src/internet-node/ipv4-interface.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/src/internet-node/ipv4-interface.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -22,6 +22,9 @@ + #include "ipv4-interface.h" + #include "ns3/ipv4-address.h" + #include "ns3/net-device.h" ++#include "ns3/debug.h" ++ ++NS_DEBUG_COMPONENT_DEFINE ("Ipv4Interface"); + + namespace ns3 { + +@@ -34,56 +37,72 @@ Ipv4Interface::Ipv4Interface (Ptr nd) + : m_netdevice (nd), + m_ifup(false) +-{} ++{ ++ NS_DEBUG ("Ipv4Interface::Ipv4Interface (" << &nd << ")"); ++} + + Ipv4Interface::~Ipv4Interface () +-{} ++{ ++ NS_DEBUG ("Ipv4Interface::~Ipv4Interface ()"); ++} + + Ptr + Ipv4Interface::GetDevice (void) const + { ++ NS_DEBUG ("Ipv4Interface::GetDevice ()"); + return m_netdevice; + } + + TraceResolver * + Ipv4Interface::CreateTraceResolver (TraceContext const &context) + { ++ NS_DEBUG ("Ipv4Interface::CreateTraceResolver (" << &context << ")"); + return DoCreateTraceResolver (context); + } + + void + Ipv4Interface::SetAddress (Ipv4Address a) + { ++ NS_DEBUG ("Ipv4Interface::SetAddress (" << a << ")"); + m_address = a; + } ++ + void + Ipv4Interface::SetNetworkMask (Ipv4Mask mask) + { ++ NS_DEBUG ("Ipv4Interface::SetMask (" << mask << ")"); + m_netmask = mask; + } + + Ipv4Address + Ipv4Interface::GetBroadcast (void) const + { ++ NS_DEBUG ("Ipv4Interface::GetBroadcast ()"); ++ + uint32_t mask = m_netmask.GetHostOrder (); + uint32_t address = m_address.GetHostOrder (); + Ipv4Address broadcast = Ipv4Address (address | (~mask)); + return broadcast; + } ++ + Ipv4Mask + Ipv4Interface::GetNetworkMask (void) const + { ++ NS_DEBUG ("Ipv4Interface::GetNetworkMask ()"); + return m_netmask; + } ++ + Ipv4Address + Ipv4Interface::GetAddress (void) const + { ++ NS_DEBUG ("Ipv4Interface::Address ()"); + return m_address; + } + + uint16_t + Ipv4Interface::GetMtu (void) const + { ++ NS_DEBUG ("Ipv4Interface::GetMtu ()"); + if (m_netdevice == 0) + { + uint32_t mtu = (1<<16) - 1; +@@ -92,32 +111,36 @@ Ipv4Interface::GetMtu (void) const + return m_netdevice->GetMtu (); + } + +- /** +- * These are IP interface states and may be distinct from +- * NetDevice states, such as found in real implementations +- * (where the device may be down but IP interface state is still up). +- */ ++/** ++ * These are IP interface states and may be distinct from ++ * NetDevice states, such as found in real implementations ++ * (where the device may be down but IP interface state is still up). ++ */ + bool + Ipv4Interface::IsUp (void) const + { ++ NS_DEBUG ("Ipv4Interface::IsUp ()"); + return m_ifup; + } + + bool + Ipv4Interface::IsDown (void) const + { ++ NS_DEBUG ("Ipv4Interface::IsDown ()"); + return !m_ifup; + } + + void + Ipv4Interface::SetUp (void) + { ++ NS_DEBUG ("Ipv4Interface::SetUp ()"); + m_ifup = true; + } + + void + Ipv4Interface::SetDown (void) + { ++ NS_DEBUG ("Ipv4Interface::SetDown ()"); + m_ifup = false; + } + +@@ -125,7 +148,10 @@ void + void + Ipv4Interface::Send(Packet p, Ipv4Address dest) + { ++ NS_DEBUG ("Ipv4Interface::Send ()"); ++ + if (IsUp()) { ++ NS_DEBUG ("Ipv4Interface::Send (): SendTo ()"); + SendTo(p, dest); + } + } +diff -r 31cb0668defd -r 25fa26a6533e src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -494,24 +494,31 @@ Ipv4L3Protocol::SendRealOut (bool found, + + if (!found) + { +- NS_DEBUG ("no route to host. drop."); ++ NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): No route to host. Drop."); + m_dropTrace (packet); + return; + } ++ ++ NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send via interface " << ++ route.GetInterface ()); ++ + packet.AddHeader (ipHeader); + Ipv4Interface *outInterface = GetInterface (route.GetInterface ()); + NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ()); + m_txTrace (packet, route.GetInterface ()); + if (route.IsGateway ()) + { ++ NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send to gateway " << ++ route.GetGateway ()); + outInterface->Send (packet, route.GetGateway ()); + } + else + { ++ NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send to destination " << ++ ipHeader.GetDestination ()); + outInterface->Send (packet, ipHeader.GetDestination ()); + } + } +- + + bool + Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) +@@ -524,7 +531,8 @@ Ipv4L3Protocol::Forwarding (Packet const + { + if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ())) + { +- NS_DEBUG ("for me 1"); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): " ++ "For me (destination match)"); + return false; + } + } +@@ -537,7 +545,8 @@ Ipv4L3Protocol::Forwarding (Packet const + { + if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) + { +- NS_DEBUG ("for me 2"); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): " ++ "For me (interface broadcast address)"); + return false; + } + break; +@@ -546,25 +555,30 @@ Ipv4L3Protocol::Forwarding (Packet const + + if (ipHeader.GetDestination ().IsBroadcast ()) + { +- NS_DEBUG ("for me 3"); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): " ++ "For me (Ipv4Addr broadcast address)"); + return false; + } ++ + if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ())) + { +- NS_DEBUG ("for me 4"); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): " ++ "For me (Ipv4Addr any address)"); + return false; + } ++ + if (ipHeader.GetTtl () == 1) + { + // Should send ttl expired here + // XXX +- NS_DEBUG ("not for me -- ttl expired. drop."); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): " ++ "Not for me (TTL expired). Drop"); + m_dropTrace (packet); + return true; + } + ipHeader.SetTtl (ipHeader.GetTtl () - 1); + +- NS_DEBUG ("forwarding."); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): Forwarding packet."); + Lookup (ipHeader, packet, + MakeCallback (&Ipv4L3Protocol::SendRealOut, this)); + // +@@ -578,12 +592,13 @@ Ipv4L3Protocol::Forwarding (Packet const + if ((*i).first.IsEqual (ipHeader.GetSource ()) && + (*i).second.IsEqual (ipHeader.GetDestination ())) + { +- NS_DEBUG ("for me 5"); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): " ++ "For me (Joined multicast group)"); + return false; + } + } + +- NS_DEBUG ("not for me."); ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (): Not for me."); + return true; + } + +diff -r 31cb0668defd -r 25fa26a6533e src/internet-node/ipv4-loopback-interface.cc +--- a/src/internet-node/ipv4-loopback-interface.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/src/internet-node/ipv4-loopback-interface.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -19,6 +19,8 @@ + * Authors: + * Mathieu Lacage , + */ ++ ++#include "ns3/debug.h" + #include "ns3/empty-trace-resolver.h" + #include "ns3/net-device.h" + #include "ns3/node.h" +@@ -26,26 +28,40 @@ + #include "ipv4-loopback-interface.h" + #include "ipv4-l3-protocol.h" + ++NS_DEBUG_COMPONENT_DEFINE ("Ipv4LoopbackInterface"); ++ + namespace ns3 { + + Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr node) + : Ipv4Interface (0), + m_node (node) +-{} ++{ ++ NS_DEBUG("Ipv4LoopbackInterface::Ipv4LoopbackInterface ()"); ++} ++ + Ipv4LoopbackInterface::~Ipv4LoopbackInterface () +-{} ++{ ++ NS_DEBUG("Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()"); ++} + + TraceResolver * + Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context) + { ++ NS_DEBUG("Ipv4LoopbackInterface::DoCreateTraceResolver ()"); + return new EmptyTraceResolver (context); + } + + void + Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest) + { +- Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); +- ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, Eui48Address ("ff:ff:ff:ff:ff:ff")); ++ NS_DEBUG("Ipv4LoopbackInterface::SendTo (" << &packet << ", " << ++ dest << ")"); ++ ++ Ptr ipv4 = ++ m_node->QueryInterface (Ipv4L3Protocol::iid); ++ ++ ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, ++ Eui48Address ("ff:ff:ff:ff:ff:ff")); + } + + }//namespace ns3 +diff -r 31cb0668defd -r 25fa26a6533e src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Sun Aug 12 15:51:12 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Sun Aug 12 22:41:24 2007 -0700 +@@ -26,7 +26,6 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRo + NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting"); + + namespace ns3 { +- + + void + Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, +@@ -325,7 +324,6 @@ Ipv4StaticRouting::RequestRoute (Ipv4Hea + + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " << + ipHeader.GetDestination ()); +- + // + // 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. +@@ -334,12 +332,15 @@ Ipv4StaticRouting::RequestRoute (Ipv4Hea + ipHeader.GetDestination ()); + if (mRoute) + { ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast route"); + for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) + { + Packet p = packet; + Ipv4Route route = + Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), + mRoute->GetOutputInterface(i)); ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " ++ "Send via interface " << mRoute->GetOutputInterface(i)); + routeReply (true, route, p, ipHeader); + return true; + } +@@ -347,6 +348,7 @@ Ipv4StaticRouting::RequestRoute (Ipv4Hea + // + // See if this is a unicast packet we have a route for. + // ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast route"); + Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); + if (route != 0) + { + +changeset: 1283:3760d52ef5d1 +parent: 1280:25fa26a6533e +parent: 1282:03ab1b7ad2d0 +user: Craig Dowell +date: Sun Aug 12 22:43:25 2007 -0700 +summary: branch merge + +diff -r 25fa26a6533e -r 3760d52ef5d1 examples/mixed-global-routing.cc +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/examples/mixed-global-routing.cc Sun Aug 12 22:43:25 2007 -0700 +@@ -0,0 +1,199 @@ ++/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ ++/* ++ * 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 ++ * ++ */ ++ ++// This script exercises global routing code in a mixed point-to-point ++// and csma/cd environment ++// ++// Network topology ++// ++// n0 ++// \ p-p ++// \ (shared csma/cd) ++// n2 -------------------------n3 ++// / | | ++// / p-p n4 n5 ---------- n6 ++// n1 p-p ++// ++// - CBR/UDP flows from n0 to n6 ++// - Tracing of queues and packet receptions to file "mixed-global-routing.tr" ++ ++#include ++#include ++#include ++#include ++ ++#include "ns3/debug.h" ++ ++#include "ns3/command-line.h" ++#include "ns3/default-value.h" ++#include "ns3/ptr.h" ++#include "ns3/random-variable.h" ++ ++#include "ns3/simulator.h" ++#include "ns3/nstime.h" ++#include "ns3/data-rate.h" ++ ++#include "ns3/ascii-trace.h" ++#include "ns3/pcap-trace.h" ++#include "ns3/internet-node.h" ++#include "ns3/point-to-point-channel.h" ++#include "ns3/point-to-point-net-device.h" ++#include "ns3/csma-channel.h" ++#include "ns3/csma-net-device.h" ++#include "ns3/csma-topology.h" ++#include "ns3/csma-ipv4-topology.h" ++#include "ns3/eui48-address.h" ++#include "ns3/ipv4-address.h" ++#include "ns3/ipv4.h" ++#include "ns3/socket.h" ++#include "ns3/inet-socket-address.h" ++#include "ns3/ipv4-route.h" ++#include "ns3/point-to-point-topology.h" ++#include "ns3/onoff-application.h" ++#include "ns3/global-route-manager.h" ++ ++using namespace ns3; ++ ++int main (int argc, char *argv[]) ++{ ++ ++ // Users may find it convenient to turn on explicit debugging ++ // for selected modules; the below lines suggest how to do this ++#if 0 ++ DebugComponentEnable ("Object"); ++ DebugComponentEnable ("Queue"); ++ DebugComponentEnable ("DropTailQueue"); ++ DebugComponentEnable ("Channel"); ++ DebugComponentEnable ("PointToPointChannel"); ++ DebugComponentEnable ("PointToPointNetDevice"); ++ DebugComponentEnable ("GlobalRouter"); ++ DebugComponentEnable ("GlobalRouteManager"); ++#endif ++ ++ // Set up some default values for the simulation. Use the Bind () ++ // technique to tell the system what subclass of Queue to use, ++ // and what the queue limit is ++ ++ // The below DefaultValue::Bind command tells the queue factory which ++ // class to instantiate, when the queue factory is invoked in the ++ // topology code ++ DefaultValue::Bind ("Queue", "DropTailQueue"); ++ ++ DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); ++ DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); ++ ++ //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30); ++ ++ // Allow the user to override any of the defaults and the above ++ // Bind ()s at run-time, via command-line arguments ++ CommandLine::Parse (argc, argv); ++ ++ Ptr n0 = Create (); ++ Ptr n1 = Create (); ++ Ptr n2 = Create (); ++ Ptr n3 = Create (); ++ Ptr n4 = Create (); ++ Ptr n5 = Create (); ++ Ptr n6 = Create (); ++ ++ // We create the channels first without any IP addressing information ++ Ptr channel0 = ++ PointToPointTopology::AddPointToPointLink ( ++ n0, n2, DataRate (5000000), MilliSeconds (2)); ++ ++ Ptr channel1 = ++ PointToPointTopology::AddPointToPointLink ( ++ n1, n2, DataRate (5000000), MilliSeconds (2)); ++ ++ Ptr channel2 = ++ PointToPointTopology::AddPointToPointLink ( ++ n5, n6, DataRate (1500000), MilliSeconds (10)); ++ ++ // We create the channels first without any IP addressing information ++ Ptr channelc0 = ++ CsmaTopology::CreateCsmaChannel( ++ DataRate(5000000), MilliSeconds(2)); ++ ++ uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0, ++ Eui48Address("10:54:23:54:23:50")); ++ uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0, ++ Eui48Address("10:54:23:54:23:51")); ++ uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0, ++ Eui48Address("10:54:23:54:23:52")); ++ uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0, ++ Eui48Address("10:54:23:54:23:53")); ++ ++ // Later, we add IP addresses. ++ PointToPointTopology::AddIpv4Addresses ( ++ channel0, n0, Ipv4Address ("10.1.1.1"), ++ n2, Ipv4Address ("10.1.1.2")); ++ ++ PointToPointTopology::AddIpv4Addresses ( ++ channel1, n1, Ipv4Address ("10.1.2.1"), ++ n2, Ipv4Address ("10.1.2.2")); ++ ++ PointToPointTopology::AddIpv4Addresses ( ++ channel2, n5, Ipv4Address ("10.1.3.1"), ++ n6, Ipv4Address ("10.1.3.2")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n2, n2ifIndex, Ipv4Address("10.250.1.1"), Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n3, n3ifIndex, Ipv4Address("10.250.1.2"), Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n4, n4ifIndex, Ipv4Address("10.250.1.3"), Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address ( ++ n5, n5ifIndex, Ipv4Address("10.250.1.4"), Ipv4Mask("255.255.255.0")); ++ ++ // Create router nodes, initialize routing database and set up the routing ++ // tables in the nodes. ++ GlobalRouteManager::PopulateRoutingTables (); ++ ++ // Create the OnOff application to send UDP datagrams of size ++ // 210 bytes at a rate of 448 Kb/s ++ Ptr ooff = Create ( ++ n0, ++ InetSocketAddress ("10.1.3.2", 80), ++ "Udp", ++ ConstantVariable (1), ++ ConstantVariable (0), ++ DataRate("300bps"), ++ 50); ++ // Start the application ++ ooff->Start (Seconds (1.0)); ++ ooff->Stop (Seconds (10.0)); ++ ++ // Configure tracing of all enqueue, dequeue, and NetDevice receive events ++ // Trace output will be sent to the simple-global-routing.tr file ++ AsciiTrace asciitrace ("mixed-global-routing.tr"); ++ asciitrace.TraceAllQueues (); ++ asciitrace.TraceAllNetDeviceRx (); ++ ++ // Also configure some tcpdump traces; each interface will be traced ++ // The output files will be named simple-p2p.pcap-- ++ // and can be read by the "tcpdump -r" command (use "-tt" option to ++ // display timestamps correctly) ++ PcapTrace pcaptrace ("mixed-global-routing.pcap"); ++ pcaptrace.TraceAllIp (); ++ ++ Simulator::Run (); ++ ++ Simulator::Destroy (); ++} +diff -r 25fa26a6533e -r 3760d52ef5d1 examples/wscript +--- a/examples/wscript Sun Aug 12 22:41:24 2007 -0700 ++++ b/examples/wscript Sun Aug 12 22:43:25 2007 -0700 +@@ -22,3 +22,6 @@ def build(bld): + ['csma', 'internet-node']) + obj.source = 'csma-multicast.cc' + ++ obj = bld.create_ns3_program( 'mixed-global-routing', ++ ['point-to-point', 'internet-node', 'global-routing' , 'csma-cd']) ++ obj.source = 'mixed-global-routing.cc' +diff -r 25fa26a6533e -r 3760d52ef5d1 src/devices/csma/csma-net-device.cc +--- a/src/devices/csma/csma-net-device.cc Sun Aug 12 22:41:24 2007 -0700 ++++ b/src/devices/csma/csma-net-device.cc Sun Aug 12 22:43:25 2007 -0700 +@@ -133,7 +133,6 @@ CsmaNetDevice::Init(bool sendEnable, boo + + EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); + EnableMulticast(); +- EnablePointToPoint(); + + SetSendEnable (sendEnable); + SetReceiveEnable (receiveEnable); +diff -r 25fa26a6533e -r 3760d52ef5d1 src/routing/global-routing/global-route-manager-impl.cc +--- a/src/routing/global-routing/global-route-manager-impl.cc Sun Aug 12 22:41:24 2007 -0700 ++++ b/src/routing/global-routing/global-route-manager-impl.cc Sun Aug 12 22:43:25 2007 -0700 +@@ -48,8 +48,7 @@ SPFVertex::SPFVertex () : + { + } + +-SPFVertex::SPFVertex (GlobalRouterLSA* lsa) : +- m_vertexType (VertexRouter), ++SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) : + m_vertexId (lsa->GetLinkStateId ()), + m_lsa (lsa), + m_distanceFromRoot (SPF_INFINITY), +@@ -58,6 +57,16 @@ SPFVertex::SPFVertex (GlobalRouterLSA* l + m_parent (0), + m_children () + { ++ if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) ++ { ++ NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexRouter"); ++ m_vertexType = SPFVertex::VertexRouter; ++ } ++ else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA) ++ { ++ NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexNetwork"); ++ m_vertexType = SPFVertex::VertexNetwork; ++ } + } + + SPFVertex::~SPFVertex () +@@ -99,12 +108,12 @@ SPFVertex::GetVertexId (void) const + } + + void +-SPFVertex::SetLSA (GlobalRouterLSA* lsa) ++SPFVertex::SetLSA (GlobalRoutingLSA* lsa) + { + m_lsa = lsa; + } + +- GlobalRouterLSA* ++ GlobalRoutingLSA* + SPFVertex::GetLSA (void) const + { + return m_lsa; +@@ -210,7 +219,7 @@ GlobalRouteManagerLSDB::~GlobalRouteMana + for (i= m_database.begin (); i!= m_database.end (); i++) + { + NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():free LSA"); +- GlobalRouterLSA* temp = i->second; ++ GlobalRoutingLSA* temp = i->second; + delete temp; + } + NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB (): clear map"); +@@ -225,19 +234,19 @@ GlobalRouteManagerLSDB::Initialize () + LSDBMap_t::iterator i; + for (i= m_database.begin (); i!= m_database.end (); i++) + { +- GlobalRouterLSA* temp = i->second; +- temp->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED); ++ GlobalRoutingLSA* temp = i->second; ++ temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); + } + } + + void +-GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRouterLSA* lsa) ++GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa) + { + NS_DEBUG ("GlobalRouteManagerLSDB::Insert ()"); + m_database.insert (LSDBPair_t (addr, lsa)); + } + +- GlobalRouterLSA* ++ GlobalRoutingLSA* + GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const + { + NS_DEBUG ("GlobalRouteManagerLSDB::GetLSA ()"); +@@ -252,6 +261,31 @@ GlobalRouteManagerLSDB::GetLSA (Ipv4Addr + return i->second; + } + } ++ return 0; ++} ++ ++ GlobalRoutingLSA* ++GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const ++{ ++ NS_DEBUG ("GlobalRouteManagerLSDB::GetLSAByLinkData ()"); ++// ++// 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; + } + +@@ -359,13 +393,12 @@ GlobalRouteManagerImpl::BuildGlobalRouti + + for (uint32_t j = 0; j < numLSAs; ++j) + { +- GlobalRouterLSA* lsa = new GlobalRouterLSA (); ++ GlobalRoutingLSA* lsa = new GlobalRoutingLSA (); + // + // This is the call to actually fetch a Link State Advertisement from the + // router. + // + rtr->GetLSA (j, *lsa); +- NS_DEBUG ("LSA " << j); + NS_DEBUG (*lsa); + // + // Write the newly discovered link state advertisement to the database. +@@ -453,52 +486,86 @@ GlobalRouteManagerImpl::SPFNext (SPFVert + GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) + { + SPFVertex* w = 0; +- GlobalRouterLSA* w_lsa = 0; ++ GlobalRoutingLSA* w_lsa = 0; ++ GlobalRoutingLinkRecord *l = 0; + uint32_t distance = 0; ++ uint32_t numRecordsInVertex = 0; + + NS_DEBUG ("GlobalRouteManagerImpl::SPFNext ()"); +-// +-// Always true for now, since all our LSAs are RouterLSAs. +-// +- if (v->GetVertexType () == SPFVertex::VertexRouter) +- { +- if (true) ++ ++// 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_DEBUG ("SPFNext: Examining " << v->GetVertexId () << "'s " << + v->GetLSA ()->GetNLinkRecords () << " link records"); +-// +-// Walk the list of link records in the link state advertisement associated +-// with the "current" router (represented by vertex ). +-// +- for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i) +- { + // + // (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. + // +- GlobalRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); +- if (l->GetLinkType () == GlobalRouterLinkRecord::StubNetwork) +- { +- NS_DEBUG ("SPFNext: Found a Stub record to " << +- l->GetLinkId ()); +- continue; +- } ++ l = v->GetLSA ()->GetLinkRecord (i); ++ if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork) ++ { ++ NS_DEBUG ("SPFNext: 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 () == GlobalRouterLinkRecord::PointToPoint) +- { ++ if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint) ++ { + // + // Lookup the link state advertisement of the new link -- we call it in + // the link state database. + // +- w_lsa = m_lsdb->GetLSA (l->GetLinkId ()); +- NS_ASSERT (w_lsa); +- NS_DEBUG ("SPFNext: Found a P2P record from " << +- v->GetVertexId () << " to " << w_lsa->GetLinkStateId ()); ++ w_lsa = m_lsdb->GetLSA (l->GetLinkId ()); ++ NS_ASSERT (w_lsa); ++ NS_DEBUG ("SPFNext: 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_DEBUG ("SPFNext: 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_DEBUG ("SPFNext: 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. +@@ -506,57 +573,56 @@ GlobalRouteManagerImpl::SPFNext (SPFVert + // 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 () == +- GlobalRouterLSA::LSA_SPF_IN_SPFTREE) +- { +- NS_DEBUG ("SPFNext: Skipping-> LSA "<< +- w_lsa->GetLinkStateId () << " already in SPF tree"); +- continue; +- } +-// +-// The link is to a router we haven't dealt with yet. ++ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE) ++ { ++ NS_DEBUG ("SPFNext: 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. + // +- distance = v->GetDistanceFromRoot () + l->GetMetric (); +- +- NS_DEBUG ("SPFNext: Considering w_lsa " << +- w_lsa->GetLinkStateId ()); +- +- if (w_lsa->GetStatus () == +- GlobalRouterLSA::LSA_SPF_NOT_EXPLORED) +- { +-// +-// If we haven't yet considered the link represented by we have to create +-// a new SPFVertex to represent it. +-// +- w = new SPFVertex (w_lsa); +-// ++ if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA) ++ { ++ distance = v->GetDistanceFromRoot () + l->GetMetric (); ++ } ++ else ++ { ++ distance = v->GetDistanceFromRoot (); ++ } ++ ++ NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ()); ++ ++// Is there already vertex w in candidate list? ++ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED) ++ { ++ ++// prepare vertex w ++ w = new SPFVertex (w_lsa); ++// Calculate nexthop to w + // We need to figure out how to actually get to the new router represented + // by . 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. + // +- if (SPFNexthopCalculation (v, w, l, distance)) +- { +- w_lsa->SetStatus ( +- GlobalRouterLSA::LSA_SPF_CANDIDATE); ++ 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_DEBUG ("SPFNext: Pushing " << +- w->GetVertexId () << ", parent vertexId: " << +- v->GetVertexId ()); +- } +- } +- } else if (w_lsa->GetStatus () == +- GlobalRouterLSA::LSA_SPF_CANDIDATE) +- { ++ candidate.Push (w); ++ NS_DEBUG ("SPFNext: Pushing " << ++ w->GetVertexId () << ", parent vertexId: " << ++ v->GetVertexId ()); ++ } ++ } ++ else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE) ++ { + // + // We have already considered the link represented by . What wse have to + // do now is to decide if this new router represents a route with a shorter +@@ -564,23 +630,23 @@ GlobalRouteManagerImpl::SPFNext (SPFVert + // + // So, locate the vertex in the candidate queue and take a look at the + // distance. +- w = candidate.Find (w_lsa->GetLinkStateId ()); +- if (w->GetDistanceFromRoot () < distance) +- { ++ w = candidate.Find (w_lsa->GetLinkStateId ()); ++ if (w->GetDistanceFromRoot () < distance) ++ { + // + // This is not a shorter path, so don't do anything. + // +- continue; +- } +- else if (w->GetDistanceFromRoot () == distance) +- { ++ continue; ++ } ++ else if (w->GetDistanceFromRoot () == distance) ++ { + // + // This path is one with an equal cost. Do nothing for now -- we're not doing + // equal-cost multipath cases yet. + // +- } +- else +- { ++ } ++ else ++ { + // + // this path represents a new, lower-cost path to (the vertex we found in + // the current link record of the link state advertisement of the current root +@@ -589,27 +655,26 @@ GlobalRouteManagerImpl::SPFNext (SPFVert + // 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, w, l, distance)) +- { ++ if (SPFNexthopCalculation (v, w, l, distance)) ++ { + // + // If we've changed the cost to get to the vertex represented by , we + // must reorder the priority queue keyed to that cost. + // +- candidate.Reorder (); +- } +- } +- } // point-to-point +- } // for loop +- } +- } ++ 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_next_hop_calculation() 16.1.1. + // +-// Calculate the next hop IP address and the outgoing interface required to +-// get packets from the root through (parent) to vertex (destination), +-// over a given distance. ++// 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 + // +@@ -617,10 +682,19 @@ GlobalRouteManagerImpl::SPFNexthopCalcul + GlobalRouteManagerImpl::SPFNexthopCalculation ( + SPFVertex* v, + SPFVertex* w, +- GlobalRouterLinkRecord* l, ++ GlobalRoutingLinkRecord* l, + uint32_t distance) + { + NS_DEBUG ("GlobalRouteManagerImpl::SPFNexthopCalculation ()"); ++ ++// 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 +@@ -669,7 +743,8 @@ GlobalRouteManagerImpl::SPFNexthopCalcul + // return the link record describing the link from to . Think of it as + // SPFGetLink. + // +- GlobalRouterLinkRecord *linkRemote = 0; ++ NS_ASSERT(l); ++ GlobalRoutingLinkRecord *linkRemote = 0; + linkRemote = SPFGetNextLink (w, v, linkRemote); + // + // At this point, is the Global Router Link Record describing the point- +@@ -695,6 +770,56 @@ GlobalRouteManagerImpl::SPFNexthopCalcul + v->GetVertexId () << " to " << w->GetVertexId () << + " goes through next hop " << w->GetNextHop () << + " via outgoing interface " << w->GetOutgoingInterfaceId ()); ++ } // 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 ++ w->SetOutgoingInterfaceId ( ++ FindOutgoingInterfaceId (w_lsa->GetLinkStateId (), ++ w_lsa->GetNetworkLSANetworkMask () )); ++ w->SetDistanceFromRoot (distance); ++ w->SetParent (v); ++ NS_DEBUG ("SPFNexthopCalculation: Next hop from " << ++ v->GetVertexId () << " to network " << w->GetVertexId () << ++ " via outgoing interface " << w->GetOutgoingInterfaceId ()); ++ 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). ++ */ ++ w->SetNextHop(linkRemote->GetLinkData ()); ++ w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ()); ++ NS_DEBUG ("SPFNexthopCalculation: Next hop from " << ++ v->GetVertexId () << " to " << w->GetVertexId () << ++ " goes through next hop " << w->GetNextHop () << ++ " via outgoing interface " << w->GetOutgoingInterfaceId ()); ++ } ++ } ++ else ++ { ++ w->SetNextHop (v->GetNextHop ()); ++ w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ()); + } + } + else +@@ -736,19 +861,17 @@ GlobalRouteManagerImpl::SPFNexthopCalcul + // to . If prev_link is not NULL, we return a Global Router Link Record + // representing a possible *second* link from to . + // +-// BUGBUG FIXME: This seems to be a bug. Shouldn't this function look for +-// any link records after pre_link and not just after the first? +-// +- GlobalRouterLinkRecord* ++ GlobalRoutingLinkRecord* + GlobalRouteManagerImpl::SPFGetNextLink ( + SPFVertex* v, + SPFVertex* w, +- GlobalRouterLinkRecord* prev_link) ++ GlobalRoutingLinkRecord* prev_link) + { + NS_DEBUG ("GlobalRouteManagerImpl::SPFGetNextLink ()"); + + bool skip = true; +- GlobalRouterLinkRecord* l; ++ bool found_prev_link = false; ++ GlobalRoutingLinkRecord* l; + // + // If prev_link is 0, we are really looking for the first link, not the next + // link. +@@ -756,6 +879,7 @@ GlobalRouteManagerImpl::SPFGetNextLink ( + if (prev_link == 0) + { + skip = false; ++ found_prev_link = true; + } + // + // Iterate through the Global Router Link Records advertised by the vertex +@@ -765,10 +889,6 @@ GlobalRouteManagerImpl::SPFGetNextLink ( + for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i) + { + l = v->GetLSA ()->GetLinkRecord (i); +- if (l->GetLinkType () != GlobalRouterLinkRecord::PointToPoint) +- { +- continue; +- } + // + // 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 +@@ -777,8 +897,16 @@ GlobalRouteManagerImpl::SPFGetNextLink ( + // We're just checking to see if the link is actually the link from to + // . + // +- if (l->GetLinkId () == w->GetVertexId ()) { +- NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " << ++ if (l->GetLinkId () == w->GetVertexId ()) ++ { ++ if (!found_prev_link) ++ { ++ NS_DEBUG ("SPFGetNextLink: Skipping links before prev_link found"); ++ found_prev_link = true; ++ continue; ++ } ++ ++ NS_DEBUG ("SPFGetNextLink: 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 +@@ -849,7 +977,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ip + // + m_spfroot= v; + v->SetDistanceFromRoot (0); +- v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE); ++ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE); + + for (;;) + { +@@ -894,7 +1022,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ip + // Update the status field of the vertex to indicate that it is in the SPF + // tree. + // +- v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE); ++ 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 +@@ -932,7 +1060,18 @@ GlobalRouteManagerImpl::SPFCalculate (Ip + // through its point-to-point links, adding a *host* route to the local IP + // address (at the side) for each of those links. + // +- SPFIntraAddRouter (v); ++ 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). + // +@@ -1026,6 +1165,80 @@ GlobalRouteManagerImpl::FindOutgoingInte + } + + // ++// XXX This should probably be a method on Ipv4 ++// ++// Return the interface index corresponding to a given IP address ++// ++ uint32_t ++GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask) ++{ ++// ++// We have an IP address 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. ++// ++ std::vector >::iterator i = NodeList::Begin (); ++ for (; i != NodeList::End (); i++) ++ { ++ Ptr node = *i; ++ ++ Ptr rtr = ++ node->QueryInterface (GlobalRouter::iid); ++// ++// 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 = node->QueryInterface (Ipv4::iid); ++ NS_ASSERT_MSG (ipv4, ++ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " ++ "QI for 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. ++// ++ for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++) ++ { ++ if (ipv4->GetAddress (i).CombineMask(amask) == ++ a.CombineMask(amask) ) ++ { ++ NS_DEBUG ( ++ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " ++ "Interface match for " << a); ++ return i; ++ } ++ } ++ } ++ } ++// ++// Couldn't find it. ++// ++ return 0; ++} ++ ++// + // 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 +@@ -1109,7 +1322,7 @@ GlobalRouteManagerImpl::SPFIntraAddRoute + // 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. + // +- GlobalRouterLSA *lsa = v->GetLSA (); ++ GlobalRoutingLSA *lsa = v->GetLSA (); + NS_ASSERT_MSG (lsa, + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " + "Expected valid LSA in SPFVertex* v"); +@@ -1128,8 +1341,8 @@ GlobalRouteManagerImpl::SPFIntraAddRoute + // + // We are only concerned about point-to-point links + // +- GlobalRouterLinkRecord *lr = lsa->GetLinkRecord (j); +- if (lr->GetLinkType () != GlobalRouterLinkRecord::PointToPoint) ++ GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j); ++ if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint) + { + continue; + } +@@ -1161,6 +1374,91 @@ GlobalRouteManagerImpl::SPFIntraAddRoute + return; + } + } ++} ++ void ++GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v) ++{ ++ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit ()"); ++ ++ 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_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): " ++ "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. ++// ++ std::vector >::iterator i = NodeList::Begin (); ++ for (; i != NodeList::End (); i++) ++ { ++ Ptr 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 rtr = ++ node->QueryInterface (GlobalRouter::iid); ++ ++ if (rtr == 0) ++ { ++ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): " ++ "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_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): " ++ "Considering router " << rtr->GetRouterId ()); ++ ++ if (rtr->GetRouterId () == routerId) ++ { ++ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): " ++ "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 = node->QueryInterface (Ipv4::iid); ++ NS_ASSERT_MSG (ipv4, ++ "GlobalRouteManagerImpl::SPFIntraAddTransit (): " ++ "QI for 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); ++ ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (), ++ v->GetOutgoingInterfaceId ()); ++ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddNetwork (): " ++ " Node " << node->GetId () << ++ " add network route to " << tempip << ++ " using next hop " << v->GetNextHop () << ++ " via interface " << v->GetOutgoingInterfaceId ()); ++ } ++ } + } + + // Derived from quagga ospf_vertex_add_parents () +@@ -1275,81 +1573,81 @@ GlobalRouteManagerImplTest::RunTests (vo + // link2: 10.1.3.1/30, 10.1.3.2/30 + // + // Router 0 +- GlobalRouterLinkRecord* lr0 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::PointToPoint, ++ GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::PointToPoint, + "0.0.0.2", // router ID 0.0.0.2 + "10.1.1.1", // local ID + 1); // metric + +- GlobalRouterLinkRecord* lr1 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::StubNetwork, ++ GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::StubNetwork, + "10.1.1.1", + "255.255.255.252", + 1); + +- GlobalRouterLSA* lsa0 = new GlobalRouterLSA (); ++ GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA (); + lsa0->SetLinkStateId ("0.0.0.0"); + lsa0->SetAdvertisingRouter ("0.0.0.0"); + lsa0->AddLinkRecord (lr0); + lsa0->AddLinkRecord (lr1); + + // Router 1 +- GlobalRouterLinkRecord* lr2 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::PointToPoint, ++ GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::PointToPoint, + "0.0.0.2", + "10.1.2.1", + 1); + +- GlobalRouterLinkRecord* lr3 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::StubNetwork, ++ GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::StubNetwork, + "10.1.2.1", + "255.255.255.252", + 1); + +- GlobalRouterLSA* lsa1 = new GlobalRouterLSA (); ++ GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA (); + lsa1->SetLinkStateId ("0.0.0.1"); + lsa1->SetAdvertisingRouter ("0.0.0.1"); + lsa1->AddLinkRecord (lr2); + lsa1->AddLinkRecord (lr3); + + // Router 2 +- GlobalRouterLinkRecord* lr4 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::PointToPoint, ++ GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::PointToPoint, + "0.0.0.0", + "10.1.1.2", + 1); + +- GlobalRouterLinkRecord* lr5 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::StubNetwork, ++ GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::StubNetwork, + "10.1.1.2", + "255.255.255.252", + 1); + +- GlobalRouterLinkRecord* lr6 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::PointToPoint, ++ GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::PointToPoint, + "0.0.0.1", + "10.1.2.2", + 1); + +- GlobalRouterLinkRecord* lr7 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::StubNetwork, ++ GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::StubNetwork, + "10.1.2.2", + "255.255.255.252", + 1); + +- GlobalRouterLinkRecord* lr8 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::PointToPoint, ++ GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::PointToPoint, + "0.0.0.3", + "10.1.3.2", + 1); + +- GlobalRouterLinkRecord* lr9 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::StubNetwork, ++ GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::StubNetwork, + "10.1.3.2", + "255.255.255.252", + 1); + +- GlobalRouterLSA* lsa2 = new GlobalRouterLSA (); ++ GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA (); + lsa2->SetLinkStateId ("0.0.0.2"); + lsa2->SetAdvertisingRouter ("0.0.0.2"); + lsa2->AddLinkRecord (lr4); +@@ -1360,19 +1658,19 @@ GlobalRouteManagerImplTest::RunTests (vo + lsa2->AddLinkRecord (lr9); + + // Router 3 +- GlobalRouterLinkRecord* lr10 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::PointToPoint, ++ GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::PointToPoint, + "0.0.0.2", + "10.1.2.1", + 1); + +- GlobalRouterLinkRecord* lr11 = new GlobalRouterLinkRecord ( +- GlobalRouterLinkRecord::StubNetwork, ++ GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord ( ++ GlobalRoutingLinkRecord::StubNetwork, + "10.1.2.1", + "255.255.255.252", + 1); + +- GlobalRouterLSA* lsa3 = new GlobalRouterLSA (); ++ GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA (); + lsa3->SetLinkStateId ("0.0.0.3"); + lsa3->SetAdvertisingRouter ("0.0.0.3"); + lsa3->AddLinkRecord (lr10); +diff -r 25fa26a6533e -r 3760d52ef5d1 src/routing/global-routing/global-route-manager-impl.h +--- a/src/routing/global-routing/global-route-manager-impl.h Sun Aug 12 22:41:24 2007 -0700 ++++ b/src/routing/global-routing/global-route-manager-impl.h Sun Aug 12 22:43:25 2007 -0700 +@@ -102,10 +102,10 @@ public: + * + * @see SPFVertex::SPFVertex () + * @see VertexType +- * @see GlobalRouterLSA ++ * @see GlobalRoutingLSA + * @param lsa The Link State Advertisement used for finding initial values. + */ +- SPFVertex(GlobalRouterLSA* lsa); ++ SPFVertex(GlobalRoutingLSA* lsa); + + /** + * @brief Destroy an SPFVertex (Shortest Path First Vertex). +@@ -181,12 +181,12 @@ public: + * @internal + * + * @see GlobalRouter +- * @see GlobalRouterLSA ++ * @see GlobalRoutingLSA + * @see GlobalRouter::DiscoverLSAs () +- * @returns A pointer to the GlobalRouterLSA found by the router represented ++ * @returns A pointer to the GlobalRoutingLSA found by the router represented + * by this SPFVertex object. + */ +- GlobalRouterLSA* GetLSA (void) const; ++ GlobalRoutingLSA* GetLSA (void) const; + + /** + * @brief Set the Global Router Link State Advertisement returned by the +@@ -196,13 +196,13 @@ public: + * + * @see SPFVertex::GetLSA () + * @see GlobalRouter +- * @see GlobalRouterLSA ++ * @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 GlobalRouterLSA. +- */ +- void SetLSA (GlobalRouterLSA* lsa); ++ * @param lsa A pointer to the GlobalRoutingLSA. ++ */ ++ void SetLSA (GlobalRoutingLSA* lsa); + + /** + * @brief Get the distance from the root vertex to "this" SPFVertex object. +@@ -283,8 +283,8 @@ public: + * SPFVertex." + * + * @see GlobalRouter +- * @see GlobalRouterLSA +- * @see GlobalRouterLinkRecord ++ * @see GlobalRoutingLSA ++ * @see GlobalRoutingLinkRecord + * @returns The interface index to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ +@@ -325,8 +325,8 @@ public: + * by "this" SPFVertex. + * + * @see GlobalRouter +- * @see GlobalRouterLSA +- * @see GlobalRouterLinkRecord ++ * @see GlobalRoutingLSA ++ * @see GlobalRoutingLinkRecord + * @param id The interface index to use when forwarding packets to the host or + * network represented by "this" SPFVertex. + */ +@@ -368,8 +368,8 @@ public: + * by 'this' SPFVertex." + * + * @see GlobalRouter +- * @see GlobalRouterLSA +- * @see GlobalRouterLinkRecord ++ * @see GlobalRoutingLSA ++ * @see GlobalRoutingLinkRecord + * @returns The IP address to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ +@@ -411,8 +411,8 @@ public: + * host represented by 'this' SPFVertex." + * + * @see GlobalRouter +- * @see GlobalRouterLSA +- * @see GlobalRouterLinkRecord ++ * @see GlobalRoutingLSA ++ * @see GlobalRoutingLinkRecord + * @param nextHop The IP address to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ +@@ -543,7 +543,7 @@ private: + private: + VertexType m_vertexType; + Ipv4Address m_vertexId; +- GlobalRouterLSA* m_lsa; ++ GlobalRoutingLSA* m_lsa; + uint32_t m_distanceFromRoot; + uint32_t m_rootOif; + Ipv4Address m_nextHop; +@@ -604,33 +604,47 @@ public: + * State Database. + * @internal + * +- * The IPV4 address and the GlobalRouterLSA given as parameters are converted ++ * The IPV4 address and the GlobalRoutingLSA given as parameters are converted + * to an STL pair and are inserted into the database map. + * +- * @see GlobalRouterLSA ++ * @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, GlobalRouterLSA* lsa); ++ void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa); + + /** + * @brief Look up the Link State Advertisement associated with the given +- * IP Address. ++ * link state ID (address). + * @internal + * + * The database map is searched for the given IPV4 address and corresponding +- * GlobalRouterLSA is returned. +- * +- * @see GlobalRouterLSA ++ * 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. + */ +- GlobalRouterLSA* GetLSA (Ipv4Address addr) const; ++ 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 +@@ -641,14 +655,14 @@ public: + * prior to each SPF calculation to reset the state of the SPFVertex structures + * that will reference the LSAs during the calculation. + * +- * @see GlobalRouterLSA ++ * @see GlobalRoutingLSA + * @see SPFVertex + */ + void Initialize (); + + private: +- typedef std::map LSDBMap_t; +- typedef std::pair LSDBPair_t; ++ typedef std::map LSDBMap_t; ++ typedef std::pair LSDBPair_t; + + LSDBMap_t m_database; + /** +@@ -734,12 +748,14 @@ private: + void SPFCalculate (Ipv4Address root); + void SPFNext (SPFVertex*, CandidateQueue&); + int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, +- GlobalRouterLinkRecord* l, uint32_t distance); ++ GlobalRoutingLinkRecord* l, uint32_t distance); + void SPFVertexAddParent (SPFVertex* v); +- GlobalRouterLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, +- GlobalRouterLinkRecord* prev_link); ++ GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, ++ GlobalRoutingLinkRecord* prev_link); + void SPFIntraAddRouter (SPFVertex* v); ++ void SPFIntraAddTransit (SPFVertex* v); + uint32_t FindOutgoingInterfaceId (Ipv4Address a); ++ uint32_t FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask); + }; + + } // namespace ns3 +diff -r 25fa26a6533e -r 3760d52ef5d1 src/routing/global-routing/global-router-interface.cc +--- a/src/routing/global-routing/global-router-interface.cc Sun Aug 12 22:41:24 2007 -0700 ++++ b/src/routing/global-routing/global-router-interface.cc Sun Aug 12 22:43:25 2007 -0700 +@@ -28,21 +28,21 @@ namespace ns3 { + + // --------------------------------------------------------------------------- + // +-// GlobalRouterLinkRecord Implementation ++// GlobalRoutingLinkRecord Implementation + // + // --------------------------------------------------------------------------- + +-GlobalRouterLinkRecord::GlobalRouterLinkRecord () ++GlobalRoutingLinkRecord::GlobalRoutingLinkRecord () + : + m_linkId ("0.0.0.0"), + m_linkData ("0.0.0.0"), + m_linkType (Unknown), + m_metric (0) + { +- NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord ()"); +-} +- +-GlobalRouterLinkRecord::GlobalRouterLinkRecord ( ++ NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()"); ++} ++ ++GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ( + LinkType linkType, + Ipv4Address linkId, + Ipv4Address linkData, +@@ -53,116 +53,126 @@ GlobalRouterLinkRecord::GlobalRouterLink + m_linkType (linkType), + m_metric (metric) + { +- NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord (" << ++ NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (" << + linkType << ", " << linkId << ", " << linkData << ", " << metric << ")"); + } + +-GlobalRouterLinkRecord::~GlobalRouterLinkRecord () +-{ +- NS_DEBUG("GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()"); ++GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord () ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()"); + } + + Ipv4Address +-GlobalRouterLinkRecord::GetLinkId (void) const +-{ +- NS_DEBUG("GlobalRouterLinkRecord::GetLinkId ()"); ++GlobalRoutingLinkRecord::GetLinkId (void) const ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::GetLinkId ()"); + return m_linkId; + } + + void +-GlobalRouterLinkRecord::SetLinkId (Ipv4Address addr) +-{ +- NS_DEBUG("GlobalRouterLinkRecord::SetLinkId ()"); ++GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr) ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::SetLinkId ()"); + m_linkId = addr; + } + + Ipv4Address +-GlobalRouterLinkRecord::GetLinkData (void) const +-{ +- NS_DEBUG("GlobalRouterLinkRecord::GetLinkData ()"); ++GlobalRoutingLinkRecord::GetLinkData (void) const ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::GetLinkData ()"); + return m_linkData; + } + + void +-GlobalRouterLinkRecord::SetLinkData (Ipv4Address addr) +-{ +- NS_DEBUG("GlobalRouterLinkRecord::SetLinkData ()"); ++GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr) ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::SetLinkData ()"); + m_linkData = addr; + } + +- GlobalRouterLinkRecord::LinkType +-GlobalRouterLinkRecord::GetLinkType (void) const +-{ +- NS_DEBUG("GlobalRouterLinkRecord::GetLinkType ()"); ++ GlobalRoutingLinkRecord::LinkType ++GlobalRoutingLinkRecord::GetLinkType (void) const ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::GetLinkType ()"); + return m_linkType; + } + + void +-GlobalRouterLinkRecord::SetLinkType ( +- GlobalRouterLinkRecord::LinkType linkType) +-{ +- NS_DEBUG("GlobalRouterLinkRecord::SetLinkType ()"); ++GlobalRoutingLinkRecord::SetLinkType ( ++ GlobalRoutingLinkRecord::LinkType linkType) ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::SetLinkType ()"); + m_linkType = linkType; + } + + uint32_t +-GlobalRouterLinkRecord::GetMetric (void) const +-{ +- NS_DEBUG("GlobalRouterLinkRecord::GetMetric ()"); ++GlobalRoutingLinkRecord::GetMetric (void) const ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::GetMetric ()"); + return m_metric; + } + + void +-GlobalRouterLinkRecord::SetMetric (uint32_t metric) +-{ +- NS_DEBUG("GlobalRouterLinkRecord::SetMetric ()"); ++GlobalRoutingLinkRecord::SetMetric (uint32_t metric) ++{ ++ NS_DEBUG("GlobalRoutingLinkRecord::SetMetric ()"); + m_metric = metric; + } + + // --------------------------------------------------------------------------- + // +-// GlobalRouterLSA Implementation ++// GlobalRoutingLSA Implementation + // + // --------------------------------------------------------------------------- + +-GlobalRouterLSA::GlobalRouterLSA() ++GlobalRoutingLSA::GlobalRoutingLSA() + : ++ m_lsType (GlobalRoutingLSA::Unknown), + m_linkStateId("0.0.0.0"), + m_advertisingRtr("0.0.0.0"), + m_linkRecords(), +- m_status(GlobalRouterLSA::LSA_SPF_NOT_EXPLORED) +-{ +- NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA ()"); +-} +- +-GlobalRouterLSA::GlobalRouterLSA ( +- GlobalRouterLSA::SPFStatus status, ++ m_networkLSANetworkMask("0.0.0.0"), ++ m_attachedRouters(), ++ m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED) ++{ ++ NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA ()"); ++} ++ ++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) + { +- NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA (" << status << ", " << ++ NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA (" << status << ", " << + linkStateId << ", " << advertisingRtr << ")"); + } + +-GlobalRouterLSA::GlobalRouterLSA (GlobalRouterLSA& lsa) +- : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_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) + { + NS_ASSERT_MSG(IsEmpty(), +- "GlobalRouterLSA::GlobalRouterLSA (): Non-empty LSA in constructor"); ++ "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor"); + CopyLinkRecords (lsa); + } + +- GlobalRouterLSA& +-GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa) +-{ ++ GlobalRoutingLSA& ++GlobalRoutingLSA::operator= (const 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; + + ClearLinkRecords (); +@@ -171,14 +181,14 @@ GlobalRouterLSA::operator= (const Global + } + + void +-GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa) ++GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa) + { + for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin (); + i != lsa.m_linkRecords.end (); + i++) + { +- GlobalRouterLinkRecord *pSrc = *i; +- GlobalRouterLinkRecord *pDst = new GlobalRouterLinkRecord; ++ GlobalRoutingLinkRecord *pSrc = *i; ++ GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord; + + pDst->SetLinkType (pSrc->GetLinkType ()); + pDst->SetLinkId (pSrc->GetLinkId ()); +@@ -187,48 +197,50 @@ GlobalRouterLSA::CopyLinkRecords (const + m_linkRecords.push_back(pDst); + pDst = 0; + } +-} +- +-GlobalRouterLSA::~GlobalRouterLSA() +-{ +- NS_DEBUG("GlobalRouterLSA::~GlobalRouterLSA ()"); ++ ++ m_attachedRouters = lsa.m_attachedRouters; ++} ++ ++GlobalRoutingLSA::~GlobalRoutingLSA() ++{ ++ NS_DEBUG("GlobalRoutingLSA::~GlobalRoutingLSA ()"); + ClearLinkRecords (); + } + + void +-GlobalRouterLSA::ClearLinkRecords(void) ++GlobalRoutingLSA::ClearLinkRecords(void) + { + for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + i != m_linkRecords.end (); + i++) + { +- NS_DEBUG("GlobalRouterLSA::ClearLinkRecords (): free link record"); +- +- GlobalRouterLinkRecord *p = *i; ++ NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords (): free link record"); ++ ++ GlobalRoutingLinkRecord *p = *i; + delete p; + p = 0; + + *i = 0; + } +- NS_DEBUG("GlobalRouterLSA::ClearLinkRecords(): clear list"); ++ NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords(): clear list"); + m_linkRecords.clear(); + } + + uint32_t +-GlobalRouterLSA::AddLinkRecord (GlobalRouterLinkRecord* lr) ++GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr) + { + m_linkRecords.push_back (lr); + return m_linkRecords.size (); + } + + uint32_t +-GlobalRouterLSA::GetNLinkRecords (void) const ++GlobalRoutingLSA::GetNLinkRecords (void) const + { + return m_linkRecords.size (); + } + +- GlobalRouterLinkRecord * +-GlobalRouterLSA::GetLinkRecord (uint32_t n) const ++ GlobalRoutingLinkRecord * ++GlobalRoutingLSA::GetLinkRecord (uint32_t n) const + { + uint32_t j = 0; + for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin (); +@@ -240,70 +252,146 @@ GlobalRouterLSA::GetLinkRecord (uint32_t + return *i; + } + } +- NS_ASSERT_MSG(false, "GlobalRouterLSA::GetLinkRecord (): invalid index"); ++ NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index"); + return 0; + } + + bool +-GlobalRouterLSA::IsEmpty (void) const ++GlobalRoutingLSA::IsEmpty (void) const + { + return m_linkRecords.size () == 0; + } + ++ GlobalRoutingLSA::LSType ++GlobalRoutingLSA::GetLSType (void) const ++{ ++ return m_lsType; ++} ++ ++ void ++GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ) ++{ ++ m_lsType = typ; ++} ++ + Ipv4Address +-GlobalRouterLSA::GetLinkStateId (void) const ++GlobalRoutingLSA::GetLinkStateId (void) const + { + return m_linkStateId; + } + + void +-GlobalRouterLSA::SetLinkStateId (Ipv4Address addr) ++GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr) + { + m_linkStateId = addr; + } + + Ipv4Address +-GlobalRouterLSA::GetAdvertisingRouter (void) const ++GlobalRoutingLSA::GetAdvertisingRouter (void) const + { + return m_advertisingRtr; + } + + void +-GlobalRouterLSA::SetAdvertisingRouter (Ipv4Address addr) ++GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr) + { + m_advertisingRtr = addr; + } + +- GlobalRouterLSA::SPFStatus +-GlobalRouterLSA::GetStatus (void) const ++ void ++GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask) ++{ ++ m_networkLSANetworkMask = mask; ++} ++ ++ Ipv4Mask ++GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const ++{ ++ return m_networkLSANetworkMask; ++} ++ ++ GlobalRoutingLSA::SPFStatus ++GlobalRoutingLSA::GetStatus (void) const + { + return m_status; + } + +- void +-GlobalRouterLSA::SetStatus (GlobalRouterLSA::SPFStatus status) ++ uint32_t ++GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr) ++{ ++ m_attachedRouters.push_back (addr); ++ return m_attachedRouters.size (); ++} ++ ++ uint32_t ++GlobalRoutingLSA::GetNAttachedRouters (void) const ++{ ++ return m_attachedRouters.size (); ++} ++ ++ Ipv4Address ++GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const ++{ ++ 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) + { + m_status = status; + } + + void +-GlobalRouterLSA::Print (std::ostream &os) const +-{ +- os << "m_linkStateId = " << m_linkStateId << std::endl << ++GlobalRoutingLSA::Print (std::ostream &os) const ++{ ++ os << "m_lsType = " << m_lsType << std::endl << ++ "m_linkStateId = " << m_linkStateId << std::endl << + "m_advertisingRtr = " << m_advertisingRtr << std::endl; + +- for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin (); +- i != m_linkRecords.end (); +- i++) +- { +- GlobalRouterLinkRecord *p = *i; ++ if (m_lsType == GlobalRoutingLSA::RouterLSA) ++ { ++ for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin (); ++ i != m_linkRecords.end (); ++ i++) ++ { ++ GlobalRoutingLinkRecord *p = *i; ++ os << "----------" << std::endl; ++ os << "m_linkId = " << p->GetLinkId () << std::endl; ++ os << "m_linkData = " << p->GetLinkData () << std::endl; ++ } ++ } ++ else if (m_lsType == GlobalRoutingLSA::NetworkLSA) ++ { + os << "----------" << std::endl; +- os << "m_linkId = " << p->GetLinkId () << std::endl; +- os << "m_linkData = " << p->GetLinkData () << std::endl; +- } +-} +- +-std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa) ++ 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; ++ } ++ } ++ else ++ { ++ NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType); ++ } ++} ++ ++std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa) + { + lsa.Print (os); + return os; +@@ -350,7 +438,7 @@ GlobalRouter::ClearLSAs () + { + NS_DEBUG("GlobalRouter::ClearLSAs (): free LSA"); + +- GlobalRouterLSA *p = *i; ++ GlobalRoutingLSA *p = *i; + delete p; + p = 0; + +@@ -373,11 +461,16 @@ GlobalRouter::GetRouterId (void) const + uint32_t + GlobalRouter::DiscoverLSAs (void) + { +- NS_DEBUG("GlobalRouter::DiscoverLSAs ()"); ++ NS_DEBUG("GlobalRouter::DiscoverLSAs () for node " << m_node->GetId () ); + NS_ASSERT_MSG(m_node, + "GlobalRouter::DiscoverLSAs (): interface not set"); + + ClearLSAs (); ++ ++// While building the router-LSA, keep a list of those NetDevices for ++// which I am the designated router and need to later build a NetworkLSA ++ std::list > listOfDRInterfaces; ++ + // + // 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 +@@ -387,116 +480,250 @@ GlobalRouter::DiscoverLSAs (void) + NS_ASSERT_MSG(ipv4Local, + "GlobalRouter::DiscoverLSAs (): QI for interface failed"); + // +-// We are, for now at least, only going to report RouterLSAs in this method. +-// What this means is that there is going to be one advertisement with some +-// number of link records. This means that GetNumLSAs will actually always +-// return exactly one. +-// +- GlobalRouterLSA *pLSA = new GlobalRouterLSA; ++// Each node originates a Router-LSA ++// ++ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; ++ pLSA->SetLSType (GlobalRoutingLSA::RouterLSA); + pLSA->SetLinkStateId (m_routerId); + pLSA->SetAdvertisingRouter (m_routerId); +- pLSA->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED); ++ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); + // + // We need to 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.). So we have to walk through the list of net devices and +-// pay attention to those that are directly connected to another router through +-// a point-to-point channel. ++// ethernets, etc.). + // + uint32_t numDevices = m_node->GetNDevices(); + NS_DEBUG("GlobalRouter::DiscoverLSAs (): numDevices = " << numDevices); +-// +-// Loop through the devices looking for those connected to a point-to-point +-// channel. +-// + for (uint32_t i = 0; i < numDevices; ++i) + { + Ptr ndLocal = m_node->GetDevice(i); + +- if (!ndLocal->IsPointToPoint ()) +- { +- NS_DEBUG("GlobalRouter::DiscoverLSAs (): non-point-to-point device"); +- continue; +- } +- +- NS_DEBUG("GlobalRouter::DiscoverLSAs (): Point-to-point device"); ++ if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) ++ { ++ NS_DEBUG("GlobalRouter::DiscoverLSAs (): broadcast link"); ++ GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; ++// ++// We need to determine whether we are on a transit or stub network ++// If we find at least one more router on this channel, we are a transit ++// + // + // Now, we have to find the Ipv4 interface whose netdevice is the one we + // just found. This is still the IP on the local side of the channel. There + // is a function to do this used down in the guts of the stack, but it's not + // exported so we had to whip up an equivalent. + // +- uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal); +-// +-// Now that we have the Ipv4 interface index, we can get the address and mask +-// we need. +-// +- Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); +- Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); +- NS_DEBUG("Working with local address " << addrLocal); ++ uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal); ++ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); ++ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); ++ NS_DEBUG("Working with local address " << addrLocal); + // + // Now, we're going to walk over to the remote net device on the other end of + // the point-to-point channel we now know we have. This is where our adjacent + // router (to use OSPF lingo) is running. + // +- Ptr ch = ndLocal->GetChannel(); +- Ptr ndRemote = GetAdjacent(ndLocal, ch); ++ Ptr ch = ndLocal->GetChannel(); ++ uint32_t nDevices = ch->GetNDevices(); ++ if (nDevices == 1) ++ { ++ // This is a stub broadcast interface ++ NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA stub broadcast link"); ++ // XXX in future, need to consider if >1 includes other routers ++ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); ++ // Link ID is IP network number of attached network ++ plr->SetLinkId (addrLocal.CombineMask(maskLocal)); ++ // Link Data is network mask; convert to Ipv4Address ++ Ipv4Address maskLocalAddr; ++ maskLocalAddr.Set(maskLocal.GetHostOrder ()); ++ plr->SetLinkData (maskLocalAddr); ++ // Cost is interface's configured output cost (NOTYET) ++ plr->SetMetric (1); ++ pLSA->AddLinkRecord(plr); ++ plr = 0; ++ continue; ++ } ++ else ++ { ++ NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Broadcast link"); ++ // multiple routers on a broadcast interface ++ // lowest IP address is designated router ++ plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); ++ // Link ID is IP interface address of designated router ++ Ipv4Address desigRtr = ++ FindDesignatedRouterForLink (m_node, ndLocal); ++ if (desigRtr == addrLocal) ++ { ++ listOfDRInterfaces.push_back (ndLocal); ++ NS_DEBUG("GlobalRouter::DiscoverLSAs (): " << ++ m_node->GetId () << " is a DR"); ++ } ++ plr->SetLinkId (desigRtr); ++ // Link Data is router's own IP address ++ plr->SetLinkData (addrLocal); ++ // Cost is interface's configured output cost (NOTYET) ++ plr->SetMetric (1); ++ pLSA->AddLinkRecord (plr); ++ plr = 0; ++ continue; ++ } ++ } ++ else if (ndLocal->IsPointToPoint () ) ++ { ++ NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Point-to-point device"); ++// ++// Now, we have to find the Ipv4 interface whose netdevice is the one we ++// just found. This is still the IP on the local side of the channel. There ++// is a function to do this used down in the guts of the stack, but it's not ++// exported so we had to whip up an equivalent. ++// ++ uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal); ++// ++// Now that we have the Ipv4 interface index, we can get the address and mask ++// we need. ++// ++ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); ++ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); ++ NS_DEBUG("Working with local address " << addrLocal); ++// ++// Now, we're going to walk over to the remote net device on the other end of ++// the point-to-point channel we now know we have. This is where our adjacent ++// router (to use OSPF lingo) is running. ++// ++ Ptr ch = ndLocal->GetChannel(); ++ Ptr 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. + // +- Ptr nodeRemote = ndRemote->GetNode(); +- Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); +- NS_ASSERT_MSG(ipv4Remote, +- "GlobalRouter::DiscoverLSAs (): QI for remote failed"); ++ Ptr nodeRemote = ndRemote->GetNode(); ++ Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); ++ NS_ASSERT_MSG(ipv4Remote, ++ "GlobalRouter::DiscoverLSAs (): QI for remote failed"); + // + // Per the OSPF spec, we're going to need the remote router ID, so we might as + // well get it now. + // +- Ptr srRemote = +- nodeRemote->QueryInterface (GlobalRouter::iid); +- NS_ASSERT_MSG(srRemote, +- "GlobalRouter::DiscoverLSAs (): QI for remote failed"); +- Ipv4Address rtrIdRemote = srRemote->GetRouterId(); +- NS_DEBUG("Working with remote router " << rtrIdRemote); ++ Ptr srRemote = ++ nodeRemote->QueryInterface (GlobalRouter::iid); ++ NS_ASSERT_MSG(srRemote, ++ "GlobalRouter::DiscoverLSAs():QI for remote failed"); ++ Ipv4Address rtrIdRemote = srRemote->GetRouterId(); ++ NS_DEBUG("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 ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote); ++ uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote); + // + // Now that we have the Ipv4 interface, we can get the (remote) address and + // mask we need. + // +- Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote); +- Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); +- NS_DEBUG("Working with remote address " << addrRemote); ++ Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote); ++ Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); ++ NS_DEBUG("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. + // +- GlobalRouterLinkRecord *plr = new GlobalRouterLinkRecord; +- plr->SetLinkType (GlobalRouterLinkRecord::PointToPoint); +- plr->SetLinkId (rtrIdRemote); +- plr->SetLinkData (addrLocal); +- pLSA->AddLinkRecord(plr); +- plr = 0; +- +- plr = new GlobalRouterLinkRecord; +- plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork); +- plr->SetLinkId (addrRemote); +- plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown +- pLSA->AddLinkRecord(plr); +- plr = 0; ++ GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; ++ plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); ++ plr->SetLinkId (rtrIdRemote); ++ plr->SetLinkData (addrLocal); ++ pLSA->AddLinkRecord (plr); ++ plr = 0; ++ ++ plr = new GlobalRoutingLinkRecord; ++ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); ++ plr->SetLinkId (addrRemote); ++ plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown ++ pLSA->AddLinkRecord (plr); ++ plr = 0; ++ } ++ else ++ { ++ NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type"); ++ } ++ + } + // + // The LSA goes on a list of LSAs in case we want to begin exporting other + // kinds of advertisements (than Router LSAs). + m_LSAs.push_back (pLSA); + NS_DEBUG(*pLSA); ++ ++ ++// Now, determine whether we need to build a NetworkLSA ++ if (listOfDRInterfaces.size () > 0) ++ { ++ for (std::list >::iterator i = listOfDRInterfaces.begin (); ++ i != listOfDRInterfaces.end (); i++) ++ { ++// Build one NetworkLSA for each interface that is a DR ++ Ptr ndLocal = *i; ++ uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal); ++ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); ++ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); ++ ++ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; ++ pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA); ++ pLSA->SetLinkStateId (addrLocal); ++ pLSA->SetAdvertisingRouter (m_routerId); ++ pLSA->SetNetworkLSANetworkMask (maskLocal); ++ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); ++// Build list of AttachedRouters ++ Ptr ch = ndLocal->GetChannel(); ++ uint32_t nDevices = ch->GetNDevices(); ++ NS_ASSERT (nDevices); ++ for (uint32_t i = 0; i < nDevices; i++) ++ { ++ Ptr tempNd = ch->GetDevice (i); ++ NS_ASSERT (tempNd); ++ Ptr tempNode = tempNd->GetNode (); ++ uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd); ++ Ptr tempIpv4 = tempNode->QueryInterface (Ipv4::iid); ++ NS_ASSERT (tempIpv4); ++ Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); ++ pLSA->AddAttachedRouter (tempAddr); ++ } ++ m_LSAs.push_back (pLSA); ++ NS_DEBUG(*pLSA); ++ } ++ } ++ + return m_LSAs.size (); ++} ++ ++ Ipv4Address ++GlobalRouter::FindDesignatedRouterForLink (Ptr node, ++ Ptr ndLocal) const ++{ ++ uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal); ++ Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); ++ NS_ASSERT (ipv4Local); ++ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); ++ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); ++ ++ Ptr ch = ndLocal->GetChannel(); ++ uint32_t nDevices = ch->GetNDevices(); ++ NS_ASSERT (nDevices); ++ Ipv4Address lowest = addrLocal; ++ // iterate all NetDevices and return the lowest numbered IP address ++ for (uint32_t i = 0; i < nDevices; i++) ++ { ++ Ptr tempNd = ch->GetDevice (i); ++ NS_ASSERT (tempNd); ++ Ptr tempNode = tempNd->GetNode (); ++ uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd); ++ Ptr tempIpv4 = tempNode->QueryInterface (Ipv4::iid); ++ NS_ASSERT (tempIpv4); ++ Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); ++ if (tempAddr < addrLocal) ++ { ++ addrLocal = tempAddr; ++ } ++ } ++ return addrLocal; + } + + uint32_t +@@ -510,7 +737,7 @@ GlobalRouter::GetNumLSAs (void) const + // Get the nth link state advertisement from this router. + // + bool +-GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const ++GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const + { + NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA"); + // +@@ -525,7 +752,7 @@ GlobalRouter::GetLSA (uint32_t n, Global + { + if (j == n) + { +- GlobalRouterLSA *p = *i; ++ GlobalRoutingLSA *p = *i; + lsa = *p; + return true; + } +diff -r 25fa26a6533e -r 3760d52ef5d1 src/routing/global-routing/global-router-interface.h +--- a/src/routing/global-routing/global-router-interface.h Sun Aug 12 22:41:24 2007 -0700 ++++ b/src/routing/global-routing/global-router-interface.h Sun Aug 12 22:43:25 2007 -0700 +@@ -31,16 +31,16 @@ namespace ns3 { + /** + * @brief A single link record for a link state advertisement. + * +- * The GlobalRouterLinkRecord is modeled after the OSPF link record field of ++ * 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 GlobalRouterLinkRecord ++class GlobalRoutingLinkRecord + { + public: + /** + * @enum LinkType +- * @brief Enumeration of the possible types of Global Router Link Records. ++ * @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. +@@ -54,16 +54,16 @@ public: + }; + + /** +- * @brief Construct an empty ("uninitialized") Global Router Link Record. ++ * @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. + */ +- GlobalRouterLinkRecord (); +- +-/** +- * Construct an initialized Global Router Link Record. ++ 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. +@@ -73,21 +73,21 @@ public: + * @see SetLinkId + * @see SetLinkData + */ +- GlobalRouterLinkRecord ( ++ GlobalRoutingLinkRecord ( + LinkType linkType, + Ipv4Address linkId, + Ipv4Address linkData, + uint32_t metric); + + /** +- * @brief Destroy a Global Router Link Record. ++ * @brief Destroy a Global Routing Link Record. + * + * Currently does nothing. Here as a placeholder only. + */ +- ~GlobalRouterLinkRecord (); +- +-/** +- * Get the Link ID field of the Global Router Link Record. ++ ~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. +@@ -100,7 +100,7 @@ public: + Ipv4Address GetLinkId(void) const; + + /** +- * @brief Set the Link ID field of the Global Router Link Record. ++ * @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. +@@ -113,7 +113,7 @@ public: + void SetLinkId(Ipv4Address addr); + + /** +- * @brief Get the Link Data field of the Global Router Link Record. ++ * @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. +@@ -126,7 +126,7 @@ public: + Ipv4Address GetLinkData(void) const; + + /** +- * @brief Set the Link Data field of the Global Router Link Record. ++ * @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. +@@ -139,29 +139,29 @@ public: + void SetLinkData(Ipv4Address addr); + + /** +- * @brief Get the Link Type field of the Global Router Link Record. ++ * @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 Router Link Record. ++ * @returns The LinkType of the current Global Routing Link Record. + */ + LinkType GetLinkType(void) const; + + /** +- * @brief Set the Link Type field of the Global Router Link Record. ++ * @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 Router Link Record. ++ * @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 Router Link Record. ++ * @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 +@@ -169,12 +169,12 @@ public: + * two hops relate to the cost of sending a packet); rather you should use + * something like delay. + * +- * @returns The metric field of the Global Router Link Record. ++ * @returns The metric field of the Global Routing Link Record. + */ + uint32_t GetMetric(void) const; + + /** +- * @brief Set the Metric Data field of the Global Router Link Record. ++ * @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 +@@ -182,7 +182,7 @@ public: + * 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 Router Link Record. ++ * @param metric The new metric for the current Global Routing Link Record. + */ + void SetMetric(uint32_t metric); + +@@ -211,7 +211,7 @@ private: + Ipv4Address m_linkData; // for links to RouterLSA, + + /** +- * The type of the Global Router Link Record. Defined in the OSPF spec. ++ * The type of the Global Routing Link Record. Defined in the OSPF spec. + * We currently only use PointToPoint and StubNetwork types. + */ + LinkType m_linkType; +@@ -236,12 +236,24 @@ private: + * 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 GlobalRouterLSA ++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 Router ++ * @brief Enumeration of the possible values of the status flag in the Routing + * Link State Advertisements. + */ + enum SPFStatus { +@@ -249,17 +261,16 @@ public: + 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 Router Link State Advertisement. ++/** ++ * @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. + */ +- GlobalRouterLSA(); +- +-/** +- * @brief Create an initialized Global Router Link State Advertisement. ++ GlobalRoutingLSA(); ++ ++/** ++ * @brief Create an initialized Global Routing Link State Advertisement. + * + * On completion the list of Link State Records is empty. + * +@@ -267,42 +278,42 @@ public: + * @param linkStateId The Ipv4Address for the link state ID field. + * @param advertisingRtr The Ipv4Address for the advertising router field. + */ +- GlobalRouterLSA(SPFStatus status, Ipv4Address linkStateId, ++ GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId, + Ipv4Address advertisingRtr); + + /** +- * @brief Copy constructor for a Global Router Link State Advertisement. ++ * @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. + */ +- GlobalRouterLSA (GlobalRouterLSA& lsa); +- +-/** +- * @brief Destroy an existing Global Router Link State Advertisement. +- * +- * Any Global Router Link Records present in the list are freed. +- */ +- ~GlobalRouterLSA(); +- +-/** +- * @brief Assignment operator for a Global Router Link State Advertisement. +- * +- * Takes an existing Global Router Link State Advertisement and overwrites ++ 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 Router Link Records present in the existing ++ * 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. + */ +- GlobalRouterLSA& operator= (const GlobalRouterLSA& lsa); +- +-/** +- * @brief Copy any Global Router Link Records in a given Global Router Link ++ 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 +@@ -311,57 +322,66 @@ public: + * @see ClearLinkRecords () + * @param lsa The LSA to copy the Link Records from. + */ +- void CopyLinkRecords (const GlobalRouterLSA& lsa); +- +-/** +- * @brief Add a given Global Router Link Record to the LSA. +- * +- * @param lr The Global Router Link Record to be added. ++ 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 (GlobalRouterLinkRecord* lr); +- +-/** +- * @brief Return the number of Global Router Link Records in the LSA. ++ 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 Router Link Record. ++ * @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. + */ +- GlobalRouterLinkRecord* GetLinkRecord (uint32_t n) const; +- +-/** +- * @brief Release all of the Global Router Link Records present in the Global +- * Router Link State Advertisement and make the list of link records empty. ++ 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 Router Link Records present in the +- * Global Router Link State Advertisement is empty. ++ * @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 Router Link State Advertisement and +- * any Global Router Link Records present in the list. Quite verbose. ++ * @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 GlobalRouter::GetRouterId () ++ * @see GlobalRouting::GetRouterId () + * @returns The Ipv4Address stored as the link state ID. + */ + Ipv4Address GetLinkStateId (void) const; +@@ -371,7 +391,7 @@ public: + * to the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () +- * @see GlobalRouter::GetRouterId () ++ * @see GlobalRouting::GetRouterId () + */ + void SetLinkStateId (Ipv4Address addr); + +@@ -380,7 +400,7 @@ public: + * set it to the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () +- * @see GlobalRouter::GetRouterId () ++ * @see GlobalRouting::GetRouterId () + * @returns The Ipv4Address stored as the advetising router. + */ + Ipv4Address GetAdvertisingRouter (void) const; +@@ -390,9 +410,46 @@ public: + * set it to the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () +- * @see GlobalRouter::GetRouterId () ++ * @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 address 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. +@@ -411,11 +468,16 @@ public: + + 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 GlobalRouter::GetRouterId () ++ * @see GlobalRouting::GetRouterId () + */ + Ipv4Address m_linkStateId; + +@@ -424,14 +486,14 @@ private: + * the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () +- * @see GlobalRouter::GetRouterId () ++ * @see GlobalRouting::GetRouterId () + */ + Ipv4Address m_advertisingRtr; + + /** + * A convenience typedef to avoid too much writers cramp. + */ +- typedef std::list ListOfLinkRecords_t; ++ typedef std::list ListOfLinkRecords_t; + + /** + * Each Link State Advertisement contains a number of Link Records that +@@ -441,9 +503,29 @@ private: + * m_linkRecords is an STL list container to hold the Link Records that have + * been discovered and prepared for the advertisement. + * +- * @see GlobalRouter::DiscoverLSAs () ++ * @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 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 +@@ -454,7 +536,7 @@ private: + SPFStatus m_status; + }; + +-std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa); ++std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa); + + /** + * @brief An interface aggregated to a node to provide global routing info +@@ -496,7 +578,7 @@ public: + + /** + * @brief Walk the connected channels, discover the adjacent routers and build +- * the associated number of Global Router Link State Advertisements that ++ * 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 +@@ -507,14 +589,14 @@ public: + * advertisements after a network topology change by calling DiscoverLSAs + * and then by reading those advertisements. + * +- * @see GlobalRouterLSA ++ * @see GlobalRoutingLSA + * @see GlobalRouter::GetLSA () +- * @returns The number of Global Router Link State Advertisements. ++ * @returns The number of Global Routing Link State Advertisements. + */ + uint32_t DiscoverLSAs (void); + + /** +- * @brief Get the Number of Global Router Link State Advertisements that this ++ * @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. +@@ -522,19 +604,19 @@ public: + * GetLSA () to retrieve the actual advertisement. + * + * @see GlobalRouterLSA +- * @see GlobalRouter::DiscoverLSAs () +- * @see GlobalRouter::GetLSA () +- * @returns The number of Global Router Link State Advertisements. ++ * @see GlobalRouting::DiscoverLSAs () ++ * @see GlobalRouting::GetLSA () ++ * @returns The number of Global Routing Link State Advertisements. + */ + uint32_t GetNumLSAs (void) const; + + /** +- * @brief Get a Global Router Link State Advertisements that this router has ++ * @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 Router Link +- * State Advertisement into the requested GlobalRouterLSA object. ++ * 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. +@@ -542,13 +624,13 @@ public: + * The parameter n (requested LSA number) must be in the range 0 to + * GetNumLSAs() - 1. + * +- * @see GlobalRouterLSA +- * @see GlobalRouter::GetNumLSAs () ++ * @see GlobalRoutingLSA ++ * @see GlobalRouting::GetNumLSAs () + * @param n The index number of the LSA you want to read. +- * @param lsa The GlobalRouterLSA class to receive the LSA information. ++ * @param lsa The GlobalRoutingLSA class to receive the LSA information. + * @returns The number of Global Router Link State Advertisements. + */ +- bool GetLSA (uint32_t n, GlobalRouterLSA &lsa) const; ++ bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const; + + private: + virtual ~GlobalRouter (); +@@ -556,10 +638,12 @@ private: + + Ptr GetAdjacent(Ptr nd, Ptr ch) const; + uint32_t FindIfIndexForDevice(Ptr node, Ptr nd) const; ++ Ipv4Address FindDesignatedRouterForLink (Ptr node, ++ Ptr ndLocal) const; + + Ptr m_node; + +- typedef std::list ListOfLSAs_t; ++ typedef std::list ListOfLSAs_t; + ListOfLSAs_t m_LSAs; + + Ipv4Address m_routerId; + +changeset: 1284:3aef7d7a71c2 +user: Craig Dowell +date: Mon Aug 13 12:08:01 2007 -0700 +summary: more multicast plumbing + +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -65,7 +65,7 @@ main (int argc, char *argv[]) + { + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this +-#if 0 ++#if 0 + DebugComponentEnable("Me"); + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); +@@ -87,16 +87,9 @@ main (int argc, char *argv[]) + #endif + + DebugComponentEnable("Me"); +- DebugComponentEnable("OnOffApplication"); +- DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("CsmaChannel"); ++ DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("UdpL4Protocol"); +- DebugComponentEnable("Ipv4L3Protocol"); +- DebugComponentEnable("Ipv4StaticRouting"); +- DebugComponentEnable("CsmaNetDevice"); +- DebugComponentEnable("CsmaChannel"); +- DebugComponentEnable("Ipv4Interface"); +- DebugComponentEnable("ArpIpv4Interface"); +- DebugComponentEnable("Ipv4LoopbackInterface"); + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, +@@ -125,29 +118,47 @@ main (int argc, char *argv[]) + DataRate(5000000), MilliSeconds(2)); + + NS_DEBUG("Build Topology."); +- uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, +- Eui48Address("10:54:23:54:23:50")); +- uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, +- Eui48Address("10:54:23:54:23:51")); +- uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0, +- Eui48Address("10:54:23:54:23:52")); +- uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0, +- Eui48Address("10:54:23:54:23:53")); ++ uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, ++ channel0, Eui48Address("10:54:23:54:23:50")); ++ uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, ++ channel0, Eui48Address("10:54:23:54:23:51")); ++ uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, ++ channel0, Eui48Address("10:54:23:54:23:52")); ++ uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, ++ channel0, Eui48Address("10:54:23:54:23:53")); ++ ++ NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0); ++ NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1); ++ NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2); ++ NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3); + + // Later, we add IP addresses. + NS_DEBUG("Assign IP Addresses."); +- +- CsmaIpv4Topology::AddIpv4Address ( +- n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); +- +- CsmaIpv4Topology::AddIpv4Address ( +- n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); +- +- CsmaIpv4Topology::AddIpv4Address ( +- n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); ++ // XXX BUGBUG ++ // Need a better way to get the interface index. The point-to-point topology ++ // as implemented can't return the index since it creates interfaces on both ++ // sides (i.e., AddIpv4Addresses, not AddIpv4Address). Need a method on ++ // Ipv4 to find the interface index corresponding to a given ipv4 address. ++ uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, ++ netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), ++ Ipv4Mask ("255.255.255.0")); ++ ++ uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, ++ netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), ++ Ipv4Mask ("255.255.255.0")); ++ ++ uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, ++ netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), ++ Ipv4Mask ("255.255.255.0")); + +- CsmaIpv4Topology::AddIpv4Address ( +- n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); ++ uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, ++ netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), ++ Ipv4Mask ("255.255.255.0")); ++ ++ NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0); ++ NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1); ++ NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2); ++ NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3); + + // Configure multicasting + NS_DEBUG("Configure multicasting."); +@@ -158,22 +169,21 @@ main (int argc, char *argv[]) + ipv4 = n0->QueryInterface (Ipv4::iid); + + std::vector outputInterfaces (1); +- outputInterfaces[0] = n0ifIndex; ++ outputInterfaces[0] = ifIndexNode0; + + ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, + outputInterfaces); + + ipv4 = n1->QueryInterface (Ipv4::iid); +- ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++ // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + + ipv4 = n2->QueryInterface (Ipv4::iid); +- ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++ // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + + ipv4 = n3->QueryInterface (Ipv4::iid); +- ipv4->JoinMulticastGroup (multicastSource, multicastGroup); +- +- // Create the OnOff application to send UDP datagrams of size +- // 210 bytes at a rate of 448 Kb/s ++ // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++ ++ // Create the OnOff application to send UDP datagrams + // from n0 to the multicast group + NS_DEBUG("Create Applications."); + Ptr ooff = Create ( +@@ -181,10 +191,12 @@ main (int argc, char *argv[]) + InetSocketAddress (multicastGroup, 80), + "Udp", + ConstantVariable(1), +- ConstantVariable(0)); ++ ConstantVariable(0), ++ DataRate ("128b/s"), ++ 128); + // Start the application +- ooff->Start(Seconds(1.0)); +- ooff->Stop (Seconds(10.0)); ++ ooff->Start(Seconds(1.)); ++ ooff->Stop (Seconds(10.)); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the csma-one-subnet.tr file +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/applications/onoff-application.cc +--- a/src/applications/onoff-application.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/applications/onoff-application.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -199,9 +199,12 @@ void OnOffApplication::ScheduleNextTx() + if (m_totBytes < m_maxBytes) + { + uint32_t bits = m_pktSize * 8 - m_residualBits; ++ NS_DEBUG("OnOffApplication::ScheduleNextTx (): bits = " << bits); + Time nextTime(Seconds (bits / + static_cast(m_cbrRate.GetBitRate()))); // Time till next packet +- m_sendEvent = Simulator::Schedule(nextTime, &OnOffApplication::SendPacket, this); ++ NS_DEBUG("OnOffApplication::ScheduleNextTx (): nextTime = " << nextTime); ++ m_sendEvent = Simulator::Schedule(nextTime, ++ &OnOffApplication::SendPacket, this); + } + else + { // All done, cancel any pending events +@@ -214,6 +217,8 @@ void OnOffApplication::ScheduleStartEven + NS_DEBUG("OnOffApplication::ScheduleStartEvent ()"); + + Time offInterval = Seconds(m_offTime->GetValue()); ++ NS_DEBUG("OnOffApplication::ScheduleStartEvent (): " ++ "start at " << offInterval); + m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this); + } + +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/devices/csma/csma-ipv4-topology.cc +--- a/src/devices/csma/csma-ipv4-topology.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/devices/csma/csma-ipv4-topology.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -91,24 +91,22 @@ CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr + nd1->Attach (ch); + } + +-void +-CsmaIpv4Topology::AddIpv4Address(Ptr n1, +- int ndNum, +- const Ipv4Address& addr1, +- const Ipv4Mask& netmask1) ++uint32_t ++CsmaIpv4Topology::AddIpv4Address( ++ Ptr node, ++ uint32_t netDeviceNumber, ++ const Ipv4Address address, ++ const Ipv4Mask mask) + { +- // Duplex link is assumed to be subnetted as a /30 +- // May run this unnumbered in the future? +- Ipv4Mask netmask(netmask1); ++ Ptr nd = node->GetDevice(netDeviceNumber); + +- Ptr nd1 = n1->GetDevice(ndNum); ++ Ptr ipv4 = node->QueryInterface (Ipv4::iid); ++ uint32_t ifIndex = ipv4->AddInterface (nd); + +- Ptr ip1 = n1->QueryInterface (Ipv4::iid); +- uint32_t index1 = ip1->AddInterface (nd1); +- +- ip1->SetAddress (index1, addr1); +- ip1->SetNetworkMask (index1, netmask); +- ip1->SetUp (index1); ++ ipv4->SetAddress (ifIndex, address); ++ ipv4->SetNetworkMask (ifIndex, mask); ++ ipv4->SetUp (ifIndex); ++ return ifIndex; + } + + void +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/devices/csma/csma-ipv4-topology.h +--- a/src/devices/csma/csma-ipv4-topology.h Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/devices/csma/csma-ipv4-topology.h Mon Aug 13 12:08:01 2007 -0700 +@@ -94,18 +94,23 @@ public: + + + /** +- * \param n1 Node +- * \param ndNum NetDevice number with which to associate address +- * \param addr1 Ipv4 Address for ndNum of n1 +- * \param network network mask for ndNum of node n1 ++ * \brief Create an Ipv4 interface for a net device and assign an ++ * Ipv4Address to that interface. ++ * ++ * \param node The node to which to add the new address and corresponding ++ * interface. ++ * \param netDeviceNumber The NetDevice index number with which to associate ++ * the address. ++ * \param address The Ipv4 Address for the interface. ++ * \param network The network mask for the interface + * + * Add an Ipv4Address to the Ipv4 interface associated with the +- * ndNum CsmaIpv4NetDevices on the provided +- * CsmaIpv4Channel ++ * ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel + */ +- static void AddIpv4Address(Ptr n1, int ndNum, +- const Ipv4Address& addr1, +- const Ipv4Mask& netmask1); ++ static uint32_t AddIpv4Address(Ptr node, ++ uint32_t netDeviceNumber, ++ const Ipv4Address address, ++ const Ipv4Mask mask); + + /** + * \param nd1 Node +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/arp-ipv4-interface.cc +--- a/src/internet-node/arp-ipv4-interface.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -81,6 +81,14 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4 + hardwareDestination = GetDevice ()->GetBroadcast (); + found = true; + } ++ else if (dest.IsMulticast ()) ++ { ++ NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast"); ++ // XXX BUGBUG ++ // Need real multicast addresses ++ hardwareDestination = GetDevice ()->GetBroadcast (); ++ found = true; ++ } + else + { + NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup"); +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -246,12 +246,26 @@ Ipv4L3Protocol::SetDefaultRoute (Ipv4Add + } + + void +-Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, +- Packet packet, +- Ipv4RoutingProtocol::RouteReplyCallback routeReply) +-{ +- NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ", " << &packet << +- &routeReply << ")"); ++Ipv4L3Protocol::Lookup ( ++ Ipv4Header const &ipHeader, ++ Packet packet, ++ Ipv4RoutingProtocol::RouteReplyCallback routeReply) ++{ ++ NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ++ ", " << &packet << &routeReply << ")"); ++ ++ Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply); ++} ++ ++void ++Ipv4L3Protocol::Lookup ( ++ uint32_t ifIndex, ++ Ipv4Header const &ipHeader, ++ Packet packet, ++ Ipv4RoutingProtocol::RouteReplyCallback routeReply) ++{ ++ NS_DEBUG("Ipv4L3Protocol::Lookup (" << ifIndex << ", " << &ipHeader << ++ ", " << &packet << &routeReply << ")"); + + for (Ipv4RoutingProtocolList::const_iterator rprotoIter = + m_routingProtocols.begin (); +@@ -259,7 +273,8 @@ Ipv4L3Protocol::Lookup (Ipv4Header const + rprotoIter++) + { + NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route"); +- if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) ++ if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet, ++ routeReply)) + return; + } + +@@ -405,7 +420,9 @@ Ipv4L3Protocol::Receive( Ptr + protocol << ", " << from << ")"); + + uint32_t index = 0; +- for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) ++ for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); ++ i != m_interfaces.end (); ++ i++) + { + if ((*i)->GetDevice () == device) + { +@@ -423,7 +440,7 @@ Ipv4L3Protocol::Receive( Ptr + return; + } + +- if (Forwarding (packet, ipHeader, device)) ++ if (Forwarding (index, packet, ipHeader, device)) + { + return; + } +@@ -521,10 +538,14 @@ Ipv4L3Protocol::SendRealOut (bool found, + } + + bool +-Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) +-{ +- NS_DEBUG("Ipv4L3Protocol::Forwarding (" << &packet << ", " << &ipHeader << +- ", " << device << ")"); ++Ipv4L3Protocol::Forwarding ( ++ uint32_t ifIndex, ++ Packet const &packet, ++ Ipv4Header &ipHeader, ++ Ptr device) ++{ ++ NS_DEBUG("Ipv4L3Protocol::Forwarding (" << ifIndex << ", " << &packet << ++ ", " << &ipHeader << ", " << device << ")"); + + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); + i != m_interfaces.end (); i++) +@@ -579,7 +600,7 @@ Ipv4L3Protocol::Forwarding (Packet const + ipHeader.SetTtl (ipHeader.GetTtl () - 1); + + NS_DEBUG("Ipv4L3Protocol::Forwarding (): Forwarding packet."); +- Lookup (ipHeader, packet, ++ Lookup (ifIndex, ipHeader, packet, + MakeCallback (&Ipv4L3Protocol::SendRealOut, this)); + // + // If this is a to a multicast address and this node is a member of the +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-l3-protocol.h +--- a/src/internet-node/ipv4-l3-protocol.h Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.h Mon Aug 13 12:08:01 2007 -0700 +@@ -195,12 +195,19 @@ protected: + virtual void DoDispose (void); + + private: ++ void Lookup (uint32_t ifIndex, ++ Ipv4Header const &ipHeader, ++ Packet packet, ++ Ipv4RoutingProtocol::RouteReplyCallback routeReply); + + void SendRealOut (bool found, + Ipv4Route const &route, + Packet packet, + Ipv4Header const &ipHeader); +- bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device); ++ bool Forwarding (uint32_t ifIndex, ++ Packet const &packet, ++ Ipv4Header &ipHeader, ++ Ptr device); + void ForwardUp (Packet p, Ipv4Header const&ip); + uint32_t AddIpv4Interface (Ipv4Interface *interface); + void SetupLoopback (void); +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -196,7 +196,8 @@ Ipv4MulticastRoute * + Ipv4MulticastRoute * + Ipv4StaticRouting::LookupStatic ( + Ipv4Address origin, +- Ipv4Address group) ++ Ipv4Address group, ++ uint32_t ifIndex) + { + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); +@@ -207,7 +208,11 @@ Ipv4StaticRouting::LookupStatic ( + origin == Ipv4Address::GetAny ()) && + group == route->GetGroup ()) + { +- return *i; ++ if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || ++ ifIndex == route->GetInputInterface ()) ++ { ++ return *i; ++ } + } + } + return 0; +@@ -312,9 +317,11 @@ Ipv4StaticRouting::RemoveRoute (uint32_t + } + + bool +-Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, +- Packet packet, +- RouteReplyCallback routeReply) ++Ipv4StaticRouting::RequestRoute ( ++ uint32_t ifIndex, ++ Ipv4Header const &ipHeader, ++ Packet packet, ++ RouteReplyCallback routeReply) + { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " << + &packet << ", " << &routeReply << ")"); +@@ -328,27 +335,35 @@ Ipv4StaticRouting::RequestRoute (Ipv4Hea + // 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. + // +- Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), +- ipHeader.GetDestination ()); +- if (mRoute) +- { +- NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast route"); +- for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) +- { +- Packet p = packet; +- Ipv4Route route = +- Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), +- mRoute->GetOutputInterface(i)); ++ if (ipHeader.GetDestination ().IsMulticast ()) ++ { ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination"); ++ ++ Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), ++ ipHeader.GetDestination (), ifIndex); ++ ++ if (mRoute) ++ { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " +- "Send via interface " << mRoute->GetOutputInterface(i)); +- routeReply (true, route, p, ipHeader); +- return true; +- } ++ "Multicast route found"); ++ for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) ++ { ++ Packet p = packet; ++ Ipv4Route route = ++ Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), ++ mRoute->GetOutputInterface(i)); ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " ++ "Send via interface " << mRoute->GetOutputInterface(i)); ++ routeReply (true, route, p, ipHeader); ++ return true; ++ } ++ } ++ return false; // Let other routing protocols try to handle this + } + // + // See if this is a unicast packet we have a route for. + // +- NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast route"); ++ NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination"); + Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); + if (route != 0) + { +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Mon Aug 13 12:08:01 2007 -0700 +@@ -51,7 +51,8 @@ public: + public: + Ipv4StaticRouting () : m_defaultRoute (0) {} + +- virtual bool RequestRoute (Ipv4Header const &ipHeader, ++ virtual bool RequestRoute (uint32_t ifIndex, ++ Ipv4Header const &ipHeader, + Packet packet, + RouteReplyCallback routeReply); + +@@ -105,7 +106,8 @@ private: + typedef std::list::iterator MulticastRoutesI; + + Ipv4Route *LookupStatic (Ipv4Address dest); +- Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group); ++ Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group, ++ uint32_t ifIndex); + + HostRoutes m_hostRoutes; + NetworkRoutes m_networkRoutes; +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/node/ipv4-address.cc +--- a/src/node/ipv4-address.cc Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/node/ipv4-address.cc Mon Aug 13 12:08:01 2007 -0700 +@@ -171,8 +171,11 @@ bool + bool + Ipv4Address::IsMulticast (void) const + { +- // XXX +- return false; ++// ++// Multicast addresses are defined as ranging from 224.0.0.0 through ++// 239.255.255.255 (which is E0000000 through EFFFFFFF in hex). ++// ++ return (m_address >= 0xe0000000 && m_address <= 0xefffffff); + } + + uint32_t +diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/node/ipv4.h +--- a/src/node/ipv4.h Sun Aug 12 22:43:25 2007 -0700 ++++ b/src/node/ipv4.h Mon Aug 13 12:08:01 2007 -0700 +@@ -70,6 +70,7 @@ public: + /** + * \brief Asynchronously requests a route for a given packet and IP header + * ++ * \param ifIndex The interface index on which the packet was received. + * \param ipHeader IP header of the packet + * \param packet packet that is being sent or forwarded + * \param routeReply callback that will receive the route reply +@@ -99,9 +100,12 @@ public: + * immediately after the IP header, although most routing do not + * insert any extra header. + */ +- virtual bool RequestRoute (const Ipv4Header &ipHeader, ++ virtual bool RequestRoute (uint32_t ifIndex, ++ const Ipv4Header &ipHeader, + Packet packet, + RouteReplyCallback routeReply) = 0; ++ ++ static const uint32_t IF_INDEX_ANY = 0xffffffff; + }; + + /** + +changeset: 1285:a6fb891b59fd +user: Craig Dowell +date: Mon Aug 13 14:58:06 2007 -0700 +summary: cleanup. more complex multicast example + +diff -r 3aef7d7a71c2 -r a6fb891b59fd examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Mon Aug 13 12:08:01 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 13 14:58:06 2007 -0700 +@@ -16,31 +16,27 @@ + + // Network topology + // +-// n0 n1 n2 n3 +-// | | | | +-// ===================== +-// +-// - CBR/UDP flows from n0 to n1, and from n3 to n0 +-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +-// (i.e., DataRate of 448,000 bps) +-// - DropTail queues +-// - Tracing of queues and packet receptions to file "csma-one-subnet.tr" +- +-#include +-#include +-#include +-#include ++// Lan1 ++// =========== ++// | | | ++// n0 n1 n2 n3 n4 ++// | | | ++// =========== ++// Lan0 ++// ++// - Multicast source is at node n0; ++// - Multicast forwarded by node n2 onto LAN1; ++// - Nodes n0, n1, n2, n3, and n4 receive the multicast frame. ++// - Node n4 listens for the data (actual listener not yet implementted) + + #include "ns3/command-line.h" + #include "ns3/default-value.h" + #include "ns3/ptr.h" + #include "ns3/random-variable.h" + #include "ns3/debug.h" +- + #include "ns3/simulator.h" + #include "ns3/nstime.h" + #include "ns3/data-rate.h" +- + #include "ns3/ascii-trace.h" + #include "ns3/pcap-trace.h" + #include "ns3/internet-node.h" +@@ -58,15 +54,18 @@ + + using namespace ns3; + +-NS_DEBUG_COMPONENT_DEFINE ("Me"); ++NS_DEBUG_COMPONENT_DEFINE ("CsmaMulticast"); + + int + main (int argc, char *argv[]) + { +- // Users may find it convenient to turn on explicit debugging +- // for selected modules; the below lines suggest how to do this ++// ++// Users may find it convenient to turn on explicit debugging ++// for selected modules; the below lines suggest how to do this ++// + #if 0 +- DebugComponentEnable("Me"); ++ DebugComponentEnable("CsmaMulticast"); ++ + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); +@@ -86,105 +85,182 @@ main (int argc, char *argv[]) + DebugComponentEnable("Ipv4LoopbackInterface"); + #endif + +- DebugComponentEnable("Me"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); ++ ++ DebugComponentEnable("CsmaMulticast"); + DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("CsmaNetDevice"); +- DebugComponentEnable("UdpL4Protocol"); +- +- // Set up some default values for the simulation. Use the Bind() +- // technique to tell the system what subclass of Queue to use, +- // and what the queue limit is +- +- // The below Bind command tells the queue factory which class to +- // instantiate, when the queue factory is invoked in the topology code ++// ++// Set up default values for the simulation. Use the DefaultValue::Bind() ++// technique to tell the system what subclass of Queue to use. The Bind ++// command command tells the queue factory which class to instantiate when the ++// queue factory is invoked in the topology code ++// + DefaultValue::Bind ("Queue", "DropTailQueue"); +- +- // Allow the user to override any of the defaults and the above +- // Bind()s at run-time, via command-line arguments ++// ++// Allow the user to override any of the defaults and the above Bind() at ++// run-time, via command-line arguments ++// + CommandLine::Parse (argc, argv); +- +- // Here, we will explicitly create four nodes. In more sophisticated +- // topologies, we could configure a node factory. ++// ++// Explicitly create the nodes required by the topology (shown above). ++// + NS_DEBUG("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); ++ Ptr n4 = Create (); + + NS_DEBUG("Create channels."); +- // We create the channels first without any IP addressing information +- Ptr channel0 = ++// ++// Explicitly create the channels required by the topology (shown above). ++// ++ Ptr lan0 = + CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); + ++ Ptr lan1 = ++ CsmaTopology::CreateCsmaChannel( ++ DataRate(5000000), MilliSeconds(2)); ++ + NS_DEBUG("Build Topology."); +- uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, +- channel0, Eui48Address("10:54:23:54:23:50")); +- uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, +- channel0, Eui48Address("10:54:23:54:23:51")); +- uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, +- channel0, Eui48Address("10:54:23:54:23:52")); +- uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, +- channel0, Eui48Address("10:54:23:54:23:53")); +- +- NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0); +- NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1); +- NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2); +- NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3); +- +- // Later, we add IP addresses. ++// ++// Now fill out the topology by creating the net devices required to connect ++// the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will ++// create a net device, add a MAC address (in memory of the pink flamingo) and ++// connect the net device to a nodes and also to a channel. the ++// AddIpv4CsmaNetDevice method returns a net device index for the net device ++// created on the node. Interpret nd0 as the net device we created for node ++// zero. Interpret nd2Lan0 as the net device we created for node two to ++// connect to Lan0. ++// ++ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan0, ++ Eui48Address("08:00:2e:00:00:00")); ++ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan0, ++ Eui48Address("08:00:2e:00:00:01")); ++ uint32_t nd2Lan0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan0, ++ Eui48Address("08:00:2e:00:00:02")); ++ ++ uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, ++ Eui48Address("08:00:2e:00:00:00")); ++ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, ++ Eui48Address("08:00:2e:00:00:01")); ++ uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, ++ Eui48Address("08:00:2e:00:00:02")); ++ ++ NS_DEBUG ("nd0 = " << nd0); ++ NS_DEBUG ("nd1 = " << nd1); ++ NS_DEBUG ("nd2Lan0 = " << nd2Lan0); ++ NS_DEBUG ("nd2Lan1 = " << nd2Lan1); ++ NS_DEBUG ("nd3 = " << nd3); ++ NS_DEBUG ("nd4 = " << nd3); ++// ++// We've got the "hardware" in place. Now we need to add IP addresses. ++// + NS_DEBUG("Assign IP Addresses."); +- // XXX BUGBUG +- // Need a better way to get the interface index. The point-to-point topology +- // as implemented can't return the index since it creates interfaces on both +- // sides (i.e., AddIpv4Addresses, not AddIpv4Address). Need a method on +- // Ipv4 to find the interface index corresponding to a given ipv4 address. +- uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, +- netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), +- Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, +- netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), +- Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, +- netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), +- Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, +- netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), +- Ipv4Mask ("255.255.255.0")); +- +- NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0); +- NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1); +- NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2); +- NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3); +- +- // Configure multicasting ++// ++// XXX BUGBUG ++// Need a better way to get the interface index. The point-to-point topology ++// as implemented can't return the index since it creates interfaces on both ++// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a ++// method on Ipv4 to find the interface index corresponding to a given ipv4 ++// address. ++// ++// First, assign IP addresses to the net devices and associated interfaces ++// on Lan0. The AddIpv4Address method returns an Ipv4 interface index. ++// Interpret ifIndexNd0 as the interface index to use to reference the ++// net device we created on node zero when coming in from the Ipv4 interface. ++// Net device numbers and interface indices are distinct. Interpret ++// ifIndexNd2Lan0 as the interface index to use to reference the ++// net device we created that connects node two to lan zero. ++// ++ uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, ++ Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0")); ++ ++ uint32_t ifIndexNd1 = CsmaIpv4Topology::AddIpv4Address (n1, nd1, ++ Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0")); ++ ++ uint32_t ifIndexNd2Lan0 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, ++ Ipv4Address ("10.1.1.3"), Ipv4Mask ("255.255.255.0")); ++// ++// Assign IP addresses to the net devices and associated interfaces on Lan1 ++// ++ uint32_t ifIndexNd2Lan1 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, ++ Ipv4Address ("10.1.2.1"), Ipv4Mask ("255.255.255.0")); ++ ++ uint32_t ifIndexNd3 = CsmaIpv4Topology::AddIpv4Address (n3, nd1, ++ Ipv4Address ("10.1.2.2"), Ipv4Mask ("255.255.255.0")); ++ ++ uint32_t ifIndexNd4 = CsmaIpv4Topology::AddIpv4Address (n4, nd4, ++ Ipv4Address ("10.1.2.3"), Ipv4Mask ("255.255.255.0")); ++ ++ NS_DEBUG ("ifIndexNd0 = " << ifIndexNd0); ++ NS_DEBUG ("ifIndexNd1 = " << ifIndexNd1); ++ NS_DEBUG ("ifIndexNd2Lan0 = " << ifIndexNd2Lan0); ++ NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); ++ NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); ++ NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); + NS_DEBUG("Configure multicasting."); ++// ++// Now we can configure multicasting. As described above, the multicast ++// source is at node zero, which we assigned the IP address of 10.1.1.1 ++// earlier. We need to define a multicast group to send packets to. This ++// can be any multicast address from 224.0.0.0 through 239.255.255.255 ++// (avoiding the reserved routing protocol addresses). We just pick a ++// convenient number. ++// + Ipv4Address multicastSource ("10.1.1.1"); + Ipv4Address multicastGroup ("225.0.0.0"); +- ++// ++// We are going to manually configure multicast routing. This means telling ++// node two that it should expect multicast data coming from IP address ++// 10.1.1.1 over its IP interface connected to Lan0. These are called ++// multicastSource and ifIndexNd2Lan0 respectively. When node two receives ++// these packets, they should be forwarded out the interface that connects it ++// to Lan1 which is called ifIndexNd2Lan1. All we need to do is to call the ++// AddMulticastRoute method on node two's Ipv4 interface and provide this ++// information. (Note: the vector of output interfaces is in case there are ++// multiple net devices on a node). ++// + Ptr ipv4; ++ ipv4 = n2->QueryInterface (Ipv4::iid); ++ ++ std::vector outputInterfaces (1); ++ outputInterfaces[0] = ifIndexNd2Lan1; ++ ++ ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0, ++ outputInterfaces); ++// ++// We also need to explain to the node zero forwarding code that when it sees ++// a packet destined for the multicast group it needs to send it out its ++// one and only interface. The 0xffffffff in the call means that the input ++// interface qualification is not applicable in this case (the packet has ++// not been received over an interface, it has been created locally). ++// + ipv4 = n0->QueryInterface (Ipv4::iid); + +- std::vector outputInterfaces (1); +- outputInterfaces[0] = ifIndexNode0; +- +- ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, ++ outputInterfaces[0] = ifIndexNd0;; ++ ++ ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0xffffffff, + outputInterfaces); +- +- ipv4 = n1->QueryInterface (Ipv4::iid); +- // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); +- +- ipv4 = n2->QueryInterface (Ipv4::iid); +- // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); +- +- ipv4 = n3->QueryInterface (Ipv4::iid); +- // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); +- +- // Create the OnOff application to send UDP datagrams +- // from n0 to the multicast group ++// ++// As described above, node four will be the only node listening for the ++// multicast data. To enable forwarding bits up the protocol stack, we need ++// to tell the stack to join the multicast group. ++// ++ ipv4 = n4->QueryInterface (Ipv4::iid); ++ ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ++// ++// Create an OnOff application to send UDP datagrams from node zero to the ++// multicast group (node four will be listening). ++// + NS_DEBUG("Create Applications."); + Ptr ooff = Create ( + n0, +@@ -192,27 +268,33 @@ main (int argc, char *argv[]) + "Udp", + ConstantVariable(1), + ConstantVariable(0), +- DataRate ("128b/s"), ++ DataRate ("255b/s"), + 128); +- // Start the application ++// ++// Tell the application when to start and stop. ++// + ooff->Start(Seconds(1.)); + ooff->Stop (Seconds(10.)); +- +- // Configure tracing of all enqueue, dequeue, and NetDevice receive events +- // Trace output will be sent to the csma-one-subnet.tr file ++// ++// Configure tracing of all enqueue, dequeue, and NetDevice receive events. ++// Trace output will be sent to the file "csma-multicast.tr" ++// + NS_DEBUG("Configure Tracing."); + AsciiTrace asciitrace ("csma-multicast.tr"); + asciitrace.TraceAllNetDeviceRx (); + asciitrace.TraceAllQueues (); +- +- // Also configure some tcpdump traces; each interface will be traced +- // The output files will be named +- // simple-point-to-point.pcap-- +- // and can be read by the "tcpdump -r" command (use "-tt" option to +- // display timestamps correctly) ++// ++// Also configure some tcpdump traces; each interface will be traced. ++// The output files will be named: ++// csma-multicast.pcap-- ++// and can be read by the "tcpdump -r" command (use "-tt" option to ++// display timestamps correctly) ++// + PcapTrace pcaptrace ("csma-multicast.pcap"); + pcaptrace.TraceAllIp (); +- ++// ++// Now, do the actual simulation. ++// + NS_DEBUG("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); +diff -r 3aef7d7a71c2 -r a6fb891b59fd examples/csma-one-subnet.cc +--- a/examples/csma-one-subnet.cc Mon Aug 13 12:08:01 2007 -0700 ++++ b/examples/csma-one-subnet.cc Mon Aug 13 14:58:06 2007 -0700 +@@ -14,35 +14,25 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-// Port of ns-2/tcl/ex/simple.tcl to ns-3 +-// + // Network topology + // + // n0 n1 n2 n3 + // | | | | +-// ===================== +-// +-// - CBR/UDP flows from n0 to n1, and from n3 to n0 +-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +-// (i.e., DataRate of 448,000 bps) ++// ================= ++// LAN ++// ++// - CBR/UDP flows from n0 to n1 and from n3 to n0 + // - DropTail queues + // - Tracing of queues and packet receptions to file "csma-one-subnet.tr" +- +-#include +-#include +-#include +-#include + + #include "ns3/command-line.h" + #include "ns3/default-value.h" + #include "ns3/ptr.h" + #include "ns3/random-variable.h" + #include "ns3/debug.h" +- + #include "ns3/simulator.h" + #include "ns3/nstime.h" + #include "ns3/data-rate.h" +- + #include "ns3/ascii-trace.h" + #include "ns3/pcap-trace.h" + #include "ns3/internet-node.h" +@@ -60,15 +50,18 @@ + + using namespace ns3; + +-NS_DEBUG_COMPONENT_DEFINE ("Me"); ++NS_DEBUG_COMPONENT_DEFINE ("CsmaOneSubnet"); + + int + main (int argc, char *argv[]) + { +- // Users may find it convenient to turn on explicit debugging +- // for selected modules; the below lines suggest how to do this ++// ++// Users may find it convenient to turn on explicit debugging ++// for selected modules; the below lines suggest how to do this ++// + #if 0 +- DebugComponentEnable("Me"); ++ DebugComponentEnable("CsmaOneSubnet"); ++ + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); +@@ -88,71 +81,90 @@ main (int argc, char *argv[]) + DebugComponentEnable("Ipv4LoopbackInterface"); + #endif + +- DebugComponentEnable("Me"); +- DebugComponentEnable("OnOffApplication"); +- DebugComponentEnable("UdpSocket"); +- DebugComponentEnable("UdpL4Protocol"); +- DebugComponentEnable("Ipv4L3Protocol"); +- DebugComponentEnable("Ipv4StaticRouting"); +- DebugComponentEnable("CsmaNetDevice"); +- DebugComponentEnable("CsmaChannel"); +- DebugComponentEnable("Ipv4Interface"); +- DebugComponentEnable("ArpIpv4Interface"); +- DebugComponentEnable("Ipv4LoopbackInterface"); +- +- // Set up some default values for the simulation. Use the Bind() +- // technique to tell the system what subclass of Queue to use, +- // and what the queue limit is +- +- // The below Bind command tells the queue factory which class to +- // instantiate, when the queue factory is invoked in the topology code ++// ++// Set up default values for the simulation. Use the DefaultValue::Bind() ++// technique to tell the system what subclass of Queue to use. The Bind ++// command command tells the queue factory which class to instantiate when the ++// queue factory is invoked in the topology code ++// + DefaultValue::Bind ("Queue", "DropTailQueue"); +- +- // Allow the user to override any of the defaults and the above +- // Bind()s at run-time, via command-line arguments ++// ++// Allow the user to override any of the defaults and the above Bind() at ++// run-time, via command-line arguments ++// + CommandLine::Parse (argc, argv); +- +- // Here, we will explicitly create four nodes. In more sophisticated +- // topologies, we could configure a node factory. ++// ++// Explicitly create the nodes required by the topology (shown above). ++// + NS_DEBUG("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + +- // We create the channels first without any IP addressing information + NS_DEBUG("Create channels."); +- Ptr channel0 = +- CsmaTopology::CreateCsmaChannel( +- DataRate(5000000), MilliSeconds(2)); ++// ++// Explicitly create the channels required by the topology (shown above). ++// ++ Ptr lan = CsmaTopology::CreateCsmaChannel( ++ DataRate(5000000), MilliSeconds(2)); + + NS_DEBUG("Build Topology."); +- uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, +- Eui48Address("10:54:23:54:23:50")); +- uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, +- Eui48Address("10:54:23:54:23:51")); +- uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0, +- Eui48Address("10:54:23:54:23:52")); +- uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0, +- Eui48Address("10:54:23:54:23:53")); +- +- // Later, we add IP addresses. ++// ++// Now fill out the topology by creating the net devices required to connect ++// the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will ++// create a net device, add a MAC address (in memory of the pink flamingo) and ++// connect the net device to a nodes and also to a channel. the ++// AddIpv4CsmaNetDevice method returns a net device index for the net device ++// created on the node. Interpret nd0 as the net device we created for node ++// zero. ++// ++ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, ++ Eui48Address("08:00:2e:00:00:00")); ++ ++ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, ++ Eui48Address("08:00:2e:00:00:01")); ++ ++ uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, ++ Eui48Address("08:00:2e:00:00:02")); ++ ++ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, ++ Eui48Address("08:00:2e:00:00:03")); ++ ++ NS_DEBUG ("nd0 = " << nd0); ++ NS_DEBUG ("nd1 = " << nd1); ++ NS_DEBUG ("nd2 = " << nd2); ++ NS_DEBUG ("nd3 = " << nd3); ++// ++// We've got the "hardware" in place. Now we need to add IP addresses. ++// + NS_DEBUG("Assign IP Addresses."); +- CsmaIpv4Topology::AddIpv4Address ( +- n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); +- +- CsmaIpv4Topology::AddIpv4Address ( +- n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); +- +- CsmaIpv4Topology::AddIpv4Address ( +- n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); ++// ++// XXX BUGBUG ++// Need a better way to get the interface index. The point-to-point topology ++// as implemented can't return the index since it creates interfaces on both ++// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a ++// method on Ipv4 to find the interface index corresponding to a given ipv4 ++// address. ++// ++// Assign IP addresses to the net devices and associated interfaces ++// on the lan. The AddIpv4Address method returns an Ipv4 interface index ++// which we do not need here. ++// ++ CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address("10.1.1.1"), ++ Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address("10.1.1.2"), ++ Ipv4Mask("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address("10.1.1.3"), ++ Ipv4Mask("255.255.255.0")); + +- CsmaIpv4Topology::AddIpv4Address ( +- n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); +- +- // Create the OnOff application to send UDP datagrams of size +- // 210 bytes at a rate of 448 Kb/s +- // from n0 to n1 ++ CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address("10.1.1.4"), ++ Ipv4Mask("255.255.255.0")); ++// ++// Create an OnOff application to send UDP datagrams from node zero to node 1. ++// + NS_DEBUG("Create Applications."); + Ptr ooff = Create ( + n0, +@@ -160,36 +172,43 @@ main (int argc, char *argv[]) + "Udp", + ConstantVariable(1), + ConstantVariable(0)); +- // Start the application ++// ++// Tell the application when to start and stop. ++// + ooff->Start(Seconds(1.0)); + ooff->Stop (Seconds(10.0)); +- +- // Create a similar flow from n3 to n0, starting at time 1.1 seconds ++// ++// Create a similar flow from n3 to n0, starting at time 1.1 seconds ++// + ooff = Create ( + n3, + InetSocketAddress ("10.1.1.1", 80), + "Udp", + ConstantVariable(1), + ConstantVariable(0)); +- // Start the application ++ + ooff->Start(Seconds(1.1)); + ooff->Stop (Seconds(10.0)); +- +- // Configure tracing of all enqueue, dequeue, and NetDevice receive events +- // Trace output will be sent to the csma-one-subnet.tr file +- NS_DEBUG("Configure Tracing."); ++// ++// Configure tracing of all enqueue, dequeue, and NetDevice receive events. ++// Trace output will be sent to the file "csma-one-subnet.tr" ++// ++ NS_DEBUG("Configure Tracing."); + AsciiTrace asciitrace ("csma-one-subnet.tr"); + asciitrace.TraceAllNetDeviceRx (); + asciitrace.TraceAllQueues (); +- +- // Also configure some tcpdump traces; each interface will be traced +- // The output files will be named +- // simple-point-to-point.pcap-- +- // and can be read by the "tcpdump -r" command (use "-tt" option to +- // display timestamps correctly) ++// ++// Also configure some tcpdump traces; each interface will be traced. ++// The output files will be named: ++// csma-one-subnet.pcap-- ++// and can be read by the "tcpdump -r" command (use "-tt" option to ++// display timestamps correctly) ++// + PcapTrace pcaptrace ("csma-one-subnet.pcap"); + pcaptrace.TraceAllIp (); +- ++// ++// Now, do the actual simulation. ++// + NS_DEBUG("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); +diff -r 3aef7d7a71c2 -r a6fb891b59fd examples/mixed-global-routing.cc +--- a/examples/mixed-global-routing.cc Mon Aug 13 12:08:01 2007 -0700 ++++ b/examples/mixed-global-routing.cc Mon Aug 13 14:58:06 2007 -0700 +@@ -128,13 +128,13 @@ int main (int argc, char *argv[]) + CsmaTopology::CreateCsmaChannel( + DataRate(5000000), MilliSeconds(2)); + +- uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0, ++ uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, channelc0, + Eui48Address("10:54:23:54:23:50")); +- uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0, ++ uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, channelc0, + Eui48Address("10:54:23:54:23:51")); +- uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0, ++ uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, channelc0, + Eui48Address("10:54:23:54:23:52")); +- uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0, ++ uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, channelc0, + Eui48Address("10:54:23:54:23:53")); + + // Later, we add IP addresses. +diff -r 3aef7d7a71c2 -r a6fb891b59fd src/devices/csma/csma-ipv4-topology.cc +--- a/src/devices/csma/csma-ipv4-topology.cc Mon Aug 13 12:08:01 2007 -0700 ++++ b/src/devices/csma/csma-ipv4-topology.cc Mon Aug 13 14:58:06 2007 -0700 +@@ -35,19 +35,20 @@ namespace ns3 { + namespace ns3 { + + uint32_t +-CsmaIpv4Topology::AddIpv4CsmaNode(Ptr n1, +- Ptr ch, +- Eui48Address addr) ++CsmaIpv4Topology::AddIpv4CsmaNetDevice( ++ Ptr node, ++ Ptr channel, ++ Eui48Address addr) + { + Ptr q = Queue::CreateDefault (); + + // assume full-duplex +- Ptr nd0 = Create (n1, addr, +- ns3::CsmaNetDevice::IP_ARP, +- true, true); +- nd0->AddQueue(q); +- nd0->Attach (ch); +- return nd0->GetIfIndex (); ++ Ptr nd = Create (node, addr, ++ ns3::CsmaNetDevice::IP_ARP, true, true); ++ ++ nd->AddQueue(q); ++ nd->Attach (channel); ++ return nd->GetIfIndex (); + } + + +diff -r 3aef7d7a71c2 -r a6fb891b59fd src/devices/csma/csma-ipv4-topology.h +--- a/src/devices/csma/csma-ipv4-topology.h Mon Aug 13 12:08:01 2007 -0700 ++++ b/src/devices/csma/csma-ipv4-topology.h Mon Aug 13 14:58:06 2007 -0700 +@@ -61,9 +61,9 @@ public: + * + * \return ifIndex of the device + */ +- static uint32_t AddIpv4CsmaNode( Ptr n1, +- Ptr ch, +- Eui48Address addr); ++ static uint32_t AddIpv4CsmaNetDevice(Ptr node, ++ Ptr channel, ++ Eui48Address addr); + + /** + * \param n1 Node to be attached to the Csma channel + +changeset: 1286:2b63aafb050b +user: Craig Dowell +date: Mon Aug 13 16:21:39 2007 -0700 +summary: set source address in socket + +diff -r a6fb891b59fd -r 2b63aafb050b examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Mon Aug 13 14:58:06 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 13 16:21:39 2007 -0700 +@@ -123,12 +123,10 @@ main (int argc, char *argv[]) + // Explicitly create the channels required by the topology (shown above). + // + Ptr lan0 = +- CsmaTopology::CreateCsmaChannel( +- DataRate(5000000), MilliSeconds(2)); ++ CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2)); + + Ptr lan1 = +- CsmaTopology::CreateCsmaChannel( +- DataRate(5000000), MilliSeconds(2)); ++ CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2)); + + NS_DEBUG("Build Topology."); + // +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-end-point.cc +--- a/src/internet-node/ipv4-end-point.cc Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-end-point.cc Mon Aug 13 16:21:39 2007 -0700 +@@ -42,6 +42,13 @@ Ipv4EndPoint::GetLocalAddress (void) + { + return m_localAddr; + } ++ ++void ++Ipv4EndPoint::SetLocalAddress (Ipv4Address address) ++{ ++ m_localAddr = address; ++} ++ + uint16_t + Ipv4EndPoint::GetLocalPort (void) + { +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-end-point.h +--- a/src/internet-node/ipv4-end-point.h Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-end-point.h Mon Aug 13 16:21:39 2007 -0700 +@@ -37,6 +37,8 @@ public: + ~Ipv4EndPoint (); + + Ipv4Address GetLocalAddress (void); ++ void SetLocalAddress (Ipv4Address address); ++ + uint16_t GetLocalPort (void); + Ipv4Address GetPeerAddress (void); + uint16_t GetPeerPort (void); +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-impl.cc +--- a/src/internet-node/ipv4-impl.cc Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-impl.cc Mon Aug 13 16:21:39 2007 -0700 +@@ -174,11 +174,28 @@ Ipv4Impl::GetNetworkMask (uint32_t i) co + { + return m_ipv4->GetNetworkMask (i); + } ++ + Ipv4Address + Ipv4Impl::GetAddress (uint32_t i) const + { + return m_ipv4->GetAddress (i); + } ++ ++Ipv4Address ++Ipv4Impl::GetSourceAddress (Ipv4Address destination) const ++{ ++ uint32_t ifIndex; ++ bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex); ++ if (result) ++ { ++ return m_ipv4->GetAddress (ifIndex); ++ } ++ else ++ { ++ return Ipv4Address::GetAny (); ++ } ++} ++ + uint16_t + Ipv4Impl::GetMtu (uint32_t i) const + { +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-impl.h +--- a/src/internet-node/ipv4-impl.h Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-impl.h Mon Aug 13 16:21:39 2007 -0700 +@@ -81,6 +81,8 @@ public: + virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); + virtual Ipv4Mask GetNetworkMask (uint32_t t) const; + virtual Ipv4Address GetAddress (uint32_t i) const; ++ virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const; ++ + virtual uint16_t GetMtu (uint32_t i) const; + virtual bool IsUp (uint32_t i) const; + virtual void SetUp (uint32_t i); +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Mon Aug 13 16:21:39 2007 -0700 +@@ -691,6 +691,28 @@ Ipv4L3Protocol::GetAddress (uint32_t i) + return interface->GetAddress (); + } + ++bool ++Ipv4L3Protocol::GetIfIndexForDestination ( ++ Ipv4Address destination, uint32_t& ifIndex) const ++{ ++ NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (" << destination << ++ ", " << &ifIndex << ")"); ++ ++ for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin (); ++ i != m_routingProtocols.end (); ++ i++) ++ { ++ NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting Source Address"); ++ uint32_t ifIndex; ++ ++ if ((*i).second->RequestIfIndex (destination, ifIndex)) ++ { ++ return true; ++ } ++ } ++ return false; ++} ++ + uint16_t + Ipv4L3Protocol::GetMtu (uint32_t i) const + { +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-l3-protocol.h +--- a/src/internet-node/ipv4-l3-protocol.h Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.h Mon Aug 13 16:21:39 2007 -0700 +@@ -182,6 +182,8 @@ public: + void SetNetworkMask (uint32_t i, Ipv4Mask mask); + Ipv4Mask GetNetworkMask (uint32_t t) const; + Ipv4Address GetAddress (uint32_t i) const; ++ bool GetIfIndexForDestination (Ipv4Address destination, ++ uint32_t& ifIndex) const; + uint16_t GetMtu (uint32_t i) const; + bool IsUp (uint32_t i) const; + void SetUp (uint32_t i); +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Mon Aug 13 16:21:39 2007 -0700 +@@ -377,6 +377,55 @@ Ipv4StaticRouting::RequestRoute ( + } + } + ++bool ++Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex) ++{ ++ NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (" << destination << ", " << ++ &ifIndex << ")"); ++// ++// 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 (destination.IsMulticast ()) ++ { ++ NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): Multicast destination"); ++ ++ Ipv4MulticastRoute *mRoute = LookupStatic(Ipv4Address::GetAny (), ++ destination, Ipv4RoutingProtocol::IF_INDEX_ANY); ++ ++ if (mRoute) ++ { ++ NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): " ++ "Multicast route found"); ++ ++ if (mRoute->GetNOutputInterfaces () != 1) ++ { ++ NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): " ++ "Route is to multiple interfaces. Ignoring."); ++ return false; ++ } ++ ++ ifIndex = mRoute->GetOutputInterface(0); ++ return true; ++ } ++ return false; // Let other routing protocols try to handle this ++ } ++// ++// See if this is a unicast packet we have a route for. ++// ++ NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): Unicast destination"); ++ Ipv4Route *route = LookupStatic (destination); ++ if (route) ++ { ++ ifIndex = route->GetInterface (); ++ return true; ++ } ++ else ++ { ++ return false; ++ } ++} ++ + void + Ipv4StaticRouting::DoDispose (void) + { +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Mon Aug 13 16:21:39 2007 -0700 +@@ -56,6 +56,7 @@ public: + Packet packet, + RouteReplyCallback routeReply); + ++ virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex); + + void AddHostRouteTo (Ipv4Address dest, + Ipv4Address nextHop, +diff -r a6fb891b59fd -r 2b63aafb050b src/internet-node/udp-socket.cc +--- a/src/internet-node/udp-socket.cc Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/internet-node/udp-socket.cc Mon Aug 13 16:21:39 2007 -0700 +@@ -26,6 +26,7 @@ + #include "udp-l4-protocol.h" + #include "ipv4-end-point.h" + #include "ipv4-l4-demux.h" ++#include "ns3/ipv4.h" + + NS_DEBUG_COMPONENT_DEFINE ("UdpSocket"); + +@@ -180,6 +181,10 @@ UdpSocket::Connect(const Address & addre + m_defaultPort = transport.GetPort (); + NotifyConnectionSucceeded (); + m_connected = true; ++ ++ Ptr ipv4; ++ ipv4 = m_node->QueryInterface (Ipv4::iid); ++ m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress)); + return 0; + } + +diff -r a6fb891b59fd -r 2b63aafb050b src/node/ipv4.h +--- a/src/node/ipv4.h Mon Aug 13 14:58:06 2007 -0700 ++++ b/src/node/ipv4.h Mon Aug 13 16:21:39 2007 -0700 +@@ -104,6 +104,16 @@ public: + const Ipv4Header &ipHeader, + Packet packet, + RouteReplyCallback routeReply) = 0; ++ /** ++ * \brief Synchronously request the interface index that will be used to ++ * send a packet to a hypothetical destination. ++ * ++ * \param destination IP address of a hypothetical destination packet ++ * \param ifIndex Reference to interface index. ++ * \returns True if the protocol has a route, false otherwise. ++ */ ++ virtual bool RequestIfIndex (Ipv4Address destination, ++ uint32_t& ifIndex) = 0; + + static const uint32_t IF_INDEX_ANY = 0xffffffff; + }; +@@ -309,6 +319,12 @@ public: + */ + virtual Ipv4Address GetAddress (uint32_t i) const = 0; + /** ++ * \param destination The IP address of a hypothetical destination. ++ * \returns The IP address assigned to the interface that will be used ++ * if we were to send a packet to destination. ++ */ ++ virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0; ++ /** + * \param i index of ipv4 interface + * \returns the Maximum Transmission Unit (in bytes) associated + * to the underlying ipv4 interface + +changeset: 1287:a70de165a25a +user: Craig Dowell +date: Mon Aug 13 19:54:47 2007 -0700 +summary: set source IP address in udp-socket packets + +diff -r 2b63aafb050b -r a70de165a25a examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Mon Aug 13 16:21:39 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 13 19:54:47 2007 -0700 +@@ -71,11 +71,11 @@ main (int argc, char *argv[]) + DebugComponentEnable("DropTailQueue"); + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaChannel"); ++ DebugComponentEnable("NetDevice"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("Ipv4L3Protocol"); +- DebugComponentEnable("NetDevice"); ++ DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("PacketSocket"); +- DebugComponentEnable("OnOffApplication"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); +@@ -84,18 +84,6 @@ main (int argc, char *argv[]) + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + #endif +- +- DebugComponentEnable("UdpSocket"); +- DebugComponentEnable("UdpL4Protocol"); +- DebugComponentEnable("Ipv4L3Protocol"); +- DebugComponentEnable("Ipv4StaticRouting"); +- DebugComponentEnable("Ipv4Interface"); +- DebugComponentEnable("ArpIpv4Interface"); +- DebugComponentEnable("Ipv4LoopbackInterface"); +- +- DebugComponentEnable("CsmaMulticast"); +- DebugComponentEnable("CsmaChannel"); +- DebugComponentEnable("CsmaNetDevice"); + // + // Set up default values for the simulation. Use the DefaultValue::Bind() + // technique to tell the system what subclass of Queue to use. The Bind +diff -r 2b63aafb050b -r a70de165a25a examples/csma-one-subnet.cc +--- a/examples/csma-one-subnet.cc Mon Aug 13 16:21:39 2007 -0700 ++++ b/examples/csma-one-subnet.cc Mon Aug 13 19:54:47 2007 -0700 +@@ -80,7 +80,6 @@ main (int argc, char *argv[]) + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + #endif +- + // + // Set up default values for the simulation. Use the DefaultValue::Bind() + // technique to tell the system what subclass of Queue to use. The Bind +diff -r 2b63aafb050b -r a70de165a25a src/internet-node/ipv4-impl.cc +--- a/src/internet-node/ipv4-impl.cc Mon Aug 13 16:21:39 2007 -0700 ++++ b/src/internet-node/ipv4-impl.cc Mon Aug 13 19:54:47 2007 -0700 +@@ -184,8 +184,10 @@ Ipv4Address + Ipv4Address + Ipv4Impl::GetSourceAddress (Ipv4Address destination) const + { +- uint32_t ifIndex; ++ uint32_t ifIndex = 0xffffffff; ++ + bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex); ++ + if (result) + { + return m_ipv4->GetAddress (ifIndex); +diff -r 2b63aafb050b -r a70de165a25a src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Mon Aug 13 16:21:39 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Mon Aug 13 19:54:47 2007 -0700 +@@ -703,10 +703,13 @@ Ipv4L3Protocol::GetIfIndexForDestination + i++) + { + NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting Source Address"); +- uint32_t ifIndex; +- +- if ((*i).second->RequestIfIndex (destination, ifIndex)) +- { ++ uint32_t ifIndexTmp; ++ ++ if ((*i).second->RequestIfIndex (destination, ifIndexTmp)) ++ { ++ NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " ++ "Found ifIndex " << ifIndexTmp); ++ ifIndex = ifIndexTmp; + return true; + } + } +diff -r 2b63aafb050b -r a70de165a25a src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Mon Aug 13 16:21:39 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Mon Aug 13 19:54:47 2007 -0700 +@@ -406,6 +406,8 @@ Ipv4StaticRouting::RequestIfIndex (Ipv4A + } + + ifIndex = mRoute->GetOutputInterface(0); ++ NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): " ++ "Found ifIndex " << ifIndex); + return true; + } + return false; // Let other routing protocols try to handle this +diff -r 2b63aafb050b -r a70de165a25a src/internet-node/udp-socket.cc +--- a/src/internet-node/udp-socket.cc Mon Aug 13 16:21:39 2007 -0700 ++++ b/src/internet-node/udp-socket.cc Mon Aug 13 19:54:47 2007 -0700 +@@ -174,7 +174,7 @@ int + int + UdpSocket::Connect(const Address & address) + { +- NS_DEBUG("UdpSocket::Connect (" << address << ")"); ++ NS_DEBUG ("UdpSocket::Connect (" << address << ")"); + + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + m_defaultAddress = transport.GetIpv4 (); +@@ -185,6 +185,8 @@ UdpSocket::Connect(const Address & addre + Ptr ipv4; + ipv4 = m_node->QueryInterface (Ipv4::iid); + m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress)); ++ NS_DEBUG ("UdpSocket::Connect (): Local address is" << ++ m_endPoint->GetLocalAddress()); + return 0; + } + +@@ -270,4 +272,4 @@ UdpSocket::ForwardUp (const Packet &pack + NotifyDataReceived (p, address); + } + +-}//namespace ns3 ++} //namespace ns3 + +changeset: 1288:9f9fe7919c89 +user: Craig Dowell +date: Mon Aug 13 20:14:36 2007 -0700 +summary: Silliness for optimized version + +diff -r a70de165a25a -r 9f9fe7919c89 examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Mon Aug 13 19:54:47 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 13 20:14:36 2007 -0700 +@@ -193,6 +193,15 @@ main (int argc, char *argv[]) + NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); + NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); + NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); ++// ++// A little silliness to let optimized code work while still printing all ++// results in debug code (without attribute). ++// ++ nd3 = nd3; ++ ifIndexNd1 = ifIndexNd1; ++ ifIndexNd3 = ifIndexNd3; ++ ifIndexNd4 = ifIndexNd4; ++ + NS_DEBUG("Configure multicasting."); + // + // Now we can configure multicasting. As described above, the multicast + +changeset: 1289:1d32949ae397 +user: Craig Dowell +date: Mon Aug 13 23:40:51 2007 -0700 +summary: fix non-unique ethernet addresses + +diff -r 9f9fe7919c89 -r 1d32949ae397 examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Mon Aug 13 20:14:36 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 13 23:40:51 2007 -0700 +@@ -135,11 +135,11 @@ main (int argc, char *argv[]) + Eui48Address("08:00:2e:00:00:02")); + + uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, +- Eui48Address("08:00:2e:00:00:00")); ++ Eui48Address("08:00:2e:00:00:03")); + uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, +- Eui48Address("08:00:2e:00:00:01")); ++ Eui48Address("08:00:2e:00:00:04")); + uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, +- Eui48Address("08:00:2e:00:00:02")); ++ Eui48Address("08:00:2e:00:00:05")); + + NS_DEBUG ("nd0 = " << nd0); + NS_DEBUG ("nd1 = " << nd1); + +changeset: 1299:2cc09d5a04c4 +parent: 1289:1d32949ae397 +parent: 1298:8bbad559c665 +user: Craig Dowell +date: Mon Aug 20 13:40:15 2007 -0700 +summary: branch merge + +diff -r 1d32949ae397 -r 2cc09d5a04c4 .hgtags +--- a/.hgtags Mon Aug 13 23:40:51 2007 -0700 ++++ b/.hgtags Mon Aug 20 13:40:15 2007 -0700 +@@ -3,3 +3,4 @@ 0dc81e76166c56aaae64da48b673b62155943aad + 0dc81e76166c56aaae64da48b673b62155943aad packet-history-working + 38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3 + 5701e60bf01a8ac1308945e69001e0cc07948faf release ns-3.0.4 ++08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5 +diff -r 1d32949ae397 -r 2cc09d5a04c4 AUTHORS +--- a/AUTHORS Mon Aug 13 23:40:51 2007 -0700 ++++ b/AUTHORS Mon Aug 20 13:40:15 2007 -0700 +@@ -3,4 +3,5 @@ Craig Dowell (craigdo@ee.washington.edu) + Craig Dowell (craigdo@ee.washington.edu) + Tom Henderson (tomhend@u.washington.edu) + Mathieu Lacage (mathieu.lacage@sophia.inria.fr) ++Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca) + George F. Riley (riley@ece.gatech.edu) +diff -r 1d32949ae397 -r 2cc09d5a04c4 RELEASE_NOTES +--- a/RELEASE_NOTES Mon Aug 13 23:40:51 2007 -0700 ++++ b/RELEASE_NOTES Mon Aug 20 13:40:15 2007 -0700 +@@ -3,12 +3,16 @@ + + This file contains ns-3 release notes (most recent releases first). + +-Release 3.0.5 (2007/08/XX) ++Release 3.0.5 (2007/08/15) + ======================== + +- - Add CSMA/CD model (Emmanuelle Laprise) +- - Modularize ipv4 routing support (Gustavo Carneiro) +- - Add mobility framework and basic mobility models ++ - Refactoring to support win32-based unix environments (Cygwin, mingw) ++ - "Packet socket" for allowing applications to access NetDevices directly ++ - Generalized, polymorphic Address class ++ - Add CSMA NetDevice model (from Emmanuelle Laprise) ++ - Modularize IPv4 routing support (from Gustavo Carneiro) ++ - Add mobility framework and basic mobility models ++ - Global unicast centralized routing + + Release 3.0.4 (2007/07/15) + ======================== +diff -r 1d32949ae397 -r 2cc09d5a04c4 VERSION +--- a/VERSION Mon Aug 13 23:40:51 2007 -0700 ++++ b/VERSION Mon Aug 20 13:40:15 2007 -0700 +@@ -1,1 +1,1 @@ 3.0.4 +-3.0.4 ++3.0.5 +diff -r 1d32949ae397 -r 2cc09d5a04c4 doc/release_steps.txt +--- a/doc/release_steps.txt Mon Aug 13 23:40:51 2007 -0700 ++++ b/doc/release_steps.txt Mon Aug 20 13:40:15 2007 -0700 +@@ -5,23 +5,20 @@ 1. prepare the source files + - revise and check in RELEASE_NOTES + - update and check in VERSION to the latest release number + 2. make a new "architecture.pdf" document and place it in the doc/ directory +-3. add current version of waf script from subversion: +- - svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf +- - build waf script and put it into top of ns-3-dev +-4. cd ns-3-dev; ./waf configure; ./waf dist +-5. test tarball on release platforms (run-tests and simple-p2p) +-6. tag ns-3-dev with "release ns-3.0.X" ++3. cd ns-3-dev; ./waf configure; ./waf dist ++4. test tarball on release platforms (waf check and maybe some other scripts) ++5. tag ns-3-dev with "release ns-3.0.X" + - hg tag "release ns-3.0.x" + - hg push +-7. clone the tagged ns-3-dev and place it on the repository ++6. clone the tagged ns-3-dev and place it on the repository + - ssh code.nsnam.org; sudo; su code; + - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x + - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately +-8. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server +-9. update web page ++7. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server ++8. update web page + - add link to news.html + - update download.html + - update roadmap.html + - build and update Doxygen directory on the server + - update and upload software architecture document (PDF, HTML) +-10. announce to ns-developers, with summary of release notes ++9. announce to ns-developers, with summary of release notes +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/devices/csma/csma-net-device.h +--- a/src/devices/csma/csma-net-device.h Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/devices/csma/csma-net-device.h Mon Aug 20 13:40:15 2007 -0700 +@@ -99,8 +99,23 @@ enum CsmaEncapsulationMode { + * + * \param node the Node to which this device is connected. + * \param addr The source MAC address of the net device. ++ * \param pktType the type of encapsulation + */ + CsmaNetDevice (Ptr node, Eui48Address addr, CsmaEncapsulationMode pktType); ++ ++ /** ++ * Construct a CsmaNetDevice ++ * ++ * This is the constructor for the CsmaNetDevice. It takes as a ++ * parameter the Node to which this device is connected. Ownership of the ++ * Node pointer is not implied and the node must not be deleted. ++ * ++ * \param node the Node to which this device is connected. ++ * \param addr The source MAC address of the net device. ++ * \param pktType the type of encapsulation ++ * \param sendEnable whether this device is able to send ++ * \param receiveEnable whether this device is able to receive ++ */ + CsmaNetDevice (Ptr node, Eui48Address addr, + CsmaEncapsulationMode pktType, + bool sendEnable, bool receiveEnable); +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/devices/point-to-point/point-to-point-net-device.h +--- a/src/devices/point-to-point/point-to-point-net-device.h Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/devices/point-to-point/point-to-point-net-device.h Mon Aug 20 13:40:15 2007 -0700 +@@ -175,7 +175,6 @@ protected: + virtual Ptr DoGetChannel(void) const; + /** + * Set a new default data rate +- * @param Data rate to set for new default + */ + static void SetDefaultRate(const DataRate&); + +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/internet-node/ascii-trace.cc +--- a/src/internet-node/ascii-trace.cc Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/internet-node/ascii-trace.cc Mon Aug 20 13:40:15 2007 -0700 +@@ -25,6 +25,7 @@ + #include "ns3/simulator.h" + #include "ns3/node.h" + #include "ns3/packet.h" ++#include "ns3/queue.h" + + namespace ns3 { + +@@ -40,8 +41,12 @@ AsciiTrace::TraceAllQueues (void) + AsciiTrace::TraceAllQueues (void) + { + Packet::EnableMetadata (); +- TraceRoot::Connect ("/nodes/*/devices/*/queue/*", +- MakeCallback (&AsciiTrace::LogDevQueue, this)); ++ TraceRoot::Connect ("/nodes/*/devices/*/queue/enqueue", ++ MakeCallback (&AsciiTrace::LogDevQueueEnqueue, this)); ++ TraceRoot::Connect ("/nodes/*/devices/*/queue/dequeue", ++ MakeCallback (&AsciiTrace::LogDevQueueDequeue, this)); ++ TraceRoot::Connect ("/nodes/*/devices/*/queue/drop", ++ MakeCallback (&AsciiTrace::LogDevQueueDrop, this)); + } + void + AsciiTrace::TraceAllNetDeviceRx (void) +@@ -52,8 +57,34 @@ AsciiTrace::TraceAllNetDeviceRx (void) + } + + void +-AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet) ++AsciiTrace::LogDevQueueEnqueue (TraceContext const &context, ++ Packet const &packet) + { ++ m_os << "+ "; ++ m_os << Simulator::Now ().GetSeconds () << " "; ++ context.Print (m_os); ++ m_os << " pkt-uid=" << packet.GetUid () << " "; ++ packet.Print (m_os); ++ m_os << std::endl; ++} ++ ++void ++AsciiTrace::LogDevQueueDequeue (TraceContext const &context, ++ Packet const &packet) ++{ ++ m_os << "- "; ++ m_os << Simulator::Now ().GetSeconds () << " "; ++ context.Print (m_os); ++ m_os << " pkt-uid=" << packet.GetUid () << " "; ++ packet.Print (m_os); ++ m_os << std::endl; ++} ++ ++void ++AsciiTrace::LogDevQueueDrop (TraceContext const &context, ++ Packet const &packet) ++{ ++ m_os << "d "; + m_os << Simulator::Now ().GetSeconds () << " "; + context.Print (m_os); + m_os << " pkt-uid=" << packet.GetUid () << " "; +@@ -63,7 +94,7 @@ void + void + AsciiTrace::LogDevRx (TraceContext const &context, Packet &p) + { +- m_os << Simulator::Now ().GetSeconds () << " "; ++ m_os << "r " << Simulator::Now ().GetSeconds () << " "; + context.Print (m_os); + m_os << " pkt-uid=" << p.GetUid () << " "; + p.Print (m_os); +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/internet-node/ascii-trace.h +--- a/src/internet-node/ascii-trace.h Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/internet-node/ascii-trace.h Mon Aug 20 13:40:15 2007 -0700 +@@ -37,7 +37,9 @@ public: + void TraceAllQueues (void); + void TraceAllNetDeviceRx (void); + private: +- void LogDevQueue (TraceContext const &context, const Packet &p); ++ void LogDevQueueEnqueue (TraceContext const &context, const Packet &p); ++ void LogDevQueueDequeue (TraceContext const &context, const Packet &p); ++ void LogDevQueueDrop (TraceContext const &context, const Packet &p); + void LogDevRx (TraceContext const &context, Packet &p); + std::ofstream m_os; + }; +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/node/socket.h +--- a/src/node/socket.h Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/node/socket.h Mon Aug 20 13:40:15 2007 -0700 +@@ -170,7 +170,6 @@ public: + /** + * \brief Send data (or dummy data) to the remote host + * \param p packet to send +- * \param dataSent Data sent callback. + * \returns -1 in case of error or the number of bytes copied in the + * internal buffer and accepted for transmission. + */ +@@ -180,7 +179,6 @@ public: + * \brief Send data to a specified peer. + * \param address IP Address of remote host + * \param p packet to send +- * \param dataSent Data sent callback. + * \returns -1 in case of error or the number of bytes copied in the + * internal buffer and accepted for transmission. + */ +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/routing/global-routing/global-route-manager-impl.cc +--- a/src/routing/global-routing/global-route-manager-impl.cc Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/routing/global-routing/global-route-manager-impl.cc Mon Aug 20 13:40:15 2007 -0700 +@@ -1586,6 +1586,7 @@ GlobalRouteManagerImplTest::RunTests (vo + 1); + + GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA (); ++ lsa0->SetLSType (GlobalRoutingLSA::RouterLSA); + lsa0->SetLinkStateId ("0.0.0.0"); + lsa0->SetAdvertisingRouter ("0.0.0.0"); + lsa0->AddLinkRecord (lr0); +@@ -1605,6 +1606,7 @@ GlobalRouteManagerImplTest::RunTests (vo + 1); + + GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA (); ++ lsa1->SetLSType (GlobalRoutingLSA::RouterLSA); + lsa1->SetLinkStateId ("0.0.0.1"); + lsa1->SetAdvertisingRouter ("0.0.0.1"); + lsa1->AddLinkRecord (lr2); +@@ -1648,6 +1650,7 @@ GlobalRouteManagerImplTest::RunTests (vo + 1); + + GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA (); ++ lsa2->SetLSType (GlobalRoutingLSA::RouterLSA); + lsa2->SetLinkStateId ("0.0.0.2"); + lsa2->SetAdvertisingRouter ("0.0.0.2"); + lsa2->AddLinkRecord (lr4); +@@ -1671,6 +1674,7 @@ GlobalRouteManagerImplTest::RunTests (vo + 1); + + GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA (); ++ lsa3->SetLSType (GlobalRoutingLSA::RouterLSA); + lsa3->SetLinkStateId ("0.0.0.3"); + lsa3->SetAdvertisingRouter ("0.0.0.3"); + lsa3->AddLinkRecord (lr10); +diff -r 1d32949ae397 -r 2cc09d5a04c4 src/routing/global-routing/global-router-interface.h +--- a/src/routing/global-routing/global-router-interface.h Mon Aug 13 23:40:51 2007 -0700 ++++ b/src/routing/global-routing/global-router-interface.h Mon Aug 20 13:40:15 2007 -0700 +@@ -431,7 +431,7 @@ public: + /** + * @brief Add an attached router to the list in the NetworkLSA + * +- * @param address The Ipv4Address of the interface on the network link ++ * @param addr The Ipv4Address of the interface on the network link + * @returns The number of addresses in the list. + */ + uint32_t AddAttachedRouter (Ipv4Address addr); + +changeset: 1311:4743aef86605 +parent: 1299:2cc09d5a04c4 +parent: 1310:394c16278532 +user: Craig Dowell +date: Fri Aug 24 13:29:51 2007 -0700 +summary: merge with trunk + +diff -r 2cc09d5a04c4 -r 4743aef86605 SConstruct +--- a/SConstruct Mon Aug 20 13:40:15 2007 -0700 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,521 +0,0 @@ +-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +- +-import os.path +-import build +- +-version_file = open ('VERSION', 'r') +-version = version_file.readline () +-version_file.close () +-version = version.strip () +- +-ns3 = build.Ns3() +-ns3.build_dir = 'build-dir' +-ns3.version = version +-ns3.name = 'ns3' +-ns3.distname = 'ns' +-ns3.doxygen_config = os.path.join('doc', 'doxygen.conf') +-ns3.add_extra_dist(os.path.join('doc', 'main.txt')) +-ns3.add_extra_dist ('doc/architecture.pdf') +-ns3.add_extra_dist ('doc/contributing.txt') +-ns3.add_extra_dist ('doc/build.txt') +-ns3.add_extra_dist ('doc/codingstd.txt') +-ns3.add_extra_dist ('doc/mercurial.txt') +-ns3.add_extra_dist ('README') +-ns3.add_extra_dist ('RELEASE_NOTES') +-ns3.add_extra_dist ('AUTHORS') +-ns3.add_extra_dist ('VERSION') +- +-ns3.add_extra_dist('doc/build-waf.txt') +-ns3.add_extra_dist('ns3/_placeholder_') +-for wscript in [ +- "src/core/wscript", +- "src/node/wscript", +- "src/devices/p2p/wscript", +- "src/common/wscript", +- "src/applications/wscript", +- "src/simulator/wscript", +- "src/internet-node/wscript", +- "src/wscript", +- "utils/wscript", +- "samples/wscript", +- "examples/wscript", +- "wscript", +- ]: +- ns3.add_extra_dist(wscript) +-ns3.add_extra_dist('waf') +-ns3.add_extra_dist('waf.bat') +- +-# +-# The Core module +-# +-core = build.Ns3Module('core', 'src/core') +-ns3.add(core) +-core.add_sources([ +- 'callback-test.cc', +- 'debug.cc', +- 'assert.cc', +- 'ptr.cc', +- 'object.cc', +- 'test.cc', +- 'random-variable.cc', +- 'rng-stream.cc', +- 'uid-manager.cc', +- 'default-value.cc', +- 'command-line.cc', +- 'type-name.cc', +- 'component-manager.cc', +- ]) +-env = Environment() +-if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin': +- core.add_external_dep('pthread') +- core.add_sources([ +- 'unix-system-wall-clock-ms.cc', +- ]) +-elif env['PLATFORM'] == 'win32': +- core.add_sources([ +- 'win32-system-wall-clock-ms.cc', +- ]) +-core.add_headers ([ +- 'uid-manager.h', +- 'singleton.h', +-]) +-core.add_inst_headers([ +- 'system-wall-clock-ms.h', +- 'empty.h', +- 'callback.h', +- 'ptr.h', +- 'object.h', +- 'debug.h', +- 'assert.h', +- 'fatal-error.h', +- 'test.h', +- 'random-variable.h', +- 'rng-stream.h', +- 'default-value.h', +- 'command-line.h', +- 'type-name.h', +- 'component-manager.h', +- ]) +- +-def config_core (env, config): +- retval = [] +- # XXX This check is primitive but it should be +- # good enough for now. +- if config.CheckCHeader ('stdlib.h') == 1: +- retval.append ('#define HAVE_STDLIB_H 1') +- retval.append ('#define HAVE_GETENV 1') +- else: +- retval.append ('#undef HAVE_STDLIB_H') +- retval.append ('#undef HAVE_GETENV') +- return retval +-core.add_config (config_core) +- +-# +-# The Simulator module +-# +-simu = build.Ns3Module('simulator', 'src/simulator') +-ns3.add(simu) +-simu.add_dep('core') +-simu.add_external_dep('m') +-simu.add_sources([ +- 'high-precision.cc', +- 'time.cc', +- 'event-id.cc', +- 'scheduler.cc', +- 'scheduler-factory.cc', +- 'scheduler-list.cc', +- 'scheduler-heap.cc', +- 'scheduler-map.cc', +- 'event-impl.cc', +- 'simulator.cc', +- ]) +-simu.add_headers([ +- 'scheduler-heap.h', +- 'scheduler-map.h', +- 'scheduler-list.h' +- ]) +-simu.add_inst_headers([ +- 'high-precision.h', +- 'nstime.h', +- 'event-id.h', +- 'event-impl.h', +- 'simulator.h', +- 'scheduler.h', +- 'scheduler-factory.h', +- 'simulation-singleton.h', +- ]) +-high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n') +-if high_precision_as_double == 'y': +- simu.add_inst_header ('high-precision-double.h') +- simu.add_source ('high-precision-double.cc') +-else: +- simu.add_inst_headers ([ +- 'high-precision-128.h', +- 'cairo-wideint-private.h' +- ]) +- simu.add_sources ([ +- 'high-precision-128.cc', +- 'cairo-wideint.c', +- ]) +- +-def config_simulator (env, config): +- retval = [] +- high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n') +- if high_precision_as_double == 'y': +- retval.append ('#define USE_HIGH_PRECISION_DOUBLE 1') +- else: +- retval.append ('#undef USE_HIGH_PRECISION_DOUBLE') +- if config.CheckCHeader ('stdint.h') == 1: +- retval.append ('#define HAVE_STDINT_H 1') +- elif config.CheckCHeader ('inttypes.h') == 1: +- retval.append ('#define HAVE_INTTYPES_H 1') +- elif config.CheckCHeader ('sys/inttypes.h') == 1: +- retval.append ('#define HAVE_SYS_INT_TYPES_H 1') +- return retval +-simu.add_config (config_simulator) +- +-# +-# The Common module +-# +-common = build.Ns3Module('common', 'src/common') +-common.add_deps(['core', 'simulator']) +-ns3.add(common) +-common.add_sources([ +- 'buffer.cc', +- 'chunk.cc', +- 'header.cc', +- 'trailer.cc', +- 'packet-printer.cc', +- 'packet-metadata.cc', +- 'packet.cc', +- 'tags.cc', +- 'pcap-writer.cc', +- 'variable-tracer-test.cc', +- 'trace-context.cc', +- 'trace-resolver.cc', +- 'callback-trace-source.cc', +- 'empty-trace-resolver.cc', +- 'composite-trace-resolver.cc', +- 'trace-root.cc', +- 'data-rate.cc', +- ]) +-common.add_headers ([ +- ]) +-common.add_inst_headers([ +- 'buffer.h', +- 'chunk.h', +- 'header.h', +- 'trailer.h', +- 'tags.h', +- 'packet.h', +- 'packet-printer.h', +- 'packet-metadata.h', +- 'uv-trace-source.h', +- 'sv-trace-source.h', +- 'fv-trace-source.h', +- 'pcap-writer.h', +- 'callback-trace-source.h', +- 'trace-context.h', +- 'trace-resolver.h', +- 'empty-trace-resolver.h', +- 'composite-trace-resolver.h', +- 'array-trace-resolver.h', +- 'trace-root.h', +- 'terminal-trace-resolver.h', +- 'data-rate.h', +- ]) +- +-# +-# The Node module +-# +-node = build.Ns3Module ('node', 'src/node') +-ns3.add (node) +-node.add_deps (['core', 'common', 'simulator']) +-node.add_sources ([ +- 'node.cc', +- 'ipv4-address.cc', +- 'net-device.cc', +- 'mac-address.cc', +- 'llc-snap-header.cc', +- 'ipv4-route.cc', +- 'queue.cc', +- 'drop-tail-queue.cc', +- 'channel.cc', +- 'node-list.cc', +- 'socket.cc', +- 'socket-factory.cc', +- 'udp.cc', +- 'ipv4.cc', +- 'application.cc', +- ]) +-node.add_inst_headers ([ +- 'node.h', +- 'ipv4-address.h', +- 'net-device.h', +- 'mac-address.h', +- 'ipv4-route.h', +- 'queue.h', +- 'drop-tail-queue.h', +- 'llc-snap-header.h', +- 'channel.h', +- 'node-list.h', +- 'socket.h', +- 'socket-factory.h', +- 'udp.h', +- 'ipv4.h', +- 'application.h', +- ]) +- +-# +-# The Applications module +-# +-applications = build.Ns3Module ('applications', 'src/applications') +-ns3.add (applications) +-applications.add_deps (['node']) +-applications.add_sources ([ +- 'onoff-application.cc', +-]) +-applications.add_inst_headers ([ +- 'onoff-application.h', +-]) +- +-# +-# The Internet Node module +-# +-inode = build.Ns3Module ('internet-node', 'src/internet-node') +-ns3.add (inode) +-inode.add_deps (['node', 'routing']) +-inode.add_sources ([ +- 'internet-node.cc', +- 'l3-demux.cc', +- 'l3-protocol.cc', +- 'ipv4-l4-demux.cc', +- 'ipv4-l4-protocol.cc', +- 'ipv4-header.cc', +- 'udp-header.cc', +- 'ipv4-checksum.cc', +- 'ipv4-interface.cc', +- 'ipv4-l3-protocol.cc', +- 'ipv4-end-point.cc', +- 'udp-l4-protocol.cc', +- 'arp-header.cc', +- 'arp-cache.cc', +- 'arp-ipv4-interface.cc', +- 'arp-l3-protocol.cc', +- 'ipv4-loopback-interface.cc', +- 'header-utils.cc', +- 'udp-socket.cc', +- 'ipv4-end-point-demux.cc', +- 'arp-private.cc', +- 'ipv4-impl.cc', +- 'ipv4-private.cc', +- 'ascii-trace.cc', +- 'pcap-trace.cc', +- 'udp-impl.cc', +-]) +-inode.add_headers ([ +- 'ipv4-checksum.h', +- 'arp-header.h', +- 'arp-cache.h', +- 'arp-l3-protocol.h', +- 'ipv4-loopback-interface.h', +- 'l3-demux.h', +- 'header-utils.h', +- 'arp-ipv4-interface.h', +- 'udp-socket.h', +- 'udp-l4-protocol.h', +- 'arp-private.h', +- 'ipv4-impl.h', +- 'ipv4-private.h', +- 'ipv4-l3-protocol.h', +- 'l3-protocol.h', +- 'ipv4-l4-protocol.h', +- 'ipv4-l4-demux.h', +- 'ipv4-end-point-demux.h', +- 'ipv4-end-point.h', +- 'ipv4-header.h', +- 'ipv4-interface.h', +- 'udp-header.h', +- 'sgi-hashmap.h', +- 'udp-impl.h', +-]) +-inode.add_inst_headers ([ +- 'internet-node.h', +- 'ascii-trace.h', +- 'pcap-trace.h', +- 'ipv4-header.h', +- 'udp-header.h', +-]) +- +-# +-# The Point-to-point module +-# +-p2p = build.Ns3Module ('p2p', 'src/devices/p2p') +-ns3.add (p2p) +-p2p.add_deps (['node']) +-p2p.add_sources ([ +- 'p2p-net-device.cc', +- 'p2p-channel.cc', +- 'p2p-topology.cc', +- ]) +-p2p.add_inst_headers ([ +- 'p2p-net-device.h', +- 'p2p-channel.h', +- 'p2p-topology.h', +- ]) +- +-# +-# The Routing module +-# +-routing = build.Ns3Module('routing', 'src/routing') +-routing.add_deps(['core', 'node']) +-ns3.add(routing) +-routing.add_sources([ +- 'routing-environment.cc', +- 'static-router.cc', +- 'static-route-manager.cc', +- 'static-route-manager-impl.cc', +- 'candidate-queue.cc', +- ]) +-routing.add_headers ([ +- 'candidate-queue.h', +- 'static-route-manager-impl.h', +- ]) +-routing.add_inst_headers([ +- 'routing-environment.h', +- 'static-router.h', +- 'static-route-manager.h', +- ]) +- +-# utils +-run_tests = build.Ns3Module('run-tests', 'utils') +-ns3.add(run_tests) +-run_tests.set_executable() +-run_tests.add_deps(['core', 'simulator', 'common', 'routing']) +-run_tests.add_source('run-tests.cc') +- +-bench_object = build.Ns3Module('bench-object', 'utils') +-ns3.add(bench_object) +-bench_object.set_executable() +-bench_object.add_deps(['core']) +-bench_object.add_source('bench-object.cc') +- +-bench_packets = build.Ns3Module('bench-packets', 'utils') +-ns3.add(bench_packets) +-bench_packets.set_executable() +-bench_packets.add_deps (['core', 'common']) +-bench_packets.add_source('bench-packets.cc') +- +-bench_simu = build.Ns3Module('bench-simulator', 'utils') +-ns3.add(bench_simu) +-bench_simu.set_executable() +-bench_simu.add_dep('simulator') +-bench_simu.add_source('bench-simulator.cc') +- +-replay_simu = build.Ns3Module('replay-simulation', 'utils') +-ns3.add(replay_simu) +-replay_simu.set_executable() +-replay_simu.add_dep('simulator') +-replay_simu.add_source('replay-simulation.cc') +- +- +-# samples +-sample_debug = build.Ns3Module('sample-debug', 'samples') +-sample_debug.set_executable() +-ns3.add(sample_debug) +-sample_debug.add_dep('core') +-sample_debug.add_source('main-debug.cc') +-sample_debug.add_source('main-debug-other.cc') +- +-sample_packet_printer = build.Ns3Module('sample-packet-printer', 'samples') +-sample_packet_printer.set_executable() +-ns3.add(sample_packet_printer) +-sample_packet_printer.add_deps (['common', 'internet-node']) +-sample_packet_printer.add_source('main-packet-printer.cc') +- +-sample_callback = build.Ns3Module('sample-callback', 'samples') +-sample_callback.set_executable() +-ns3.add(sample_callback) +-sample_callback.add_dep('core') +-sample_callback.add_source('main-callback.cc') +- +-sample_ptr = build.Ns3Module('sample-ptr', 'samples') +-sample_ptr.set_executable() +-ns3.add(sample_ptr) +-sample_ptr.add_dep('core') +-sample_ptr.add_source('main-ptr.cc') +- +-sample_trace = build.Ns3Module('sample-trace', 'samples') +-#ns3.add(sample_trace) +-sample_trace.add_dep('common') +-sample_trace.set_executable() +-sample_trace.add_source('main-trace.cc') +- +-sample_query_interface = build.Ns3Module('sample-query-interface', 'samples') +-ns3.add(sample_query_interface) +-sample_query_interface.add_dep('common') +-sample_query_interface.set_executable() +-sample_query_interface.add_source('main-query-interface.cc') +- +-sample_simu = build.Ns3Module('sample-simulator', 'samples') +-ns3.add(sample_simu) +-sample_simu.set_executable() +-sample_simu.add_dep('simulator') +-sample_simu.add_source('main-simulator.cc') +- +-sample_packet = build.Ns3Module('sample-packet', 'samples') +-ns3.add(sample_packet) +-sample_packet.set_executable() +-sample_packet.add_dep('common') +-sample_packet.add_source('main-packet.cc') +- +-sample_test = build.Ns3Module('sample-test', 'samples') +-sample_test.set_executable() +-ns3.add(sample_test) +-sample_test.add_dep('core') +-sample_test.add_source('main-test.cc') +- +-sample_simple = build.Ns3Module('sample-simple', 'samples') +-sample_simple.set_executable() +-ns3.add(sample_simple) +-sample_simple.add_deps(['core', 'simulator', 'node', 'internet-node', 'routing']) +-sample_simple.add_source('main-simple.cc') +- +-sample_sp2p = build.Ns3Module('sample-simple-p2p', 'samples') +-sample_sp2p.set_executable() +-#n3.add(sample_sp2p) +-sample_sp2p.add_deps(['core', 'simulator', 'node', 'internet-node', 'p2p']) +-sample_sp2p.add_source('main-simple-p2p.cc') +- +-sample_default_value = build.Ns3Module('sample-default-value', 'samples') +-sample_default_value.set_executable() +-ns3.add(sample_default_value) +-sample_default_value.add_deps(['core', 'simulator', 'node', 'p2p']) +-sample_default_value.add_source('main-default-value.cc') +- +-sample_object = build.Ns3Module('sample-object', 'samples') +-sample_object.set_executable() +-ns3.add(sample_object) +-sample_object.add_deps(['core']) +-sample_object.add_source('main-object.cc') +- +-sample_component_manager = build.Ns3Module('sample-component-manager', 'samples') +-sample_component_manager.set_executable() +-ns3.add(sample_component_manager) +-sample_component_manager.add_deps(['core']) +-sample_component_manager.add_source('main-component-manager.cc') +- +-# examples +-example_simple_p2p = build.Ns3Module('simple-p2p', 'examples') +-example_simple_p2p.set_executable() +-ns3.add(example_simple_p2p) +-example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing']) +-example_simple_p2p.add_source('simple-p2p.cc') +- +-example_static_routing = build.Ns3Module('simple-static-routing', 'examples') +-example_static_routing.set_executable() +-ns3.add(example_static_routing) +-example_static_routing.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing']) +-example_static_routing.add_source('simple-static-routing.cc') +- +-ns3.generate_dependencies() +diff -r 2cc09d5a04c4 -r 4743aef86605 examples/simple-point-to-point.cc +--- a/examples/simple-point-to-point.cc Mon Aug 20 13:40:15 2007 -0700 ++++ b/examples/simple-point-to-point.cc Fri Aug 24 13:29:51 2007 -0700 +@@ -71,6 +71,7 @@ main (int argc, char *argv[]) + + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this ++ // remember to add #include "ns3/debug.h" before enabling these + #if 0 + DebugComponentEnable("Me"); + DebugComponentEnable("Object"); +diff -r 2cc09d5a04c4 -r 4743aef86605 src/applications/onoff-application.h +--- a/src/applications/onoff-application.h Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/applications/onoff-application.h Fri Aug 24 13:29:51 2007 -0700 +@@ -28,13 +28,13 @@ + #include "ns3/application.h" + #include "ns3/event-id.h" + #include "ns3/ptr.h" ++#include "ns3/data-rate.h" + + namespace ns3 { + + class Address; + class RandomVariable; + class Socket; +-class DataRate; + + /** + * \brief Generate traffic to a single destination according to an +diff -r 2cc09d5a04c4 -r 4743aef86605 src/mobility/mobility-model.cc +--- a/src/mobility/mobility-model.cc Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/mobility/mobility-model.cc Fri Aug 24 13:29:51 2007 -0700 +@@ -52,9 +52,9 @@ MobilityModel::Set (const Position &posi + } + + double +-MobilityModel::GetDistanceFrom (const MobilityModel &other) const ++MobilityModel::GetDistanceFrom (Ptr other) const + { +- Position oPosition = other.DoGet (); ++ Position oPosition = other->DoGet (); + Position position = DoGet (); + return CalculateDistance (position, oPosition); + } +diff -r 2cc09d5a04c4 -r 4743aef86605 src/mobility/mobility-model.h +--- a/src/mobility/mobility-model.h Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/mobility/mobility-model.h Fri Aug 24 13:29:51 2007 -0700 +@@ -57,7 +57,7 @@ public: + * \param position a reference to another mobility model + * \returns the distance between the two objects. Unit is meters. + */ +- double GetDistanceFrom (const MobilityModel &position) const; ++ double GetDistanceFrom (Ptr position) const; + protected: + /** + * Must be invoked by subclasses when the course of the +diff -r 2cc09d5a04c4 -r 4743aef86605 src/node/inet-socket-address.cc +--- a/src/node/inet-socket-address.cc Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/node/inet-socket-address.cc Fri Aug 24 13:29:51 2007 -0700 +@@ -1,3 +1,24 @@ ++/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ ++/* ++ * Copyright (c) 2005 INRIA ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation; ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Mathieu Lacage ++ */ ++ + #include "inet-socket-address.h" + #include "ns3/assert.h" + +diff -r 2cc09d5a04c4 -r 4743aef86605 src/node/inet-socket-address.h +--- a/src/node/inet-socket-address.h Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/node/inet-socket-address.h Fri Aug 24 13:29:51 2007 -0700 +@@ -1,5 +1,26 @@ +-#ifndef IPV4_TRANSPORT_ADDRESS_H +-#define IPV4_TRANSPORT_ADDRESS_H ++/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ ++/* ++ * Copyright (c) 2005 INRIA ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation; ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Mathieu Lacage ++ */ ++ ++#ifndef INET_SOCKET_ADDRESS_H ++#define INET_SOCKET_ADDRESS_H + + #include "address.h" + #include "ipv4-address.h" +@@ -93,4 +114,4 @@ private: + } // namespace ns3 + + +-#endif /* IPV4_TRANSPORT_ADDRESS_H */ ++#endif /* INET_SOCKET_ADDRESS_H */ +diff -r 2cc09d5a04c4 -r 4743aef86605 src/node/net-device.cc +--- a/src/node/net-device.cc Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/node/net-device.cc Fri Aug 24 13:29:51 2007 -0700 +@@ -197,7 +197,7 @@ NetDevice::GetChannel (void) const + + // Receive packets from below + bool +-NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from) ++NetDevice::ForwardUp(const Packet& p, uint16_t param, const Address &from) + { + bool retval = false; + +diff -r 2cc09d5a04c4 -r 4743aef86605 src/node/net-device.h +--- a/src/node/net-device.h Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/node/net-device.h Fri Aug 24 13:29:51 2007 -0700 +@@ -251,7 +251,7 @@ public: + * forwards it to the higher layers by calling this method + * which is responsible for passing it up to the Rx callback. + */ +- bool ForwardUp (const Packet& p, uint32_t param, const Address &address); ++ bool ForwardUp (const Packet& p, uint16_t param, const Address &address); + + + /** +diff -r 2cc09d5a04c4 -r 4743aef86605 src/simulator/simulator.cc +--- a/src/simulator/simulator.cc Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/simulator/simulator.cc Fri Aug 24 13:29:51 2007 -0700 +@@ -539,13 +539,14 @@ public: + public: + SimulatorTests (); + // only here for testing of Ptr<> +- void Ref (void); +- void Unref (void); ++ void Ref (void) const; ++ void Unref (void) const; + virtual ~SimulatorTests (); + virtual bool RunTests (void); + private: + uint64_t NowUs (); + bool RunOneTest (void); ++ void RunTestsConst (void) const; + void A (int a); + void B (int b); + void C (int c); +@@ -566,6 +567,24 @@ private: + void cbaz3 (const int &, const int &, const int &); + void cbaz4 (const int &, const int &, const int &, const int &); + void cbaz5 (const int &, const int &, const int &, const int &, const int &); ++ ++ void bar0c (void) const; ++ void bar1c (int) const; ++ void bar2c (int, int) const; ++ void bar3c (int, int, int) const; ++ void bar4c (int, int, int, int) const; ++ void bar5c (int, int, int, int, int) const; ++ void baz1c (int &) const; ++ void baz2c (int &, int &) const; ++ void baz3c (int &, int &, int &) const; ++ void baz4c (int &, int &, int &, int &) const; ++ void baz5c (int &, int &, int &, int &, int &) const; ++ void cbaz1c (const int &) const; ++ void cbaz2c (const int &, const int &) const; ++ void cbaz3c (const int &, const int &, const int &) const; ++ void cbaz4c (const int &, const int &, const int &, const int &) const; ++ void cbaz5c (const int &, const int &, const int &, const int &, const int &) const; ++ + void destroy (void); + + bool m_b; +@@ -583,10 +602,10 @@ SimulatorTests::~SimulatorTests () + SimulatorTests::~SimulatorTests () + {} + void +-SimulatorTests::Ref (void) +-{} +-void +-SimulatorTests::Unref (void) ++SimulatorTests::Ref (void) const ++{} ++void ++SimulatorTests::Unref (void) const + {} + uint64_t + SimulatorTests::NowUs (void) +@@ -687,6 +706,57 @@ SimulatorTests::cbaz4 (const int &, cons + {} + void + SimulatorTests::cbaz5 (const int &, const int &, const int &, const int &, const int &) ++{} ++ ++void ++SimulatorTests::bar0c (void) const ++{} ++void ++SimulatorTests::bar1c (int) const ++{} ++void ++SimulatorTests::bar2c (int, int) const ++{} ++void ++SimulatorTests::bar3c (int, int, int) const ++{} ++void ++SimulatorTests::bar4c (int, int, int, int) const ++{} ++void ++SimulatorTests::bar5c (int, int, int, int, int) const ++{} ++ ++void ++SimulatorTests::baz1c (int &) const ++{} ++void ++SimulatorTests::baz2c (int &, int &) const ++{} ++void ++SimulatorTests::baz3c (int &, int &, int &) const ++{} ++void ++SimulatorTests::baz4c (int &, int &, int &, int &) const ++{} ++void ++SimulatorTests::baz5c (int &, int &, int &, int &, int &) const ++{} ++ ++void ++SimulatorTests::cbaz1c (const int &) const ++{} ++void ++SimulatorTests::cbaz2c (const int &, const int &) const ++{} ++void ++SimulatorTests::cbaz3c (const int &, const int &, const int &) const ++{} ++void ++SimulatorTests::cbaz4c (const int &, const int &, const int &, const int &) const ++{} ++void ++SimulatorTests::cbaz5c (const int &, const int &, const int &, const int &, const int &) const + {} + + bool +@@ -723,6 +793,80 @@ SimulatorTests::RunOneTest (void) + } + return ok; + } ++void ++SimulatorTests::RunTestsConst (void) const ++{ ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar0c, this); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar1c, this, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar2c, this, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar3c, this, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar4c, this, 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar5c, this, 0, 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar0c, Ptr (this)); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar1c, Ptr (this), 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar2c, Ptr (this), 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar3c, Ptr (this), 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar4c, Ptr (this), 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar5c, Ptr (this), 0, 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz1c, this, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz2c, this, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz3c, this, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz4c, this, 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar0c, this); ++ Simulator::ScheduleNow (&SimulatorTests::bar1c, this, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar2c, this, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar3c, this, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar4c, this, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::cbaz1c, this, 0); ++ Simulator::ScheduleNow (&SimulatorTests::cbaz2c, this, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::cbaz3c, this, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::cbaz4c, this, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::cbaz5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar0c, Ptr (this)); ++ Simulator::ScheduleNow (&SimulatorTests::bar1c, Ptr (this), 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar2c, Ptr (this), 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar3c, Ptr (this), 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar4c, Ptr (this), 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::bar5c, Ptr (this), 0, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar0c, this); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar1c, this, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar2c, this, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar3c, this, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar4c, this, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::cbaz1c, this, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::cbaz2c, this, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::cbaz3c, this, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::cbaz4c, this, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::cbaz5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar0c, Ptr (this)); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar1c, Ptr (this), 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar2c, Ptr (this), 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar3c, Ptr (this), 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar4c, Ptr (this), 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::bar5c, Ptr (this), 0, 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz1c, this, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz2c, this, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz3c, this, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz4c, this, 0, 0, 0, 0); ++ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::baz1c, this, 0); ++ Simulator::ScheduleNow (&SimulatorTests::baz2c, this, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::baz3c, this, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::baz4c, this, 0, 0, 0, 0); ++ Simulator::ScheduleNow (&SimulatorTests::baz5c, this, 0, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::baz1c, this, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::baz2c, this, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::baz3c, this, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::baz4c, this, 0, 0, 0, 0); ++ Simulator::ScheduleDestroy (&SimulatorTests::baz5c, this, 0, 0, 0, 0, 0); ++ ++ Simulator::Run (); ++ Simulator::Destroy (); ++} ++ + bool + SimulatorTests::RunTests (void) + { +@@ -870,6 +1014,8 @@ SimulatorTests::RunTests (void) + Simulator::ScheduleDestroy (&SimulatorTests::baz5, this, 0, 0, 0, 0, 0); + #endif + ++ RunTestsConst (); ++ + EventId nowId = Simulator::ScheduleNow (&foo0); + m_destroyId = Simulator::ScheduleDestroy (&SimulatorTests::destroy, this); + if (m_destroyId.IsExpired ()) +diff -r 2cc09d5a04c4 -r 4743aef86605 src/simulator/simulator.h +--- a/src/simulator/simulator.h Mon Aug 20 13:40:15 2007 -0700 ++++ b/src/simulator/simulator.h Fri Aug 24 13:29:51 2007 -0700 +@@ -163,8 +163,8 @@ public: + * @param obj the object on which to invoke the member method + * @returns an id for the scheduled event. + */ +- template +- static EventId Schedule (Time const &time, void (T::*mem_ptr) (void), OBJ obj); ++ template ++ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj); + /** + * @param time the relative expiration time of the event. + * @param mem_ptr member method pointer to invoke +@@ -172,8 +172,8 @@ public: + * @param a1 the first argument to pass to the invoked method + * @returns an id for the scheduled event. + */ +- template +- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1), OBJ obj, T1 a1); ++ template ++ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1); + /** + * @param time the relative expiration time of the event. + * @param mem_ptr member method pointer to invoke +@@ -182,8 +182,8 @@ public: + * @param a2 the second argument to pass to the invoked method + * @returns an id for the scheduled event. + */ +- template +- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2); ++ template ++ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2); + /** + * @param time the relative expiration time of the event. + * @param mem_ptr member method pointer to invoke +@@ -193,10 +193,9 @@ public: + * @param a3 the third argument to pass to the invoked method + * @returns an id for the scheduled event. + */ +- template +- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3); ++ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); + /** + * @param time the relative expiration time of the event. + * @param mem_ptr member method pointer to invoke +@@ -207,10 +206,9 @@ public: + * @param a4 the fourth argument to pass to the invoked method + * @returns an id for the scheduled event. + */ +- template +- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4); ++ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4); + /** + * @param time the relative expiration time of the event. + * @param mem_ptr member method pointer to invoke +@@ -222,10 +220,9 @@ public: + * @param a5 the fifth argument to pass to the invoked method + * @returns an id for the scheduled event. + */ +- template +- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, ++ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, + T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); + /** + * @param time the relative expiration time of the event. +@@ -295,27 +292,25 @@ public: + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method + */ +- template +- static EventId ScheduleNow (void (T::*mem_ptr) (void), OBJ obj); +- /** +- * @param mem_ptr member method pointer to invoke +- * @param obj the object on which to invoke the member method +- * @param a1 the first argument to pass to the invoked method +- */ +- template ++ static EventId ScheduleNow (MEM mem_ptr, OBJ obj); ++ /** ++ * @param mem_ptr member method pointer to invoke ++ * @param obj the object on which to invoke the member method ++ * @param a1 the first argument to pass to the invoked method ++ */ ++ template +- static EventId ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1); ++ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method + * @param a1 the first argument to pass to the invoked method + * @param a2 the second argument to pass to the invoked method + */ +- template +- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2); ++ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method +@@ -323,10 +318,9 @@ public: + * @param a2 the second argument to pass to the invoked method + * @param a3 the third argument to pass to the invoked method + */ +- template +- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3); ++ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method +@@ -335,11 +329,10 @@ public: + * @param a3 the third argument to pass to the invoked method + * @param a4 the fourth argument to pass to the invoked method + */ +- template +- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4); ++ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method +@@ -349,11 +342,10 @@ public: + * @param a4 the fourth argument to pass to the invoked method + * @param a5 the fifth argument to pass to the invoked method + */ +- template +- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); ++ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); + /** + * @param f the function to invoke + */ +@@ -414,27 +406,25 @@ public: + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method + */ +- template +- static EventId ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj); +- /** +- * @param mem_ptr member method pointer to invoke +- * @param obj the object on which to invoke the member method +- * @param a1 the first argument to pass to the invoked method +- */ +- template ++ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj); ++ /** ++ * @param mem_ptr member method pointer to invoke ++ * @param obj the object on which to invoke the member method ++ * @param a1 the first argument to pass to the invoked method ++ */ ++ template +- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1); ++ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method + * @param a1 the first argument to pass to the invoked method + * @param a2 the second argument to pass to the invoked method + */ +- template +- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2); ++ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method +@@ -442,10 +432,9 @@ public: + * @param a2 the second argument to pass to the invoked method + * @param a3 the third argument to pass to the invoked method + */ +- template +- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3); ++ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method +@@ -454,11 +443,10 @@ public: + * @param a3 the third argument to pass to the invoked method + * @param a4 the fourth argument to pass to the invoked method + */ +- template +- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4); ++ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4); + /** + * @param mem_ptr member method pointer to invoke + * @param obj the object on which to invoke the member method +@@ -468,11 +456,10 @@ public: + * @param a4 the fourth argument to pass to the invoked method + * @param a5 the fifth argument to pass to the invoked method + */ +- template +- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); ++ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); + /** + * @param f the function to invoke + */ +@@ -569,29 +556,24 @@ private: + Simulator (); + ~Simulator (); + +- template +- static Ptr MakeEvent (void (T::*mem_ptr) (void), OBJ obj); +- template ++ static Ptr MakeEvent (MEM mem_ptr, OBJ obj); ++ template +- static Ptr MakeEvent (void (T::*mem_ptr) (U1), OBJ obj, T1 a1); +- template MakeEvent (MEM mem_ptr, OBJ obj, T1 a1); ++ template +- static Ptr MakeEvent (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2); +- template MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2); ++ template +- static Ptr MakeEvent (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3); +- template MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); ++ template +- static Ptr MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4); +- template MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4); ++ template +- static Ptr MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); ++ static Ptr MakeEvent (MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); + static Ptr MakeEvent (void (*f) (void)); + template +@@ -649,14 +631,13 @@ struct EventMemberImplObjTraits + } + }; + +-template +-Ptr Simulator::MakeEvent (void (T::*mem_ptr) (void), OBJ obj) ++template ++Ptr Simulator::MakeEvent (MEM mem_ptr, OBJ obj) + { + // zero argument version + class EventMemberImpl0 : public EventImpl { + public: +- typedef void (T::*F)(void); +- EventMemberImpl0 (OBJ obj, F function) ++ EventMemberImpl0 (OBJ obj, MEM function) + : m_obj (obj), + m_function (function) + {} +@@ -666,22 +647,20 @@ Ptr Simulator::MakeEvent (voi + (EventMemberImplObjTraits::GetReference (m_obj).*m_function) (); + } + OBJ m_obj; +- F m_function; ++ MEM m_function; + } * ev = new EventMemberImpl0 (obj, mem_ptr); + return Ptr (ev, false); + } + + +-template +-Ptr Simulator::MakeEvent (void (T::*mem_ptr) (U1), OBJ obj, T1 a1) ++Ptr Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1) + { + // one argument version + class EventMemberImpl1 : public EventImpl { + public: +- typedef void (T::*F)(U1); +- EventMemberImpl1 (OBJ obj, F function, T1 a1) ++ EventMemberImpl1 (OBJ obj, MEM function, T1 a1) + : m_obj (obj), + m_function (function), + m_a1 (a1) +@@ -693,23 +672,20 @@ Ptr Simulator::MakeEvent (voi + (EventMemberImplObjTraits::GetReference (m_obj).*m_function) (m_a1); + } + OBJ m_obj; +- F m_function; ++ MEM m_function; + typename TypeTraits::ReferencedType m_a1; + } *ev = new EventMemberImpl1 (obj, mem_ptr, a1); + return Ptr (ev, false); + } + +-template +-Ptr Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2) ++Ptr Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2) + { + // two argument version + class EventMemberImpl2 : public EventImpl { + public: +- typedef void (T::*F)(U1, U2); +- +- EventMemberImpl2 (OBJ obj, F function, T1 a1, T2 a2) ++ EventMemberImpl2 (OBJ obj, MEM function, T1 a1, T2 a2) + : m_obj (obj), + m_function (function), + m_a1 (a1), +@@ -722,24 +698,21 @@ Ptr Simulator::MakeEvent (voi + (EventMemberImplObjTraits::GetReference (m_obj).*m_function) (m_a1, m_a2); + } + OBJ m_obj; +- F m_function; ++ MEM m_function; + typename TypeTraits::ReferencedType m_a1; + typename TypeTraits::ReferencedType m_a2; + } *ev = new EventMemberImpl2 (obj, mem_ptr, a1, a2); + return Ptr (ev, false); + } + +-template +-Ptr Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3) ++Ptr Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3) + { + // three argument version + class EventMemberImpl3 : public EventImpl { + public: +- typedef void (T::*F)(U1,U2,U3); +- +- EventMemberImpl3 (OBJ obj, F function, T1 a1, T2 a2, T3 a3) ++ EventMemberImpl3 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3) + : m_obj (obj), + m_function (function), + m_a1 (a1), +@@ -753,7 +726,7 @@ Ptr Simulator::MakeEvent (voi + (EventMemberImplObjTraits::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3); + } + OBJ m_obj; +- F m_function; ++ MEM m_function; + typename TypeTraits::ReferencedType m_a1; + typename TypeTraits::ReferencedType m_a2; + typename TypeTraits::ReferencedType m_a3; +@@ -761,17 +734,14 @@ Ptr Simulator::MakeEvent (voi + return Ptr (ev, false); + } + +-template +-Ptr Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) ++Ptr Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) + { + // four argument version + class EventMemberImpl4 : public EventImpl { + public: +- typedef void (T::*F)(U1, U2, U3, U4); +- +- EventMemberImpl4 (OBJ obj, F function, T1 a1, T2 a2, T3 a3, T4 a4) ++ EventMemberImpl4 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4) + : m_obj (obj), + m_function (function), + m_a1 (a1), +@@ -786,7 +756,7 @@ Ptr Simulator::MakeEvent (voi + (EventMemberImplObjTraits::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4); + } + OBJ m_obj; +- F m_function; ++ MEM m_function; + typename TypeTraits::ReferencedType m_a1; + typename TypeTraits::ReferencedType m_a2; + typename TypeTraits::ReferencedType m_a3; +@@ -795,18 +765,15 @@ Ptr Simulator::MakeEvent (voi + return Ptr (ev, false); + } + +-template +-Ptr Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) ++Ptr Simulator::MakeEvent (MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) + { + // five argument version + class EventMemberImpl5 : public EventImpl { + public: +- typedef void (T::*F)(U1, U2, U3, U4, U5); +- +- EventMemberImpl5 (OBJ obj, F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) ++ EventMemberImpl5 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) + : m_obj (obj), + m_function (function), + m_a1 (a1), +@@ -822,7 +789,7 @@ Ptr Simulator::MakeEvent (voi + (EventMemberImplObjTraits::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5); + } + OBJ m_obj; +- F m_function; ++ MEM m_function; + typename TypeTraits::ReferencedType m_a1; + typename TypeTraits::ReferencedType m_a2; + typename TypeTraits::ReferencedType m_a3; +@@ -975,50 +942,45 @@ Ptr Simulator::MakeEvent (voi + return Ptr (ev, false); + } + +-template +-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (void), OBJ obj) ++template ++EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj) + { + return Schedule (time, MakeEvent (mem_ptr, obj)); + } + + +-template +-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1), OBJ obj, T1 a1) ++EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1) + { + return Schedule (time, MakeEvent (mem_ptr, obj, a1)); + } + +-template +-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2) ++EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2) + { + return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2)); + } + +-template +-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3) ++EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3) + { + return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3)); + } + +-template +-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) ++EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) + { + return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4)); + } + +-template +-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, +- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) ++EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, ++ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) + { + return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5)); + } +@@ -1060,55 +1022,50 @@ EventId Simulator::Schedule (Time const + + + +-template +-EventId +-Simulator::ScheduleNow (void (T::*mem_ptr) (void), OBJ obj) ++template ++EventId ++Simulator::ScheduleNow (MEM mem_ptr, OBJ obj) + { + return ScheduleNow (MakeEvent (mem_ptr, obj)); + } + + +-template + EventId +-Simulator::ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1) ++Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1) + { + return ScheduleNow (MakeEvent (mem_ptr, obj, a1)); + } + +-template + EventId +-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2) ++Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2) + { + return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2)); + } + +-template + EventId +-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3) ++Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3) + { + return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3)); + } + +-template + EventId +-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) ++Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) + { + return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4)); + } + +-template + EventId +-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, ++Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, + T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) + { + return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5)); +@@ -1156,55 +1113,50 @@ Simulator::ScheduleNow (void (*f) (U1,U2 + + + +-template +-EventId +-Simulator::ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj) ++template ++EventId ++Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj) + { + return ScheduleDestroy (MakeEvent (mem_ptr, obj)); + } + + +-template + EventId +-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1) ++Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1) + { + return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1)); + } + +-template + EventId +-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2) ++Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2) + { + return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2)); + } + +-template + EventId +-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3) ++Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3) + { + return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3)); + } + +-template + EventId +-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) ++Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) + { + return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4)); + } + +-template + EventId +-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj, ++Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, + T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) + { + return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5)); +diff -r 2cc09d5a04c4 -r 4743aef86605 wscript +--- a/wscript Mon Aug 20 13:40:15 2007 -0700 ++++ b/wscript Fri Aug 24 13:29:51 2007 -0700 +@@ -37,7 +37,7 @@ def set_options(opt): + + opt.add_option('-d', '--debug-level', + action='callback', +- type=str, dest='debug_level', default='debug', ++ type="string", dest='debug_level', default='debug', + help=('Specify the debug level, does nothing if CFLAGS is set' + ' in the environment. [Allowed Values: debug, optimized].' + ' WARNING: this option only has effect ' + +changeset: 1312:c77745b2731c +user: Craig Dowell +date: Fri Aug 24 16:57:54 2007 -0700 +summary: add ipv4 methods, remove source multicast route requirement, fix udp socket source address prob + +diff -r 4743aef86605 -r c77745b2731c examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Fri Aug 24 13:29:51 2007 -0700 ++++ b/examples/csma-multicast.cc Fri Aug 24 16:57:54 2007 -0700 +@@ -84,6 +84,21 @@ main (int argc, char *argv[]) + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); + #endif ++ ++ DebugComponentEnable("Channel"); ++ DebugComponentEnable("CsmaChannel"); ++ DebugComponentEnable("CsmaMulticast"); ++ DebugComponentEnable("CsmaNetDevice"); ++ DebugComponentEnable("OnOffApplication"); ++ DebugComponentEnable("PacketSocket"); ++ DebugComponentEnable("UdpSocket"); ++ DebugComponentEnable("UdpL4Protocol"); ++ DebugComponentEnable("Ipv4L3Protocol"); ++ DebugComponentEnable("Ipv4StaticRouting"); ++ DebugComponentEnable("Ipv4Interface"); ++ DebugComponentEnable("ArpIpv4Interface"); ++ DebugComponentEnable("Ipv4LoopbackInterface"); ++ + // + // Set up default values for the simulation. Use the DefaultValue::Bind() + // technique to tell the system what subclass of Queue to use. The Bind +@@ -151,56 +166,32 @@ main (int argc, char *argv[]) + // We've got the "hardware" in place. Now we need to add IP addresses. + // + NS_DEBUG("Assign IP Addresses."); +-// +-// XXX BUGBUG +-// Need a better way to get the interface index. The point-to-point topology +-// as implemented can't return the index since it creates interfaces on both +-// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a +-// method on Ipv4 to find the interface index corresponding to a given ipv4 +-// address. +-// +-// First, assign IP addresses to the net devices and associated interfaces +-// on Lan0. The AddIpv4Address method returns an Ipv4 interface index. +-// Interpret ifIndexNd0 as the interface index to use to reference the +-// net device we created on node zero when coming in from the Ipv4 interface. +-// Net device numbers and interface indices are distinct. Interpret +-// ifIndexNd2Lan0 as the interface index to use to reference the +-// net device we created that connects node two to lan zero. +-// +- uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, +- Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNd1 = CsmaIpv4Topology::AddIpv4Address (n1, nd1, +- Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNd2Lan0 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, +- Ipv4Address ("10.1.1.3"), Ipv4Mask ("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), ++ Ipv4Mask ("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), ++ Ipv4Mask ("255.255.255.0")); ++ ++// ++// We'll need these addresses later ++// ++ Ipv4Address n2Lan0Addr ("10.1.1.3"); ++ Ipv4Address n2Lan1Addr ("10.1.2.1"); ++ ++ CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, n2Lan0Addr, ++ Ipv4Mask ("255.255.255.0")); + // + // Assign IP addresses to the net devices and associated interfaces on Lan1 + // +- uint32_t ifIndexNd2Lan1 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, +- Ipv4Address ("10.1.2.1"), Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNd3 = CsmaIpv4Topology::AddIpv4Address (n3, nd1, +- Ipv4Address ("10.1.2.2"), Ipv4Mask ("255.255.255.0")); +- +- uint32_t ifIndexNd4 = CsmaIpv4Topology::AddIpv4Address (n4, nd4, +- Ipv4Address ("10.1.2.3"), Ipv4Mask ("255.255.255.0")); +- +- NS_DEBUG ("ifIndexNd0 = " << ifIndexNd0); +- NS_DEBUG ("ifIndexNd1 = " << ifIndexNd1); +- NS_DEBUG ("ifIndexNd2Lan0 = " << ifIndexNd2Lan0); +- NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); +- NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); +- NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); +-// +-// A little silliness to let optimized code work while still printing all +-// results in debug code (without attribute). +-// +- nd3 = nd3; +- ifIndexNd1 = ifIndexNd1; +- ifIndexNd3 = ifIndexNd3; +- ifIndexNd4 = ifIndexNd4; ++ CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, n2Lan1Addr, ++ Ipv4Mask ("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address (n3, nd1, Ipv4Address ("10.1.2.2"), ++ Ipv4Mask ("255.255.255.0")); ++ ++ CsmaIpv4Topology::AddIpv4Address (n4, nd4, Ipv4Address ("10.1.2.3"), ++ Ipv4Mask ("255.255.255.0")); + + NS_DEBUG("Configure multicasting."); + // +@@ -216,34 +207,35 @@ main (int argc, char *argv[]) + // + // We are going to manually configure multicast routing. This means telling + // node two that it should expect multicast data coming from IP address +-// 10.1.1.1 over its IP interface connected to Lan0. These are called +-// multicastSource and ifIndexNd2Lan0 respectively. When node two receives +-// these packets, they should be forwarded out the interface that connects it +-// to Lan1 which is called ifIndexNd2Lan1. All we need to do is to call the +-// AddMulticastRoute method on node two's Ipv4 interface and provide this +-// information. (Note: the vector of output interfaces is in case there are +-// multiple net devices on a node). ++// 10.1.1.1 originally. It should expect these data coming in over its IP ++// interface connected to Lan0. When node two receives these packets, they ++// should be forwarded out the interface that connects it to Lan1. ++// ++// We're going to need the interface indices on node two corresponding to ++// these interfaces, which we call ifIndexLan0 and ifIndexLan1. The most ++// general way to get these interfaces is to look them up by IP address. ++// Looking back to the topology creation calls above, we saved the addresses ++// assigned to the interface connecting node two to Lan0 and Lan1. Now is ++// a fine time to find the interface indices on node two. + // + Ptr ipv4; + ipv4 = n2->QueryInterface (Ipv4::iid); + ++ uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr(n2Lan0Addr); ++ uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr(n2Lan1Addr); ++// ++// Now, we need to do is to call the AddMulticastRoute () method on node ++// two's Ipv4 interface and tell it that whenever it receives a packet on ++// the interface from Lan0, with the packet from the multicast source, ++// destined for the multicast group, it should forward these packets down ++// the interface connecting it to Lan1. (Note: the vector of output ++// interfaces is in case there are multiple net devices on a node -- not ++// true in this case). ++// + std::vector outputInterfaces (1); +- outputInterfaces[0] = ifIndexNd2Lan1; +- +- ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0, +- outputInterfaces); +-// +-// We also need to explain to the node zero forwarding code that when it sees +-// a packet destined for the multicast group it needs to send it out its +-// one and only interface. The 0xffffffff in the call means that the input +-// interface qualification is not applicable in this case (the packet has +-// not been received over an interface, it has been created locally). +-// +- ipv4 = n0->QueryInterface (Ipv4::iid); +- +- outputInterfaces[0] = ifIndexNd0;; +- +- ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0xffffffff, ++ outputInterfaces[0] = ifIndexLan1; ++ ++ ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0, + outputInterfaces); + // + // As described above, node four will be the only node listening for the +diff -r 4743aef86605 -r c77745b2731c src/internet-node/ipv4-impl.cc +--- a/src/internet-node/ipv4-impl.cc Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/ipv4-impl.cc Fri Aug 24 16:57:54 2007 -0700 +@@ -136,11 +136,25 @@ Ipv4Impl::AddInterface (Ptr d + { + return m_ipv4->AddInterface (device); + } ++ + uint32_t + Ipv4Impl::GetNInterfaces (void) + { + return m_ipv4->GetNInterfaces (); + } ++ ++uint32_t ++Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr) const ++{ ++ return m_ipv4->FindInterfaceForAddr (addr); ++} ++ ++uint32_t ++Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const ++{ ++ return m_ipv4->FindInterfaceForAddr (addr, mask); ++} ++ + Ptr + Ipv4Impl::GetNetDevice (uint32_t i) + { +diff -r 4743aef86605 -r c77745b2731c src/internet-node/ipv4-impl.h +--- a/src/internet-node/ipv4-impl.h Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/ipv4-impl.h Fri Aug 24 16:57:54 2007 -0700 +@@ -72,6 +72,11 @@ public: + + virtual uint32_t AddInterface (Ptr device); + virtual uint32_t GetNInterfaces (void); ++ ++ virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const; ++ virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, ++ Ipv4Mask mask) const; ++ + virtual Ptr GetNetDevice(uint32_t i); + + virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); +diff -r 4743aef86605 -r c77745b2731c src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Fri Aug 24 16:57:54 2007 -0700 +@@ -278,6 +278,33 @@ Ipv4L3Protocol::Lookup ( + return; + } + ++ if (ipHeader.GetDestination ().IsMulticast () && ++ ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY) ++ { ++ NS_DEBUG ("Ipv4L3Protocol::Lookup (): " ++ "Multicast destination with local source"); ++// ++// We have a multicast packet originating from the current node. We didn't ++// want to force users to construct a route in order to get packets out of a ++// node, so there will have been no route found and it is left to us to send ++// the packet. What we'll do is to send the multicast out all of the ++// interfaces on this node. ++// ++ NS_DEBUG ("Ipv4StaticRouting::Lookup (): " ++ "Local source. Flooding multicast packet"); ++ ++ for (uint32_t i = 0; i < GetNInterfaces (); ++i) ++ { ++ Packet p = packet; ++ Ipv4Header h = ipHeader; ++ Ipv4Route route = ++ Ipv4Route::CreateHostRouteTo(h.GetDestination (), i); ++ NS_DEBUG ("Ipv4StaticRouting::Lookup (): " ++ "Send via interface " << i); ++ routeReply (true, route, p, h); ++ } ++ return; ++ } + // No route found + routeReply (false, Ipv4Route (), packet, ipHeader); + } +@@ -397,6 +424,49 @@ Ipv4L3Protocol::GetNInterfaces (void) co + { + NS_DEBUG("Ipv4L3Protocol::GetNInterface ()"); + return m_nInterfaces; ++} ++ ++uint32_t ++Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const ++{ ++ NS_DEBUG("Ipv4L3Protocol::FindInterfaceForAddr (" << addr << ")"); ++ ++ uint32_t ifIndex = 0; ++ for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); ++ i != m_interfaces.end (); ++ i++, ifIndex++) ++ { ++ if ((*i)->GetAddress () == addr) ++ { ++ return ifIndex; ++ } ++ } ++ ++ NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): " ++ "Interface not found for IP address"); ++ return 0; ++} ++ ++uint32_t ++Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const ++{ ++ NS_DEBUG("Ipv4L3Protocol::FindInterfaceForAddr (" << addr << ", " << ++ mask << ")"); ++ ++ uint32_t ifIndex = 0; ++ for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); ++ i != m_interfaces.end (); ++ i++, ifIndex++) ++ { ++ if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask)) ++ { ++ return ifIndex; ++ } ++ } ++ ++ NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): " ++ "Interface not found for masked IP address"); ++ return 0; + } + + Ipv4Interface * +@@ -713,7 +783,40 @@ Ipv4L3Protocol::GetIfIndexForDestination + return true; + } + } +- return false; ++// ++// If there's no routing table entry telling us what single interface will be ++// used to send a packet to this destination, we'll have to just pick one. ++// If there's only one interface on this node, a good answer isn't very hard ++// to come up with. Before jumping to any conclusions, remember that the ++// zeroth interface is the loopback interface, so what we actually want is ++// a situation where there are exactly two interfaces on the node, in which ++// case interface one is the "single" interface. ++// ++ if (GetNInterfaces () == 2) ++ { ++ NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " ++ "One Interface. Using interface 1."); ++ ifIndex = 1; ++ return true; ++ } ++// ++// If we fall through to here, we have a node with multiple interfaces and ++// no routes to guide us in determining what interface to choose. The last ++// choice is to use the one set in the default route. ++// ++ NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " ++ "Using default route"); ++ Ipv4Route *route = m_staticRouting->GetDefaultRoute (); ++ ++ NS_ASSERT_MSG(route, ++ "Ipv4L3Protocol::GetIfIndexForDestination (): " ++ "Unable to determine outbound interface. No default route set"); ++ ++ ifIndex = route->GetInterface (); ++ ++ NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " ++ "Default route specifies interface " << ifIndex); ++ return true; + } + + uint16_t +diff -r 4743aef86605 -r c77745b2731c src/internet-node/ipv4-l3-protocol.h +--- a/src/internet-node/ipv4-l3-protocol.h Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.h Fri Aug 24 16:57:54 2007 -0700 +@@ -174,9 +174,12 @@ public: + uint32_t AddInterface (Ptr device); + Ipv4Interface * GetInterface (uint32_t i) const; + uint32_t GetNInterfaces (void) const; ++ ++ uint32_t FindInterfaceForAddr (Ipv4Address addr) const; ++ uint32_t FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const; + +- virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); +- virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); + + void SetAddress (uint32_t i, Ipv4Address address); + void SetNetworkMask (uint32_t i, Ipv4Mask mask); +diff -r 4743aef86605 -r c77745b2731c src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Fri Aug 24 16:57:54 2007 -0700 +@@ -230,6 +230,20 @@ Ipv4StaticRouting::GetNRoutes (void) + n += m_networkRoutes.size (); + return n; + } ++ ++Ipv4Route * ++Ipv4StaticRouting::GetDefaultRoute () ++{ ++ if (m_defaultRoute != 0) ++ { ++ return m_defaultRoute; ++ } ++ else ++ { ++ return 0; ++ } ++} ++ + Ipv4Route * + Ipv4StaticRouting::GetRoute (uint32_t index) + { +@@ -331,14 +345,37 @@ Ipv4StaticRouting::RequestRoute ( + + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " << + ipHeader.GetDestination ()); +-// +-// 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 (ipHeader.GetDestination ().IsMulticast ()) + { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination"); +- ++// ++// We have a multicast packet we're going to send. There are two distinct ++// cases we need to support. The first is if the current node is the source ++// of the packet. In that case, we don't want to have to consult multicast ++// routing tables (nor build them) in order to send multicasts. The interface ++// index (ifIndex) is Ipv4RoutingProtocol::IF_INDEX_ANY if we're the source. ++// ++// The second case is if the current packet has gotten to us by being ++// received over one of our interfaces. In this case, ifIndex is set to the ++// index over which we received the packet. For these packets, we need to ++// consult the multicast routing table for a disposition. ++// ++// So, first let's see if we're the source. In this case, we don't consult ++// the routing tables, but just return false and let the caller (up in ++// ipv4-l3-protocol) flood the multicast packet out of all of its interfaces. ++// We can't really do it here even if we wanted to since we have no easy way ++// to get to the Ipv4 interface which we would need. ++// ++ if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY) ++ { ++ return false; ++ } ++// ++// If we fall through to this point, we have a multicast packet that has ++// not originated at this node. We need to deal with forwarding. Let's ++// see if we have a route, and if so go ahead and forward this puppy. ++// + Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), + ipHeader.GetDestination (), ifIndex); + +@@ -349,14 +386,15 @@ Ipv4StaticRouting::RequestRoute ( + for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) + { + Packet p = packet; ++ Ipv4Header h = ipHeader; + Ipv4Route route = +- Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), ++ Ipv4Route::CreateHostRouteTo(h.GetDestination (), + mRoute->GetOutputInterface(i)); + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " + "Send via interface " << mRoute->GetOutputInterface(i)); +- routeReply (true, route, p, ipHeader); +- return true; +- } ++ routeReply (true, route, p, h); ++ } ++ return true; + } + return false; // Let other routing protocols try to handle this + } +diff -r 4743aef86605 -r c77745b2731c src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Fri Aug 24 16:57:54 2007 -0700 +@@ -74,6 +74,7 @@ public: + void SetDefaultRoute (Ipv4Address nextHop, + uint32_t interface); + uint32_t GetNRoutes (void); ++ Ipv4Route *GetDefaultRoute (void); + Ipv4Route *GetRoute (uint32_t i); + void RemoveRoute (uint32_t i); + +diff -r 4743aef86605 -r c77745b2731c src/internet-node/udp-socket.cc +--- a/src/internet-node/udp-socket.cc Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/internet-node/udp-socket.cc Fri Aug 24 16:57:54 2007 -0700 +@@ -182,10 +182,11 @@ UdpSocket::Connect(const Address & addre + NotifyConnectionSucceeded (); + m_connected = true; + ++ NS_DEBUG ("UdpSocket::Connect (): Updating local address"); + Ptr ipv4; + ipv4 = m_node->QueryInterface (Ipv4::iid); + m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress)); +- NS_DEBUG ("UdpSocket::Connect (): Local address is" << ++ NS_DEBUG ("UdpSocket::Connect (): Local address is " << + m_endPoint->GetLocalAddress()); + return 0; + } +@@ -214,9 +215,9 @@ UdpSocket::DoSendTo (const Packet &p, co + } + + int +-UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port) +-{ +- NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << ipv4 << ", " << ++UdpSocket::DoSendTo (const Packet &p, Ipv4Address addr, uint16_t port) ++{ ++ NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << addr << ", " << + port << ")"); + + if (m_endPoint == 0) +@@ -234,9 +235,16 @@ UdpSocket::DoSendTo (const Packet &p, Ip + return -1; + } + ++ NS_DEBUG ("UdpSocket::DoSendTo (): Finding source address"); ++ Ptr ipv4; ++ ipv4 = m_node->QueryInterface (Ipv4::iid); ++ ++ Ipv4Address source = ipv4->GetSourceAddress(m_defaultAddress); ++ NS_DEBUG ("UdpSocket::DoSendTo (): Source address is " << source); ++ + NS_DEBUG("UdpSocket::DoSendTo (): Send to UDP"); +- m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4, +- m_endPoint->GetLocalPort (), port); ++ m_udp->Send (p, source, addr, m_endPoint->GetLocalPort (), port); ++ + NotifyDataSent (p.GetSize ()); + return 0; + } +@@ -245,11 +253,13 @@ UdpSocket::SendTo(const Address &address + UdpSocket::SendTo(const Address &address, const Packet &p) + { + NS_DEBUG("UdpSocket::SendTo (" << address << ", " << &p << ")"); ++#if 0 + if (m_connected) + { + m_errno = ERROR_ISCONN; + return -1; + } ++#endif + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + Ipv4Address ipv4 = transport.GetIpv4 (); + uint16_t port = transport.GetPort (); +diff -r 4743aef86605 -r c77745b2731c src/node/ipv4.h +--- a/src/node/ipv4.h Fri Aug 24 13:29:51 2007 -0700 ++++ b/src/node/ipv4.h Fri Aug 24 16:57:54 2007 -0700 +@@ -275,6 +275,36 @@ public: + virtual uint32_t GetNInterfaces (void) = 0; + + /** ++ * \brief Find and return the interface ID of the interface that has been ++ * assigned the specified IP address. ++ * \param addr The IP address assigned to the interface of interest. ++ * \returns The index of the ipv4 interface with the given address. ++ * ++ * Each IP interface has an IP address associated with it. It is often ++ * useful to search the list of interfaces for one that corresponds to ++ * a known IP Address. This call takes an IP address as a parameter and ++ * returns the interface index of the first interface that has been assigned ++ * that address. If the address is not found, this function asserts. ++ */ ++ virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const = 0; ++ ++ /** ++ * \brief Find and return the interface ID of the interface that has been ++ * assigned the specified (masked) IP address. ++ * \param addr The IP address assigned to the interface of interest. ++ * \param mask The address mask to be used in address matching. ++ * \returns The index of the ipv4 interface with the given address. ++ * ++ * Each IP interface has an IP address associated with it. It is often ++ * useful to search the list of interfaces for one that corresponds to ++ * a known IP Address. This call takes an IP address and an IP address ++ * mask as parameters and returns the interface index of the first interface ++ * that matches the masked IP address. ++ */ ++ virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, ++ Ipv4Mask mask) const = 0; ++ ++ /** + * \param i index of ipv4 interface + * \returns the NetDevice associated with the ipv4 interface index + */ + +changeset: 1313:d6f8a7546e7f +user: Craig Dowell +date: Fri Aug 24 17:38:49 2007 -0700 +summary: semi-real multicast hardware addresses + +diff -r c77745b2731c -r d6f8a7546e7f src/devices/csma/csma-net-device.cc +--- a/src/devices/csma/csma-net-device.cc Fri Aug 24 16:57:54 2007 -0700 ++++ b/src/devices/csma/csma-net-device.cc Fri Aug 24 17:38:49 2007 -0700 +@@ -132,7 +132,7 @@ CsmaNetDevice::Init(bool sendEnable, boo + m_queue = 0; + + EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); +- EnableMulticast(); ++ EnableMulticast (Eui48Address ("01:00:5e:00:00:00")); + + SetSendEnable (sendEnable); + SetReceiveEnable (receiveEnable); +@@ -500,10 +500,11 @@ CsmaNetDevice::Receive (const Packet& pa + EthernetHeader header (false); + EthernetTrailer trailer; + Eui48Address broadcast; ++ Eui48Address multicast; + Eui48Address destination; + Packet p = packet; + +- NS_DEBUG ("CsmaNetDevice::Receive UID is (" << p.GetUid() << ")"); ++ NS_DEBUG ("CsmaNetDevice::Receive (): UID is " << p.GetUid()); + + // Only receive if send side of net device is enabled + if (!IsReceiveEnabled()) +@@ -522,12 +523,25 @@ CsmaNetDevice::Receive (const Packet& pa + trailer.CheckFcs(p); + p.RemoveHeader(header); + ++ NS_DEBUG ("CsmaNetDevice::Receive (): Pkt destination is " << ++ header.GetDestination ()); ++// ++// XXX BUGBUG ++// ++// An IP host group address is mapped to an Ethernet multicast address ++// by placing the low-order 23-bits of the IP address into the low-order ++// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). ++// ++// Need to mask off the appropriate multicast bits. ++// ++ multicast = Eui48Address::ConvertFrom (GetMulticast ()); + broadcast = Eui48Address::ConvertFrom (GetBroadcast ()); + destination = Eui48Address::ConvertFrom (GetAddress ()); + if ((header.GetDestination() != broadcast) && ++ (header.GetDestination() != multicast) && + (header.GetDestination() != destination)) + { +- // not for us. ++ NS_DEBUG ("CsmaNetDevice::Receive (): Dropping pkt "); + m_dropTrace (p); + return; + } +diff -r c77745b2731c -r d6f8a7546e7f src/devices/point-to-point/point-to-point-net-device.cc +--- a/src/devices/point-to-point/point-to-point-net-device.cc Fri Aug 24 16:57:54 2007 -0700 ++++ b/src/devices/point-to-point/point-to-point-net-device.cc Fri Aug 24 17:38:49 2007 -0700 +@@ -68,11 +68,14 @@ PointToPointNetDevice::PointToPointNetDe + { + NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")"); + +- // BUGBUG FIXME +- // +- // You _must_ support broadcast to get any sort of packet from the ARP layer. ++// BUGBUG FIXME ++// ++// You _must_ support broadcast to get any sort of packet from the ARP layer. + EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); +- EnableMulticast(); ++// ++// Randomly pick the ethernet multicast address base ++// ++ EnableMulticast (Eui48Address ("01:00:5e:00:00:00")); + EnablePointToPoint(); + } + +diff -r c77745b2731c -r d6f8a7546e7f src/internet-node/arp-ipv4-interface.cc +--- a/src/internet-node/arp-ipv4-interface.cc Fri Aug 24 16:57:54 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.cc Fri Aug 24 17:38:49 2007 -0700 +@@ -84,9 +84,18 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4 + else if (dest.IsMulticast ()) + { + NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast"); +- // XXX BUGBUG +- // Need real multicast addresses +- hardwareDestination = GetDevice ()->GetBroadcast (); ++ NS_ASSERT_MSG(GetDevice ()->IsMulticast (), ++ "ArpIpv4Interface::SendTo (): Sending multicast packet over " ++ "non-multicast device"); ++// XXX ++// ++// An IP host group address is mapped to an Ethernet multicast address ++// by placing the low-order 23-bits of the IP address into the low-order ++// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). ++// ++// Currently no easy way to or bit from Ipv4Address into Address ++// ++ hardwareDestination = GetDevice ()->GetMulticast (); + found = true; + } + else +diff -r c77745b2731c -r d6f8a7546e7f src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Fri Aug 24 16:57:54 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Fri Aug 24 17:38:49 2007 -0700 +@@ -288,12 +288,13 @@ Ipv4L3Protocol::Lookup ( + // want to force users to construct a route in order to get packets out of a + // node, so there will have been no route found and it is left to us to send + // the packet. What we'll do is to send the multicast out all of the +-// interfaces on this node. ++// interfaces on this node. Note that we start with interface 1 since we ++// don't particularly want to send the packet out the loopback. + // + NS_DEBUG ("Ipv4StaticRouting::Lookup (): " + "Local source. Flooding multicast packet"); + +- for (uint32_t i = 0; i < GetNInterfaces (); ++i) ++ for (uint32_t i = 1; i < GetNInterfaces (); ++i) + { + Packet p = packet; + Ipv4Header h = ipHeader; +diff -r c77745b2731c -r d6f8a7546e7f src/node/net-device.cc +--- a/src/node/net-device.cc Fri Aug 24 16:57:54 2007 -0700 ++++ b/src/node/net-device.cc Fri Aug 24 17:38:49 2007 -0700 +@@ -113,6 +113,7 @@ NetDevice::IsBroadcast (void) const + { + return m_isBroadcast; + } ++ + Address const & + NetDevice::GetBroadcast (void) const + { +@@ -139,10 +140,18 @@ NetDevice::IsMulticast (void) const + return m_isMulticast; + } + +-void +-NetDevice::EnableMulticast (void) ++Address const & ++NetDevice::GetMulticast (void) const ++{ ++ NS_ASSERT (m_isMulticast); ++ return m_multicast; ++} ++ ++void ++NetDevice::EnableMulticast (Address multicast) + { + m_isMulticast = true; ++ m_multicast = multicast; + } + + void +diff -r c77745b2731c -r d6f8a7546e7f src/node/net-device.h +--- a/src/node/net-device.h Fri Aug 24 16:57:54 2007 -0700 ++++ b/src/node/net-device.h Fri Aug 24 17:38:49 2007 -0700 +@@ -138,10 +138,21 @@ public: + * not true. + */ + Address const &GetBroadcast (void) const; ++ + /** + * \return value of m_isMulticast flag + */ + bool IsMulticast (void) const; ++ ++ /** ++ * \return the multicast address supported by ++ * this netdevice. ++ * ++ * Calling this method is invalid if IsMulticast returns ++ * not true. ++ */ ++ Address const &GetMulticast (void) const; ++ + /** + * \return value of m_isPointToPoint flag + */ +@@ -212,9 +223,10 @@ public: + */ + void DisableBroadcast (void); + /** +- * Set m_isMulticast flag to true +- */ +- void EnableMulticast (void); ++ * Enable multicast support. This method should be ++ * called by subclasses from their constructor ++ */ ++ void EnableMulticast (Address multicast); + /** + * Set m_isMulticast flag to false + */ +@@ -303,6 +315,7 @@ public: + uint16_t m_ifIndex; + Address m_address; + Address m_broadcast; ++ Address m_multicast; + uint16_t m_mtu; + bool m_isUp; + bool m_isBroadcast; + +changeset: 1314:bb5cf98c0c64 +user: Craig Dowell +date: Mon Aug 27 23:46:14 2007 -0700 +summary: real multicast enet addr, more source routes, default multicast route + +diff -r d6f8a7546e7f -r bb5cf98c0c64 examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/examples/csma-multicast.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -98,7 +98,6 @@ main (int argc, char *argv[]) + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); +- + // + // Set up default values for the simulation. Use the DefaultValue::Bind() + // technique to tell the system what subclass of Queue to use. The Bind +@@ -200,10 +199,11 @@ main (int argc, char *argv[]) + // earlier. We need to define a multicast group to send packets to. This + // can be any multicast address from 224.0.0.0 through 239.255.255.255 + // (avoiding the reserved routing protocol addresses). We just pick a +-// convenient number. ++// convenient number (225.0.0.0) and or in some bits to let us verify that ++// correct Ethernet multicast addresses are constructed down in the system. + // + Ipv4Address multicastSource ("10.1.1.1"); +- Ipv4Address multicastGroup ("225.0.0.0"); ++ Ipv4Address multicastGroup ("225.1.2.4"); + // + // We are going to manually configure multicast routing. This means telling + // node two that it should expect multicast data coming from IP address +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/devices/csma/csma-channel.cc +--- a/src/devices/csma/csma-channel.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/devices/csma/csma-channel.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -250,7 +250,7 @@ CsmaChannel::TransmitEnd() + } + + NS_DEBUG ("CsmaChannel::TransmitEnd (): Schedule event in " << +- m_delay.GetSeconds () << "sec"); ++ m_delay.GetSeconds () << " sec"); + + Simulator::Schedule (m_delay, + &CsmaChannel::PropagationCompleteEvent, +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/devices/csma/csma-net-device.cc +--- a/src/devices/csma/csma-net-device.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/devices/csma/csma-net-device.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -526,20 +526,29 @@ CsmaNetDevice::Receive (const Packet& pa + NS_DEBUG ("CsmaNetDevice::Receive (): Pkt destination is " << + header.GetDestination ()); + // +-// XXX BUGBUG +-// + // An IP host group address is mapped to an Ethernet multicast address + // by placing the low-order 23-bits of the IP address into the low-order + // 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). + // +-// Need to mask off the appropriate multicast bits. +-// ++// We are going to receive all packets destined to any multicast address, ++// which means clearing the low-order 23 bits the header destination ++// ++ Eui48Address mcDest; ++ uint8_t mcBuf[6]; ++ ++ header.GetDestination ().CopyTo (mcBuf); ++ mcBuf[3] &= 0x80; ++ mcBuf[4] = 0; ++ mcBuf[5] = 0; ++ mcDest.CopyFrom (mcBuf); ++ + multicast = Eui48Address::ConvertFrom (GetMulticast ()); + broadcast = Eui48Address::ConvertFrom (GetBroadcast ()); + destination = Eui48Address::ConvertFrom (GetAddress ()); +- if ((header.GetDestination() != broadcast) && +- (header.GetDestination() != multicast) && +- (header.GetDestination() != destination)) ++ ++ if ((header.GetDestination () != broadcast) && ++ (mcDest != multicast) && ++ (header.GetDestination () != destination)) + { + NS_DEBUG ("CsmaNetDevice::Receive (): Dropping pkt "); + m_dropTrace (p); +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/arp-ipv4-interface.cc +--- a/src/internet-node/arp-ipv4-interface.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -61,6 +61,74 @@ ArpIpv4Interface::DoCreateTraceResolver + return resolver; + } + ++// ++// RFC 1112 says that an IP host group address is mapped to an Ethernet ++// multicast address by placing the low-order 23-bits of the IP address into ++// the low-order 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 ++// (hex). These are completely different animals and they're encapsulated ++// very nicely. Translation: This isn't going to be very pretty. ++// ++Address ++ArpIpv4Interface::MakeMulticastAddress(Ipv4Address multicastGroup) ++{ ++ NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (" << multicastGroup << ++ ")"); ++// ++// First, get the generic multicast address from the device. Since it is ++// connected to this object, and this object is an IPV4 stack, we hope that ++// it is really an Eui48Address. If it's not, then we don't know what to do. ++// ++ Address hardwareDestination = GetDevice ()->GetMulticast (); ++ ++ NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " ++ "Device multicast address: " << hardwareDestination); ++ ++ Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination); ++// ++// We now have the multicast address in an abstract 48-bit container. We ++// need to pull it out so we can play with it. When we're done, we have the ++// high order bits in etherBuffer[0], etc. ++// ++ uint8_t etherBuffer[6]; ++ etherAddr.CopyTo (etherBuffer); ++// ++// If the device is playing the game correctly, the low order 23 bits of the ++// multicast base address will be zero. ++// ++ NS_ASSERT_MSG((etherBuffer[4] & 0x7f) == 0, ++ "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); ++ NS_ASSERT_MSG(etherBuffer[5] == 0, ++ "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); ++ NS_ASSERT_MSG(etherBuffer[6] == 0, ++ "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); ++// ++// Now we need to pull the raw bits out of the Ipv4 destination address. ++// ++ uint8_t ipBuffer[4]; ++ multicastGroup.Serialize (ipBuffer); ++// ++// We need to place the low order 23 bits of the IP address into the low order ++// 23 bits of the ethernet address. ++// ++ etherBuffer[3] |= ipBuffer[1] & 0x7f; ++ etherBuffer[4] = ipBuffer[2]; ++ etherBuffer[5] = ipBuffer[3]; ++// ++// Now, etherBuffer has the desired ethernet multicast address. We have to ++// suck these bits back into the Eui48Address; and then suck those bits back ++// into the abstract hardwareAddress. ++// ++ etherAddr.CopyFrom (etherBuffer); ++// ++// Implicit conversion (operator Address ()) is defined for Eui48Address, so ++// use it. ++// ++ NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " ++ "multicast address is " << etherAddr); ++ ++ return etherAddr; ++} ++ + void + ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) + { +@@ -87,15 +155,8 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4 + NS_ASSERT_MSG(GetDevice ()->IsMulticast (), + "ArpIpv4Interface::SendTo (): Sending multicast packet over " + "non-multicast device"); +-// XXX +-// +-// An IP host group address is mapped to an Ethernet multicast address +-// by placing the low-order 23-bits of the IP address into the low-order +-// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). +-// +-// Currently no easy way to or bit from Ipv4Address into Address +-// +- hardwareDestination = GetDevice ()->GetMulticast (); ++ ++ hardwareDestination = MakeMulticastAddress(dest); + found = true; + } + else +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/arp-ipv4-interface.h +--- a/src/internet-node/arp-ipv4-interface.h Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.h Mon Aug 27 23:46:14 2007 -0700 +@@ -24,6 +24,7 @@ + + #include "ipv4-interface.h" + #include "ns3/ptr.h" ++#include "ns3/eui48-address.h" + + namespace ns3 { + +@@ -46,6 +47,7 @@ class ArpIpv4Interface : public Ipv4Inte + virtual void SendTo (Packet p, Ipv4Address dest); + virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); + Ptr m_node; ++ Address MakeMulticastAddress (Ipv4Address multicastGroup); + }; + + }//namespace ns3 +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/ipv4-impl.cc +--- a/src/internet-node/ipv4-impl.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/ipv4-impl.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -105,6 +105,16 @@ Ipv4Impl::AddMulticastRoute (Ipv4Address + m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces); + } + ++void ++Ipv4Impl::SetDefaultMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ m_ipv4->SetDefaultMulticastRoute (origin, group, inputInterface, ++ outputInterfaces); ++} ++ + uint32_t + Ipv4Impl::GetNMulticastRoutes (void) const + { +@@ -208,6 +218,9 @@ Ipv4Impl::GetSourceAddress (Ipv4Address + } + else + { ++// ++// If we can't find any address, just leave it 0.0.0.0 ++// + return Ipv4Address::GetAny (); + } + } +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/ipv4-impl.h +--- a/src/internet-node/ipv4-impl.h Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/ipv4-impl.h Mon Aug 27 23:46:14 2007 -0700 +@@ -62,6 +62,10 @@ public: + uint32_t inputInterface, + std::vector outputInterfaces); + ++ virtual void SetDefaultMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, uint32_t inputInterface, ++ std::vector outputInterfaces); ++ + virtual uint32_t GetNMulticastRoutes (void) const; + virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const; + +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -352,6 +352,20 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4A + group << ", " << inputInterface << ", " << &outputInterfaces << ")"); + + m_staticRouting->AddMulticastRoute (origin, group, inputInterface, ++ outputInterfaces); ++} ++ ++void ++Ipv4L3Protocol::SetDefaultMulticastRoute ( ++ Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << origin << ", " << ++ group << ", " << inputInterface << ", " << &outputInterfaces << ")"); ++ ++ m_staticRouting->SetDefaultMulticastRoute (origin, group, inputInterface, + outputInterfaces); + } + +@@ -768,7 +782,11 @@ Ipv4L3Protocol::GetIfIndexForDestination + { + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (" << destination << + ", " << &ifIndex << ")"); +- ++// ++// The first thing we do in trying to determine a source address is to ++// consult the routing protocols. These will also check for a default route ++// if one has been set. ++// + for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin (); + i != m_routingProtocols.end (); + i++) +@@ -785,13 +803,13 @@ Ipv4L3Protocol::GetIfIndexForDestination + } + } + // +-// If there's no routing table entry telling us what single interface will be +-// used to send a packet to this destination, we'll have to just pick one. ++// If there's no routing table entry telling us what *single* interface will ++// be used to send a packet to this destination, we'll have to just pick one. + // If there's only one interface on this node, a good answer isn't very hard + // to come up with. Before jumping to any conclusions, remember that the + // zeroth interface is the loopback interface, so what we actually want is + // a situation where there are exactly two interfaces on the node, in which +-// case interface one is the "single" interface. ++// case interface one is the "single" interface connected to the outside world. + // + if (GetNInterfaces () == 2) + { +@@ -802,11 +820,21 @@ Ipv4L3Protocol::GetIfIndexForDestination + } + // + // If we fall through to here, we have a node with multiple interfaces and +-// no routes to guide us in determining what interface to choose. The last +-// choice is to use the one set in the default route. +-// ++// no routes to guide us in determining what interface to choose. Either ++// no default route was found (for unicast or multicast), or in the case of a ++// multicast, the default route contained multiple outbound interfaces. ++// ++// The fallback position is to just get the unicast default route and use ++// the outgoing interface specified there. We don't want to leave the source ++// address unset, so we just assert here. ++// ++// N.B. that in the case of a multicast with a route containing multiple ++// outgoing interfaces, the source address of packets from that node will be ++// set to the IP address of the interface set in the default unicast route. ++// Also, in the case of a broadcast, the same will be true. ++// + NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): " +- "Using default route"); ++ "Using default unicast route"); + Ipv4Route *route = m_staticRouting->GetDefaultRoute (); + + NS_ASSERT_MSG(route, +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/ipv4-l3-protocol.h +--- a/src/internet-node/ipv4-l3-protocol.h Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.h Mon Aug 27 23:46:14 2007 -0700 +@@ -163,6 +163,11 @@ public: + uint32_t inputInterface, + std::vector outputInterfaces); + ++ void SetDefaultMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces); ++ + uint32_t GetNMulticastRoutes (void) const; + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Mon Aug 27 23:46:14 2007 -0700 +@@ -26,6 +26,11 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRo + NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting"); + + namespace ns3 { ++ ++Ipv4StaticRouting::Ipv4StaticRouting () ++: m_defaultRoute (0), m_defaultMulticastRoute (0) ++{ ++} + + void + Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, +@@ -95,10 +100,24 @@ Ipv4StaticRouting::AddMulticastRoute(Ipv + m_multicastRoutes.push_back (route); + } + ++void ++Ipv4StaticRouting::SetDefaultMulticastRoute( ++ Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++{ ++ Ipv4MulticastRoute *route = new Ipv4MulticastRoute (); ++ *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, ++ inputInterface, outputInterfaces); ++ delete m_defaultMulticastRoute; ++ m_defaultMulticastRoute = route; ++} ++ + uint32_t + Ipv4StaticRouting::GetNMulticastRoutes (void) const + { +- return m_multicastRoutes.size (); ++ return m_multicastRoutes.size () + m_defaultMulticastRoute ? 1 : 0; + } + + Ipv4MulticastRoute * +@@ -106,17 +125,54 @@ Ipv4StaticRouting::GetMulticastRoute (ui + { + NS_ASSERT_MSG(index < m_multicastRoutes.size (), + "Ipv4StaticRouting::GetMulticastRoute (): Index out of range"); +- +- uint32_t tmp = 0; +- for (MulticastRoutesCI i = m_multicastRoutes.begin (); +- i != m_multicastRoutes.end (); +- i++) +- { +- if (tmp == index) +- { +- return *i; +- } +- tmp++; ++// ++// From an external point of view the default route appears to be in slot 0 ++// of the routing table. The implementation, however, puts it in a separate ++// place. So, if a client asks for index 0 and we have a default multicast ++// route, we have to return it from that different place ++// (m_defaultMulticastRoute). ++// ++ if (index == 0 && m_defaultMulticastRoute != 0) ++ { ++ return m_defaultMulticastRoute; ++ } ++// ++// If there is a default multicast route present, a client will just assume ++// that it is in slot zero and there is one "extra" zeroth route in the table. ++// To return the correct indexed entry in our list, we have to decrement the ++// index to take into account the default route not being in the actual list. ++// Since we fell through to here, we've taken care of the case where the ++// index was zero. ++// ++ if (m_defaultMulticastRoute != 0) ++ { ++ NS_ASSERT(index > 0); ++ index--; ++ } ++ ++ 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; ++} ++ ++Ipv4MulticastRoute * ++Ipv4StaticRouting::GetDefaultMulticastRoute () const ++{ ++ if (m_defaultMulticastRoute != 0) ++ { ++ return m_defaultMulticastRoute; + } + return 0; + } +@@ -126,6 +182,9 @@ Ipv4StaticRouting::RemoveMulticastRoute( + Ipv4Address group, + uint32_t inputInterface) + { ++// ++// This method does not attempt to delete the multicast route. ++// + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) +@@ -145,6 +204,32 @@ void + void + Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index) + { ++// ++// From an external point of view the default route appears to be in slot 0 ++// of the routing table. The implementation, however, puts it in a separate ++// place. So, if a client asks to delete index 0 and we have a default ++// multicast route set, we have to delete it from that different place ++// (m_defaultMulticastRoute). ++// ++ if (index == 0 && m_defaultMulticastRoute != 0) ++ { ++ delete m_defaultMulticastRoute; ++ m_defaultMulticastRoute = 0; ++ } ++// ++// If there is a default multicast route present, a client will just assume ++// that it is in slot zero and there is one "extra" zeroth route in the table. ++// To return the correct indexed entry in our list, we have to decrement the ++// index to take into account the default route not being in the actual list. ++// Since we fell through to here, we've taken care of the case where the ++// index was zero. ++// ++ if (m_defaultMulticastRoute != 0) ++ { ++ NS_ASSERT(index > 0); ++ index--; ++ } ++ + uint32_t tmp = 0; + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); +@@ -215,6 +300,12 @@ Ipv4StaticRouting::LookupStatic ( + } + } + } ++ ++ if (m_defaultMulticastRoute != 0) ++ { ++ return m_defaultMulticastRoute; ++ } ++ + return 0; + } + +@@ -492,6 +583,11 @@ Ipv4StaticRouting::DoDispose (void) + { + delete (*i); + } ++ if (m_defaultMulticastRoute != 0) ++ { ++ delete m_defaultMulticastRoute; ++ m_defaultMulticastRoute = 0; ++ } + Ipv4RoutingProtocol::DoDispose (); + } + +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Mon Aug 27 23:46:14 2007 -0700 +@@ -49,7 +49,7 @@ class Ipv4StaticRouting : public Ipv4Rou + { + + public: +- Ipv4StaticRouting () : m_defaultRoute (0) {} ++ Ipv4StaticRouting (); + + virtual bool RequestRoute (uint32_t ifIndex, + Ipv4Header const &ipHeader, +@@ -83,8 +83,14 @@ public: + uint32_t inputInterface, + std::vector outputInterfaces); + ++ void SetDefaultMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces); ++ + uint32_t GetNMulticastRoutes (void) const; + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; ++ Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const; + + void RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, +@@ -114,6 +120,7 @@ private: + HostRoutes m_hostRoutes; + NetworkRoutes m_networkRoutes; + Ipv4Route *m_defaultRoute; ++ Ipv4MulticastRoute *m_defaultMulticastRoute; + MulticastRoutes m_multicastRoutes; + }; + +diff -r d6f8a7546e7f -r bb5cf98c0c64 src/node/ipv4.h +--- a/src/node/ipv4.h Fri Aug 24 17:38:49 2007 -0700 ++++ b/src/node/ipv4.h Mon Aug 27 23:46:14 2007 -0700 +@@ -244,6 +244,19 @@ public: + uint32_t inputInterface) = 0; + + /** ++ * \brief Set the default static multicast route for a given multicast ++ * source and group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ * \param inputInterface The interface index over which the packet arrived. ++ * \param outputInterfaces The list of output interface indices over which ++ * the packet should be sent (excluding the inputInterface). ++ */ ++ virtual void SetDefaultMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, uint32_t inputInterface, ++ std::vector outputInterfaces) = 0; ++ /** + * \returns the number of entries in the multicast routing table. + */ + virtual uint32_t GetNMulticastRoutes (void) const = 0; + +changeset: 1315:580ed7a4dd1e +user: Craig Dowell +date: Wed Aug 29 12:11:11 2007 -0700 +summary: Move MakeMulticastAddress to NetDevice + +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/devices/csma/csma-net-device.cc +--- a/src/devices/csma/csma-net-device.cc Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/devices/csma/csma-net-device.cc Wed Aug 29 12:11:11 2007 -0700 +@@ -19,8 +19,6 @@ + * Author: Emmanuelle Laprise + */ + +-#include +-#include + #include "ns3/debug.h" + #include "ns3/queue.h" + #include "ns3/simulator.h" +@@ -60,7 +58,6 @@ CsmaTraceType::GetUid (void) + return uid; + } + +- + CsmaNetDevice::CsmaNetDevice (Ptr node) + : NetDevice (node, Eui48Address::Allocate ()), + m_bps (DataRate (0xffffffff)) +@@ -71,7 +68,7 @@ CsmaNetDevice::CsmaNetDevice (Ptr + } + + CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, +- CsmaEncapsulationMode encapMode) ++ CsmaEncapsulationMode encapMode) + : NetDevice(node, addr), + m_bps (DataRate (0xffffffff)) + { +@@ -82,8 +79,8 @@ CsmaNetDevice::CsmaNetDevice (Ptr + } + + CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, +- CsmaEncapsulationMode encapMode, +- bool sendEnable, bool receiveEnable) ++ CsmaEncapsulationMode encapMode, ++ bool sendEnable, bool receiveEnable) + : NetDevice(node, addr), + m_bps (DataRate (0xffffffff)) + { +@@ -582,6 +579,61 @@ CsmaNetDevice::Receive (const Packet& pa + return; + } + ++Address ++CsmaNetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const ++{ ++ NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (" << multicastGroup << ++ ")"); ++// ++// First, get the generic multicast address. ++// ++ Address hardwareDestination = GetMulticast (); ++ ++ NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): " ++ "Device multicast address: " << hardwareDestination); ++// ++// It's our address, and we know we're playing with an EUI-48 address here ++// primarily since we know that by construction, but also since the parameter ++// is an Ipv4Address. ++// ++ Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination); ++// ++// We now have the multicast address in an abstract 48-bit container. We ++// need to pull it out so we can play with it. When we're done, we have the ++// high order bits in etherBuffer[0], etc. ++// ++ uint8_t etherBuffer[6]; ++ etherAddr.CopyTo (etherBuffer); ++// ++// Now we need to pull the raw bits out of the Ipv4 destination address. ++// ++ uint8_t ipBuffer[4]; ++ multicastGroup.Serialize (ipBuffer); ++// ++// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48 ++// multicast address by placing the low-order 23-bits of the IP address into ++// the low-order 23 bits of the Ethernet multicast address ++// 01-00-5E-00-00-00 (hex). ++// ++ etherBuffer[3] |= ipBuffer[1] & 0x7f; ++ etherBuffer[4] = ipBuffer[2]; ++ etherBuffer[5] = ipBuffer[3]; ++// ++// Now, etherBuffer has the desired ethernet multicast address. We have to ++// suck these bits back into the Eui48Address, ++// ++ etherAddr.CopyFrom (etherBuffer); ++// ++// Implicit conversion (operator Address ()) is defined for Eui48Address, so ++// use it by just returning the EUI-48 address which is automagically converted ++// to an Address. ++// ++ NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): " ++ "multicast address is " << etherAddr); ++ ++ return etherAddr; ++} ++ + Ptr + CsmaNetDevice::GetQueue(void) const + { +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/devices/csma/csma-net-device.h +--- a/src/devices/csma/csma-net-device.h Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/devices/csma/csma-net-device.h Wed Aug 29 12:11:11 2007 -0700 +@@ -197,6 +197,37 @@ enum CsmaEncapsulationMode { + */ + void Receive (const Packet& p); + ++ /** ++ * @brief Make and return a MAC multicast address using the provided ++ * multicast group ++ * ++ * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet ++ * multicast address by placing the low-order 23-bits of the IP address into ++ * the low-order 23 bits of the Ethernet multicast address ++ * 01-00-5E-00-00-00 (hex). ++ * ++ * This method performs the multicast address creation function appropriate ++ * to an EUI-48-based CSMA device. This MAC address is encapsulated in an ++ * abstract Address to avoid dependencies on the exact address format. ++ * ++ * A default imlementation of MakeMulticastAddress is provided, but this ++ * method simply NS_ASSERTS. In the case of net devices that do not support ++ * multicast, clients are expected to test NetDevice::IsMulticast and avoid ++ * attempting to map multicast packets. Subclasses of NetDevice that do ++ * support multicasting are expected to override this method and provide an ++ * implementation appropriate to the particular device. ++ * ++ * @param multicastGroup The IP address for the multicast group destination ++ * of the packet. ++ * @return The MAC multicast Address used to send packets to the provided ++ * multicast group. ++ * ++ * @see Ipv4Address ++ * @see Eui48Address ++ * @see Address ++ */ ++ Address MakeMulticastAddress (Ipv4Address multicastGroup) const; ++ + bool IsSendEnabled (void); + bool IsReceiveEnabled (void); + +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/devices/point-to-point/point-to-point-net-device.cc +--- a/src/devices/point-to-point/point-to-point-net-device.cc Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/devices/point-to-point/point-to-point-net-device.cc Wed Aug 29 12:11:11 2007 -0700 +@@ -20,8 +20,6 @@ + * Revised: George Riley + */ + +-#include +-#include + #include "ns3/debug.h" + #include "ns3/queue.h" + #include "ns3/simulator.h" +@@ -73,7 +71,7 @@ PointToPointNetDevice::PointToPointNetDe + // You _must_ support broadcast to get any sort of packet from the ARP layer. + EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); + // +-// Randomly pick the ethernet multicast address base ++// We want to allow multicast packets to flow across this link + // + EnableMulticast (Eui48Address ("01:00:5e:00:00:00")); + EnablePointToPoint(); +@@ -214,6 +212,8 @@ bool PointToPointNetDevice::Attach (Ptr< + m_bps = m_channel->GetDataRate (); + // GFR Comment. Below is definitely wrong. Interframe gap + // is unrelated to channel delay. ++ // -- unlesss you want to introduce a default gap which is there to avoid ++ // parts of multiple packets flowing on the "wire" at the same time. + //m_tInterframeGap = m_channel->GetDelay (); + + /* +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/internet-node/arp-ipv4-interface.cc +--- a/src/internet-node/arp-ipv4-interface.cc Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.cc Wed Aug 29 12:11:11 2007 -0700 +@@ -61,74 +61,6 @@ ArpIpv4Interface::DoCreateTraceResolver + return resolver; + } + +-// +-// RFC 1112 says that an IP host group address is mapped to an Ethernet +-// multicast address by placing the low-order 23-bits of the IP address into +-// the low-order 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 +-// (hex). These are completely different animals and they're encapsulated +-// very nicely. Translation: This isn't going to be very pretty. +-// +-Address +-ArpIpv4Interface::MakeMulticastAddress(Ipv4Address multicastGroup) +-{ +- NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (" << multicastGroup << +- ")"); +-// +-// First, get the generic multicast address from the device. Since it is +-// connected to this object, and this object is an IPV4 stack, we hope that +-// it is really an Eui48Address. If it's not, then we don't know what to do. +-// +- Address hardwareDestination = GetDevice ()->GetMulticast (); +- +- NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " +- "Device multicast address: " << hardwareDestination); +- +- Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination); +-// +-// We now have the multicast address in an abstract 48-bit container. We +-// need to pull it out so we can play with it. When we're done, we have the +-// high order bits in etherBuffer[0], etc. +-// +- uint8_t etherBuffer[6]; +- etherAddr.CopyTo (etherBuffer); +-// +-// If the device is playing the game correctly, the low order 23 bits of the +-// multicast base address will be zero. +-// +- NS_ASSERT_MSG((etherBuffer[4] & 0x7f) == 0, +- "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); +- NS_ASSERT_MSG(etherBuffer[5] == 0, +- "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); +- NS_ASSERT_MSG(etherBuffer[6] == 0, +- "ArpIpv4Interface::SendTo (): Expected low order bits zeroed"); +-// +-// Now we need to pull the raw bits out of the Ipv4 destination address. +-// +- uint8_t ipBuffer[4]; +- multicastGroup.Serialize (ipBuffer); +-// +-// We need to place the low order 23 bits of the IP address into the low order +-// 23 bits of the ethernet address. +-// +- etherBuffer[3] |= ipBuffer[1] & 0x7f; +- etherBuffer[4] = ipBuffer[2]; +- etherBuffer[5] = ipBuffer[3]; +-// +-// Now, etherBuffer has the desired ethernet multicast address. We have to +-// suck these bits back into the Eui48Address; and then suck those bits back +-// into the abstract hardwareAddress. +-// +- etherAddr.CopyFrom (etherBuffer); +-// +-// Implicit conversion (operator Address ()) is defined for Eui48Address, so +-// use it. +-// +- NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): " +- "multicast address is " << etherAddr); +- +- return etherAddr; +-} +- + void + ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) + { +@@ -156,7 +88,7 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4 + "ArpIpv4Interface::SendTo (): Sending multicast packet over " + "non-multicast device"); + +- hardwareDestination = MakeMulticastAddress(dest); ++ hardwareDestination = GetDevice ()->MakeMulticastAddress(dest); + found = true; + } + else +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/internet-node/arp-ipv4-interface.h +--- a/src/internet-node/arp-ipv4-interface.h Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/internet-node/arp-ipv4-interface.h Wed Aug 29 12:11:11 2007 -0700 +@@ -47,7 +47,6 @@ class ArpIpv4Interface : public Ipv4Inte + virtual void SendTo (Packet p, Ipv4Address dest); + virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); + Ptr m_node; +- Address MakeMulticastAddress (Ipv4Address multicastGroup); + }; + + }//namespace ns3 +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Wed Aug 29 12:11:11 2007 -0700 +@@ -503,6 +503,8 @@ Ipv4L3Protocol::Receive( Ptr + { + NS_DEBUG("Ipv4L3Protocol::Receive (" << &device << ", " << &p << ", " << + protocol << ", " << from << ")"); ++ ++ NS_DEBUG("Ipv4L3Protocol::Receive (): Packet from " << from); + + uint32_t index = 0; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/node/net-device.cc +--- a/src/node/net-device.cc Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/node/net-device.cc Wed Aug 29 12:11:11 2007 -0700 +@@ -140,10 +140,19 @@ NetDevice::IsMulticast (void) const + return m_isMulticast; + } + +-Address const & ++Address + NetDevice::GetMulticast (void) const + { +- NS_ASSERT (m_isMulticast); ++ NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): " ++ "Invalid operation when not IsMulticast ()"); ++ return m_multicast; ++} ++ ++Address ++NetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const ++{ ++ NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): " ++ "Invalid operation when not IsMulticast ()"); + return m_multicast; + } + +diff -r bb5cf98c0c64 -r 580ed7a4dd1e src/node/net-device.h +--- a/src/node/net-device.h Mon Aug 27 23:46:14 2007 -0700 ++++ b/src/node/net-device.h Wed Aug 29 12:11:11 2007 -0700 +@@ -29,6 +29,7 @@ + #include "ns3/object.h" + #include "ns3/ptr.h" + #include "address.h" ++#include "ipv4-address.h" + + namespace ns3 { + +@@ -145,13 +146,61 @@ public: + bool IsMulticast (void) const; + + /** +- * \return the multicast address supported by +- * this netdevice. +- * +- * Calling this method is invalid if IsMulticast returns +- * not true. +- */ +- Address const &GetMulticast (void) const; ++ * \brief Return the MAC multicast base address used when mapping multicast ++ * groups to MAC multicast addresses. ++ * ++ * Typically when one constructs a multicast MAC addresses, some bits from ++ * the IP multicast group are copied into a corresponding MAC multicast ++ * group. In EUI-48, for example, the low order 23 bits of the multicast ++ * group are copied to the MAC multicast group base address. ++ * ++ * This method allows access to the underlying MAC multicast group base ++ * address. It is expected that in most cases, a net device client will ++ * allow the net device to perform the actual construction of the multicast ++ * address. Use of this method is discouraged unless you have a good reason ++ * to perform a custom mapping. You should prefer ++ * NetDevice::MakeMulticastAddress which will do the RFC-specified mapping ++ * for the net device in question. ++ * ++ * \return The multicast address supported by this net device. ++ * ++ * \warning Calling this method is invalid if IsMulticast returns not true. ++ * The method NS_ASSERTs if the device is not a multicast device. ++ * \see NetDevice::MakeMulticastAddress ++ */ ++ Address GetMulticast (void) const; ++ ++ /** ++ * \brief Make and return a MAC multicast address using the provided ++ * multicast group ++ * ++ * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet ++ * multicast address by placing the low-order 23-bits of the IP address into ++ * the low-order 23 bits of the Ethernet multicast address ++ * 01-00-5E-00-00-00 (hex). Similar RFCs exist for Ipv6 and Eui64 mappings. ++ * This method performs the multicast address creation function appropriate ++ * to the underlying MAC address of the device. This MAC address is ++ * encapsulated in an abstract Address to avoid dependencies on the exact ++ * MAC address format. ++ * ++ * A default imlementation of MakeMulticastAddress is provided, but this ++ * method simply NS_ASSERTS. In the case of net devices that do not support ++ * multicast, clients are expected to test NetDevice::IsMulticast and avoid ++ * attempting to map multicast packets. Subclasses of NetDevice that do ++ * support multicasting are expected to override this method and provide an ++ * implementation appropriate to the particular device. ++ * ++ * \param multicastGroup The IP address for the multicast group destination ++ * of the packet. ++ * \return The MAC multicast Address used to send packets to the provided ++ * multicast group. ++ * ++ * \warning Calling this method is invalid if IsMulticast returns not true. ++ * \see Ipv4Address ++ * \see Address ++ * \see NetDevice::IsMulticast ++ */ ++ virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + + /** + * \return value of m_isPointToPoint flag + +changeset: 1316:7c81b4e2617d +user: Craig Dowell +date: Tue Sep 04 14:38:40 2007 -0700 +summary: piles of doxygen, changes to SetDefaultMulticastRoute plumbing + +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/internet-node/ipv4-impl.cc +--- a/src/internet-node/ipv4-impl.cc Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/internet-node/ipv4-impl.cc Tue Sep 04 14:38:40 2007 -0700 +@@ -106,13 +106,9 @@ Ipv4Impl::AddMulticastRoute (Ipv4Address + } + + void +-Ipv4Impl::SetDefaultMulticastRoute (Ipv4Address origin, +- Ipv4Address group, +- uint32_t inputInterface, +- std::vector outputInterfaces) +-{ +- m_ipv4->SetDefaultMulticastRoute (origin, group, inputInterface, +- outputInterfaces); ++Ipv4Impl::SetDefaultMulticastRoute (uint32_t outputInterface) ++{ ++ m_ipv4->SetDefaultMulticastRoute (outputInterface); + } + + uint32_t +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/internet-node/ipv4-impl.h +--- a/src/internet-node/ipv4-impl.h Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/internet-node/ipv4-impl.h Tue Sep 04 14:38:40 2007 -0700 +@@ -62,9 +62,7 @@ public: + uint32_t inputInterface, + std::vector outputInterfaces); + +- virtual void SetDefaultMulticastRoute (Ipv4Address origin, +- Ipv4Address group, uint32_t inputInterface, +- std::vector outputInterfaces); ++ virtual void SetDefaultMulticastRoute (uint32_t outputInterface); + + virtual uint32_t GetNMulticastRoutes (void) const; + virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const; +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Tue Sep 04 14:38:40 2007 -0700 +@@ -356,17 +356,12 @@ Ipv4L3Protocol::AddMulticastRoute (Ipv4A + } + + void +-Ipv4L3Protocol::SetDefaultMulticastRoute ( +- Ipv4Address origin, +- Ipv4Address group, +- uint32_t inputInterface, +- std::vector outputInterfaces) +-{ +- NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << origin << ", " << +- group << ", " << inputInterface << ", " << &outputInterfaces << ")"); +- +- m_staticRouting->SetDefaultMulticastRoute (origin, group, inputInterface, +- outputInterfaces); ++Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface) ++{ ++ NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << outputInterface << ++ ")"); ++ ++ m_staticRouting->SetDefaultMulticastRoute (outputInterface); + } + + uint32_t +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/internet-node/ipv4-l3-protocol.h +--- a/src/internet-node/ipv4-l3-protocol.h Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.h Tue Sep 04 14:38:40 2007 -0700 +@@ -163,10 +163,7 @@ public: + uint32_t inputInterface, + std::vector outputInterfaces); + +- void SetDefaultMulticastRoute (Ipv4Address origin, +- Ipv4Address group, +- uint32_t inputInterface, +- std::vector outputInterfaces); ++ void SetDefaultMulticastRoute (uint32_t onputInterface); + + uint32_t GetNMulticastRoutes (void) const; + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Tue Sep 04 14:38:40 2007 -0700 +@@ -101,15 +101,19 @@ Ipv4StaticRouting::AddMulticastRoute(Ipv + } + + void +-Ipv4StaticRouting::SetDefaultMulticastRoute( +- Ipv4Address origin, +- Ipv4Address group, +- uint32_t inputInterface, +- std::vector outputInterfaces) +-{ ++Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface) ++{ ++ Ipv4Address origin = Ipv4Address::GetAny (); ++ Ipv4Address group = Ipv4Address::GetAny (); ++ uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY; ++ ++ std::vector outputInterfaces (1); ++ outputInterfaces[0] = outputInterface; ++ + Ipv4MulticastRoute *route = new Ipv4MulticastRoute (); + *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, + inputInterface, outputInterfaces); ++ + delete m_defaultMulticastRoute; + m_defaultMulticastRoute = route; + } +@@ -177,7 +181,7 @@ Ipv4StaticRouting::GetDefaultMulticastRo + return 0; + } + +-void ++bool + Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface) +@@ -196,9 +200,10 @@ Ipv4StaticRouting::RemoveMulticastRoute( + { + delete *i; + m_multicastRoutes.erase (i); +- return; +- } +- } ++ return true; ++ } ++ } ++ return false; + } + + void +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Tue Sep 04 14:38:40 2007 -0700 +@@ -45,57 +45,418 @@ class TraceContext; + class TraceContext; + + ++/** ++ * @brief Static 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). ++ * ++ * The Ipv4StaticRouting class inherits from the abstract base class ++ * Ipv4RoutingProtocol that defines the interface methods that a routing ++ * protocol must support. ++ * ++ * When a packet arrives in the Ipv4L3Protocol for transmission, it comes ++ * either from a local source via Ipv4L3Protocol::Send or from a remote ++ * source via Ipv4L3Protocol::Forwarding. In both cases, a function is called ++ * (Ipv4L3Protocol::Lookup) to look up the routing information for the packet. ++ * ++ * The lookup function iterates through the list of routing protocols asking ++ * each to see if it can find a route and send the packet. A callback is ++ * provided during each of these calls that should be considered a pre- ++ * packaged send call. This is done to allow asynchronous calls into ++ * routing subsystems in order to support on-demand routing, for example. The ++ * method for requesting this operation is Ipv4StaticRouting::RequestRoute for ++ * the static routing protocol. ++ * ++ * Each routing protocol is also free to implement its own methods for managing ++ * routes which you will find below. This class manages a set of "static" or ++ * manually configured routes for host, network and multicast routes. ++ * ++ * @see Ipv4RoutingProtocol ++ * @see Ipv4L3Protocol::AddRoutingProtocol ++ * @see Ipv4L3Protocol::Ipv4L3Protocol ++ */ + class Ipv4StaticRouting : public Ipv4RoutingProtocol + { +- + public: ++/** ++ * @brief Construct an empty Ipv4StaticRouting routing protocol, ++ * @internal ++ * ++ * The Ipv4StaticRouting class supports host, network and multicast routes. ++ * This method initializes the lists containing these routes to empty. ++ * ++ * @see Ipv4StaticRouting ++ */ + Ipv4StaticRouting (); + ++/** ++ * @brief Request that a check for a route bw performed and if a route is found ++ * that the packet be sent on its way using the pre-packaged send callback. ++ * ++ * The source and destination IP addresses for the packet in question are found ++ * in the provided Ipv4Header. There are two major processing forks depending ++ * on the type of destination address. ++ * ++ * If the destination address is unicast then the routing table is consulted ++ * for a route to the destination and if it is found, the routeReply callback ++ * is executed to send the packet (with the found route). ++ * ++ * If the destination address is a multicast, then the exact processing steps ++ * depend on whether or not the packet has been sourced locally. This is ++ * determined by the parameter ifIndex. This is the interface index over which ++ * this packet was received. If the packet has not been received over a ++ * network interface, this index will be set to ++ * Ipv4RoutingProtocol::IF_INDEX_ANY (a very large number). In that case, ++ * we want to avoid the requirement that an explicit route out of each node ++ * must be set, so we don't do anything here. ++ * ++ * If the packet is a multicast destination and has been received over a ++ * network interface, a call to this method implies that the packet is being ++ * forwarded. In that case, there must be an explicit route out of the node. ++ * A multicast route references the source address, the destination address ++ * (the multicast group) and the input interface in order to find a route. ++ * We consult the multicast routing table and, if a route is found, send the ++ * packet out of as many interfaces as required using the provided callback ++ * (think of it as a pre-packaged send call). ++ * ++ * @param ifIndex The network interface index over which the packed was ++ * received. If the packet is from a local source, ifIndex will be set to ++ * Ipv4RoutingProtocol::IF_INDEX_ANY. ++ * @param ipHeader the Ipv4Header containing the source and destination IP ++ * addresses for the packet. ++ * @param packet The packet to be sent if a route is found. ++ * @param routeReply A callback that packaged up the call to actually send the ++ * packet. ++ * @return Returns true if a route is found and the packet has been sent, ++ * otherwise returns false indicating that the next routing protocol should ++ * be consulted. In practice, the static routing protocol is the last chance ++ * protocol. ++ * ++ * @see Ipv4StaticRouting ++ * @see Ipv4RoutingProtocol ++ */ + virtual bool RequestRoute (uint32_t ifIndex, + Ipv4Header const &ipHeader, + Packet packet, + RouteReplyCallback routeReply); + ++/** ++ * @brief Check to see if we can determine the interface index that will be ++ * used if a packet is sent to this destination. ++ * ++ * This method addresses a problem in the IP stack where a destination address ++ * must be present and checksummed into the IP header before the actual ++ * interface over which the packet is sent can be determined. The answer is ++ * to implement a known and intentional cross-layer violation. This is the ++ * endpoint of a call chain that started up quite high in the stack (sockets) ++ * and has found its way down to the Ipv4L3Protocol which is consulting the ++ * routing protocols for what they would do if presented with a packet of the ++ * given destination. ++ * ++ * Note that the a single interface index is returned. This means that if ++ * the destination address is a multicast, and an explicit route is present ++ * that includeds multiple output interfaces, that route cannot be used. ++ * ++ * If there are multiple paths out of the node, the resolution is performed ++ * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more ++ * contextual information that is useful for making a determination. ++ * ++ * @param destination The Ipv4Address if the destination of a hypothetical ++ * packet. This may be a multicast group address. ++ * @param ifIndex A reference to the interface index over which a packet ++ * sent to this destination would be sent. ++ * @return Returns true if a route is found to the destination that involves ++ * a single output interface index, otherwise returns false indicating that ++ * the next routing protocol should be consulted. In practice, the static ++ * routing protocol is the last chance protocol. ++ * ++ * @see Ipv4StaticRouting ++ * @see Ipv4RoutingProtocol ++ * @see Ipv4L3Protocol ++ */ + virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex); + ++/** ++ * @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. ++ * ++ * @see Ipv4Address ++ */ + void AddHostRouteTo (Ipv4Address dest, + Ipv4Address nextHop, + uint32_t interface); ++/** ++ * @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. ++ * ++ * @see Ipv4Address ++ */ + void AddHostRouteTo (Ipv4Address dest, + uint32_t interface); + ++/** ++ * @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. ++ * ++ * @see Ipv4Address ++ */ + void AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + Ipv4Address nextHop, + uint32_t interface); ++ ++/** ++ * @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. ++ * ++ * @see Ipv4Address ++ */ + void AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + uint32_t interface); ++ ++/** ++ * @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. ++ * ++ * @see Ipv4Address ++ * @see Ipv4StaticRouting::Lookup ++ */ + void SetDefaultRoute (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 the default route from the static routing table. ++ * ++ * @return If the default route is set, a pointer to that Ipv4Route is ++ * returned, otherwise a zero pointer is returned. ++ * ++ * @see Ipv4Route ++ */ + Ipv4Route *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. The one sublety 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 explicity 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 Ipv4Route is returned, otherwise ++ * a zero pointer is returned. ++ * ++ * @see Ipv4Route ++ * @see Ipv4StaticRouting::RemoveRoute ++ */ + Ipv4Route *GetRoute (uint32_t i); ++ ++/** ++ * @brief Remove a route from the static unicast routing table. ++ * ++ * Externally, the unicast static routing table appears simply as a table with ++ * n entries. The one sublety 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 Ipv4Route ++ * @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 -- the address of the ++ * node that originates packets destined for a given multicast group. This ++ * address may be Ipv4Address::GetAny (typically 0.0.0.0) if the multicast ++ * group is open, or it may specify a single IP address if the multicast ++ * group is closed. The route must also specify the multicast group address. ++ * ++ * For each route, the input nework interface must be specified. For ++ * forwarding operations, this is the interface index that you expect multicast ++ * packets to arrive over. If you want to specify routes off of a local node ++ * for given multicast groups, this index may be set to ++ * Ipv4RoutingProtocol::IF_INDEX_ANY. ++ * ++ * For each route, a vector of output network interfaces must also be ++ * specified. When the RequestRoute operation is performed, copies of a ++ * packet are sent out all of the specified interfaces. ++ * ++ * @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::IF_INDEX_ANY for packets of local origin. ++ * @param outputInterface 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 outputInterfaces); + +- void SetDefaultMulticastRoute (Ipv4Address origin, +- Ipv4Address group, +- uint32_t inputInterface, +- std::vector 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. ++ * ++ * Since we're basically forwarding packets to some entity we think may know ++ * better what to do, we don't pay attention to subleties like origin address ++ * and input interface, 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, multicast group or ++ * input interface 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. The one sublety 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 explicity calling GetDefaultMulticastRoute () or by ++ * calling GetMulticastRoute (0). ++ * ++ * Similarly, if the default route has been set, calling ++ * RemoveMulticastRoute (0) will remove the default route. ++ * ++ * @param i The index (into the routing table) of the multicast route to ++ * retrieve. If the default route has been set, it will occupy index zero. ++ * @return If route is set, a pointer to that Ipv4MulticastRoute is ++ * returned, otherwise a zero pointer is returned. ++ * ++ * @see Ipv4MulticastRoute ++ * @see Ipv4StaticRouting::RemoveRoute ++ */ + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; ++ ++/** ++ * @brief Get the default multicast route from the static routing table. ++ * ++ * @return If the default route is set, a pointer to that Ipv4MulticastRoute is ++ * returned, otherwise a zero pointer is returned. ++ * ++ * @see Ipv4Route ++ */ + Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const; + +- void RemoveMulticastRoute (Ipv4Address origin, ++/** ++ * @brief Remove a route from the static multicast routing table. ++ * ++ * Externally, the multicast static routing table appears simply as a table ++ * with n entries. The one sublety of note is that if a default multicast ++ * route has been set it will appear as the zeroth entry in the table. This ++ * means that the default route may be removed by calling this method with ++ * appropriate wildcard parameters. ++ * ++ * This method causes the multicast routing table to be searched for the first ++ * route that matches the parameters and removes it. ++ * ++ * @param origin The IP address specified as the origin of packets for the ++ * route. ++ * @param origin The IP address specified as the multicast group addres of ++ * the route. ++ * @param inputInterfade 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 Ipv4Route ++ * @see Ipv4StaticRouting::GetRoute ++ * @see Ipv4StaticRouting::AddRoute ++ */ ++ 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. The one sublety of note is that if a default multicast ++ * 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 ++ * RemoveMulticastRoute (0) will remove the default route. ++ * ++ * @param index The index (into the multicast routing table) of the route to ++ * remove. If the default route has been set, it will occupy index zero. ++ * ++ * @see Ipv4Route ++ * @see Ipv4StaticRouting::GetRoute ++ * @see Ipv4StaticRouting::AddRoute ++ */ + void RemoveMulticastRoute (uint32_t index); + + protected: +diff -r 580ed7a4dd1e -r 7c81b4e2617d src/node/ipv4.h +--- a/src/node/ipv4.h Wed Aug 29 12:11:11 2007 -0700 ++++ b/src/node/ipv4.h Tue Sep 04 14:38:40 2007 -0700 +@@ -104,14 +104,38 @@ public: + const Ipv4Header &ipHeader, + Packet packet, + RouteReplyCallback routeReply) = 0; +- /** +- * \brief Synchronously request the interface index that will be used to +- * send a packet to a hypothetical destination. +- * +- * \param destination IP address of a hypothetical destination packet +- * \param ifIndex Reference to interface index. +- * \returns True if the protocol has a route, false otherwise. +- */ ++/** ++ * \brief Synchronously check to see if we can determine the interface index ++ * that will be used if a packet is sent to this destination. ++ * ++ * This method addresses a problem in the IP stack where a destination address ++ * must be present and checksummed into the IP header before the actual ++ * interface over which the packet is sent can be determined. The answer is ++ * to implement a known and intentional cross-layer violation. This is the ++ * endpoint of a call chain that started up quite high in the stack (sockets) ++ * and has found its way down to the Ipv4L3Protocol which is consulting the ++ * routing protocols for what they would do if presented with a packet of the ++ * given destination. ++ * ++ * Note that the a single interface index is returned. This means that if ++ * the destination address is a multicast, and an explicit route is present ++ * that includeds multiple output interfaces, that route cannot be used. ++ * ++ * If there are multiple paths out of the node, the resolution is performed ++ * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more ++ * contextual information that is useful for making a determination. ++ * ++ * \param destination The Ipv4Address if the destination of a hypothetical ++ * packet. This may be a multicast group address. ++ * \param ifIndex A reference to the interface index over which a packet ++ * sent to this destination would be sent. ++ * \return Returns true if a route is found to the destination that involves ++ * a single output interface index, otherwise false. ++ * ++ * \see Ipv4StaticRouting ++ * \see Ipv4RoutingProtocol ++ * \see Ipv4L3Protocol ++ */ + virtual bool RequestIfIndex (Ipv4Address destination, + uint32_t& ifIndex) = 0; + +@@ -207,11 +231,13 @@ public: + * \returns the number of entries in the routing table. + */ + virtual uint32_t GetNRoutes (void) = 0; ++ + /** + * \param i index of route to return + * \returns the route whose index is i + */ + virtual Ipv4Route GetRoute (uint32_t i) = 0; ++ + /** + * \param i index of route to remove from routing table. + */ +@@ -244,18 +270,13 @@ public: + uint32_t inputInterface) = 0; + + /** +- * \brief Set the default static multicast route for a given multicast +- * source and group. +- * +- * \param origin The Ipv4 address of the multicast source. +- * \param group The multicast group address. +- * \param inputInterface The interface index over which the packet arrived. +- * \param outputInterfaces The list of output interface indices over which +- * the packet should be sent (excluding the inputInterface). +- */ +- virtual void SetDefaultMulticastRoute (Ipv4Address origin, +- Ipv4Address group, uint32_t inputInterface, +- std::vector outputInterfaces) = 0; ++ * \brief Set the default static multicast route. ++ * ++ * \param outputInterface The network output interface index over which ++ * packets without specific routes should be sent. ++ */ ++ virtual void SetDefaultMulticastRoute (uint32_t outputInterface) = 0; ++ + /** + * \returns the number of entries in the multicast routing table. + */ +@@ -282,6 +303,7 @@ public: + * make sure that it is never used during packet forwarding. + */ + virtual uint32_t AddInterface (Ptr device) = 0; ++ + /** + * \returns the number of interfaces added by the user. + */ +@@ -346,39 +368,46 @@ public: + * \param address address to associate to the underlying ipv4 interface + */ + virtual void SetAddress (uint32_t i, Ipv4Address address) = 0; ++ + /** + * \param i index of ipv4 interface + * \param mask mask to associate to the underlying ipv4 interface + */ + virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0; ++ + /** + * \param i index of ipv4 interface + * \returns the mask associated to the underlying ipv4 interface + */ + virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0; ++ + /** + * \param i index of ipv4 interface + * \returns the address associated to the underlying ipv4 interface + */ + virtual Ipv4Address GetAddress (uint32_t i) const = 0; ++ + /** + * \param destination The IP address of a hypothetical destination. + * \returns The IP address assigned to the interface that will be used + * if we were to send a packet to destination. + */ + virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0; ++ + /** + * \param i index of ipv4 interface + * \returns the Maximum Transmission Unit (in bytes) associated + * to the underlying ipv4 interface + */ + virtual uint16_t GetMtu (uint32_t i) const = 0; ++ + /** + * \param i index of ipv4 interface + * \returns true if the underlying interface is in the "up" state, + * false otherwise. + */ + virtual bool IsUp (uint32_t i) const = 0; ++ + /** + * \param i index of ipv4 interface + * +@@ -386,6 +415,7 @@ public: + * considered valid during ipv4 forwarding. + */ + virtual void SetUp (uint32_t i) = 0; ++ + /** + * \param i index of ipv4 interface + * +@@ -393,7 +423,6 @@ public: + * ignored during ipv4 forwarding. + */ + virtual void SetDown (uint32_t i) = 0; +- + }; + + } // namespace ns3 + +changeset: 1317:3fba36666488 +user: Craig Dowell +date: Tue Sep 04 15:10:47 2007 -0700 +summary: Don't flood multicasts if no route found + +diff -r 7c81b4e2617d -r 3fba36666488 src/internet-node/ipv4-l3-protocol.cc +--- a/src/internet-node/ipv4-l3-protocol.cc Tue Sep 04 14:38:40 2007 -0700 ++++ b/src/internet-node/ipv4-l3-protocol.cc Tue Sep 04 15:10:47 2007 -0700 +@@ -284,29 +284,29 @@ Ipv4L3Protocol::Lookup ( + NS_DEBUG ("Ipv4L3Protocol::Lookup (): " + "Multicast destination with local source"); + // +-// We have a multicast packet originating from the current node. We didn't +-// want to force users to construct a route in order to get packets out of a +-// node, so there will have been no route found and it is left to us to send +-// the packet. What we'll do is to send the multicast out all of the +-// interfaces on this node. Note that we start with interface 1 since we +-// don't particularly want to send the packet out the loopback. +-// +- NS_DEBUG ("Ipv4StaticRouting::Lookup (): " +- "Local source. Flooding multicast packet"); +- +- for (uint32_t i = 1; i < GetNInterfaces (); ++i) +- { +- Packet p = packet; +- Ipv4Header h = ipHeader; +- Ipv4Route route = +- Ipv4Route::CreateHostRouteTo(h.GetDestination (), i); ++// We have a multicast packet originating from the current node and were not ++// able to send it using the usual RequestRoute process. Since the usual ++// process includes trying to use a default multicast route, this means that ++// there was no specific route out of the node found, and there was no default ++// multicast route set. ++// ++// The fallback position is to look for a default unicast route and use that ++// to get the packet off the node if we have one. ++// ++ Ipv4Route *route = m_staticRouting->GetDefaultRoute (); ++ ++ if (route) ++ { + NS_DEBUG ("Ipv4StaticRouting::Lookup (): " +- "Send via interface " << i); +- routeReply (true, route, p, h); +- } +- return; +- } +- // No route found ++ "Local source. Using unicast default route for multicast packet"); ++ ++ routeReply (true, *route, packet, ipHeader); ++ return; ++ } ++ } ++// ++// No route found ++// + routeReply (false, Ipv4Route (), packet, ipHeader); + } + +diff -r 7c81b4e2617d -r 3fba36666488 src/node/ipv4-route.cc +--- a/src/node/ipv4-route.cc Tue Sep 04 14:38:40 2007 -0700 ++++ b/src/node/ipv4-route.cc Tue Sep 04 15:10:47 2007 -0700 +@@ -30,11 +30,19 @@ namespace ns3 { + + Ipv4Route::Ipv4Route () + {} ++ + Ipv4Route::Ipv4Route (Ipv4Route const &route) + : m_dest (route.m_dest), + m_destNetworkMask (route.m_destNetworkMask), + m_gateway (route.m_gateway), + m_interface (route.m_interface) ++{} ++ ++Ipv4Route::Ipv4Route (Ipv4Route const *route) ++ : m_dest (route->m_dest), ++ m_destNetworkMask (route->m_destNetworkMask), ++ m_gateway (route->m_gateway), ++ m_interface (route->m_interface) + {} + + Ipv4Route::Ipv4Route (Ipv4Address dest, +@@ -236,6 +244,15 @@ Ipv4MulticastRoute::Ipv4MulticastRoute ( + { + } + ++Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const *route) ++: ++ m_origin (route->m_origin), ++ m_group (route->m_group), ++ m_inputInterface (route->m_inputInterface), ++ m_outputInterfaces (route->m_outputInterfaces) ++{ ++} ++ + Ipv4MulticastRoute::Ipv4MulticastRoute ( + Ipv4Address origin, + Ipv4Address group, +diff -r 7c81b4e2617d -r 3fba36666488 src/node/ipv4-route.h +--- a/src/node/ipv4-route.h Tue Sep 04 14:38:40 2007 -0700 ++++ b/src/node/ipv4-route.h Tue Sep 04 15:10:47 2007 -0700 +@@ -37,11 +37,18 @@ public: + * \brief This constructor does nothing + */ + Ipv4Route (); ++ + /** + * \brief Copy Constructor + * \param route The route to copy + */ + Ipv4Route (Ipv4Route const &route); ++ ++ /** ++ * \brief Copy Constructor ++ * \param route The route to copy ++ */ ++ Ipv4Route (Ipv4Route const *route); + + bool IsHost (void) const; + /** +@@ -108,11 +115,18 @@ public: + * \brief This constructor does nothing + */ + Ipv4MulticastRoute (); ++ + /** + * \brief Copy Constructor + * \param route The route to copy + */ + Ipv4MulticastRoute (Ipv4MulticastRoute const &route); ++ ++ /** ++ * \brief Copy Constructor ++ * \param route The route to copy ++ */ ++ Ipv4MulticastRoute (Ipv4MulticastRoute const *route); + + /** + * \return The IPv4 address of the source of this route + +changeset: 1318:f9bc98cbe5fe +user: Craig Dowell +date: Tue Sep 04 18:06:06 2007 -0700 +summary: clarify use of wildcards in multicast routes versus default mulicast routes. + +diff -r 3fba36666488 -r f9bc98cbe5fe examples/csma-multicast.cc +--- a/examples/csma-multicast.cc Tue Sep 04 15:10:47 2007 -0700 ++++ b/examples/csma-multicast.cc Tue Sep 04 18:06:06 2007 -0700 +@@ -221,8 +221,8 @@ main (int argc, char *argv[]) + Ptr ipv4; + ipv4 = n2->QueryInterface (Ipv4::iid); + +- uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr(n2Lan0Addr); +- uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr(n2Lan1Addr); ++ uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr (n2Lan0Addr); ++ uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr (n2Lan1Addr); + // + // Now, we need to do is to call the AddMulticastRoute () method on node + // two's Ipv4 interface and tell it that whenever it receives a packet on +@@ -237,6 +237,41 @@ main (int argc, char *argv[]) + + ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0, + outputInterfaces); ++// ++// We need to specify how the source node handles multicasting. There are a ++// number of ways we can deal with this, we just need to pick one. The first ++// method is to add an explicit route out of the source node, just as we did ++// for the forwarding node. Use this method when you want to send packets out ++// multiple interfaces or send packets out different interfaces based on the ++// differing multicast groups. Since the source is local, there will be no ++// input interface over which packets are received, so use ++// Ipv4RoutingProtocol::IF_INDEX_ANY as a wildcard. ++// ++// A second way is to specify a multicast route using wildcards. If you ++// want to send multicasts out differing sets of interfaces based on the ++// multicast group, you can use AddMulticastRoute () but specify the origin ++// as a wildcard. If you want all multicasts to go out a single set of ++// interfaces, you can make both the origin and group a wildcard. ++// ++// If you have a simple system, where the source has a single interface, this ++// can be done via the SetDefaultMulticastRoute () method on the Ipv4 ++// interface. This tells the system to send all multicasts out a single ++// specified network interface index. ++// ++// A last way is to specify a (or use an existing) default unicast route. The ++// multicast routing code uses the unicast default route as a multicast "route ++// of last resort." this method for is also on Ipv4 and is called ++// SetDefaultRoute (). ++// ++// Since this is a simple multicast example, we use the ++// SetDefaultMulticastRoute () approach. We are going to first need the ++// Ipv4 interface for node 0 which is the multicast source. We use this ++// interface to find the output interface index, and tell node zero to send ++// its multicast traffic out that interface. ++// ++ ipv4 = n0->QueryInterface (Ipv4::iid); ++ uint32_t ifIndexSrc = ipv4->FindInterfaceForAddr (multicastSource); ++ ipv4->SetDefaultMulticastRoute (ifIndexSrc); + // + // As described above, node four will be the only node listening for the + // multicast data. To enable forwarding bits up the protocol stack, we need +diff -r 3fba36666488 -r f9bc98cbe5fe src/internet-node/ipv4-static-routing.cc +--- a/src/internet-node/ipv4-static-routing.cc Tue Sep 04 15:10:47 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.cc Tue Sep 04 18:06:06 2007 -0700 +@@ -289,14 +289,27 @@ Ipv4StaticRouting::LookupStatic ( + Ipv4Address group, + uint32_t ifIndex) + { ++// ++// We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching ++// scheme. ++// ++ Ipv4Address wildcard = Ipv4Address::GetAny (); ++ + for (MulticastRoutesI i = m_multicastRoutes.begin (); + i != m_multicastRoutes.end (); + i++) + { + Ipv4MulticastRoute *route = *i; +- if ( (origin == route->GetOrigin () || +- origin == Ipv4Address::GetAny ()) && +- group == route->GetGroup ()) ++// ++// 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 ()) + { + if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || + ifIndex == route->GetInputInterface ()) +@@ -305,7 +318,67 @@ Ipv4StaticRouting::LookupStatic ( + } + } + } +- ++// ++// If the input interface index is not a wildcard (that means that the packet ++// did not originally come from this node), we're done. We don't ++// just happily forward packets we don't really know what to do with. ++// Multicast storms are not generally considered a good thing. ++// ++ if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY) ++ { ++ return 0; ++ } ++// ++// Now, we're going to get a litle less restricive. This only applies in the ++// case where the packet in question is coming from the local node. In order ++// to avoid dependencies on the order in which routes were added, we will ++// actually walk the list two more times, the first time looking for routes ++// with a single wildcard, and the last time looking for the first route ++// with two wildcards. ++// ++ for (MulticastRoutesI i = m_multicastRoutes.begin (); ++ i != m_multicastRoutes.end (); ++ i++) ++ { ++ Ipv4MulticastRoute *route = *i; ++// ++// Here we will ignore the origin. We know that a single source address must ++// be picked for a packet, but we may want to send multicast packets out ++// multiple interfaces. To support this case, a user would need to add ++// a Multicast route with the route's origin set to wildcard. N.B As a ++// result, packets sourced from a node with multiple interface may have a ++// source IP address different from that of the interface actually used to ++// send the packet. ++// ++ if (route->GetOrigin () == wildcard && group == route->GetGroup ()) ++ { ++ return *i; ++ } ++ } ++// ++// Finally we want to allow users to specify a default route that specifies ++// sending all multicast packets out multiple interfaces. The standard ++// default multicast route is patterned after other systems and limits the ++// number of outputs to one. If, however a client manually adds a multicast ++// route with the origin, the multicast group and the input interface index ++// all set to wildcard, she has created a default route with multiple output ++// interfaces. ++// ++ for (MulticastRoutesI i = m_multicastRoutes.begin (); ++ i != m_multicastRoutes.end (); ++ i++) ++ { ++ Ipv4MulticastRoute *route = *i; ++ ++ if (route->GetOrigin () == wildcard && route->GetGroup () == wildcard) ++ { ++ return *i; ++ } ++ } ++// ++// We also allow users to specify a typical default multicast route. This ++// default route is limited to specifying a single output interface. ++// + if (m_defaultMulticastRoute != 0) + { + return m_defaultMulticastRoute; +@@ -445,33 +518,7 @@ Ipv4StaticRouting::RequestRoute ( + if (ipHeader.GetDestination ().IsMulticast ()) + { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination"); +-// +-// We have a multicast packet we're going to send. There are two distinct +-// cases we need to support. The first is if the current node is the source +-// of the packet. In that case, we don't want to have to consult multicast +-// routing tables (nor build them) in order to send multicasts. The interface +-// index (ifIndex) is Ipv4RoutingProtocol::IF_INDEX_ANY if we're the source. +-// +-// The second case is if the current packet has gotten to us by being +-// received over one of our interfaces. In this case, ifIndex is set to the +-// index over which we received the packet. For these packets, we need to +-// consult the multicast routing table for a disposition. +-// +-// So, first let's see if we're the source. In this case, we don't consult +-// the routing tables, but just return false and let the caller (up in +-// ipv4-l3-protocol) flood the multicast packet out of all of its interfaces. +-// We can't really do it here even if we wanted to since we have no easy way +-// to get to the Ipv4 interface which we would need. +-// +- if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY) +- { +- return false; +- } +-// +-// If we fall through to this point, we have a multicast packet that has +-// not originated at this node. We need to deal with forwarding. Let's +-// see if we have a route, and if so go ahead and forward this puppy. +-// ++ + Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (), + ipHeader.GetDestination (), ifIndex); + +@@ -479,6 +526,7 @@ Ipv4StaticRouting::RequestRoute ( + { + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): " + "Multicast route found"); ++ + for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i) + { + Packet p = packet; +@@ -495,7 +543,7 @@ Ipv4StaticRouting::RequestRoute ( + return false; // Let other routing protocols try to handle this + } + // +-// See if this is a unicast packet we have a route for. ++// This is a unicast packet. Check to see if we have a route for it. + // + NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination"); + Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); +diff -r 3fba36666488 -r f9bc98cbe5fe src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Tue Sep 04 15:10:47 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Tue Sep 04 18:06:06 2007 -0700 +@@ -317,21 +317,34 @@ public: + /** + * @brief Add a multicast route to the static routing table. + * +- * A multicast route must specify an origin IP address -- the address of the +- * node that originates packets destined for a given multicast group. This +- * address may be Ipv4Address::GetAny (typically 0.0.0.0) if the multicast +- * group is open, or it may specify a single IP address if the multicast +- * group is closed. The route must also specify the multicast group address. +- * +- * For each route, the input nework interface must be specified. For +- * forwarding operations, this is the interface index that you expect multicast +- * packets to arrive over. If you want to specify routes off of a local node +- * for given multicast groups, this index may be set to +- * Ipv4RoutingProtocol::IF_INDEX_ANY. +- * +- * For each route, a vector of output network interfaces must also be +- * specified. When the RequestRoute operation is performed, copies of a +- * packet are sent out all of the specified interfaces. ++ * 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 ++ * exlicitly 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::IF_INDEX_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. +@@ -425,6 +438,12 @@ public: + * 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 ++ * exacly 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 origin The IP address specified as the multicast group addres of +@@ -433,9 +452,8 @@ public: + * input interface for the route. + * @returns True if a route was found and removed, false otherwise. + * +- * @see Ipv4Route +- * @see Ipv4StaticRouting::GetRoute +- * @see Ipv4StaticRouting::AddRoute ++ * @see Ipv4MulticastRoute ++ * @see Ipv4StaticRouting::AddMulticastRoute + */ + bool RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + +changeset: 1319:f136fc719267 +tag: tip +user: Craig Dowell +date: Thu Sep 06 15:57:53 2007 -0700 +summary: readme file includes APIs + +diff -r f9bc98cbe5fe -r f136fc719267 README.multicast-routing +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/README.multicast-routing Thu Sep 06 15:57:53 2007 -0700 +@@ -0,0 +1,213 @@ ++Static multicast routing overview ++-------------------------------- ++ ++This is brief documentation of a proposal to add static multicast ++routing to ns-3. ++ ++This extension allows the simulation user to: ++ ++- manually add an Ipv4 multicast route to a router ++- specify a default outgoing interface for multicast sources (hosts) in ++ various ways ++- allow a multicast receiver (hosts) to join a multicast group, to enable ++ reception of that group's datagrams ++ ++1. Code location: ++ ++- http://code.nsnam.org/craigdo/ns-3-mc ++ ++- the main source code is found in src/internet-node/ipv4-static-routing.{cc,h} ++ ++also touched are: ++- src/internet-node/ipv4-l3-protocol.cc (forwarding methods for the ++ static routing API) ++- src/node/net-device.cc (provides virtual NetDevice::MakeMulticastAddress) ++- src/arp-ipv4-interface.cc (calls NetDevice::MakeMulticastAddress) ++- src/devices/csma/csma-net-device.cc (handles multicast addressing and ++ reception). ++- src/devices/point-to-point/point-to-point-net-device.cc (implements required ++ virtual methods. ++- src/internet-node/ (several files have added tracing) ++ ++- an example script is in examples/csma-multicast.cc ++ ++2. API: ++ ++The API for adding a multicast route is: ++ ++/** ++ * @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 ++ * exlicitly 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::IF_INDEX_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::IF_INDEX_ANY for packets of local origin. ++ * @param outputInterface A vector of network interface indices used to specify ++ * how to send packets to the destination(s). ++ * ++ * @see Ipv4Address ++ */ ++ Ipv4::AddMulticastRoute (Ipv4Address origin, ++ Ipv4Address group, ++ uint32_t inputInterface, ++ std::vector outputInterfaces) ++ ++To remove a route, one uses: ++ ++/** ++ * @brief Remove a route from the static multicast routing table. ++ * ++ * Externally, the multicast static routing table appears simply as a table ++ * with n entries. The one sublety of note is that if a default multicast ++ * route has been set it will appear as the zeroth entry in the table. This ++ * means that the default route may be removed by calling this method with ++ * appropriate wildcard parameters. ++ * ++ * 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 ++ * exacly 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 origin The IP address specified as the multicast group addres of ++ * the route. ++ * @param inputInterfade 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 Ipv4MulticastRoute ++ * @see Ipv4StaticRouting::AddMulticastRoute ++ */ ++ Ipv4::RemoveMulticastRoute (Ipv4Address origin, Ipv4Address group, ++ uint32_t inputInterface) ++ ++For compatibility, and to provide simplicity, one can set a default multicast ++route for a host originating data: ++ ++/** ++ * @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 ++ */ ++ Ipv4::SetDefaultMulticastRoute (uint32_t outputInterface) ++ ++For a host wanting to receive multicast data, the following function is used ++to join each multicast group. ++ ++ /** ++ * \brief Join a multicast group for a given multicast source and ++ * group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ */ ++ Ipv4::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ ++To stop receiving multicast data, the following function is used: ++ ++ /** ++ * \brief Leave a multicast group for a given multicast source and ++ * group. ++ * ++ * \param origin The Ipv4 address of the multicast source. ++ * \param group The multicast group address. ++ */ ++ LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group); ++ ++There are new lookup functions implemented in Ipv4: ++ ++ /** ++ * \brief Find and return the interface ID of the interface that has been ++ * assigned the specified IP address. ++ * \param addr The IP address assigned to the interface of interest. ++ * \returns The index of the ipv4 interface with the given address. ++ * ++ * Each IP interface has an IP address associated with it. It is often ++ * useful to search the list of interfaces for one that corresponds to ++ * a known IP Address. This call takes an IP address as a parameter and ++ * returns the interface index of the first interface that has been assigned ++ * that address. If the address is not found, this function asserts. ++ */ ++ Ipv4::FindInterfaceForAddr (Ipv4Address addr) const; ++ ++ /** ++ * \brief Find and return the interface ID of the interface that has been ++ * assigned the specified (masked) IP address. ++ * \param addr The IP address assigned to the interface of interest. ++ * \param mask The address mask to be used in address matching. ++ * \returns The index of the ipv4 interface with the given address. ++ * ++ * Each IP interface has an IP address associated with it. It is often ++ * useful to search the list of interfaces for one that corresponds to ++ * a known IP Address. This call takes an IP address and an IP address ++ * mask as parameters and returns the interface index of the first interface ++ * that matches the masked IP address. ++ */ ++ Ipv4::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const; ++ ++Also, there are various methods to lookup and iterate the static multicast ++routes of a node, in the Ipv4StaticRouting class. ++ ++3. Dependencies: ++ ++- fix for bug 69 (source Ipv4 address is set correctly for UDP) ++- fix for OnOffApplication that receives data ++ ++4. Open issues or features not included ++ ++- choose source interface on a per-group basis when a host is multihomed +diff -r f9bc98cbe5fe -r f136fc719267 src/internet-node/ipv4-static-routing.h +--- a/src/internet-node/ipv4-static-routing.h Tue Sep 04 18:06:06 2007 -0700 ++++ b/src/internet-node/ipv4-static-routing.h Thu Sep 06 15:57:53 2007 -0700 +@@ -369,14 +369,17 @@ public: + * 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. +- * +- * Since we're basically forwarding packets to some entity we think may know +- * better what to do, we don't pay attention to subleties like origin address +- * and input interface, 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, multicast group or +- * input interface if another specific route is not found. ++ * 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. + From b39cf878a0af35ad2f69e9e3b13df09885c21b28 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 10 Sep 2007 15:57:33 -0700 Subject: [PATCH 19/23] name changes missed --- examples/csma-broadcast.cc | 8 ++++---- src/internet-node/udp-socket.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/csma-broadcast.cc b/examples/csma-broadcast.cc index 1cb9faa75..effbcc310 100644 --- a/examples/csma-broadcast.cc +++ b/examples/csma-broadcast.cc @@ -103,13 +103,13 @@ int main (int argc, char *argv[]) CsmaTopology::CreateCsmaChannel( DataRate(5000000), MilliSeconds(2)); - uint32_t n0ifIndex0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, + uint32_t n0ifIndex0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, channel0, Eui48Address("10:54:23:54:0:50")); - uint32_t n0ifIndex1 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel1, + uint32_t n0ifIndex1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, channel1, Eui48Address("10:54:23:54:0:51")); - uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0, + uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, channel0, Eui48Address("10:54:23:54:23:51")); - uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel1, + uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, channel1, Eui48Address("10:54:23:54:23:52")); // Later, we add IP addresses. diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 01de3e989..1183ce7d9 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -255,7 +255,7 @@ UdpSocket::DoSendTo (const Packet &p, const Address &address) int UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port) { - NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << addr << ", " << + NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << dest << ", " << port << ")"); Ipv4Route routeToDest; From f894771e7d4e8754057e44590f1fb70a3d2e3848 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 11 Sep 2007 18:29:26 -0700 Subject: [PATCH 20/23] socket update broke multicast --- examples/csma-multicast.cc | 13 ---------- src/internet-node/ipv4-impl.cc | 6 +++++ src/internet-node/ipv4-impl.h | 2 ++ src/internet-node/udp-socket.cc | 24 ++++++++++++------- src/node/ipv4.cc | 22 +++++++++++------ src/node/ipv4.h | 22 +++++++++++------ .../global-route-manager-impl.cc | 2 +- 7 files changed, 55 insertions(+), 36 deletions(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 9b964abec..801e8ea51 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -85,19 +85,6 @@ main (int argc, char *argv[]) DebugComponentEnable("Ipv4LoopbackInterface"); #endif - DebugComponentEnable("Channel"); - DebugComponentEnable("CsmaChannel"); - DebugComponentEnable("CsmaMulticast"); - DebugComponentEnable("CsmaNetDevice"); - DebugComponentEnable("OnOffApplication"); - DebugComponentEnable("PacketSocket"); - DebugComponentEnable("UdpSocket"); - DebugComponentEnable("UdpL4Protocol"); - DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("Ipv4StaticRouting"); - DebugComponentEnable("Ipv4Interface"); - DebugComponentEnable("ArpIpv4Interface"); - DebugComponentEnable("Ipv4LoopbackInterface"); // // Set up default values for the simulation. Use the DefaultValue::Bind() // technique to tell the system what subclass of Queue to use. The Bind diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index b105d5a41..a67c6a4e8 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -201,6 +201,12 @@ Ipv4Impl::GetAddress (uint32_t i) const return m_ipv4->GetAddress (i); } +bool +Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const +{ + return m_ipv4->GetIfIndexForDestination (dest, ifIndex); +} + Ipv4Address Ipv4Impl::GetSourceAddress (Ipv4Address destination) const { diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index ab17c16f4..1f4a79f5c 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -89,6 +89,8 @@ public: virtual Ipv4Mask GetNetworkMask (uint32_t t) const; virtual Ipv4Address GetAddress (uint32_t i) const; virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const; + virtual bool GetIfIndexForDestination (Ipv4Address dest, + uint32_t &ifIndex) const; virtual uint16_t GetMtu (uint32_t i) const; virtual bool IsUp (uint32_t i) const; diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 1183ce7d9..6f123bed5 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -186,11 +186,13 @@ UdpSocket::Connect(const Address & address) NS_DEBUG ("UdpSocket::Connect (): Updating local address"); - if (GetIpv4RouteToDestination (m_node, routeToDest, m_defaultAddress) ) + uint32_t localIfIndex; + + Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); + + if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex)) { - uint32_t localIfIndex = routeToDest.GetInterface (); - Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); - m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex) ); + m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex)); } NS_DEBUG ("UdpSocket::Connect (): Local address is " << @@ -240,6 +242,7 @@ UdpSocket::DoSendTo (const Packet &p, const Address &address) if (!m_connected) { + NS_DEBUG("UdpSocket::DoSendTo (): Not connected"); InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); @@ -248,6 +251,7 @@ UdpSocket::DoSendTo (const Packet &p, const Address &address) else { // connected UDP socket must use default addresses + NS_DEBUG("UdpSocket::DoSendTo (): Connected"); return DoSendTo (p, m_defaultAddress, m_defaultPort); } } @@ -274,13 +278,17 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port) m_errno = ERROR_SHUTDOWN; return -1; } + + uint32_t localIfIndex; + Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); + // // If dest is sent to the limited broadcast address (all ones), // convert it to send a copy of the packet out of every interface // if (dest.IsBroadcast ()) { - Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); + NS_DEBUG("UdpSocket::DoSendTo (): Limited broadcast"); for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ ) { Ipv4Address addri = ipv4->GetAddress (i); @@ -290,10 +298,9 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port) NotifyDataSent (p.GetSize ()); } } - else if (GetIpv4RouteToDestination (m_node, routeToDest, dest) ) + else if (ipv4->GetIfIndexForDestination(dest, localIfIndex)) { - uint32_t localIfIndex = routeToDest.GetInterface (); - Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); + NS_DEBUG("UdpSocket::DoSendTo (): Route exists"); m_udp->Send (p, ipv4->GetAddress (localIfIndex), dest, m_endPoint->GetLocalPort (), port); NotifyDataSent (p.GetSize ()); @@ -301,6 +308,7 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port) } else { + NS_DEBUG("UdpSocket::DoSendTo (): ERROR_NOROUTETOHOST"); m_errno = ERROR_NOROUTETOHOST; return -1; } diff --git a/src/node/ipv4.cc b/src/node/ipv4.cc index d7c83d42a..f8a852149 100644 --- a/src/node/ipv4.cc +++ b/src/node/ipv4.cc @@ -36,10 +36,10 @@ Ipv4::~Ipv4 () {} uint32_t -GetIfIndexByIpv4Address (Ptr node, Ipv4Address a, Ipv4Mask amask) +Ipv4::GetIfIndexByAddress (Ptr node, Ipv4Address a, Ipv4Mask amask) { Ptr ipv4 = node->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG (ipv4, "GetIfIndexByIpv4Address: No Ipv4 interface"); + NS_ASSERT_MSG (ipv4, "Ipv4::GetIfIndexByAddress: No Ipv4 interface"); for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++) { if (ipv4->GetAddress (i).CombineMask(amask) == a.CombineMask(amask) ) @@ -48,17 +48,26 @@ GetIfIndexByIpv4Address (Ptr node, Ipv4Address a, Ipv4Mask amask) } } // Mapping not found - NS_ASSERT_MSG (false, "GetIfIndexByIpv4Address failed"); + NS_ASSERT_MSG (false, "Ipv4::GetIfIndexByAddress failed"); return 0; } +// +// XXX BUGBUG I don't think this is really the right approach here. The call +// to GetRoute () filters down into Ipv4L3Protocol where it translates into +// a call into the Ipv4 static routing package. This bypasses any other +// routing packages. At a minimum, the name is misleading. +// bool -GetIpv4RouteToDestination (Ptr node, Ipv4Route& route, - Ipv4Address a, Ipv4Mask amask) +Ipv4::GetRouteToDestination ( + Ptr node, + Ipv4Route& route, + Ipv4Address a, + Ipv4Mask amask) { Ipv4Route tempRoute; Ptr ipv4 = node->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG (ipv4, "GetIpv4RouteToDestination: No Ipv4 interface"); + NS_ASSERT_MSG (ipv4, "Ipv4::GetRouteToDestination: No Ipv4 interface"); for (uint32_t i = 0; i < ipv4->GetNRoutes (); i++) { tempRoute = ipv4->GetRoute (i); @@ -83,5 +92,4 @@ GetIpv4RouteToDestination (Ptr node, Ipv4Route& route, return false; } - } // namespace ns3 diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 1cdc08d6f..ba4868a4a 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -105,6 +105,7 @@ public: const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply) = 0; + /** * \brief Synchronously check to see if we can determine the interface index * that will be used if a packet is sent to this destination. @@ -395,6 +396,15 @@ public: */ virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0; + /** + * \param destination The IP address of a hypothetical destination. + * \param ifIndex filled in with the interface index that will be used to + * send a packet to the hypothetical destination. + * \returns True if a single interface can be identified, false otherwise. + */ + virtual bool GetIfIndexForDestination (Ipv4Address dest, + uint32_t &ifIndex) const = 0; + /** * \param i index of ipv4 interface * \returns the Maximum Transmission Unit (in bytes) associated @@ -424,20 +434,18 @@ public: * ignored during ipv4 forwarding. */ virtual void SetDown (uint32_t i) = 0; -}; /** * Convenience functions (Doxygen still needed) * * Return the ifIndex corresponding to the Ipv4Address provided. */ -uint32_t GetIfIndexByIpv4Address (Ptr node, - Ipv4Address a, - Ipv4Mask amask = Ipv4Mask("255.255.255.255")); + static uint32_t GetIfIndexByAddress (Ptr node, Ipv4Address a, + Ipv4Mask amask = Ipv4Mask("255.255.255.255")); -bool GetIpv4RouteToDestination (Ptr node, Ipv4Route& route, - Ipv4Address a, - Ipv4Mask amask = Ipv4Mask("255.255.255.255")); + static bool GetRouteToDestination (Ptr node, Ipv4Route& route, + Ipv4Address a, Ipv4Mask amask = Ipv4Mask("255.255.255.255")); +}; } // namespace ns3 diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 10f07ca85..4e8f19f51 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -1143,7 +1143,7 @@ GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask) // we're looking for. If we find one, return the corresponding interface // index. // - return (GetIfIndexByIpv4Address (node, a, amask) ); + return (Ipv4::GetIfIndexByAddress (node, a, amask) ); } } // From 1cf86b9641eb452974ce0a83b555a6a08a5c4879 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 11 Sep 2007 19:09:49 -0700 Subject: [PATCH 21/23] integrating broadcast with multicast and sockets with multiple interfaces required default route for disambiguation --- examples/csma-broadcast.cc | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/examples/csma-broadcast.cc b/examples/csma-broadcast.cc index effbcc310..b372fa201 100644 --- a/examples/csma-broadcast.cc +++ b/examples/csma-broadcast.cc @@ -66,13 +66,24 @@ int main (int argc, char *argv[]) // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this -#if 0 - DebugComponentEnable("CsmaNetDevice"); - DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("NetDevice"); +#if 1 + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); DebugComponentEnable("Channel"); DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("NetDevice"); + DebugComponentEnable("CsmaNetDevice"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("OnOffApplication"); DebugComponentEnable("PacketSocket"); + DebugComponentEnable("UdpSocket"); + DebugComponentEnable("UdpL4Protocol"); + DebugComponentEnable("Ipv4L3Protocol"); + DebugComponentEnable("Ipv4StaticRouting"); + DebugComponentEnable("Ipv4Interface"); + DebugComponentEnable("ArpIpv4Interface"); + DebugComponentEnable("Ipv4LoopbackInterface"); #endif // Set up some default values for the simulation. Use the Bind() @@ -125,6 +136,18 @@ int main (int argc, char *argv[]) CsmaIpv4Topology::AddIpv4Address ( n2, n2ifIndex, Ipv4Address("192.168.1.2"), Ipv4Mask("255.255.255.0")); + // XXX Is this the right thing to do? + // + // The OnOff application uses a connected socket. This socket needs to be + // able to figure out which interface to use as the source address for + // packets. When there's one interface, this isn't too hard, but node zero + // has two interfaces, and limited broadcasts will be sent out both of those + // interfaces. We need to provide some way to disambiguate the choice. + // If we supply a default route, the specified interface will be chosen. + + Ptr ipv4 = n0->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute ("192.168.1.3", n0ifIndex0); + // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s // from n0 to n1 From b639466adbc06f42294381dbf4d390162a96abf5 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 11 Sep 2007 19:11:03 -0700 Subject: [PATCH 22/23] turn off debugging flags --- examples/csma-broadcast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/csma-broadcast.cc b/examples/csma-broadcast.cc index b372fa201..b032f0aea 100644 --- a/examples/csma-broadcast.cc +++ b/examples/csma-broadcast.cc @@ -66,7 +66,7 @@ int main (int argc, char *argv[]) // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this -#if 1 +#if 0 DebugComponentEnable("Object"); DebugComponentEnable("Queue"); DebugComponentEnable("DropTailQueue"); From 49cf104a1253734621f9499dabb0641bac731a0b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 11 Sep 2007 19:40:50 -0700 Subject: [PATCH 23/23] variable unused in optimized build -- fixed via attribute --- examples/csma-multicast.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 801e8ea51..6bae090ff 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -137,7 +137,8 @@ main (int argc, char *argv[]) uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, Eui48Address("08:00:2e:00:00:03")); - uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, + uint32_t nd3 __attribute__ ((unused)) = + CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, Eui48Address("08:00:2e:00:00:04")); uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, Eui48Address("08:00:2e:00:00:05"));