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> ())
66 m_uvar = CreateObject<UniformRandomVariable> ();
98 NS_LOG_FUNCTION (
this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
111 uint8_t processedSize = 0;
113 uint8_t *
data =
new uint8_t[size];
116 uint8_t optionType = 0;
117 uint8_t optionLength = 0;
119 while (length > processedSize && !isDropped)
121 optionType = *(data + processedSize);
122 ipv6Option = ipv6OptionDemux->GetOption (optionType);
130 optionLength = *(data + processedSize + 1) + 2;
137 stopProcessing =
true;
146 stopProcessing =
true;
159 stopProcessing =
true;
170 optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
173 processedSize += optionLength;
179 return processedSize;
194 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionHopByHop")
196 .SetGroupName (
"Internet")
224 bool& stopProcessing,
228 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
241 offset += processedSize;
244 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
246 return processedSize;
254 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionDestination")
256 .SetGroupName (
"Internet")
284 bool& stopProcessing,
288 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
301 offset += processedSize;
304 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
306 return processedSize;
314 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionFragment")
316 .SetGroupName (
"Internet")
357 bool& stopProcessing,
361 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
375 uint16_t fragmentOffset = fragmentHeader.
GetOffset ();
379 std::pair<Ipv6Address, uint32_t> fragmentsId = std::pair<Ipv6Address, uint32_t> (src, identification);
385 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
388 fragments = Create<Fragments> ();
389 m_fragments.insert (std::make_pair (fragmentsId, fragments));
392 fragmentsId, ipHeader);
393 fragments->SetTimeoutEventId (timeout);
397 fragments = it->second;
400 if (fragmentOffset == 0)
404 fragments->SetUnfragmentablePart (unfragmentablePart);
407 fragments->AddFragment (p, fragmentOffset, moreFragment);
409 if (fragments->IsEntire ())
411 packet = fragments->GetPacket ();
412 fragments->CancelTimeout ();
414 stopProcessing =
false;
418 stopProcessing =
true;
437 bool moreHeader =
true;
445 std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
446 uint32_t unfragmentablePartSize = 0;
450 uint8_t extensionHeaderLength;
460 extensionHeaderLength = hopbyhopHeader->
GetLength ();
473 unfragmentablePartSize += extensionHeaderLength;
479 uint8_t numberAddress = buf[1] / 2;
485 extensionHeaderLength = routingHeader->
GetLength ();
497 unfragmentablePartSize += extensionHeaderLength;
505 extensionHeaderLength = destinationHeader->
GetLength ();
517 unfragmentablePartSize += extensionHeaderLength;
524 uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
525 uint32_t currentFragmentablePartSize = 0;
527 bool moreFragment =
true;
528 uint32_t identification = (uint32_t)
m_uvar->
GetValue (0, (uint32_t)-1);
533 if (p->
GetSize () > offset + maxFragmentablePartSize)
536 currentFragmentablePartSize = maxFragmentablePartSize;
537 currentFragmentablePartSize -= currentFragmentablePartSize % 8;
541 moreFragment =
false;
542 currentFragmentablePartSize = p->
GetSize () - offset;
552 offset += currentFragmentablePartSize;
556 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
584 std::ostringstream oss;
585 fragment->
Print (oss);
586 listFragments.push_back (fragment);
588 while (moreFragment);
590 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
595 unfragmentablePart.clear ();
604 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
606 fragments = it->second;
608 Ptr<Packet> packet = fragments->GetPartialPacket ();
637 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
639 for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
641 if (it->second > fragmentOffset)
647 if (it == m_packetFragments.end ())
649 m_moreFragment = moreFragment;
652 m_packetFragments.insert (it, std::pair<
Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
657 m_unfragmentable = unfragmentablePart;
662 bool ret = !m_moreFragment && m_packetFragments.size () > 0;
666 uint16_t lastEndOffset = 0;
668 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
670 if (lastEndOffset != it->second)
676 lastEndOffset += it->first->GetSize ();
687 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
699 if ( m_unfragmentable )
701 p = m_unfragmentable->
Copy ();
708 uint16_t lastEndOffset = 0;
710 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
712 if (lastEndOffset != it->second)
717 lastEndOffset += it->first->GetSize ();
725 m_timeoutEventId = event;
731 m_timeoutEventId.Cancel ();
740 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRouting")
742 .SetGroupName (
"Internet")
776 bool& stopProcessing,
780 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
790 packet->
CopyData (buf,
sizeof(buf));
792 uint8_t routingNextHeader = buf[0];
793 uint8_t routingLength = buf[1];
794 uint8_t routingTypeRouting = buf[2];
795 uint8_t routingSegmentsLeft = buf[3];
799 *nextHeader = routingNextHeader;
807 if (ipv6ExtensionRouting == 0)
809 if (routingSegmentsLeft == 0)
820 stopProcessing =
true;
823 return routingLength;
826 return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, stopProcessing, isDropped, dropReason);
834 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRoutingDemux")
836 .SetGroupName (
"Internet")
837 .AddAttribute (
"Routing Extensions",
"The set of IPv6 Routing extensions registered with this demux.",
840 MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
855 for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
860 m_extensionsRouting.clear ();
872 m_extensionsRouting.push_back (extensionRouting);
877 for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
879 if ((*i)->GetTypeRouting () == typeRouting)
889 m_extensionsRouting.remove (extensionRouting);
897 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionLooseRouting")
899 .SetGroupName (
"Internet")
927 bool& stopProcessing,
931 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
951 uint8_t numberAddress = buf[1] / 2;
967 uint8_t length = (routingHeader.
GetLength () >> 3) - 1;
968 uint8_t nbAddress = length / 2;
969 uint8_t nextAddressIndex;
972 if (segmentsLeft == 0)
984 stopProcessing =
true;
988 if (segmentsLeft > nbAddress)
994 stopProcessing =
true;
999 nextAddressIndex = nbAddress - segmentsLeft;
1006 stopProcessing =
true;
1015 NS_LOG_LOGIC (
"Time Exceeded : Hop Limit <= 1. Drop!");
1019 stopProcessing =
true;
1039 Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
1044 ipv6->SendRealOut (rtentry, p, ipv6header);
1064 .SetGroupName (
"Internet")
1091 uint8_t *nextHeader,
1092 bool& stopProcessing,
1096 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1110 .SetGroupName (
"Internet")
1137 uint8_t *nextHeader,
1138 bool& stopProcessing,
1142 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.
void AddAtStart(uint32_t start)
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.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
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.
#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.
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual ~Ipv6ExtensionRoutingDemux()
Destructor.
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.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
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.
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< 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)
Set the parent TypeId.
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.