A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv4-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  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include <list>
20 #include "ns3/abort.h"
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/simulation-singleton.h"
24 #include "ipv4-address-generator.h"
25 
26 NS_LOG_COMPONENT_DEFINE ("Ipv4AddressGenerator");
27 
28 namespace ns3 {
29 
40 {
41 public:
43  virtual ~Ipv4AddressGeneratorImpl ();
44 
56  void Init (const Ipv4Address net, const Ipv4Mask mask,
57  const Ipv4Address addr);
58 
69  Ipv4Address GetNetwork (const Ipv4Mask mask) const;
70 
84  Ipv4Address NextNetwork (const Ipv4Mask mask);
85 
93  void InitAddress (const Ipv4Address addr, const Ipv4Mask mask);
94 
105  Ipv4Address NextAddress (const Ipv4Mask mask);
106 
117  Ipv4Address GetAddress (const Ipv4Mask mask) const;
118 
123  void Reset (void);
124 
136  bool AddAllocated (const Ipv4Address addr);
137 
142  void TestMode (void);
143 private:
144  static const uint32_t N_BITS = 32;
145  static const uint32_t MOST_SIGNIFICANT_BIT = 0x80000000;
146 
153  uint32_t MaskToIndex (Ipv4Mask mask) const;
154 
160  {
161 public:
162  uint32_t mask;
163  uint32_t shift;
164  uint32_t network;
165  uint32_t addr;
166  uint32_t addrMax;
167  };
168 
170 
175  class Entry
176  {
177 public:
178  uint32_t addrLow;
179  uint32_t addrHigh;
180  };
181 
182  std::list<Entry> m_entries;
183  bool m_test;
184 };
185 
187  : m_entries (), m_test (false)
188 {
189  NS_LOG_FUNCTION (this);
190  Reset ();
191 }
192 
193 void
195 {
196  NS_LOG_FUNCTION (this);
197 
198  uint32_t mask = 0;
199 //
200 // There are 32 possible masks in a 32-bit integer. Two of these are illegal
201 // for a network mask (0x00000000 and 0xffffffff). Valid network masks
202 // correspond to some nonzero number of high order bits set to one followed by
203 // some nonzero number of lower order bits set to zero.
204 //
205 // We look at a network number as an n-bit number where n is defined as the
206 // number of bits in each mask. Allocating a new network number is simply
207 // incrementing this number.
208 //
209 // In order to combine an allocated network number with an IP address, we have
210 // to shift the network into the correct alignment with respect to its mask.
211 // For example, a network mask of 0xff000000 admits the possibility of 256
212 // different network numbers since there are eight bits available. To create
213 // IP addresses, we need to shift the network number counter left by 24 bits
214 // to put it in correct alignment. This leaves 24 bits left for addresses.
215 // We make sure we don't overflow by saving a maximum address number which is
216 // just the inverse of the mask (~mask).
217 //
218  for (uint32_t i = 0; i < N_BITS; ++i)
219  {
220  m_netTable[i].mask = mask;
221  mask >>= 1;
222  mask |= MOST_SIGNIFICANT_BIT;
223  m_netTable[i].network = 1;
224  m_netTable[i].addr = 1;
225  m_netTable[i].addrMax = ~mask;
226  m_netTable[i].shift = N_BITS - i;
227  }
228  m_entries.clear ();
229  m_test = false;
230 }
231 
233 {
234  NS_LOG_FUNCTION (this);
235 }
236 
237 void
239  const Ipv4Address net,
240  const Ipv4Mask mask,
241  const Ipv4Address addr)
242 {
243  NS_LOG_FUNCTION (this << net << mask << addr);
244 //
245 // We're going to be playing with the actual bits in the network and mask so
246 // pull them out into ints.
247 //
248  uint32_t maskBits = mask.Get ();
249  uint32_t netBits = net.Get ();
250  uint32_t addrBits = addr.Get ();
251 //
252 // Some quick reasonableness testing.
253 //
254  NS_ABORT_MSG_UNLESS ((netBits & ~maskBits) == 0, "Ipv4AddressGeneratorImpl::Init (): Inconsistent network and mask");
255  NS_ABORT_MSG_UNLESS ((addrBits & maskBits) == 0, "Ipv4AddressGeneratorImpl::Init (): Inconsistent address and mask");
256 
257 //
258 // Convert the network mask into an index into the network number table.
259 // The network number comes in to us properly aligned for the mask and so
260 // needs to be shifted right into the normalized position (lowest bit of the
261 // network number at bit zero of the int that holds it).
262 //
263  uint32_t index = MaskToIndex (mask);
264 
265  m_netTable[index].network = netBits >> m_netTable[index].shift;
266  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::Init(): Address overflow");
267  m_netTable[index].addr = addrBits;
268  return;
269 }
270 
273  const Ipv4Mask mask) const
274 {
275  NS_LOG_FUNCTION (this << mask);
276 
277  uint32_t index = MaskToIndex (mask);
278  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
279 }
280 
283  const Ipv4Mask mask)
284 {
285  NS_LOG_FUNCTION (this << mask);
286 //
287 // The way this is expected to be used is that an address and network prefix
288 // are initialized, and then NextAddress() is called repeatedly to set the
289 // addresses on a given subnet. The client will expect that the first
290 // addresses will use the network prefix she used to initialize the generator
291 // with. After a subnet is assigned, the client will call NextNetwork to
292 // get the network number of the next subnet. This implies that that this
293 // operation is a pre-increment.
294 //
295  uint32_t index = MaskToIndex (mask);
296  ++m_netTable[index].network;
297  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
298 }
299 
300 void
302  const Ipv4Address addr,
303  const Ipv4Mask mask)
304 {
305  NS_LOG_FUNCTION (this << addr << mask);
306 
307  uint32_t index = MaskToIndex (mask);
308  uint32_t addrBits = addr.Get ();
309 
310  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::InitAddress(): Address overflow");
311  m_netTable[index].addr = addrBits;
312 }
313 
316  const Ipv4Mask mask) const
317 {
318  NS_LOG_FUNCTION (this << mask);
319 
320  uint32_t index = MaskToIndex (mask);
321 
322  return Ipv4Address (
323  (m_netTable[index].network << m_netTable[index].shift) |
324  m_netTable[index].addr);
325 }
326 
329 {
330  NS_LOG_FUNCTION (this << mask);
331 //
332 // The way this is expected to be used is that an address and network prefix
333 // are initialized, and then NextAddress() is called repeatedly to set the
334 // addresses on a given subnet. The client will expect that the first address
335 // she gets back is the one she used to initialize the generator with. This
336 // implies that this operation is a post-increment.
337 //
338  uint32_t index = MaskToIndex (mask);
339 
340  NS_ABORT_MSG_UNLESS (m_netTable[index].addr <= m_netTable[index].addrMax,
341  "Ipv4AddressGeneratorImpl::NextAddress(): Address overflow");
342 
343  Ipv4Address addr = Ipv4Address (
344  (m_netTable[index].network << m_netTable[index].shift) |
345  m_netTable[index].addr);
346 
347  ++m_netTable[index].addr;
348 //
349 // Make a note that we've allocated this address -- used for address collision
350 // detection.
351 //
352  AddAllocated (addr);
353  return addr;
354 }
355 
356 bool
358 {
359  NS_LOG_FUNCTION (this << address);
360 
361  uint32_t addr = address.Get ();
362 
363  NS_ABORT_MSG_UNLESS (addr, "Ipv4AddressGeneratorImpl::Add(): Allocating the broadcast address is not a good idea");
364 
365  std::list<Entry>::iterator i;
366 
367  for (i = m_entries.begin (); i != m_entries.end (); ++i)
368  {
369  NS_LOG_LOGIC ("examine entry: " << Ipv4Address ((*i).addrLow) <<
370  " to " << Ipv4Address ((*i).addrHigh));
371 //
372 // First things first. Is there an address collision -- that is, does the
373 // new address fall in a previously allocated block of addresses.
374 //
375  if (addr >= (*i).addrLow && addr <= (*i).addrHigh)
376  {
377  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
378  if (!m_test)
379  {
380  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
381  }
382  return false;
383  }
384 //
385 // If the new address is less than the lowest address in the current block,
386 // and can't be merged into to the current block, then insert it as a new
387 // block before the current block.
388 //
389  if (addr < (*i).addrLow - 1)
390  {
391  break;
392  }
393 //
394 // If the new address fits at the end of the block, look ahead to the next
395 // block and make sure it's not a collision there. If we won't overlap, then
396 // just extend the current block by one address. We expect that completely
397 // filled network ranges will be a fairly rare occurrence, so we don't worry
398 // about collapsing address range blocks.
399 //
400  if (addr == (*i).addrHigh + 1)
401  {
402  std::list<Entry>::iterator j = i;
403  ++j;
404 
405  if (j != m_entries.end ())
406  {
407  if (addr == (*j).addrLow)
408  {
409  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): "
410  "Address Collision: " << Ipv4Address (addr));
411  if (!m_test)
412  {
413  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
414  }
415  return false;
416  }
417  }
418 
419  NS_LOG_LOGIC ("New addrHigh = " << Ipv4Address (addr));
420  (*i).addrHigh = addr;
421  return true;
422  }
423 //
424 // If we get here, we know that the next lower block of addresses couldn't
425 // have been extended to include this new address since the code immediately
426 // above would have been executed and that next lower block extended upward.
427 // So we know it's safe to extend the current block down to includ the new
428 // address.
429 //
430  if (addr == (*i).addrLow - 1)
431  {
432  NS_LOG_LOGIC ("New addrLow = " << Ipv4Address (addr));
433  (*i).addrLow = addr;
434  return true;
435  }
436  }
437 
438  Entry entry;
439  entry.addrLow = entry.addrHigh = addr;
440  m_entries.insert (i, entry);
441  return true;
442 }
443 
444 void
446 {
447  NS_LOG_FUNCTION (this);
448  m_test = true;
449 }
450 
451 uint32_t
453 {
454 
455  NS_LOG_FUNCTION (this << mask);
456 
457 //
458 // We've been given a mask that has a higher order bit set for each bit of the
459 // network number. In order to translate this mask into an index, we just need
460 // to count the number of zero bits in the mask. We do this in a loop in which
461 // we shift the mask right until we find the first nonzero bit. This tells us
462 // the number of zero bits, and from this we infer the number of nonzero bits
463 // which is the number of bits in the mask.
464 //
465 // We use the number of bits in the mask as the number of bits in the network
466 // number and as the index into the network number state table.
467 //
468  uint32_t maskBits = mask.Get ();
469 
470  for (uint32_t i = 0; i < N_BITS; ++i)
471  {
472  if (maskBits & 1)
473  {
474  uint32_t index = N_BITS - i;
475  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ipv4AddressGenerator::MaskToIndex(): Illegal Mask");
476  return index;
477  }
478  maskBits >>= 1;
479  }
480  NS_ASSERT_MSG (false, "Ipv4AddressGenerator::MaskToIndex(): Impossible");
481  return 0;
482 }
483 
484 void
486  const Ipv4Address net,
487  const Ipv4Mask mask,
488  const Ipv4Address addr)
489 {
491 
493  ->Init (net, mask, addr);
494 }
495 
498 {
500 
502  ->NextNetwork (mask);
503 }
504 
507 {
509 
511  ->GetNetwork (mask);
512 }
513 
514 void
516  const Ipv4Address addr,
517  const Ipv4Mask mask)
518 {
520 
522  ->InitAddress (addr, mask);
523 }
524 
527 {
529 
531  ->GetAddress (mask);
532 }
533 
536 {
538 
540  ->NextAddress (mask);
541 }
542 
543 void
545 {
547 
549  ->Reset ();
550 }
551 
552 bool
554 {
556 
558  ->AddAllocated (addr);
559 }
560 
561 void
563 {
565 
567  ->TestMode ();
568 }
569 
570 } // namespace ns3
571 
void Init(const Ipv4Address net, const Ipv4Mask mask, const Ipv4Address addr)
Initialise the base network, mask and address for the generator.
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
This class holds the state for a given network.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
static Ipv4Address NextAddress(const Ipv4Mask mask)
Allocate the next Ipv4Address for the configured network and mask.
This class holds the allocated addresses.
uint32_t addrMax
/internal the maximum address
static void InitAddress(const Ipv4Address addr, const Ipv4Mask mask)
Set the address for the given mask.
void TestMode(void)
Used to turn off fatal errors and assertions, for testing.
bool AddAllocated(const Ipv4Address addr)
Add the Ipv4Address to the list of IPv4 entries.
static void TestMode(void)
Used to turn off fatal errors and assertions, for testing.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
#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 const uint32_t MOST_SIGNIFICANT_BIT
/internal MSB set to 1
static void Reset(void)
Reset the networks and Ipv4Address to zero.
NS_LOG_COMPONENT_DEFINE("Ipv4AddressGenerator")
void Reset(void)
Reset the networks and Ipv4Address to zero.
uint32_t MaskToIndex(Ipv4Mask mask) const
Create an index number for the network mask.
static Ipv4Address NextNetwork(const Ipv4Mask mask)
Get the next network according to the given Ipv4Mask.
uint32_t Get(void) const
Get the host-order 32-bit IP address.
Ipv4Address GetAddress(const Ipv4Mask mask) const
Get the Ipv4Address that will be allocated upon NextAddress ()
void InitAddress(const Ipv4Address addr, const Ipv4Mask mask)
Set the address for the given mask.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
std::list< Entry > m_entries
/internal contained of allocated addresses
static bool AddAllocated(const Ipv4Address addr)
Add the Ipv4Address to the list of IPv4 entries.
static const uint32_t N_BITS
/internal the number of bits in the address
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t addrLow
/internal the lowest allocated address
Implementation class of Ipv4AddressGenerator This generator assigns addresses sequentially from a pro...
static Ipv4Address GetNetwork(const Ipv4Mask mask)
Get the current network of the given Ipv4Mask.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Ipv4Address NextAddress(const Ipv4Mask mask)
Allocate the next Ipv4Address for the configured network and mask.
bool m_test
/internal test mode (if true)
uint32_t addrHigh
/internal the highest allocated address
Ipv4Address NextNetwork(const Ipv4Mask mask)
Get the next network according to the given Ipv4Mask.
Ipv4Address GetNetwork(const Ipv4Mask mask) const
Get the current network of the given Ipv4Mask.
uint32_t Get(void) const
Get the host-order 32-bit IP mask.
tuple address
Definition: first.py:37
NetworkState m_netTable[N_BITS]
/internal the available networks
static Ipv4Address GetAddress(const Ipv4Mask mask)
Get the Ipv4Address that will be allocated upon NextAddress ()
static void Init(const Ipv4Address net, const Ipv4Mask mask, const Ipv4Address addr="0.0.0.1")
Initialise the base network, mask and address for the generator.
uint32_t mask
/internal the network mask