25 #include "ns3/assert.h" 26 #include "ns3/uinteger.h" 27 #include "ns3/object-vector.h" 28 #include "ns3/ipv6-address.h" 29 #include "ns3/ipv6-header.h" 30 #include "ns3/ipv6-l3-protocol.h" 31 #include "ns3/ipv6-static-routing.h" 32 #include "ns3/ipv6-list-routing.h" 33 #include "ns3/ipv6-route.h" 34 #include "ns3/trace-source-accessor.h" 53 .SetGroupName (
"Internet")
54 .AddAttribute (
"ExtensionNumber",
"The IPv6 extension number.",
57 MakeUintegerChecker<uint8_t> ())
64 m_uvar = CreateObject<UniformRandomVariable> ();
93 NS_LOG_FUNCTION (
this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
106 uint8_t processedSize = 0;
108 uint8_t *
data =
new uint8_t[size];
111 uint8_t optionType = 0;
112 uint8_t optionLength = 0;
114 while (length > processedSize && !isDropped)
116 optionType = *(
data + processedSize);
117 ipv6Option = ipv6OptionDemux->GetOption (optionType);
125 optionLength = *(
data + processedSize + 1) + 2;
132 stopProcessing =
true;
141 stopProcessing =
true;
154 stopProcessing =
true;
165 optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
168 processedSize += optionLength;
174 return processedSize;
189 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionHopByHop")
191 .SetGroupName (
"Internet")
215 bool& stopProcessing,
219 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
232 offset += processedSize;
235 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
237 return processedSize;
245 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionDestination")
247 .SetGroupName (
"Internet")
271 bool& stopProcessing,
275 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
288 offset += processedSize;
291 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
293 return processedSize;
301 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionFragment")
303 .SetGroupName (
"Internet")
305 .AddAttribute (
"FragmentExpirationTimeout",
306 "When this timeout expires, the fragments " 307 "will be cleared from the buffer.",
351 bool& stopProcessing,
355 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
369 uint16_t fragmentOffset = fragmentHeader.
GetOffset ();
379 MapFragments_t::iterator it =
m_fragments.find (fragmentKey);
382 fragments = Create<Fragments> ();
383 m_fragments.insert (std::make_pair (fragmentKey, fragments));
384 NS_LOG_DEBUG (
"Insert new fragment key: src: " << src <<
" IP hdr id " << identification <<
" m_fragments.size() " <<
m_fragments.size () <<
" offset " << fragmentOffset);
390 fragments = it->second;
393 if (fragmentOffset == 0)
400 NS_LOG_DEBUG (
"Add fragment with IP hdr id " << identification <<
" offset " << fragmentOffset);
401 fragments->
AddFragment (p, fragmentOffset, moreFragment);
408 NS_LOG_DEBUG (
"Finished fragment with IP hdr id " << fragmentKey.second <<
" erase timeout, m_fragments.size(): " <<
m_fragments.size ());
409 stopProcessing =
false;
413 stopProcessing =
true;
430 bool moreHeader =
true;
438 std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
439 uint32_t unfragmentablePartSize = 0;
443 uint8_t extensionHeaderLength;
453 extensionHeaderLength = hopbyhopHeader->
GetLength ();
466 unfragmentablePartSize += extensionHeaderLength;
472 uint8_t numberAddress = buf[1] / 2;
478 extensionHeaderLength = routingHeader->
GetLength ();
490 unfragmentablePartSize += extensionHeaderLength;
498 extensionHeaderLength = destinationHeader->
GetLength ();
510 unfragmentablePartSize += extensionHeaderLength;
517 uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
518 uint32_t currentFragmentablePartSize = 0;
520 bool moreFragment =
true;
521 uint32_t identification = (uint32_t)
m_uvar->
GetValue (0, (uint32_t)-1);
526 if (p->
GetSize () > offset + maxFragmentablePartSize)
529 currentFragmentablePartSize = maxFragmentablePartSize;
530 currentFragmentablePartSize -= currentFragmentablePartSize % 8;
534 moreFragment =
false;
535 currentFragmentablePartSize = p->
GetSize () - offset;
545 offset += currentFragmentablePartSize;
549 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
576 std::ostringstream oss;
578 fragment->
Print (oss);
580 listFragments.emplace_back (fragment, ipv6Header);
582 while (moreFragment);
584 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
589 unfragmentablePart.clear ();
596 NS_LOG_FUNCTION (
this << fragmentKey.first << fragmentKey.second << ipHeader);
599 MapFragments_t::iterator it =
m_fragments.find (fragmentKey);
601 fragments = it->second;
603 Ptr<Packet> packet = fragments->GetPartialPacket ();
606 if (packet && packet->
GetSize () > 8)
647 NS_LOG_DEBUG (
"Handle time " << std::get<0> (element).GetSeconds () <<
" IP hdr id " << std::get<1> (element).
second);
662 NS_LOG_DEBUG (
"Scheduling later HandleTimeout at " << (now + difference).GetSeconds ());
682 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
684 for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
686 if (it->second > fragmentOffset)
692 if (it == m_packetFragments.end ())
694 m_moreFragment = moreFragment;
697 m_packetFragments.insert (it, std::pair<
Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
703 m_unfragmentable = unfragmentablePart;
708 bool ret = !m_moreFragment && m_packetFragments.size () > 0;
712 uint16_t lastEndOffset = 0;
714 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
716 if (lastEndOffset != it->second)
722 lastEndOffset += it->first->GetSize ();
733 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
745 if ( m_unfragmentable )
747 p = m_unfragmentable->
Copy ();
754 uint16_t lastEndOffset = 0;
756 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
758 if (lastEndOffset != it->second)
763 lastEndOffset += it->first->GetSize ();
772 m_timeoutIter = iter;
778 return m_timeoutIter;
786 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRouting")
788 .SetGroupName (
"Internet")
817 bool& stopProcessing,
821 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
831 packet->
CopyData (buf,
sizeof(buf));
833 uint8_t routingNextHeader = buf[0];
834 uint8_t routingLength = buf[1];
835 uint8_t routingTypeRouting = buf[2];
836 uint8_t routingSegmentsLeft = buf[3];
840 *nextHeader = routingNextHeader;
848 if (ipv6ExtensionRouting == 0)
850 if (routingSegmentsLeft == 0)
861 stopProcessing =
true;
864 return routingLength;
867 return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, stopProcessing, isDropped, dropReason);
875 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRoutingDemux")
877 .SetGroupName (
"Internet")
878 .AddAttribute (
"RoutingExtensions",
"The set of IPv6 Routing extensions registered with this demux.",
881 MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
897 for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
902 m_extensionsRouting.clear ();
916 m_extensionsRouting.push_back (extensionRouting);
921 for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
923 if ((*i)->GetTypeRouting () == typeRouting)
934 m_extensionsRouting.remove (extensionRouting);
942 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionLooseRouting")
944 .SetGroupName (
"Internet")
968 bool& stopProcessing,
972 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
992 uint8_t numberAddress = buf[1] / 2;
1008 uint8_t length = (routingHeader.
GetLength () >> 3) - 1;
1009 uint8_t nbAddress = length / 2;
1010 uint8_t nextAddressIndex;
1013 if (segmentsLeft == 0)
1019 if (length % 2 != 0)
1025 stopProcessing =
true;
1029 if (segmentsLeft > nbAddress)
1035 stopProcessing =
true;
1040 nextAddressIndex = nbAddress - segmentsLeft;
1047 stopProcessing =
true;
1056 NS_LOG_LOGIC (
"Time Exceeded : Hop Limit <= 1. Drop!");
1060 stopProcessing =
true;
1079 Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
1084 ipv6->SendRealOut (rtentry, p, ipv6header);
1104 .SetGroupName (
"Internet")
1127 uint8_t *nextHeader,
1128 bool& stopProcessing,
1132 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1146 .SetGroupName (
"Internet")
1169 uint8_t *nextHeader,
1170 bool& stopProcessing,
1174 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Ptr< UniformRandomVariable > m_uvar
Provides uniform random variables.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
IPv6 Extension base If you want to implement a new IPv6 extension, all you have to do is implement a ...
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
void HandleTimeout(void)
Handles a fragmented packet timeout.
void AddAtStart(uint32_t start)
Simulation virtual time values and global simulation resolution.
Ipv6ExtensionLooseRouting()
Constructor.
virtual void DoDispose()
Dispose this object.
void Print(std::ostream &os) const
Print the packet contents.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
FragmentsTimeoutsListI_t GetTimeoutIter()
Get the Timeout iterator.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
void Insert(Ptr< Ipv6ExtensionRouting > extensionRouting)
Insert a new IPv6 Routing Extension.
Ptr< Packet > GetPartialPacket() const
Get the packet parts so far received.
static const uint8_t EXT_NUMBER
Fragmentation extension number.
IPv6 layer implementation.
Demultiplexes IPv6 extensions.
automatically resized byte buffer
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
void HandleFragmentsTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Process the timeout for packet fragments.
virtual void DoDispose()
Dispose this object.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
static TypeId GetTypeId()
Get the type identificator.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
static TypeId GetTypeId()
Get the type identificator.
void GetFragments(Ptr< Packet > packet, Ipv6Header ipv6Header, uint32_t fragmentSize, std::list< Ipv6PayloadHeaderPair > &listFragments)
Fragment a packet.
virtual void DoDispose(void)
Destructor implementation.
virtual ~Ipv6ExtensionRoutingDemux()
Destructor.
Ipv6ExtensionRoutingDemux()
Constructor.
FragmentsTimeoutsList_t m_timeoutEventList
Timeout "events" container.
SocketErrno
Enumeration of the possible errors returned by a socket.
Time m_fragmentExpirationTimeout
Expiration timeout.
IPv6 Extension Destination.
Ipv6ExtensionFragment()
Constructor.
~Ipv6ExtensionDestination()
Destructor.
iterator in a Buffer instance
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionHopByHop()
Destructor.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
~Ipv6ExtensionLooseRouting()
Destructor.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Ipv6ExtensionHopByHop()
Constructor.
AttributeValue implementation for Time.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Hold an unsigned integer type.
std::list< std::tuple< Time, FragmentKey_t, Ipv6Header > >::iterator FragmentsTimeoutsListI_t
Container Iterator for fragment timeouts.
IPv6 Extension ESP (Encapsulating Security Payload)
~Ipv6ExtensionFragment()
Destructor.
An implementation of the ICMPv6 protocol.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
~Ipv6ExtensionRouting()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Ipv6ExtensionDestination()
Constructor.
IPv6 Extension Routing Demux.
void SetUnfragmentablePart(Ptr< Packet > unfragmentablePart)
Set the unfragmentable part of the packet.
IPv6 Extension "Hop By Hop".
void Remove(Ptr< Ipv6ExtensionRouting > extensionRouting)
Remove a routing extension from this demux.
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset, bool moreFragment)
Add a fragment.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
void SetNode(Ptr< Node > node)
Set the node.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
MapFragments_t m_fragments
The hash of fragmented packets.
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
static TypeId GetTypeId()
The interface ID.
static TypeId GetTypeId()
Get the type identificator.
Ptr< Ipv6ExtensionRouting > GetExtensionRouting(uint8_t typeRouting)
Get the routing extension corresponding to typeRouting.
~Ipv6ExtensionESP()
Destructor.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Ipv6ExtensionAH()
Constructor.
static Time Now(void)
Return the current simulation virtual time.
static TypeId GetTypeId()
Get the type identificator.
IPv6 Extension Loose Routing.
virtual uint8_t GetExtensionNumber() const =0
Get the extension number.
static const uint8_t EXT_NUMBER
Hop-by-hop extension number.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ipv6Extension()
Constructor.
Describes an IPv6 address.
void SetTimeoutIter(FragmentsTimeoutsListI_t iter)
Set the Timeout iterator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Ipv6ExtensionRouting()
Constructor.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Time Seconds(double value)
Construct a Time in the indicated unit.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
FragmentsTimeoutsListI_t SetTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Set a new timeout "event" for a fragmented packet.
virtual uint8_t ProcessOptions(Ptr< Packet > &packet, uint8_t offset, uint8_t length, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process options Called by implementing classes to process the options.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
EventId m_timeoutEvent
Event for the next scheduled timeout.
bool IsEntire() const
If all fragments have been added.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
Ptr< Node > GetNode() const
Get the node.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Ipv6ExtensionRoutingList_t m_extensionsRouting
List of IPv6 Routing Extensions supported.
std::pair< Ipv6Address, uint32_t > FragmentKey_t
Key identifying a fragmented packet.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ipv6ExtensionESP()
Constructor.
A base class which provides memory management and object aggregation.
static const uint8_t EXT_NUMBER
Destination extension number.
Container for a set of ns3::Object pointers.
Ptr< Node > m_node
The node.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
a unique identifier for an interface.
Ptr< Packet > GetPacket() const
Get the entire packet.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Buffer::Iterator Begin(void) const
static TypeId GetTypeId()
Get the type identificator.
void AddHeader(const Header &header)
Add header to this packet.
~Ipv6ExtensionAH()
Destructor.
DropReason
Reason why a packet has been dropped.
virtual ~Ipv6Extension()
Destructor.
IPv6 Extension AH (Authentication Header)