More on IPv6 extensions support.
--- a/src/helper/internet-stack-helper.cc Fri Oct 16 10:25:12 2009 +0200
+++ b/src/helper/internet-stack-helper.cc Fri Oct 16 11:33:56 2009 +0200
@@ -360,6 +360,10 @@
Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
Ptr<Ipv6RoutingProtocol> ipv6Routing = m_routingv6->Create (node);
ipv6->SetRoutingProtocol (ipv6Routing);
+
+ /* register IPv6 extensions and options */
+ ipv6->RegisterExtensions ();
+ ipv6->RegisterOptions ();
}
}
--- a/src/internet-stack/ipv6-extension.cc Fri Oct 16 10:25:12 2009 +0200
+++ b/src/internet-stack/ipv6-extension.cc Fri Oct 16 11:33:56 2009 +0200
@@ -109,9 +109,9 @@
return EXT_NUMBER;
}
-uint8_t Ipv6ExtensionHopByHop::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionHopByHop::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
// For ICMPv6 Error packets
Ptr<Packet> malformedPacket = packet->Copy();
@@ -163,7 +163,7 @@
case 2:
NS_LOG_LOGIC ("Unknown Option. Drop!");
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
m_dropTrace (packet);
optionLength = 0;
isDropped = true;
@@ -175,7 +175,7 @@
if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
{
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
}
m_dropTrace (packet);
@@ -190,7 +190,7 @@
else
{
- optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, ipv6Interface, isDropped);
+ optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
}
processedSize += optionLength;
@@ -231,9 +231,9 @@
return EXT_NUMBER;
}
-uint8_t Ipv6ExtensionDestination::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionDestination::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
// For ICMPv6 Error packets
Ptr<Packet> malformedPacket = packet->Copy();
@@ -285,7 +285,7 @@
case 2:
NS_LOG_LOGIC ("Unknown Option. Drop!");
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
m_dropTrace (packet);
optionLength = 0;
isDropped = true;
@@ -297,7 +297,7 @@
if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
{
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
}
m_dropTrace (packet);
@@ -312,7 +312,7 @@
else
{
- optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, ipv6Interface, isDropped);
+ optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
}
processedSize += optionLength;
@@ -366,9 +366,9 @@
return EXT_NUMBER;
}
-uint8_t Ipv6ExtensionFragment::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionFragment::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
@@ -709,9 +709,9 @@
return 0;
}
-uint8_t Ipv6ExtensionRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
// For ICMPv6 Error Packets
Ptr<Packet> malformedPacket = packet->Copy();
@@ -749,7 +749,7 @@
NS_LOG_LOGIC("Malformed header. Drop!");
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
m_dropTrace (packet);
isDropped = true;
}
@@ -757,7 +757,7 @@
return routingLength;
}
- return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, ipv6Interface, (uint8_t *)0, isDropped);
+ return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, isDropped);
}
@@ -853,9 +853,9 @@
return TYPE_ROUTING;
}
-uint8_t Ipv6ExtensionLooseRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionLooseRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
// For ICMPv6 Error packets
Ptr<Packet> malformedPacket = packet->Copy ();
@@ -905,7 +905,7 @@
{
NS_LOG_LOGIC("Malformed header. Drop!");
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
m_dropTrace (packet);
isDropped = true;
return routingHeader.GetSerializedSize ();
@@ -915,7 +915,7 @@
{
NS_LOG_LOGIC("Malformed header. Drop!");
/* TODO */
- /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3); */
+ /* icmpv6->SendErrorParameterError (malformedPacket, dst, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3); */
m_dropTrace (packet);
isDropped = true;
return routingHeader.GetSerializedSize ();
@@ -939,7 +939,7 @@
{
NS_LOG_LOGIC("Time Exceeded : Hop Limit <= 1. Drop!");
/* TODO */
- /* icmpv6->SendErrorTimeExceeded (malformedPacket, ipv6Interface->GetAddress(), srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT); */
+ /* icmpv6->SendErrorTimeExceeded (malformedPacket, dst, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT); */
m_dropTrace (packet);
isDropped = true;
return routingHeader.GetSerializedSize ();
@@ -994,9 +994,9 @@
return EXT_NUMBER;
}
-uint8_t Ipv6ExtensionESP::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionESP::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
/* TODO */
@@ -1034,9 +1034,9 @@
return EXT_NUMBER;
}
-uint8_t Ipv6ExtensionAH::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+uint8_t Ipv6ExtensionAH::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
/* TODO */
--- a/src/internet-stack/ipv6-extension.h Fri Oct 16 10:25:12 2009 +0200
+++ b/src/internet-stack/ipv6-extension.h Fri Oct 16 11:33:56 2009 +0200
@@ -83,12 +83,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped) = 0;
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped) = 0;
protected:
TracedCallback<Ptr<const Packet> > m_dropTrace;
@@ -137,12 +137,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
};
/**
@@ -182,12 +182,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
};
/**
@@ -227,12 +227,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
/**
* \brief Fragment a packet
@@ -371,12 +371,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
};
/**
@@ -485,12 +485,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
};
/**
@@ -531,12 +531,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
};
/**
@@ -577,12 +577,12 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param dst destination address of the packet received (i.e. us)
* \param nextHeader the next header
* \param isDropped if the packet must be dropped
* \return the size processed
*/
- virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
};
} /* namespace ns3 */
--- a/src/internet-stack/ipv6-l3-protocol.cc Fri Oct 16 10:25:12 2009 +0200
+++ b/src/internet-stack/ipv6-l3-protocol.cc Fri Oct 16 11:33:56 2009 +0200
@@ -34,6 +34,11 @@
#include "ipv6-interface.h"
#include "ipv6-raw-socket-impl.h"
#include "ipv6-autoconfigured-prefix.h"
+#include "ipv6-extension-demux.h"
+#include "ipv6-extension.h"
+#include "ipv6-extension-header.h"
+#include "ipv6-option-demux.h"
+#include "ipv6-option.h"
#include "icmpv6-l4-protocol.h"
#include "ndisc-cache.h"
@@ -692,6 +697,26 @@
socket->ForwardUp (packet, hdr, device);
}
+ Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
+ Ptr<Ipv6Extension> ipv6Extension = 0;
+ uint8_t nextHeader = hdr.GetNextHeader ();
+ bool isDropped = false;
+
+ if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ {
+ ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
+
+ if (ipv6Extension)
+ {
+ ipv6Extension->Process (packet, 0, hdr, hdr.GetDestinationAddress (), (uint8_t *)0, isDropped);
+ }
+
+ if (isDropped)
+ {
+ return;
+ }
+ }
+
m_routingProtocol->RouteInput (packet, hdr, device,
MakeCallback (&Ipv6L3Protocol::IpForward, this),
MakeCallback (&Ipv6L3Protocol::IpMulticastForward, this),
@@ -717,15 +742,47 @@
Ptr<Ipv6Interface> outInterface = GetInterface (interface);
NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
+ // Check packet size
+ std::list<Ptr<Packet> > fragments;
+
+ if (packet->GetSize () > (size_t)(dev->GetMtu () + 40)) /* 40 => size of IPv6 header */
+ {
+ // Router => drop
+ if (m_ipForward)
+ {
+ return;
+ }
+
+ Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
+
+ // 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);
+ }
+
if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
{
if (outInterface->IsUp ())
{
NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
packet->AddHeader (ipHeader);
- NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
- m_txTrace (packet, interface);
- outInterface->Send (packet, route->GetGateway ());
+
+ if (fragments.size () != 0)
+ {
+ std::ostringstream oss;
+
+ for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
+ {
+ m_txTrace (*it, interface);
+ outInterface->Send (*it, route->GetGateway ());
+ }
+ }
+ else
+ {
+ /* NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ()); */
+ m_txTrace (packet, interface);
+ outInterface->Send (packet, route->GetGateway ());
+ }
}
else
{
@@ -739,9 +796,23 @@
{
NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
packet->AddHeader (ipHeader);
- NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
- m_txTrace (packet, interface);
- outInterface->Send (packet, ipHeader.GetDestinationAddress ());
+
+ if (fragments.size () != 0)
+ {
+ std::ostringstream oss;
+
+ for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
+ {
+ m_txTrace (*it, interface);
+ outInterface->Send (*it, ipHeader.GetDestinationAddress ());
+ }
+ }
+ else
+ {
+ /* NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ()); */
+ m_txTrace (packet, interface);
+ outInterface->Send (packet, ipHeader.GetDestinationAddress ());
+ }
}
else
{
@@ -855,8 +926,89 @@
{
NS_LOG_FUNCTION (this << packet << ip << iif);
Ptr<Packet> p = packet->Copy ();
- Ptr<Ipv6L4Protocol> protocol = GetProtocol (ip.GetNextHeader ());
+ Ptr<Ipv6L4Protocol> protocol = 0;
+/*GetProtocol (ip.GetNextHeader ());*/
+
+ Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
+ Ptr<Ipv6Extension> ipv6Extension = 0;
+
+ Ipv6Address src = ip.GetSourceAddress ();
+ Ipv6Address dst = ip.GetDestinationAddress ();
+ uint8_t nextHeader = ip.GetNextHeader ();
+ uint8_t nextHeaderPosition = 0;
+ bool isDropped = false;
+
+ if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ {
+ const uint8_t *buff = p->PeekData ();
+
+ nextHeader = *buff;
+ nextHeaderPosition = *(buff + 1);
+ }
+
+ do {
+ ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
+
+ if (ipv6Extension)
+ {
+ nextHeaderPosition += ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, isDropped);
+
+ if (isDropped)
+ {
+ return;
+ }
+ }
+ else
+ {
+ protocol = GetProtocol (nextHeader);
+
+ if (!protocol)
+ {
+ NS_LOG_LOGIC ("Unknown Next Header. Drop!");
+ if (nextHeaderPosition == 0)
+ {
+ /* TODO */
+ /* GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, src, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40); */
+ }
+ else
+ {
+ /* TODO */
+ /* GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, src, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition); */
+ }
+ m_dropTrace (ip, p, DROP_UNKNOWN_PROTOCOL, iif);
+ break;
+ }
+ else
+ {
+ p->RemoveAtStart (nextHeaderPosition);
+ /* protocol->Receive (p, src, dst, incomingInterface); */
+
+ /* L4 protocol */
+ Ptr<Packet> copy = p->Copy ();
+ enum Ipv6L4Protocol::RxStatus_e status = protocol->Receive (p, ip.GetSourceAddress (), ip.GetDestinationAddress (), GetInterface (iif));
+
+ switch (status)
+ {
+ case Ipv6L4Protocol::RX_OK:
+ break;
+ case Ipv6L4Protocol::RX_CSUM_FAILED:
+ break;
+ case Ipv6L4Protocol::RX_ENDPOINT_UNREACH:
+ if (ip.GetDestinationAddress ().IsMulticast ())
+ {
+ /* do not rely on multicast address */
+ break;
+ }
+
+ copy->AddHeader (ip);
+ GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
+ }
+ }
+ }
+ } while (ipv6Extension);
+
+#if 0
if (protocol)
{
Ptr<Packet> copy = p->Copy ();
@@ -879,6 +1031,7 @@
GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
}
}
+#endif
}
void Ipv6L3Protocol::RouteInputError (Ptr<const Packet> p, const Ipv6Header& ipHeader, Socket::SocketErrno sockErrno)
@@ -901,5 +1054,60 @@
return hdr;
}
+void Ipv6L3Protocol::RegisterExtensions ()
+{
+ Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
+ ipv6ExtensionDemux->SetNode (m_node);
+
+ Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
+ hopbyhopExtension->SetNode (m_node);
+ Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
+ destinationExtension->SetNode (m_node);
+ Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
+ fragmentExtension->SetNode (m_node);
+ Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
+ routingExtension->SetNode (m_node);
+ // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
+ // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
+
+ ipv6ExtensionDemux->Insert (hopbyhopExtension);
+ ipv6ExtensionDemux->Insert (destinationExtension);
+ ipv6ExtensionDemux->Insert (fragmentExtension);
+ ipv6ExtensionDemux->Insert (routingExtension);
+ // ipv6ExtensionDemux->Insert (espExtension);
+ // ipv6ExtensionDemux->Insert (ahExtension);
+
+ Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
+ routingExtensionDemux->SetNode (m_node);
+ Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
+ looseRoutingExtension->SetNode (m_node);
+ routingExtensionDemux->Insert (looseRoutingExtension);
+
+ m_node->AggregateObject (routingExtensionDemux);
+ m_node->AggregateObject (ipv6ExtensionDemux);
+}
+
+void Ipv6L3Protocol::RegisterOptions ()
+{
+ Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
+ ipv6OptionDemux->SetNode (m_node);
+
+ Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
+ pad1Option->SetNode (m_node);
+ Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
+ padnOption->SetNode (m_node);
+ Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
+ jumbogramOption->SetNode (m_node);
+ Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
+ routerAlertOption->SetNode (m_node);
+
+ ipv6OptionDemux->Insert (pad1Option);
+ ipv6OptionDemux->Insert (padnOption);
+ ipv6OptionDemux->Insert (jumbogramOption);
+ ipv6OptionDemux->Insert (routerAlertOption);
+
+ m_node->AggregateObject (ipv6OptionDemux);
+}
+
} /* namespace ns3 */
--- a/src/internet-stack/ipv6-l3-protocol.h Fri Oct 16 10:25:12 2009 +0200
+++ b/src/internet-stack/ipv6-l3-protocol.h Fri Oct 16 11:33:56 2009 +0200
@@ -79,6 +79,7 @@
DROP_NO_ROUTE, /**< No route to host */
DROP_INTERFACE_DOWN, /**< Interface is down so can not send packet */
DROP_ROUTE_ERROR, /**< Route error */
+ DROP_UNKNOWN_PROTOCOL, /**< Unkown L4 protocol */
};
/**
@@ -329,6 +330,16 @@
*/
void RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter);
+ /**
+ * \brief Register the IPv6 Extensions.
+ */
+ virtual void RegisterExtensions ();
+
+ /**
+ * \brief Register the IPv6 Options.
+ */
+ virtual void RegisterOptions ();
+
protected:
/**
* \brief Dispose object.
--- a/src/internet-stack/ipv6-option.cc Fri Oct 16 10:25:12 2009 +0200
+++ b/src/internet-stack/ipv6-option.cc Fri Oct 16 11:33:56 2009 +0200
@@ -85,9 +85,9 @@
return OPT_NUMBER;
}
-uint8_t Ipv6OptionPad1::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+uint8_t Ipv6OptionPad1::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << isDropped);
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
@@ -131,9 +131,9 @@
return OPT_NUMBER;
}
-uint8_t Ipv6OptionPadn::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+uint8_t Ipv6OptionPadn::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << isDropped);
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
@@ -177,9 +177,9 @@
return OPT_NUMBER;
}
-uint8_t Ipv6OptionJumbogram::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+uint8_t Ipv6OptionJumbogram::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << isDropped);
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
@@ -223,9 +223,9 @@
return OPT_NUMBER;
}
-uint8_t Ipv6OptionRouterAlert::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+uint8_t Ipv6OptionRouterAlert::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped)
{
- NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << isDropped);
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
--- a/src/internet-stack/ipv6-option.h Fri Oct 16 10:25:12 2009 +0200
+++ b/src/internet-stack/ipv6-option.h Fri Oct 16 11:33:56 2009 +0200
@@ -73,11 +73,10 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
* \param isDropped if the packet must be dropped
* \return the processed size
*/
- virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped) = 0;
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped) = 0;
private:
/**
@@ -123,11 +122,10 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
* \param isDropped if the packet must be dropped
* \return the processed size
*/
- virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped);
};
/**
@@ -167,11 +165,10 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
* \param isDropped if the packet must be dropped
* \return the processed size
*/
- virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped);
};
/**
@@ -211,11 +208,10 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
* \param isDropped if the packet must be dropped
* \return the processed size
*/
- virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped);
private:
/**
@@ -261,11 +257,10 @@
* \param packet the packet
* \param offset the offset of the extension to process
* \param ipv6Header the IPv6 header of packet received
- * \param ipv6Interface the Ipv6Interface on which the packet arrived
* \param isDropped if the packet must be dropped
* \return the processed size
*/
- virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped);
};
} /* namespace ns3 */
--- a/src/node/ipv6.h Fri Oct 16 10:25:12 2009 +0200
+++ b/src/node/ipv6.h Fri Oct 16 11:33:56 2009 +0200
@@ -284,6 +284,16 @@
virtual void SetForwarding (uint32_t interface, bool val) = 0;
/**
+ * \brief Register the IPv6 Extensions.
+ */
+ virtual void RegisterExtensions () = 0;
+
+ /**
+ * \brief Register the IPv6 Options.
+ */
+ virtual void RegisterOptions () = 0;
+
+ /**
* \brief Any interface magic number.
*/
static const uint32_t IF_ANY = 0xffffffff;