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"
37#include "ipv6-extension.h"
39#include "ipv6-option-demux.h"
40#include "ipv6-option.h"
41#include "udp-header.h"
42
43namespace ns3 {
44
45NS_LOG_COMPONENT_DEFINE ("Ipv6Extension");
46
47NS_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,
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
177int64_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)),
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 ();
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
419void 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
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
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
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
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
679void 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;
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 ();
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.
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.
std::list< std::tuple< Time, FragmentKey_t, Ipv6Header > >::iterator FragmentsTimeoutsListI_t
Container Iterator for fragment timeouts.
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)
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
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:536
Definition: second.py:1
#define list
uint8_t data[writeSize]