set source address in socket
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 13 Aug 2007 16:21:39 -0700
changeset 1434 2b63aafb050b
parent 1433 a6fb891b59fd
child 1435 a70de165a25a
set source address in socket
examples/csma-multicast.cc
src/internet-node/ipv4-end-point.cc
src/internet-node/ipv4-end-point.h
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	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 @@
 // Explicitly create the channels required by the topology (shown above).
 //
   Ptr<CsmaChannel> lan0 = 
-    CsmaTopology::CreateCsmaChannel(
-      DataRate(5000000), MilliSeconds(2));
+    CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2));
 
   Ptr<CsmaChannel> lan1 = 
-    CsmaTopology::CreateCsmaChannel(
-      DataRate(5000000), MilliSeconds(2));
+    CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2));
 
   NS_DEBUG("Build Topology.");
 //
--- 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 @@
 {
   return m_localAddr;
 }
+
+void
+Ipv4EndPoint::SetLocalAddress (Ipv4Address address)
+{
+  m_localAddr = address;
+}
+
 uint16_t 
 Ipv4EndPoint::GetLocalPort (void)
 {
--- 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 @@
   ~Ipv4EndPoint ();
 
   Ipv4Address GetLocalAddress (void);
+  void SetLocalAddress (Ipv4Address address);
+
   uint16_t GetLocalPort (void);
   Ipv4Address GetPeerAddress (void);
   uint16_t GetPeerPort (void);
--- 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 @@
 {
   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
 {
--- 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 @@
   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);
--- 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 @@
   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
 {
--- 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 @@
   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);
--- 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 @@
     }
 }
 
+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)
 {
--- 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 @@
                              Packet packet,
                              RouteReplyCallback routeReply);
 
+  virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
 
   void AddHostRouteTo (Ipv4Address dest, 
                        Ipv4Address nextHop, 
--- 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 @@
   m_defaultPort = transport.GetPort ();
   NotifyConnectionSucceeded ();
   m_connected = true;
+
+  Ptr<Ipv4> ipv4;
+  ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+  m_endPoint->SetLocalAddress (ipv4->GetSourceAddress(m_defaultAddress));
   return 0;
 }
 
--- 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 @@
                              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 @@
    */
   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