IPv6 Fragmentation support.
--- 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 ());
}