A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv6-address-generator.cc
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 
32 {
33 public:
35  virtual ~Ipv6AddressGeneratorImpl ();
36 
37  void Init (const Ipv6Address net, const Ipv6Prefix prefix,
38  const Ipv6Address interfaceId);
39 
40  Ipv6Address GetNetwork (const Ipv6Prefix prefix) const;
41  Ipv6Address NextNetwork (const Ipv6Prefix prefix);
42 
43  void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
44  Ipv6Address GetAddress (const Ipv6Prefix prefix) const;
45  Ipv6Address NextAddress (const Ipv6Prefix prefix);
46 
47  void Reset (void);
48  bool AddAllocated (const Ipv6Address addr);
49 
50  void TestMode (void);
51 private:
52  static const uint32_t N_BITS = 128;
53  static const uint32_t MOST_SIGNIFICANT_BIT = 0x80;
54 
55  uint32_t PrefixToIndex (Ipv6Prefix prefix) const;
56 
58  {
59 public:
60  uint8_t prefix[16];
61  uint32_t shift;
62  uint8_t network[16];
63  uint8_t addr[16];
64  uint8_t addrMax[16];
65  };
66 
67  NetworkState m_netTable[N_BITS];
68 
69  class Entry
70  {
71 public:
72  uint8_t addrLow[16];
73  uint8_t addrHigh[16];
74  };
75 
76  std::list<Entry> m_entries;
77  Ipv6Address m_base;
78  bool m_test;
79 };
80 
81 Ipv6AddressGeneratorImpl::Ipv6AddressGeneratorImpl ()
82  : m_entries (),
83  m_base ("::1"),
84  m_test (false)
85 {
86  NS_LOG_FUNCTION (this);
87  Reset ();
88 }
89 
90 void
91 Ipv6AddressGeneratorImpl::Reset (void)
92 {
93  NS_LOG_FUNCTION (this);
94 
95  uint8_t prefix[16] = { 0};
96 
97  for (uint32_t i = 0; i < N_BITS; ++i)
98  {
99  for (uint32_t j = 0; j < 16; ++j)
100  {
101  m_netTable[i].prefix[j] = prefix[j];
102  }
103  for (uint32_t j = 0; j < 15; ++j)
104  {
105  prefix[15 - j] >>= 1;
106  prefix[15 - j] |= (prefix[15 - j - 1] & 1);
107  }
108  prefix[0] |= MOST_SIGNIFICANT_BIT;
109  for (uint32_t j = 0; j < 15; ++j)
110  {
111  m_netTable[i].network[j] = 0;
112  }
113  m_netTable[i].network[15] = 1;
114  for (uint32_t j = 0; j < 15; ++j)
115  {
116  m_netTable[i].addr[j] = 0;
117  }
118  m_netTable[i].addr[15] = 1;
119  for (uint32_t j = 0; j < 16; ++j)
120  {
121  m_netTable[i].addrMax[j] = ~prefix[j];
122  }
123  m_netTable[i].shift = N_BITS - i;
124  }
125  m_entries.clear ();
126  m_base = Ipv6Address ("::1");
127  m_test = false;
128 }
129 
130 Ipv6AddressGeneratorImpl::~Ipv6AddressGeneratorImpl ()
131 {
132  NS_LOG_FUNCTION (this);
133 }
134 
135 void
136 Ipv6AddressGeneratorImpl::Init (
137  const Ipv6Address net,
138  const Ipv6Prefix prefix,
139  const Ipv6Address interfaceId)
140 {
141  NS_LOG_FUNCTION (this << net << prefix << interfaceId);
142 
143  m_base = interfaceId;
144  //
145  // We're going to be playing with the actual bits in the network and prefix so
146  // pull them out into ints.
147  //
148  uint8_t prefixBits[16];
149  prefix.GetBytes (prefixBits);
150  uint8_t netBits[16];
151  net.GetBytes (netBits);
152  uint8_t interfaceIdBits[16];
153  interfaceId.GetBytes (interfaceIdBits);
154  //
155  // Some quick reasonableness testing.
156  //
157  // Convert the network prefix into an index into the network number table.
158  // The network number comes in to us properly aligned for the prefix and so
159  // needs to be shifted right into the normalized position (lowest bit of the
160  // network number at bit zero of the int that holds it).
161  //
162  uint32_t index = PrefixToIndex (prefix);
163  NS_LOG_DEBUG ("Index " << index);
164  uint32_t a = m_netTable[index].shift / 8;
165  uint32_t b = m_netTable[index].shift % 8;
166  for (int32_t j = 15 - a; j >= 0; j--)
167  {
168  m_netTable[index].network[j + a] = netBits[j];
169  }
170  for (uint32_t j = 0; j < a; j++)
171  {
172  m_netTable[index].network[j] = 0;
173  }
174  for (uint32_t j = 15; j >= a; j--)
175  {
176  m_netTable[index].network[j] = m_netTable[index].network[j] >> b;
177  m_netTable[index].network[j] |= m_netTable[index].network[j - 1] << (8 - b);
178  }
179  for (int32_t j = 0; j < 16; j++)
180  {
181  m_netTable[index].addr[j] = interfaceIdBits[j];
182  }
183  return;
184 }
185 
186 Ipv6Address
187 Ipv6AddressGeneratorImpl::GetNetwork (
188  const Ipv6Prefix prefix) const
189 {
190  NS_LOG_FUNCTION (this);
191  uint8_t nw[16];
192  uint32_t index = PrefixToIndex (prefix);
193  uint32_t a = m_netTable[index].shift / 8;
194  uint32_t b = m_netTable[index].shift % 8;
195  for (uint32_t j = 0; j < 16 - a; ++j)
196  {
197  nw[j] = m_netTable[index].network[j + a];
198  }
199  for (uint32_t j = 16 - a; j < 16; ++j)
200  {
201  nw[j] = 0;
202  }
203  for (uint32_t j = 0; j < 15; j++)
204  {
205  nw[j] = nw[j] << b;
206  nw[j] |= nw[j + 1] >> (8 - b);
207  }
208  nw[15] = nw[15] << b;
209 
210  return Ipv6Address (nw);
211 }
212 
213 Ipv6Address
214 Ipv6AddressGeneratorImpl::NextNetwork (
215  const Ipv6Prefix prefix)
216 {
217  NS_LOG_FUNCTION (this);
218 
219  uint32_t index = PrefixToIndex (prefix);
220  // Reset the base to what was initialized
221  uint8_t interfaceIdBits[16];
222  m_base.GetBytes (interfaceIdBits);
223  for (int32_t j = 0; j < 16; j++)
224  {
225  m_netTable[index].addr[j] = interfaceIdBits[j];
226  }
227 
228  for (int32_t j = 15; j >= 0; j--)
229  {
230  if (m_netTable[index].network[j] < 0xff)
231  {
232  ++m_netTable[index].network[j];
233  break;
234  }
235  else
236  {
237  ++m_netTable[index].network[j];
238  }
239  }
240 
241  uint8_t nw[16];
242  uint32_t a = m_netTable[index].shift / 8;
243  uint32_t b = m_netTable[index].shift % 8;
244  for (uint32_t j = 0; j < 16 - a; ++j)
245  {
246  nw[j] = m_netTable[index].network[j + a];
247  }
248  for (uint32_t j = 16 - a; j < 16; ++j)
249  {
250  nw[j] = 0;
251  }
252  for (uint32_t j = 0; j < 15; j++)
253  {
254  nw[j] = nw[j] << b;
255  nw[j] |= nw[j + 1] >> (8 - b);
256  }
257  nw[15] = nw[15] << b;
258 
259  return Ipv6Address (nw);
260 
261 }
262 
263 void
264 Ipv6AddressGeneratorImpl::InitAddress (
265  const Ipv6Address interfaceId,
266  const Ipv6Prefix prefix)
267 {
268  NS_LOG_FUNCTION (this);
269 
270  uint32_t index = PrefixToIndex (prefix);
271  uint8_t interfaceIdBits[16];
272  interfaceId.GetBytes (interfaceIdBits);
273 
274  for (uint32_t j = 0; j < 16; ++j)
275  {
276  m_netTable[index].addr[j] = interfaceIdBits[j];
277  }
278 }
279 
280 Ipv6Address
281 Ipv6AddressGeneratorImpl::GetAddress (const Ipv6Prefix prefix) const
282 {
283  NS_LOG_FUNCTION (this);
284 
285  uint32_t index = PrefixToIndex (prefix);
286 
287  uint8_t nw[16];
288  uint32_t a = m_netTable[index].shift / 8;
289  uint32_t b = m_netTable[index].shift % 8;
290  for (uint32_t j = 0; j < 16 - a; ++j)
291  {
292  nw[j] = m_netTable[index].network[j + a];
293  }
294  for (uint32_t j = 16 - a; j < 16; ++j)
295  {
296  nw[j] = 0;
297  }
298  for (uint32_t j = 0; j < 15; j++)
299  {
300  nw[j] = nw[j] << b;
301  nw[j] |= nw[j + 1] >> (8 - b);
302  }
303  nw[15] = nw[15] << b;
304  for (uint32_t j = 0; j < 16; j++)
305  {
306  nw[j] |= m_netTable[index].addr[j];
307  }
308 
309  return Ipv6Address (nw);
310 }
311 
312 Ipv6Address
313 Ipv6AddressGeneratorImpl::NextAddress (const Ipv6Prefix prefix)
314 {
315  NS_LOG_FUNCTION (this);
316 
317  uint32_t index = PrefixToIndex (prefix);
318 
319  uint8_t ad[16];
320  uint32_t a = m_netTable[index].shift / 8;
321  uint32_t b = m_netTable[index].shift % 8;
322  for (uint32_t j = 0; j < 16 - a; ++j)
323  {
324  ad[j] = m_netTable[index].network[j + a];
325  }
326  for (uint32_t j = 16 - a; j < 16; ++j)
327  {
328  ad[j] = 0;
329  }
330  for (uint32_t j = 0; j < 15; j++)
331  {
332  ad[j] = ad[j] << b;
333  ad[j] |= ad[j + 1] >> (8 - b);
334  }
335  ad[15] = ad[15] << b;
336  for (uint32_t j = 0; j < 16; j++)
337  {
338  ad[j] |= m_netTable[index].addr[j];
339  }
340  Ipv6Address addr = Ipv6Address (ad);
341 
342  for (int32_t j = 15; j >= 0; j--)
343  {
344  if (m_netTable[index].addr[j] < 0xff)
345  {
346  ++m_netTable[index].addr[j];
347  break;
348  }
349  else
350  {
351  ++m_netTable[index].addr[j];
352  }
353  }
354 
355  //
356  // Make a note that we've allocated this address -- used for address collision
357  // detection.
358  //
359  AddAllocated (addr);
360  return addr;
361 }
362 
363 bool
364 Ipv6AddressGeneratorImpl::AddAllocated (const Ipv6Address address)
365 {
366  NS_LOG_FUNCTION (this << address);
367 
368  uint8_t addr[16];
369  address.GetBytes (addr);
370 
371  std::list<Entry>::iterator i;
372 
373  for (i = m_entries.begin (); i != m_entries.end (); ++i)
374  {
375  NS_LOG_LOGIC ("examine entry: " << Ipv6Address ((*i).addrLow) <<
376  " to " << Ipv6Address ((*i).addrHigh));
377  //
378  // First things first. Is there an address collision -- that is, does the
379  // new address fall in a previously allocated block of addresses.
380  //
381  if (!(Ipv6Address (addr) < Ipv6Address ((*i).addrLow))
382  && ((Ipv6Address (addr) < Ipv6Address ((*i).addrHigh))
383  || (Ipv6Address (addr) == Ipv6Address ((*i).addrHigh))))
384  {
385  NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
386  if (!m_test)
387  {
388  NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
389  }
390  return false;
391  }
392  //
393  // If the new address is less than the lowest address in the current
394  // block and can't be merged into to the current block, then insert it
395  // as a new block before the current block.
396  //
397  uint8_t taddr[16];
398  for (uint32_t j = 0; j < 16; j++)
399  {
400  taddr[j] = (*i).addrLow[j];
401  }
402  taddr[15] -= 1;
403  if (Ipv6Address (addr) < Ipv6Address (taddr))
404  {
405  break;
406  }
407  //
408  // If the new address fits at the end of the block, look ahead to the next
409  // block and make sure it's not a collision there. If we won't overlap,
410  // then just extend the current block by one address. We expect that
411  // completely filled network ranges will be a fairly rare occurrence,
412  // so we don't worry about collapsing address range blocks.
413  //
414  for (uint32_t j = 0; j < 16; j++)
415  {
416  taddr[j] = (*i).addrLow[j];
417  }
418  taddr[15] += 1;
419  if (Ipv6Address (addr) == Ipv6Address (taddr))
420  {
421  std::list<Entry>::iterator j = i;
422  ++j;
423 
424  if (j != m_entries.end ())
425  {
426  if (Ipv6Address (addr) == Ipv6Address ((*j).addrLow))
427  {
428  NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): "
429  "Address Collision: " << Ipv6Address (addr));
430  if (!m_test)
431  {
432  NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
433  }
434  return false;
435  }
436  }
437 
438  NS_LOG_LOGIC ("New addrHigh = " << Ipv6Address (addr));
439  for (uint32_t j = 0; j < 16; j++)
440  {
441  (*i).addrHigh[j] = addr[j];
442  }
443  return true;
444  }
445  //
446  // If we get here, we know that the next lower block of addresses
447  // couldn't have been extended to include this new address since the
448  // code immediately above would have been executed and that next lower
449  // block extended upward. So we know it's safe to extend the current
450  // block down to includ the new address.
451  //
452  for (uint32_t j = 0; j < 16; j++)
453  {
454  taddr[j] = (*i).addrLow[j];
455  }
456  taddr[15] -= 1;
457  if ((Ipv6Address (addr) == Ipv6Address (taddr)))
458  {
459  NS_LOG_LOGIC ("New addrLow = " << Ipv6Address (addr));
460  for (uint32_t j = 0; j < 16; j++)
461  {
462  (*i).addrLow[j] = addr[j];
463  }
464  return true;
465  }
466  }
467 
468  Entry entry;
469  for (uint32_t j = 0; j < 16; j++)
470  {
471  entry.addrLow[j] = entry.addrHigh[j] = addr[j];
472  }
473  m_entries.insert (i, entry);
474  return true;
475 }
476 
477 void
478 Ipv6AddressGeneratorImpl::TestMode (void)
479 {
480  NS_LOG_FUNCTION (this);
481  m_test = true;
482 }
483 
484 uint32_t
485 Ipv6AddressGeneratorImpl::PrefixToIndex (Ipv6Prefix prefix) const
486 {
487  //
488  // We've been given a prefix that has a higher order bit set for each bit of
489  // the network number. In order to translate this prefix into an index,
490  // we just need to count the number of zero bits in the prefix. We do this
491  // in a loop in which we shift the prefix right until we find the first
492  // nonzero bit. This tells us the number of zero bits, and from this we
493  // infer the number of nonzero bits which is the number of bits in the prefix.
494  //
495  // We use the number of bits in the prefix as the number of bits in the
496  // network number and as the index into the network number state table.
497  //
498  uint8_t prefixBits[16];
499  prefix.GetBytes (prefixBits);
500 
501  for (int32_t i = 15; i >= 0; --i)
502  {
503  for (uint32_t j = 0; j < 8; ++j)
504  {
505  if (prefixBits[i] & 1)
506  {
507  uint32_t index = N_BITS - (15 - i) * 8 - j;
508  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix");
509  return index;
510  }
511  prefixBits[i] >>= 1;
512  }
513  }
514  NS_ASSERT_MSG (false, "Ipv6AddressGenerator::PrefixToIndex(): Impossible");
515  return 0;
516 }
517 
518 void
520  const Ipv6Address net,
521  const Ipv6Prefix prefix,
522  const Ipv6Address interfaceId)
523 {
525 
527  ->Init (net, prefix, interfaceId);
528 }
529 
532 {
534 
536  ->NextNetwork (prefix);
537 }
538 
541 {
543 
545  ->GetNetwork (prefix);
546 }
547 
548 void
550  const Ipv6Address interfaceId,
551  const Ipv6Prefix prefix)
552 {
554 
556  ->InitAddress (interfaceId, prefix);
557 }
558 
561 {
563 
565  ->GetAddress (prefix);
566 }
567 
570 {
572 
574  ->NextAddress (prefix);
575 }
576 
577 void
579 {
581 
583  ->Reset ();
584 }
585 
586 bool
588 {
590 
592  ->AddAllocated (addr);
593 }
594 
595 void
597 {
599 
601  ->TestMode ();
602 }
603 
604 } // namespace ns3
605 
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
static Ipv6Address NextNetwork(const Ipv6Prefix prefix)
Get the next network acoording to the given Ipv6Prefix.
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:131
#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 GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
static void TestMode(void)
Used to turn off fatal errors and assertions, for testing.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Describes an IPv6 address.
Definition: ipv6-address.h:44
static void Reset(void)
Reset the networks and Ipv6Address to zero.
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
static Ipv6Address GetAddress(const Ipv6Prefix prefix)
Get the Ipv6Address that will be allocated upon NextAddress()
Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
Definition: ipv6-address.h:326
static bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
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.