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