A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
sixlowpan-nd-header.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Università di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 *
7 *
8 * Author: Alessio Bonadio <alessio.bonadio@gmail.com>
9 * Tommaso Pecorella <tommaso.pecorella@unifi.it>
10 * Adnan Rashid <adnanrashidpk@gmail.com>
11 */
12
13#include "sixlowpan-nd-header.h"
14
15#include "ns3/address-utils.h"
16#include "ns3/assert.h"
17#include "ns3/log.h"
18
19#include <ios>
20#include <utility>
21
22namespace ns3
23{
24
25NS_LOG_COMPONENT_DEFINE("SixLowPanNdHeader");
26
28
38
51
65
67 uint8_t status,
68 uint16_t time,
69 std::vector<uint8_t> rovr,
70 Ipv6Address address)
71{
72 NS_LOG_FUNCTION(this);
74 SetChecksum(0);
75 m_status = status;
76 m_regTime = time;
77 SetRovr(rovr);
78 m_regAddress = address;
79}
80
86
89{
90 static TypeId tid = TypeId("ns3::Icmpv6DuplicateAddress")
92 .SetGroupName("Internet")
94 return tid;
95}
96
103
104uint8_t
110
111void
113{
114 NS_LOG_FUNCTION(this << static_cast<uint32_t>(status));
115 m_status = status;
116}
117
118uint16_t
124
125void
127{
128 NS_LOG_FUNCTION(this << time);
129 m_regTime = time;
130}
131
132std::vector<uint8_t>
138
139void
141{
142 NS_LOG_FUNCTION(this);
143
144 uint8_t rovrLength = rovr.size();
145 NS_ASSERT_MSG((rovrLength == 8) || (rovrLength == 16) || (rovrLength == 24) ||
146 (rovrLength == 32),
147 "ROVR length must be 64, 128, 192, or 256 bits");
148
149 m_rovr = std::move(rovr);
150}
151
158
159void
165
166void
168{
169 NS_LOG_FUNCTION(this << &os);
170
171 std::ios oldState(nullptr);
172 oldState.copyfmt(os);
173 uint8_t rovrLength = m_rovr.size();
174
175 os << "( type = " << (uint32_t)GetType() << " status " << (uint32_t)m_status << " TID " << m_tid
176 << " lifetime " << m_regTime << " ROVR len " << rovrLength;
177 for (uint8_t index = 0; index < rovrLength; index++)
178 {
179 os << std::hex << m_rovr[index];
180 }
181 os << ")";
182
183 os.copyfmt(oldState);
184}
185
192
193void
195{
196 NS_LOG_FUNCTION(this << &start);
197 Buffer::Iterator i = start;
198
199 i.WriteU8(GetType());
200 i.WriteU8(m_status);
201
202 // note: codePfx is always zero, ROVR size is a multiple of 8 bytes, and less than 32 bytes.
203 uint8_t codeSfx = m_rovr.size() / 8;
204 i.WriteU8(codeSfx);
205
207 i.WriteU8(m_status);
208 i.WriteU8(m_tid);
210
211 for (const auto& rovr : m_rovr)
212 {
213 i.WriteU8(rovr);
214 }
215}
216
219{
220 NS_LOG_FUNCTION(this << &start);
221 Buffer::Iterator i = start;
222
223 SetType(i.ReadU8());
224 uint8_t codePSfx = i.ReadU8();
225 if (codePSfx > 4)
226 {
227 NS_LOG_LOGIC("Invalid CodeSfx or CodePfx value (" << codePSfx << "), discarding message");
228 return 0;
229 }
230 uint8_t rovrLength = codePSfx * 8;
231
232 m_status = i.ReadU8();
233 i.Next(3);
234 m_regTime = i.ReadU16();
235
236 m_rovr.clear();
237 for (uint8_t index = 0; index < rovrLength; index++)
238 {
239 m_rovr.push_back(i.ReadU8());
240 }
241
242 return GetSerializedSize();
243}
244
246
259
261 uint16_t time,
262 const std::vector<uint8_t>& rovr,
263 uint8_t tid)
264{
265 NS_LOG_FUNCTION(this);
267 SetLength(1 + rovr.size() / 8);
268 m_status = 0;
269 m_opaque = 0;
270 m_i = 0;
271 m_flagR = false;
272 m_tid = tid;
273 m_regTime = time;
274 SetRovr(rovr);
275}
276
278 uint8_t status,
279 uint16_t time,
280 const std::vector<uint8_t>& rovr,
281 uint8_t tid)
282{
283 NS_LOG_FUNCTION(this);
285 SetLength(1 + rovr.size() / 8);
286 m_status = status;
287 m_opaque = 0;
288 m_i = 0;
289 m_flagR = false;
290 m_tid = tid;
291 m_regTime = time;
292 SetRovr(rovr);
293}
294
300
301TypeId
303{
304 static TypeId tid = TypeId("ns3::Icmpv6OptionAddressRegistration")
306 .SetGroupName("Internet")
308 return tid;
309}
310
311TypeId
317
318uint8_t
324
325void
327{
328 NS_LOG_FUNCTION(this << static_cast<uint32_t>(status));
329 m_status = status;
330}
331
332uint8_t
338
339void
341{
342 NS_LOG_FUNCTION(this << static_cast<uint32_t>(opaque));
343 m_opaque = opaque;
344}
345
346uint8_t
353
354void
356{
357 if (twobit > 3)
358 {
359 NS_LOG_FUNCTION(this << static_cast<uint32_t>(twobit));
360 return;
361 }
362 m_i = twobit;
363}
364
365bool
371
372void
378
379uint8_t
385
386void
392
393uint16_t
399
400void
402{
403 NS_LOG_FUNCTION(this << time);
404 m_regTime = time;
405}
406
407std::vector<uint8_t>
413
414void
416{
417 NS_LOG_FUNCTION(this);
418
419 uint8_t rovrLength = rovr.size();
420 NS_ASSERT_MSG((rovrLength == 8) || (rovrLength == 16) || (rovrLength == 24) ||
421 (rovrLength == 32),
422 "ROVR length must be 64, 128, 192, or 256 bits");
423
424 m_rovr = std::move(rovr);
425}
426
427void
429{
430 NS_LOG_FUNCTION(this << &os);
431
432 std::ios oldState(nullptr);
433 oldState.copyfmt(os);
434 uint8_t rovrLength = m_rovr.size();
435
436 os << "(type = " << (uint32_t)GetType() << " length = " << (uint32_t)GetLength() << " status "
437 << (uint32_t)m_status << " lifetime " << m_regTime << " ROVR (" << +rovrLength << ") ";
438 for (uint8_t index = 0; index < rovrLength; index++)
439 {
440 os << std::hex << +m_rovr[index];
441 }
442 os << ")";
443
444 os.copyfmt(oldState);
445}
446
453
454void
456{
457 NS_LOG_FUNCTION(this << &start);
458 Buffer::Iterator i = start;
459
460 i.WriteU8(GetType());
461 i.WriteU8(GetLength());
462 i.WriteU8(m_status);
463 i.WriteU8(m_opaque);
464
465 uint8_t flags;
466 flags = m_i;
467 flags <<= 1;
468 if (m_flagR)
469 {
470 flags |= 1;
471 }
472 flags <<= 1;
473
474 // Flag T *must* be set to comply with rfc 8505
475 flags |= 1;
476
477 i.WriteU8(flags);
478 i.WriteU8(m_tid);
480
481 for (const auto& rovr : m_rovr)
482 {
483 i.WriteU8(rovr);
484 }
485}
486
489{
490 NS_LOG_FUNCTION(this << &start);
491 Buffer::Iterator i = start;
492
493 SetType(i.ReadU8());
494 SetLength(i.ReadU8());
495 uint8_t rovrLength = (GetLength() - 1) * 8;
496
497 m_status = i.ReadU8();
498 m_opaque = i.ReadU8();
499
500 uint8_t flags = i.ReadU8();
501 if ((flags & 0x01) != 0x01)
502 {
503 NS_LOG_LOGIC("Received an EARO without the T flag set - ignoring");
504 return 0;
505 }
506 if ((flags & 0x02) == 0x02)
507 {
508 m_flagR = true;
509 }
510 m_i = (flags >> 2) & 0x03;
511
512 m_tid = i.ReadU8();
513 m_regTime = i.ReadU16();
514
515 m_rovr.clear();
516 for (uint8_t index = 0; index < rovrLength; index++)
517 {
518 m_rovr.push_back(i.ReadU8());
519 }
520
521 return GetSerializedSize();
522}
523
525
537
539 uint8_t cid,
540 uint16_t time,
541 Ipv6Prefix prefix)
542{
543 NS_LOG_FUNCTION(this);
545
546 if (prefix.GetPrefixLength() > 64)
547 {
548 SetLength(3);
549 }
550 else
551 {
552 SetLength(2);
553 }
554
555 m_contextLen = prefix.GetPrefixLength();
556 m_c = c;
557 m_cid = cid;
558 m_validTime = time;
559 m_prefix = prefix;
560}
561
566
567TypeId
569{
570 static TypeId tid = TypeId("ns3::Icmpv6OptionSixLowPanContext")
572 .SetGroupName("Internet")
573 .AddConstructor<Icmpv6OptionSixLowPanContext>();
574 return tid;
575}
576
577TypeId
583
584uint8_t
590
591bool
593{
594 NS_LOG_FUNCTION(this);
595 return m_c;
596}
597
598void
600{
601 NS_LOG_FUNCTION(this << c);
602 m_c = c;
603}
604
605uint8_t
607{
608 NS_LOG_FUNCTION(this);
609 return m_cid;
610}
611
612void
614{
615 NS_LOG_FUNCTION(this << static_cast<uint32_t>(cid));
616 NS_ASSERT(cid <= 15);
617 m_cid = cid;
618}
619
620uint16_t
626
627void
629{
630 NS_LOG_FUNCTION(this << time);
631 m_validTime = time;
632}
633
640
641void
643{
644 NS_LOG_FUNCTION(this << prefix);
645 m_prefix = prefix;
646 m_contextLen = prefix.GetPrefixLength();
647
648 if (prefix.GetPrefixLength() > 64)
649 {
650 SetLength(3);
651 }
652 else
653 {
654 SetLength(2);
655 }
656}
657
658void
660{
661 NS_LOG_FUNCTION(this << &os);
662 os << "( type = " << (uint32_t)GetType() << " length = " << (uint32_t)GetLength()
663 << " context length = " << (uint32_t)m_contextLen << " flag C = " << m_c
664 << " CID = " << (uint32_t)m_cid << " lifetime = " << m_validTime
665 << " context prefix = " << m_prefix.ConvertToIpv6Address() << "/"
666 << +m_prefix.GetPrefixLength() << ")";
667}
668
671{
672 NS_LOG_FUNCTION(this);
673 uint8_t nb = GetLength() * 8;
674 return nb;
675}
676
677void
679{
680 NS_LOG_FUNCTION(this << &start);
681 Buffer::Iterator i = start;
682 uint8_t buf[16];
683 uint8_t bitfield = 0;
684
685 memset(buf, 0x0000, sizeof(buf));
686
687 i.WriteU8(GetType());
688 i.WriteU8(GetLength());
690
691 bitfield |= m_cid;
692 bitfield |= (uint8_t)(m_c << 4);
693
694 i.WriteU8(bitfield);
695 i.WriteU16(0);
697
698 m_prefix.GetBytes(buf);
699 if (m_contextLen <= 64)
700 {
701 i.Write(buf, 8);
702 }
703 else
704 {
705 i.Write(buf, 16);
706 }
707}
708
711{
712 NS_LOG_FUNCTION(this << &start);
713 Buffer::Iterator i = start;
714 uint8_t buf[16];
715 uint8_t bitfield;
716
717 memset(buf, 0x0000, sizeof(buf));
718
719 SetType(i.ReadU8());
720 SetLength(i.ReadU8());
721 m_contextLen = i.ReadU8();
722
723 bitfield = i.ReadU8();
724 m_c = false;
725 if (bitfield & (uint8_t)(1 << 4))
726 {
727 m_c = true;
728 }
729 m_cid = bitfield & 0xF;
730 i.Next(2);
732
733 if (GetContextLen() <= 64)
734 {
735 i.Read(buf, 8);
736 }
737 else
738 {
739 i.Read(buf, 16);
740 }
742
743 if (m_contextLen > 64)
744 {
745 SetLength(3);
746 }
747 else
748 {
749 SetLength(2);
750 }
751
752 return GetSerializedSize();
753}
754
756
766
779
784
785TypeId
787{
788 static TypeId tid = TypeId("ns3::Icmpv6OptionAuthoritativeBorderRouter")
790 .SetGroupName("Internet")
792 return tid;
793}
794
795TypeId
801
808
809void
815
816uint16_t
822
823void
829
836
837void
843
844void
846{
847 NS_LOG_FUNCTION(this << &os);
848 os << "( type = " << (uint32_t)GetType() << " length = " << (uint32_t)GetLength()
849 << " version = " << m_version << " lifetime = " << m_validTime
850 << " router address = " << m_routerAddress << ")";
851}
852
859
860void
862{
863 NS_LOG_FUNCTION(this << &start);
864 Buffer::Iterator i = start;
865 uint8_t buf[16];
866 uint32_t versionL = m_version;
867 uint32_t versionH = m_version;
868
869 memset(buf, 0x0000, sizeof(buf));
870
871 i.WriteU8(GetType());
872 i.WriteU8(GetLength());
873
874 versionL &= 0xFFFF;
875 i.WriteU16((uint16_t)versionL);
876 versionH >>= 16;
877 versionH &= 0xFFFF;
878 i.WriteU16((uint16_t)versionH);
879
881
882 m_routerAddress.Serialize(buf);
883 i.Write(buf, 16);
884}
885
888{
889 NS_LOG_FUNCTION(this << &start);
890 Buffer::Iterator i = start;
891 uint8_t buf[16];
892 uint32_t versionL;
893 uint32_t versionH;
894
895 memset(buf, 0x0000, sizeof(buf));
896
897 SetType(i.ReadU8());
898 SetLength(i.ReadU8());
899
900 versionL = (uint32_t)i.ReadU16();
901 versionH = (uint32_t)i.ReadU16();
902 versionH <<= 16;
903 m_version = (versionL &= 0xFFFF) + (versionH &= 0xFFFF0000);
904
905 m_validTime = i.ReadU16();
906
907 i.Read(buf, 16);
909
910 return GetSerializedSize();
911}
912
913} /* namespace ns3 */
uint32_t r
iterator in a Buffer instance
Definition buffer.h:98
void WriteU8(uint8_t data)
Definition buffer.h:897
void Write(const uint8_t *buffer, uint32_t size)
Definition buffer.cc:937
void WriteU16(uint16_t data)
Definition buffer.cc:848
void Read(uint8_t *buffer, uint32_t size)
Definition buffer.cc:1114
uint16_t ReadNtohU16()
Definition buffer.h:970
uint16_t ReadU16()
Definition buffer.h:1051
void Next()
go forward by one byte
Definition buffer.h:869
@ ICMPV6_OPT_AUTHORITATIVE_BORDER_ROUTER
@ ICMPV6_OPT_EXTENDED_ADDRESS_REGISTRATION
uint8_t GetType() const
Get the type field.
Icmpv6Header()
Constructor.
uint16_t m_checksum
The checksum.
void SetType(uint8_t type)
Set the type.
@ ICMPV6_ND_DUPLICATE_ADDRESS_CONFIRM
@ ICMPV6_ND_DUPLICATE_ADDRESS_REQUEST
void SetChecksum(uint16_t checksum)
Set the checksum.
void SetType(uint8_t type)
Set the type of the option.
Icmpv6OptionHeader()
Constructor.
uint8_t GetType() const
Get the type of the option.
void SetLength(uint8_t len)
Set the length of the option.
uint8_t GetLength() const
Get the length of the option in 8 bytes unit.
ICMPv6 Authoritative Border Router Option header (see RFC 8505).
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void Print(std::ostream &os) const override
Print information.
uint16_t m_validTime
The valid lifetime value (units of 60 seconds).
static TypeId GetTypeId()
Get the UID of this class.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
void SetValidLifeTime(uint16_t time)
Set the valid lifetime field.
uint32_t GetVersion() const
Get the version field.
void SetVersion(uint32_t version)
Set the version field.
uint32_t GetSerializedSize() const override
Get the serialized size.
uint16_t GetValidLifeTime() const
Get the valid lifetime field.
void SetRouterAddress(Ipv6Address router)
Set the 6LBR address field.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
Ipv6Address GetRouterAddress() const
Get the 6LBR address field.
ICMPv6 SixLowPan Context Option header (see RFC 8505).
uint8_t GetCid() const
Get the context identifier field.
bool m_c
The compression flag, indicates that this context is valid for use in compression.
Ipv6Prefix GetContextPrefix() const
Get the context prefix field.
void Print(std::ostream &os) const override
Print information.
uint8_t m_cid
The context identifier value.
void SetFlagC(bool c)
Set the C flag.
Ipv6Prefix m_prefix
The context prefix value.
void SetContextPrefix(Ipv6Prefix prefix)
Set the context prefix field.
uint8_t m_contextLen
The context length value.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
static TypeId GetTypeId()
Get the UID of this class.
uint8_t GetContextLen() const
Get the context length field.
void SetValidTime(uint16_t time)
Set the valid lifetime field.
uint16_t m_validTime
The valid lifetime value (units of 60 seconds).
void SetCid(uint8_t cid)
Set the context identifier field.
bool IsFlagC() const
Is compression flag ?
uint32_t GetSerializedSize() const override
Get the serialized size.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
~Icmpv6OptionSixLowPanContext() override
Destructor.
uint16_t GetValidTime() const
Get the valid lifetime field.
ICMPv6 Extended Address Registration Option header RFC 8505.
uint32_t GetSerializedSize() const override
Get the serialized size.
static TypeId GetTypeId()
Get the UID of this class.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
void SetStatus(uint8_t status)
Set the status field.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
uint8_t GetTransactionId() const
Get the transaction ID field.
uint16_t m_regTime
The registration lifetime value (units of 60 seconds).
void SetRovr(const std::vector< uint8_t > &rovr)
Set the ROVR field.
std::vector< uint8_t > GetRovr() const
Get the ROVR field.
uint16_t GetRegTime() const
Get the registration lifetime field.
void SetI(uint8_t twobits)
Set the I-TwoBit field.
void SetTransactionId(uint8_t tid)
Set the transaction ID field.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void SetRegTime(uint16_t time)
Set the registration lifetime field.
void Print(std::ostream &os) const override
Print information.
void SetOpaque(uint8_t opaque)
Set the opaque field.
ICMPv6 Extended Duplicate Address Request or Confirmation header (see RFC 8505).
Ipv6Address m_regAddress
The registered address value.
uint16_t GetRegTime() const
Get the registration lifetime field.
void SetRegAddress(Ipv6Address registered)
Set the registered address field.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
Ipv6Address GetRegAddress() const
Get the registered address field.
void SetStatus(uint8_t status)
Set the status field.
uint16_t m_regTime
The registration lifetime value (units of 60 seconds).
uint32_t GetSerializedSize() const override
Get the serialized size.
static TypeId GetTypeId()
Get the UID of this class.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void SetRovr(const std::vector< uint8_t > &rovr)
Set the ROVR field.
void SetRegTime(uint16_t time)
Set the registration lifetime field.
std::vector< uint8_t > GetRovr() const
Get the ROVR field.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
void Print(std::ostream &os) const override
Print information.
Describes an IPv6 address.
static Ipv6Address Deserialize(const uint8_t buf[16])
Deserialize this address.
Describes an IPv6 prefix.
uint8_t GetPrefixLength() const
Get prefix length.
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.