diff --git a/src/helper/internet-stack-helper.cc b/src/helper/internet-stack-helper.cc index 9848b25a3..909d0062b 100644 --- a/src/helper/internet-stack-helper.cc +++ b/src/helper/internet-stack-helper.cc @@ -360,6 +360,10 @@ InternetStackHelper::Install (Ptr node) const Ptr ipv6 = node->GetObject (); Ptr ipv6Routing = m_routingv6->Create (node); ipv6->SetRoutingProtocol (ipv6Routing); + + /* register IPv6 extensions and options */ + ipv6->RegisterExtensions (); + ipv6->RegisterOptions (); } } diff --git a/src/internet-stack/ipv6-extension.cc b/src/internet-stack/ipv6-extension.cc index b629da69c..a11cefb3a 100644 --- a/src/internet-stack/ipv6-extension.cc +++ b/src/internet-stack/ipv6-extension.cc @@ -109,9 +109,9 @@ uint8_t Ipv6ExtensionHopByHop::GetExtensionNumber () const return EXT_NUMBER; } -uint8_t Ipv6ExtensionHopByHop::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionHopByHop::Process (Ptr& 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 malformedPacket = packet->Copy(); @@ -163,7 +163,7 @@ uint8_t Ipv6ExtensionHopByHop::Process (Ptr& packet, uint8_t offset, Ipv 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 @@ uint8_t Ipv6ExtensionHopByHop::Process (Ptr& packet, uint8_t offset, Ipv 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 @@ uint8_t Ipv6ExtensionHopByHop::Process (Ptr& packet, uint8_t offset, Ipv else { - optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, ipv6Interface, isDropped); + optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped); } processedSize += optionLength; @@ -231,9 +231,9 @@ uint8_t Ipv6ExtensionDestination::GetExtensionNumber () const return EXT_NUMBER; } -uint8_t Ipv6ExtensionDestination::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionDestination::Process (Ptr& 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 malformedPacket = packet->Copy(); @@ -285,7 +285,7 @@ uint8_t Ipv6ExtensionDestination::Process (Ptr& packet, uint8_t offset, 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 @@ uint8_t Ipv6ExtensionDestination::Process (Ptr& packet, uint8_t offset, 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 @@ uint8_t Ipv6ExtensionDestination::Process (Ptr& packet, uint8_t offset, else { - optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, ipv6Interface, isDropped); + optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped); } processedSize += optionLength; @@ -366,9 +366,9 @@ uint8_t Ipv6ExtensionFragment::GetExtensionNumber () const return EXT_NUMBER; } -uint8_t Ipv6ExtensionFragment::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionFragment::Process (Ptr& 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 p = packet->Copy (); p->RemoveAtStart (offset); @@ -709,9 +709,9 @@ uint8_t Ipv6ExtensionRouting::GetTypeRouting () const return 0; } -uint8_t Ipv6ExtensionRouting::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionRouting::Process (Ptr& 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 malformedPacket = packet->Copy(); @@ -749,7 +749,7 @@ uint8_t Ipv6ExtensionRouting::Process (Ptr& packet, uint8_t offset, Ipv6 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 @@ uint8_t Ipv6ExtensionRouting::Process (Ptr& packet, uint8_t offset, Ipv6 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 @@ uint8_t Ipv6ExtensionLooseRouting::GetTypeRouting () const return TYPE_ROUTING; } -uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& 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 malformedPacket = packet->Copy (); @@ -905,7 +905,7 @@ uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset, { 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 @@ uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset, { 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 @@ uint8_t Ipv6ExtensionLooseRouting::Process (Ptr& packet, uint8_t offset, { 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 @@ uint8_t Ipv6ExtensionESP::GetExtensionNumber () const return EXT_NUMBER; } -uint8_t Ipv6ExtensionESP::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionESP::Process (Ptr& 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 @@ uint8_t Ipv6ExtensionAH::GetExtensionNumber () const return EXT_NUMBER; } -uint8_t Ipv6ExtensionAH::Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) +uint8_t Ipv6ExtensionAH::Process (Ptr& 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 */ diff --git a/src/internet-stack/ipv6-extension.h b/src/internet-stack/ipv6-extension.h index 904d9c663..1cb3a01a5 100644 --- a/src/internet-stack/ipv6-extension.h +++ b/src/internet-stack/ipv6-extension.h @@ -83,12 +83,12 @@ class Ipv6Extension : public Object * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped) = 0; + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped) = 0; protected: TracedCallback > m_dropTrace; @@ -137,12 +137,12 @@ class Ipv6ExtensionHopByHop : public Ipv6Extension * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); }; /** @@ -182,12 +182,12 @@ class Ipv6ExtensionDestination : public Ipv6Extension * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); }; /** @@ -227,12 +227,12 @@ class Ipv6ExtensionFragment : public Ipv6Extension * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); /** * \brief Fragment a packet @@ -371,12 +371,12 @@ class Ipv6ExtensionRouting : public Ipv6Extension * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); }; /** @@ -485,12 +485,12 @@ class Ipv6ExtensionLooseRouting : public Ipv6ExtensionRouting * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); }; /** @@ -531,12 +531,12 @@ class Ipv6ExtensionESP : public Ipv6Extension * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); }; /** @@ -577,12 +577,12 @@ class Ipv6ExtensionAH : public Ipv6Extension * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, uint8_t *nextHeader, bool& isDropped); + virtual uint8_t Process (Ptr& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped); }; } /* namespace ns3 */ diff --git a/src/internet-stack/ipv6-l3-protocol.cc b/src/internet-stack/ipv6-l3-protocol.cc index 3b29ac470..a9fbe32c0 100644 --- a/src/internet-stack/ipv6-l3-protocol.cc +++ b/src/internet-stack/ipv6-l3-protocol.cc @@ -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 @@ void Ipv6L3Protocol::Receive (Ptr device, Ptr p, uint16 socket->ForwardUp (packet, hdr, device); } + Ptr ipv6ExtensionDemux = m_node->GetObject(); + Ptr 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 @@ void Ipv6L3Protocol::SendRealOut (Ptr route, Ptr packet, Ipv6 Ptr outInterface = GetInterface (interface); NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface); + // Check packet size + std::list > fragments; + + if (packet->GetSize () > (size_t)(dev->GetMtu () + 40)) /* 40 => size of IPv6 header */ + { + // Router => drop + if (m_ipForward) + { + return; + } + + Ptr ipv6ExtensionDemux = m_node->GetObject (); + + // To get specific method GetFragments from Ipv6ExtensionFragmentation + Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast(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 >::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 @@ void Ipv6L3Protocol::SendRealOut (Ptr route, Ptr packet, Ipv6 { 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 >::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 @@ void Ipv6L3Protocol::LocalDeliver (Ptr packet, Ipv6Header const& i { NS_LOG_FUNCTION (this << packet << ip << iif); Ptr p = packet->Copy (); - Ptr protocol = GetProtocol (ip.GetNextHeader ()); + Ptr protocol = 0; +/*GetProtocol (ip.GetNextHeader ());*/ + Ptr ipv6ExtensionDemux = m_node->GetObject(); + Ptr 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 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 copy = p->Copy (); @@ -879,6 +1031,7 @@ void Ipv6L3Protocol::LocalDeliver (Ptr packet, Ipv6Header const& i GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE); } } +#endif } void Ipv6L3Protocol::RouteInputError (Ptr p, const Ipv6Header& ipHeader, Socket::SocketErrno sockErrno) @@ -901,5 +1054,60 @@ Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_ return hdr; } +void Ipv6L3Protocol::RegisterExtensions () +{ + Ptr ipv6ExtensionDemux = CreateObject (); + ipv6ExtensionDemux->SetNode (m_node); + + Ptr hopbyhopExtension = CreateObject (); + hopbyhopExtension->SetNode (m_node); + Ptr destinationExtension = CreateObject (); + destinationExtension->SetNode (m_node); + Ptr fragmentExtension = CreateObject (); + fragmentExtension->SetNode (m_node); + Ptr routingExtension = CreateObject (); + routingExtension->SetNode (m_node); + // Ptr espExtension = CreateObject (); + // Ptr ahExtension = CreateObject (); + + ipv6ExtensionDemux->Insert (hopbyhopExtension); + ipv6ExtensionDemux->Insert (destinationExtension); + ipv6ExtensionDemux->Insert (fragmentExtension); + ipv6ExtensionDemux->Insert (routingExtension); + // ipv6ExtensionDemux->Insert (espExtension); + // ipv6ExtensionDemux->Insert (ahExtension); + + Ptr routingExtensionDemux = CreateObject (); + routingExtensionDemux->SetNode (m_node); + Ptr looseRoutingExtension = CreateObject (); + looseRoutingExtension->SetNode (m_node); + routingExtensionDemux->Insert (looseRoutingExtension); + + m_node->AggregateObject (routingExtensionDemux); + m_node->AggregateObject (ipv6ExtensionDemux); +} + +void Ipv6L3Protocol::RegisterOptions () +{ + Ptr ipv6OptionDemux = CreateObject (); + ipv6OptionDemux->SetNode (m_node); + + Ptr pad1Option = CreateObject (); + pad1Option->SetNode (m_node); + Ptr padnOption = CreateObject (); + padnOption->SetNode (m_node); + Ptr jumbogramOption = CreateObject (); + jumbogramOption->SetNode (m_node); + Ptr routerAlertOption = CreateObject (); + routerAlertOption->SetNode (m_node); + + ipv6OptionDemux->Insert (pad1Option); + ipv6OptionDemux->Insert (padnOption); + ipv6OptionDemux->Insert (jumbogramOption); + ipv6OptionDemux->Insert (routerAlertOption); + + m_node->AggregateObject (ipv6OptionDemux); +} + } /* namespace ns3 */ diff --git a/src/internet-stack/ipv6-l3-protocol.h b/src/internet-stack/ipv6-l3-protocol.h index a4a77dd65..6330da211 100644 --- a/src/internet-stack/ipv6-l3-protocol.h +++ b/src/internet-stack/ipv6-l3-protocol.h @@ -79,6 +79,7 @@ class Ipv6L3Protocol : public Ipv6 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 @@ class Ipv6L3Protocol : public Ipv6 */ 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. diff --git a/src/internet-stack/ipv6-option.cc b/src/internet-stack/ipv6-option.cc index a9d4f61d2..8caaabff4 100644 --- a/src/internet-stack/ipv6-option.cc +++ b/src/internet-stack/ipv6-option.cc @@ -85,9 +85,9 @@ uint8_t Ipv6OptionPad1::GetOptionNumber () const return OPT_NUMBER; } -uint8_t Ipv6OptionPad1::Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped) +uint8_t Ipv6OptionPad1::Process (Ptr 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 p = packet->Copy (); p->RemoveAtStart (offset); @@ -131,9 +131,9 @@ uint8_t Ipv6OptionPadn::GetOptionNumber () const return OPT_NUMBER; } -uint8_t Ipv6OptionPadn::Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped) +uint8_t Ipv6OptionPadn::Process (Ptr 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 p = packet->Copy (); p->RemoveAtStart (offset); @@ -177,9 +177,9 @@ uint8_t Ipv6OptionJumbogram::GetOptionNumber () const return OPT_NUMBER; } -uint8_t Ipv6OptionJumbogram::Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped) +uint8_t Ipv6OptionJumbogram::Process (Ptr 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 p = packet->Copy (); p->RemoveAtStart (offset); @@ -223,9 +223,9 @@ uint8_t Ipv6OptionRouterAlert::GetOptionNumber () const return OPT_NUMBER; } -uint8_t Ipv6OptionRouterAlert::Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped) +uint8_t Ipv6OptionRouterAlert::Process (Ptr 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 p = packet->Copy (); p->RemoveAtStart (offset); diff --git a/src/internet-stack/ipv6-option.h b/src/internet-stack/ipv6-option.h index 55aa4509d..6cc5be1e9 100644 --- a/src/internet-stack/ipv6-option.h +++ b/src/internet-stack/ipv6-option.h @@ -73,11 +73,10 @@ class Ipv6Option : public Object * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped) = 0; + virtual uint8_t Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped) = 0; private: /** @@ -123,11 +122,10 @@ class Ipv6OptionPad1 : public Ipv6Option * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped); + virtual uint8_t Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped); }; /** @@ -167,11 +165,10 @@ class Ipv6OptionPadn : public Ipv6Option * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped); + virtual uint8_t Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped); }; /** @@ -211,11 +208,10 @@ class Ipv6OptionJumbogram : public Ipv6Option * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped); + virtual uint8_t Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped); private: /** @@ -261,11 +257,10 @@ class Ipv6OptionRouterAlert : public Ipv6Option * \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, uint8_t offset, Ipv6Header const& ipv6Header, Ptr ipv6Interface, bool& isDropped); + virtual uint8_t Process (Ptr packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped); }; } /* namespace ns3 */ diff --git a/src/node/ipv6.h b/src/node/ipv6.h index f5fc6c50f..fa140e0fd 100644 --- a/src/node/ipv6.h +++ b/src/node/ipv6.h @@ -283,6 +283,16 @@ public: */ 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. */