A Discrete-Event Network Simulator
API
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 namespace ns3 {
27 
28 NS_LOG_COMPONENT_DEFINE ("Ipv4AddressGenerator");
29 
39 {
40 public:
42  virtual ~Ipv4AddressGeneratorImpl ();
43 
54  void Init (const Ipv4Address net, const Ipv4Mask mask,
55  const Ipv4Address addr);
56 
66  Ipv4Address GetNetwork (const Ipv4Mask mask) const;
67 
80  Ipv4Address NextNetwork (const Ipv4Mask mask);
81 
88  void InitAddress (const Ipv4Address addr, const Ipv4Mask mask);
89 
99  Ipv4Address NextAddress (const Ipv4Mask mask);
100 
110  Ipv4Address GetAddress (const Ipv4Mask mask) const;
111 
115  void Reset (void);
116 
127  bool AddAllocated (const Ipv4Address addr);
128 
132  void TestMode (void);
133 private:
134  static const uint32_t N_BITS = 32;
135  static const uint32_t MOST_SIGNIFICANT_BIT = 0x80000000;
136 
142  uint32_t MaskToIndex (Ipv4Mask mask) const;
143 
148  {
149 public:
150  uint32_t mask;
151  uint32_t shift;
152  uint32_t network;
153  uint32_t addr;
154  uint32_t addrMax;
155  };
156 
158 
162  class Entry
163  {
164 public:
165  uint32_t addrLow;
166  uint32_t addrHigh;
167  };
168 
169  std::list<Entry> m_entries;
170  bool m_test;
171 };
172 
174  : m_entries (), m_test (false)
175 {
176  NS_LOG_FUNCTION (this);
177  Reset ();
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION (this);
184 
185  uint32_t mask = 0;
186 //
187 // There are 32 possible masks in a 32-bit integer. Two of these are illegal
188 // for a network mask (0x00000000 and 0xffffffff). Valid network masks
189 // correspond to some nonzero number of high order bits set to one followed by
190 // some nonzero number of lower order bits set to zero.
191 //
192 // We look at a network number as an n-bit number where n is defined as the
193 // number of bits in each mask. Allocating a new network number is simply
194 // incrementing this number.
195 //
196 // In order to combine an allocated network number with an IP address, we have
197 // to shift the network into the correct alignment with respect to its mask.
198 // For example, a network mask of 0xff000000 admits the possibility of 256
199 // different network numbers since there are eight bits available. To create
200 // IP addresses, we need to shift the network number counter left by 24 bits
201 // to put it in correct alignment. This leaves 24 bits left for addresses.
202 // We make sure we don't overflow by saving a maximum address number which is
203 // just the inverse of the mask (~mask).
204 //
205  for (uint32_t i = 0; i < N_BITS; ++i)
206  {
207  m_netTable[i].mask = mask;
208  mask >>= 1;
209  mask |= MOST_SIGNIFICANT_BIT;
210  m_netTable[i].network = 1;
211  m_netTable[i].addr = 1;
212  m_netTable[i].addrMax = ~mask;
213  m_netTable[i].shift = N_BITS - i;
214  }
215  m_entries.clear ();
216  m_test = false;
217 }
218 
220 {
221  NS_LOG_FUNCTION (this);
222 }
223 
224 void
226  const Ipv4Address net,
227  const Ipv4Mask mask,
228  const Ipv4Address addr)
229 {
230  NS_LOG_FUNCTION (this << net << mask << addr);
231 //
232 // We're going to be playing with the actual bits in the network and mask so
233 // pull them out into ints.
234 //
235  uint32_t maskBits = mask.Get ();
236  uint32_t netBits = net.Get ();
237  uint32_t addrBits = addr.Get ();
238 //
239 // Some quick reasonableness testing.
240 //
241  NS_ABORT_MSG_UNLESS ((netBits & ~maskBits) == 0, "Ipv4AddressGeneratorImpl::Init (): Inconsistent network and mask");
242  NS_ABORT_MSG_UNLESS ((addrBits & maskBits) == 0, "Ipv4AddressGeneratorImpl::Init (): Inconsistent address and mask");
243 
244 //
245 // Convert the network mask into an index into the network number table.
246 // The network number comes in to us properly aligned for the mask and so
247 // needs to be shifted right into the normalized position (lowest bit of the
248 // network number at bit zero of the int that holds it).
249 //
250  uint32_t index = MaskToIndex (mask);
251 
252  m_netTable[index].network = netBits >> m_netTable[index].shift;
253  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::Init(): Address overflow");
254  m_netTable[index].addr = addrBits;
255  return;
256 }
257 
260  const Ipv4Mask mask) const
261 {
262  NS_LOG_FUNCTION (this << mask);
263 
264  uint32_t index = MaskToIndex (mask);
265  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
266 }
267 
270  const Ipv4Mask mask)
271 {
272  NS_LOG_FUNCTION (this << mask);
273 //
274 // The way this is expected to be used is that an address and network prefix
275 // are initialized, and then NextAddress() is called repeatedly to set the
276 // addresses on a given subnet. The client will expect that the first
277 // addresses will use the network prefix she used to initialize the generator
278 // with. After a subnet is assigned, the client will call NextNetwork to
279 // get the network number of the next subnet. This implies that that this
280 // operation is a pre-increment.
281 //
282  uint32_t index = MaskToIndex (mask);
283  ++m_netTable[index].network;
284  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
285 }
286 
287 void
289  const Ipv4Address addr,
290  const Ipv4Mask mask)
291 {
292  NS_LOG_FUNCTION (this << addr << mask);
293 
294  uint32_t index = MaskToIndex (mask);
295  uint32_t addrBits = addr.Get ();
296 
297  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::InitAddress(): Address overflow");
298  m_netTable[index].addr = addrBits;
299 }
300 
303  const Ipv4Mask mask) const
304 {
305  NS_LOG_FUNCTION (this << mask);
306 
307  uint32_t index = MaskToIndex (mask);
308 
309  return Ipv4Address (
310  (m_netTable[index].network << m_netTable[index].shift) |
311  m_netTable[index].addr);
312 }
313 
316 {
317  NS_LOG_FUNCTION (this << mask);
318 //
319 // The way this is expected to be used is that an address and network prefix
320 // are initialized, and then NextAddress() is called repeatedly to set the
321 // addresses on a given subnet. The client will expect that the first address
322 // she gets back is the one she used to initialize the generator with. This
323 // implies that this operation is a post-increment.
324 //
325  uint32_t index = MaskToIndex (mask);
326 
327  NS_ABORT_MSG_UNLESS (m_netTable[index].addr <= m_netTable[index].addrMax,
328  "Ipv4AddressGeneratorImpl::NextAddress(): Address overflow");
329 
330  Ipv4Address addr = Ipv4Address (
331  (m_netTable[index].network << m_netTable[index].shift) |
332  m_netTable[index].addr);
333 
334  ++m_netTable[index].addr;
335 //
336 // Make a note that we've allocated this address -- used for address collision
337 // detection.
338 //
339  AddAllocated (addr);
340  return addr;
341 }
342 
343 bool
345 {
346  NS_LOG_FUNCTION (this << address);
347 
348  uint32_t addr = address.Get ();
349 
350  NS_ABORT_MSG_UNLESS (addr, "Ipv4AddressGeneratorImpl::Add(): Allocating the broadcast address is not a good idea");
351 
352  std::list<Entry>::iterator i;
353 
354  for (i = m_entries.begin (); i != m_entries.end (); ++i)
355  {
356  NS_LOG_LOGIC ("examine entry: " << Ipv4Address ((*i).addrLow) <<
357  " to " << Ipv4Address ((*i).addrHigh));
358 //
359 // First things first. Is there an address collision -- that is, does the
360 // new address fall in a previously allocated block of addresses.
361 //
362  if (addr >= (*i).addrLow && addr <= (*i).addrHigh)
363  {
364  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
365  if (!m_test)
366  {
367  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
368  }
369  return false;
370  }
371 //
372 // If the new address is less than the lowest address in the current block,
373 // and can't be merged into to the current block, then insert it as a new
374 // block before the current block.
375 //
376  if (addr < (*i).addrLow - 1)
377  {
378  break;
379  }
380 //
381 // If the new address fits at the end of the block, look ahead to the next
382 // block and make sure it's not a collision there. If we won't overlap, then
383 // just extend the current block by one address. We expect that completely
384 // filled network ranges will be a fairly rare occurrence, so we don't worry
385 // about collapsing address range blocks.
386 //
387  if (addr == (*i).addrHigh + 1)
388  {
389  std::list<Entry>::iterator j = i;
390  ++j;
391 
392  if (j != m_entries.end ())
393  {
394  if (addr == (*j).addrLow)
395  {
396  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): "
397  "Address Collision: " << Ipv4Address (addr));
398  if (!m_test)
399  {
400  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
401  }
402  return false;
403  }
404  }
405 
406  NS_LOG_LOGIC ("New addrHigh = " << Ipv4Address (addr));
407  (*i).addrHigh = addr;
408  return true;
409  }
410 //
411 // If we get here, we know that the next lower block of addresses couldn't
412 // have been extended to include this new address since the code immediately
413 // above would have been executed and that next lower block extended upward.
414 // So we know it's safe to extend the current block down to includ the new
415 // address.
416 //
417  if (addr == (*i).addrLow - 1)
418  {
419  NS_LOG_LOGIC ("New addrLow = " << Ipv4Address (addr));
420  (*i).addrLow = addr;
421  return true;
422  }
423  }
424 
425  Entry entry;
426  entry.addrLow = entry.addrHigh = addr;
427  m_entries.insert (i, entry);
428  return true;
429 }
430 
431 void
433 {
434  NS_LOG_FUNCTION (this);
435  m_test = true;
436 }
437 
438 uint32_t
440 {
441 
442  NS_LOG_FUNCTION (this << mask);
443 
444 //
445 // We've been given a mask that has a higher order bit set for each bit of the
446 // network number. In order to translate this mask into an index, we just need
447 // to count the number of zero bits in the mask. We do this in a loop in which
448 // we shift the mask right until we find the first nonzero bit. This tells us
449 // the number of zero bits, and from this we infer the number of nonzero bits
450 // which is the number of bits in the mask.
451 //
452 // We use the number of bits in the mask as the number of bits in the network
453 // number and as the index into the network number state table.
454 //
455  uint32_t maskBits = mask.Get ();
456 
457  for (uint32_t i = 0; i < N_BITS; ++i)
458  {
459  if (maskBits & 1)
460  {
461  uint32_t index = N_BITS - i;
462  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ipv4AddressGenerator::MaskToIndex(): Illegal Mask");
463  return index;
464  }
465  maskBits >>= 1;
466  }
467  NS_ASSERT_MSG (false, "Ipv4AddressGenerator::MaskToIndex(): Impossible");
468  return 0;
469 }
470 
471 void
473  const Ipv4Address net,
474  const Ipv4Mask mask,
475  const Ipv4Address addr)
476 {
478 
480  ->Init (net, mask, addr);
481 }
482 
485 {
487 
489  ->NextNetwork (mask);
490 }
491 
494 {
496 
498  ->GetNetwork (mask);
499 }
500 
501 void
503  const Ipv4Address addr,
504  const Ipv4Mask mask)
505 {
507 
509  ->InitAddress (addr, mask);
510 }
511 
514 {
516 
518  ->GetAddress (mask);
519 }
520 
523 {
525 
527  ->NextAddress (mask);
528 }
529 
530 void
532 {
534 
536  ->Reset ();
537 }
538 
539 bool
541 {
543 
545  ->AddAllocated (addr);
546 }
547 
548 void
550 {
552 
554  ->TestMode ();
555 }
556 
557 } // namespace ns3
558 
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)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
This class holds the state for a given network.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
static Ipv4Address NextAddress(const Ipv4Mask mask)
Allocate the next Ipv4Address for the configured network and mask.
This class holds the allocated addresses.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
static void InitAddress(const Ipv4Address addr, const Ipv4Mask mask)
Set the address for the given mask.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
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.
static T * Get(void)
Get a pointer to the singleton instance.
static const uint32_t MOST_SIGNIFICANT_BIT
MSB set to 1.
static void Reset(void)
Reset the networks and Ipv4Address to zero.
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)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
std::list< Entry > m_entries
contained of allocated addresses
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static bool AddAllocated(const Ipv4Address addr)
Add the Ipv4Address to the list of IPv4 entries.
static const uint32_t N_BITS
the number of bits in the address
#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:90
uint32_t addrLow
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:40
Ipv4Address NextAddress(const Ipv4Mask mask)
Allocate the next Ipv4Address for the configured network and mask.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
uint32_t addrHigh
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]
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.