A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
sixlowpan-nd-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Università di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 *
7 *
8 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
9 * Adnan Rashid <adnanrashidpk@gmail.com>
10 * Boh Jie Qi <jieqiboh5836@gmail.com>
11 */
12
14
15#include "sixlowpan-header.h"
17#include "sixlowpan-nd-header.h"
18#include "sixlowpan-nd-prefix.h"
20
21#include "ns3/abort.h"
22#include "ns3/assert.h"
23#include "ns3/boolean.h"
24#include "ns3/integer.h"
25#include "ns3/ipv6-interface.h"
26#include "ns3/ipv6-l3-protocol.h"
27#include "ns3/ipv6-route.h"
28#include "ns3/ipv6-routing-protocol.h"
29#include "ns3/log.h"
30#include "ns3/mac16-address.h"
31#include "ns3/mac48-address.h"
32#include "ns3/mac64-address.h"
33#include "ns3/ndisc-cache.h"
34#include "ns3/node.h"
35#include "ns3/nstime.h"
36#include "ns3/packet.h"
37#include "ns3/pointer.h"
38#include "ns3/ptr.h"
39#include "ns3/string.h"
40#include "ns3/uinteger.h"
41
42#include <algorithm>
43#include <cmath>
44#include <iomanip>
45
46namespace ns3
47{
48
49NS_LOG_COMPONENT_DEFINE("SixLowPanNdProtocol");
50
52
60
65
68{
69 static TypeId tid =
70 TypeId("ns3::SixLowPanNdProtocol")
72 .SetGroupName("Internet")
73 .AddConstructor<SixLowPanNdProtocol>()
74 .AddAttribute("AddressRegistrationJitter",
75 "The jitter in ms a node is allowed to wait before sending any address "
76 "registration. Some jitter aims to prevent collisions. By default, the "
77 "model will wait for a duration in ms defined by a uniform "
78 "random variable between 0 and AddressRegistrationJitter",
79 StringValue("ns3::UniformRandomVariable[Min=0.0|Max=10.0]"),
82 .AddAttribute("RegistrationLifeTime",
83 "The amount of time (units of 60 seconds) that the router should retain "
84 "the NCE for the node.",
85 UintegerValue(65535),
88 .AddAttribute("AdvanceTime",
89 "How many seconds before registration expiry to begin re-registration.",
93 .AddAttribute("DefaultRouterLifeTime",
94 "The default router lifetime.",
95 TimeValue(Minutes(60)),
97 MakeTimeChecker(Time(0), Seconds(0xffff)))
98 .AddAttribute("DefaultPrefixInformationPreferredLifeTime",
99 "The default Prefix Information preferred lifetime.",
100 TimeValue(Minutes(10)),
103 .AddAttribute("DefaultPrefixInformationValidLifeTime",
104 "The default Prefix Information valid lifetime.",
105 TimeValue(Minutes(10)),
108 .AddAttribute("DefaultContextValidLifeTime",
109 "The default Context valid lifetime.",
110 TimeValue(Minutes(10)),
113 .AddAttribute("DefaultAbroValidLifeTime",
114 "The default ABRO Valid lifetime.",
115 TimeValue(Minutes(10)),
118 .AddAttribute("MaxRtrSolicitationInterval",
119 "Maximum Time between two RS (after the backoff).",
120 TimeValue(Seconds(60)),
123 .AddTraceSource(
124 "AddressRegistrationResult",
125 "Trace fired when an address registration succeeds or fails",
127 "ns3::SixLowPanNdProtocol::AddressRegistrationCallback")
128 .AddTraceSource("MulticastRS",
129 "Trace fired when a multicast RS is sent",
131 "ns3::SixLowPanNdProtocol::MulticastRsCallback")
132 .AddTraceSource("NaRx",
133 "Trace fired when a NA packet is received",
135 "ns3::SixLowPanNdProtocol::NaRxCallback");
136
137 return tid;
138}
139
140int64_t
142{
143 NS_LOG_FUNCTION(this << stream);
144 m_addressRegistrationJitter->SetStream(stream);
145 return 2;
146}
147
148void
150{
151 if (!m_raEntries.empty())
152 {
154 }
155
156 m_addrPendingReg.isValid = false;
157
159}
160
161void
163{
164 NS_LOG_FUNCTION(this);
165 if (!m_node)
166 {
167 Ptr<Node> node = this->GetObject<Node>();
168 if (node)
169 {
170 Ptr<Ipv6> ipv6 = this->GetObject<Ipv6>();
171 if (ipv6 && m_downTarget.IsNull())
172 {
173 SetNode(node);
174 // We must NOT insert the protocol as a default protocol.
175 // This protocol will be inserted later for specific NetDevices.
176 // ipv6->Insert (this);
178 }
179 }
180 }
182}
183
184void
186 Ipv6Address dst,
187 Address dstMac,
188 uint16_t time,
189 const std::vector<uint8_t>& rovr,
190 Ptr<NetDevice> sixLowPanNetDevice)
191{
192 NS_LOG_FUNCTION(this << addrToRegister << dst << dstMac << time << rovr << sixLowPanNetDevice);
193
195 "Destination address must not be a multicast address in EARO messages.");
196
197 // Build NS Header
198 Icmpv6NS nsHdr(addrToRegister);
199
200 // Build EARO option
201 // EARO (request) + SLLAO + TLLAO (SLLAO and TLLAO must be identical, RFC 8505, section 5.6)
203 Icmpv6OptionLinkLayerAddress tlla(false, sixLowPanNetDevice->GetAddress());
204 Icmpv6OptionLinkLayerAddress slla(true, sixLowPanNetDevice->GetAddress());
205
206 Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol>();
207 Ipv6Address src =
208 ipv6->GetAddress(ipv6->GetInterfaceForDevice(sixLowPanNetDevice), 0).GetAddress();
209
210 // Build NS EARO Packet
211 Ptr<Packet> p = MakeNsEaroPacket(src, dst, nsHdr, slla, tlla, earo);
212
213 // Build ipv6 header manually as neighbour cache is probably empty
214 Ipv6Header hdr;
215 hdr.SetSource(src);
216 hdr.SetDestination(dst);
218 hdr.SetPayloadLength(p->GetSize());
219 hdr.SetHopLimit(255);
220
221 Ptr<Packet> pkt = p->Copy();
222 pkt->AddHeader(hdr);
223
224 sixLowPanNetDevice->Send(pkt, dstMac, Ipv6L3Protocol::PROT_NUMBER);
225}
226
227void
229 Ipv6Address dst,
230 Ipv6Address target,
231 uint16_t time,
232 const std::vector<uint8_t>& rovr,
233 Ptr<NetDevice> sixLowPanNetDevice,
234 uint8_t status)
235{
236 NS_LOG_FUNCTION(this << src << dst << target << time << rovr << sixLowPanNetDevice << status);
237
238 // Build the NA Header
239 Icmpv6NA naHdr;
240 naHdr.SetIpv6Target(target);
241 naHdr.SetFlagO(false);
242 naHdr.SetFlagS(true);
243 naHdr.SetFlagR(true);
244
245 // Build EARO Option
246 Icmpv6OptionSixLowPanExtendedAddressRegistration earo(status, time, rovr, 0);
247
248 // Build NA EARO Packet
249 Ptr<Packet> p = MakeNaEaroPacket(src, dst, naHdr, earo);
250
251 SendMessage(p, src, dst, 255);
252}
253
254void
256{
257 NS_LOG_FUNCTION(this << src << hardwareAddress);
258
260
262 Icmpv6RS rs;
263
264 Icmpv6OptionLinkLayerAddress slla(true, hardwareAddress);
266 p->AddHeader(slla);
267 p->AddHeader(cio);
268
269 Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol>();
270 if (ipv6->GetInterfaceForAddress(src) == -1)
271 {
272 NS_LOG_LOGIC("Preventing RS from being sent or rescheduled because the source address "
273 << src << " has been removed");
274 return;
275 }
276
277 NS_LOG_LOGIC("Send RS (from " << src << " to AllRouters multicast address)");
278
281 p->GetSize() + rs.GetSerializedSize(),
283 p->AddHeader(rs);
284
286 Time delay = Seconds(10);
288 {
290 {
291 delay = Seconds(60);
292 }
293 else
294 {
295 delay =
296 std::min(delay * pow(2, 1 + m_rsRetransmissionCount - m_rsMaxRetransmissionCount),
298 }
299 }
300
303 this,
304 p,
305 src,
307 255);
308
312 this,
313 src,
314 hardwareAddress);
315}
316
317void
319{
320 NS_LOG_FUNCTION(this << src << dst << interface);
321
322 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
323 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
325 m_raEntries.find(sixLowPanNetDevice) == m_raEntries.end(),
326 "6LBR not configured on the interface");
327
328 // if the node is a 6LBR, send out the RA entry for the interface
329 auto it = m_raEntries.find(sixLowPanNetDevice);
330 if (it != m_raEntries.end())
331 {
332 Ptr<SixLowPanRaEntry> raEntry = it->second;
333
334 // Build SLLA Option
335 Icmpv6OptionLinkLayerAddress slla(true, interface->GetDevice()->GetAddress());
336
337 // Build 6CIO Option
339 // cio.SetOption(Icmpv6OptionSixLowPanCapabilityIndication::D); // no EDAR EDAC support yet
342
343 // Build RA Packet
344 Ptr<Packet> p = MakeRaPacket(src, dst, slla, cio, raEntry);
345
346 // Build Ipv6 Header manually
347 Ipv6Header ipHeader;
348 ipHeader.SetSource(src);
349 ipHeader.SetDestination(dst);
350 ipHeader.SetNextHeader(PROT_NUMBER);
351 ipHeader.SetPayloadLength(p->GetSize());
352 ipHeader.SetHopLimit(255);
353
354 // send RA
355 NS_LOG_LOGIC("Send RA to " << dst);
356
357 interface->Send(p, ipHeader, dst);
358 }
359}
360
363 const Ipv6Header& header,
364 Ptr<Ipv6Interface> interface)
365{
366 NS_LOG_FUNCTION(this << *packet << header << interface);
367
368 uint8_t type;
369 packet->CopyData(&type, sizeof(type));
370
371 switch (type)
372 {
374 HandleSixLowPanRS(packet, header.GetSource(), header.GetDestination(), interface);
375 break;
377 HandleSixLowPanRA(packet, header.GetSource(), header.GetDestination(), interface);
378 break;
380 HandleSixLowPanNS(packet, header.GetSource(), header.GetDestination(), interface);
381 break;
383 HandleSixLowPanNA(packet, header.GetSource(), header.GetDestination(), interface);
384 break;
385 default:
386 return Icmpv6L4Protocol::Receive(packet, header, interface);
387 break;
388 }
389 return IpL4Protocol::RX_OK;
390}
391
392void
394{
395 NS_LOG_FUNCTION(this);
396
397 m_handleRsTimeoutEvent.Cancel();
399 m_raEntries.clear();
400 m_bindingTableList.clear();
401 m_pendingRas.clear();
402 m_registeredAddresses.clear();
403 m_addrPendingReg.interface = nullptr;
406}
407
408void
410 const Ipv6Address& src,
411 const Ipv6Address& dst,
412 Ptr<Ipv6Interface> interface)
413{
414 NS_LOG_FUNCTION(this << pkt << src << dst << interface);
415
416 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
417 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
418 if (!sixLowPanNetDevice)
419 {
420 HandleNS(pkt, src, dst, interface);
421 return;
422 }
423
424 // NS (EARO) — only a 6LBR maintains a binding table and handles registration.
426 {
427 NS_LOG_LOGIC("Discarding NS(EARO): not a 6LBR");
428 return;
429 }
430
431 if (src == Ipv6Address::GetAny())
432 {
433 NS_LOG_LOGIC("Discarding a NS from unspecified source address");
434 return;
435 }
436
437 if (dst.IsMulticast())
438 {
439 NS_LOG_LOGIC("Discarding a NS sent to a multicast destination");
440 return;
441 }
442
443 Ptr<Packet> packet = pkt->Copy();
444
445 Icmpv6NS nsHdr;
446 Icmpv6OptionLinkLayerAddress sllaoHdr(true);
447 Icmpv6OptionLinkLayerAddress tllaoHdr(false);
449 bool hasEaro = false;
450
451 if (!ParseAndValidateNsEaroPacket(packet, nsHdr, sllaoHdr, tllaoHdr, earoHdr, hasEaro))
452 {
453 NS_LOG_LOGIC("Discarding invalid NS(EARO)");
454 return;
455 }
456 Ipv6Address target = nsHdr.GetIpv6Target();
457
458 // Check if hasEaro
459 if (!hasEaro)
460 {
461 // Let the "normal" Icmpv6L4Protocol handle it.
462 HandleNS(pkt, src, dst, interface);
463 return;
464 }
465
466 Ptr<SixLowPanNdBindingTable> bindingTable = FindBindingTable(interface);
467 NS_ASSERT_MSG(bindingTable, "Can not find a SixLowPanNdBindingTable");
468
469 Ptr<NdiscCache> cache = DynamicCast<NdiscCache>(FindCache(sixLowPanNetDevice));
470 NS_ASSERT_MSG(cache, "Can not find a NdiscCache");
471
472 // Validate: reject if a reachable binding exists for this target with a different ROVR.
473 auto btEntry = bindingTable->Lookup(target);
474 if (btEntry && btEntry->IsReachable() && btEntry->GetRovr() != earoHdr.GetRovr())
475 {
476 NS_LOG_LOGIC("NS EARO: ROVR mismatch, discarding");
478 src,
479 target,
480 earoHdr.GetRegTime(),
481 earoHdr.GetRovr(),
482 sixLowPanNetDevice,
484 return;
485 }
486
487 // Update or create Binding Table entry.
488 if (!btEntry)
489 {
490 btEntry = bindingTable->Add(target);
491 btEntry->SetRovr(earoHdr.GetRovr());
492 }
493 btEntry->MarkReachable(earoHdr.GetRegTime());
494
495 // Update or create Neighbor Cache entry.
496 NdiscCache::Entry* ncEntry = cache->Lookup(target);
497 if (!ncEntry)
498 {
499 ncEntry = cache->Add(target);
500 }
501 ncEntry->SetRouter(false);
502 ncEntry->SetMacAddress(sllaoHdr.GetAddress());
503 ncEntry->MarkReachable();
504 ncEntry->StartReachableTimer();
505
506 // Install a /128 host route for non-link-local registered addresses.
507 if (!target.IsLinkLocal())
508 {
509 Ptr<Ipv6L3Protocol> ipv6l3Protocol = m_node->GetObject<Ipv6L3Protocol>();
510 ipv6l3Protocol->GetRoutingProtocol()->NotifyAddRoute(
511 target,
512 Ipv6Prefix(128),
513 src,
514 ipv6l3Protocol->GetInterfaceForDevice(interface->GetDevice()));
515 }
516
518 src,
519 target,
520 earoHdr.GetRegTime(),
521 earoHdr.GetRovr(),
522 sixLowPanNetDevice,
523 0);
524}
525
526void
528 const Ipv6Address& src,
529 const Ipv6Address& dst,
530 Ptr<Ipv6Interface> interface)
531{
532 NS_LOG_FUNCTION(this << *packet << src << dst << interface);
533
534 if (src == Ipv6Address::GetAny())
535 {
536 NS_LOG_LOGIC("Discarding a NA from unspecified source address (" << Ipv6Address::GetAny()
537 << ")");
538 return;
539 }
540
541 m_naRxTrace(packet->Copy());
542
543 Ptr<Packet> p = packet->Copy();
544
545 Icmpv6NA naHdr;
548
549 bool hasEaro = false;
550 if (!ParseAndValidateNaEaroPacket(packet, naHdr, tlla, earo, hasEaro))
551 {
552 return; // note that currently it will always return valid
553 }
554
555 // NA without EARO: pass to the standard handler for address resolution.
556 if (!hasEaro)
557 {
558 HandleNA(p, naHdr.GetIpv6Target(), dst, interface);
559 return;
560 }
561
562 // NA (EARO) — validate before processing the registration result.
563 if (earo.GetRovr() != m_rovr)
564 {
565 NS_LOG_LOGIC("NA EARO: ROVR mismatch, discarding");
566 return;
567 }
568
569 if (!m_addrPendingReg.isValid ||
570 m_addrPendingReg.addressPendingRegistration != naHdr.GetIpv6Target())
571 {
572 NS_LOG_LOGIC("NA EARO: target does not match pending registration, discarding");
573 return;
574 }
575
576 // Process registration result.
577 bool registrationSucceeded = (earo.GetStatus() == SUCCESS);
578 m_addressRegistrationResultTrace(m_addrPendingReg.addressPendingRegistration,
579 registrationSucceeded,
580 earo.GetStatus());
581 if (!registrationSucceeded)
582 {
583 // Let the retransmit timeout handle retry up to the maximum count.
584 return;
585 }
587}
588
589void
591 const Ipv6Address& src,
592 const Ipv6Address& dst,
593 Ptr<Ipv6Interface> interface)
594{
595 NS_LOG_FUNCTION(this << packet << src << dst << interface);
596
597 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
598 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
599 if (!sixLowPanNetDevice)
600 {
601 HandleRS(packet, src, dst, interface);
602 return;
603 }
604
605 // Validate: only a 6LBR responds to RS.
607 {
608 NS_LOG_LOGIC("Discarding an RS because this node is not a router");
609 return;
610 }
611
612 if (src == Ipv6Address::GetAny())
613 {
614 NS_LOG_LOGIC("Discarding a RS from unspecified source address (" << Ipv6Address::GetAny()
615 << ")");
616 return;
617 }
618
619 Icmpv6RS rsHdr;
622
623 if (!ParseAndValidateRsPacket(packet, rsHdr, slla, cio))
624 {
625 return;
626 }
627
628 // Update or create Neighbor Cache entry for the soliciting node.
629 Ptr<NdiscCache> neighbourCache = DynamicCast<NdiscCache>(FindCache(sixLowPanNetDevice));
630 NS_ASSERT_MSG(neighbourCache, "Can not find a NdiscCache");
631
632 auto ncEntry = neighbourCache->Lookup(src);
633 if (!ncEntry)
634 {
635 ncEntry = neighbourCache->Add(src);
636 ncEntry->SetRouter(false);
637 }
638 if (ncEntry->GetMacAddress() != slla.GetAddress())
639 {
640 ncEntry->MarkStale(slla.GetAddress());
641 }
642
643 // Send RA in response.
644 SendSixLowPanRA(interface->GetLinkLocalAddress().GetAddress(), src, interface);
645}
646
647void
649 const Ipv6Address& src,
650 const Ipv6Address& dst,
651 Ptr<Ipv6Interface> interface)
652{
653 NS_LOG_FUNCTION(this << packet << src << dst << interface);
654
655 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
656 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
657 if (!sixLowPanNetDevice)
658 {
659 HandleRA(packet, src, dst, interface);
660 return;
661 }
662
663 if (src == Ipv6Address::GetAny())
664 {
665 NS_LOG_LOGIC("Discarding a RA from unspecified source address (" << Ipv6Address::GetAny()
666 << ")");
667 return;
668 }
669
670 // Stop RS retransmissions: receiving any RA from a valid source indicates
671 // a 6LBR is reachable, regardless of whether the RA passes validation below.
672 if (m_handleRsTimeoutEvent.IsPending())
673 {
674 m_handleRsTimeoutEvent.Cancel();
676 }
677
678 Icmpv6RA raHdr;
682 std::list<Icmpv6OptionPrefixInformation> pios;
683 std::list<Icmpv6OptionSixLowPanContext> contexts;
684
685 if (!ParseAndValidateRaPacket(packet, raHdr, pios, abro, slla, cio, contexts))
686 {
687 return;
688 }
689
690 // Deduplicate: only process the first RA from each 6LBR.
691 // Subsequent RAs are dropped until ABRO version management is implemented.
692 if (m_raCache.count(abro.GetRouterAddress()))
693 {
694 return;
695 }
696 m_raCache.insert(abro.GetRouterAddress());
697
698 // Build the set of addresses to register: link-local first (no PIO for
699 // link-local), then one autoconfigured global address per PIO.
700 SixLowPanPendingRa pending;
701 pending.source = src;
702 pending.interface = interface;
703 pending.llaHdr = slla;
704 // Add the link-local address first (no PIO for link-local addresses)
705 pending.addressesToBeRegistered.emplace_back(interface->GetLinkLocalAddress().GetAddress(),
707 for (const auto& pio : pios)
708 {
709 Ipv6Address gaddr = Ipv6Address::MakeAutoconfiguredAddress(sixLowPanNetDevice->GetAddress(),
710 pio.GetPrefix());
711 pending.addressesToBeRegistered.emplace_back(gaddr, pio);
712 }
713 m_pendingRas.push_back(pending);
714
716}
717
718bool
720 const Ipv6Header& ipHeader,
721 Ipv6Address dst,
722 Ptr<NetDevice> device,
723 Ptr<NdiscCache> cache,
724 Address* hardwareDestination)
725{
726 if (!cache)
727 {
728 cache = FindCache(device);
729 }
730 if (!cache)
731 {
732 return false;
733 }
734
735 NdiscCache::Entry* ncEntry = cache->Lookup(dst);
736 if (!ncEntry)
737 {
738 // RFC 8505 prohibits multicast neighbor discovery in 6LoWPAN networks.
739 // The base class would send a multicast NS when an entry is not found,
740 // but in 6LoWPAN ND, address resolution is handled via ARO/EARO registration
741 // rather than multicast NS. Return false to let the caller handle the
742 // unresolved address without triggering multicast NS.
743 return false;
744 }
745 return Icmpv6L4Protocol::Lookup(p, ipHeader, dst, device, cache, hardwareDestination);
746}
747
748void
750{
751 NS_LOG_FUNCTION(this << device << interface);
752
754 table->SetDevice(device, interface, this);
755
756 m_bindingTableList.push_back(table);
757}
758
761{
762 NS_LOG_FUNCTION(this << interface);
763
764 Ptr<NetDevice> device = interface->GetDevice();
765 for (const auto& table : m_bindingTableList)
766 {
767 if (table->GetDevice() == device)
768 {
769 return table;
770 }
771 }
772 return nullptr;
773}
774
775void
777{
778 NS_LOG_FUNCTION(this << interface << addr);
779}
780
781void
782SixLowPanNdProtocol::SetRovr(std::vector<uint8_t> rovr)
783{
784 NS_LOG_FUNCTION(this);
785 m_rovr = rovr;
786}
787
788void
790{
791 NS_LOG_FUNCTION(this);
792
794 {
795 return;
796 }
797
798 // Populate m_addrPendingReg if no registration is currently in progress.
799 Time additionalDelay = Seconds(0);
800 if (!m_addrPendingReg.isValid)
801 {
802 if (!m_pendingRas.empty())
803 {
804 // New registration triggered by a received RA.
805 m_addrPendingReg.isValid = true;
806 m_addrPendingReg.addressPendingRegistration =
807 m_pendingRas.front().addressesToBeRegistered.front().first;
808 m_addrPendingReg.registrar = m_pendingRas.front().source;
809 m_addrPendingReg.newRegistration = true;
810 m_addrPendingReg.llaHdr = m_pendingRas.front().llaHdr;
811 m_addrPendingReg.interface = m_pendingRas.front().interface;
812 m_addrPendingReg.pioHdr = m_pendingRas.front().addressesToBeRegistered.front().second;
813 }
814 else if (!m_registeredAddresses.empty())
815 {
816 // Renewal of an already-registered address.
817 m_addrPendingReg.isValid = true;
818 m_addrPendingReg.addressPendingRegistration =
819 m_registeredAddresses.front().registeredAddr;
820 m_addrPendingReg.registrar = m_registeredAddresses.front().registrar;
821 m_addrPendingReg.newRegistration = false;
822 m_addrPendingReg.llaHdr = m_registeredAddresses.front().llaHdr;
823 m_addrPendingReg.interface = m_registeredAddresses.front().interface;
824 m_addrPendingReg.pioHdr = m_registeredAddresses.front().pioHdr;
825
826 Time now = Simulator::Now();
827 if (m_registeredAddresses.front().registrationTimeout > now)
828 {
829 additionalDelay =
830 m_registeredAddresses.front().registrationTimeout - now - Seconds(m_advance);
831 }
832 }
833 else
834 {
835 // No addresses to register — send multicast RS on each interface to solicit an RA.
836 Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol>();
837 NS_ASSERT(ipv6);
838
839 for (uint32_t i = 0; i < ipv6->GetNInterfaces(); ++i)
840 {
841 Ptr<Ipv6Interface> iface = ipv6->GetInterface(i);
842 if (!iface->IsUp())
843 {
844 continue;
845 }
846
847 Ipv6InterfaceAddress ifaddr = iface->GetAddress(0); // typically link-local
848 Ipv6Address lla = ifaddr.GetAddress();
849
852 this,
853 lla,
854 iface->GetDevice()->GetAddress());
855 }
856 return;
857 }
858 }
859
860 // Schedule NS(EARO) and registration timeout.
862
863 Simulator::Schedule(additionalDelay + MilliSeconds(m_addressRegistrationJitter->GetValue()),
865 this,
866 m_addrPendingReg.addressPendingRegistration,
867 m_addrPendingReg.registrar,
868 m_addrPendingReg.llaHdr.GetAddress(),
869 m_regTime,
870 m_rovr,
871 m_addrPendingReg.interface->GetDevice());
872
874 Simulator::Schedule(additionalDelay + m_retransmissionTime +
877 this);
878}
879
880void
882{
883 NS_LOG_FUNCTION(this << registrar);
884 NS_ABORT_MSG_IF(registrar != m_addrPendingReg.registrar,
885 "AddressRegistrationSuccess, mismatch between sender and expected sender "
886 << registrar << " vs expected " << m_addrPendingReg.registrar);
887
888 if (m_addressRegistrationTimeoutEvent.IsPending())
889 {
891 }
892
894
895 // Update the registered address list.
896 if (!m_addrPendingReg.newRegistration)
897 {
898 // Renewal: refresh the timeout and rotate to the back of the queue.
901 m_registeredAddresses.pop_front();
902 m_registeredAddresses.push_back(regAddr);
903 }
904 else
905 {
906 // New registration: record it and consume the address from the pending RA queue.
908 "AddressRegistrationSuccess, expected to register an address from the "
909 "pending RA list, but it's empty");
911 m_pendingRas.front().addressesToBeRegistered.empty(),
912 "AddressRegistrationSuccess, expected to register an address from the pending RA list "
913 << "but the pending registration address list is empty");
914
915 SixLowPanRegisteredAddress newRegisteredAddr;
916 newRegisteredAddr.registrationTimeout = Now() + Minutes(m_regTime);
917 newRegisteredAddr.registeredAddr = m_addrPendingReg.addressPendingRegistration;
918 newRegisteredAddr.registrar = m_addrPendingReg.registrar;
919 newRegisteredAddr.llaHdr = m_addrPendingReg.llaHdr;
920 newRegisteredAddr.interface = m_pendingRas.front().interface;
921 newRegisteredAddr.pioHdr = m_addrPendingReg.pioHdr;
922 m_registeredAddresses.push_back(newRegisteredAddr);
923
924 // Drop the front pending RA once all its addresses have been registered.
925 m_pendingRas.front().addressesToBeRegistered.pop_front();
926 if (m_pendingRas.front().addressesToBeRegistered.empty())
927 {
928 m_pendingRas.pop_front();
929 }
930 }
931
932 // Notify the IPv6 stack to configure the registered address.
933 if (m_addrPendingReg.addressPendingRegistration.IsLinkLocal())
934 {
936 m_addrPendingReg.registrar,
938 m_addrPendingReg.interface);
939 }
940 else
941 {
942 Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol>();
944 ipv6->AddAutoconfiguredAddress(
945 ipv6->GetInterfaceForDevice(m_addrPendingReg.interface->GetDevice()),
946 prefixHdr.GetPrefix(),
947 prefixHdr.GetPrefixLength(),
948 prefixHdr.GetFlags(),
949 prefixHdr.GetValidTime(),
950 prefixHdr.GetPreferredTime(),
951 registrar);
952 }
953
954 // Clear the pending registration and schedule the next one.
955 m_addrPendingReg.isValid = false; // invalidate before scheduling the next registration
959 this);
960}
961
962void
964{
965 NS_LOG_FUNCTION(this);
966
968 !m_addrPendingReg.isValid,
969 "Address Registration Timeout but there is no valid address pending registration. "
970 << "Node ID=" << m_node->GetId());
971
973 {
975 }
976 else
977 {
978 NS_LOG_INFO("Address registration failed for node "
979 << m_node->GetId()
980 << ", address: " << m_addrPendingReg.addressPendingRegistration
981 << ", registrar: " << m_addrPendingReg.registrar
982 << ", retries: " << static_cast<int>(m_addressRegistrationCounter));
983
984 // todo
985 // Add code to remove next hop from the reliable neighbors.
986 // If the re-registration failed (for all of the candidate next hops), remove the address.
987 // If we don't have any address anymore, start sending RS (again).
988 // For now since we only have 1 6LBR we are registering with, we just stop trying to
989 // register with it
990 }
991}
992
993void
995{
996 NS_LOG_FUNCTION(this << device);
997
998 if (m_raEntries.find(device) != m_raEntries.end())
999 {
1000 NS_LOG_LOGIC("Not going to reconfigure an interface");
1001 return;
1002 }
1003
1005 newRa->SetManagedFlag(false);
1006 newRa->SetHomeAgentFlag(false);
1007 newRa->SetOtherConfigFlag(false);
1008 newRa->SetCurHopLimit(0); // unspecified by this router
1009 newRa->SetRetransTimer(0); // unspecified by this router
1010
1011 newRa->SetReachableTime(0); // unspecified by this router
1012
1013 uint64_t routerLifetime = std::ceil(m_routerLifeTime.GetMinutes());
1014 if (routerLifetime > 0xffff)
1015 {
1016 routerLifetime = 0xffff;
1017 }
1018
1019 newRa->SetRouterLifeTime(routerLifetime);
1020
1022 int32_t interfaceId = ipv6->GetInterfaceForDevice(device);
1023 Ipv6Address borderAddress = Ipv6Address::GetAny();
1024 for (uint32_t i = 0; i < ipv6->GetNAddresses(interfaceId); ++i)
1025 {
1026 if (ipv6->GetAddress(interfaceId, i).GetScope() == Ipv6InterfaceAddress::GLOBAL)
1027 {
1028 borderAddress = ipv6->GetAddress(interfaceId, i).GetAddress();
1029 continue;
1030 }
1031 }
1033 borderAddress == Ipv6Address::GetAny(),
1034 "Can not set a 6LBR because I can't find a global address associated with the interface");
1035 newRa->SetAbroBorderRouterAddress(borderAddress);
1036 newRa->SetAbroVersion(0x66); // placeholder value for testing purposes
1037 newRa->SetAbroValidLifeTime(m_abroValidLifeTime.GetSeconds());
1038
1039 m_raEntries[device] = newRa;
1040}
1041
1042void
1044{
1045 NS_LOG_FUNCTION(this << device << prefix);
1046
1047 if (m_raEntries.find(device) == m_raEntries.end())
1048 {
1049 NS_LOG_LOGIC("Not adding a prefix to an unconfigured interface");
1050 return;
1051 }
1052
1054 prefix.GetPrefixLength(),
1057
1058 m_raEntries[device]->AddPrefix(newPrefix);
1059}
1060
1061void
1063{
1064 NS_LOG_FUNCTION(this << device << context);
1065
1066 if (m_raEntries.find(device) == m_raEntries.end())
1067 {
1068 NS_LOG_LOGIC("Not adding a context to an unconfigured interface");
1069 return;
1070 }
1071 auto contextMap = m_raEntries[device]->GetContexts();
1072
1073 bool found = std::any_of(contextMap.begin(), contextMap.end(), [&context](const auto& entry) {
1074 return entry.second->GetContextPrefix() == context;
1075 });
1076 if (found)
1077 {
1078 NS_LOG_WARN("Not adding an already existing context - remove the old one first "
1079 << context);
1080 return;
1081 }
1082
1083 uint8_t unusedCid;
1084 for (unusedCid = 0; unusedCid < 16; ++unusedCid)
1085 {
1086 if (contextMap.count(unusedCid) == 0)
1087 {
1088 break;
1089 }
1090 }
1091
1092 Ptr<SixLowPanNdContext> newContext =
1093 Create<SixLowPanNdContext>(true, unusedCid, m_contextValidLifeTime, context);
1094 newContext->SetLastUpdateTime(Simulator::Now());
1095
1096 m_raEntries[device]->AddContext(newContext);
1097}
1098
1099void
1101{
1102 NS_LOG_FUNCTION(this << device << context);
1103
1104 if (m_raEntries.find(device) == m_raEntries.end())
1105 {
1106 NS_LOG_LOGIC("Not removing a context from an unconfigured interface");
1107 return;
1108 }
1109
1110 auto contextMap = m_raEntries[device]->GetContexts();
1111
1112 for (const auto& [cid, ctx] : contextMap)
1113 {
1114 if (ctx->GetContextPrefix() == context)
1115 {
1116 m_raEntries[device]->RemoveContext(ctx);
1117 return;
1118 }
1119 }
1120 NS_LOG_WARN("Not removing a non-existing context " << context);
1121}
1122
1123bool
1125{
1126 NS_LOG_FUNCTION(this << device);
1127
1128 return m_raEntries.find(device) != m_raEntries.end();
1129}
1130
1131//
1132// SixLowPanRaEntry class
1133//
1134
1135// NS_LOG_COMPONENT_DEFINE ("SixLowPanRaEntry");
1136
1141
1143 Icmpv6RA raHeader,
1145 std::list<Icmpv6OptionSixLowPanContext> contextList,
1146 std::list<Icmpv6OptionPrefixInformation> prefixList)
1147{
1148 NS_LOG_FUNCTION(this << abroHdr << &prefixList << &contextList);
1149
1150 SetManagedFlag(raHeader.GetFlagM());
1151 SetOtherConfigFlag(raHeader.GetFlagO());
1152 SetHomeAgentFlag(raHeader.GetFlagH());
1154 SetRouterLifeTime(raHeader.GetLifeTime());
1156 SetCurHopLimit(raHeader.GetCurHopLimit());
1157 ParseAbro(abroHdr);
1158
1159 for (const auto& ctxOpt : contextList)
1160 {
1162 context->SetCid(ctxOpt.GetCid());
1163 context->SetFlagC(ctxOpt.IsFlagC());
1164 context->SetValidTime(Minutes(ctxOpt.GetValidTime()));
1165 context->SetContextPrefix(ctxOpt.GetContextPrefix());
1166 context->SetLastUpdateTime(Simulator::Now());
1167
1168 AddContext(context);
1169 }
1170
1171 for (const auto& pfxOpt : prefixList)
1172 {
1174 prefix->SetPrefix(pfxOpt.GetPrefix());
1175 prefix->SetPrefixLength(pfxOpt.GetPrefixLength());
1176 prefix->SetPreferredLifeTime(Seconds(pfxOpt.GetPreferredTime()));
1177 prefix->SetValidLifeTime(Seconds(pfxOpt.GetValidTime()));
1178
1179 AddPrefix(prefix);
1180 }
1181}
1182
1187
1188void
1190{
1191 NS_LOG_FUNCTION(this << prefix);
1192
1193 for (const auto& pfx : m_prefixes)
1194 {
1195 if (pfx->GetPrefix() == prefix->GetPrefix())
1196 {
1197 NS_LOG_WARN("Ignoring an already-existing prefix: " << prefix->GetPrefix());
1198 return;
1199 }
1200 }
1201
1202 m_prefixes.push_back(prefix);
1203}
1204
1205void
1207{
1208 NS_LOG_FUNCTION(this << prefix);
1209
1210 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
1211 {
1212 if ((*it)->GetPrefix() == prefix->GetPrefix())
1213 {
1214 m_prefixes.erase(it);
1215 return;
1216 }
1217 }
1218}
1219
1220std::list<Ptr<SixLowPanNdPrefix>>
1226
1227void
1229{
1230 NS_LOG_FUNCTION(this << context);
1231 m_contexts.emplace(context->GetCid(), context);
1232}
1233
1234void
1236{
1237 NS_LOG_FUNCTION(this);
1238
1239 m_contexts.erase(context->GetCid());
1240}
1241
1242std::map<uint8_t, Ptr<SixLowPanNdContext>>
1248
1251{
1252 NS_LOG_FUNCTION(this);
1253 Icmpv6RA raHdr;
1254 // set RA header information
1255 raHdr.SetFlagM(IsManagedFlag());
1256 raHdr.SetFlagO(IsOtherConfigFlag());
1257 raHdr.SetFlagH(IsHomeAgentFlag());
1262
1263 return raHdr;
1264}
1265
1266std::list<Icmpv6OptionPrefixInformation>
1268{
1269 NS_LOG_FUNCTION(this);
1270 std::list<Icmpv6OptionPrefixInformation> prefixHdrs;
1271
1272 for (const auto& pfx : m_prefixes)
1273 {
1275 prefixHdr.SetPrefixLength(pfx->GetPrefixLength());
1276 prefixHdr.SetFlags(0x40); // We set the Autonomous address configuration only.
1277 prefixHdr.SetValidTime(pfx->GetValidLifeTime().GetSeconds());
1278 prefixHdr.SetPreferredTime(pfx->GetPreferredLifeTime().GetSeconds());
1279 prefixHdr.SetPrefix(pfx->GetPrefix());
1280 prefixHdrs.push_back(prefixHdr);
1281 }
1282
1283 return prefixHdrs;
1284}
1285
1286bool
1292
1293void
1295{
1296 NS_LOG_FUNCTION(this << managedFlag);
1297 m_managedFlag = managedFlag;
1298}
1299
1300bool
1306
1307void
1309{
1310 NS_LOG_FUNCTION(this << otherConfigFlag);
1311 m_otherConfigFlag = otherConfigFlag;
1312}
1313
1314bool
1320
1321void
1323{
1324 NS_LOG_FUNCTION(this << homeAgentFlag);
1325 m_homeAgentFlag = homeAgentFlag;
1326}
1327
1334
1335void
1341
1348
1349void
1355
1362
1363void
1369
1370uint8_t
1376
1377void
1379{
1380 NS_LOG_FUNCTION(this << curHopLimit);
1381 m_curHopLimit = curHopLimit;
1382}
1383
1390
1391void
1393{
1394 NS_LOG_FUNCTION(this << version);
1395 m_abroVersion = version;
1396}
1397
1398uint16_t
1404
1405void
1411
1418
1419void
1425
1426bool
1429{
1430 Ipv6Address addr = abro.GetRouterAddress();
1431 if (addr == Ipv6Address::GetAny())
1432 {
1433 return false;
1434 }
1435 m_abroBorderRouter = addr;
1436
1437 m_abroVersion = abro.GetVersion();
1439 return true;
1440}
1441
1453
1456 Ipv6Address dst,
1457 Icmpv6NS& nsHdr,
1461{
1463
1464 p->AddHeader(earo);
1465 p->AddHeader(tlla);
1466 p->AddHeader(slla);
1467
1469 dst,
1470 p->GetSize() + nsHdr.GetSerializedSize(),
1471 PROT_NUMBER);
1472 p->AddHeader(nsHdr);
1473
1474 return p;
1475}
1476
1479 Ipv6Address dst,
1480 Icmpv6NA& naHdr,
1482{
1484 p->AddHeader(earo);
1485
1487 dst,
1488 p->GetSize() + naHdr.GetSerializedSize(),
1489 PROT_NUMBER);
1490 p->AddHeader(naHdr);
1491
1492 return p;
1493}
1494
1497 Ipv6Address dst,
1500 Ptr<SixLowPanRaEntry> raEntry)
1501{
1502 NS_LOG_FUNCTION(src << dst << raEntry);
1504
1505 // Build RA Hdr
1506 Icmpv6RA ra = raEntry->BuildRouterAdvertisementHeader();
1507
1508 // PIO
1509 for (const auto& pio : raEntry->BuildPrefixInformationOptions())
1510 {
1511 p->AddHeader(pio);
1512 }
1513
1514 // ABRO
1515 p->AddHeader(raEntry->MakeAbro());
1516
1517 // SLLAO
1518 p->AddHeader(slla);
1519
1520 // 6CIO
1521 p->AddHeader(cio);
1522
1523 // 6CO
1524 for (const auto& [cid, ctx] : raEntry->GetContexts())
1525 {
1527 sixHdr.SetContextPrefix(ctx->GetContextPrefix());
1528 sixHdr.SetFlagC(ctx->IsFlagC());
1529 sixHdr.SetCid(ctx->GetCid());
1530
1531 Time difference = Simulator::Now() - ctx->GetLastUpdateTime();
1532 double updatedValidTime =
1533 ctx->GetValidTime().GetMinutes() - std::floor(difference.GetMinutes());
1534
1535 // we want to advertise only contexts with a remaining validity time greater than 1
1536 // minute.
1537 if (updatedValidTime > 1)
1538 {
1539 sixHdr.SetValidTime(updatedValidTime);
1540 p->AddHeader(sixHdr);
1541 }
1542 }
1543
1544 // Compute checksum after everything is added
1545 ra.CalculatePseudoHeaderChecksum(src, dst, p->GetSize() + ra.GetSerializedSize(), PROT_NUMBER);
1546 p->AddHeader(ra);
1547
1548 return p;
1549}
1550
1551bool
1553 Ptr<Packet> p,
1554 Icmpv6NS& nsHdr,
1558 bool& hasEaro)
1559{
1560 NS_LOG_FUNCTION(p);
1561 p->RemoveHeader(nsHdr);
1562 bool hasSllao = false;
1563 bool hasTllao = false;
1564 hasEaro = false;
1565 bool next = true;
1566
1567 while (next && p->GetSize() > 0)
1568 {
1569 uint8_t type;
1570 p->CopyData(&type, sizeof(type));
1571
1572 switch (type)
1573 {
1575 if (!hasSllao)
1576 {
1577 p->RemoveHeader(slla);
1578 hasSllao = true;
1579 }
1580 break;
1582 if (!hasTllao)
1583 {
1584 p->RemoveHeader(tlla);
1585 hasTllao = true;
1586 }
1587 break;
1589 if (!hasEaro)
1590 {
1591 p->RemoveHeader(earo);
1592 hasEaro = true;
1593 }
1594 break;
1595 default:
1596 // unknown option, quit
1597 next = false;
1598 }
1599 if (p->GetSize() == 0)
1600 {
1601 next = false;
1602 }
1603 }
1604
1605 // If it contains EARO, then it must have SLLAO and TLLAO, and SLLAO address == TLLAO address
1606 if (hasEaro)
1607 {
1608 if (!(hasSllao && hasTllao)) // error
1609 {
1610 // Address registration proxy is not yet supported.
1612 "NS(EARO) message MUST have both source and target link layer options. Ignoring.");
1613 return false;
1614 }
1615 if (slla.GetAddress() != tlla.GetAddress())
1616 {
1617 NS_LOG_LOGIC("Discarding NS(EARO) with different target and source addresses: TLLAO ("
1618 << tlla.GetAddress() << "), SLLAO (" << slla.GetAddress() << ")");
1619 return false;
1620 }
1621 }
1622
1623 return true; // Valid NS (May or may not contain EARO)
1624}
1625
1626bool
1628 Ptr<Packet> p,
1629 Icmpv6NA& naHdr,
1632 bool& hasEaro)
1633{
1634 NS_LOG_FUNCTION(p);
1635 p->RemoveHeader(naHdr);
1636 hasEaro = false;
1637 bool next = true;
1638
1639 // search all options following the NA header
1640 while (next && p->GetSize() > 0)
1641 {
1642 uint8_t type;
1643 p->CopyData(&type, sizeof(type));
1644
1645 switch (type)
1646 {
1647 case Icmpv6Header::ICMPV6_OPT_LINK_LAYER_TARGET: // NA + EARO + TLLAO
1648 p->RemoveHeader(tlla);
1649 break;
1651 p->RemoveHeader(earo);
1652 hasEaro = true;
1653 break;
1654 default:
1655 // unknown option, quit
1656 next = false;
1657 }
1658 if (p->GetSize() == 0)
1659 {
1660 next = false;
1661 }
1662 }
1663
1664 return true;
1665}
1666
1667bool
1669 Icmpv6RS& rsHdr,
1672{
1673 NS_LOG_FUNCTION(p);
1674 p->RemoveHeader(rsHdr);
1675 bool hasSlla = false;
1676 bool hasCio = false;
1677 bool next = true;
1678
1679 while (next && p->GetSize() > 0)
1680 {
1681 uint8_t type;
1682 p->CopyData(&type, sizeof(type));
1683
1684 switch (type)
1685 {
1687 p->RemoveHeader(slla);
1688 hasSlla = true;
1689 break;
1691 p->RemoveHeader(cio);
1692 hasCio = true;
1693 break;
1694 default:
1695 // unknown option, quit
1696 next = false;
1697 }
1698 if (p->GetSize() == 0)
1699 {
1700 next = false;
1701 }
1702 }
1703
1704 if (!hasSlla)
1705 {
1706 NS_LOG_LOGIC("RS message MUST have source link-layer option, discarding it.");
1707 return false;
1708 }
1709
1710 if (!hasCio)
1711 {
1712 NS_LOG_LOGIC("RS message MUST have sixlowpan capability indication option, discarding it.");
1713 return false;
1714 }
1715
1716 return true;
1717}
1718
1719bool
1721 Icmpv6RA& raHdr,
1722 std::list<Icmpv6OptionPrefixInformation>& pios,
1726 std::list<Icmpv6OptionSixLowPanContext>& contexts)
1727{
1728 NS_LOG_FUNCTION(p);
1729 // Remove the RA header first
1730 p->RemoveHeader(raHdr);
1731
1732 bool hasAbro = false;
1733 bool hasSlla = false;
1734 bool hasCio = false;
1735
1736 bool next = true;
1737 while (next && p->GetSize() > 0)
1738 {
1739 uint8_t type = 0;
1740 p->CopyData(&type, sizeof(type));
1741
1744
1745 switch (type)
1746 {
1748 p->RemoveHeader(prefix);
1749 pios.push_back(prefix);
1750 break;
1752 p->RemoveHeader(context);
1753 contexts.push_back(context);
1754 break;
1756 p->RemoveHeader(abro);
1757 hasAbro = true;
1758 break;
1760 // generates an entry in NDISC table with m_router = true
1761 // Deferred to when we receive the address registration confirmation
1762 p->RemoveHeader(slla);
1763 hasSlla = true;
1764 break;
1766 p->RemoveHeader(cio);
1767 hasCio = true;
1768 break;
1769 default:
1770 NS_LOG_WARN("Ignoring unknown option in RA (type=" << static_cast<uint32_t>(type)
1771 << ")");
1772 next = false;
1773 }
1774 if (p->GetSize() == 0)
1775 {
1776 next = false;
1777 }
1778 }
1779
1780 if (!hasAbro)
1781 {
1782 // RAs MUST contain one (and only one) ABRO
1783 NS_LOG_LOGIC("Ignoring RA: no ABRO");
1784 return false;
1785 }
1786
1787 if (abro.GetRouterAddress() == Ipv6Address::GetAny())
1788 {
1789 NS_LOG_LOGIC("Ignoring RA: ABRO border router address is unspecified");
1790 return false;
1791 }
1792
1793 if (!hasSlla)
1794 {
1795 // RAs must contain one (and only one) LLA
1796 NS_LOG_LOGIC("Ignoring RA: no SLLAO");
1797 return false;
1798 }
1799
1800 if (!hasCio)
1801 {
1802 // RAs must contain one (and only one) 6CIO
1803 NS_LOG_LOGIC("Ignoring RA: no 6CIO");
1804 return false;
1805 }
1806
1807 return true;
1808}
1809} /* namespace ns3 */
a polymophic address class
Definition address.h:114
@ ICMPV6_OPT_AUTHORITATIVE_BORDER_ROUTER
@ ICMPV6_OPT_EXTENDED_ADDRESS_REGISTRATION
void CalculatePseudoHeaderChecksum(Ipv6Address src, Ipv6Address dst, uint16_t length, uint8_t protocol)
Calculate pseudo header checksum for IPv6.
void ReceiveLLA(Icmpv6OptionLinkLayerAddress lla, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
Link layer address option processing.
IpL4Protocol::RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > interface) override
Receive method.
void DoDispose() override
Dispose this object.
uint32_t m_rsMaxRetransmissionCount
Maximum number of multicast RS retransmissions [RFC 7559].
void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
uint32_t m_rsRetransmissionCount
Multicast RS retransmissions counter [RFC 7559].
void DelayedSendMessage(Ptr< Packet > packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
Helper function used during delayed solicitation.
Ptr< Node > GetNode()
Get the node.
Ptr< UniformRandomVariable > m_rsRetransmissionJitter
Random jitter for RS retransmissions.
void HandleRA(Ptr< Packet > p, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
Receive Router Advertisement method.
static constexpr uint8_t PROT_NUMBER
ICMPv6 protocol number (58).
void HandleRS(Ptr< Packet > p, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
Receive Router Solicitation method.
uint8_t m_maxUnicastSolicit
Neighbor Discovery node constants: max unicast solicitations.
Ptr< Node > m_node
The node.
IpL4Protocol::DownTargetCallback6 m_downTarget
callback to Ipv6::Send
Ptr< NdiscCache > FindCache(Ptr< NetDevice > device)
Get the cache corresponding to the device.
Time m_retransmissionTime
Neighbor Discovery node constants: retransmission timer.
void HandleNS(Ptr< Packet > p, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
Receive Neighbor Solicitation method.
virtual bool Lookup(Ipv6Address dst, Ptr< NetDevice > device, Ptr< NdiscCache > cache, Address *hardwareDestination)
Lookup in the ND cache for the IPv6 address.
EventId m_handleRsTimeoutEvent
RS timeout handler event.
void SendMessage(Ptr< Packet > packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
Send a packet via ICMPv6, note that packet already contains ICMPv6 header.
Time GetReachableTime() const
Neighbor Discovery node constants: reachable time.
void SetNode(Ptr< Node > node)
Set the node.
void HandleNA(Ptr< Packet > p, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
Receive Neighbor Advertisement method.
ICMPv6 Neighbor Advertisement header.
void SetFlagS(bool s)
Set the S flag.
void SetIpv6Target(Ipv6Address target)
Set the IPv6 target field.
void SetFlagR(bool r)
Set the R flag.
Ipv6Address GetIpv6Target() const
Get the IPv6 target field.
uint32_t GetSerializedSize() const override
Get the serialized size.
void SetFlagO(bool o)
Set the O flag.
ICMPv6 Neighbor Solicitation header.
uint32_t GetSerializedSize() const override
Get the serialized size.
Ipv6Address GetIpv6Target() const
Get the IPv6 target field.
ICMPv6 Option Prefix Information.
void SetValidTime(uint32_t validTime)
Set the valid time of the information.
void SetPrefix(Ipv6Address prefix)
Set the IPv6 prefix.
void SetFlags(uint8_t flags)
Set the flags.
void SetPrefixLength(uint8_t prefixLength)
Set the prefix length.
void SetPreferredTime(uint32_t preferredTime)
Set the preferred time of the information.
ICMPv6 Authoritative Border Router Option header (see RFC 8505).
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.
uint16_t GetValidLifeTime() const
Get the valid lifetime field.
void SetRouterAddress(Ipv6Address router)
Set the 6LBR address field.
Ipv6Address GetRouterAddress() const
Get the 6LBR address field.
6LoWPAN Capability Indication Option - see RFC 7400.
void SetOption(SixLowPanCapability_e option)
Set an option.
@ B
The node is a 6LBR (see RFC 8505).
@ E
The node is an IPv6 ND Registrar (see RFC 8505).
ICMPv6 SixLowPan Context Option header (see RFC 8505).
void SetFlagC(bool c)
Set the C flag.
void SetContextPrefix(Ipv6Prefix prefix)
Set the context prefix field.
void SetValidTime(uint16_t time)
Set the valid lifetime field.
void SetCid(uint8_t cid)
Set the context identifier field.
ICMPv6 Extended Address Registration Option header RFC 8505.
std::vector< uint8_t > GetRovr() const
Get the ROVR field.
uint16_t GetRegTime() const
Get the registration lifetime field.
ICMPv6 Router Advertisement header.
void SetLifeTime(uint16_t l)
Set the node Life time (Neighbor Discovery).
uint32_t GetRetransmissionTime() const
Get the node Retransmission time (Neighbor Discovery).
void SetFlagH(bool h)
Set the H flag.
void SetRetransmissionTime(uint32_t r)
Set the node Retransmission time (Neighbor Discovery).
void SetCurHopLimit(uint8_t m)
Set the IPv6 maximum number of jumps.
void SetFlagO(bool o)
Set the O flag.
void SetFlagM(bool m)
Set the M flag.
void SetReachableTime(uint32_t r)
Set the node Reachable time (Neighbor Discovery).
uint32_t GetSerializedSize() const override
Get the serialized size.
uint16_t GetLifeTime() const
Get the node Life time (Neighbor Discovery).
uint32_t GetReachableTime() const
Get the node Reachable time (Neighbor Discovery).
uint8_t GetCurHopLimit() const
Get the IPv6 maximum number of jumps.
bool GetFlagO() const
Get the O flag.
bool GetFlagM() const
Get the M flag.
bool GetFlagH() const
Get the H flag.
ICMPv6 Router Solicitation header.
uint32_t GetSerializedSize() const override
Get the serialized size.
RxStatus
Rx status codes.
Describes an IPv6 address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
Packet header for IPv6.
Definition ipv6-header.h:24
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
void SetSource(Ipv6Address src)
Set the "Source address" field.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Ipv6Address GetDestination() const
Get the "Destination address" field.
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Ipv6Address GetSource() const
Get the "Source address" field.
void SetNextHeader(uint8_t next)
Set the "Next header" field.
virtual void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)=0
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
@ GLOBAL
Global address (2000::/3).
The IPv6 representation of a network interface.
IPv6 layer implementation.
static constexpr uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
Describes an IPv6 prefix.
uint8_t GetPrefixLength() const
Get prefix length.
Ipv6Address ConvertToIpv6Address() const
Convert the Prefix into an IPv6 Address.
A record that holds information about a NdiscCache entry.
void StartReachableTimer()
Start the reachable timer.
std::list< Ipv6PayloadHeaderPair > MarkReachable(Address mac)
Changes the state to this entry to REACHABLE.
void SetMacAddress(Address mac)
Set the MAC address of this entry.
void SetRouter(bool router)
Set the node type.
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition object.cc:409
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:518
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:437
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
void SetManagedFlag(bool managedFlag)
Set managed flag.
void SetHomeAgentFlag(bool homeAgentFlag)
Set "home agent" flag.
void SetCurHopLimit(uint8_t curHopLimit)
Set current hop limit.
Icmpv6OptionSixLowPanAuthoritativeBorderRouter MakeAbro()
Build an ABRO header.
std::list< Ptr< SixLowPanNdPrefix > > m_prefixes
Advertised Prefixes.
uint32_t GetRouterLifeTime() const
Get router lifetime.
uint32_t m_retransTimer
Retransmission timer in milliseconds.
uint16_t m_abroValidLifeTime
Valid lifetime value for ABRO (units of 60 seconds).
void RemovePrefix(Ptr< SixLowPanNdPrefix > prefix)
Remove a prefix from the ones advertised on interface.
bool IsOtherConfigFlag() const
Is "other config" flag enabled ?
uint8_t GetCurHopLimit() const
Get current hop limit.
bool m_homeAgentFlag
Flag to add HA (home agent) flag in RA.
std::list< Ptr< SixLowPanNdPrefix > > GetPrefixes() const
Get the prefixes advertised for this interface.
Ipv6Address m_abroBorderRouter
Border Router address for ABRO.
SixLowPanRaEntry()
void SetRouterLifeTime(uint32_t time)
Set router lifetime.
uint32_t GetRetransTimer() const
Get retransmission timer.
void SetAbroVersion(uint32_t version)
Set version value (ABRO).
bool m_otherConfigFlag
Other configuration flag.
Icmpv6RA BuildRouterAdvertisementHeader() const
Builds an Icmpv6RA from the stored data.
void SetAbroValidLifeTime(uint16_t time)
Set valid lifetime value (ABRO).
uint32_t GetReachableTime() const
Get reachable time.
bool m_managedFlag
Managed flag.
std::map< uint8_t, Ptr< SixLowPanNdContext > > GetContexts() const
Get list of 6LoWPAN contexts advertised for this interface.
uint8_t m_curHopLimit
Current hop limit (TTL).
uint32_t GetAbroVersion() const
Get version value (ABRO).
Ipv6Address GetAbroBorderRouterAddress() const
Get Border Router address (ABRO).
void SetRetransTimer(uint32_t timer)
Set retransmission timer.
bool IsHomeAgentFlag() const
Is "home agent" flag enabled ?
std::list< Icmpv6OptionPrefixInformation > BuildPrefixInformationOptions()
Builds a container of Icmpv6OptionPrefixInformation from the stored data.
void SetAbroBorderRouterAddress(Ipv6Address border)
Set Border Router address (ABRO).
uint32_t m_routerLifeTime
Router life time in seconds.
uint32_t m_reachableTime
Reachable time in milliseconds.
bool IsManagedFlag() const
Is managed flag enabled ?
void SetOtherConfigFlag(bool otherConfigFlag)
Set "other config" flag.
void SetReachableTime(uint32_t time)
Set reachable time.
~SixLowPanRaEntry()
uint32_t m_abroVersion
Version value for ABRO.
uint16_t GetAbroValidLifeTime() const
Get valid lifetime value (ABRO).
void AddContext(Ptr< SixLowPanNdContext > context)
Add a 6LoWPAN context to advertise on interface.
void RemoveContext(Ptr< SixLowPanNdContext > context)
Remove a 6LoWPAN context.
bool ParseAbro(Icmpv6OptionSixLowPanAuthoritativeBorderRouter abro)
Parse an ABRO and records the appropriate params.
std::map< uint8_t, Ptr< SixLowPanNdContext > > m_contexts
List of 6LoWPAN contexts advertised.
void AddPrefix(Ptr< SixLowPanNdPrefix > prefix)
Add a prefix to advertise on interface.
An optimization of the ND protocol for 6LoWPANs.
void AddAdvertisedContext(Ptr< SixLowPanNetDevice > device, Ipv6Prefix context)
Add a context to be advertised on an interface (6LBR).
void SendSixLowPanNsWithEaro(Ipv6Address addrToRegister, Ipv6Address dst, Address dstMac, uint16_t time, const std::vector< uint8_t > &rovr, Ptr< NetDevice > sixDevice)
Send a NS for 6LoWPAN ND (+ EARO, SLLAO).
void FunctionDadTimeout(Ipv6Interface *interface, Ipv6Address addr) override
Function called when DAD timeout.
static Ptr< Packet > MakeRaPacket(Ipv6Address src, Ipv6Address dst, Icmpv6OptionLinkLayerAddress &slla, Icmpv6OptionSixLowPanCapabilityIndication &cio, Ptr< SixLowPanRaEntry > raEntry)
Constructs a RA packet (raEntry contains info for raHdr, pios, abro and contexts).
Time m_routerLifeTime
Default Router Lifetime.
void HandleSixLowPanRA(Ptr< Packet > packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
RA handler for 6LoWPAN ND.
static bool ParseAndValidateRaPacket(Ptr< Packet > p, Icmpv6RA &raHdr, std::list< Icmpv6OptionPrefixInformation > &pios, Icmpv6OptionSixLowPanAuthoritativeBorderRouter &abro, Icmpv6OptionLinkLayerAddress &slla, Icmpv6OptionSixLowPanCapabilityIndication &cio, std::list< Icmpv6OptionSixLowPanContext > &contexts)
Parses RA packet and populates params, returning true if packet is valid.
void SendSixLowPanMulticastRS(Ipv6Address src, Address hardwareAddress)
Send a Multicast RS (+ 6CIO) (RFC6775 5.3).
void SendSixLowPanRA(Ipv6Address src, Ipv6Address dst, Ptr< Ipv6Interface > interface)
Send a RA for 6LoWPAN ND (+ PIO, 6CO, 6CIO, ABRO, SLLAO).
TracedCallback< Ptr< Packet > > m_naRxTrace
Trace fired whenever an NA packet is received.
TracedCallback< Ipv6Address, bool, uint8_t > m_addressRegistrationResultTrace
Traces address registration result (address, success/failure, status code).
static Ptr< Packet > MakeNaEaroPacket(Ipv6Address src, Ipv6Address dst, Icmpv6NA &naHdr, Icmpv6OptionSixLowPanExtendedAddressRegistration &earo)
Construct NA (EARO) packet.
static bool ParseAndValidateNsEaroPacket(Ptr< Packet > p, Icmpv6NS &nsHdr, Icmpv6OptionLinkLayerAddress &slla, Icmpv6OptionLinkLayerAddress &tlla, Icmpv6OptionSixLowPanExtendedAddressRegistration &earo, bool &hasEaro)
Parses NS packet and populates params, returning true if packet is a valid NS/NS(EARO) packet.
void AddressRegistration()
Address registration procedure.
Time m_pioPreferredLifeTime
Default Prefix Information Preferred Lifetime.
Time m_maxRtrSolicitationInterval
Maximum RS Retransmission interval.
Time m_contextValidLifeTime
Default Context Valid Lifetime.
std::list< SixLowPanRegisteredAddress > m_registeredAddresses
Addresses that have been registered.
void SendSixLowPanNaWithEaro(Ipv6Address src, Ipv6Address dst, Ipv6Address target, uint16_t time, const std::vector< uint8_t > &rovr, Ptr< NetDevice > sixDevice, uint8_t status)
Send a NA for 6LoWPAN ND (+ EARO).
std::map< Ptr< SixLowPanNetDevice >, Ptr< SixLowPanRaEntry > > m_raEntries
Router Advertisement entries (if the node is a 6LBR).
void HandleSixLowPanNS(Ptr< Packet > packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
NS handler for 6LoWPAN ND.
void SetRovr(const std::vector< uint8_t > rovr)
Sets the ROVR for the node.
Time m_pioValidLifeTime
Default Prefix Information Valid Lifetime.
SixLowPanNodeStatus_e m_nodeRole
Status of the node.
std::set< Ipv6Address > m_raCache
Set of 6LBR addresses from which a RA has already been processed.
static bool ParseAndValidateNaEaroPacket(Ptr< Packet > p, Icmpv6NA &naHdr, Icmpv6OptionLinkLayerAddress &tlla, Icmpv6OptionSixLowPanExtendedAddressRegistration &earo, bool &hasEaro)
Parses NA packet and populates params, returning true if packet is valid.
std::list< SixLowPanPendingRa > m_pendingRas
RA awaiting processing (address registration).
void AddressRegistrationSuccess(Ipv6Address registrar)
Address registration success or failure.
static bool ParseAndValidateRsPacket(Ptr< Packet > p, Icmpv6RS &rsHdr, Icmpv6OptionLinkLayerAddress &slla, Icmpv6OptionSixLowPanCapabilityIndication &cio)
Parses RS packet and populates params, returning true if packet is valid.
@ SixLowPanNodeOnly
a 6LN that can not become a 6LR
@ SixLowPanNode
a 6LN that can (and want to) become a 6LR
void SetInterfaceAs6lbr(Ptr< SixLowPanNetDevice > device)
Set an interface to be used as a 6LBR.
bool IsBorderRouterOnInterface(Ptr< SixLowPanNetDevice > device) const
Checks if an interface is set as 6LBR.
Ptr< SixLowPanNdBindingTable > FindBindingTable(Ptr< Ipv6Interface > interface)
Find the binding table corresponding to the IPv6 interface.
uint16_t m_regTime
The amount of time (units of 60 seconds) that the router should retain the NCE for the node.
AddressPendingRegistration m_addrPendingReg
Address currently being Registered.
TracedCallback< Ipv6Address > m_multicastRsTrace
Trace fired whenever a multicast RS is sent.
EventId m_addressRegistrationEvent
Address Registration event.
void DoInitialize() override
Initialize() implementation.
@ DUPLICATE_ADDRESS
Duplicate Address.
bool Lookup(Ptr< Packet > p, const Ipv6Header &ipHeader, Ipv6Address dst, Ptr< NetDevice > device, Ptr< NdiscCache > cache, Address *hardwareDestination) override
Lookup in the ND cache for the IPv6 address (similar as ARP protocol).
void RemoveAdvertisedContext(Ptr< SixLowPanNetDevice > device, Ipv6Prefix context)
Remove a context to be advertised on an interface (6LBR).
static Ptr< Packet > MakeNsEaroPacket(Ipv6Address src, Ipv6Address dst, Icmpv6NS &nsHdr, Icmpv6OptionLinkLayerAddress &slla, Icmpv6OptionLinkLayerAddress &tlla, Icmpv6OptionSixLowPanExtendedAddressRegistration &earo)
Construct NS (EARO) packet.
void NotifyNewAggregate() override
This method is called by AggregateObject and completes the aggregation by setting the node in the ICM...
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
BindingTableList m_bindingTableList
Binding Table for 6LoWPAN ND.
void HandleSixLowPanRS(Ptr< Packet > packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
RS handler for 6LoWPAN ND.
Ptr< RandomVariableStream > m_addressRegistrationJitter
Random jitter before sending address registrations.
void AddressRegistrationTimeout()
Address registration timeout handler.
~SixLowPanNdProtocol() override
Destructor.
std::vector< uint8_t > m_rovr
Node ROVR.
void HandleSixLowPanNA(Ptr< Packet > packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr< Ipv6Interface > interface)
NA handler for 6LoWPAN ND.
static TypeId GetTypeId()
Get the type ID.
void SetAdvertisedPrefix(Ptr< SixLowPanNetDevice > device, Ipv6Prefix prefix)
Set a prefix to be announced on an interface (6LBR).
uint16_t m_advance
How many seconds before registration expiry to begin re-registration.
void DoDispose() override
Dispose this object.
EventId m_addressRegistrationTimeoutEvent
Address Registration timeout event.
uint8_t m_addressRegistrationCounter
Number of retries of an address registration.
void CreateBindingTable(Ptr< NetDevice > device, Ptr< Ipv6Interface > interface)
Create and register a binding table for the given device and interface.
Time m_abroValidLifeTime
Default ABRO Valid Lifetime.
enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, const Ipv6Header &header, Ptr< Ipv6Interface > interface) override
Receive method.
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
double GetMinutes() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:388
AttributeValue implementation for Time.
Definition nstime.h:1375
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
Hold an unsigned integer type.
Definition uinteger.h:34
#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
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:250
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:273
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:1376
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1396
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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:35
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:690
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#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_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:253
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:288
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1256
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1290
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
Struct holding data about a pending RA being processed.
std::list< std::pair< Ipv6Address, Icmpv6OptionPrefixInformation > > addressesToBeRegistered
Addresses pending registration with their PIOs.
Icmpv6OptionLinkLayerAddress llaHdr
Contains MAC address of the RA sender (6LBR).
Ptr< Ipv6Interface > interface
Interface that received the RA.
Ipv6Address source
Origin of the RA / Registering Node (will be a 6LBR).
Struct holding data about registered addresses.
Icmpv6OptionLinkLayerAddress llaHdr
Contains MAC address of the RA sender (6LBR).
Ipv6Address registrar
Registering node (link-local addr / gaddr of 6LBR).
Ptr< Ipv6Interface > interface
Interface used for the registration.
Icmpv6OptionPrefixInformation pioHdr
Prefix Information Option for the address being registered.