A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv4-address-generator.cc
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 
31 {
32 public:
34  virtual ~Ipv4AddressGeneratorImpl ();
35 
36  void Init (const Ipv4Address net, const Ipv4Mask mask,
37  const Ipv4Address addr);
38 
39  Ipv4Address GetNetwork (const Ipv4Mask mask) const;
40  Ipv4Address NextNetwork (const Ipv4Mask mask);
41 
42  void InitAddress (const Ipv4Address addr, const Ipv4Mask mask);
43  Ipv4Address GetAddress (const Ipv4Mask mask) const;
44  Ipv4Address NextAddress (const Ipv4Mask mask);
45 
46  void Reset (void);
47  bool AddAllocated (const Ipv4Address addr);
48 
49  void TestMode (void);
50 private:
51  static const uint32_t N_BITS = 32;
52  static const uint32_t MOST_SIGNIFICANT_BIT = 0x80000000;
53 
54  uint32_t MaskToIndex (Ipv4Mask mask) const;
55 
57  {
58 public:
59  uint32_t mask;
60  uint32_t shift;
61  uint32_t network;
62  uint32_t addr;
63  uint32_t addrMax;
64  };
65 
66  NetworkState m_netTable[N_BITS];
67 
68  class Entry
69  {
70 public:
71  uint32_t addrLow;
72  uint32_t addrHigh;
73  };
74 
75  std::list<Entry> m_entries;
76  bool m_test;
77 };
78 
79 Ipv4AddressGeneratorImpl::Ipv4AddressGeneratorImpl ()
80  : m_entries (), m_test (false)
81 {
82  NS_LOG_FUNCTION (this);
83  Reset ();
84 }
85 
86 void
87 Ipv4AddressGeneratorImpl::Reset (void)
88 {
89  NS_LOG_FUNCTION (this);
90 
91  uint32_t mask = 0;
92 //
93 // There are 32 possible masks in a 32-bit integer. Two of these are illegal
94 // for a network mask (0x00000000 and 0xffffffff). Valid network masks
95 // correspond to some nonzero number of high order bits set to one followed by
96 // some nonzero number of lower order bits set to zero.
97 //
98 // We look at a network number as an n-bit number where n is defined as the
99 // number of bits in each mask. Allocating a new network number is simply
100 // incrementing this number.
101 //
102 // In order to combine an allocated network number with an IP address, we have
103 // to shift the network into the correct alignment with respect to its mask.
104 // For example, a network mask of 0xff000000 admits the possibility of 256
105 // different network numbers since there are eight bits available. To create
106 // IP addresses, we need to shift the network number counter left by 24 bits
107 // to put it in correct alignment. This leaves 24 bits left for addresses.
108 // We make sure we don't overflow by saving a maximum address number which is
109 // just the inverse of the mask (~mask).
110 //
111  for (uint32_t i = 0; i < N_BITS; ++i)
112  {
113  m_netTable[i].mask = mask;
114  mask >>= 1;
115  mask |= MOST_SIGNIFICANT_BIT;
116  m_netTable[i].network = 1;
117  m_netTable[i].addr = 1;
118  m_netTable[i].addrMax = ~mask;
119  m_netTable[i].shift = N_BITS - i;
120  }
121  m_entries.clear ();
122  m_test = false;
123 }
124 
125 Ipv4AddressGeneratorImpl::~Ipv4AddressGeneratorImpl ()
126 {
127  NS_LOG_FUNCTION (this);
128 }
129 
130 void
131 Ipv4AddressGeneratorImpl::Init (
132  const Ipv4Address net,
133  const Ipv4Mask mask,
134  const Ipv4Address addr)
135 {
136  NS_LOG_FUNCTION (this << net << mask << addr);
137 //
138 // We're going to be playing with the actual bits in the network and mask so
139 // pull them out into ints.
140 //
141  uint32_t maskBits = mask.Get ();
142  uint32_t netBits = net.Get ();
143  uint32_t addrBits = addr.Get ();
144 //
145 // Some quick reasonableness testing.
146 //
147  NS_ABORT_MSG_UNLESS ((netBits & ~maskBits) == 0, "Ipv4AddressGeneratorImpl::Init (): Inconsistent network and mask");
148  NS_ABORT_MSG_UNLESS ((addrBits & maskBits) == 0, "Ipv4AddressGeneratorImpl::Init (): Inconsistent address and mask");
149 
150 //
151 // Convert the network mask into an index into the network number table.
152 // The network number comes in to us properly aligned for the mask and so
153 // needs to be shifted right into the normalized position (lowest bit of the
154 // network number at bit zero of the int that holds it).
155 //
156  uint32_t index = MaskToIndex (mask);
157 
158  m_netTable[index].network = netBits >> m_netTable[index].shift;
159  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::Init(): Address overflow");
160  m_netTable[index].addr = addrBits;
161  return;
162 }
163 
164 Ipv4Address
165 Ipv4AddressGeneratorImpl::GetNetwork (
166  const Ipv4Mask mask) const
167 {
168  NS_LOG_FUNCTION (this << mask);
169 
170  uint32_t index = MaskToIndex (mask);
171  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
172 }
173 
174 Ipv4Address
175 Ipv4AddressGeneratorImpl::NextNetwork (
176  const Ipv4Mask mask)
177 {
178  NS_LOG_FUNCTION (this << mask);
179 //
180 // The way this is expected to be used is that an address and network prefix
181 // are initialized, and then NextAddress() is called repeatedly to set the
182 // addresses on a given subnet. The client will expect that the first
183 // addresses will use the network prefix she used to initialize the generator
184 // with. After a subnet is assigned, the client will call NextNetwork to
185 // get the network number of the next subnet. This implies that that this
186 // operation is a pre-increment.
187 //
188  uint32_t index = MaskToIndex (mask);
189  ++m_netTable[index].network;
190  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
191 }
192 
193 void
194 Ipv4AddressGeneratorImpl::InitAddress (
195  const Ipv4Address addr,
196  const Ipv4Mask mask)
197 {
198  NS_LOG_FUNCTION (this << addr << mask);
199 
200  uint32_t index = MaskToIndex (mask);
201  uint32_t addrBits = addr.Get ();
202 
203  NS_ABORT_MSG_UNLESS (addrBits <= m_netTable[index].addrMax, "Ipv4AddressGeneratorImpl::InitAddress(): Address overflow");
204  m_netTable[index].addr = addrBits;
205 }
206 
207 Ipv4Address
208 Ipv4AddressGeneratorImpl::GetAddress (
209  const Ipv4Mask mask) const
210 {
211  NS_LOG_FUNCTION (this << mask);
212 
213  uint32_t index = MaskToIndex (mask);
214 
215  return Ipv4Address (
216  (m_netTable[index].network << m_netTable[index].shift) |
217  m_netTable[index].addr);
218 }
219 
220 Ipv4Address
221 Ipv4AddressGeneratorImpl::NextAddress (const Ipv4Mask mask)
222 {
223  NS_LOG_FUNCTION (this << mask);
224 //
225 // The way this is expected to be used is that an address and network prefix
226 // are initialized, and then NextAddress() is called repeatedly to set the
227 // addresses on a given subnet. The client will expect that the first address
228 // she gets back is the one she used to initialize the generator with. This
229 // implies that this operation is a post-increment.
230 //
231  uint32_t index = MaskToIndex (mask);
232 
233  NS_ABORT_MSG_UNLESS (m_netTable[index].addr <= m_netTable[index].addrMax,
234  "Ipv4AddressGeneratorImpl::NextAddress(): Address overflow");
235 
236  Ipv4Address addr = Ipv4Address (
237  (m_netTable[index].network << m_netTable[index].shift) |
238  m_netTable[index].addr);
239 
240  ++m_netTable[index].addr;
241 //
242 // Make a note that we've allocated this address -- used for address collision
243 // detection.
244 //
245  AddAllocated (addr);
246  return addr;
247 }
248 
249 bool
250 Ipv4AddressGeneratorImpl::AddAllocated (const Ipv4Address address)
251 {
252  NS_LOG_FUNCTION (this << address);
253 
254  uint32_t addr = address.Get ();
255 
256  NS_ABORT_MSG_UNLESS (addr, "Ipv4AddressGeneratorImpl::Add(): Allocating the broadcast address is not a good idea");
257 
258  std::list<Entry>::iterator i;
259 
260  for (i = m_entries.begin (); i != m_entries.end (); ++i)
261  {
262  NS_LOG_LOGIC ("examine entry: " << Ipv4Address ((*i).addrLow) <<
263  " to " << Ipv4Address ((*i).addrHigh));
264 //
265 // First things first. Is there an address collision -- that is, does the
266 // new address fall in a previously allocated block of addresses.
267 //
268  if (addr >= (*i).addrLow && addr <= (*i).addrHigh)
269  {
270  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
271  if (!m_test)
272  {
273  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
274  }
275  return false;
276  }
277 //
278 // If the new address is less than the lowest address in the current block,
279 // and can't be merged into to the current block, then insert it as a new
280 // block before the current block.
281 //
282  if (addr < (*i).addrLow - 1)
283  {
284  break;
285  }
286 //
287 // If the new address fits at the end of the block, look ahead to the next
288 // block and make sure it's not a collision there. If we won't overlap, then
289 // just extend the current block by one address. We expect that completely
290 // filled network ranges will be a fairly rare occurrence, so we don't worry
291 // about collapsing address range blocks.
292 //
293  if (addr == (*i).addrHigh + 1)
294  {
295  std::list<Entry>::iterator j = i;
296  ++j;
297 
298  if (j != m_entries.end ())
299  {
300  if (addr == (*j).addrLow)
301  {
302  NS_LOG_LOGIC ("Ipv4AddressGeneratorImpl::Add(): "
303  "Address Collision: " << Ipv4Address (addr));
304  if (!m_test)
305  {
306  NS_FATAL_ERROR ("Ipv4AddressGeneratorImpl::Add(): Address Collision: " << Ipv4Address (addr));
307  }
308  return false;
309  }
310  }
311 
312  NS_LOG_LOGIC ("New addrHigh = " << Ipv4Address (addr));
313  (*i).addrHigh = addr;
314  return true;
315  }
316 //
317 // If we get here, we know that the next lower block of addresses couldn't
318 // have been extended to include this new address since the code immediately
319 // above would have been executed and that next lower block extended upward.
320 // So we know it's safe to extend the current block down to includ the new
321 // address.
322 //
323  if (addr == (*i).addrLow - 1)
324  {
325  NS_LOG_LOGIC ("New addrLow = " << Ipv4Address (addr));
326  (*i).addrLow = addr;
327  return true;
328  }
329  }
330 
331  Entry entry;
332  entry.addrLow = entry.addrHigh = addr;
333  m_entries.insert (i, entry);
334  return true;
335 }
336 
337 void
338 Ipv4AddressGeneratorImpl::TestMode (void)
339 {
340  NS_LOG_FUNCTION (this);
341  m_test = true;
342 }
343 
344 uint32_t
345 Ipv4AddressGeneratorImpl::MaskToIndex (Ipv4Mask mask) const
346 {
347 
348  NS_LOG_FUNCTION (this << mask);
349 
350 //
351 // We've been given a mask that has a higher order bit set for each bit of the
352 // network number. In order to translate this mask into an index, we just need
353 // to count the number of zero bits in the mask. We do this in a loop in which
354 // we shift the mask right until we find the first nonzero bit. This tells us
355 // the number of zero bits, and from this we infer the number of nonzero bits
356 // which is the number of bits in the mask.
357 //
358 // We use the number of bits in the mask as the number of bits in the network
359 // number and as the index into the network number state table.
360 //
361  uint32_t maskBits = mask.Get ();
362 
363  for (uint32_t i = 0; i < N_BITS; ++i)
364  {
365  if (maskBits & 1)
366  {
367  uint32_t index = N_BITS - i;
368  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ipv4AddressGenerator::MaskToIndex(): Illegal Mask");
369  return index;
370  }
371  maskBits >>= 1;
372  }
373  NS_ASSERT_MSG (false, "Ipv4AddressGenerator::MaskToIndex(): Impossible");
374  return 0;
375 }
376 
377 void
378 Ipv4AddressGenerator::Init (
379  const Ipv4Address net,
380  const Ipv4Mask mask,
381  const Ipv4Address addr)
382 {
384 
386  ->Init (net, mask, addr);
387 }
388 
389 Ipv4Address
390 Ipv4AddressGenerator::NextNetwork (const Ipv4Mask mask)
391 {
393 
395  ->NextNetwork (mask);
396 }
397 
398 Ipv4Address
399 Ipv4AddressGenerator::GetNetwork (const Ipv4Mask mask)
400 {
402 
404  ->GetNetwork (mask);
405 }
406 
407 void
408 Ipv4AddressGenerator::InitAddress (
409  const Ipv4Address addr,
410  const Ipv4Mask mask)
411 {
413 
415  ->InitAddress (addr, mask);
416 }
417 
418 Ipv4Address
419 Ipv4AddressGenerator::GetAddress (const Ipv4Mask mask)
420 {
422 
424  ->GetAddress (mask);
425 }
426 
427 Ipv4Address
428 Ipv4AddressGenerator::NextAddress (const Ipv4Mask mask)
429 {
431 
433  ->NextAddress (mask);
434 }
435 
436 void
437 Ipv4AddressGenerator::Reset (void)
438 {
440 
442  ->Reset ();
443 }
444 
445 bool
446 Ipv4AddressGenerator::AddAllocated (const Ipv4Address addr)
447 {
449 
451  ->AddAllocated (addr);
452 }
453 
454 void
455 Ipv4AddressGenerator::TestMode (void)
456 {
458 
460  ->TestMode ();
461 }
462 
463 } // namespace ns3
464 
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#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
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38