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
401
402void
404 const Ipv6Address& src,
405 const Ipv6Address& dst,
406 Ptr<Ipv6Interface> interface)
407{
408 NS_LOG_FUNCTION(this << pkt << src << dst << interface);
409
410 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
411 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
412 if (!sixLowPanNetDevice)
413 {
414 HandleNS(pkt, src, dst, interface);
415 return;
416 }
417
418 // NS (EARO) — only a 6LBR maintains a binding table and handles registration.
420 {
421 NS_LOG_LOGIC("Discarding NS(EARO): not a 6LBR");
422 return;
423 }
424
425 if (src == Ipv6Address::GetAny())
426 {
427 NS_LOG_LOGIC("Discarding a NS from unspecified source address");
428 return;
429 }
430
431 if (dst.IsMulticast())
432 {
433 NS_LOG_LOGIC("Discarding a NS sent to a multicast destination");
434 return;
435 }
436
437 Ptr<Packet> packet = pkt->Copy();
438
439 Icmpv6NS nsHdr;
440 Icmpv6OptionLinkLayerAddress sllaoHdr(true);
441 Icmpv6OptionLinkLayerAddress tllaoHdr(false);
443 bool hasEaro = false;
444
445 if (!ParseAndValidateNsEaroPacket(packet, nsHdr, sllaoHdr, tllaoHdr, earoHdr, hasEaro))
446 {
447 NS_LOG_LOGIC("Discarding invalid NS(EARO)");
448 return;
449 }
450 Ipv6Address target = nsHdr.GetIpv6Target();
451
452 // Check if hasEaro
453 if (!hasEaro)
454 {
455 // Let the "normal" Icmpv6L4Protocol handle it.
456 HandleNS(pkt, src, dst, interface);
457 return;
458 }
459
460 Ptr<SixLowPanNdBindingTable> bindingTable = FindBindingTable(interface);
461 NS_ASSERT_MSG(bindingTable, "Can not find a SixLowPanNdBindingTable");
462
463 Ptr<NdiscCache> cache = DynamicCast<NdiscCache>(FindCache(sixLowPanNetDevice));
464 NS_ASSERT_MSG(cache, "Can not find a NdiscCache");
465
466 // Validate: reject if a reachable binding exists for this target with a different ROVR.
467 auto btEntry = bindingTable->Lookup(target);
468 if (btEntry && btEntry->IsReachable() && btEntry->GetRovr() != earoHdr.GetRovr())
469 {
470 NS_LOG_LOGIC("NS EARO: ROVR mismatch, discarding");
472 src,
473 target,
474 earoHdr.GetRegTime(),
475 earoHdr.GetRovr(),
476 sixLowPanNetDevice,
478 return;
479 }
480
481 // Update or create Binding Table entry.
482 if (!btEntry)
483 {
484 btEntry = bindingTable->Add(target);
485 btEntry->SetRovr(earoHdr.GetRovr());
486 }
487 btEntry->MarkReachable(earoHdr.GetRegTime());
488
489 // Update or create Neighbor Cache entry.
490 NdiscCache::Entry* ncEntry = cache->Lookup(target);
491 if (!ncEntry)
492 {
493 ncEntry = cache->Add(target);
494 }
495 ncEntry->SetRouter(false);
496 ncEntry->SetMacAddress(sllaoHdr.GetAddress());
497 ncEntry->MarkReachable();
498 ncEntry->StartReachableTimer();
499
500 // Install a /128 host route for non-link-local registered addresses.
501 if (!target.IsLinkLocal())
502 {
503 Ptr<Ipv6L3Protocol> ipv6l3Protocol = m_node->GetObject<Ipv6L3Protocol>();
504 ipv6l3Protocol->GetRoutingProtocol()->NotifyAddRoute(
505 target,
506 Ipv6Prefix(128),
507 src,
508 ipv6l3Protocol->GetInterfaceForDevice(interface->GetDevice()));
509 }
510
512 src,
513 target,
514 earoHdr.GetRegTime(),
515 earoHdr.GetRovr(),
516 sixLowPanNetDevice,
517 0);
518}
519
520void
522 const Ipv6Address& src,
523 const Ipv6Address& dst,
524 Ptr<Ipv6Interface> interface)
525{
526 NS_LOG_FUNCTION(this << *packet << src << dst << interface);
527
528 if (src == Ipv6Address::GetAny())
529 {
530 NS_LOG_LOGIC("Discarding a NA from unspecified source address (" << Ipv6Address::GetAny()
531 << ")");
532 return;
533 }
534
535 m_naRxTrace(packet->Copy());
536
537 Ptr<Packet> p = packet->Copy();
538
539 Icmpv6NA naHdr;
542
543 bool hasEaro = false;
544 if (!ParseAndValidateNaEaroPacket(packet, naHdr, tlla, earo, hasEaro))
545 {
546 return; // note that currently it will always return valid
547 }
548
549 // NA without EARO: pass to the standard handler for address resolution.
550 if (!hasEaro)
551 {
552 HandleNA(p, naHdr.GetIpv6Target(), dst, interface);
553 return;
554 }
555
556 // NA (EARO) — validate before processing the registration result.
557 if (earo.GetRovr() != m_rovr)
558 {
559 NS_LOG_LOGIC("NA EARO: ROVR mismatch, discarding");
560 return;
561 }
562
563 if (!m_addrPendingReg.isValid ||
564 m_addrPendingReg.addressPendingRegistration != naHdr.GetIpv6Target())
565 {
566 NS_LOG_LOGIC("NA EARO: target does not match pending registration, discarding");
567 return;
568 }
569
570 // Process registration result.
571 bool registrationSucceeded = (earo.GetStatus() == SUCCESS);
572 m_addressRegistrationResultTrace(m_addrPendingReg.addressPendingRegistration,
573 registrationSucceeded,
574 earo.GetStatus());
575 if (!registrationSucceeded)
576 {
577 // Let the retransmit timeout handle retry up to the maximum count.
578 return;
579 }
581}
582
583void
585 const Ipv6Address& src,
586 const Ipv6Address& dst,
587 Ptr<Ipv6Interface> interface)
588{
589 NS_LOG_FUNCTION(this << packet << src << dst << interface);
590
591 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
592 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
593 if (!sixLowPanNetDevice)
594 {
595 HandleRS(packet, src, dst, interface);
596 return;
597 }
598
599 // Validate: only a 6LBR responds to RS.
601 {
602 NS_LOG_LOGIC("Discarding an RS because this node is not a router");
603 return;
604 }
605
606 if (src == Ipv6Address::GetAny())
607 {
608 NS_LOG_LOGIC("Discarding a RS from unspecified source address (" << Ipv6Address::GetAny()
609 << ")");
610 return;
611 }
612
613 Icmpv6RS rsHdr;
616
617 if (!ParseAndValidateRsPacket(packet, rsHdr, slla, cio))
618 {
619 return;
620 }
621
622 // Update or create Neighbor Cache entry for the soliciting node.
623 Ptr<NdiscCache> neighbourCache = DynamicCast<NdiscCache>(FindCache(sixLowPanNetDevice));
624 NS_ASSERT_MSG(neighbourCache, "Can not find a NdiscCache");
625
626 auto ncEntry = neighbourCache->Lookup(src);
627 if (!ncEntry)
628 {
629 ncEntry = neighbourCache->Add(src);
630 ncEntry->SetRouter(false);
631 }
632 if (ncEntry->GetMacAddress() != slla.GetAddress())
633 {
634 ncEntry->MarkStale(slla.GetAddress());
635 }
636
637 // Send RA in response.
638 SendSixLowPanRA(interface->GetLinkLocalAddress().GetAddress(), src, interface);
639}
640
641void
643 const Ipv6Address& src,
644 const Ipv6Address& dst,
645 Ptr<Ipv6Interface> interface)
646{
647 NS_LOG_FUNCTION(this << packet << src << dst << interface);
648
649 Ptr<SixLowPanNetDevice> sixLowPanNetDevice =
650 DynamicCast<SixLowPanNetDevice>(interface->GetDevice());
651 if (!sixLowPanNetDevice)
652 {
653 HandleRA(packet, src, dst, interface);
654 return;
655 }
656
657 if (src == Ipv6Address::GetAny())
658 {
659 NS_LOG_LOGIC("Discarding a RA from unspecified source address (" << Ipv6Address::GetAny()
660 << ")");
661 return;
662 }
663
664 // Stop RS retransmissions: receiving any RA from a valid source indicates
665 // a 6LBR is reachable, regardless of whether the RA passes validation below.
666 if (m_handleRsTimeoutEvent.IsPending())
667 {
668 m_handleRsTimeoutEvent.Cancel();
670 }
671
672 Icmpv6RA raHdr;
676 std::list<Icmpv6OptionPrefixInformation> pios;
677 std::list<Icmpv6OptionSixLowPanContext> contexts;
678
679 if (!ParseAndValidateRaPacket(packet, raHdr, pios, abro, slla, cio, contexts))
680 {
681 return;
682 }
683
684 // Deduplicate: only process the first RA from each 6LBR.
685 // Subsequent RAs are dropped until ABRO version management is implemented.
686 if (m_raCache.count(abro.GetRouterAddress()))
687 {
688 return;
689 }
690 m_raCache.insert(abro.GetRouterAddress());
691
692 // Build the set of addresses to register: link-local first (no PIO for
693 // link-local), then one autoconfigured global address per PIO.
694 SixLowPanPendingRa pending;
695 pending.source = src;
696 pending.interface = interface;
697 pending.llaHdr = slla;
698 // Add the link-local address first (no PIO for link-local addresses)
699 pending.addressesToBeRegistered.emplace_back(interface->GetLinkLocalAddress().GetAddress(),
701 for (const auto& pio : pios)
702 {
703 Ipv6Address gaddr = Ipv6Address::MakeAutoconfiguredAddress(sixLowPanNetDevice->GetAddress(),
704 pio.GetPrefix());
705 pending.addressesToBeRegistered.emplace_back(gaddr, pio);
706 }
707 m_pendingRas.push_back(pending);
708
710}
711
712bool
714 const Ipv6Header& ipHeader,
715 Ipv6Address dst,
716 Ptr<NetDevice> device,
717 Ptr<NdiscCache> cache,
718 Address* hardwareDestination)
719{
720 if (!cache)
721 {
722 cache = FindCache(device);
723 }
724 if (!cache)
725 {
726 return false;
727 }
728
729 NdiscCache::Entry* ncEntry = cache->Lookup(dst);
730 if (!ncEntry)
731 {
732 // RFC 8505 prohibits multicast neighbor discovery in 6LoWPAN networks.
733 // The base class would send a multicast NS when an entry is not found,
734 // but in 6LoWPAN ND, address resolution is handled via ARO/EARO registration
735 // rather than multicast NS. Return false to let the caller handle the
736 // unresolved address without triggering multicast NS.
737 return false;
738 }
739 return Icmpv6L4Protocol::Lookup(p, ipHeader, dst, device, cache, hardwareDestination);
740}
741
742void
744{
745 NS_LOG_FUNCTION(this << device << interface);
746
748 table->SetDevice(device, interface, this);
749
750 m_bindingTableList.push_back(table);
751}
752
755{
756 NS_LOG_FUNCTION(this << interface);
757
758 Ptr<NetDevice> device = interface->GetDevice();
759 for (const auto& table : m_bindingTableList)
760 {
761 if (table->GetDevice() == device)
762 {
763 return table;
764 }
765 }
766 return nullptr;
767}
768
769void
771{
772 NS_LOG_FUNCTION(this << interface << addr);
773}
774
775void
776SixLowPanNdProtocol::SetRovr(std::vector<uint8_t> rovr)
777{
778 NS_LOG_FUNCTION(this);
779 m_rovr = rovr;
780}
781
782void
784{
785 NS_LOG_FUNCTION(this);
786
788 {
789 return;
790 }
791
792 // Populate m_addrPendingReg if no registration is currently in progress.
793 Time additionalDelay = Seconds(0);
794 if (!m_addrPendingReg.isValid)
795 {
796 if (!m_pendingRas.empty())
797 {
798 // New registration triggered by a received RA.
799 m_addrPendingReg.isValid = true;
800 m_addrPendingReg.addressPendingRegistration =
801 m_pendingRas.front().addressesToBeRegistered.front().first;
802 m_addrPendingReg.registrar = m_pendingRas.front().source;
803 m_addrPendingReg.newRegistration = true;
804 m_addrPendingReg.llaHdr = m_pendingRas.front().llaHdr;
805 m_addrPendingReg.interface = m_pendingRas.front().interface;
806 m_addrPendingReg.pioHdr = m_pendingRas.front().addressesToBeRegistered.front().second;
807 }
808 else if (!m_registeredAddresses.empty())
809 {
810 // Renewal of an already-registered address.
811 m_addrPendingReg.isValid = true;
812 m_addrPendingReg.addressPendingRegistration =
813 m_registeredAddresses.front().registeredAddr;
814 m_addrPendingReg.registrar = m_registeredAddresses.front().registrar;
815 m_addrPendingReg.newRegistration = false;
816 m_addrPendingReg.llaHdr = m_registeredAddresses.front().llaHdr;
817 m_addrPendingReg.interface = m_registeredAddresses.front().interface;
818 m_addrPendingReg.pioHdr = m_registeredAddresses.front().pioHdr;
819
820 Time now = Simulator::Now();
821 if (m_registeredAddresses.front().registrationTimeout > now)
822 {
823 additionalDelay =
824 m_registeredAddresses.front().registrationTimeout - now - Seconds(m_advance);
825 }
826 }
827 else
828 {
829 // No addresses to register — send multicast RS on each interface to solicit an RA.
830 Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol>();
831 NS_ASSERT(ipv6);
832
833 for (uint32_t i = 0; i < ipv6->GetNInterfaces(); ++i)
834 {
835 Ptr<Ipv6Interface> iface = ipv6->GetInterface(i);
836 if (!iface->IsUp())
837 {
838 continue;
839 }
840
841 Ipv6InterfaceAddress ifaddr = iface->GetAddress(0); // typically link-local
842 Ipv6Address lla = ifaddr.GetAddress();
843
846 this,
847 lla,
848 iface->GetDevice()->GetAddress());
849 }
850 return;
851 }
852 }
853
854 // Schedule NS(EARO) and registration timeout.
856
857 Simulator::Schedule(additionalDelay + MilliSeconds(m_addressRegistrationJitter->GetValue()),
859 this,
860 m_addrPendingReg.addressPendingRegistration,
861 m_addrPendingReg.registrar,
862 m_addrPendingReg.llaHdr.GetAddress(),
863 m_regTime,
864 m_rovr,
865 m_addrPendingReg.interface->GetDevice());
866
868 Simulator::Schedule(additionalDelay + m_retransmissionTime +
871 this);
872}
873
874void
876{
877 NS_LOG_FUNCTION(this << registrar);
878 NS_ABORT_MSG_IF(registrar != m_addrPendingReg.registrar,
879 "AddressRegistrationSuccess, mismatch between sender and expected sender "
880 << registrar << " vs expected " << m_addrPendingReg.registrar);
881
882 if (m_addressRegistrationTimeoutEvent.IsPending())
883 {
885 }
886
888
889 // Update the registered address list.
890 if (!m_addrPendingReg.newRegistration)
891 {
892 // Renewal: refresh the timeout and rotate to the back of the queue.
895 m_registeredAddresses.pop_front();
896 m_registeredAddresses.push_back(regAddr);
897 }
898 else
899 {
900 // New registration: record it and consume the address from the pending RA queue.
902 "AddressRegistrationSuccess, expected to register an address from the "
903 "pending RA list, but it's empty");
905 m_pendingRas.front().addressesToBeRegistered.empty(),
906 "AddressRegistrationSuccess, expected to register an address from the pending RA list "
907 << "but the pending registration address list is empty");
908
909 SixLowPanRegisteredAddress newRegisteredAddr;
910 newRegisteredAddr.registrationTimeout = Now() + Minutes(m_regTime);
911 newRegisteredAddr.registeredAddr = m_addrPendingReg.addressPendingRegistration;
912 newRegisteredAddr.registrar = m_addrPendingReg.registrar;
913 newRegisteredAddr.llaHdr = m_addrPendingReg.llaHdr;
914 newRegisteredAddr.interface = m_pendingRas.front().interface;
915 newRegisteredAddr.pioHdr = m_addrPendingReg.pioHdr;
916 m_registeredAddresses.push_back(newRegisteredAddr);
917
918 // Drop the front pending RA once all its addresses have been registered.
919 m_pendingRas.front().addressesToBeRegistered.pop_front();
920 if (m_pendingRas.front().addressesToBeRegistered.empty())
921 {
922 m_pendingRas.pop_front();
923 }
924 }
925
926 // Notify the IPv6 stack to configure the registered address.
927 if (m_addrPendingReg.addressPendingRegistration.IsLinkLocal())
928 {
930 m_addrPendingReg.registrar,
932 m_addrPendingReg.interface);
933 }
934 else
935 {
936 Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol>();
938 ipv6->AddAutoconfiguredAddress(
939 ipv6->GetInterfaceForDevice(m_addrPendingReg.interface->GetDevice()),
940 prefixHdr.GetPrefix(),
941 prefixHdr.GetPrefixLength(),
942 prefixHdr.GetFlags(),
943 prefixHdr.GetValidTime(),
944 prefixHdr.GetPreferredTime(),
945 registrar);
946 }
947
948 // Clear the pending registration and schedule the next one.
949 m_addrPendingReg.isValid = false; // invalidate before scheduling the next registration
953 this);
954}
955
956void
958{
959 NS_LOG_FUNCTION(this);
960
962 !m_addrPendingReg.isValid,
963 "Address Registration Timeout but there is no valid address pending registration. "
964 << "Node ID=" << m_node->GetId());
965
967 {
969 }
970 else
971 {
972 NS_LOG_INFO("Address registration failed for node "
973 << m_node->GetId()
974 << ", address: " << m_addrPendingReg.addressPendingRegistration
975 << ", registrar: " << m_addrPendingReg.registrar
976 << ", retries: " << static_cast<int>(m_addressRegistrationCounter));
977
978 // todo
979 // Add code to remove next hop from the reliable neighbors.
980 // If the re-registration failed (for all of the candidate next hops), remove the address.
981 // If we don't have any address anymore, start sending RS (again).
982 // For now since we only have 1 6LBR we are registering with, we just stop trying to
983 // register with it
984 }
985}
986
987void
989{
990 NS_LOG_FUNCTION(this << device);
991
992 if (m_raEntries.find(device) != m_raEntries.end())
993 {
994 NS_LOG_LOGIC("Not going to reconfigure an interface");
995 return;
996 }
997
999 newRa->SetManagedFlag(false);
1000 newRa->SetHomeAgentFlag(false);
1001 newRa->SetOtherConfigFlag(false);
1002 newRa->SetCurHopLimit(0); // unspecified by this router
1003 newRa->SetRetransTimer(0); // unspecified by this router
1004
1005 newRa->SetReachableTime(0); // unspecified by this router
1006
1007 uint64_t routerLifetime = std::ceil(m_routerLifeTime.GetMinutes());
1008 if (routerLifetime > 0xffff)
1009 {
1010 routerLifetime = 0xffff;
1011 }
1012
1013 newRa->SetRouterLifeTime(routerLifetime);
1014
1016 int32_t interfaceId = ipv6->GetInterfaceForDevice(device);
1017 Ipv6Address borderAddress = Ipv6Address::GetAny();
1018 for (uint32_t i = 0; i < ipv6->GetNAddresses(interfaceId); ++i)
1019 {
1020 if (ipv6->GetAddress(interfaceId, i).GetScope() == Ipv6InterfaceAddress::GLOBAL)
1021 {
1022 borderAddress = ipv6->GetAddress(interfaceId, i).GetAddress();
1023 continue;
1024 }
1025 }
1027 borderAddress == Ipv6Address::GetAny(),
1028 "Can not set a 6LBR because I can't find a global address associated with the interface");
1029 newRa->SetAbroBorderRouterAddress(borderAddress);
1030 newRa->SetAbroVersion(0x66); // placeholder value for testing purposes
1031 newRa->SetAbroValidLifeTime(m_abroValidLifeTime.GetSeconds());
1032
1033 m_raEntries[device] = newRa;
1034}
1035
1036void
1038{
1039 NS_LOG_FUNCTION(this << device << prefix);
1040
1041 if (m_raEntries.find(device) == m_raEntries.end())
1042 {
1043 NS_LOG_LOGIC("Not adding a prefix to an unconfigured interface");
1044 return;
1045 }
1046
1048 prefix.GetPrefixLength(),
1051
1052 m_raEntries[device]->AddPrefix(newPrefix);
1053}
1054
1055void
1057{
1058 NS_LOG_FUNCTION(this << device << context);
1059
1060 if (m_raEntries.find(device) == m_raEntries.end())
1061 {
1062 NS_LOG_LOGIC("Not adding a context to an unconfigured interface");
1063 return;
1064 }
1065 auto contextMap = m_raEntries[device]->GetContexts();
1066
1067 bool found = std::any_of(contextMap.begin(), contextMap.end(), [&context](const auto& entry) {
1068 return entry.second->GetContextPrefix() == context;
1069 });
1070 if (found)
1071 {
1072 NS_LOG_WARN("Not adding an already existing context - remove the old one first "
1073 << context);
1074 return;
1075 }
1076
1077 uint8_t unusedCid;
1078 for (unusedCid = 0; unusedCid < 16; ++unusedCid)
1079 {
1080 if (contextMap.count(unusedCid) == 0)
1081 {
1082 break;
1083 }
1084 }
1085
1086 Ptr<SixLowPanNdContext> newContext =
1087 Create<SixLowPanNdContext>(true, unusedCid, m_contextValidLifeTime, context);
1088 newContext->SetLastUpdateTime(Simulator::Now());
1089
1090 m_raEntries[device]->AddContext(newContext);
1091}
1092
1093void
1095{
1096 NS_LOG_FUNCTION(this << device << context);
1097
1098 if (m_raEntries.find(device) == m_raEntries.end())
1099 {
1100 NS_LOG_LOGIC("Not removing a context from an unconfigured interface");
1101 return;
1102 }
1103
1104 auto contextMap = m_raEntries[device]->GetContexts();
1105
1106 for (const auto& [cid, ctx] : contextMap)
1107 {
1108 if (ctx->GetContextPrefix() == context)
1109 {
1110 m_raEntries[device]->RemoveContext(ctx);
1111 return;
1112 }
1113 }
1114 NS_LOG_WARN("Not removing a non-existing context " << context);
1115}
1116
1117bool
1119{
1120 NS_LOG_FUNCTION(this << device);
1121
1122 return m_raEntries.find(device) != m_raEntries.end();
1123}
1124
1125//
1126// SixLowPanRaEntry class
1127//
1128
1129// NS_LOG_COMPONENT_DEFINE ("SixLowPanRaEntry");
1130
1135
1137 Icmpv6RA raHeader,
1139 std::list<Icmpv6OptionSixLowPanContext> contextList,
1140 std::list<Icmpv6OptionPrefixInformation> prefixList)
1141{
1142 NS_LOG_FUNCTION(this << abroHdr << &prefixList << &contextList);
1143
1144 SetManagedFlag(raHeader.GetFlagM());
1145 SetOtherConfigFlag(raHeader.GetFlagO());
1146 SetHomeAgentFlag(raHeader.GetFlagH());
1148 SetRouterLifeTime(raHeader.GetLifeTime());
1150 SetCurHopLimit(raHeader.GetCurHopLimit());
1151 ParseAbro(abroHdr);
1152
1153 for (const auto& ctxOpt : contextList)
1154 {
1156 context->SetCid(ctxOpt.GetCid());
1157 context->SetFlagC(ctxOpt.IsFlagC());
1158 context->SetValidTime(Minutes(ctxOpt.GetValidTime()));
1159 context->SetContextPrefix(ctxOpt.GetContextPrefix());
1160 context->SetLastUpdateTime(Simulator::Now());
1161
1162 AddContext(context);
1163 }
1164
1165 for (const auto& pfxOpt : prefixList)
1166 {
1168 prefix->SetPrefix(pfxOpt.GetPrefix());
1169 prefix->SetPrefixLength(pfxOpt.GetPrefixLength());
1170 prefix->SetPreferredLifeTime(Seconds(pfxOpt.GetPreferredTime()));
1171 prefix->SetValidLifeTime(Seconds(pfxOpt.GetValidTime()));
1172
1173 AddPrefix(prefix);
1174 }
1175}
1176
1181
1182void
1184{
1185 NS_LOG_FUNCTION(this << prefix);
1186
1187 for (const auto& pfx : m_prefixes)
1188 {
1189 if (pfx->GetPrefix() == prefix->GetPrefix())
1190 {
1191 NS_LOG_WARN("Ignoring an already-existing prefix: " << prefix->GetPrefix());
1192 return;
1193 }
1194 }
1195
1196 m_prefixes.push_back(prefix);
1197}
1198
1199void
1201{
1202 NS_LOG_FUNCTION(this << prefix);
1203
1204 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
1205 {
1206 if ((*it)->GetPrefix() == prefix->GetPrefix())
1207 {
1208 m_prefixes.erase(it);
1209 return;
1210 }
1211 }
1212}
1213
1214std::list<Ptr<SixLowPanNdPrefix>>
1220
1221void
1223{
1224 NS_LOG_FUNCTION(this << context);
1225 m_contexts.emplace(context->GetCid(), context);
1226}
1227
1228void
1230{
1231 NS_LOG_FUNCTION(this);
1232
1233 m_contexts.erase(context->GetCid());
1234}
1235
1236std::map<uint8_t, Ptr<SixLowPanNdContext>>
1242
1245{
1246 NS_LOG_FUNCTION(this);
1247 Icmpv6RA raHdr;
1248 // set RA header information
1249 raHdr.SetFlagM(IsManagedFlag());
1250 raHdr.SetFlagO(IsOtherConfigFlag());
1251 raHdr.SetFlagH(IsHomeAgentFlag());
1256
1257 return raHdr;
1258}
1259
1260std::list<Icmpv6OptionPrefixInformation>
1262{
1263 NS_LOG_FUNCTION(this);
1264 std::list<Icmpv6OptionPrefixInformation> prefixHdrs;
1265
1266 for (const auto& pfx : m_prefixes)
1267 {
1269 prefixHdr.SetPrefixLength(pfx->GetPrefixLength());
1270 prefixHdr.SetFlags(0x40); // We set the Autonomous address configuration only.
1271 prefixHdr.SetValidTime(pfx->GetValidLifeTime().GetSeconds());
1272 prefixHdr.SetPreferredTime(pfx->GetPreferredLifeTime().GetSeconds());
1273 prefixHdr.SetPrefix(pfx->GetPrefix());
1274 prefixHdrs.push_back(prefixHdr);
1275 }
1276
1277 return prefixHdrs;
1278}
1279
1280bool
1286
1287void
1289{
1290 NS_LOG_FUNCTION(this << managedFlag);
1291 m_managedFlag = managedFlag;
1292}
1293
1294bool
1300
1301void
1303{
1304 NS_LOG_FUNCTION(this << otherConfigFlag);
1305 m_otherConfigFlag = otherConfigFlag;
1306}
1307
1308bool
1314
1315void
1317{
1318 NS_LOG_FUNCTION(this << homeAgentFlag);
1319 m_homeAgentFlag = homeAgentFlag;
1320}
1321
1328
1329void
1335
1342
1343void
1349
1356
1357void
1363
1364uint8_t
1370
1371void
1373{
1374 NS_LOG_FUNCTION(this << curHopLimit);
1375 m_curHopLimit = curHopLimit;
1376}
1377
1384
1385void
1387{
1388 NS_LOG_FUNCTION(this << version);
1389 m_abroVersion = version;
1390}
1391
1392uint16_t
1398
1399void
1405
1412
1413void
1419
1420bool
1423{
1424 Ipv6Address addr = abro.GetRouterAddress();
1425 if (addr == Ipv6Address::GetAny())
1426 {
1427 return false;
1428 }
1429 m_abroBorderRouter = addr;
1430
1431 m_abroVersion = abro.GetVersion();
1433 return true;
1434}
1435
1447
1450 Ipv6Address dst,
1451 Icmpv6NS& nsHdr,
1455{
1457
1458 p->AddHeader(earo);
1459 p->AddHeader(tlla);
1460 p->AddHeader(slla);
1461
1463 dst,
1464 p->GetSize() + nsHdr.GetSerializedSize(),
1465 PROT_NUMBER);
1466 p->AddHeader(nsHdr);
1467
1468 return p;
1469}
1470
1473 Ipv6Address dst,
1474 Icmpv6NA& naHdr,
1476{
1478 p->AddHeader(earo);
1479
1481 dst,
1482 p->GetSize() + naHdr.GetSerializedSize(),
1483 PROT_NUMBER);
1484 p->AddHeader(naHdr);
1485
1486 return p;
1487}
1488
1491 Ipv6Address dst,
1494 Ptr<SixLowPanRaEntry> raEntry)
1495{
1496 NS_LOG_FUNCTION(src << dst << raEntry);
1498
1499 // Build RA Hdr
1500 Icmpv6RA ra = raEntry->BuildRouterAdvertisementHeader();
1501
1502 // PIO
1503 for (const auto& pio : raEntry->BuildPrefixInformationOptions())
1504 {
1505 p->AddHeader(pio);
1506 }
1507
1508 // ABRO
1509 p->AddHeader(raEntry->MakeAbro());
1510
1511 // SLLAO
1512 p->AddHeader(slla);
1513
1514 // 6CIO
1515 p->AddHeader(cio);
1516
1517 // 6CO
1518 for (const auto& [cid, ctx] : raEntry->GetContexts())
1519 {
1521 sixHdr.SetContextPrefix(ctx->GetContextPrefix());
1522 sixHdr.SetFlagC(ctx->IsFlagC());
1523 sixHdr.SetCid(ctx->GetCid());
1524
1525 Time difference = Simulator::Now() - ctx->GetLastUpdateTime();
1526 double updatedValidTime =
1527 ctx->GetValidTime().GetMinutes() - std::floor(difference.GetMinutes());
1528
1529 // we want to advertise only contexts with a remaining validity time greater than 1
1530 // minute.
1531 if (updatedValidTime > 1)
1532 {
1533 sixHdr.SetValidTime(updatedValidTime);
1534 p->AddHeader(sixHdr);
1535 }
1536 }
1537
1538 // Compute checksum after everything is added
1539 ra.CalculatePseudoHeaderChecksum(src, dst, p->GetSize() + ra.GetSerializedSize(), PROT_NUMBER);
1540 p->AddHeader(ra);
1541
1542 return p;
1543}
1544
1545bool
1547 Ptr<Packet> p,
1548 Icmpv6NS& nsHdr,
1552 bool& hasEaro)
1553{
1554 NS_LOG_FUNCTION(p);
1555 p->RemoveHeader(nsHdr);
1556 bool hasSllao = false;
1557 bool hasTllao = false;
1558 hasEaro = false;
1559 bool next = true;
1560
1561 while (next && p->GetSize() > 0)
1562 {
1563 uint8_t type;
1564 p->CopyData(&type, sizeof(type));
1565
1566 switch (type)
1567 {
1569 if (!hasSllao)
1570 {
1571 p->RemoveHeader(slla);
1572 hasSllao = true;
1573 }
1574 break;
1576 if (!hasTllao)
1577 {
1578 p->RemoveHeader(tlla);
1579 hasTllao = true;
1580 }
1581 break;
1583 if (!hasEaro)
1584 {
1585 p->RemoveHeader(earo);
1586 hasEaro = true;
1587 }
1588 break;
1589 default:
1590 // unknown option, quit
1591 next = false;
1592 }
1593 if (p->GetSize() == 0)
1594 {
1595 next = false;
1596 }
1597 }
1598
1599 // If it contains EARO, then it must have SLLAO and TLLAO, and SLLAO address == TLLAO address
1600 if (hasEaro)
1601 {
1602 if (!(hasSllao && hasTllao)) // error
1603 {
1604 // Address registration proxy is not yet supported.
1606 "NS(EARO) message MUST have both source and target link layer options. Ignoring.");
1607 return false;
1608 }
1609 if (slla.GetAddress() != tlla.GetAddress())
1610 {
1611 NS_LOG_LOGIC("Discarding NS(EARO) with different target and source addresses: TLLAO ("
1612 << tlla.GetAddress() << "), SLLAO (" << slla.GetAddress() << ")");
1613 return false;
1614 }
1615 }
1616
1617 return true; // Valid NS (May or may not contain EARO)
1618}
1619
1620bool
1622 Ptr<Packet> p,
1623 Icmpv6NA& naHdr,
1626 bool& hasEaro)
1627{
1628 NS_LOG_FUNCTION(p);
1629 p->RemoveHeader(naHdr);
1630 hasEaro = false;
1631 bool next = true;
1632
1633 // search all options following the NA header
1634 while (next && p->GetSize() > 0)
1635 {
1636 uint8_t type;
1637 p->CopyData(&type, sizeof(type));
1638
1639 switch (type)
1640 {
1641 case Icmpv6Header::ICMPV6_OPT_LINK_LAYER_TARGET: // NA + EARO + TLLAO
1642 p->RemoveHeader(tlla);
1643 break;
1645 p->RemoveHeader(earo);
1646 hasEaro = true;
1647 break;
1648 default:
1649 // unknown option, quit
1650 next = false;
1651 }
1652 if (p->GetSize() == 0)
1653 {
1654 next = false;
1655 }
1656 }
1657
1658 return true;
1659}
1660
1661bool
1663 Icmpv6RS& rsHdr,
1666{
1667 NS_LOG_FUNCTION(p);
1668 p->RemoveHeader(rsHdr);
1669 bool hasSlla = false;
1670 bool hasCio = false;
1671 bool next = true;
1672
1673 while (next && p->GetSize() > 0)
1674 {
1675 uint8_t type;
1676 p->CopyData(&type, sizeof(type));
1677
1678 switch (type)
1679 {
1681 p->RemoveHeader(slla);
1682 hasSlla = true;
1683 break;
1685 p->RemoveHeader(cio);
1686 hasCio = true;
1687 break;
1688 default:
1689 // unknown option, quit
1690 next = false;
1691 }
1692 if (p->GetSize() == 0)
1693 {
1694 next = false;
1695 }
1696 }
1697
1698 if (!hasSlla)
1699 {
1700 NS_LOG_LOGIC("RS message MUST have source link-layer option, discarding it.");
1701 return false;
1702 }
1703
1704 if (!hasCio)
1705 {
1706 NS_LOG_LOGIC("RS message MUST have sixlowpan capability indication option, discarding it.");
1707 return false;
1708 }
1709
1710 return true;
1711}
1712
1713bool
1715 Icmpv6RA& raHdr,
1716 std::list<Icmpv6OptionPrefixInformation>& pios,
1720 std::list<Icmpv6OptionSixLowPanContext>& contexts)
1721{
1722 NS_LOG_FUNCTION(p);
1723 // Remove the RA header first
1724 p->RemoveHeader(raHdr);
1725
1726 bool hasAbro = false;
1727 bool hasSlla = false;
1728 bool hasCio = false;
1729
1730 bool next = true;
1731 while (next && p->GetSize() > 0)
1732 {
1733 uint8_t type = 0;
1734 p->CopyData(&type, sizeof(type));
1735
1738
1739 switch (type)
1740 {
1742 p->RemoveHeader(prefix);
1743 pios.push_back(prefix);
1744 break;
1746 p->RemoveHeader(context);
1747 contexts.push_back(context);
1748 break;
1750 p->RemoveHeader(abro);
1751 hasAbro = true;
1752 break;
1754 // generates an entry in NDISC table with m_router = true
1755 // Deferred to when we receive the address registration confirmation
1756 p->RemoveHeader(slla);
1757 hasSlla = true;
1758 break;
1760 p->RemoveHeader(cio);
1761 hasCio = true;
1762 break;
1763 default:
1764 NS_LOG_WARN("Ignoring unknown option in RA (type=" << static_cast<uint32_t>(type)
1765 << ")");
1766 next = false;
1767 }
1768 if (p->GetSize() == 0)
1769 {
1770 next = false;
1771 }
1772 }
1773
1774 if (!hasAbro)
1775 {
1776 // RAs MUST contain one (and only one) ABRO
1777 NS_LOG_LOGIC("Ignoring RA: no ABRO");
1778 return false;
1779 }
1780
1781 if (abro.GetRouterAddress() == Ipv6Address::GetAny())
1782 {
1783 NS_LOG_LOGIC("Ignoring RA: ABRO border router address is unspecified");
1784 return false;
1785 }
1786
1787 if (!hasSlla)
1788 {
1789 // RAs must contain one (and only one) LLA
1790 NS_LOG_LOGIC("Ignoring RA: no SLLAO");
1791 return false;
1792 }
1793
1794 if (!hasCio)
1795 {
1796 // RAs must contain one (and only one) 6CIO
1797 NS_LOG_LOGIC("Ignoring RA: no 6CIO");
1798 return false;
1799 }
1800
1801 return true;
1802}
1803} /* 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.
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.
static const uint8_t PROT_NUMBER
ICMPv6 protocol number (58).
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.