# HG changeset patch # User Craig Dowell # Date 1186952389 25200 # Node ID a8f3d01d4a2c4d8a12070f9d07b5b162fa3a95b0 # Parent c26bf05110781334242f4238d3b5e7e36b442289 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 @@ 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 @@ { 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 @@ } 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,10 +55,28 @@ 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 -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 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 @@ 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 @@ 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 @@ } 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) { @@ -479,6 +535,28 @@ } 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) { Ipv4Interface *interface = GetInterface (i); 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 @@ 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 @@ 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 @@ 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,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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -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 @@ return m_interface; } - Ipv4Route Ipv4Route::CreateHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, @@ -220,4 +219,99 @@ 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 @@ 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,8 +202,50 @@ * \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. * \returns the index of the ipv4 interface added. @@ -225,6 +267,24 @@ 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 */