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
19namespace ns3
20{
21
22NS_LOG_COMPONENT_DEFINE("SixLowPanNdHeader");
23
25
35
48
62
64 uint8_t status,
65 uint16_t time,
66 std::vector<uint8_t> rovr,
67 Ipv6Address address)
68{
69 NS_LOG_FUNCTION(this);
71 SetChecksum(0);
72 m_status = status;
73 m_regTime = time;
74 SetRovr(rovr);
75 m_regAddress = address;
76}
77
83
86{
87 static TypeId tid = TypeId("ns3::Icmpv6DuplicateAddress")
89 .SetGroupName("Internet")
91 return tid;
92}
93
100
101uint8_t
107
108void
110{
111 NS_LOG_FUNCTION(this << static_cast<uint32_t>(status));
112 m_status = status;
113}
114
115uint16_t
121
122void
124{
125 NS_LOG_FUNCTION(this << time);
126 m_regTime = time;
127}
128
129std::vector<uint8_t>
135
136void
138{
139 NS_LOG_FUNCTION(this);
140
141 uint8_t rovrLength = rovr.size();
142 NS_ASSERT_MSG((rovrLength == 8) || (rovrLength == 16) || (rovrLength == 24) ||
143 (rovrLength == 32),
144 "ROVR length must be 64, 128, 192, or 256 bits");
145
146 m_rovr = std::move(rovr);
147}
148
155
156void
162
163void
165{
166 NS_LOG_FUNCTION(this << &os);
167
168 std::ios oldState(nullptr);
169 oldState.copyfmt(os);
170 uint8_t rovrLength = m_rovr.size();
171
172 os << "( type = " << (uint32_t)GetType() << " status " << (uint32_t)m_status << " TID " << m_tid
173 << " lifetime " << m_regTime << " ROVR len " << rovrLength;
174 for (uint8_t index = 0; index < rovrLength; index++)
175 {
176 os << std::hex << m_rovr[index];
177 }
178 os << ")";
179
180 os.copyfmt(oldState);
181}
182
189
190void
192{
193 NS_LOG_FUNCTION(this << &start);
194 Buffer::Iterator i = start;
195
196 i.WriteU8(GetType());
197 i.WriteU8(m_status);
198
199 // note: codePfx is always zero, ROVR size is a multiple of 8 bytes, and less than 32 bytes.
200 uint8_t codeSfx = m_rovr.size() / 8;
201 i.WriteU8(codeSfx);
202
204 i.WriteU8(m_status);
205 i.WriteU8(m_tid);
207
208 for (const auto& rovr : m_rovr)
209 {
210 i.WriteU8(rovr);
211 }
212}
213
216{
217 NS_LOG_FUNCTION(this << &start);
218 Buffer::Iterator i = start;
219
220 SetType(i.ReadU8());
221 uint8_t codePSfx = i.ReadU8();
222 if (codePSfx > 4)
223 {
224 NS_LOG_LOGIC("Invalid CodeSfx or CodePfx value (" << codePSfx << "), discarding message");
225 return 0;
226 }
227 uint8_t rovrLength = codePSfx * 8;
228
229 m_status = i.ReadU8();
230 i.Next(3);
231 m_regTime = i.ReadU16();
232
233 m_rovr.clear();
234 for (uint8_t index = 0; index < rovrLength; index++)
235 {
236 m_rovr.push_back(i.ReadU8());
237 }
238
239 return GetSerializedSize();
240}
241
243
256
258 uint16_t time,
259 const std::vector<uint8_t>& rovr,
260 uint8_t tid)
261{
262 NS_LOG_FUNCTION(this);
264 SetLength(1 + rovr.size() / 8);
265 m_status = 0;
266 m_opaque = 0;
267 m_i = 0;
268 m_flagR = false;
269 m_tid = tid;
270 m_regTime = time;
271 SetRovr(rovr);
272}
273
275 uint8_t status,
276 uint16_t time,
277 const std::vector<uint8_t>& rovr,
278 uint8_t tid)
279{
280 NS_LOG_FUNCTION(this);
282 SetLength(1 + rovr.size() / 8);
283 m_status = status;
284 m_opaque = 0;
285 m_i = 0;
286 m_flagR = false;
287 m_tid = tid;
288 m_regTime = time;
289 SetRovr(rovr);
290}
291
297
298TypeId
300{
301 static TypeId tid = TypeId("ns3::Icmpv6OptionAddressRegistration")
303 .SetGroupName("Internet")
305 return tid;
306}
307
308TypeId
314
315uint8_t
321
322void
324{
325 NS_LOG_FUNCTION(this << static_cast<uint32_t>(status));
326 m_status = status;
327}
328
329uint8_t
335
336void
338{
339 NS_LOG_FUNCTION(this << static_cast<uint32_t>(opaque));
340 m_opaque = opaque;
341}
342
343uint8_t
350
351void
353{
354 if (twobit > 3)
355 {
356 NS_LOG_FUNCTION(this << static_cast<uint32_t>(twobit));
357 return;
358 }
359 m_i = twobit;
360}
361
362bool
368
369void
375
376uint8_t
382
383void
389
390uint16_t
396
397void
399{
400 NS_LOG_FUNCTION(this << time);
401 m_regTime = time;
402}
403
404std::vector<uint8_t>
410
411void
413{
414 NS_LOG_FUNCTION(this);
415
416 uint8_t rovrLength = rovr.size();
417 NS_ASSERT_MSG((rovrLength == 8) || (rovrLength == 16) || (rovrLength == 24) ||
418 (rovrLength == 32),
419 "ROVR length must be 64, 128, 192, or 256 bits");
420
421 m_rovr = std::move(rovr);
422}
423
424void
426{
427 NS_LOG_FUNCTION(this << &os);
428
429 std::ios oldState(nullptr);
430 oldState.copyfmt(os);
431 uint8_t rovrLength = m_rovr.size();
432
433 os << "(type = " << (uint32_t)GetType() << " length = " << (uint32_t)GetLength() << " status "
434 << (uint32_t)m_status << " lifetime " << m_regTime << " ROVR (" << +rovrLength << ") ";
435 for (uint8_t index = 0; index < rovrLength; index++)
436 {
437 os << std::hex << +m_rovr[index];
438 }
439 os << ")";
440
441 os.copyfmt(oldState);
442}
443
450
451void
453{
454 NS_LOG_FUNCTION(this << &start);
455 Buffer::Iterator i = start;
456
457 i.WriteU8(GetType());
458 i.WriteU8(GetLength());
459 i.WriteU8(m_status);
460 i.WriteU8(m_opaque);
461
462 uint8_t flags;
463 flags = m_i;
464 flags <<= 1;
465 if (m_flagR)
466 {
467 flags |= 1;
468 }
469 flags <<= 1;
470
471 // Flag T *must* be set to comply with rfc 8505
472 flags |= 1;
473
474 i.WriteU8(flags);
475 i.WriteU8(m_tid);
477
478 for (const auto& rovr : m_rovr)
479 {
480 i.WriteU8(rovr);
481 }
482}
483
486{
487 NS_LOG_FUNCTION(this << &start);
488 Buffer::Iterator i = start;
489
490 SetType(i.ReadU8());
491 SetLength(i.ReadU8());
492 uint8_t rovrLength = (GetLength() - 1) * 8;
493
494 m_status = i.ReadU8();
495 m_opaque = i.ReadU8();
496
497 uint8_t flags = i.ReadU8();
498 if ((flags & 0x01) != 0x01)
499 {
500 NS_LOG_LOGIC("Received an EARO without the T flag set - ignoring");
501 return 0;
502 }
503 if ((flags & 0x02) == 0x02)
504 {
505 m_flagR = true;
506 }
507 m_i = (flags >> 2) & 0x03;
508
509 m_tid = i.ReadU8();
510 m_regTime = i.ReadU16();
511
512 m_rovr.clear();
513 for (uint8_t index = 0; index < rovrLength; index++)
514 {
515 m_rovr.push_back(i.ReadU8());
516 }
517
518 return GetSerializedSize();
519}
520
522
534
536 uint8_t cid,
537 uint16_t time,
538 Ipv6Prefix prefix)
539{
540 NS_LOG_FUNCTION(this);
542
543 if (prefix.GetPrefixLength() > 64)
544 {
545 SetLength(3);
546 }
547 else
548 {
549 SetLength(2);
550 }
551
552 m_contextLen = prefix.GetPrefixLength();
553 m_c = c;
554 m_cid = cid;
555 m_validTime = time;
556 m_prefix = prefix;
557}
558
563
564TypeId
566{
567 static TypeId tid = TypeId("ns3::Icmpv6OptionSixLowPanContext")
569 .SetGroupName("Internet")
570 .AddConstructor<Icmpv6OptionSixLowPanContext>();
571 return tid;
572}
573
574TypeId
580
581uint8_t
587
588bool
590{
591 NS_LOG_FUNCTION(this);
592 return m_c;
593}
594
595void
597{
598 NS_LOG_FUNCTION(this << c);
599 m_c = c;
600}
601
602uint8_t
604{
605 NS_LOG_FUNCTION(this);
606 return m_cid;
607}
608
609void
611{
612 NS_LOG_FUNCTION(this << static_cast<uint32_t>(cid));
613 NS_ASSERT(cid <= 15);
614 m_cid = cid;
615}
616
617uint16_t
623
624void
626{
627 NS_LOG_FUNCTION(this << time);
628 m_validTime = time;
629}
630
637
638void
640{
641 NS_LOG_FUNCTION(this << prefix);
642 m_prefix = prefix;
643 m_contextLen = prefix.GetPrefixLength();
644
645 if (prefix.GetPrefixLength() > 64)
646 {
647 SetLength(3);
648 }
649 else
650 {
651 SetLength(2);
652 }
653}
654
655void
657{
658 NS_LOG_FUNCTION(this << &os);
659 os << "( type = " << (uint32_t)GetType() << " length = " << (uint32_t)GetLength()
660 << " context length = " << (uint32_t)m_contextLen << " flag C = " << m_c
661 << " CID = " << (uint32_t)m_cid << " lifetime = " << m_validTime
662 << " context prefix = " << m_prefix.ConvertToIpv6Address() << "/"
663 << +m_prefix.GetPrefixLength() << ")";
664}
665
668{
669 NS_LOG_FUNCTION(this);
670 uint8_t nb = GetLength() * 8;
671 return nb;
672}
673
674void
676{
677 NS_LOG_FUNCTION(this << &start);
678 Buffer::Iterator i = start;
679 uint8_t buf[16];
680 uint8_t bitfield = 0;
681
682 memset(buf, 0x0000, sizeof(buf));
683
684 i.WriteU8(GetType());
685 i.WriteU8(GetLength());
687
688 bitfield |= m_cid;
689 bitfield |= (uint8_t)(m_c << 4);
690
691 i.WriteU8(bitfield);
692 i.WriteU16(0);
694
695 m_prefix.GetBytes(buf);
696 if (m_contextLen <= 64)
697 {
698 i.Write(buf, 8);
699 }
700 else
701 {
702 i.Write(buf, 16);
703 }
704}
705
708{
709 NS_LOG_FUNCTION(this << &start);
710 Buffer::Iterator i = start;
711 uint8_t buf[16];
712 uint8_t bitfield;
713
714 memset(buf, 0x0000, sizeof(buf));
715
716 SetType(i.ReadU8());
717 SetLength(i.ReadU8());
718 m_contextLen = i.ReadU8();
719
720 bitfield = i.ReadU8();
721 m_c = false;
722 if (bitfield & (uint8_t)(1 << 4))
723 {
724 m_c = true;
725 }
726 m_cid = bitfield & 0xF;
727 i.Next(2);
729
730 if (GetContextLen() <= 64)
731 {
732 i.Read(buf, 8);
733 }
734 else
735 {
736 i.Read(buf, 16);
737 }
739
740 if (m_contextLen > 64)
741 {
742 SetLength(3);
743 }
744 else
745 {
746 SetLength(2);
747 }
748
749 return GetSerializedSize();
750}
751
753
763
776
781
782TypeId
784{
785 static TypeId tid = TypeId("ns3::Icmpv6OptionAuthoritativeBorderRouter")
787 .SetGroupName("Internet")
789 return tid;
790}
791
792TypeId
798
805
806void
812
813uint16_t
819
820void
826
833
834void
840
841void
843{
844 NS_LOG_FUNCTION(this << &os);
845 os << "( type = " << (uint32_t)GetType() << " length = " << (uint32_t)GetLength()
846 << " version = " << m_version << " lifetime = " << m_validTime
847 << " router address = " << m_routerAddress << ")";
848}
849
856
857void
859{
860 NS_LOG_FUNCTION(this << &start);
861 Buffer::Iterator i = start;
862 uint8_t buf[16];
863 uint32_t versionL = m_version;
864 uint32_t versionH = m_version;
865
866 memset(buf, 0x0000, sizeof(buf));
867
868 i.WriteU8(GetType());
869 i.WriteU8(GetLength());
870
871 versionL &= 0xFFFF;
872 i.WriteU16((uint16_t)versionL);
873 versionH >>= 16;
874 versionH &= 0xFFFF;
875 i.WriteU16((uint16_t)versionH);
876
878
879 m_routerAddress.Serialize(buf);
880 i.Write(buf, 16);
881}
882
885{
886 NS_LOG_FUNCTION(this << &start);
887 Buffer::Iterator i = start;
888 uint8_t buf[16];
889 uint32_t versionL;
890 uint32_t versionH;
891
892 memset(buf, 0x0000, sizeof(buf));
893
894 SetType(i.ReadU8());
895 SetLength(i.ReadU8());
896
897 versionL = (uint32_t)i.ReadU16();
898 versionH = (uint32_t)i.ReadU16();
899 versionH <<= 16;
900 m_version = (versionL &= 0xFFFF) + (versionH &= 0xFFFF0000);
901
902 m_validTime = i.ReadU16();
903
904 i.Read(buf, 16);
906
907 return GetSerializedSize();
908}
909
910} /* 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.