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 .AddAttribute (
"ExtensionNumber",
"The IPv6 extension number.",
56 MakeUintegerChecker<uint8_t> ())
65 m_uvar = CreateObject<UniformRandomVariable> ();
97 NS_LOG_FUNCTION (
this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
110 uint8_t processedSize = 0;
112 uint8_t *
data =
new uint8_t[size];
115 uint8_t optionType = 0;
116 uint8_t optionLength = 0;
118 while (length > processedSize && !isDropped)
120 optionType = *(data + processedSize);
121 ipv6Option = ipv6OptionDemux->GetOption (optionType);
129 optionLength = *(data + processedSize + 1) + 2;
136 stopProcessing =
true;
145 stopProcessing =
true;
158 stopProcessing =
true;
169 optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
172 processedSize += optionLength;
178 return processedSize;
193 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionHopByHop")
195 .AddConstructor<Ipv6ExtensionHopByHop> ()
222 bool& stopProcessing,
226 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
239 offset += processedSize;
242 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
244 return processedSize;
252 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionDestination")
254 .AddConstructor<Ipv6ExtensionDestination> ()
281 bool& stopProcessing,
285 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
298 offset += processedSize;
301 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
303 return processedSize;
311 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionFragment")
313 .AddConstructor<Ipv6ExtensionFragment> ()
353 bool& stopProcessing,
357 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
371 uint16_t fragmentOffset = fragmentHeader.
GetOffset ();
375 std::pair<Ipv6Address, uint32_t> fragmentsId = std::pair<Ipv6Address, uint32_t> (src, identification);
381 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
384 fragments = Create<Fragments> ();
385 m_fragments.insert (std::make_pair (fragmentsId, fragments));
388 fragmentsId, ipHeader);
389 fragments->SetTimeoutEventId (timeout);
393 fragments = it->second;
396 if (fragmentOffset == 0)
400 fragments->SetUnfragmentablePart (unfragmentablePart);
403 fragments->AddFragment (p, fragmentOffset, moreFragment);
405 if (fragments->IsEntire ())
407 packet = fragments->GetPacket ();
408 fragments->CancelTimeout ();
410 stopProcessing =
false;
414 stopProcessing =
true;
433 bool moreHeader =
true;
441 std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
442 uint32_t unfragmentablePartSize = 0;
446 uint8_t extensionHeaderLength;
456 extensionHeaderLength = hopbyhopHeader->
GetLength ();
469 unfragmentablePartSize += extensionHeaderLength;
475 uint8_t numberAddress = buf[1] / 2;
481 extensionHeaderLength = routingHeader->
GetLength ();
493 unfragmentablePartSize += extensionHeaderLength;
501 extensionHeaderLength = destinationHeader->
GetLength ();
513 unfragmentablePartSize += extensionHeaderLength;
520 uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
521 uint32_t currentFragmentablePartSize = 0;
523 bool moreFragment =
true;
524 uint32_t identification = (uint32_t)
m_uvar->
GetValue (0, (uint32_t)-1);
529 if (p->
GetSize () > offset + maxFragmentablePartSize)
532 currentFragmentablePartSize = maxFragmentablePartSize;
533 currentFragmentablePartSize -= currentFragmentablePartSize % 8;
537 moreFragment =
false;
538 currentFragmentablePartSize = p->
GetSize () - offset;
548 offset += currentFragmentablePartSize;
552 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
580 std::ostringstream oss;
581 fragment->
Print (oss);
582 listFragments.push_back (fragment);
584 while (moreFragment);
586 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
591 unfragmentablePart.clear ();
600 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
602 fragments = it->second;
604 Ptr<Packet> packet = fragments->GetPartialPacket ();
633 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
635 for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
637 if (it->second > fragmentOffset)
643 if (it == m_packetFragments.end ())
645 m_moreFragment = moreFragment;
648 m_packetFragments.insert (it, std::pair<
Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
653 m_unfragmentable = unfragmentablePart;
658 bool ret = !m_moreFragment && m_packetFragments.size () > 0;
662 uint16_t lastEndOffset = 0;
664 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
666 if (lastEndOffset != it->second)
672 lastEndOffset += it->first->GetSize ();
683 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
695 if ( m_unfragmentable )
697 p = m_unfragmentable->
Copy ();
704 uint16_t lastEndOffset = 0;
706 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
708 if (lastEndOffset != it->second)
713 lastEndOffset += it->first->GetSize ();
721 m_timeoutEventId = event;
727 m_timeoutEventId.Cancel ();
736 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRouting")
738 .AddConstructor<Ipv6ExtensionRouting> ()
771 bool& stopProcessing,
775 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
785 packet->
CopyData (buf,
sizeof(buf));
787 uint8_t routingNextHeader = buf[0];
788 uint8_t routingLength = buf[1];
789 uint8_t routingTypeRouting = buf[2];
790 uint8_t routingSegmentsLeft = buf[3];
794 *nextHeader = routingNextHeader;
802 if (ipv6ExtensionRouting == 0)
804 if (routingSegmentsLeft == 0)
815 stopProcessing =
true;
818 return routingLength;
821 return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, stopProcessing, isDropped, dropReason);
829 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRoutingDemux")
831 .AddAttribute (
"Routing Extensions",
"The set of IPv6 Routing extensions registered with this demux.",
834 MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
849 for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
854 m_extensionsRouting.clear ();
866 m_extensionsRouting.push_back (extensionRouting);
871 for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
873 if ((*i)->GetTypeRouting () == typeRouting)
883 m_extensionsRouting.remove (extensionRouting);
891 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionLooseRouting")
893 .AddConstructor<Ipv6ExtensionLooseRouting> ()
920 bool& stopProcessing,
924 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
944 uint8_t numberAddress = buf[1] / 2;
960 uint8_t length = (routingHeader.
GetLength () >> 3) - 1;
961 uint8_t nbAddress = length / 2;
962 uint8_t nextAddressIndex;
965 if (segmentsLeft == 0)
977 stopProcessing =
true;
981 if (segmentsLeft > nbAddress)
987 stopProcessing =
true;
992 nextAddressIndex = nbAddress - segmentsLeft;
999 stopProcessing =
true;
1008 NS_LOG_LOGIC (
"Time Exceeded : Hop Limit <= 1. Drop!");
1012 stopProcessing =
true;
1032 Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
1037 ipv6->SendRealOut (rtentry, p, ipv6header);
1057 .AddConstructor<Ipv6ExtensionESP> ()
1083 uint8_t *nextHeader,
1084 bool& stopProcessing,
1088 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1102 .AddConstructor<Ipv6ExtensionAH> ()
1128 uint8_t *nextHeader,
1129 bool& stopProcessing,
1133 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
void GetFragments(Ptr< Packet > packet, uint32_t fragmentSize, std::list< Ptr< Packet > > &listFragments)
Fragment a packet.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Ptr< UniformRandomVariable > m_uvar
Provides uniform random variables.
Introspection did not find any typical Config paths.
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.
Ipv6ExtensionLooseRouting()
Constructor.
virtual void DoDispose()
Dispose this object.
#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 this RNG stream.
SocketErrno
Enumeration of the possible errors returned by a socket.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< Packet > GetPartialPacket() const
Get the packet parts so far received.
void Insert(Ptr< Ipv6ExtensionRouting > extensionRouting)
Insert a new IPv6 Routing Extension.
static const uint8_t EXT_NUMBER
Fragmentation extension number.
IPv6 layer implementation.
Introspection did not find any typical Config paths.
automatically resized byte buffer
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
void SetNode(Ptr< Node > node)
Set the node.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
virtual void DoDispose()
Dispose this object.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
virtual void DoDispose(void)
Destructor implementation.
#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.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual ~Ipv6ExtensionRoutingDemux()
Destructor.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Ipv6ExtensionRoutingDemux()
Constructor.
void Print(std::ostream &os) const
Print the packet contents.
Introspection did not find any typical Config paths.
Ipv6ExtensionFragment()
Constructor.
~Ipv6ExtensionDestination()
Destructor.
iterator in a Buffer instance
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Introspection did not find any typical Config paths.
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.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
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.
void SetTimeoutEventId(EventId event)
Set the Timeout EventId.
Ipv6ExtensionHopByHop()
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.
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.
Hold an unsigned integer type.
Ptr< Packet > GetPacket() const
Get the entire packet.
Introspection did not find any typical Config paths.
~Ipv6ExtensionFragment()
Destructor.
void CancelTimeout()
Cancel the timeout event.
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.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Buffer::Iterator Begin(void) const
Ipv6ExtensionDestination()
Constructor.
Introspection did not find any typical Config paths.
void SetUnfragmentablePart(Ptr< Packet > unfragmentablePart)
Set the unfragmentable part of the packet.
bool IsEntire() const
If all fragments have been added.
Introspection did not find any typical Config paths.
Ptr< Node > GetNode() const
Get the node.
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.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
void SetNode(Ptr< Node > node)
Set the node.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TypeId GetTypeId()
Get the type identificator.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
MapFragments_t m_fragments
The hash of fragmented packets.
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
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.
Ipv6ExtensionAH()
Constructor.
static TypeId GetTypeId()
Get the type identificator.
Introspection did not find any typical Config paths.
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.
Introspection did not find any typical Config paths.
Describes an IPv6 address.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
An identifier for simulation events.
Ipv6ExtensionRouting()
Constructor.
Time Seconds(double value)
Construct a Time in the indicated unit.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
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.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Ipv6ExtensionRoutingList_t m_extensionsRouting
List of IPv6 Routing Extensions supported.
Ipv6ExtensionESP()
Constructor.
void HandleFragmentsTimeout(std::pair< Ipv6Address, uint32_t > key, Ipv6Header ipHeader)
Process the timeout for packet fragments.
bool AddAtStart(uint32_t start)
A base class which provides memory management and object aggregation.
Introspection did not find any typical Config paths.
static const uint8_t EXT_NUMBER
Destination extension number.
Container for a set of ns3::Object pointers.
Ptr< Node > m_node
The node.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
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.
TypeId SetParent(TypeId tid)
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.
Introspection did not find any typical Config paths.