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> ())
57 .AddTraceSource (
"Drop",
"Drop IPv6 packet",
67 m_uvar = CreateObject<UniformRandomVariable> ();
91 NS_LOG_FUNCTION (
this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
104 uint8_t processedSize = 0;
106 uint8_t *
data =
new uint8_t[size];
109 uint8_t optionType = 0;
110 uint8_t optionLength = 0;
112 while (length > processedSize && !isDropped)
114 optionType = *(data + processedSize);
115 ipv6Option = ipv6OptionDemux->GetOption (optionType);
123 optionLength = *(data + processedSize + 1) + 2;
165 optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
168 processedSize += optionLength;
174 return processedSize;
189 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionHopByHop")
191 .AddConstructor<Ipv6ExtensionHopByHop> ()
215 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
228 offset += processedSize;
231 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
233 return processedSize;
241 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionDestination")
243 .AddConstructor<Ipv6ExtensionDestination> ()
267 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
280 offset += processedSize;
283 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
285 return processedSize;
293 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionFragment")
295 .AddConstructor<Ipv6ExtensionFragment> ()
332 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
346 uint16_t fragmentOffset = fragmentHeader.
GetOffset ();
350 std::pair<Ipv6Address, uint32_t> fragmentsId = std::pair<Ipv6Address, uint32_t> (src, identification);
356 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
359 fragments = Create<Fragments> ();
360 m_fragments.insert (std::make_pair (fragmentsId, fragments));
363 fragmentsId, ipHeader);
364 fragments->SetTimeoutEventId (timeout);
368 fragments = it->second;
371 if (fragmentOffset == 0)
375 fragments->SetUnfragmentablePart (unfragmentablePart);
378 fragments->AddFragment (p, fragmentOffset, moreFragment);
380 if (fragments->IsEntire ())
382 packet = fragments->GetPacket ();
383 fragments->CancelTimeout ();
409 bool moreHeader =
true;
417 std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
418 uint32_t unfragmentablePartSize = 0;
422 uint8_t extensionHeaderLength;
432 extensionHeaderLength = hopbyhopHeader->
GetLength ();
445 unfragmentablePartSize += extensionHeaderLength;
451 uint8_t numberAddress = buf[1] / 2;
457 extensionHeaderLength = routingHeader->
GetLength ();
469 unfragmentablePartSize += extensionHeaderLength;
477 extensionHeaderLength = destinationHeader->
GetLength ();
489 unfragmentablePartSize += extensionHeaderLength;
496 uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
497 uint32_t currentFragmentablePartSize = 0;
499 bool moreFragment =
true;
500 uint32_t identification = (uint32_t)
m_uvar->
GetValue (0, (uint32_t)-1);
505 if (p->
GetSize () > offset + maxFragmentablePartSize)
508 currentFragmentablePartSize = maxFragmentablePartSize;
512 moreFragment =
false;
513 currentFragmentablePartSize = p->
GetSize () - offset;
516 currentFragmentablePartSize -= currentFragmentablePartSize % 8;
519 fragmentHeader.
SetLength (currentFragmentablePartSize);
525 offset += currentFragmentablePartSize;
529 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
557 std::ostringstream oss;
558 fragment->
Print (oss);
559 listFragments.push_back (fragment);
561 while (moreFragment);
563 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
568 unfragmentablePart.clear ();
577 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
579 fragments = it->second;
581 Ptr<Packet> packet = fragments->GetPartialPacket ();
608 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
610 for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
612 if (it->second > fragmentOffset)
618 if (it == m_packetFragments.end ())
620 m_moreFragment = moreFragment;
623 m_packetFragments.insert (it, std::pair<
Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
628 m_unfragmentable = unfragmentablePart;
633 bool ret = !m_moreFragment && m_packetFragments.size () > 0;
637 uint16_t lastEndOffset = 0;
639 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
641 if (lastEndOffset != it->second)
647 lastEndOffset += it->first->GetSize ();
658 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
670 if ( m_unfragmentable )
672 p = m_unfragmentable->
Copy ();
679 uint16_t lastEndOffset = 0;
681 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
683 if (lastEndOffset != it->second)
688 lastEndOffset += it->first->GetSize ();
696 m_timeoutEventId = event;
702 m_timeoutEventId.Cancel ();
711 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRouting")
713 .AddConstructor<Ipv6ExtensionRouting> ()
743 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
753 packet->
CopyData (buf,
sizeof(buf));
755 uint8_t routingNextHeader = buf[0];
756 uint8_t routingLength = buf[1];
757 uint8_t routingTypeRouting = buf[2];
758 uint8_t routingSegmentsLeft = buf[3];
762 *nextHeader = routingNextHeader;
770 if (ipv6ExtensionRouting == 0)
772 if (routingSegmentsLeft == 0)
785 return routingLength;
788 return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, isDropped);
796 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRoutingDemux")
798 .AddAttribute (
"Routing Extensions",
"The set of IPv6 Routing extensions registered with this demux.",
801 MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
816 for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
821 m_extensionsRouting.clear ();
833 m_extensionsRouting.push_back (extensionRouting);
838 for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
840 if ((*i)->GetTypeRouting () == typeRouting)
850 m_extensionsRouting.remove (extensionRouting);
858 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionLooseRouting")
860 .AddConstructor<Ipv6ExtensionLooseRouting> ()
884 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
904 uint8_t numberAddress = buf[1] / 2;
920 uint8_t length = (routingHeader.
GetLength () >> 3) - 1;
921 uint8_t nbAddress = length / 2;
922 uint8_t nextAddressIndex;
925 if (segmentsLeft == 0)
940 if (segmentsLeft > nbAddress)
950 nextAddressIndex = nbAddress - segmentsLeft;
988 Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
993 ipv6->SendRealOut (rtentry, p, ipv6header);
1013 .AddConstructor<Ipv6ExtensionESP> ()
1037 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1051 .AddConstructor<Ipv6ExtensionAH> ()
1075 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)
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method Called from Ipv6L3Protocol::Receive.
Ptr< UniformRandomVariable > m_uvar
Provides uniform random variables.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberContainer)
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)
Ipv6ExtensionLooseRouting()
Constructor.
virtual void DoDispose()
Dispose this object.
#define NS_LOG_FUNCTION(parameters)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
TracedCallback< Ptr< const Packet > > m_dropTrace
Drop trace callback.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method Called from Ipv6L3Protocol::Receive.
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.
Demultiplexes IPv6 extensions.
automatically resized byte buffer
void SetNode(Ptr< Node > node)
Set the node.
#define NS_ASSERT(condition)
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method Called from Ipv6L3Protocol::Receive.
virtual void DoDispose()
Dispose this object.
#define NS_LOG_COMPONENT_DEFINE(name)
virtual uint8_t GetExtensionNumber() const
Get the extension number.
uint32_t GetSize(void) const
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
virtual void DoDispose(void)
static TypeId GetTypeId()
Get the type identificator.
#define NS_LOG_FUNCTION_NOARGS()
virtual ~Ipv6ExtensionRoutingDemux()
Destructor.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Ipv6ExtensionRoutingDemux()
Constructor.
void Print(std::ostream &os) const
IPv6 Extension Destination.
Ipv6ExtensionFragment()
Constructor.
~Ipv6ExtensionDestination()
Destructor.
iterator in a Buffer instance
virtual uint8_t GetExtensionNumber() const
Get the extension number.
IPv6 Extension Routing If you want to implement a new IPv6 routing extension, all you have to do is i...
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionHopByHop()
Destructor.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
void AddAtEnd(Ptr< const Packet > packet)
~Ipv6ExtensionLooseRouting()
Destructor.
void RemoveAtStart(uint32_t size)
void SetTimeoutEventId(EventId event)
Set the Timeout EventId.
Ipv6ExtensionHopByHop()
Constructor.
void HandleFragmentsTimeout(std::pair< Ipv6Address, uint32_t > key, Ipv6Header &ipHeader)
Process the timeout for packet fragments.
Hold an unsigned integer type.
Ptr< Packet > GetPacket() const
Get the entire packet.
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
IPv6 Extension ESP (Encapsulating Security Payload)
~Ipv6ExtensionFragment()
Destructor.
void CancelTimeout()
Cancel the timeout event.
An implementation of the ICMPv6 protocol.
~Ipv6ExtensionRouting()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
#define NS_LOG_LOGIC(msg)
Buffer::Iterator Begin(void) const
Ipv6ExtensionDestination()
Constructor.
IPv6 Extension Routing Demux.
void SetUnfragmentablePart(Ptr< Packet > unfragmentablePart)
Set the unfragmentable part of the packet.
bool IsEntire() const
If all fragments have been added.
IPv6 Extension "Hop By Hop".
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
void SetNode(Ptr< Node > node)
Set the node.
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 &isDropped)
Process options Called by implementing classes to process the options.
static TypeId GetTypeId()
Get the type identificator.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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)
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.
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)
Ipv6Extension()
Constructor.
Describes an IPv6 address.
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 &isDropped)
Process method.
an identifier for simulation events.
Ipv6ExtensionRouting()
Constructor.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Ipv6ExtensionRoutingList_t m_extensionsRouting
List of IPv6 Routing Extensions supported.
Ipv6ExtensionESP()
Constructor.
bool AddAtStart(uint32_t start)
a base class which provides memory management and object aggregation
static const uint8_t EXT_NUMBER
Destination extension number.
contain a set of ns3::Object pointers.
Ptr< Node > m_node
The node.
Ptr< T > GetObject(void) const
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method Called from Ipv6L3Protocol::Receive.
static TypeId GetTypeId()
Get the type identificator.
void AddHeader(const Header &header)
~Ipv6ExtensionAH()
Destructor.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method Called from Ipv6L3Protocol::Receive.
virtual ~Ipv6Extension()
Destructor.
IPv6 Extension AH (Authentication Header)
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method.