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 
38 class Ipv4AddressGeneratorImpl
39 {
40 public:
41  Ipv4AddressGeneratorImpl ();
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 
147  class NetworkState
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 
157  NetworkState m_netTable[N_BITS];
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 
173 Ipv4AddressGeneratorImpl::Ipv4AddressGeneratorImpl ()
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 = ~m_netTable[i].mask;
213  m_netTable[i].shift = N_BITS - i;
214  }
215  m_entries.clear ();
216  m_test = false;
217 }
218 
219 Ipv4AddressGeneratorImpl::~Ipv4AddressGeneratorImpl ()
220 {
221  NS_LOG_FUNCTION (this);
222 }
223 
224 void
225 Ipv4AddressGeneratorImpl::Init (
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 
254  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::Init(): Address overflow");
255  m_netTable[index].addr = addrBits;
256  return;
257 }
258 
259 Ipv4Address
260 Ipv4AddressGeneratorImpl::GetNetwork (
261  const Ipv4Mask mask) const
262 {
263  NS_LOG_FUNCTION (this << mask);
264 
265  uint32_t index = MaskToIndex (mask);
266  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
267 }
268 
269 Ipv4Address
270 Ipv4AddressGeneratorImpl::NextNetwork (
271  const Ipv4Mask mask)
272 {
273  NS_LOG_FUNCTION (this << mask);
274 //
275 // The way this is expected to be used is that an address and network prefix
276 // are initialized, and then NextAddress() is called repeatedly to set the
277 // addresses on a given subnet. The client will expect that the first
278 // addresses will use the network prefix she used to initialize the generator
279 // with. After a subnet is assigned, the client will call NextNetwork to
280 // get the network number of the next subnet. This implies that that this
281 // operation is a pre-increment.
282 //
283  uint32_t index = MaskToIndex (mask);
284  ++m_netTable[index].network;
285  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
286 }
287 
288 void
289 Ipv4AddressGeneratorImpl::InitAddress (
290  const Ipv4Address addr,
291  const Ipv4Mask mask)
292 {
293  NS_LOG_FUNCTION (this << addr << mask);
294 
295  uint32_t index = MaskToIndex (mask);
296  uint32_t addrBits = addr.Get ();
297 
298  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::InitAddress(): Address overflow");
299  m_netTable[index].addr = addrBits;
300 }
301 
302 Ipv4Address
303 Ipv4AddressGeneratorImpl::GetAddress (
304  const Ipv4Mask mask) const
305 {
306  NS_LOG_FUNCTION (this << mask);
307 
308  uint32_t index = MaskToIndex (mask);
309 
310  return Ipv4Address (
311  (m_netTable[index].network << m_netTable[index].shift) |
312  m_netTable[index].addr);
313 }
314 
315 Ipv4Address
316 Ipv4AddressGeneratorImpl::NextAddress (const Ipv4Mask mask)
317 {
318  NS_LOG_FUNCTION (this << mask);
319 //
320 // The way this is expected to be used is that an address and network prefix
321 // are initialized, and then NextAddress() is called repeatedly to set the
322 // addresses on a given subnet. The client will expect that the first address
323 // she gets back is the one she used to initialize the generator with. This
324 // implies that this operation is a post-increment.
325 //
326  uint32_t index = MaskToIndex (mask);
327 
328  NS_ABORT_MSG_UNLESS (m_netTable[index].addr <= m_netTable[index].addrMax,
329  "Ipv4AddressGeneratorImpl::NextAddress(): Address overflow");
330 
331  Ipv4Address addr = Ipv4Address (
332  (m_netTable[index].network << m_netTable[index].shift) |
333  m_netTable[index].addr);
334 
335  ++m_netTable[index].addr;
336 //
337 // Make a note that we've allocated this address -- used for address collision
338 // detection.
339 //
340  AddAllocated (addr);
341  return addr;
342 }
343 
344 bool
345 Ipv4AddressGeneratorImpl::AddAllocated (const Ipv4Address address)
346 {
347  NS_LOG_FUNCTION (this << address);
348 
349  uint32_t addr = address.Get ();
350 
351  NS_ABORT_MSG_UNLESS (addr, "Ipv4AddressGeneratorImpl::Add(): Allocating the broadcast address is not a good idea");
352 
353  std::list<Entry>::iterator i;
354 
355  for (i = m_entries.begin (); i != m_entries.end (); ++i)
356  {
357  NS_LOG_LOGIC ("examine entry: " << Ipv4Address ((*i).addrLow) <<
358  " to " << Ipv4Address ((*i).addrHigh));
359 //
360 // First things first. Is there an address collision -- that is, does the
361 // new address fall in a previously allocated block of addresses.
362 //
363  if (addr >= (*i).addrLow && addr <= (*i).addrHigh)
364  {
365  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
366  if (!m_test)
367  {
368  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
369  }
370  return false;
371  }
372 //
373 // If the new address is less than the lowest address in the current block,
374 // and can't be merged into to the current block, then insert it as a new
375 // block before the current block.
376 //
377  if (addr < (*i).addrLow - 1)
378  {
379  break;
380  }
381 //
382 // If the new address fits at the end of the block, look ahead to the next
383 // block and make sure it's not a collision there. If we won't overlap, then
384 // just extend the current block by one address. We expect that completely
385 // filled network ranges will be a fairly rare occurrence, so we don't worry
386 // about collapsing address range blocks.
387 //
388  if (addr == (*i).addrHigh + 1)
389  {
390  std::list<Entry>::iterator j = i;
391  ++j;
392 
393  if (j != m_entries.end ())
394  {
395  if (addr == (*j).addrLow)
396  {
397  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): "
398  "Address Collision: " << Ipv4Address (addr));
399  if (!m_test)
400  {
401  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
402  }
403  return false;
404  }
405  }
406 
407  NS_LOG_LOGIC ("New addrHigh = " << Ipv4Address (addr));
408  (*i).addrHigh = addr;
409  return true;
410  }
411 //
412 // If we get here, we know that the next lower block of addresses couldn't
413 // have been extended to include this new address since the code immediately
414 // above would have been executed and that next lower block extended upward.
415 // So we know it's safe to extend the current block down to includ the new
416 // address.
417 //
418  if (addr == (*i).addrLow - 1)
419  {
420  NS_LOG_LOGIC ("New addrLow = " << Ipv4Address (addr));
421  (*i).addrLow = addr;
422  return true;
423  }
424  }
425 
426  Entry entry;
427  entry.addrLow = entry.addrHigh = addr;
428  m_entries.insert (i, entry);
429  return true;
430 }
431 
432 void
433 Ipv4AddressGeneratorImpl::TestMode (void)
434 {
435  NS_LOG_FUNCTION (this);
436  m_test = true;
437 }
438 
439 uint32_t
440 Ipv4AddressGeneratorImpl::MaskToIndex (Ipv4Mask mask) const
441 {
442 
443  NS_LOG_FUNCTION (this << mask);
444 
445 //
446 // We've been given a mask that has a higher order bit set for each bit of the
447 // network number. In order to translate this mask into an index, we just need
448 // to count the number of zero bits in the mask. We do this in a loop in which
449 // we shift the mask right until we find the first nonzero bit. This tells us
450 // the number of zero bits, and from this we infer the number of nonzero bits
451 // which is the number of bits in the mask.
452 //
453 // We use the number of bits in the mask as the number of bits in the network
454 // number and as the index into the network number state table.
455 //
456  uint32_t maskBits = mask.Get ();
457 
458  for (uint32_t i = 0; i < N_BITS; ++i)
459  {
460  if (maskBits & 1)
461  {
462  uint32_t index = N_BITS - i;
463  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ipv4AddressGenerator::MaskToIndex(): Illegal Mask");
464  return index;
465  }
466  maskBits >>= 1;
467  }
468  NS_ASSERT_MSG (false, "Ipv4AddressGenerator::MaskToIndex(): Impossible");
469  return 0;
470 }
471 
472 void
474  const Ipv4Address net,
475  const Ipv4Mask mask,
476  const Ipv4Address addr)
477 {
479 
481  ->Init (net, mask, addr);
482 }
483 
484 Ipv4Address
485 Ipv4AddressGenerator::NextNetwork (const Ipv4Mask mask)
486 {
488 
490  ->NextNetwork (mask);
491 }
492 
493 Ipv4Address
494 Ipv4AddressGenerator::GetNetwork (const Ipv4Mask mask)
495 {
497 
499  ->GetNetwork (mask);
500 }
501 
502 void
504  const Ipv4Address addr,
505  const Ipv4Mask mask)
506 {
508 
510  ->InitAddress (addr, mask);
511 }
512 
513 Ipv4Address
514 Ipv4AddressGenerator::GetAddress (const Ipv4Mask mask)
515 {
517 
519  ->GetAddress (mask);
520 }
521 
522 Ipv4Address
523 Ipv4AddressGenerator::NextAddress (const Ipv4Mask mask)
524 {
526 
528  ->NextAddress (mask);
529 }
530 
531 void
533 {
535 
537  ->Reset ();
538 }
539 
540 bool
541 Ipv4AddressGenerator::AddAllocated (const Ipv4Address addr)
542 {
544 
546  ->AddAllocated (addr);
547 }
548 
549 void
551 {
553 
555  ->TestMode ();
556 }
557 
558 } // namespace ns3
559 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
static T * Get(void)
Get a pointer to the singleton instance.
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.
const uint32_t N_BITS
number of bits in a IPv4 address
static Ipv4Address NextAddress(const Ipv4Mask mask)
Allocate the next Ipv4Address for the configured network and mask.
static Ipv4Address GetAddress(const Ipv4Mask mask)
Get the Ipv4Address that will be allocated upon NextAddress ()
static bool AddAllocated(const Ipv4Address addr)
Add the Ipv4Address to the list of IPv4 entries.
static void InitAddress(const Ipv4Address addr, const Ipv4Mask mask)
Set the address for the given mask.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static void Reset(void)
Reset the networks and Ipv4Address to zero.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void Reset(void)
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition: config.cc:757
static Ipv4Address NextNetwork(const Ipv4Mask mask)
Get the next network according to the given Ipv4Mask.
static void TestMode(void)
Used to turn off fatal errors and assertions, for testing.
#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
static Ipv4Address GetNetwork(const Ipv4Mask mask)
Get the current network of the given Ipv4Mask.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
tuple address
Definition: first.py:37