src/internet-stack/ipv4-raw-socket-impl.cc
changeset 3820 c04ecfdce1ef
child 4372 d99061f1167c
equal deleted inserted replaced
3819:37b316422064 3820:c04ecfdce1ef
       
     1 #include "ipv4-raw-socket-impl.h"
       
     2 #include "ipv4-l3-protocol.h"
       
     3 #include "icmpv4.h"
       
     4 #include "ns3/inet-socket-address.h"
       
     5 #include "ns3/node.h"
       
     6 #include "ns3/packet.h"
       
     7 #include "ns3/uinteger.h"
       
     8 #include "ns3/log.h"
       
     9 
       
    10 NS_LOG_COMPONENT_DEFINE ("Ipv4RawSocketImpl");
       
    11 
       
    12 namespace ns3 {
       
    13 
       
    14 NS_OBJECT_ENSURE_REGISTERED (Ipv4RawSocketImpl);
       
    15 
       
    16 TypeId 
       
    17 Ipv4RawSocketImpl::GetTypeId (void)
       
    18 {
       
    19   static TypeId tid = TypeId ("ns3::Ipv4RawSocketImpl")
       
    20     .SetParent<Socket> ()
       
    21     .AddAttribute ("Protocol", "Protocol number to match.",
       
    22 		   UintegerValue (0),
       
    23 		   MakeUintegerAccessor (&Ipv4RawSocketImpl::m_protocol),
       
    24 		   MakeUintegerChecker<uint16_t> ())
       
    25     .AddAttribute ("IcmpFilter", 
       
    26 		   "Any icmp header whose type field matches a bit in this filter is dropped.",
       
    27 		   UintegerValue (0),
       
    28 		   MakeUintegerAccessor (&Ipv4RawSocketImpl::m_icmpFilter),
       
    29 		   MakeUintegerChecker<uint32_t> ())
       
    30     ;
       
    31   return tid;
       
    32 }
       
    33 
       
    34 Ipv4RawSocketImpl::Ipv4RawSocketImpl ()
       
    35 {
       
    36   NS_LOG_FUNCTION (this);
       
    37   m_err = Socket::ERROR_NOTERROR;
       
    38   m_node = 0;
       
    39   m_src = Ipv4Address::GetAny ();
       
    40   m_dst = Ipv4Address::GetAny ();
       
    41   m_protocol = 0;
       
    42   m_shutdownSend = false;
       
    43   m_shutdownRecv = false;
       
    44 }
       
    45 
       
    46 void 
       
    47 Ipv4RawSocketImpl::SetNode (Ptr<Node> node)
       
    48 {
       
    49   m_node = node;
       
    50 }
       
    51 
       
    52 void
       
    53 Ipv4RawSocketImpl::DoDispose (void)
       
    54 {
       
    55   NS_LOG_FUNCTION (this);
       
    56   m_node = 0;
       
    57   Socket::DoDispose ();
       
    58 }
       
    59 
       
    60 enum Socket::SocketErrno 
       
    61 Ipv4RawSocketImpl::GetErrno (void) const
       
    62 {
       
    63   NS_LOG_FUNCTION (this);
       
    64   return m_err;
       
    65 }
       
    66 Ptr<Node> 
       
    67 Ipv4RawSocketImpl::GetNode (void) const
       
    68 {
       
    69   NS_LOG_FUNCTION (this);
       
    70   return m_node;
       
    71 }
       
    72 int 
       
    73 Ipv4RawSocketImpl::Bind (const Address &address)
       
    74 {
       
    75   NS_LOG_FUNCTION (this << address);
       
    76   if (!InetSocketAddress::IsMatchingType (address))
       
    77     {
       
    78       m_err = Socket::ERROR_INVAL;
       
    79       return -1;
       
    80     }
       
    81   InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
       
    82   m_src = ad.GetIpv4 ();
       
    83   return 0;
       
    84 }
       
    85 int 
       
    86 Ipv4RawSocketImpl::Bind (void)
       
    87 {
       
    88   NS_LOG_FUNCTION (this);
       
    89   m_src = Ipv4Address::GetAny ();
       
    90   return 0;
       
    91 }
       
    92 int 
       
    93 Ipv4RawSocketImpl::GetSockName (Address &address) const
       
    94 {
       
    95   address = InetSocketAddress (m_src, 0);
       
    96   return 0;
       
    97 }
       
    98 int 
       
    99 Ipv4RawSocketImpl::Close (void)
       
   100 {
       
   101   NS_LOG_FUNCTION (this);
       
   102   Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
       
   103   if (ipv4 != 0)
       
   104     {
       
   105       ipv4->DeleteRawSocket (this);
       
   106     }
       
   107   return 0;
       
   108 }
       
   109 int 
       
   110 Ipv4RawSocketImpl::ShutdownSend (void)
       
   111 {
       
   112   NS_LOG_FUNCTION (this);
       
   113   m_shutdownSend = true;
       
   114   return 0;
       
   115 }
       
   116 int 
       
   117 Ipv4RawSocketImpl::ShutdownRecv (void)
       
   118 {
       
   119   NS_LOG_FUNCTION (this);
       
   120   m_shutdownRecv = true;
       
   121   return 0;
       
   122 }
       
   123 int 
       
   124 Ipv4RawSocketImpl::Connect (const Address &address)
       
   125 {
       
   126   NS_LOG_FUNCTION (this << address);
       
   127   if (!InetSocketAddress::IsMatchingType (address))
       
   128     {
       
   129       m_err = Socket::ERROR_INVAL;
       
   130       return -1;
       
   131     }
       
   132   InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
       
   133   m_dst = ad.GetIpv4 ();
       
   134   return 0;
       
   135 }
       
   136 int 
       
   137 Ipv4RawSocketImpl::Listen (void)
       
   138 {
       
   139   NS_LOG_FUNCTION (this);
       
   140   m_err = Socket::ERROR_OPNOTSUPP;
       
   141   return -1;
       
   142 }
       
   143 uint32_t 
       
   144 Ipv4RawSocketImpl::GetTxAvailable (void) const
       
   145 {
       
   146   NS_LOG_FUNCTION (this);
       
   147   return 0xffffffff;
       
   148 }
       
   149 int 
       
   150 Ipv4RawSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
       
   151 {
       
   152   NS_LOG_FUNCTION (this << p << flags);
       
   153   InetSocketAddress to = InetSocketAddress (m_dst, m_protocol);
       
   154   return SendTo (p, flags, to);
       
   155 }
       
   156 int 
       
   157 Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, 
       
   158 			   const Address &toAddress)
       
   159 {
       
   160   NS_LOG_FUNCTION (this << p << flags << toAddress);
       
   161   if (!InetSocketAddress::IsMatchingType (toAddress))
       
   162     {
       
   163       m_err = Socket::ERROR_INVAL;
       
   164       return -1;
       
   165     }
       
   166   if (m_shutdownSend)
       
   167     {
       
   168       return 0;
       
   169     }
       
   170   InetSocketAddress ad = InetSocketAddress::ConvertFrom (toAddress);
       
   171   Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
       
   172   Ipv4Address dst = ad.GetIpv4 ();
       
   173   uint32_t localIfIndex;
       
   174   if (ipv4->GetIfIndexForDestination(dst, localIfIndex))
       
   175     {
       
   176       ipv4->Send (p, ipv4->GetAddress (localIfIndex), dst, m_protocol);
       
   177     }
       
   178   else
       
   179     {
       
   180       NS_LOG_DEBUG ("dropped because no outgoing route.");
       
   181     }
       
   182   return 0;
       
   183 }
       
   184 uint32_t 
       
   185 Ipv4RawSocketImpl::GetRxAvailable (void) const
       
   186 {
       
   187   NS_LOG_FUNCTION (this);
       
   188   uint32_t rx = 0;
       
   189   for (std::list<Data>::const_iterator i = m_recv.begin (); i != m_recv.end (); ++i)
       
   190     {
       
   191       rx += (i->packet)->GetSize ();
       
   192     }
       
   193   return rx;
       
   194 }
       
   195 Ptr<Packet> 
       
   196 Ipv4RawSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
       
   197 {
       
   198   NS_LOG_FUNCTION (this << maxSize << flags);
       
   199   Address tmp;
       
   200   return RecvFrom (maxSize, flags, tmp);
       
   201 }
       
   202 Ptr<Packet> 
       
   203 Ipv4RawSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,  
       
   204 			     Address &fromAddress)
       
   205 {
       
   206   NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
       
   207   if (m_recv.empty ())
       
   208     {
       
   209       return 0;
       
   210     }
       
   211   struct Data data = m_recv.front ();
       
   212   m_recv.pop_front ();
       
   213   if (data.packet->GetSize () > maxSize)
       
   214     {
       
   215       Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
       
   216       data.packet->RemoveAtStart (maxSize);
       
   217       m_recv.push_front (data);
       
   218       return first;
       
   219     }
       
   220   InetSocketAddress inet = InetSocketAddress (data.fromIp, data.fromProtocol);
       
   221   fromAddress = inet;
       
   222   return data.packet;
       
   223 }
       
   224 
       
   225 void 
       
   226 Ipv4RawSocketImpl::SetProtocol (uint16_t protocol)
       
   227 {
       
   228   NS_LOG_FUNCTION (this << protocol);
       
   229   m_protocol = protocol;
       
   230 }
       
   231 
       
   232 bool 
       
   233 Ipv4RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv4Header ipHeader, Ptr<NetDevice> device)
       
   234 {
       
   235   NS_LOG_FUNCTION (this << *p << ipHeader << device);
       
   236   if (m_shutdownRecv)
       
   237     {
       
   238       return false;
       
   239     }
       
   240   if ((m_src == Ipv4Address::GetAny () || ipHeader.GetDestination () == m_src) &&
       
   241       (m_dst == Ipv4Address::GetAny () || ipHeader.GetSource () == m_dst) &&
       
   242       ipHeader.GetProtocol () == m_protocol)
       
   243     {
       
   244       Ptr<Packet> copy = p->Copy ();
       
   245       if (m_protocol == 1)
       
   246 	{
       
   247 	  Icmpv4Header icmpHeader;
       
   248 	  copy->PeekHeader (icmpHeader);
       
   249 	  uint8_t type = icmpHeader.GetType ();
       
   250 	  if (type < 32 && 
       
   251 	      ((1 << type) & m_icmpFilter))
       
   252 	    {
       
   253 	      // filter out icmp packet.
       
   254 	      return false;
       
   255 	    }
       
   256 	}
       
   257       copy->AddHeader (ipHeader);
       
   258       struct Data data;
       
   259       data.packet = copy;
       
   260       data.fromIp = ipHeader.GetSource ();
       
   261       data.fromProtocol = ipHeader.GetProtocol ();
       
   262       m_recv.push_back (data);
       
   263       NotifyDataRecv ();
       
   264       return true;
       
   265     }
       
   266   return false;
       
   267 }
       
   268 
       
   269 } // namespace ns3