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 
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 
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 
80  : m_entries (), m_test (false)
81 {
83  Reset ();
84 }
85 
86 void
88 {
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 
126 {
128 }
129 
130 void
132  const Ipv4Address net,
133  const Ipv4Mask mask,
134  const Ipv4Address addr)
135 {
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 
166  const Ipv4Mask mask) const
167 {
169 
170  uint32_t index = MaskToIndex (mask);
171  return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
172 }
173 
176  const Ipv4Mask mask)
177 {
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
195  const Ipv4Address addr,
196  const Ipv4Mask mask)
197 {
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 
209  const Ipv4Mask mask) const
210 {
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 
222 {
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
251 {
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
339 {
341  m_test = true;
342 }
343 
344 uint32_t
346 {
347 //
348 // We've been given a mask that has a higher order bit set for each bit of the
349 // network number. In order to translate this mask into an index, we just need
350 // to count the number of zero bits in the mask. We do this in a loop in which
351 // we shift the mask right until we find the first nonzero bit. This tells us
352 // the number of zero bits, and from this we infer the number of nonzero bits
353 // which is the number of bits in the mask.
354 //
355 // We use the number of bits in the mask as the number of bits in the network
356 // number and as the index into the network number state table.
357 //
358  uint32_t maskBits = mask.Get ();
359 
360  for (uint32_t i = 0; i < N_BITS; ++i)
361  {
362  if (maskBits & 1)
363  {
364  uint32_t index = N_BITS - i;
365  NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ipv4AddressGenerator::MaskToIndex(): Illegal Mask");
366  return index;
367  }
368  maskBits >>= 1;
369  }
370  NS_ASSERT_MSG (false, "Ipv4AddressGenerator::MaskToIndex(): Impossible");
371  return 0;
372 }
373 
374 void
376  const Ipv4Address net,
377  const Ipv4Mask mask,
378  const Ipv4Address addr)
379 {
381 
383  ->Init (net, mask, addr);
384 }
385 
388 {
390 
392  ->NextNetwork (mask);
393 }
394 
397 {
399 
401  ->GetNetwork (mask);
402 }
403 
404 void
406  const Ipv4Address addr,
407  const Ipv4Mask mask)
408 {
410 
412  ->InitAddress (addr, mask);
413 }
414 
417 {
419 
421  ->GetAddress (mask);
422 }
423 
426 {
428 
430  ->NextAddress (mask);
431 }
432 
433 void
435 {
437 
439  ->Reset ();
440 }
441 
442 bool
444 {
446 
448  ->AddAllocated (addr);
449 }
450 
451 void
453 {
455 
457  ->TestMode ();
458 }
459 
460 } // namespace ns3
461