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;
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);
iterator in a Buffer instance
automatically resized byte buffer
void AddAtStart(uint32_t start)
Buffer::Iterator Begin(void) const
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
An implementation of the ICMPv6 protocol.
Describes an IPv6 address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
IPv6 Extension AH (Authentication Header)
virtual uint8_t GetExtensionNumber() const
Get the extension number.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionAH()
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.
Ipv6ExtensionAH()
Constructor.
Demultiplexes IPv6 extensions.
IPv6 Extension Destination.
Ipv6ExtensionDestination()
Constructor.
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 const uint8_t EXT_NUMBER
Destination extension number.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
~Ipv6ExtensionDestination()
Destructor.
IPv6 Extension ESP (Encapsulating Security Payload)
Ipv6ExtensionESP()
Constructor.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
~Ipv6ExtensionESP()
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.
Ptr< Packet > GetPartialPacket() const
Get the packet parts so far received.
Ptr< Packet > GetPacket() const
Get the entire packet.
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset, bool moreFragment)
Add a fragment.
void SetTimeoutIter(FragmentsTimeoutsListI_t iter)
Set the Timeout iterator.
void SetUnfragmentablePart(Ptr< Packet > unfragmentablePart)
Set the unfragmentable part of the packet.
bool IsEntire() const
If all fragments have been added.
FragmentsTimeoutsListI_t GetTimeoutIter()
Get the Timeout iterator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Time m_fragmentExpirationTimeout
Expiration timeout.
std::list< std::tuple< Time, FragmentKey_t, Ipv6Header > >::iterator FragmentsTimeoutsListI_t
Container Iterator for fragment timeouts.
Ipv6ExtensionFragment()
Constructor.
static TypeId GetTypeId()
Get the type identificator.
void GetFragments(Ptr< Packet > packet, Ipv6Header ipv6Header, uint32_t fragmentSize, std::list< Ipv6PayloadHeaderPair > &listFragments)
Fragment a packet.
std::pair< Ipv6Address, uint32_t > FragmentKey_t
Key identifying a fragmented packet.
virtual void DoDispose()
Dispose this object.
EventId m_timeoutEvent
Event for the next scheduled timeout.
~Ipv6ExtensionFragment()
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.
MapFragments_t m_fragments
The hash of fragmented packets.
void HandleTimeout(void)
Handles a fragmented packet timeout.
FragmentsTimeoutsList_t m_timeoutEventList
Timeout "events" container.
void HandleFragmentsTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Process the timeout for packet fragments.
FragmentsTimeoutsListI_t SetTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Set a new timeout "event" for a fragmented packet.
static const uint8_t EXT_NUMBER
Fragmentation extension number.
IPv6 Extension "Hop By Hop".
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 GetExtensionNumber() const
Get the extension number.
~Ipv6ExtensionHopByHop()
Destructor.
Ipv6ExtensionHopByHop()
Constructor.
static const uint8_t EXT_NUMBER
Hop-by-hop extension number.
IPv6 Extension base If you want to implement a new IPv6 extension, all you have to do is implement a ...
Ptr< Node > GetNode() const
Get the node.
virtual uint8_t GetExtensionNumber() const =0
Get the extension number.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< Node > m_node
The node.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< UniformRandomVariable > m_uvar
Provides uniform random variables.
Ipv6Extension()
Constructor.
virtual ~Ipv6Extension()
Destructor.
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.
static TypeId GetTypeId()
Get the type identificator.
IPv6 Extension Loose Routing.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
~Ipv6ExtensionLooseRouting()
Destructor.
Ipv6ExtensionLooseRouting()
Constructor.
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.
IPv6 Extension Routing Demux.
virtual void DoDispose()
Dispose this object.
Ipv6ExtensionRoutingDemux()
Constructor.
virtual ~Ipv6ExtensionRoutingDemux()
Destructor.
void Insert(Ptr< Ipv6ExtensionRouting > extensionRouting)
Insert a new IPv6 Routing Extension.
static TypeId GetTypeId()
The interface ID.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< Ipv6ExtensionRouting > GetExtensionRouting(uint8_t typeRouting)
Get the routing extension corresponding to typeRouting.
void Remove(Ptr< Ipv6ExtensionRouting > extensionRouting)
Remove a routing extension from this demux.
Ipv6ExtensionRoutingList_t m_extensionsRouting
List of IPv6 Routing Extensions supported.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ipv6ExtensionRouting()
Constructor.
~Ipv6ExtensionRouting()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
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.
IPv6 layer implementation.
DropReason
Reason why a packet has been dropped.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_MALFORMED_HEADER
Malformed header.
A base class which provides memory management and object aggregation.
virtual void DoDispose(void)
Destructor implementation.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Container for a set of ns3::Object pointers.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
void AddHeader(const Header &header)
Add header to this packet.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
void Print(std::ostream &os) const
Print the packet contents.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now(void)
Return the current simulation virtual time.
SocketErrno
Enumeration of the possible errors returned by a socket.
Simulation virtual time values and global simulation resolution.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.