A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv6-address-generator.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 University of Washington
4  * Copyright (c) 2011 Atishay Jain
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include <list>
21 #include "ns3/abort.h"
22 #include "ns3/assert.h"
23 #include "ns3/log.h"
24 #include "ns3/simulation-singleton.h"
25 #include "ipv6-address-generator.h"
26 
27 NS_LOG_COMPONENT_DEFINE ("Ipv6AddressGenerator");
28 
29 namespace ns3 {
30 
42 {
43 public:
45  virtual ~Ipv6AddressGeneratorImpl ();
46 
58  void Init (const Ipv6Address net, const Ipv6Prefix prefix,
59  const Ipv6Address interfaceId);
60 
74  Ipv6Address NextNetwork (const Ipv6Prefix prefix);
75 
86  Ipv6Address GetNetwork (const Ipv6Prefix prefix) const;
87 
95  void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
96 
107  Ipv6Address GetAddress (const Ipv6Prefix prefix) const;
108 
119  Ipv6Address NextAddress (const Ipv6Prefix prefix);
120 
125  void Reset (void);
126 
138  bool AddAllocated (const Ipv6Address addr);
139 
144  void TestMode (void);
145 
146 private:
147  static const uint32_t N_BITS = 128;
148  static const uint32_t MOST_SIGNIFICANT_BIT = 0x80;
149 
156  uint32_t PrefixToIndex (Ipv6Prefix prefix) const;
157 
163  {
164 public:
165  uint8_t prefix[16];
166  uint32_t shift;
167  uint8_t network[16];
168  uint8_t addr[16];
169  uint8_t addrMax[16];
170  };
171 
173 
178  class Entry
179  {
180 public:
181  uint8_t addrLow[16];
182  uint8_t addrHigh[16];
183  };
184 
185  std::list<Entry> m_entries;
187  bool m_test;
188 };
189 
191  : m_entries (),
192  m_base ("::1"),
193  m_test (false)
194 {
195  NS_LOG_FUNCTION (this);
196  Reset ();
197 }
198 
199 void
201 {
202  NS_LOG_FUNCTION (this);
203 
204  uint8_t prefix[16] = { 0};
205 
206  for (uint32_t i = 0; i < N_BITS; ++i)
207  {
208  for (uint32_t j = 0; j < 16; ++j)
209  {
210  m_netTable[i].prefix[j] = prefix[j];
211  }
212  for (uint32_t j = 0; j < 15; ++j)
213  {
214  prefix[15 - j] >>= 1;
215  prefix[15 - j] |= (prefix[15 - j - 1] & 1);
216  }
217  prefix[0] |= MOST_SIGNIFICANT_BIT;
218  for (uint32_t j = 0; j < 15; ++j)
219  {
220  m_netTable[i].network[j] = 0;
221  }
222  m_netTable[i].network[15] = 1;
223  for (uint32_t j = 0; j < 15; ++j)
224  {
225  m_netTable[i].addr[j] = 0;
226  }
227  m_netTable[i].addr[15] = 1;
228  for (uint32_t j = 0; j < 16; ++j)
229  {
230  m_netTable[i].addrMax[j] = ~prefix[j];
231  }
232  m_netTable[i].shift = N_BITS - i;
233  }
234  m_entries.clear ();
235  m_base = Ipv6Address ("::1");
236  m_test = false;
237 }
238 
240 {
241  NS_LOG_FUNCTION (this);
242 }
243 
244 void
246  const Ipv6Address net,
247  const Ipv6Prefix prefix,
248  const Ipv6Address interfaceId)
249 {
250  NS_LOG_FUNCTION (this << net << prefix << interfaceId);
251 
252  m_base = interfaceId;
253  //
254  // We're going to be playing with the actual bits in the network and prefix so
255  // pull them out into ints.
256  //
257  uint8_t prefixBits[16];
258  prefix.GetBytes (prefixBits);
259  uint8_t netBits[16];
260  net.GetBytes (netBits);
261  uint8_t interfaceIdBits[16];
262  interfaceId.GetBytes (interfaceIdBits);
263  //
264  // Some quick reasonableness testing.
265  //
266  // Convert the network prefix into an index into the network number table.
267  // The network number comes in to us properly aligned for the prefix and so
268  // needs to be shifted right into the normalized position (lowest bit of the
269  // network number at bit zero of the int that holds it).
270  //
271  uint32_t index = PrefixToIndex (prefix);
272  NS_LOG_DEBUG ("Index " << index);
273  uint32_t a = m_netTable[index].shift / 8;
274  uint32_t b = m_netTable[index].shift % 8;
275  for (int32_t j = 15 - a; j >= 0; j--)
276  {
277  m_netTable[index].network[j + a] = netBits[j];
278  }
279  for (uint32_t j = 0; j < a; j++)
280  {
281  m_netTable[index].network[j] = 0;
282  }
283  for (uint32_t j = 15; j >= a; j--)
284  {
285  m_netTable[index].network[j] = m_netTable[index].network[j] >> b;
286  m_netTable[index].network[j] |= m_netTable[index].network[j - 1] << (8 - b);
287  }
288  for (int32_t j = 0; j < 16; j++)
289  {
290  m_netTable[index].addr[j] = interfaceIdBits[j];
291  }
292  return;
293 }
294 
297  const Ipv6Prefix prefix) const
298 {
299  NS_LOG_FUNCTION (this);
300  uint8_t nw[16];
301  uint32_t index = PrefixToIndex (prefix);
302  uint32_t a = m_netTable[index].shift / 8;
303  uint32_t b = m_netTable[index].shift % 8;
304  for (uint32_t j = 0; j < 16 - a; ++j)
305  {
306  nw[j] = m_netTable[index].network[j + a];
307  }
308  for (uint32_t j = 16 - a; j < 16; ++j)
309  {
310  nw[j] = 0;
311  }
312  for (uint32_t j = 0; j < 15; j++)
313  {
314  nw[j] = nw[j] << b;
315  nw[j] |= nw[j + 1] >> (8 - b);
316  }
317  nw[15] = nw[15] << b;
318 
319  return Ipv6Address (nw);
320 }
321 
324  const Ipv6Prefix prefix)
325 {
326  NS_LOG_FUNCTION (this);
327 
328  uint32_t index = PrefixToIndex (prefix);
329  // Reset the base to what was initialized
330  uint8_t interfaceIdBits[16];
331  m_base.GetBytes (interfaceIdBits);
332  for (int32_t j = 0; j < 16; j++)
333  {
334  m_netTable[index].addr[j] = interfaceIdBits[j];
335  }
336 
337  for (int32_t j = 15; j >= 0; j--)
338  {
339  if (m_netTable[index].network[j] < 0xff)
340  {
341  ++m_netTable[index].network[j];
342  break;
343  }
344  else
345  {
346  ++m_netTable[index].network[j];
347  }
348  }
349 
350  uint8_t nw[16];
351  uint32_t a = m_netTable[index].shift / 8;
352  uint32_t b = m_netTable[index].shift % 8;
353  for (uint32_t j = 0; j < 16 - a; ++j)
354  {
355  nw[j] = m_netTable[index].network[j + a];
356  }
357  for (uint32_t j = 16 - a; j < 16; ++j)
358  {
359  nw[j] = 0;
360  }
361  for (uint32_t j = 0; j < 15; j++)
362  {
363  nw[j] = nw[j] << b;
364  nw[j] |= nw[j + 1] >> (8 - b);
365  }
366  nw[15] = nw[15] << b;
367 
368  return Ipv6Address (nw);
369 
370 }
371 
372 void
374  const Ipv6Address interfaceId,
375  const Ipv6Prefix prefix)
376 {
377  NS_LOG_FUNCTION (this);
378 
379  uint32_t index = PrefixToIndex (prefix);
380  uint8_t interfaceIdBits[16];
381  interfaceId.GetBytes (interfaceIdBits);
382 
383  for (uint32_t j = 0; j < 16; ++j)
384  {
385  m_netTable[index].addr[j] = interfaceIdBits[j];
386  }
387 }
388 
391 {
392  NS_LOG_FUNCTION (this);
393 
394  uint32_t index = PrefixToIndex (prefix);
395 
396  uint8_t nw[16];
397  uint32_t a = m_netTable[index].shift / 8;
398  uint32_t b = m_netTable[index].shift % 8;
399  for (uint32_t j = 0; j < 16 - a; ++j)
400  {
401  nw[j] = m_netTable[index].network[j + a];
402  }
403  for (uint32_t j = 16 - a; j < 16; ++j)
404  {
405  nw[j] = 0;
406  }
407  for (uint32_t j = 0; j < 15; j++)
408  {
409  nw[j] = nw[j] << b;
410  nw[j] |= nw[j + 1] >> (8 - b);
411  }
412  nw[15] = nw[15] << b;
413  for (uint32_t j = 0; j < 16; j++)
414  {
415  nw[j] |= m_netTable[index].addr[j];
416  }
417 
418  return Ipv6Address (nw);
419 }
420 
423 {
424  NS_LOG_FUNCTION (this);
425 
426  uint32_t index = PrefixToIndex (prefix);
427 
428  uint8_t ad[16];
429  uint32_t a = m_netTable[index].shift / 8;
430  uint32_t b = m_netTable[index].shift % 8;
431  for (uint32_t j = 0; j < 16 - a; ++j)
432  {
433  ad[j] = m_netTable[index].network[j + a];
434  }
435  for (uint32_t j = 16 - a; j < 16; ++j)
436  {
437  ad[j] = 0;
438  }
439  for (uint32_t j = 0; j < 15; j++)
440  {
441  ad[j] = ad[j] << b;
442  ad[j] |= ad[j + 1] >> (8 - b);
443  }
444  ad[15] = ad[15] << b;
445  for (uint32_t j = 0; j < 16; j++)
446  {
447  ad[j] |= m_netTable[index].addr[j];
448  }
449  Ipv6Address addr = Ipv6Address (ad);
450 
451  for (int32_t j = 15; j >= 0; j--)
452  {
453  if (m_netTable[index].addr[j] < 0xff)
454  {
455  ++m_netTable[index].addr[j];
456  break;
457  }
458  else
459  {
460  ++m_netTable[index].addr[j];
461  }
462  }
463 
464  //
465  // Make a note that we've allocated this address -- used for address collision
466  // detection.
467  //
468  AddAllocated (addr);
469  return addr;
470 }
471 
472 bool
474 {
475  NS_LOG_FUNCTION (this << address);
476 
477  uint8_t addr[16];
478  address.GetBytes (addr);
479 
480  std::list<Entry>::iterator i;
481 
482  for (i = m_entries.begin (); i != m_entries.end (); ++i)
483  {
484  NS_LOG_LOGIC ("examine entry: " << Ipv6Address ((*i).addrLow) <<
485  " to " << Ipv6Address ((*i).addrHigh));
486  //
487  // First things first. Is there an address collision -- that is, does the
488  // new address fall in a previously allocated block of addresses.
489  //
490  if (!(Ipv6Address (addr) < Ipv6Address ((*i).addrLow))
491  && ((Ipv6Address (addr) < Ipv6Address ((*i).addrHigh))
492  || (Ipv6Address (addr) == Ipv6Address ((*i).addrHigh))))
493  {
494  NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
495  if (!m_test)
496  {
497  NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
498  }
499  return false;
500  }
501  //
502  // If the new address is less than the lowest address in the current
503  // block and can't be merged into to the current block, then insert it
504  // as a new block before the current block.
505  //
506  uint8_t taddr[16];
507  for (uint32_t j = 0; j < 16; j++)
508  {
509  taddr[j] = (*i).addrLow[j];
510  }
511  taddr[15] -= 1;
512  if (Ipv6Address (addr) < Ipv6Address (taddr))
513  {
514  break;
515  }
516  //
517  // If the new address fits at the end of the block, look ahead to the next
518  // block and make sure it's not a collision there. If we won't overlap,
519  // then just extend the current block by one address. We expect that
520  // completely filled network ranges will be a fairly rare occurrence,
521  // so we don't worry about collapsing address range blocks.
522  //
523  for (uint32_t j = 0; j < 16; j++)
524  {
525  taddr[j] = (*i).addrLow[j];
526  }
527  taddr[15] += 1;
528  if (Ipv6Address (addr) == Ipv6Address (taddr))
529  {
530  std::list<Entry>::iterator j = i;
531  ++j;
532 
533  if (j != m_entries.end ())
534  {
535  if (Ipv6Address (addr) == Ipv6Address ((*j).addrLow))
536  {
537  NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): "
538  "Address Collision: " << Ipv6Address (addr));
539  if (!m_test)
540  {
541  NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
542  }
543  return false;
544  }
545  }
546 
547  NS_LOG_LOGIC ("New addrHigh = " << Ipv6Address (addr));
548  for (uint32_t j = 0; j < 16; j++)
549  {
550  (*i).addrHigh[j] = addr[j];
551  }
552  return true;
553  }
554  //
555  // If we get here, we know that the next lower block of addresses
556  // couldn't have been extended to include this new address since the
557  // code immediately above would have been executed and that next lower
558  // block extended upward. So we know it's safe to extend the current
559  // block down to includ the new address.
560  //
561  for (uint32_t j = 0; j < 16; j++)
562  {
563  taddr[j] = (*i).addrLow[j];
564  }
565  taddr[15] -= 1;
566  if ((Ipv6Address (addr) == Ipv6Address (taddr)))
567  {
568  NS_LOG_LOGIC ("New addrLow = " << Ipv6Address (addr));
569  for (uint32_t j = 0; j < 16; j++)
570  {
571  (*i).addrLow[j] = addr[j];
572  }
573  return true;
574  }
575  }
576 
577  Entry entry;
578  for (uint32_t j = 0; j < 16; j++)
579  {
580  entry.addrLow[j] = entry.addrHigh[j] = addr[j];
581  }
582  m_entries.insert (i, entry);
583  return true;
584 }
585 
586 void
588 {
589  NS_LOG_FUNCTION (this);
590  m_test = true;
591 }
592 
593 uint32_t
595 {
596  //
597  // We've been given a prefix that has a higher order bit set for each bit of
598  // the network number. In order to translate this prefix into an index,
599  // we just need to count the number of zero bits in the prefix. We do this
600  // in a loop in which we shift the prefix right until we find the first
601  // nonzero bit. This tells us the number of zero bits, and from this we
602  // infer the number of nonzero bits which is the number of bits in the prefix.
603  //
604  // We use the number of bits in the prefix as the number of bits in the
605  // network number and as the index into the network number state table.
606  //
607  uint8_t prefixBits[16];
608  prefix.GetBytes (prefixBits);
609 
610  for (int32_t i = 15; i >= 0; --i)
611  {
612  for (uint32_t j = 0; j < 8; ++j)
613  {
614  if (prefixBits[i] & 1)
615  {
616  uint32_t index = N_BITS - (15 - i) * 8 - j;
617  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix");
618  return index;
619  }
620  prefixBits[i] >>= 1;
621  }
622  }
623  NS_ASSERT_MSG (false, "Ipv6AddressGenerator::PrefixToIndex(): Impossible");
624  return 0;
625 }
626 
627 void
629  const Ipv6Address net,
630  const Ipv6Prefix prefix,
631  const Ipv6Address interfaceId)
632 {
634 
636  ->Init (net, prefix, interfaceId);
637 }
638 
641 {
643 
645  ->NextNetwork (prefix);
646 }
647 
650 {
652 
654  ->GetNetwork (prefix);
655 }
656 
657 void
659  const Ipv6Address interfaceId,
660  const Ipv6Prefix prefix)
661 {
663 
665  ->InitAddress (interfaceId, prefix);
666 }
667 
670 {
672 
674  ->GetAddress (prefix);
675 }
676 
679 {
681 
683  ->NextAddress (prefix);
684 }
685 
686 void
688 {
690 
692  ->Reset ();
693 }
694 
695 bool
697 {
699 
701  ->AddAllocated (addr);
702 }
703 
704 void
706 {
708 
710  ->TestMode ();
711 }
712 
713 } // namespace ns3
714 
Ipv6Address GetNetwork(const Ipv6Prefix prefix) const
Get the current network of the given Ipv6Prefix.
This class holds the state for a given network.
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
This class holds the allocated addresses.
uint8_t prefix[16]
/internal the network prefix
uint32_t PrefixToIndex(Ipv6Prefix prefix) const
Create an index number for the prefix.
Ipv6Address m_base
/internal base address
static Ipv6Address NextNetwork(const Ipv6Prefix prefix)
Get the next network according to the given Ipv6Prefix.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
uint8_t addrMax[16]
/internal the maximum address
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:131
void Reset(void)
Reset the networks and Ipv6Address to zero.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
static void InitAddress(const Ipv6Address interfaceId, const Ipv6Prefix prefix)
Set the interfaceId for the given Ipv6Prefix.
static void Init(const Ipv6Address net, const Ipv6Prefix prefix, const Ipv6Address interfaceId="::1")
Initialise the base network and interfaceId for the generator.
void InitAddress(const Ipv6Address interfaceId, const Ipv6Prefix prefix)
Set the interfaceId for the given Ipv6Prefix.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
NetworkState m_netTable[N_BITS]
/internal the available networks
std::list< Entry > m_entries
/internal contained of allocated addresses
static const uint32_t N_BITS
/internal the number of bits in the address
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
Ipv6Address GetAddress(const Ipv6Prefix prefix) const
Get the Ipv6Address that will be allocated upon NextAddress ()
static const uint32_t MOST_SIGNIFICANT_BIT
/internal MSB set to 1
Implementation class of Ipv6AddressGenerator This generator assigns addresses sequentially from a pro...
static void TestMode(void)
Used to turn off fatal errors and assertions, for testing.
void TestMode(void)
Used to turn off fatal errors and assertions, for testing.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
NS_LOG_COMPONENT_DEFINE("Ipv6AddressGenerator")
Describes an IPv6 address.
Definition: ipv6-address.h:46
bool m_test
/internal test mode (if true)
static void Reset(void)
Reset the networks and Ipv6Address to zero.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
Ipv6Address NextNetwork(const Ipv6Prefix prefix)
Get the next network according to the given Ipv6Prefix.
static Ipv6Address GetAddress(const Ipv6Prefix prefix)
Get the Ipv6Address that will be allocated upon NextAddress ()
Describes an IPv6 prefix.
Definition: ipv6-address.h:387
static bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
uint8_t addrLow[16]
/internal the lowest allocated address
tuple address
Definition: first.py:37
Ipv6Address NextAddress(const Ipv6Prefix prefix)
Allocate the next Ipv6Address for the configured network and prefix.
void Init(const Ipv6Address net, const Ipv6Prefix prefix, const Ipv6Address interfaceId)
Initialise the base network and interfaceId for the generator.
static Ipv6Address NextAddress(const Ipv6Prefix prefix)
Allocate the next Ipv6Address for the configured network and prefix.
uint8_t addrHigh[16]
/internal the highest allocated address
bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
static Ipv6Address GetNetwork(const Ipv6Prefix prefix)
Get the current network of the given Ipv6Prefix.