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);