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::make_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++)
533 fragment->
AddHeader (*dynamic_cast<Ipv6ExtensionHopByHopHeader *> (it->first));
537 fragment->
AddHeader (*dynamic_cast<Ipv6ExtensionLooseRoutingHeader *> (it->first));
541 fragment->
AddHeader (*dynamic_cast<Ipv6ExtensionDestinationHeader *> (it->first));
548 std::ostringstream oss;
549 fragment->
Print (oss);
550 listFragments.push_back (fragment);
552 while (moreFragment);
554 for (
std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
559 unfragmentablePart.clear ();
568 MapFragments_t::iterator it =
m_fragments.find (fragmentsId);
570 fragments = it->second;
572 Ptr<Packet> packet = fragments->GetPartialPacket ();
599 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
601 for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
603 if (it->second > fragmentOffset)
609 if (it == m_packetFragments.end ())
611 m_moreFragment = moreFragment;
614 m_packetFragments.insert (it, std::make_pair<
Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
619 m_unfragmentable = unfragmentablePart;
624 bool ret = !m_moreFragment && m_packetFragments.size () > 0;
628 uint16_t lastEndOffset = 0;
630 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
632 if (lastEndOffset != it->second)
638 lastEndOffset += it->first->GetSize ();
649 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
661 if ( m_unfragmentable )
663 p = m_unfragmentable->
Copy ();
670 uint16_t lastEndOffset = 0;
672 for (
std::list<std::pair<
Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
674 if (lastEndOffset != it->second)
679 lastEndOffset += it->first->GetSize ();
687 m_timeoutEventId = event;
693 m_timeoutEventId.Cancel ();
702 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRouting")
704 .AddConstructor<Ipv6ExtensionRouting> ()
734 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
744 packet->
CopyData (buf,
sizeof(buf));
746 uint8_t routingNextHeader = buf[0];
747 uint8_t routingLength = buf[1];
748 uint8_t routingTypeRouting = buf[2];
749 uint8_t routingSegmentsLeft = buf[3];
753 *nextHeader = routingNextHeader;
761 if (ipv6ExtensionRouting == 0)
763 if (routingSegmentsLeft == 0)
776 return routingLength;
779 return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, isDropped);
787 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionRoutingDemux")
789 .AddAttribute (
"Routing Extensions",
"The set of IPv6 Routing extensions registered with this demux.",
792 MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
807 for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
812 m_extensionsRouting.clear ();
824 m_extensionsRouting.push_back (extensionRouting);
829 for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
831 if ((*i)->GetTypeRouting () == typeRouting)
841 m_extensionsRouting.remove (extensionRouting);
849 static TypeId tid =
TypeId (
"ns3::Ipv6ExtensionLooseRouting")
851 .AddConstructor<Ipv6ExtensionLooseRouting> ()
875 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
895 uint8_t numberAddress = buf[1] / 2;
911 uint8_t length = (routingHeader.
GetLength () >> 3) - 1;
912 uint8_t nbAddress = length / 2;
913 uint8_t nextAddressIndex;
916 if (segmentsLeft == 0)
931 if (segmentsLeft > nbAddress)
941 nextAddressIndex = nbAddress - segmentsLeft;
979 Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
984 ipv6->SendRealOut (rtentry, p, ipv6header);
1004 .AddConstructor<Ipv6ExtensionESP> ()
1028 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1042 .AddConstructor<Ipv6ExtensionAH> ()
1066 NS_LOG_FUNCTION (
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);