RawSocketImpl::ForwardUp fixed
authorBorovkova Elena <borovkovaes@iitp.ru>
Wed, 29 Jul 2009 13:52:00 +0400
changeset 5616 9d22b787ea7c
parent 5615 85bb591dc8ad
child 5617 23f363019fd1
RawSocketImpl::ForwardUp fixed
src/internet-stack/ipv4-l3-protocol.h
src/internet-stack/raw-socket-impl.cc
src/internet-stack/raw-socket-impl.h
src/routing/aodv/aodv-routing-protocol.cc
--- a/src/internet-stack/ipv4-l3-protocol.h	Wed Jul 29 11:47:06 2009 +0400
+++ b/src/internet-stack/ipv4-l3-protocol.h	Wed Jul 29 13:52:00 2009 +0400
@@ -30,7 +30,6 @@
 #include "ns3/traced-callback.h"
 #include "ns3/ipv4-header.h"
 #include "ns3/ipv4-routing-protocol.h"
-#include "raw-socket-impl.h"
 
 
 namespace ns3 {
@@ -45,6 +44,7 @@
 class Node;
 class Socket;
 class Ipv4RawSocketImpl;
+class RawSocketImpl;
 class Ipv4L4Protocol;
 class Ipv4L4Protocol;
 class Icmpv4L4Protocol;
--- a/src/internet-stack/raw-socket-impl.cc	Wed Jul 29 11:47:06 2009 +0400
+++ b/src/internet-stack/raw-socket-impl.cc	Wed Jul 29 13:52:00 2009 +0400
@@ -42,6 +42,12 @@
 RawSocketImpl::SetNode (Ptr<Node> node)
 {
   m_node = node;
+  m_ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+  NS_ASSERT(m_ipv4 != 0);
+  for(uint32_t i = 0; i < m_ipv4->GetNInterfaces(); ++i)
+  {
+    m_interfaces.push_back (m_ipv4->GetInterface(i));
+  }
 }
 
 void
@@ -163,61 +169,127 @@
   {
     return 0;
   }
-  InetSocketAddress ad = InetSocketAddress::ConvertFrom (toAddress);
-  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
-  NS_ASSERT(ipv4 != 0);
-  Ipv4Address dst = ad.GetIpv4 ();
-  NS_LOG_LOGIC ("RawSocketImpl::SendTo packet uid " << packet->GetUid() << " address " << dst);
-  if (ipv4->GetRoutingProtocol ())
+
+
+  if (m_ipv4->GetRoutingProtocol ())
   {
     Ipv4Header header;
     packet->PeekHeader (header);
+    NS_LOG_LOGIC ("RawSocketImpl::SendTo packet uid " << packet->GetUid() << " address " << header.GetDestination());
     SocketErrno errno_ = ERROR_NOTERROR;//do not use errno as it is the standard C last error number
     Ptr<Ipv4Route> route;
     uint32_t oif = 0; //specify non-zero if bound to a source address
-    route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+    route = m_ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
     if (route != 0)
     {
-      NS_LOG_LOGIC ("Route exists");
-      Ptr<NetDevice> outDev = route->GetOutputDevice ();
-      int32_t interface = ipv4->GetInterfaceForDevice (outDev);
-      NS_ASSERT (interface >= 0);
-      Ptr<Ipv4Interface> outInterface = ipv4->GetInterface (interface);
-      NS_LOG_LOGIC ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
-
-      NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
-      if (!route->GetGateway ().IsEqual (Ipv4Address ("0.0.0.0")))
-      {
-        if (outInterface->IsUp ())
-        {
-          NS_LOG_UNCOND ("Send to gateway " << route->GetGateway ());
-          outInterface->Send (packet, route->GetGateway ());
-        }
-        else
-        {
-          NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
-        }
-      }
-      else
-      {
-        if (outInterface->IsUp ())
-        {
-          NS_LOG_LOGIC ("Send to destination " << header.GetDestination ());
-          outInterface->Send (packet, header.GetDestination ());
-        }
-        else
-        {
-          NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << header.GetDestination ());
-        }
-      }
+      NS_LOG_UNCOND ("Route exists");
+      SendByInterface(packet, route);
     }
     else
     {
-      NS_LOG_DEBUG ("dropped because no outgoing route.");
+      NS_LOG_UNCOND ("dropped because no outgoing route.");
     }
   }
   return 0;
 }
+
+void
+RawSocketImpl::SendByInterface (Ptr<Packet> packet, Ptr<const Ipv4Route> route)
+{
+  NS_ASSERT(m_node != 0);
+  Ipv4Header ipv4Header;
+  packet->PeekHeader(ipv4Header);
+  Ipv4Address source = ipv4Header.GetSource ();
+  Ipv4Address destination = ipv4Header.GetDestination ();
+  NS_LOG_UNCOND ("RawSocketImpl::SendByInterface to " << destination);
+
+  // Handle a few cases:
+  // 1) packet is destined to limited broadcast address
+  // 2) packet is destined to a subnet-directed broadcast address
+  // 3) packet is not broadcast, and is passed in with a route entry
+  const Ipv4Address loopback ("127.0.0.1");
+  // 1) packet is destined to limited broadcast address
+  if (destination.IsBroadcast ())
+    {
+      NS_LOG_UNCOND ("RawSocketImpl::Send case 1:  limited broadcast");
+      for (std::list< Ptr<Ipv4Interface> >::iterator ifaceIter = m_interfaces.begin (); ifaceIter != m_interfaces.end (); ifaceIter++)
+        {
+          Ptr<Ipv4Interface> outInterface = *ifaceIter;
+          Ptr<Packet> packetCopy = packet->Copy ();
+
+          NS_ASSERT (packet->GetSize () <= outInterface->GetDevice()->GetMtu ());
+          outInterface->Send (packet, destination);
+        }
+      return;
+    }
+
+  // 2) check: packet is destined to a subnet-directed broadcast address
+  uint32_t ifaceIndex = 0;
+  bool result = false;
+  for (std::list< Ptr<Ipv4Interface> >::iterator ifaceIter = m_interfaces.begin (); ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
+  {
+    Ptr<Ipv4Interface> outInterface = *ifaceIter;
+    for (uint32_t j = 0; j < m_ipv4->GetNAddresses (ifaceIndex); j++)
+    {
+      Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (ifaceIndex, j);
+      NS_LOG_UNCOND ("Testing address " << ifAddr.GetLocal () << " with mask " << ifAddr.GetMask ());
+      if (destination.IsSubnetDirectedBroadcast (ifAddr.GetMask ()) &&
+          destination.CombineMask (ifAddr.GetMask ()) == ifAddr.GetLocal ().CombineMask (ifAddr.GetMask ())   )
+      {
+        NS_LOG_UNCOND ("RawSocketImpl::Send case 2:  subnet directed bcast to " << ifAddr.GetLocal ());
+        if (ifAddr.GetLocal() != loopback)
+        {
+          Ptr<Packet> copy = packet->Copy();
+          copy->RemoveHeader(ipv4Header);
+          ipv4Header.SetSource(ifAddr.GetLocal());
+          copy->AddHeader(ipv4Header);
+          outInterface->Send (copy, destination);
+          result = true;
+        }
+      }
+    }
+  }
+  if(result) return;
+
+  // 3) packet is not broadcast, and is passed in with a route entry
+  //    with a valid Ipv4Address as the gateway
+  if (route && route->GetGateway () != Ipv4Address ())
+  {
+    NS_LOG_UNCOND ("RawSocketImpl::Send case 3:  passed in with route");
+    Ptr<NetDevice> outDev = route->GetOutputDevice ();
+    int32_t interface = m_ipv4->GetInterfaceForDevice (outDev);
+    NS_ASSERT (interface >= 0);
+    Ptr<Ipv4Interface> outInterface = m_ipv4->GetInterface (interface);
+    NS_LOG_UNCOND ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
+
+    NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
+    if (!route->GetGateway ().IsEqual (Ipv4Address ("0.0.0.0")))
+    {
+      if (outInterface->IsUp ())
+      {
+        NS_LOG_UNCOND ("Send to gateway " << route->GetGateway ());
+        outInterface->Send (packet, route->GetGateway ());
+      }
+      else
+      {
+        NS_LOG_UNCOND ("Dropping-- outgoing interface is down: " << route->GetGateway ());
+      }
+    }
+       else
+         {
+           if (outInterface->IsUp ())
+             {
+             NS_LOG_UNCOND ("Send to destination " << destination);
+               outInterface->Send (packet,destination);
+             }
+           else
+             {
+             NS_LOG_UNCOND ("Dropping-- outgoing interface is down: " << destination);
+             }
+         }      return;
+    }
+}
+
 uint32_t
 RawSocketImpl::GetRxAvailable (void) const
 {
@@ -276,6 +348,14 @@
   Ptr<Packet> copy = p->Copy ();
   Ipv4Header ipHeader;
   copy->RemoveHeader(ipHeader);
+  for (std::list< Ptr<Ipv4Interface> >::const_iterator ifaceIter = m_interfaces.begin (); ifaceIter != m_interfaces.end (); ifaceIter++)
+  {
+    for (uint32_t i = 0; i < (*ifaceIter)->GetNAddresses(); ++i)
+    {
+      if ((*ifaceIter)->GetAddress(i).GetLocal() == ipHeader.GetSource())
+      return true;
+    }
+  }
   UdpHeader udpHeader;
   copy->RemoveHeader(udpHeader);
   NS_LOG_LOGIC ("src = " << m_src << " dst = " << m_dst);
--- a/src/internet-stack/raw-socket-impl.h	Wed Jul 29 11:47:06 2009 +0400
+++ b/src/internet-stack/raw-socket-impl.h	Wed Jul 29 13:52:00 2009 +0400
@@ -4,6 +4,7 @@
 #include "ns3/socket.h"
 #include "ns3/ipv4-header.h"
 #include "ns3/ipv4-route.h"
+#include "ipv4-l3-protocol.h"
 #include <list>
 
 namespace ns3 {
@@ -32,8 +33,8 @@
   virtual int Listen (void);
   virtual uint32_t GetTxAvailable (void) const;
   virtual int Send (Ptr<Packet> p, uint32_t flags);
-  virtual int SendTo (Ptr<Packet> p, uint32_t flags, 
-		      const Address &toAddress);
+  virtual int SendTo (Ptr<Packet> p, uint32_t flags,const Address &toAddress);
+  void SendByInterface (Ptr<Packet> packet, Ptr<const Ipv4Route> route);
   virtual uint32_t GetRxAvailable (void) const;
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,  
@@ -44,6 +45,7 @@
 private:
   virtual void DoDispose (void);
 
+
   struct Data {
     Ptr<Packet> packet;
     Ipv4Address fromIp;
@@ -60,6 +62,8 @@
   bool m_shutdownSend;
   bool m_shutdownRecv;
   uint32_t m_icmpFilter;
+  std::list< Ptr<Ipv4Interface> > m_interfaces;
+  Ptr<Ipv4L3Protocol> m_ipv4;
 };
 
 } // namespace ns3
--- a/src/routing/aodv/aodv-routing-protocol.cc	Wed Jul 29 11:47:06 2009 +0400
+++ b/src/routing/aodv/aodv-routing-protocol.cc	Wed Jul 29 13:52:00 2009 +0400
@@ -250,8 +250,6 @@
     RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true, /*seqno=*/0, /*iface=*/iface,
         /*hops=*/1, /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Seconds (1e9)); // TODO use infty
     m_routingTable.AddRoute (rt);
-    m_routingTable.Print(std::cout);
-
   }
 
   m_scb = MakeCallback (&RoutingProtocol::Send, this);
@@ -382,7 +380,9 @@
 void
 RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
 {
-  NS_LOG_FUNCTION (this);NS_ASSERT (ipv4 != 0);NS_ASSERT (m_ipv4 == 0);
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT (ipv4 != 0);
+  NS_ASSERT (m_ipv4 == 0);
 
   btimer.SetFunction (&RoutingProtocol::BroadcastTimerExpire, this);
   ntimer.SetFunction (&RoutingProtocol::NeighborTimerExpire, this);