add ipv4 methods, remove source multicast route requirement, fix udp socket source address prob
authorCraig Dowell <craigdo@ee.washington.edu>
Fri, 24 Aug 2007 16:57:54 -0700
changeset 1440 c77745b2731c
parent 1439 4743aef86605
child 1441 d6f8a7546e7f
add ipv4 methods, remove source multicast route requirement, fix udp socket source address prob
examples/csma-multicast.cc
src/internet-node/ipv4-impl.cc
src/internet-node/ipv4-impl.h
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/internet-node/ipv4-static-routing.cc
src/internet-node/ipv4-static-routing.h
src/internet-node/udp-socket.cc
src/node/ipv4.h
--- 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 @@
   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 @@
 // 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.
+
+  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"));
+
 //
-// 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.
+// We'll need these addresses later
 //
-  uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, 
-    Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0"));
+  Ipv4Address n2Lan0Addr ("10.1.1.3");
+  Ipv4Address n2Lan1Addr ("10.1.2.1");
 
-  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 (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"));
+  CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, n2Lan1Addr, 
+    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 (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 @@
 //
 // 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;
   ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
 
-  std::vector<uint32_t> outputInterfaces (1);
-  outputInterfaces[0] = ifIndexNd2Lan1;
-
-  ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0,
-    outputInterfaces);
+  uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr(n2Lan0Addr);
+  uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr(n2Lan1Addr);
 //
-// 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).
+// 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).
 //
-  ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
+  std::vector<uint32_t> outputInterfaces (1);
+  outputInterfaces[0] = ifIndexLan1;
 
-  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
--- 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 @@
 {
   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<NetDevice>
 Ipv4Impl::GetNetDevice (uint32_t i)
 {
--- 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 @@
 
   virtual uint32_t AddInterface (Ptr<NetDevice> device);
   virtual uint32_t GetNInterfaces (void);  
+
+  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
+  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, 
+    Ipv4Mask mask) const;
+
   virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
 
   virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
--- 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 @@
         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 @@
   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<const NetDevice> device)
 {
@@ -713,7 +783,40 @@
           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 
--- 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 @@
   uint32_t AddInterface (Ptr<NetDevice> 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);
--- 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 @@
   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 @@
 
   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 @@
           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
     }
--- 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 @@
   void SetDefaultRoute (Ipv4Address nextHop, 
                         uint32_t interface);
   uint32_t GetNRoutes (void);
+  Ipv4Route *GetDefaultRoute (void);
   Ipv4Route *GetRoute (uint32_t i);
   void RemoveRoute (uint32_t i);
 
--- 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 @@
   NotifyConnectionSucceeded ();
   m_connected = true;
 
+  NS_DEBUG ("UdpSocket::Connect (): Updating local address");
   Ptr<Ipv4> ipv4;
   ipv4 = m_node->QueryInterface<Ipv4> (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 @@
 }
 
 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 @@
       return -1;
     }
 
+  NS_DEBUG ("UdpSocket::DoSendTo (): Finding source address");
+  Ptr<Ipv4> ipv4;
+  ipv4 = m_node->QueryInterface<Ipv4> (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, 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 ();
--- 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 @@
   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
    */