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"
54 .AddAttribute (
"ExtensionNumber",
"The IPv6 extension number.",
57 MakeUintegerChecker<uint8_t> ())
58 .AddTraceSource (
"Drop",
"Drop IPv6 packet",
68 m_uvar = CreateObject<UniformRandomVariable> ();
92 NS_LOG_FUNCTION (
this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
105 uint8_t processedSize = 0;
107 uint8_t *
data =
new uint8_t[size];
110 uint8_t optionType = 0;
111 uint8_t optionLength = 0;
113 while (length > processedSize && !isDropped)
115 optionType = *(data + processedSize);
116 ipv6Option = ipv6OptionDemux->GetOption (optionType);
124 optionLength = *(data + processedSize + 1) + 2;
166 optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
169 processedSize += optionLength;
175 return processedSize;
191 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionHopByHop")
193 .AddConstructor<Ipv6ExtensionHopByHop> ()
217 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
230 offset += processedSize;
233 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
235 return processedSize;
244 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionDestination")
246 .AddConstructor<Ipv6ExtensionDestination> ()
270 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
283 offset += processedSize;
286 processedSize +=
ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
288 return processedSize;
297 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionFragment")
299 .AddConstructor<Ipv6ExtensionFragment> ()
336 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
350 uint16_t fragmentOffset = fragmentHeader.
GetOffset ();
354 std::pair<Ipv6Address, uint32_t> fragmentsId = std::pair<Ipv6Address, uint32_t> (src, identification);
360 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
363 fragments = Create<Fragments> ();
364 m_fragments.insert (std::make_pair (fragmentsId, fragments));
367 fragmentsId, ipHeader);
368 fragments->SetTimeoutEventId (timeout);
372 fragments = it->second;
375 if (fragmentOffset == 0)
379 fragments->SetUnfragmentablePart (unfragmentablePart);
382 fragments->AddFragment (p, fragmentOffset, moreFragment);
384 if (fragments->IsEntire ())
386 packet = fragments->GetPacket ();
387 fragments->CancelTimeout ();
413 bool moreHeader =
true;
421 std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
422 uint32_t unfragmentablePartSize = 0;
426 uint8_t extensionHeaderLength;
436 extensionHeaderLength = hopbyhopHeader->
GetLength ();
449 unfragmentablePartSize += extensionHeaderLength;
455 uint8_t numberAddress = buf[1] / 2;
461 extensionHeaderLength = routingHeader->
GetLength ();
473 unfragmentablePartSize += extensionHeaderLength;
481 extensionHeaderLength = destinationHeader->
GetLength ();
493 unfragmentablePartSize += extensionHeaderLength;
500 uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
501 uint32_t currentFragmentablePartSize = 0;
503 bool moreFragment =
true;
504 uint32_t identification = (uint32_t)
m_uvar->
GetValue (0, (uint32_t)-1);
509 if (p->
GetSize () > offset + maxFragmentablePartSize)
512 currentFragmentablePartSize = maxFragmentablePartSize;
513 currentFragmentablePartSize -= currentFragmentablePartSize % 8;
517 moreFragment =
false;
518 currentFragmentablePartSize = p->
GetSize () - offset;
528 offset += currentFragmentablePartSize;
532 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
560 std::ostringstream oss;
561 fragment->
Print (oss);
562 listFragments.push_back (fragment);
564 while (moreFragment);
566 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
571 unfragmentablePart.clear ();
580 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
582 fragments = it->second;
584 Ptr<Packet> packet = fragments->GetPartialPacket ();
611 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
613 for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
615 if (it->second > fragmentOffset)
621 if (it == m_packetFragments.end ())
623 m_moreFragment = moreFragment;
626 m_packetFragments.insert (it, std::pair<
Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
631 m_unfragmentable = unfragmentablePart;
636 bool ret = !m_moreFragment && m_packetFragments.size () > 0;
640 uint16_t lastEndOffset = 0;
642 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
644 if (lastEndOffset != it->second)
650 lastEndOffset += it->first->GetSize ();
661 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
673 if ( m_unfragmentable )
675 p = m_unfragmentable->
Copy ();
682 uint16_t lastEndOffset = 0;
684 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
686 if (lastEndOffset != it->second)
691 lastEndOffset += it->first->GetSize ();
699 m_timeoutEventId = event;
705 m_timeoutEventId.Cancel ();
715 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRouting")
717 .AddConstructor<Ipv6ExtensionRouting> ()
747 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
757 packet->
CopyData (buf,
sizeof(buf));
759 uint8_t routingNextHeader = buf[0];
760 uint8_t routingLength = buf[1];
761 uint8_t routingTypeRouting = buf[2];
762 uint8_t routingSegmentsLeft = buf[3];
766 *nextHeader = routingNextHeader;
774 if (ipv6ExtensionRouting == 0)
776 if (routingSegmentsLeft == 0)
789 return routingLength;
792 return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, isDropped);
801 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRoutingDemux")
803 .AddAttribute (
"Routing Extensions",
"The set of IPv6 Routing extensions registered with this demux.",
806 MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
821 for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
826 m_extensionsRouting.clear ();
838 m_extensionsRouting.push_back (extensionRouting);
843 for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
845 if ((*i)->GetTypeRouting () == typeRouting)
855 m_extensionsRouting.remove (extensionRouting);
864 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionLooseRouting")
866 .AddConstructor<Ipv6ExtensionLooseRouting> ()
890 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
910 uint8_t numberAddress = buf[1] / 2;
926 uint8_t length = (routingHeader.
GetLength () >> 3) - 1;
927 uint8_t nbAddress = length / 2;
928 uint8_t nextAddressIndex;
931 if (segmentsLeft == 0)
946 if (segmentsLeft > nbAddress)
956 nextAddressIndex = nbAddress - segmentsLeft;
994 Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
999 ipv6->SendRealOut (rtentry, p, ipv6header);
1020 .AddConstructor<Ipv6ExtensionESP> ()
1044 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1059 .AddConstructor<Ipv6ExtensionAH> ()
1083 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.
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)
Doxygen 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...
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.
NS_LOG_COMPONENT_DEFINE("Ipv6Extension")
IPv6 layer implementation.
Doxygen introspection did not find any typical Config paths.
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.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual void DoDispose()
Dispose this object.
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)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
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
SocketErrno
Enumeration of the possible errors returned by a socket.
Doxygen 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.
Doxygen introspection did not find any typical Config paths.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionHopByHop()
Destructor.
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.
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.
Doxygen introspection did not find any typical Config paths.
~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.
Doxygen 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.
Doxygen 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
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)
Remove size bytes from the end of the current packet It is safe to remove more bytes than are present...
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.
Doxygen 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)
Ipv6Extension()
Constructor.
Doxygen introspection did not find any typical Config paths.
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
Copy the packet contents to a byte buffer.
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
Doxygen introspection did not find any typical Config paths.
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)
Add header to this packet.
~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.
Doxygen introspection did not find any typical Config paths.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &isDropped)
Process method.