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 
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 
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;
78  bool m_test;
79 };
80 
82  : m_entries (),
83  m_base ("::1"),
84  m_test (false)
85 {
86  NS_LOG_FUNCTION (this);
87  Reset ();
88 }
89 
90 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 
131 {
132  NS_LOG_FUNCTION (this);
133 }
134 
135 void
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 
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 
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
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 
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 
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
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
479 {
480  NS_LOG_FUNCTION (this);
481  m_test = true;
482 }
483 
484 uint32_t
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