A Discrete-Event Network Simulator
API
ipv6-extension.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007-2009 Strasbourg University
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: David Gross <gdavid.devel@gmail.com>
18  */
19 
20 #include "ipv6-extension.h"
21 
22 #include "icmpv6-l4-protocol.h"
23 #include "ipv6-extension-demux.h"
24 #include "ipv6-extension-header.h"
25 #include "ipv6-option-demux.h"
26 #include "ipv6-option.h"
27 #include "udp-header.h"
28 
29 #include "ns3/assert.h"
30 #include "ns3/ipv6-address.h"
31 #include "ns3/ipv6-header.h"
32 #include "ns3/ipv6-l3-protocol.h"
33 #include "ns3/ipv6-list-routing.h"
34 #include "ns3/ipv6-route.h"
35 #include "ns3/ipv6-static-routing.h"
36 #include "ns3/log.h"
37 #include "ns3/object-vector.h"
38 #include "ns3/trace-source-accessor.h"
39 #include "ns3/uinteger.h"
40 
41 #include <ctime>
42 #include <list>
43 
44 namespace ns3
45 {
46 
47 NS_LOG_COMPONENT_DEFINE("Ipv6Extension");
48 
49 NS_OBJECT_ENSURE_REGISTERED(Ipv6Extension);
50 
51 TypeId
53 {
54  static TypeId tid = TypeId("ns3::Ipv6Extension")
55  .SetParent<Object>()
56  .SetGroupName("Internet")
57  .AddAttribute("ExtensionNumber",
58  "The IPv6 extension number.",
59  UintegerValue(0),
61  MakeUintegerChecker<uint8_t>());
62  return tid;
63 }
64 
66 {
67  m_uvar = CreateObject<UniformRandomVariable>();
68 }
69 
71 {
72 }
73 
74 void
76 {
77  NS_LOG_FUNCTION(this << node);
78 
79  m_node = node;
80 }
81 
84 {
85  return m_node;
86 }
87 
88 uint8_t
90  uint8_t offset,
91  uint8_t length,
92  const Ipv6Header& ipv6Header,
93  Ipv6Address dst,
94  uint8_t* nextHeader,
95  bool& stopProcessing,
96  bool& isDropped,
97  Ipv6L3Protocol::DropReason& dropReason)
98 {
99  NS_LOG_FUNCTION(this << packet << offset << length << ipv6Header << dst << nextHeader
100  << isDropped);
101 
102  // For ICMPv6 Error packets
103  Ptr<Packet> malformedPacket = packet->Copy();
104  malformedPacket->AddHeader(ipv6Header);
105  Ptr<Icmpv6L4Protocol> icmpv6 = GetNode()->GetObject<Ipv6L3Protocol>()->GetIcmpv6();
106 
107  Ptr<Packet> p = packet->Copy();
108  p->RemoveAtStart(offset);
109 
110  Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode()->GetObject<Ipv6OptionDemux>();
111  Ptr<Ipv6Option> ipv6Option;
112 
113  uint8_t processedSize = 0;
114  uint32_t size = p->GetSize();
115  uint8_t* data = new uint8_t[size];
116  p->CopyData(data, size);
117 
118  uint8_t optionType = 0;
119  uint8_t optionLength = 0;
120 
121  while (length > processedSize && !isDropped)
122  {
123  optionType = *(data + processedSize);
124  ipv6Option = ipv6OptionDemux->GetOption(optionType);
125 
126  if (!ipv6Option)
127  {
128  optionType >>= 6;
129  switch (optionType)
130  {
131  case 0:
132  optionLength = *(data + processedSize + 1) + 2;
133  break;
134 
135  case 1:
136  NS_LOG_LOGIC("Unknown Option. Drop!");
137  optionLength = 0;
138  isDropped = true;
139  stopProcessing = true;
141  break;
142 
143  case 2:
144  NS_LOG_LOGIC("Unknown Option. Drop!");
145  icmpv6->SendErrorParameterError(malformedPacket,
146  ipv6Header.GetSource(),
148  offset + processedSize);
149  optionLength = 0;
150  isDropped = true;
151  stopProcessing = true;
153  break;
154 
155  case 3:
156  NS_LOG_LOGIC("Unknown Option. Drop!");
157 
158  if (!ipv6Header.GetDestination().IsMulticast())
159  {
160  icmpv6->SendErrorParameterError(malformedPacket,
161  ipv6Header.GetSource(),
163  offset + processedSize);
164  }
165  optionLength = 0;
166  isDropped = true;
167  stopProcessing = true;
169  break;
170 
171  default:
172  break;
173  }
174  }
175  else
176  {
177  optionLength =
178  ipv6Option->Process(packet, offset + processedSize, ipv6Header, isDropped);
179  }
180 
181  processedSize += optionLength;
182  p->RemoveAtStart(optionLength);
183  }
184 
185  delete[] data;
186 
187  return processedSize;
188 }
189 
190 int64_t
192 {
193  NS_LOG_FUNCTION(this << stream);
194  m_uvar->SetStream(stream);
195  return 1;
196 }
197 
199 
200 TypeId
202 {
203  static TypeId tid = TypeId("ns3::Ipv6ExtensionHopByHop")
205  .SetGroupName("Internet")
206  .AddConstructor<Ipv6ExtensionHopByHop>();
207  return tid;
208 }
209 
211 {
212 }
213 
215 {
216 }
217 
218 uint8_t
220 {
221  return EXT_NUMBER;
222 }
223 
224 uint8_t
226  uint8_t offset,
227  const Ipv6Header& ipv6Header,
228  Ipv6Address dst,
229  uint8_t* nextHeader,
230  bool& stopProcessing,
231  bool& isDropped,
232  Ipv6L3Protocol::DropReason& dropReason)
233 {
234  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
235 
236  Ptr<Packet> p = packet->Copy();
237  p->RemoveAtStart(offset);
238 
239  Ipv6ExtensionHopByHopHeader hopbyhopHeader;
240  p->RemoveHeader(hopbyhopHeader);
241  if (nextHeader)
242  {
243  *nextHeader = hopbyhopHeader.GetNextHeader();
244  }
245 
246  uint8_t processedSize = hopbyhopHeader.GetOptionsOffset();
247  offset += processedSize;
248  uint8_t length = hopbyhopHeader.GetLength() - hopbyhopHeader.GetOptionsOffset();
249 
250  processedSize += ProcessOptions(packet,
251  offset,
252  length,
253  ipv6Header,
254  dst,
255  nextHeader,
256  stopProcessing,
257  isDropped,
258  dropReason);
259 
260  return processedSize;
261 }
262 
264 
265 TypeId
267 {
268  static TypeId tid = TypeId("ns3::Ipv6ExtensionDestination")
270  .SetGroupName("Internet")
271  .AddConstructor<Ipv6ExtensionDestination>();
272  return tid;
273 }
274 
276 {
277 }
278 
280 {
281 }
282 
283 uint8_t
285 {
286  return EXT_NUMBER;
287 }
288 
289 uint8_t
291  uint8_t offset,
292  const Ipv6Header& ipv6Header,
293  Ipv6Address dst,
294  uint8_t* nextHeader,
295  bool& stopProcessing,
296  bool& isDropped,
297  Ipv6L3Protocol::DropReason& dropReason)
298 {
299  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
300 
301  Ptr<Packet> p = packet->Copy();
302  p->RemoveAtStart(offset);
303 
304  Ipv6ExtensionDestinationHeader destinationHeader;
305  p->RemoveHeader(destinationHeader);
306  if (nextHeader)
307  {
308  *nextHeader = destinationHeader.GetNextHeader();
309  }
310 
311  uint8_t processedSize = destinationHeader.GetOptionsOffset();
312  offset += processedSize;
313  uint8_t length = destinationHeader.GetLength() - destinationHeader.GetOptionsOffset();
314 
315  processedSize += ProcessOptions(packet,
316  offset,
317  length,
318  ipv6Header,
319  dst,
320  nextHeader,
321  stopProcessing,
322  isDropped,
323  dropReason);
324 
325  return processedSize;
326 }
327 
329 
330 TypeId
332 {
333  static TypeId tid =
334  TypeId("ns3::Ipv6ExtensionFragment")
336  .SetGroupName("Internet")
337  .AddConstructor<Ipv6ExtensionFragment>()
338  .AddAttribute("FragmentExpirationTimeout",
339  "When this timeout expires, the fragments "
340  "will be cleared from the buffer.",
341  TimeValue(Seconds(60)),
343  MakeTimeChecker());
344  return tid;
345 }
346 
348 {
349 }
350 
352 {
353 }
354 
355 void
357 {
358  NS_LOG_FUNCTION(this);
359 
360  for (MapFragments_t::iterator it = m_fragments.begin(); it != m_fragments.end(); it++)
361  {
362  it->second = nullptr;
363  }
364 
365  m_fragments.clear();
366  m_timeoutEventList.clear();
368  {
370  }
372 }
373 
374 uint8_t
376 {
377  return EXT_NUMBER;
378 }
379 
380 uint8_t
382  uint8_t offset,
383  const Ipv6Header& ipv6Header,
384  Ipv6Address dst,
385  uint8_t* nextHeader,
386  bool& stopProcessing,
387  bool& isDropped,
388  Ipv6L3Protocol::DropReason& dropReason)
389 {
390  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
391 
392  Ptr<Packet> p = packet->Copy();
393  p->RemoveAtStart(offset);
394 
395  Ipv6ExtensionFragmentHeader fragmentHeader;
396  p->RemoveHeader(fragmentHeader);
397 
398  if (nextHeader)
399  {
400  *nextHeader = fragmentHeader.GetNextHeader();
401  }
402 
403  bool moreFragment = fragmentHeader.GetMoreFragment();
404  uint16_t fragmentOffset = fragmentHeader.GetOffset();
405  uint32_t identification = fragmentHeader.GetIdentification();
406  Ipv6Address src = ipv6Header.GetSource();
407 
408  FragmentKey_t fragmentKey = FragmentKey_t(src, identification);
409  Ptr<Fragments> fragments;
410 
411  Ipv6Header ipHeader = ipv6Header;
412  ipHeader.SetNextHeader(fragmentHeader.GetNextHeader());
413 
414  MapFragments_t::iterator it = m_fragments.find(fragmentKey);
415  if (it == m_fragments.end())
416  {
417  fragments = Create<Fragments>();
418  m_fragments.insert(std::make_pair(fragmentKey, fragments));
419  NS_LOG_DEBUG("Insert new fragment key: src: "
420  << src << " IP hdr id " << identification << " m_fragments.size() "
421  << m_fragments.size() << " offset " << fragmentOffset);
422  FragmentsTimeoutsListI_t iter = SetTimeout(fragmentKey, ipHeader);
423  fragments->SetTimeoutIter(iter);
424  }
425  else
426  {
427  fragments = it->second;
428  }
429 
430  if (fragmentOffset == 0)
431  {
432  Ptr<Packet> unfragmentablePart = packet->Copy();
433  unfragmentablePart->RemoveAtEnd(packet->GetSize() - offset);
434  fragments->SetUnfragmentablePart(unfragmentablePart);
435  }
436 
437  NS_LOG_DEBUG("Add fragment with IP hdr id " << identification << " offset " << fragmentOffset);
438  fragments->AddFragment(p, fragmentOffset, moreFragment);
439 
440  if (fragments->IsEntire())
441  {
442  packet = fragments->GetPacket();
443  m_timeoutEventList.erase(fragments->GetTimeoutIter());
444  m_fragments.erase(fragmentKey);
445  NS_LOG_DEBUG("Finished fragment with IP hdr id "
446  << fragmentKey.second
447  << " erase timeout, m_fragments.size(): " << m_fragments.size());
448  stopProcessing = false;
449  }
450  else
451  {
452  stopProcessing = true;
453  }
454 
455  return 0;
456 }
457 
458 void
460  Ipv6Header ipv6Header,
461  uint32_t maxFragmentSize,
462  std::list<Ipv6PayloadHeaderPair>& listFragments)
463 {
464  NS_LOG_FUNCTION(this << packet << ipv6Header << maxFragmentSize);
465  Ptr<Packet> p = packet->Copy();
466 
467  uint8_t nextHeader = ipv6Header.GetNextHeader();
468  uint8_t ipv6HeaderSize = ipv6Header.GetSerializedSize();
469 
470  uint8_t type;
471  p->CopyData(&type, sizeof(type));
472 
473  bool moreHeader = true;
474  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP ||
475  nextHeader == Ipv6Header::IPV6_EXT_ROUTING ||
477  {
478  moreHeader = false;
480  }
481 
482  std::list<std::pair<Ipv6ExtensionHeader*, uint8_t>> unfragmentablePart;
483  uint32_t unfragmentablePartSize = 0;
484 
486  Ptr<Ipv6Extension> extension = extensionDemux->GetExtension(nextHeader);
487  uint8_t extensionHeaderLength;
488 
489  while (moreHeader)
490  {
491  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
492  {
494  p->RemoveHeader(*hopbyhopHeader);
495 
496  nextHeader = hopbyhopHeader->GetNextHeader();
497  extensionHeaderLength = hopbyhopHeader->GetLength();
498 
499  uint8_t type;
500  p->CopyData(&type, sizeof(type));
501 
502  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP ||
503  nextHeader == Ipv6Header::IPV6_EXT_ROUTING ||
504  (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION &&
506  {
507  moreHeader = false;
509  }
510 
511  unfragmentablePart.emplace_back(hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP);
512  unfragmentablePartSize += extensionHeaderLength;
513  }
514  else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
515  {
516  uint8_t buf[2];
517  p->CopyData(buf, sizeof(buf));
518  uint8_t numberAddress = buf[1] / 2;
520  routingHeader->SetNumberAddress(numberAddress);
521  p->RemoveHeader(*routingHeader);
522 
523  nextHeader = routingHeader->GetNextHeader();
524  extensionHeaderLength = routingHeader->GetLength();
525 
526  uint8_t type;
527  p->CopyData(&type, sizeof(type));
528  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP ||
529  nextHeader == Ipv6Header::IPV6_EXT_ROUTING ||
530  (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION &&
532  {
533  moreHeader = false;
535  }
536 
537  unfragmentablePart.emplace_back(routingHeader, Ipv6Header::IPV6_EXT_ROUTING);
538  unfragmentablePartSize += extensionHeaderLength;
539  }
540  else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
541  {
542  Ipv6ExtensionDestinationHeader* destinationHeader =
544  p->RemoveHeader(*destinationHeader);
545 
546  nextHeader = destinationHeader->GetNextHeader();
547  extensionHeaderLength = destinationHeader->GetLength();
548 
549  uint8_t type;
550  p->CopyData(&type, sizeof(type));
551  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP ||
552  nextHeader == Ipv6Header::IPV6_EXT_ROUTING ||
553  (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION &&
555  {
556  moreHeader = false;
558  }
559 
560  unfragmentablePart.emplace_back(destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION);
561  unfragmentablePartSize += extensionHeaderLength;
562  }
563  }
564 
565  Ipv6ExtensionFragmentHeader fragmentHeader;
566  uint8_t fragmentHeaderSize = fragmentHeader.GetSerializedSize();
567 
568  uint32_t maxFragmentablePartSize =
569  maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
570  uint32_t currentFragmentablePartSize = 0;
571 
572  bool moreFragment = true;
573  uint32_t identification = (uint32_t)m_uvar->GetValue(0, (uint32_t)-1);
574  uint16_t offset = 0;
575 
576  do
577  {
578  if (p->GetSize() > offset + maxFragmentablePartSize)
579  {
580  moreFragment = true;
581  currentFragmentablePartSize = maxFragmentablePartSize;
582  currentFragmentablePartSize -= currentFragmentablePartSize % 8;
583  }
584  else
585  {
586  moreFragment = false;
587  currentFragmentablePartSize = p->GetSize() - offset;
588  }
589 
590  fragmentHeader.SetNextHeader(nextHeader);
591  fragmentHeader.SetOffset(offset);
592  fragmentHeader.SetMoreFragment(moreFragment);
593  fragmentHeader.SetIdentification(identification);
594 
595  Ptr<Packet> fragment = p->CreateFragment(offset, currentFragmentablePartSize);
596  offset += currentFragmentablePartSize;
597 
598  fragment->AddHeader(fragmentHeader);
599 
600  for (std::list<std::pair<Ipv6ExtensionHeader*, uint8_t>>::iterator it =
601  unfragmentablePart.begin();
602  it != unfragmentablePart.end();
603  it++)
604  {
605  if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
606  {
608  dynamic_cast<Ipv6ExtensionHopByHopHeader*>(it->first);
609  NS_ASSERT(p != nullptr);
610  fragment->AddHeader(*p);
611  }
612  else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
613  {
615  dynamic_cast<Ipv6ExtensionLooseRoutingHeader*>(it->first);
616  NS_ASSERT(p != nullptr);
617  fragment->AddHeader(*p);
618  }
619  else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
620  {
622  dynamic_cast<Ipv6ExtensionDestinationHeader*>(it->first);
623  NS_ASSERT(p != nullptr);
624  fragment->AddHeader(*p);
625  }
626  }
627 
628  ipv6Header.SetPayloadLength(fragment->GetSize());
629 
630  std::ostringstream oss;
631  oss << ipv6Header;
632  fragment->Print(oss);
633 
634  listFragments.emplace_back(fragment, ipv6Header);
635  } while (moreFragment);
636 
637  for (std::list<std::pair<Ipv6ExtensionHeader*, uint8_t>>::iterator it =
638  unfragmentablePart.begin();
639  it != unfragmentablePart.end();
640  it++)
641  {
642  delete it->first;
643  }
644 
645  unfragmentablePart.clear();
646 }
647 
648 void
650 {
651  NS_LOG_FUNCTION(this << fragmentKey.first << fragmentKey.second << ipHeader);
652  Ptr<Fragments> fragments;
653 
654  MapFragments_t::iterator it = m_fragments.find(fragmentKey);
655  NS_ASSERT_MSG(it != m_fragments.end(),
656  "IPv6 Fragment timeout reached for non-existent fragment");
657  fragments = it->second;
658 
659  Ptr<Packet> packet = fragments->GetPartialPacket();
660 
661  // if we have at least 8 bytes, we can send an ICMP.
662  if (packet && packet->GetSize() > 8)
663  {
664  Ptr<Packet> p = packet->Copy();
665  p->AddHeader(ipHeader);
667  icmp->SendErrorTimeExceeded(p, ipHeader.GetSource(), Icmpv6Header::ICMPV6_FRAGTIME);
668  }
669 
671  ipL3->ReportDrop(ipHeader, packet, Ipv6L3Protocol::DROP_FRAGMENT_TIMEOUT);
672 
673  // clear the buffers
674  m_fragments.erase(fragmentKey);
675 }
676 
679 {
680  NS_LOG_FUNCTION(this << key.first << key.second << ipHeader);
681  if (m_timeoutEventList.empty())
682  {
683  NS_LOG_DEBUG("Scheduling timeout for IP hdr id "
684  << key.second << " at time "
685  << (Simulator::Now() + m_fragmentExpirationTimeout).GetSeconds());
688  this);
689  }
690  NS_LOG_DEBUG("Adding timeout at "
691  << (Simulator::Now() + m_fragmentExpirationTimeout).GetSeconds() << " with key "
692  << key.second);
693  m_timeoutEventList.emplace_back(Simulator::Now() + m_fragmentExpirationTimeout, key, ipHeader);
694 
696 
697  return (iter);
698 }
699 
700 void
702 {
703  NS_LOG_FUNCTION(this);
704  Time now = Simulator::Now();
705 
706  // std::list Time, Fragment_key_t, Ipv6Header
707  // Fragment key is a pair: Ipv6Address, uint32_t ipHeaderId
708  for (auto& element : m_timeoutEventList)
709  {
710  NS_LOG_DEBUG("Handle time " << std::get<0>(element).GetSeconds() << " IP hdr id "
711  << std::get<1>(element).second);
712  }
713  while (!m_timeoutEventList.empty() && std::get<0>(*m_timeoutEventList.begin()) == now)
714  {
715  HandleFragmentsTimeout(std::get<1>(*m_timeoutEventList.begin()),
716  std::get<2>(*m_timeoutEventList.begin()));
717  m_timeoutEventList.pop_front();
718  }
719 
720  if (m_timeoutEventList.empty())
721  {
722  return;
723  }
724 
725  Time difference = std::get<0>(*m_timeoutEventList.begin()) - now;
726  NS_LOG_DEBUG("Scheduling later HandleTimeout at " << (now + difference).GetSeconds());
728 }
729 
731  : m_moreFragment(0)
732 {
733 }
734 
736 {
737 }
738 
739 void
741  uint16_t fragmentOffset,
742  bool moreFragment)
743 {
744  NS_LOG_FUNCTION(this << fragment << fragmentOffset << moreFragment);
745  std::list<std::pair<Ptr<Packet>, uint16_t>>::iterator it;
746 
747  for (it = m_packetFragments.begin(); it != m_packetFragments.end(); it++)
748  {
749  if (it->second > fragmentOffset)
750  {
751  break;
752  }
753  }
754 
755  if (it == m_packetFragments.end())
756  {
757  m_moreFragment = moreFragment;
758  }
759 
760  m_packetFragments.insert(it, std::pair<Ptr<Packet>, uint16_t>(fragment, fragmentOffset));
761 }
762 
763 void
765 {
766  NS_LOG_FUNCTION(this << unfragmentablePart);
767  m_unfragmentable = unfragmentablePart;
768 }
769 
770 bool
772 {
773  bool ret = !m_moreFragment && !m_packetFragments.empty();
774 
775  if (ret)
776  {
777  uint16_t lastEndOffset = 0;
778 
779  for (std::list<std::pair<Ptr<Packet>, uint16_t>>::const_iterator it =
780  m_packetFragments.begin();
781  it != m_packetFragments.end();
782  it++)
783  {
784  if (lastEndOffset != it->second)
785  {
786  ret = false;
787  break;
788  }
789 
790  lastEndOffset += it->first->GetSize();
791  }
792  }
793 
794  return ret;
795 }
796 
799 {
800  Ptr<Packet> p = m_unfragmentable->Copy();
801 
802  for (std::list<std::pair<Ptr<Packet>, uint16_t>>::const_iterator it = m_packetFragments.begin();
803  it != m_packetFragments.end();
804  it++)
805  {
806  p->AddAtEnd(it->first);
807  }
808 
809  return p;
810 }
811 
814 {
815  Ptr<Packet> p;
816 
817  if (m_unfragmentable)
818  {
819  p = m_unfragmentable->Copy();
820  }
821  else
822  {
823  return p;
824  }
825 
826  uint16_t lastEndOffset = 0;
827 
828  for (std::list<std::pair<Ptr<Packet>, uint16_t>>::const_iterator it = m_packetFragments.begin();
829  it != m_packetFragments.end();
830  it++)
831  {
832  if (lastEndOffset != it->second)
833  {
834  break;
835  }
836  p->AddAtEnd(it->first);
837  lastEndOffset += it->first->GetSize();
838  }
839 
840  return p;
841 }
842 
843 void
845 {
846  NS_LOG_FUNCTION(this);
847  m_timeoutIter = iter;
848 }
849 
852 {
853  return m_timeoutIter;
854 }
855 
857 
858 TypeId
860 {
861  static TypeId tid = TypeId("ns3::Ipv6ExtensionRouting")
863  .SetGroupName("Internet")
864  .AddConstructor<Ipv6ExtensionRouting>();
865  return tid;
866 }
867 
869 {
870 }
871 
873 {
874 }
875 
876 uint8_t
878 {
879  return EXT_NUMBER;
880 }
881 
882 uint8_t
884 {
885  return 0;
886 }
887 
888 uint8_t
890  uint8_t offset,
891  const Ipv6Header& ipv6Header,
892  Ipv6Address dst,
893  uint8_t* nextHeader,
894  bool& stopProcessing,
895  bool& isDropped,
896  Ipv6L3Protocol::DropReason& dropReason)
897 {
898  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
899 
900  // For ICMPv6 Error Packets
901  Ptr<Packet> malformedPacket = packet->Copy();
902  malformedPacket->AddHeader(ipv6Header);
903 
904  Ptr<Packet> p = packet->Copy();
905  p->RemoveAtStart(offset);
906 
907  uint8_t buf[4];
908  packet->CopyData(buf, sizeof(buf));
909 
910  uint8_t routingNextHeader = buf[0];
911  uint8_t routingLength = buf[1];
912  uint8_t routingTypeRouting = buf[2];
913  uint8_t routingSegmentsLeft = buf[3];
914 
915  if (nextHeader)
916  {
917  *nextHeader = routingNextHeader;
918  }
919 
920  Ptr<Icmpv6L4Protocol> icmpv6 = GetNode()->GetObject<Ipv6L3Protocol>()->GetIcmpv6();
921 
922  Ptr<Ipv6ExtensionRoutingDemux> ipv6ExtensionRoutingDemux =
924  Ptr<Ipv6ExtensionRouting> ipv6ExtensionRouting =
925  ipv6ExtensionRoutingDemux->GetExtensionRouting(routingTypeRouting);
926 
927  if (!ipv6ExtensionRouting)
928  {
929  if (routingSegmentsLeft == 0)
930  {
931  isDropped = false;
932  }
933  else
934  {
935  NS_LOG_LOGIC("Malformed header. Drop!");
936 
937  icmpv6->SendErrorParameterError(malformedPacket,
938  ipv6Header.GetSource(),
940  offset + 1);
942  isDropped = true;
943  stopProcessing = true;
944  }
945 
946  return routingLength;
947  }
948 
949  return ipv6ExtensionRouting->Process(packet,
950  offset,
951  ipv6Header,
952  dst,
953  (uint8_t*)nullptr,
954  stopProcessing,
955  isDropped,
956  dropReason);
957 }
958 
960 
961 TypeId
963 {
964  static TypeId tid =
965  TypeId("ns3::Ipv6ExtensionRoutingDemux")
966  .SetParent<Object>()
967  .SetGroupName("Internet")
968  .AddAttribute("RoutingExtensions",
969  "The set of IPv6 Routing extensions registered with this demux.",
972  MakeObjectVectorChecker<Ipv6ExtensionRouting>());
973  return tid;
974 }
975 
977 {
978 }
979 
981 {
982 }
983 
984 void
986 {
987  NS_LOG_FUNCTION(this);
988  for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin();
989  it != m_extensionsRouting.end();
990  it++)
991  {
992  (*it)->Dispose();
993  *it = nullptr;
994  }
995  m_extensionsRouting.clear();
996  m_node = nullptr;
998 }
999 
1000 void
1002 {
1003  NS_LOG_FUNCTION(this << node);
1004  m_node = node;
1005 }
1006 
1007 void
1009 {
1010  NS_LOG_FUNCTION(this << extensionRouting);
1011  m_extensionsRouting.push_back(extensionRouting);
1012 }
1013 
1016 {
1017  for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin();
1018  i != m_extensionsRouting.end();
1019  i++)
1020  {
1021  if ((*i)->GetTypeRouting() == typeRouting)
1022  {
1023  return *i;
1024  }
1025  }
1026  return nullptr;
1027 }
1028 
1029 void
1031 {
1032  NS_LOG_FUNCTION(this << extensionRouting);
1033  m_extensionsRouting.remove(extensionRouting);
1034 }
1035 
1037 
1038 TypeId
1040 {
1041  static TypeId tid = TypeId("ns3::Ipv6ExtensionLooseRouting")
1043  .SetGroupName("Internet")
1044  .AddConstructor<Ipv6ExtensionLooseRouting>();
1045  return tid;
1046 }
1047 
1049 {
1050 }
1051 
1053 {
1054 }
1055 
1056 uint8_t
1058 {
1059  return TYPE_ROUTING;
1060 }
1061 
1062 uint8_t
1064  uint8_t offset,
1065  const Ipv6Header& ipv6Header,
1066  Ipv6Address dst,
1067  uint8_t* nextHeader,
1068  bool& stopProcessing,
1069  bool& isDropped,
1070  Ipv6L3Protocol::DropReason& dropReason)
1071 {
1072  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1073 
1074  // For ICMPv6 Error packets
1075  Ptr<Packet> malformedPacket = packet->Copy();
1076  malformedPacket->AddHeader(ipv6Header);
1077 
1078  Ptr<Packet> p = packet->Copy();
1079  p->RemoveAtStart(offset);
1080 
1081  // Copy IPv6 Header : ipv6Header -> ipv6header
1082  Buffer tmp;
1083  tmp.AddAtStart(ipv6Header.GetSerializedSize());
1084  Buffer::Iterator it = tmp.Begin();
1085  Ipv6Header ipv6header;
1086  ipv6Header.Serialize(it);
1087  ipv6header.Deserialize(it);
1088 
1089  // Get the number of routers' address field
1090  uint8_t buf[2];
1091  p->CopyData(buf, sizeof(buf));
1092  uint8_t numberAddress = buf[1] / 2;
1093  Ipv6ExtensionLooseRoutingHeader routingHeader;
1094  routingHeader.SetNumberAddress(numberAddress);
1095  p->RemoveHeader(routingHeader);
1096 
1097  if (nextHeader)
1098  {
1099  *nextHeader = routingHeader.GetNextHeader();
1100  }
1101 
1102  Ptr<Icmpv6L4Protocol> icmpv6 = GetNode()->GetObject<Ipv6L3Protocol>()->GetIcmpv6();
1103 
1104  Ipv6Address srcAddress = ipv6header.GetSource();
1105  Ipv6Address destAddress = ipv6header.GetDestination();
1106  uint8_t hopLimit = ipv6header.GetHopLimit();
1107  uint8_t segmentsLeft = routingHeader.GetSegmentsLeft();
1108  uint8_t length = (routingHeader.GetLength() >> 3) - 1;
1109  uint8_t nbAddress = length / 2;
1110  uint8_t nextAddressIndex;
1111  Ipv6Address nextAddress;
1112 
1113  if (segmentsLeft == 0)
1114  {
1115  isDropped = false;
1116  return routingHeader.GetSerializedSize();
1117  }
1118 
1119  if (length % 2 != 0)
1120  {
1121  NS_LOG_LOGIC("Malformed header. Drop!");
1122  icmpv6->SendErrorParameterError(malformedPacket,
1123  srcAddress,
1125  offset + 1);
1127  isDropped = true;
1128  stopProcessing = true;
1129  return routingHeader.GetSerializedSize();
1130  }
1131 
1132  if (segmentsLeft > nbAddress)
1133  {
1134  NS_LOG_LOGIC("Malformed header. Drop!");
1135  icmpv6->SendErrorParameterError(malformedPacket,
1136  srcAddress,
1138  offset + 3);
1140  isDropped = true;
1141  stopProcessing = true;
1142  return routingHeader.GetSerializedSize();
1143  }
1144 
1145  routingHeader.SetSegmentsLeft(segmentsLeft - 1);
1146  nextAddressIndex = nbAddress - segmentsLeft;
1147  nextAddress = routingHeader.GetRouterAddress(nextAddressIndex);
1148 
1149  if (nextAddress.IsMulticast() || destAddress.IsMulticast())
1150  {
1152  isDropped = true;
1153  stopProcessing = true;
1154  return routingHeader.GetSerializedSize();
1155  }
1156 
1157  routingHeader.SetRouterAddress(nextAddressIndex, destAddress);
1158  ipv6header.SetDestination(nextAddress);
1159 
1160  if (hopLimit <= 1)
1161  {
1162  NS_LOG_LOGIC("Time Exceeded : Hop Limit <= 1. Drop!");
1163  icmpv6->SendErrorTimeExceeded(malformedPacket, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT);
1165  isDropped = true;
1166  stopProcessing = true;
1167  return routingHeader.GetSerializedSize();
1168  }
1169 
1170  ipv6header.SetHopLimit(hopLimit - 1);
1171  p->AddHeader(routingHeader);
1172 
1173  /* short-circuiting routing stuff
1174  *
1175  * If we process this option,
1176  * the packet was for us so we resend it to
1177  * the new destination (modified in the header above).
1178  */
1179 
1181  Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol();
1182  Socket::SocketErrno err;
1183  NS_ASSERT(ipv6rp);
1184 
1185  Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput(p, ipv6header, nullptr, err);
1186 
1187  if (rtentry)
1188  {
1189  /* we know a route exists so send packet now */
1190  ipv6->SendRealOut(rtentry, p, ipv6header);
1191  }
1192  else
1193  {
1194  NS_LOG_INFO("No route for next router");
1195  }
1196 
1197  /* as we directly send packet, mark it as dropped */
1198  isDropped = true;
1199 
1200  return routingHeader.GetSerializedSize();
1201 }
1202 
1204 
1205 TypeId
1207 {
1208  static TypeId tid = TypeId("ns3::Ipv6ExtensionESP")
1210  .SetGroupName("Internet")
1211  .AddConstructor<Ipv6ExtensionESP>();
1212  return tid;
1213 }
1214 
1216 {
1217 }
1218 
1220 {
1221 }
1222 
1223 uint8_t
1225 {
1226  return EXT_NUMBER;
1227 }
1228 
1229 uint8_t
1231  uint8_t offset,
1232  const Ipv6Header& ipv6Header,
1233  Ipv6Address dst,
1234  uint8_t* nextHeader,
1235  bool& stopProcessing,
1236  bool& isDropped,
1237  Ipv6L3Protocol::DropReason& dropReason)
1238 {
1239  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1240 
1243  return 0;
1244 }
1245 
1247 
1248 TypeId
1250 {
1251  static TypeId tid = TypeId("ns3::Ipv6ExtensionAH")
1253  .SetGroupName("Internet")
1254  .AddConstructor<Ipv6ExtensionAH>();
1255  return tid;
1256 }
1257 
1259 {
1260 }
1261 
1263 {
1264 }
1265 
1266 uint8_t
1268 {
1269  return EXT_NUMBER;
1270 }
1271 
1272 uint8_t
1274  uint8_t offset,
1275  const Ipv6Header& ipv6Header,
1276  Ipv6Address dst,
1277  uint8_t* nextHeader,
1278  bool& stopProcessing,
1279  bool& isDropped,
1280  Ipv6L3Protocol::DropReason& dropReason)
1281 {
1282  NS_LOG_FUNCTION(this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1283 
1286  return true;
1287 }
1288 
1289 } /* namespace ns3 */
iterator in a Buffer instance
Definition: buffer.h:100
automatically resized byte buffer
Definition: buffer.h:94
void AddAtStart(uint32_t start)
Definition: buffer.cc:311
Buffer::Iterator Begin() const
Definition: buffer.h:1074
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
An implementation of the ICMPv6 protocol.
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
IPv6 Extension AH (Authentication Header)
~Ipv6ExtensionAH() override
Destructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
static TypeId GetTypeId()
Get the type identificator.
uint8_t GetExtensionNumber() const override
Get the extension number.
Ipv6ExtensionAH()
Constructor.
Demultiplexes IPv6 extensions.
Header of IPv6 Extension Destination.
IPv6 Extension Destination.
uint8_t GetExtensionNumber() const override
Get the extension number.
static const uint8_t EXT_NUMBER
Destination extension number.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionDestination() override
Destructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
IPv6 Extension ESP (Encapsulating Security Payload)
~Ipv6ExtensionESP() override
Destructor.
Ipv6ExtensionESP()
Constructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
uint8_t GetExtensionNumber() const override
Get the extension number.
static TypeId GetTypeId()
Get the type identificator.
Ptr< Packet > GetPartialPacket() const
Get the packet parts so far received.
Ptr< Packet > GetPacket() const
Get the entire packet.
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset, bool moreFragment)
Add a fragment.
void SetTimeoutIter(FragmentsTimeoutsListI_t iter)
Set the Timeout iterator.
void SetUnfragmentablePart(Ptr< Packet > unfragmentablePart)
Set the unfragmentable part of the packet.
bool IsEntire() const
If all fragments have been added.
FragmentsTimeoutsListI_t GetTimeoutIter()
Get the Timeout iterator.
Header of IPv6 Extension Fragment.
void SetIdentification(uint32_t identification)
Set the "Identification" field.
void SetOffset(uint16_t offset)
Set the "Offset" field.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint16_t GetOffset() const
Get the field "Offset".
bool GetMoreFragment() const
Get the status of "More Fragment" bit.
uint32_t GetIdentification() const
Get the field "Identification".
void SetMoreFragment(bool moreFragment)
Set the status of "More Fragment" bit.
IPv6 Extension Fragment.
Time m_fragmentExpirationTimeout
Expiration timeout.
void HandleTimeout()
Handles a fragmented packet timeout.
std::list< std::tuple< Time, FragmentKey_t, Ipv6Header > >::iterator FragmentsTimeoutsListI_t
Container Iterator for fragment timeouts.
Ipv6ExtensionFragment()
Constructor.
static TypeId GetTypeId()
Get the type identificator.
void GetFragments(Ptr< Packet > packet, Ipv6Header ipv6Header, uint32_t fragmentSize, std::list< Ipv6PayloadHeaderPair > &listFragments)
Fragment a packet.
std::pair< Ipv6Address, uint32_t > FragmentKey_t
Key identifying a fragmented packet.
EventId m_timeoutEvent
Event for the next scheduled timeout.
MapFragments_t m_fragments
The hash of fragmented packets.
void DoDispose() override
Dispose this object.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
~Ipv6ExtensionFragment() override
Destructor.
FragmentsTimeoutsList_t m_timeoutEventList
Timeout "events" container.
void HandleFragmentsTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Process the timeout for packet fragments.
FragmentsTimeoutsListI_t SetTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Set a new timeout "event" for a fragmented packet.
uint8_t GetExtensionNumber() const override
Get the extension number.
static const uint8_t EXT_NUMBER
Fragmentation extension number.
uint16_t GetLength() const
Get the length of the extension.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
uint8_t GetNextHeader() const
Get the next header.
Header of IPv6 Extension "Hop by Hop".
IPv6 Extension "Hop By Hop".
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionHopByHop() override
Destructor.
Ipv6ExtensionHopByHop()
Constructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
static const uint8_t EXT_NUMBER
Hop-by-hop extension number.
uint8_t GetExtensionNumber() const override
Get the extension number.
IPv6 Extension base If you want to implement a new IPv6 extension, all you have to do is implement a ...
Ptr< Node > GetNode() const
Get the node.
virtual uint8_t ProcessOptions(Ptr< Packet > &packet, uint8_t offset, uint8_t length, const Ipv6Header &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 GetExtensionNumber() const =0
Get the extension number.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< Node > m_node
The node.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< UniformRandomVariable > m_uvar
Provides uniform random variables.
~Ipv6Extension() override
Destructor.
Ipv6Extension()
Constructor.
static TypeId GetTypeId()
Get the type identificator.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
Ipv6Address GetRouterAddress(uint8_t index) const
Get a Router IPv6 Address.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void SetRouterAddress(uint8_t index, Ipv6Address addr)
Set a Router IPv6 Address.
void SetNumberAddress(uint8_t n)
Set the number of routers' address.
IPv6 Extension Loose Routing.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionLooseRouting() override
Destructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
uint8_t GetTypeRouting() const override
Get the type of routing.
IPv6 Extension Routing Demux.
void DoDispose() override
Dispose this object.
void Insert(Ptr< Ipv6ExtensionRouting > extensionRouting)
Insert a new IPv6 Routing Extension.
static TypeId GetTypeId()
The interface ID.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< Ipv6ExtensionRouting > GetExtensionRouting(uint8_t typeRouting)
Get the routing extension corresponding to typeRouting.
void Remove(Ptr< Ipv6ExtensionRouting > extensionRouting)
Remove a routing extension from this demux.
Ipv6ExtensionRoutingList_t m_extensionsRouting
List of IPv6 Routing Extensions supported.
~Ipv6ExtensionRoutingDemux() override
Destructor.
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.
IPv6 Extension Routing.
uint8_t GetExtensionNumber() const override
Get the extension number.
Ipv6ExtensionRouting()
Constructor.
~Ipv6ExtensionRouting() override
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
Packet header for IPv6.
Definition: ipv6-header.h:36
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:118
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:100
uint8_t GetNextHeader() const
Get the next header.
Definition: ipv6-header.cc:88
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:94
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:70
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: ipv6-header.cc:159
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Definition: ipv6-header.cc:165
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
Definition: ipv6-header.cc:182
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:82
IPv6 layer implementation.
DropReason
Reason why a packet has been dropped.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_MALFORMED_HEADER
Malformed header.
IPv6 Option Demux.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
uint32_t GetOptionsOffset() const
Get the offset where the options begin, measured from the start of the extension header.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:376
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:384
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:238
void Print(std::ostream &os) const
Print the packet contents.
Definition: packet.cc:456
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
Definition: second.py:1
#define list
uint8_t data[writeSize]