A Discrete-Event Network Simulator
API
ipv6-extension.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: David Gross <gdavid.devel@gmail.com>
19  */
20 
21 #include <list>
22 #include <ctime>
23 
24 #include "ns3/log.h"
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"
35 #include "icmpv6-l4-protocol.h"
36 #include "ipv6-extension-demux.h"
37 #include "ipv6-extension.h"
38 #include "ipv6-extension-header.h"
39 #include "ipv6-option-demux.h"
40 #include "ipv6-option.h"
41 #include "udp-header.h"
42 
43 namespace ns3 {
44 
45 NS_LOG_COMPONENT_DEFINE ("Ipv6Extension");
46 
47 NS_OBJECT_ENSURE_REGISTERED (Ipv6Extension);
48 
50 {
51  static TypeId tid = TypeId ("ns3::Ipv6Extension")
52  .SetParent<Object> ()
53  .SetGroupName ("Internet")
54  .AddAttribute ("ExtensionNumber", "The IPv6 extension number.",
55  UintegerValue (0),
57  MakeUintegerChecker<uint8_t> ())
58  ;
59  return tid;
60 }
61 
63 {
64  m_uvar = CreateObject<UniformRandomVariable> ();
65 }
66 
68 {
69 }
70 
72 {
73  NS_LOG_FUNCTION (this << node);
74 
75  m_node = node;
76 }
77 
79 {
80  return m_node;
81 }
82 
84  uint8_t offset,
85  uint8_t length,
86  Ipv6Header const& ipv6Header,
87  Ipv6Address dst,
88  uint8_t *nextHeader,
89  bool& stopProcessing,
90  bool& isDropped,
91  Ipv6L3Protocol::DropReason& dropReason)
92 {
93  NS_LOG_FUNCTION (this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
94 
95  // For ICMPv6 Error packets
96  Ptr<Packet> malformedPacket = packet->Copy ();
97  malformedPacket->AddHeader (ipv6Header);
98  Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
99 
100  Ptr<Packet> p = packet->Copy ();
101  p->RemoveAtStart (offset);
102 
103  Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
104  Ptr<Ipv6Option> ipv6Option;
105 
106  uint8_t processedSize = 0;
107  uint32_t size = p->GetSize ();
108  uint8_t *data = new uint8_t[size];
109  p->CopyData (data, size);
110 
111  uint8_t optionType = 0;
112  uint8_t optionLength = 0;
113 
114  while (length > processedSize && !isDropped)
115  {
116  optionType = *(data + processedSize);
117  ipv6Option = ipv6OptionDemux->GetOption (optionType);
118 
119  if (ipv6Option == 0)
120  {
121  optionType >>= 6;
122  switch (optionType)
123  {
124  case 0:
125  optionLength = *(data + processedSize + 1) + 2;
126  break;
127 
128  case 1:
129  NS_LOG_LOGIC ("Unknown Option. Drop!");
130  optionLength = 0;
131  isDropped = true;
132  stopProcessing = true;
134  break;
135 
136  case 2:
137  NS_LOG_LOGIC ("Unknown Option. Drop!");
138  icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSource (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
139  optionLength = 0;
140  isDropped = true;
141  stopProcessing = true;
143  break;
144 
145  case 3:
146  NS_LOG_LOGIC ("Unknown Option. Drop!");
147 
148  if (!ipv6Header.GetDestination ().IsMulticast ())
149  {
150  icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSource (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
151  }
152  optionLength = 0;
153  isDropped = true;
154  stopProcessing = true;
156  break;
157 
158  default:
159  break;
160  }
161 
162  }
163  else
164  {
165  optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
166  }
167 
168  processedSize += optionLength;
169  p->RemoveAtStart (optionLength);
170  }
171 
172  delete [] data;
173 
174  return processedSize;
175 }
176 
177 int64_t
179 {
180  NS_LOG_FUNCTION (this << stream);
181  m_uvar->SetStream (stream);
182  return 1;
183 }
184 
186 
188 {
189  static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHop")
191  .SetGroupName ("Internet")
192  .AddConstructor<Ipv6ExtensionHopByHop> ()
193  ;
194  return tid;
195 }
196 
198 {
199 }
200 
202 {
203 }
204 
206 {
207  return EXT_NUMBER;
208 }
209 
211  uint8_t offset,
212  Ipv6Header const& ipv6Header,
213  Ipv6Address dst,
214  uint8_t *nextHeader,
215  bool& stopProcessing,
216  bool& isDropped,
217  Ipv6L3Protocol::DropReason& dropReason)
218 {
219  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
220 
221  Ptr<Packet> p = packet->Copy ();
222  p->RemoveAtStart (offset);
223 
224  Ipv6ExtensionHopByHopHeader hopbyhopHeader;
225  p->RemoveHeader (hopbyhopHeader);
226  if (nextHeader)
227  {
228  *nextHeader = hopbyhopHeader.GetNextHeader ();
229  }
230 
231  uint8_t processedSize = hopbyhopHeader.GetOptionsOffset ();
232  offset += processedSize;
233  uint8_t length = hopbyhopHeader.GetLength () - hopbyhopHeader.GetOptionsOffset ();
234 
235  processedSize += ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
236 
237  return processedSize;
238 }
239 
240 
242 
244 {
245  static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestination")
247  .SetGroupName ("Internet")
248  .AddConstructor<Ipv6ExtensionDestination> ()
249  ;
250  return tid;
251 }
252 
254 {
255 }
256 
258 {
259 }
260 
262 {
263  return EXT_NUMBER;
264 }
265 
267  uint8_t offset,
268  Ipv6Header const& ipv6Header,
269  Ipv6Address dst,
270  uint8_t *nextHeader,
271  bool& stopProcessing,
272  bool& isDropped,
273  Ipv6L3Protocol::DropReason& dropReason)
274 {
275  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
276 
277  Ptr<Packet> p = packet->Copy ();
278  p->RemoveAtStart (offset);
279 
280  Ipv6ExtensionDestinationHeader destinationHeader;
281  p->RemoveHeader (destinationHeader);
282  if (nextHeader)
283  {
284  *nextHeader = destinationHeader.GetNextHeader ();
285  }
286 
287  uint8_t processedSize = destinationHeader.GetOptionsOffset ();
288  offset += processedSize;
289  uint8_t length = destinationHeader.GetLength () - destinationHeader.GetOptionsOffset ();
290 
291  processedSize += ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, stopProcessing, isDropped, dropReason);
292 
293  return processedSize;
294 }
295 
296 
298 
300 {
301  static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragment")
303  .SetGroupName ("Internet")
304  .AddConstructor<Ipv6ExtensionFragment> ()
305  .AddAttribute ("FragmentExpirationTimeout",
306  "When this timeout expires, the fragments "
307  "will be cleared from the buffer.",
308  TimeValue (Seconds (60)),
310  MakeTimeChecker ())
311  ;
312  return tid;
313 }
314 
316 {
317 }
318 
320 {
321 }
322 
324 {
325  NS_LOG_FUNCTION (this);
326 
327  for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
328  {
329  it->second = 0;
330  }
331 
332  m_fragments.clear ();
333  m_timeoutEventList.clear ();
334  if (m_timeoutEvent.IsRunning ())
335  {
337  }
339 }
340 
342 {
343  return EXT_NUMBER;
344 }
345 
347  uint8_t offset,
348  Ipv6Header const& ipv6Header,
349  Ipv6Address dst,
350  uint8_t *nextHeader,
351  bool& stopProcessing,
352  bool& isDropped,
353  Ipv6L3Protocol::DropReason& dropReason)
354 {
355  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
356 
357  Ptr<Packet> p = packet->Copy ();
358  p->RemoveAtStart (offset);
359 
360  Ipv6ExtensionFragmentHeader fragmentHeader;
361  p->RemoveHeader (fragmentHeader);
362 
363  if (nextHeader)
364  {
365  *nextHeader = fragmentHeader.GetNextHeader ();
366  }
367 
368  bool moreFragment = fragmentHeader.GetMoreFragment ();
369  uint16_t fragmentOffset = fragmentHeader.GetOffset ();
370  uint32_t identification = fragmentHeader.GetIdentification ();
371  Ipv6Address src = ipv6Header.GetSource ();
372 
373  FragmentKey_t fragmentKey = FragmentKey_t (src, identification);
374  Ptr<Fragments> fragments;
375 
376  Ipv6Header ipHeader = ipv6Header;
377  ipHeader.SetNextHeader (fragmentHeader.GetNextHeader ());
378 
379  MapFragments_t::iterator it = m_fragments.find (fragmentKey);
380  if (it == m_fragments.end ())
381  {
382  fragments = Create<Fragments> ();
383  m_fragments.insert (std::make_pair (fragmentKey, fragments));
384  NS_LOG_DEBUG ("Insert new fragment key: src: " << src << " IP hdr id " << identification << " m_fragments.size() " << m_fragments.size () << " offset " << fragmentOffset);
385  FragmentsTimeoutsListI_t iter = SetTimeout (fragmentKey, ipHeader);
386  fragments->SetTimeoutIter (iter);
387  }
388  else
389  {
390  fragments = it->second;
391  }
392 
393  if (fragmentOffset == 0)
394  {
395  Ptr<Packet> unfragmentablePart = packet->Copy ();
396  unfragmentablePart->RemoveAtEnd (packet->GetSize () - offset);
397  fragments->SetUnfragmentablePart (unfragmentablePart);
398  }
399 
400  NS_LOG_DEBUG ("Add fragment with IP hdr id " << identification << " offset " << fragmentOffset);
401  fragments->AddFragment (p, fragmentOffset, moreFragment);
402 
403  if (fragments->IsEntire ())
404  {
405  packet = fragments->GetPacket ();
406  m_timeoutEventList.erase (fragments->GetTimeoutIter ());
407  m_fragments.erase (fragmentKey);
408  NS_LOG_DEBUG ("Finished fragment with IP hdr id " << fragmentKey.second << " erase timeout, m_fragments.size(): " << m_fragments.size ());
409  stopProcessing = false;
410  }
411  else
412  {
413  stopProcessing = true;
414  }
415 
416  return 0;
417 }
418 
419 void Ipv6ExtensionFragment::GetFragments (Ptr<Packet> packet, Ipv6Header ipv6Header, uint32_t maxFragmentSize, std::list<Ipv6PayloadHeaderPair>& listFragments)
420 {
421  NS_LOG_FUNCTION (this << packet << ipv6Header << maxFragmentSize);
422  Ptr<Packet> p = packet->Copy ();
423 
424  uint8_t nextHeader = ipv6Header.GetNextHeader ();
425  uint8_t ipv6HeaderSize = ipv6Header.GetSerializedSize ();
426 
427  uint8_t type;
428  p->CopyData (&type, sizeof(type));
429 
430  bool moreHeader = true;
431  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
432  || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
433  {
434  moreHeader = false;
436  }
437 
438  std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
439  uint32_t unfragmentablePartSize = 0;
440 
442  Ptr<Ipv6Extension> extension = extensionDemux->GetExtension (nextHeader);
443  uint8_t extensionHeaderLength;
444 
445  while (moreHeader)
446  {
447  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
448  {
450  p->RemoveHeader (*hopbyhopHeader);
451 
452  nextHeader = hopbyhopHeader->GetNextHeader ();
453  extensionHeaderLength = hopbyhopHeader->GetLength ();
454 
455  uint8_t type;
456  p->CopyData (&type, sizeof(type));
457 
458  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
459  || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
460  {
461  moreHeader = false;
463  }
464 
465  unfragmentablePart.emplace_back (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP);
466  unfragmentablePartSize += extensionHeaderLength;
467  }
468  else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
469  {
470  uint8_t buf[2];
471  p->CopyData (buf, sizeof(buf));
472  uint8_t numberAddress = buf[1] / 2;
474  routingHeader->SetNumberAddress (numberAddress);
475  p->RemoveHeader (*routingHeader);
476 
477  nextHeader = routingHeader->GetNextHeader ();
478  extensionHeaderLength = routingHeader->GetLength ();
479 
480  uint8_t type;
481  p->CopyData (&type, sizeof(type));
482  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
483  || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
484  {
485  moreHeader = false;
487  }
488 
489  unfragmentablePart.emplace_back (routingHeader, Ipv6Header::IPV6_EXT_ROUTING);
490  unfragmentablePartSize += extensionHeaderLength;
491  }
492  else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
493  {
495  p->RemoveHeader (*destinationHeader);
496 
497  nextHeader = destinationHeader->GetNextHeader ();
498  extensionHeaderLength = destinationHeader->GetLength ();
499 
500  uint8_t type;
501  p->CopyData (&type, sizeof(type));
502  if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
503  || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
504  {
505  moreHeader = false;
507  }
508 
509  unfragmentablePart.emplace_back (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION);
510  unfragmentablePartSize += extensionHeaderLength;
511  }
512  }
513 
514  Ipv6ExtensionFragmentHeader fragmentHeader;
515  uint8_t fragmentHeaderSize = fragmentHeader.GetSerializedSize ();
516 
517  uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
518  uint32_t currentFragmentablePartSize = 0;
519 
520  bool moreFragment = true;
521  uint32_t identification = (uint32_t) m_uvar->GetValue (0, (uint32_t)-1);
522  uint16_t offset = 0;
523 
524  do
525  {
526  if (p->GetSize () > offset + maxFragmentablePartSize)
527  {
528  moreFragment = true;
529  currentFragmentablePartSize = maxFragmentablePartSize;
530  currentFragmentablePartSize -= currentFragmentablePartSize % 8;
531  }
532  else
533  {
534  moreFragment = false;
535  currentFragmentablePartSize = p->GetSize () - offset;
536  }
537 
538 
539  fragmentHeader.SetNextHeader (nextHeader);
540  fragmentHeader.SetOffset (offset);
541  fragmentHeader.SetMoreFragment (moreFragment);
542  fragmentHeader.SetIdentification (identification);
543 
544  Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
545  offset += currentFragmentablePartSize;
546 
547  fragment->AddHeader (fragmentHeader);
548 
549  for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
550  {
551  if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
552  {
554  dynamic_cast<Ipv6ExtensionHopByHopHeader *> (it->first);
555  NS_ASSERT (p != 0);
556  fragment->AddHeader (*p);
557  }
558  else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
559  {
561  dynamic_cast<Ipv6ExtensionLooseRoutingHeader *> (it->first);
562  NS_ASSERT (p != 0);
563  fragment->AddHeader (*p);
564  }
565  else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
566  {
568  dynamic_cast<Ipv6ExtensionDestinationHeader *> (it->first);
569  NS_ASSERT (p != 0);
570  fragment->AddHeader (*p);
571  }
572  }
573 
574  ipv6Header.SetPayloadLength (fragment->GetSize ());
575 
576  std::ostringstream oss;
577  oss << ipv6Header;
578  fragment->Print (oss);
579 
580  listFragments.emplace_back (fragment, ipv6Header);
581  }
582  while (moreFragment);
583 
584  for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
585  {
586  delete it->first;
587  }
588 
589  unfragmentablePart.clear ();
590 }
591 
592 
594  Ipv6Header ipHeader)
595 {
596  NS_LOG_FUNCTION (this << fragmentKey.first << fragmentKey.second << ipHeader);
597  Ptr<Fragments> fragments;
598 
599  MapFragments_t::iterator it = m_fragments.find (fragmentKey);
600  NS_ASSERT_MSG(it != m_fragments.end (), "IPv6 Fragment timeout reached for non-existent fragment");
601  fragments = it->second;
602 
603  Ptr<Packet> packet = fragments->GetPartialPacket ();
604 
605  // if we have at least 8 bytes, we can send an ICMP.
606  if (packet && packet->GetSize () > 8)
607  {
608  Ptr<Packet> p = packet->Copy ();
609  p->AddHeader (ipHeader);
611  icmp->SendErrorTimeExceeded (p, ipHeader.GetSource (), Icmpv6Header::ICMPV6_FRAGTIME);
612  }
613 
615  ipL3->ReportDrop (ipHeader, packet, Ipv6L3Protocol::DROP_FRAGMENT_TIMEOUT);
616 
617  // clear the buffers
618  m_fragments.erase (fragmentKey);
619 }
620 
621 
623 {
624  NS_LOG_FUNCTION (this << key.first << key.second << ipHeader);
625  if (m_timeoutEventList.empty ())
626  {
627  NS_LOG_DEBUG ("Scheduling timeout for IP hdr id " << key.second << " at time " << (Simulator::Now () + m_fragmentExpirationTimeout).GetSeconds ());
629  }
630  NS_LOG_DEBUG ("Adding timeout at " << (Simulator::Now () + m_fragmentExpirationTimeout).GetSeconds () << " with key " << key.second);
631  m_timeoutEventList.emplace_back (Simulator::Now () + m_fragmentExpirationTimeout, key, ipHeader);
632 
634 
635  return (iter);
636 }
637 
639 {
640  NS_LOG_FUNCTION (this);
641  Time now = Simulator::Now ();
642 
643  // std::list Time, Fragment_key_t, Ipv6Header
644  // Fragment key is a pair: Ipv6Address, uint32_t ipHeaderId
645  for (auto & element : m_timeoutEventList)
646  {
647  NS_LOG_DEBUG ("Handle time " << std::get<0> (element).GetSeconds () << " IP hdr id " << std::get<1> (element).second);
648  }
649  while (!m_timeoutEventList.empty () && std::get<0> (*m_timeoutEventList.begin ()) == now)
650  {
651  HandleFragmentsTimeout (std::get<1> (*m_timeoutEventList.begin ()),
652  std::get<2> (*m_timeoutEventList.begin ()));
653  m_timeoutEventList.pop_front ();
654  }
655 
656  if (m_timeoutEventList.empty ())
657  {
658  return;
659  }
660 
661  Time difference = std::get<0> (*m_timeoutEventList.begin ()) - now;
662  NS_LOG_DEBUG ("Scheduling later HandleTimeout at " << (now + difference).GetSeconds ());
664 
665  return;
666 }
667 
668 
669 
671  : m_moreFragment (0)
672 {
673 }
674 
676 {
677 }
678 
679 void Ipv6ExtensionFragment::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
680 {
681  NS_LOG_FUNCTION (this << fragment << fragmentOffset << moreFragment);
682  std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
683 
684  for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
685  {
686  if (it->second > fragmentOffset)
687  {
688  break;
689  }
690  }
691 
692  if (it == m_packetFragments.end ())
693  {
694  m_moreFragment = moreFragment;
695  }
696 
697  m_packetFragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
698 }
699 
701 {
702  NS_LOG_FUNCTION (this << unfragmentablePart);
703  m_unfragmentable = unfragmentablePart;
704 }
705 
707 {
708  bool ret = !m_moreFragment && m_packetFragments.size () > 0;
709 
710  if (ret)
711  {
712  uint16_t lastEndOffset = 0;
713 
714  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
715  {
716  if (lastEndOffset != it->second)
717  {
718  ret = false;
719  break;
720  }
721 
722  lastEndOffset += it->first->GetSize ();
723  }
724  }
725 
726  return ret;
727 }
728 
730 {
731  Ptr<Packet> p = m_unfragmentable->Copy ();
732 
733  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
734  {
735  p->AddAtEnd (it->first);
736  }
737 
738  return p;
739 }
740 
742 {
743  Ptr<Packet> p;
744 
745  if ( m_unfragmentable )
746  {
747  p = m_unfragmentable->Copy ();
748  }
749  else
750  {
751  return p;
752  }
753 
754  uint16_t lastEndOffset = 0;
755 
756  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
757  {
758  if (lastEndOffset != it->second)
759  {
760  break;
761  }
762  p->AddAtEnd (it->first);
763  lastEndOffset += it->first->GetSize ();
764  }
765 
766  return p;
767 }
768 
770 {
771  NS_LOG_FUNCTION (this);
772  m_timeoutIter = iter;
773  return;
774 }
775 
777 {
778  return m_timeoutIter;
779 }
780 
781 
783 
785 {
786  static TypeId tid = TypeId ("ns3::Ipv6ExtensionRouting")
788  .SetGroupName ("Internet")
789  .AddConstructor<Ipv6ExtensionRouting> ()
790  ;
791  return tid;
792 }
793 
795 {
796 }
797 
799 {
800 }
801 
803 {
804  return EXT_NUMBER;
805 }
806 
808 {
809  return 0;
810 }
811 
813  uint8_t offset,
814  Ipv6Header const& ipv6Header,
815  Ipv6Address dst,
816  uint8_t *nextHeader,
817  bool& stopProcessing,
818  bool& isDropped,
819  Ipv6L3Protocol::DropReason& dropReason)
820 {
821  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
822 
823  // For ICMPv6 Error Packets
824  Ptr<Packet> malformedPacket = packet->Copy ();
825  malformedPacket->AddHeader (ipv6Header);
826 
827  Ptr<Packet> p = packet->Copy ();
828  p->RemoveAtStart (offset);
829 
830  uint8_t buf[4];
831  packet->CopyData (buf, sizeof(buf));
832 
833  uint8_t routingNextHeader = buf[0];
834  uint8_t routingLength = buf[1];
835  uint8_t routingTypeRouting = buf[2];
836  uint8_t routingSegmentsLeft = buf[3];
837 
838  if (nextHeader)
839  {
840  *nextHeader = routingNextHeader;
841  }
842 
843  Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
844 
846  Ptr<Ipv6ExtensionRouting> ipv6ExtensionRouting = ipv6ExtensionRoutingDemux->GetExtensionRouting (routingTypeRouting);
847 
848  if (ipv6ExtensionRouting == 0)
849  {
850  if (routingSegmentsLeft == 0)
851  {
852  isDropped = false;
853  }
854  else
855  {
856  NS_LOG_LOGIC ("Malformed header. Drop!");
857 
858  icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSource (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
860  isDropped = true;
861  stopProcessing = true;
862  }
863 
864  return routingLength;
865  }
866 
867  return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, stopProcessing, isDropped, dropReason);
868 }
869 
870 
872 
874 {
875  static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingDemux")
876  .SetParent<Object> ()
877  .SetGroupName ("Internet")
878  .AddAttribute ("RoutingExtensions", "The set of IPv6 Routing extensions registered with this demux.",
881  MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
882  ;
883  return tid;
884 }
885 
887 {
888 }
889 
891 {
892 }
893 
895 {
896  NS_LOG_FUNCTION (this);
897  for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
898  {
899  (*it)->Dispose ();
900  *it = 0;
901  }
902  m_extensionsRouting.clear ();
903  m_node = 0;
905 }
906 
908 {
909  NS_LOG_FUNCTION (this << node);
910  m_node = node;
911 }
912 
914 {
915  NS_LOG_FUNCTION (this << extensionRouting);
916  m_extensionsRouting.push_back (extensionRouting);
917 }
918 
920 {
921  for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
922  {
923  if ((*i)->GetTypeRouting () == typeRouting)
924  {
925  return *i;
926  }
927  }
928  return 0;
929 }
930 
932 {
933  NS_LOG_FUNCTION (this << extensionRouting);
934  m_extensionsRouting.remove (extensionRouting);
935 }
936 
937 
939 
941 {
942  static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRouting")
944  .SetGroupName ("Internet")
945  .AddConstructor<Ipv6ExtensionLooseRouting> ()
946  ;
947  return tid;
948 }
949 
951 {
952 }
953 
955 {
956 }
957 
959 {
960  return TYPE_ROUTING;
961 }
962 
964  uint8_t offset,
965  Ipv6Header const& ipv6Header,
966  Ipv6Address dst,
967  uint8_t *nextHeader,
968  bool& stopProcessing,
969  bool& isDropped,
970  Ipv6L3Protocol::DropReason& dropReason)
971 {
972  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
973 
974  // For ICMPv6 Error packets
975  Ptr<Packet> malformedPacket = packet->Copy ();
976  malformedPacket->AddHeader (ipv6Header);
977 
978  Ptr<Packet> p = packet->Copy ();
979  p->RemoveAtStart (offset);
980 
981  // Copy IPv6 Header : ipv6Header -> ipv6header
982  Buffer tmp;
983  tmp.AddAtStart (ipv6Header.GetSerializedSize ());
984  Buffer::Iterator it = tmp.Begin ();
985  Ipv6Header ipv6header;
986  ipv6Header.Serialize (it);
987  ipv6header.Deserialize (it);
988 
989  // Get the number of routers' address field
990  uint8_t buf[2];
991  p->CopyData (buf, sizeof(buf));
992  uint8_t numberAddress = buf[1] / 2;
993  Ipv6ExtensionLooseRoutingHeader routingHeader;
994  routingHeader.SetNumberAddress (numberAddress);
995  p->RemoveHeader (routingHeader);
996 
997  if (nextHeader)
998  {
999  *nextHeader = routingHeader.GetNextHeader ();
1000  }
1001 
1002  Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
1003 
1004  Ipv6Address srcAddress = ipv6header.GetSource ();
1005  Ipv6Address destAddress = ipv6header.GetDestination ();
1006  uint8_t hopLimit = ipv6header.GetHopLimit ();
1007  uint8_t segmentsLeft = routingHeader.GetSegmentsLeft ();
1008  uint8_t length = (routingHeader.GetLength () >> 3) - 1;
1009  uint8_t nbAddress = length / 2;
1010  uint8_t nextAddressIndex;
1011  Ipv6Address nextAddress;
1012 
1013  if (segmentsLeft == 0)
1014  {
1015  isDropped = false;
1016  return routingHeader.GetSerializedSize ();
1017  }
1018 
1019  if (length % 2 != 0)
1020  {
1021  NS_LOG_LOGIC ("Malformed header. Drop!");
1022  icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
1024  isDropped = true;
1025  stopProcessing = true;
1026  return routingHeader.GetSerializedSize ();
1027  }
1028 
1029  if (segmentsLeft > nbAddress)
1030  {
1031  NS_LOG_LOGIC ("Malformed header. Drop!");
1032  icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3);
1034  isDropped = true;
1035  stopProcessing = true;
1036  return routingHeader.GetSerializedSize ();
1037  }
1038 
1039  routingHeader.SetSegmentsLeft (segmentsLeft - 1);
1040  nextAddressIndex = nbAddress - segmentsLeft;
1041  nextAddress = routingHeader.GetRouterAddress (nextAddressIndex);
1042 
1043  if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
1044  {
1046  isDropped = true;
1047  stopProcessing = true;
1048  return routingHeader.GetSerializedSize ();
1049  }
1050 
1051  routingHeader.SetRouterAddress (nextAddressIndex, destAddress);
1052  ipv6header.SetDestination (nextAddress);
1053 
1054  if (hopLimit <= 1)
1055  {
1056  NS_LOG_LOGIC ("Time Exceeded : Hop Limit <= 1. Drop!");
1057  icmpv6->SendErrorTimeExceeded (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT);
1059  isDropped = true;
1060  stopProcessing = true;
1061  return routingHeader.GetSerializedSize ();
1062  }
1063 
1064  ipv6header.SetHopLimit (hopLimit - 1);
1065  p->AddHeader (routingHeader);
1066 
1067  /* short-circuiting routing stuff
1068  *
1069  * If we process this option,
1070  * the packet was for us so we resend it to
1071  * the new destination (modified in the header above).
1072  */
1073 
1075  Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
1076  Socket::SocketErrno err;
1077  NS_ASSERT (ipv6rp);
1078 
1079  Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
1080 
1081  if (rtentry)
1082  {
1083  /* we know a route exists so send packet now */
1084  ipv6->SendRealOut (rtentry, p, ipv6header);
1085  }
1086  else
1087  {
1088  NS_LOG_INFO ("No route for next router");
1089  }
1090 
1091  /* as we directly send packet, mark it as dropped */
1092  isDropped = true;
1093 
1094  return routingHeader.GetSerializedSize ();
1095 }
1096 
1097 
1099 
1101 {
1102  static TypeId tid = TypeId ("ns3::Ipv6ExtensionESP")
1104  .SetGroupName ("Internet")
1105  .AddConstructor<Ipv6ExtensionESP> ()
1106  ;
1107  return tid;
1108 }
1109 
1111 {
1112 }
1113 
1115 {
1116 }
1117 
1119 {
1120  return EXT_NUMBER;
1121 }
1122 
1124  uint8_t offset,
1125  Ipv6Header const& ipv6Header,
1126  Ipv6Address dst,
1127  uint8_t *nextHeader,
1128  bool& stopProcessing,
1129  bool& isDropped,
1130  Ipv6L3Protocol::DropReason& dropReason)
1131 {
1132  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1133 
1136  return 0;
1137 }
1138 
1139 
1141 
1143 {
1144  static TypeId tid = TypeId ("ns3::Ipv6ExtensionAH")
1146  .SetGroupName ("Internet")
1147  .AddConstructor<Ipv6ExtensionAH> ()
1148  ;
1149  return tid;
1150 }
1151 
1153 {
1154 }
1155 
1157 {
1158 }
1159 
1161 {
1162  return EXT_NUMBER;
1163 }
1164 
1166  uint8_t offset,
1167  Ipv6Header const& ipv6Header,
1168  Ipv6Address dst,
1169  uint8_t *nextHeader,
1170  bool& stopProcessing,
1171  bool& isDropped,
1172  Ipv6L3Protocol::DropReason& dropReason)
1173 {
1174  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
1175 
1178  return true;
1179 }
1180 
1181 } /* namespace ns3 */
1182 
iterator in a Buffer instance
Definition: buffer.h:99
automatically resized byte buffer
Definition: buffer.h:93
void AddAtStart(uint32_t start)
Definition: buffer.cc:309
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
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)
virtual uint8_t GetExtensionNumber() const
Get the extension number.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionAH()
Destructor.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
Ipv6ExtensionAH()
Constructor.
Demultiplexes IPv6 extensions.
Header of IPv6 Extension Destination.
IPv6 Extension Destination.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
static const uint8_t EXT_NUMBER
Destination extension number.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
IPv6 Extension ESP (Encapsulating Security Payload)
Ipv6ExtensionESP()
Constructor.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
~Ipv6ExtensionESP()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
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.
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.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
IPv6 Extension Fragment.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Time m_fragmentExpirationTimeout
Expiration 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.
virtual void DoDispose()
Dispose this object.
EventId m_timeoutEvent
Event for the next scheduled timeout.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
MapFragments_t m_fragments
The hash of fragmented packets.
void HandleTimeout(void)
Handles a fragmented packet timeout.
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.
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.
virtual uint8_t Process(Ptr< Packet > &packet, uint8_t offset, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ipv6ExtensionHopByHop()
Constructor.
static const uint8_t EXT_NUMBER
Hop-by-hop 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 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()
Constructor.
virtual ~Ipv6Extension()
Destructor.
virtual uint8_t ProcessOptions(Ptr< Packet > &packet, uint8_t offset, uint8_t length, Ipv6Header const &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process options Called by implementing classes to process the options.
static TypeId GetTypeId()
Get the type identificator.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
Ipv6Address GetRouterAddress(uint8_t index) const
Get a Router IPv6 Address.
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.
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 &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process method Called from Ipv6L3Protocol::Receive.
IPv6 Extension Routing Demux.
virtual void DoDispose()
Dispose this object.
virtual ~Ipv6ExtensionRoutingDemux()
Destructor.
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.
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.
IPv6 Extension Routing.
virtual uint8_t GetExtensionNumber() const
Get the extension number.
Ipv6ExtensionRouting()
Constructor.
~Ipv6ExtensionRouting()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
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 &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
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:115
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:90
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:163
uint8_t GetNextHeader(void) const
Get the next header.
Definition: ipv6-header.cc:80
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:85
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:65
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Definition: ipv6-header.cc:168
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
Definition: ipv6-header.cc:184
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:75
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:88
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
Container for a set of ns3::Object pointers.
uint32_t GetOptionsOffset()
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:280
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
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:227
void Print(std::ostream &os) const
Print the packet contents.
Definition: packet.cc:434
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#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:88
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
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:1309
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:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
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:522
Definition: second.py:1
#define list
uint8_t data[writeSize]