View | Details | Raw Unified | Return to bug 606
Collapse All | Expand All

(-)a/src/internet-stack/arp-l3-protocol.cc (-9 / +4 lines)
 Lines 23-29    Link Here 
23
#include "ns3/net-device.h"
23
#include "ns3/net-device.h"
24
#include "ns3/object-vector.h"
24
#include "ns3/object-vector.h"
25
#include "ns3/trace-source-accessor.h"
25
#include "ns3/trace-source-accessor.h"
26
#include "ns3/ipv4-route.h"
27
26
28
#include "ipv4-l3-protocol.h"
27
#include "ipv4-l3-protocol.h"
29
#include "arp-l3-protocol.h"
28
#include "arp-l3-protocol.h"
 Lines 320-338    Link Here 
320
  NS_ASSERT (interface >= 0);
319
  NS_ASSERT (interface >= 0);
321
  Ipv4Header header;
320
  Ipv4Header header;
322
  header.SetDestination (to);
321
  header.SetDestination (to);
323
  Socket::SocketErrno errno_;
324
  Ptr<Packet> packet = Create<Packet> ();
322
  Ptr<Packet> packet = Create<Packet> ();
325
  Ptr<Ipv4Route> route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, interface, errno_);
323
  Ipv4Address source = ipv4->SelectSourceAddress (cache->GetDevice (), to, Ipv4InterfaceAddress::GLOBAL);
326
  NS_ASSERT (route != 0);
327
  NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
324
  NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
328
            " || src: " << cache->GetDevice ()->GetAddress () <<
325
            " || src: " << cache->GetDevice ()->GetAddress () <<
329
            " / " << route->GetSource () <<
326
            " / " << source <<
330
            " || dst: " << cache->GetDevice ()->GetBroadcast () <<
327
            " || dst: " << cache->GetDevice ()->GetBroadcast () <<
331
            " / " << to);
328
            " / " << to);
332
  arp.SetRequest (cache->GetDevice ()->GetAddress (),
329
  arp.SetRequest (cache->GetDevice ()->GetAddress (), source,
333
		  route->GetSource (),
330
                  cache->GetDevice ()->GetBroadcast (), to);
334
                  cache->GetDevice ()->GetBroadcast (),
335
                  to);
336
  packet->AddHeader (arp);
331
  packet->AddHeader (arp);
337
  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
332
  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
338
}
333
}
(-)a/src/internet-stack/ipv4-l3-protocol.cc (+53 lines)
 Lines 866-871    Link Here 
866
  return false;
866
  return false;
867
}
867
}
868
868
869
Ipv4Address 
870
Ipv4L3Protocol::SelectSourceAddress (Ptr<const NetDevice> device,
871
    Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
872
{
873
  NS_LOG_FUNCTION (device << dst << scope);
874
  Ipv4Address addr ("0.0.0.0");
875
  Ipv4InterfaceAddress iaddr; 
876
  bool found = false;
877
878
  if (device != 0)
879
    {
880
      int32_t i = GetInterfaceForDevice (device);
881
      NS_ASSERT_MSG (i >= 0, "No device found on node");
882
      for (uint32_t j = 0; j < GetNAddresses (i); j++)
883
        {
884
          iaddr = GetAddress (i, j);
885
          if (iaddr.IsSecondary ()) continue;
886
          if (iaddr.GetScope () > scope) continue; 
887
          if (dst.CombineMask (iaddr.GetMask ())  == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )  
888
            {
889
              return iaddr.GetLocal ();
890
            }
891
          if (!found)
892
            {
893
              addr = iaddr.GetLocal ();
894
              found = true;
895
            }
896
        }
897
    }
898
  if (found)
899
    {
900
      return addr;
901
    }
902
903
  // Iterate among all interfaces
904
  for (uint32_t i = 0; i < GetNInterfaces (); i++)
905
    {
906
      for (uint32_t j = 0; j < GetNAddresses (i); j++)
907
        {
908
          iaddr = GetAddress (i, j);
909
          if (iaddr.IsSecondary ()) continue;
910
          if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK 
911
              && iaddr.GetScope () <= scope) 
912
            {
913
              return iaddr.GetLocal ();
914
            }
915
        }
916
    }
917
  NS_LOG_WARN ("Could not find source address for " << dst << " and scope " 
918
    << scope << ", returning 0");
919
  return addr;  
920
}
921
869
void 
922
void 
870
Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
923
Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
871
{
924
{
(-)a/src/internet-stack/ipv4-l3-protocol.h (+3 lines)
 Lines 176-181    Link Here 
176
  Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
176
  Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
177
  uint32_t GetNAddresses (uint32_t interface) const;
177
  uint32_t GetNAddresses (uint32_t interface) const;
178
  bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
178
  bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
179
  Ipv4Address SelectSourceAddress (Ptr<const NetDevice> device,
180
    Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope);
181
179
182
180
  void SetMetric (uint32_t i, uint16_t metric);
183
  void SetMetric (uint32_t i, uint16_t metric);
181
  uint16_t GetMetric (uint32_t i) const;
184
  uint16_t GetMetric (uint32_t i) const;
(-)a/src/node/ipv4.h (+38 lines)
 Lines 216-221    Link Here 
216
  virtual bool RemoveAddress (uint32_t interface, uint32_t addressIndex) = 0;
216
  virtual bool RemoveAddress (uint32_t interface, uint32_t addressIndex) = 0;
217
217
218
  /**
218
  /**
219
   * \brief Return the first primary source address with scope less than 
220
   * or equal to the requested scope, to use in sending a packet to 
221
   * destination dst out of the specified device.
222
   *
223
   * This method mirrors the behavior of Linux inet_select_addr() and is
224
   * provided because interfaces may have multiple IP addresses configured
225
   * on them with different scopes, and with a primary and secondary status.
226
   * Secondary addresses are never returned.
227
   * \see Ipv4InterfaceAddress
228
   *
229
   * If a non-zero device pointer is provided, the method first tries to
230
   * return a primary address that is configured on that device, and whose
231
   * subnet matches that of dst and whose scope is less than or equal to
232
   * the requested scope.  If a primary address does not match the
233
   * subnet of dst but otherwise matches the scope, it is returned.  
234
   * If no such address on the device is found, the other devices are 
235
   * searched in order of their interface index, but not considering dst
236
   * as a factor in the search.  Because a loopback interface is typically 
237
   * the first one configured on a node, it will be the first alternate 
238
   * device to be tried.  Addresses scoped at LINK scope are not returned
239
   * in this phase.
240
   * 
241
   * If no device pointer is provided, the same logic as above applies, only
242
   * that there is no preferred device that is consulted first.  This means
243
   * that if the device pointer is null, input parameter dst will be ignored.
244
   * 
245
   * If there are no possible addresses to return, a warning log message 
246
   * is issued and the all-zeroes address is returned.
247
   *
248
   * \param device output NetDevice (optionally provided, only to constrain the search)
249
   * \param dst Destination address to match, if device is provided 
250
   * \param scope Scope of returned address must be less than or equal to this
251
   * \returns the first primary Ipv4Address that meets the search criteria
252
   */
253
  virtual Ipv4Address SelectSourceAddress (Ptr<const NetDevice> device, 
254
    Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope) = 0;
255
256
  /**
219
   * \param interface The interface number of an Ipv4 interface
257
   * \param interface The interface number of an Ipv4 interface
220
   * \param metric routing metric (cost) associated to the underlying 
258
   * \param metric routing metric (cost) associated to the underlying 
221
   *          Ipv4 interface
259
   *          Ipv4 interface

Return to bug 606