A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-address-generator.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 University of Washington
3 * Copyright (c) 2011 Atishay Jain
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
9
10#include "ns3/abort.h"
11#include "ns3/assert.h"
12#include "ns3/log.h"
13#include "ns3/simulation-singleton.h"
14
15#include <list>
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("Ipv6AddressGenerator");
21
22/**
23 * \ingroup address
24 *
25 * \brief Implementation class of Ipv6AddressGenerator
26 * This generator assigns addresses sequentially from a provided
27 * network address; used in topology code. It also keeps track of all
28 * addresses assigned to perform duplicate detection.
29 *
30 */
32{
33 public:
36
37 /**
38 * \brief Initialise the base network and interfaceId for the generator
39 *
40 * The first call to NextAddress() or GetAddress() will return the
41 * value passed in.
42 *
43 * \param net The network for the base Ipv6Address
44 * \param prefix The prefix of the base Ipv6Address
45 * \param interfaceId The base interface ID used for initialization
46 */
47 void Init(const Ipv6Address net, const Ipv6Prefix prefix, const Ipv6Address interfaceId);
48
49 /**
50 * \brief Get the next network according to the given Ipv6Prefix
51 *
52 * This operation is a pre-increment, meaning that the internal state
53 * is changed before returning the new network address.
54 *
55 * This also resets the interface ID to the base interface ID that was
56 * used for initialization.
57 *
58 * \param prefix The Ipv6Prefix used to set the next network
59 * \returns the IPv6 address of the next network
60 */
62
63 /**
64 * \brief Get the current network of the given Ipv6Prefix
65 *
66 * Does not change the internal state; this just peeks at the current
67 * network
68 *
69 * \param prefix The Ipv6Prefix for the current network
70 * \returns the IPv6 address of the current network
71 */
72 Ipv6Address GetNetwork(const Ipv6Prefix prefix) const;
73
74 /**
75 * \brief Set the interfaceId for the given Ipv6Prefix
76 *
77 * \param interfaceId The interfaceId to set for the current Ipv6Prefix
78 * \param prefix The Ipv6Prefix whose address is to be set
79 */
80 void InitAddress(const Ipv6Address interfaceId, const Ipv6Prefix prefix);
81
82 /**
83 * \brief Get the Ipv6Address that will be allocated upon NextAddress ()
84 *
85 * Does not change the internal state; just is used to peek the next
86 * address that will be allocated upon NextAddress ()
87 *
88 * \param prefix The Ipv6Prefix for the current network
89 * \returns the IPv6 address
90 */
91 Ipv6Address GetAddress(const Ipv6Prefix prefix) const;
92
93 /**
94 * \brief Allocate the next Ipv6Address for the configured network and prefix
95 *
96 * This operation is a post-increment, meaning that the first address
97 * allocated will be the one that was initially configured.
98 *
99 * \param prefix The Ipv6Prefix for the current network
100 * \returns the IPv6 address
101 */
102 Ipv6Address NextAddress(const Ipv6Prefix prefix);
103
104 /**
105 * \brief Reset the networks and Ipv6Address to zero
106 */
107 void Reset();
108
109 /**
110 * \brief Add the Ipv6Address to the list of IPv6 entries
111 *
112 * Typically, this is used by external address allocators that want
113 * to make use of this class's ability to track duplicates. AddAllocated
114 * is always called internally for any address generated by NextAddress ()
115 *
116 * \param addr The Ipv6Address to be added to the list of Ipv6 entries
117 * \returns true on success
118 */
119 bool AddAllocated(const Ipv6Address addr);
120
121 /**
122 * \brief Check the Ipv6Address allocation in the list of IPv6 entries
123 *
124 * \param addr The Ipv6Address to be checked in the list of Ipv4 entries
125 * \returns true if the network is already allocated
126 */
127 bool IsAddressAllocated(const Ipv6Address addr);
128
129 /**
130 * \brief Check if a network has already allocated addresses
131 *
132 * \param addr The Ipv6 network to be checked
133 * \param prefix The Ipv6 network prefix
134 * \returns true if the network is already allocated
135 */
136 bool IsNetworkAllocated(const Ipv6Address addr, const Ipv6Prefix prefix);
137
138 /**
139 * \brief Used to turn off fatal errors and assertions, for testing
140 */
141 void TestMode();
142
143 private:
144 static const uint32_t N_BITS = 128; //!< the number of bits in the address
145 static const uint32_t MOST_SIGNIFICANT_BIT = 0x80; //!< MSB set to 1
146
147 /**
148 * \brief Create an index number for the prefix
149 * \param prefix the prefix to index
150 * \returns an index
151 */
152 uint32_t PrefixToIndex(Ipv6Prefix prefix) const;
153
154 /**
155 * \brief This class holds the state for a given network
156 */
158 {
159 public:
160 uint8_t prefix[16]; //!< the network prefix
161 uint32_t shift; //!< a shift
162 uint8_t network[16]; //!< the network
163 uint8_t addr[16]; //!< the address
164 uint8_t addrMax[16]; //!< the maximum address
165 };
166
167 NetworkState m_netTable[N_BITS]; //!< the available networks
168
169 /**
170 * \brief This class holds the allocated addresses
171 */
172 class Entry
173 {
174 public:
175 uint8_t addrLow[16]; //!< the lowest allocated address
176 uint8_t addrHigh[16]; //!< the highest allocated address
177 };
178
179 std::list<Entry> m_entries; //!< contained of allocated addresses
180 Ipv6Address m_base; //!< base address
181 bool m_test; //!< test mode (if true)
182};
183
185 : m_entries(),
186 m_base("::1"),
187 m_test(false)
188{
189 NS_LOG_FUNCTION(this);
190 Reset();
191}
192
193void
195{
196 NS_LOG_FUNCTION(this);
197
198 uint8_t prefix[16] = {0};
199
200 for (uint32_t i = 0; i < N_BITS; ++i)
201 {
202 for (uint32_t j = 0; j < 16; ++j)
203 {
204 m_netTable[i].prefix[j] = prefix[j];
205 }
206 for (uint32_t j = 0; j < 15; ++j)
207 {
208 prefix[15 - j] >>= 1;
209 prefix[15 - j] |= (prefix[15 - j - 1] & 1);
210 }
211 prefix[0] |= MOST_SIGNIFICANT_BIT;
212 for (uint32_t j = 0; j < 15; ++j)
213 {
214 m_netTable[i].network[j] = 0;
215 }
216 m_netTable[i].network[15] = 1;
217 for (uint32_t j = 0; j < 15; ++j)
218 {
219 m_netTable[i].addr[j] = 0;
220 }
221 m_netTable[i].addr[15] = 1;
222 for (uint32_t j = 0; j < 16; ++j)
223 {
224 m_netTable[i].addrMax[j] = ~prefix[j];
225 }
226 m_netTable[i].shift = N_BITS - i;
227 }
228 m_entries.clear();
229 m_base = Ipv6Address("::1");
230 m_test = false;
231}
232
237
238void
240 const Ipv6Prefix prefix,
241 const Ipv6Address interfaceId)
242{
243 NS_LOG_FUNCTION(this << net << prefix << interfaceId);
244
245 m_base = interfaceId;
246 //
247 // We're going to be playing with the actual bits in the network and prefix so
248 // pull them out into ints.
249 //
250 uint8_t prefixBits[16];
251 prefix.GetBytes(prefixBits);
252 uint8_t netBits[16];
253 net.GetBytes(netBits);
254 uint8_t interfaceIdBits[16];
255 interfaceId.GetBytes(interfaceIdBits);
256 //
257 // Some quick reasonableness testing.
258 //
259 // Convert the network prefix into an index into the network number table.
260 // The network number comes in to us properly aligned for the prefix and so
261 // needs to be shifted right into the normalized position (lowest bit of the
262 // network number at bit zero of the int that holds it).
263 //
264 uint32_t index = PrefixToIndex(prefix);
265 NS_LOG_DEBUG("Index " << index);
266 uint32_t a = m_netTable[index].shift / 8;
267 uint32_t b = m_netTable[index].shift % 8;
268 for (int32_t j = 15 - a; j >= 0; j--)
269 {
270 m_netTable[index].network[j + a] = netBits[j];
271 }
272 for (uint32_t j = 0; j < a; j++)
273 {
274 m_netTable[index].network[j] = 0;
275 }
276 for (uint32_t j = 15; j >= a; j--)
277 {
278 m_netTable[index].network[j] = m_netTable[index].network[j] >> b;
279 m_netTable[index].network[j] |= m_netTable[index].network[j - 1] << (8 - b);
280 }
281 for (int32_t j = 0; j < 16; j++)
282 {
283 m_netTable[index].addr[j] = interfaceIdBits[j];
284 }
285}
286
289{
290 NS_LOG_FUNCTION(this);
291 uint8_t nw[16] = {0};
292 uint32_t index = PrefixToIndex(prefix);
293 uint32_t a = m_netTable[index].shift / 8;
294 uint32_t b = m_netTable[index].shift % 8;
295 for (uint32_t j = 0; j < 16 - a; ++j)
296 {
297 nw[j] = m_netTable[index].network[j + a];
298 }
299 for (uint32_t j = 0; j < 15; j++)
300 {
301 nw[j] = nw[j] << b;
302 nw[j] |= nw[j + 1] >> (8 - b);
303 }
304 nw[15] = nw[15] << b;
305
306 return Ipv6Address(nw);
307}
308
311{
312 NS_LOG_FUNCTION(this);
313
314 uint32_t index = PrefixToIndex(prefix);
315 // Reset the base to what was initialized
316 uint8_t interfaceIdBits[16];
317 m_base.GetBytes(interfaceIdBits);
318 for (int32_t j = 0; j < 16; j++)
319 {
320 m_netTable[index].addr[j] = interfaceIdBits[j];
321 }
322
323 for (int32_t j = 15; j >= 0; j--)
324 {
325 if (m_netTable[index].network[j] < 0xff)
326 {
327 ++m_netTable[index].network[j];
328 break;
329 }
330 else
331 {
332 ++m_netTable[index].network[j];
333 }
334 }
335
336 uint8_t nw[16];
337 uint32_t a = m_netTable[index].shift / 8;
338 uint32_t b = m_netTable[index].shift % 8;
339 for (uint32_t j = 0; j < 16 - a; ++j)
340 {
341 nw[j] = m_netTable[index].network[j + a];
342 }
343 for (uint32_t j = 16 - a; j < 16; ++j)
344 {
345 nw[j] = 0;
346 }
347 for (uint32_t j = 0; j < 15; j++)
348 {
349 nw[j] = nw[j] << b;
350 nw[j] |= nw[j + 1] >> (8 - b);
351 }
352 nw[15] = nw[15] << b;
353
354 return Ipv6Address(nw);
355}
356
357void
359{
360 NS_LOG_FUNCTION(this);
361
362 uint32_t index = PrefixToIndex(prefix);
363 uint8_t interfaceIdBits[16];
364 interfaceId.GetBytes(interfaceIdBits);
365
366 for (uint32_t j = 0; j < 16; ++j)
367 {
368 m_netTable[index].addr[j] = interfaceIdBits[j];
369 }
370}
371
374{
375 NS_LOG_FUNCTION(this);
376
377 uint32_t index = PrefixToIndex(prefix);
378
379 uint8_t nw[16] = {0};
380 uint32_t a = m_netTable[index].shift / 8;
381 uint32_t b = m_netTable[index].shift % 8;
382 for (uint32_t j = 0; j < 16 - a; ++j)
383 {
384 nw[j] = m_netTable[index].network[j + a];
385 }
386 for (uint32_t j = 0; j < 15; j++)
387 {
388 nw[j] = nw[j] << b;
389 nw[j] |= nw[j + 1] >> (8 - b);
390 }
391 nw[15] = nw[15] << b;
392 for (uint32_t j = 0; j < 16; j++)
393 {
394 nw[j] |= m_netTable[index].addr[j];
395 }
396
397 return Ipv6Address(nw);
398}
399
402{
403 NS_LOG_FUNCTION(this);
404
405 uint32_t index = PrefixToIndex(prefix);
406
407 uint8_t ad[16] = {0};
408 uint32_t a = m_netTable[index].shift / 8;
409 uint32_t b = m_netTable[index].shift % 8;
410 for (uint32_t j = 0; j < 16 - a; ++j)
411 {
412 ad[j] = m_netTable[index].network[j + a];
413 }
414 for (uint32_t j = 0; j < 15; j++)
415 {
416 ad[j] = ad[j] << b;
417 ad[j] |= ad[j + 1] >> (8 - b);
418 }
419 ad[15] = ad[15] << b;
420 for (uint32_t j = 0; j < 16; j++)
421 {
422 ad[j] |= m_netTable[index].addr[j];
423 }
424 Ipv6Address addr = Ipv6Address(ad);
425
426 for (int32_t j = 15; j >= 0; j--)
427 {
428 if (m_netTable[index].addr[j] < 0xff)
429 {
430 ++m_netTable[index].addr[j];
431 break;
432 }
433 else
434 {
435 ++m_netTable[index].addr[j];
436 }
437 }
438
439 //
440 // Make a note that we've allocated this address -- used for address collision
441 // detection.
442 //
443 AddAllocated(addr);
444 return addr;
445}
446
447bool
449{
450 NS_LOG_FUNCTION(this << address);
451
452 uint8_t addr[16];
453 address.GetBytes(addr);
454
455 std::list<Entry>::iterator i;
456
457 for (i = m_entries.begin(); i != m_entries.end(); ++i)
458 {
459 NS_LOG_LOGIC("examine entry: " << Ipv6Address((*i).addrLow) << " to "
460 << Ipv6Address((*i).addrHigh));
461 //
462 // First things first. Is there an address collision -- that is, does the
463 // new address fall in a previously allocated block of addresses.
464 //
465 if (!(Ipv6Address(addr) < Ipv6Address((*i).addrLow)) &&
466 ((Ipv6Address(addr) < Ipv6Address((*i).addrHigh)) ||
467 (Ipv6Address(addr) == Ipv6Address((*i).addrHigh))))
468 {
470 "Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address(addr));
471 if (!m_test)
472 {
474 "Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address(addr));
475 }
476 return false;
477 }
478 //
479 // If the new address is less than the lowest address in the current
480 // block and can't be merged into to the current block, then insert it
481 // as a new block before the current block.
482 //
483 uint8_t taddr[16];
484 for (uint32_t j = 0; j < 16; j++)
485 {
486 taddr[j] = (*i).addrLow[j];
487 }
488 taddr[15] -= 1;
489 if (Ipv6Address(addr) < Ipv6Address(taddr))
490 {
491 break;
492 }
493 //
494 // If the new address fits at the end of the block, look ahead to the next
495 // block and make sure it's not a collision there. If we won't overlap,
496 // then just extend the current block by one address. We expect that
497 // completely filled network ranges will be a fairly rare occurrence,
498 // so we don't worry about collapsing address range blocks.
499 //
500 for (uint32_t j = 0; j < 16; j++)
501 {
502 taddr[j] = (*i).addrLow[j];
503 }
504 taddr[15] += 1;
505 if (Ipv6Address(addr) == Ipv6Address(taddr))
506 {
507 auto j = i;
508 ++j;
509
510 if (j != m_entries.end())
511 {
512 if (Ipv6Address(addr) == Ipv6Address((*j).addrLow))
513 {
514 NS_LOG_LOGIC("Ipv6AddressGeneratorImpl::Add(): "
515 "Address Collision: "
516 << Ipv6Address(addr));
517 if (!m_test)
518 {
519 NS_FATAL_ERROR("Ipv6AddressGeneratorImpl::Add(): Address Collision: "
520 << Ipv6Address(addr));
521 }
522 return false;
523 }
524 }
525
526 NS_LOG_LOGIC("New addrHigh = " << Ipv6Address(addr));
527 for (uint32_t j = 0; j < 16; j++)
528 {
529 (*i).addrHigh[j] = addr[j];
530 }
531 return true;
532 }
533 //
534 // If we get here, we know that the next lower block of addresses
535 // couldn't have been extended to include this new address since the
536 // code immediately above would have been executed and that next lower
537 // block extended upward. So we know it's safe to extend the current
538 // block down to include the new address.
539 //
540 for (uint32_t j = 0; j < 16; j++)
541 {
542 taddr[j] = (*i).addrLow[j];
543 }
544 taddr[15] -= 1;
545 if (Ipv6Address(addr) == Ipv6Address(taddr))
546 {
547 NS_LOG_LOGIC("New addrLow = " << Ipv6Address(addr));
548 for (uint32_t j = 0; j < 16; j++)
549 {
550 (*i).addrLow[j] = addr[j];
551 }
552 return true;
553 }
554 }
555
556 Entry entry;
557 for (uint32_t j = 0; j < 16; j++)
558 {
559 entry.addrLow[j] = entry.addrHigh[j] = addr[j];
560 }
561 m_entries.insert(i, entry);
562 return true;
563}
564
565bool
567{
568 NS_LOG_FUNCTION(this << address);
569
570 uint8_t addr[16];
571 address.GetBytes(addr);
572
573 for (auto i = m_entries.begin(); i != m_entries.end(); ++i)
574 {
575 NS_LOG_LOGIC("examine entry: " << Ipv6Address((*i).addrLow) << " to "
576 << Ipv6Address((*i).addrHigh));
577
578 if (!(Ipv6Address(addr) < Ipv6Address((*i).addrLow)) &&
579 ((Ipv6Address(addr) < Ipv6Address((*i).addrHigh)) ||
580 (Ipv6Address(addr) == Ipv6Address((*i).addrHigh))))
581 {
582 NS_LOG_LOGIC("Ipv6AddressGeneratorImpl::IsAddressAllocated(): Address Collision: "
583 << Ipv6Address(addr));
584 return true;
585 }
586 }
587 return false;
588}
589
590bool
592{
593 NS_LOG_FUNCTION(this << address << prefix);
594
596 address == address.CombinePrefix(prefix),
597 "Ipv6AddressGeneratorImpl::IsNetworkAllocated(): network address and mask don't match "
598 << address << " " << prefix);
599
600 for (auto i = m_entries.begin(); i != m_entries.end(); ++i)
601 {
602 NS_LOG_LOGIC("examine entry: " << Ipv6Address((*i).addrLow) << " to "
603 << Ipv6Address((*i).addrHigh));
604 Ipv6Address low = Ipv6Address((*i).addrLow);
605 Ipv6Address high = Ipv6Address((*i).addrHigh);
606
607 if (address == low.CombinePrefix(prefix) || address == high.CombinePrefix(prefix))
608 {
610 "Ipv6AddressGeneratorImpl::IsNetworkAllocated(): Network already allocated: "
611 << address << " " << low << "-" << high);
612 return false;
613 }
614 }
615 return true;
616}
617
618void
624
627{
628 //
629 // We've been given a prefix that has a higher order bit set for each bit of
630 // the network number. In order to translate this prefix into an index,
631 // we just need to count the number of zero bits in the prefix. We do this
632 // in a loop in which we shift the prefix right until we find the first
633 // nonzero bit. This tells us the number of zero bits, and from this we
634 // infer the number of nonzero bits which is the number of bits in the prefix.
635 //
636 // We use the number of bits in the prefix as the number of bits in the
637 // network number and as the index into the network number state table.
638 //
639 uint8_t prefixBits[16];
640 prefix.GetBytes(prefixBits);
641
642 for (int32_t i = 15; i >= 0; --i)
643 {
644 for (uint32_t j = 0; j < 8; ++j)
645 {
646 if (prefixBits[i] & 1)
647 {
648 uint32_t index = N_BITS - (15 - i) * 8 - j;
649 NS_ABORT_MSG_UNLESS(index > 0 && index < N_BITS,
650 "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix");
651 return index;
652 }
653 prefixBits[i] >>= 1;
654 }
655 }
656 NS_ASSERT_MSG(false, "Ipv6AddressGenerator::PrefixToIndex(): Impossible");
657 return 0;
658}
659
660void
662 const Ipv6Prefix prefix,
663 const Ipv6Address interfaceId)
664{
665 NS_LOG_FUNCTION(net << prefix << interfaceId);
666
667 SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->Init(net, prefix, interfaceId);
668}
669
672{
673 NS_LOG_FUNCTION(prefix);
674
675 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->NextNetwork(prefix);
676}
677
680{
681 NS_LOG_FUNCTION(prefix);
682
683 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->GetNetwork(prefix);
684}
685
686void
688{
689 NS_LOG_FUNCTION(interfaceId << prefix);
690
691 SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->InitAddress(interfaceId, prefix);
692}
693
696{
697 NS_LOG_FUNCTION(prefix);
698
699 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->GetAddress(prefix);
700}
701
704{
705 NS_LOG_FUNCTION(prefix);
706
707 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->NextAddress(prefix);
708}
709
710void
717
718bool
725
726bool
728{
729 NS_LOG_FUNCTION(addr);
730
731 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->IsAddressAllocated(addr);
732}
733
734bool
736{
737 NS_LOG_FUNCTION(addr << prefix);
738
739 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get()->IsNetworkAllocated(addr, prefix);
740}
741
742void
749
750} // namespace ns3
static void Init(const Ipv6Address net, const Ipv6Prefix prefix, const Ipv6Address interfaceId="::1")
Initialise the base network and interfaceId for the generator.
static void TestMode()
Used to turn off fatal errors and assertions, for testing.
static Ipv6Address NextAddress(const Ipv6Prefix prefix)
Allocate the next Ipv6Address for the configured network and prefix.
static Ipv6Address GetNetwork(const Ipv6Prefix prefix)
Get the current network of the given Ipv6Prefix.
static void InitAddress(const Ipv6Address interfaceId, const Ipv6Prefix prefix)
Set the interfaceId for the given Ipv6Prefix.
static bool IsNetworkAllocated(const Ipv6Address addr, const Ipv6Prefix prefix)
Check if a network has already allocated addresses.
static bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
static Ipv6Address GetAddress(const Ipv6Prefix prefix)
Get the Ipv6Address that will be allocated upon NextAddress ()
static Ipv6Address NextNetwork(const Ipv6Prefix prefix)
Get the next network according to the given Ipv6Prefix.
static bool IsAddressAllocated(const Ipv6Address addr)
Check the Ipv6Address allocation in the list of IPv6 entries.
static void Reset()
Reset the networks and Ipv6Address to zero.
This class holds the allocated addresses.
uint8_t addrLow[16]
the lowest allocated address
uint8_t addrHigh[16]
the highest allocated address
This class holds the state for a given network.
Implementation class of Ipv6AddressGenerator This generator assigns addresses sequentially from a pro...
void Reset()
Reset the networks and Ipv6Address to zero.
static const uint32_t MOST_SIGNIFICANT_BIT
MSB set to 1.
NetworkState m_netTable[N_BITS]
the available networks
bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
Ipv6Address GetAddress(const Ipv6Prefix prefix) const
Get the Ipv6Address that will be allocated upon NextAddress ()
uint32_t PrefixToIndex(Ipv6Prefix prefix) const
Create an index number for the prefix.
Ipv6Address NextNetwork(const Ipv6Prefix prefix)
Get the next network according to the given Ipv6Prefix.
void TestMode()
Used to turn off fatal errors and assertions, for testing.
std::list< Entry > m_entries
contained of allocated addresses
static const uint32_t N_BITS
the number of bits in the address
void Init(const Ipv6Address net, const Ipv6Prefix prefix, const Ipv6Address interfaceId)
Initialise the base network and interfaceId for the generator.
void InitAddress(const Ipv6Address interfaceId, const Ipv6Prefix prefix)
Set the interfaceId for the given Ipv6Prefix.
bool IsNetworkAllocated(const Ipv6Address addr, const Ipv6Prefix prefix)
Check if a network has already allocated addresses.
Ipv6Address GetNetwork(const Ipv6Prefix prefix) const
Get the current network of the given Ipv6Prefix.
bool IsAddressAllocated(const Ipv6Address addr)
Check the Ipv6Address allocation in the list of IPv6 entries.
Ipv6Address NextAddress(const Ipv6Prefix prefix)
Allocate the next Ipv6Address for the configured network and prefix.
Describes an IPv6 address.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
Ipv6Address CombinePrefix(const Ipv6Prefix &prefix) const
Combine this address with a prefix.
Describes an IPv6 prefix.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
static T * Get()
Get a pointer to the singleton instance.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.