Example #1
0
void Ping6::Send ()
{
  NS_LOG_FUNCTION_NOARGS ();
  NS_ASSERT (m_sendEvent.IsExpired ());
  Ptr<Packet> p = 0;
  uint8_t* data = new uint8_t[m_size];
  Ipv6Address src;
  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();

  if (m_ifIndex > 0)
    {
      /* hack to have ifIndex in Ipv6RawSocketImpl
       * maybe add a SetIfIndex in Ipv6RawSocketImpl directly 
       */
      Ipv6InterfaceAddress dstIa (m_peerAddress);
      for (uint32_t i = 0; i < GetNode ()->GetObject<Ipv6> ()->GetNAddresses (m_ifIndex); i++)
        {
          src = GetNode ()->GetObject<Ipv6> ()->GetAddress (m_ifIndex, i).GetAddress ();
          Ipv6InterfaceAddress srcIa (src);
          if ( srcIa.GetScope() == dstIa.GetScope() )
            {
              break;
            }
        }
     }
  else
    {
      src = m_localAddress;
    }

  NS_ASSERT_MSG (m_size >= 4, "ICMPv6 echo request payload size must be >= 4");
  data[0] = 0xDE;
  data[1] = 0xAD;
  data[2] = 0xBE;
  data[3] = 0xEF;

  p = Create<Packet> (data, 4);
  p->AddAtEnd (Create<Packet> (m_size - 4));
  Icmpv6Echo req (1);

  req.SetId (0xBEEF);
  req.SetSeq (m_seq);
  m_seq++;

  /* we do not calculate pseudo header checksum here, because we are not sure about 
   * source IPv6 address. Checksum is calculated in Ipv6RawSocketImpl.
   */

  p->AddHeader (req);
  m_socket->Bind (Inet6SocketAddress (src, 0));

  /* use Loose Routing (routing type 0) */
  if (m_routers.size ())
    {
      Ipv6ExtensionLooseRoutingHeader routingHeader;
      routingHeader.SetNextHeader (Ipv6Header::IPV6_ICMPV6);
      routingHeader.SetLength (m_routers.size () * 16 + 8);
      routingHeader.SetTypeRouting (0);
      routingHeader.SetSegmentsLeft (m_routers.size ());
      routingHeader.SetRoutersAddress (m_routers);
      p->AddHeader (routingHeader);
      m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_EXT_ROUTING));
    }

  m_socket->Send (p, 0);
  ++m_sent;

  NS_LOG_INFO ("Sent " << p->GetSize () << " bytes to " << m_peerAddress);

  if (m_sent < m_count)
    {
      ScheduleTransmit (m_interval);
    }

  delete[] data;
}
Ptr<Packet> PendingData::CopyFromOffset (uint32_t s, uint32_t o)
{ // Make a copy of data from starting position "o" for "s" bytes
  // Return NULL if results in zero length data
  NS_LOG_FUNCTION (this << s << o);
  uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
  if (s1 == 0)
    {
      return Create<Packet> ();   // No data requested
    }
  if (data.size () != 0)
    { // Actual data exists, make copy and return it
      uint32_t count = 0;
      std::vector<Ptr<Packet> >::size_type begin = 0;
      bool beginFound = false;
      std::vector<Ptr<Packet> >::size_type end = 0;
      Ptr<Packet> outPacket;
      Ptr<Packet> endFragment;
      for (std::vector<Ptr<Packet> >::size_type i=0; i<data.size (); ++i)
        {
          count+=data[i]->GetSize ();
          if (!beginFound)
            {
              if (count > o)
                {
                  if (count >= o + s1) //then just copy within this packet
                    {
                      Ptr<Packet> toFragment = data[i];
                      uint32_t packetStart = count - toFragment->GetSize ();
                      uint32_t packetOffset = o - packetStart;
                      outPacket = toFragment->CreateFragment (packetOffset, s1);
                      return outPacket;
                    }
                  begin = i;
                  beginFound = true;
                  Ptr<Packet> toFragment = data[begin];
                  uint32_t packetStart = count - toFragment->GetSize ();
                  uint32_t packetOffset = o - packetStart;
                  uint32_t fragmentLength = count - o;
                  outPacket = toFragment->CreateFragment (packetOffset, fragmentLength);
                }
            }
          else
            {
              if (count >= o + s1)
                {
                  end = i;
                  Ptr<Packet> toFragment = data[end];
                  uint32_t packetStart = count - toFragment->GetSize ();
                  uint32_t fragmentLength = o + s1 - packetStart;
                  endFragment = toFragment->CreateFragment (0, fragmentLength);
                  break;
                }
            }
        }
      for (std::vector<Ptr<Packet> >::size_type i=begin+1; i<end; ++i)
        {
          outPacket->AddAtEnd (data[i]);
        }
      if (endFragment)
        {
          outPacket->AddAtEnd (endFragment);
        }
      NS_ASSERT (outPacket->GetSize () == s1);
      return outPacket;
    }
  else
    { // No actual data, just return dummy-data packet of correct size
      return Create<Packet> (s1);
    }
}