IPv6 Fragmentation support.
authorSebastien Vincent <sebastien.vincent@turnserver.org>
Sun, 18 Oct 2009 15:55:34 +0200
changeset 5785 5d433b13a9c1
parent 5784 512909f442f7
child 5786 75fe172041e0
IPv6 Fragmentation support.
examples/ipv6/wscript
src/applications/ping6/ping6.cc
src/internet-stack/icmpv6-l4-protocol.cc
src/internet-stack/ipv6-extension.cc
src/internet-stack/ipv6-l3-protocol.cc
--- a/examples/ipv6/wscript	Fri Oct 16 11:33:56 2009 +0200
+++ b/examples/ipv6/wscript	Sun Oct 18 15:55:34 2009 +0200
@@ -6,6 +6,9 @@
 
     obj = bld.create_ns3_program('ping6', ['csma', 'internet-stack'])
     obj.source = 'ping6.cc'
+    
+    obj = bld.create_ns3_program('fragmentation-ipv6', ['csma', 'internet-stack'])
+    obj.source = 'fragmentation-ipv6.cc'
 
     obj = bld.create_ns3_program('radvd', ['csma', 'internet-stack'])
     obj.source = 'radvd.cc'
--- a/src/applications/ping6/ping6.cc	Fri Oct 16 11:33:56 2009 +0200
+++ b/src/applications/ping6/ping6.cc	Sun Oct 18 15:55:34 2009 +0200
@@ -156,7 +156,7 @@
   NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT (m_sendEvent.IsExpired ());
   Ptr<Packet> p = 0;
-  uint8_t data[4];
+  uint8_t data[m_size];
   Ipv6Address src;
   Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
 
@@ -172,12 +172,14 @@
     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, sizeof (data));
+  p = Create<Packet> (data, 4);
+  p->AddAtEnd (Create<Packet> (m_size - 4));
   Icmpv6Echo req (1);
 
   req.SetId (0xBEEF);
--- a/src/internet-stack/icmpv6-l4-protocol.cc	Fri Oct 16 11:33:56 2009 +0200
+++ b/src/internet-stack/icmpv6-l4-protocol.cc	Sun Oct 18 15:55:34 2009 +0200
@@ -228,10 +228,15 @@
 {
   NS_LOG_FUNCTION (this << packet << src << dst << interface);
   Icmpv6Echo request;
+  uint8_t buf[packet->GetSize ()];
+
   packet->RemoveHeader (request);
+  /* XXX IPv6 extension: obtain a fresh copy of data otherwise it crash... */
+  packet->CopyData (buf, packet->GetSize ());
+  Ptr<Packet> p = Create<Packet> (buf, packet->GetSize ());
 
   /* if we send message from ff02::* (link-local multicast), we use our link-local address */
-  SendEchoReply (dst.IsMulticast () ? interface->GetLinkLocalAddress ().GetAddress () : dst, src, request.GetId (), request.GetSeq (), packet);
+  SendEchoReply (dst.IsMulticast () ? interface->GetLinkLocalAddress ().GetAddress () : dst, src, request.GetId (), request.GetSeq (), p);
 }
 
 void Icmpv6L4Protocol::HandleRA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
--- a/src/internet-stack/ipv6-extension.cc	Fri Oct 16 11:33:56 2009 +0200
+++ b/src/internet-stack/ipv6-extension.cc	Sun Oct 18 15:55:34 2009 +0200
@@ -187,7 +187,6 @@
           break;
       }
     }
-
     else 
     {
       optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
@@ -309,7 +308,6 @@
           break;
       }
     }
-
     else 
     {
       optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
@@ -395,7 +393,6 @@
     fragments = Create<Fragments> ();
     m_fragments.insert (std::make_pair (fragmentsId, fragments));
   }
-
   else
   {
     fragments = it->second;
@@ -415,7 +412,6 @@
     packet = fragments->GetPacket ();
     isDropped = false;
   }
-
   else 
   {
     NS_LOG_LOGIC("Fragment. Drop!");
@@ -743,7 +739,6 @@
     {
       isDropped = false;
     }
-
     else
     {
       NS_LOG_LOGIC("Malformed header. Drop!");
@@ -894,7 +889,6 @@
   uint8_t nextAddressIndex;
   Ipv6Address nextAddress;
 
-
   if (segmentsLeft == 0)
   {
     isDropped = false;
@@ -1042,6 +1036,6 @@
 
   return true;
 }
+
 } /* namespace ns3 */
 
-
--- a/src/internet-stack/ipv6-l3-protocol.cc	Fri Oct 16 11:33:56 2009 +0200
+++ b/src/internet-stack/ipv6-l3-protocol.cc	Sun Oct 18 15:55:34 2009 +0200
@@ -755,6 +755,8 @@
 
     Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
 
+    packet->AddHeader (ipHeader);
+
     // To get specific method GetFragments from Ipv6ExtensionFragmentation
     Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *>(PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
     ipv6Fragment->GetFragments (packet, outInterface->GetDevice ()->GetMtu (), fragments);
@@ -765,12 +767,12 @@
     if (outInterface->IsUp ())
     {
       NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
-      packet->AddHeader (ipHeader);
 
       if (fragments.size () != 0)
       {
         std::ostringstream oss;
 
+        /* IPv6 header is already added in fragments */
         for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
         {
           m_txTrace (*it, interface);
@@ -780,6 +782,7 @@
       else
       {
         /* NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ()); */
+        packet->AddHeader (ipHeader);
         m_txTrace (packet, interface);
         outInterface->Send (packet, route->GetGateway ());
       }
@@ -794,13 +797,13 @@
   {
     if (outInterface->IsUp ())
     {
-       NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
-       packet->AddHeader (ipHeader);
+      NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
 
       if (fragments.size () != 0)
       {
         std::ostringstream oss;
-
+        
+        /* IPv6 header is already added in fragments */
         for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
         {
           m_txTrace (*it, interface);
@@ -810,6 +813,7 @@
       else
       {
         /* NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ()); */
+        packet->AddHeader (ipHeader);
         m_txTrace (packet, interface);
         outInterface->Send (packet, ipHeader.GetDestinationAddress ());
       }