A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
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
30
class
Ipv4AddressGeneratorImpl
31
{
32
public
:
33
Ipv4AddressGeneratorImpl
();
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
56
class
NetworkState
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_NOARGS
();
83
Reset
();
84
}
85
86
void
87
Ipv4AddressGeneratorImpl::Reset
(
void
)
88
{
89
NS_LOG_FUNCTION_NOARGS
();
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_NOARGS
();
128
}
129
130
void
131
Ipv4AddressGeneratorImpl::Init
(
132
const
Ipv4Address
net,
133
const
Ipv4Mask
mask,
134
const
Ipv4Address
addr)
135
{
136
NS_LOG_FUNCTION_NOARGS
();
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_NOARGS
();
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_NOARGS
();
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_NOARGS
();
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_NOARGS
();
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_NOARGS
();
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_NOARGS
();
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_NOARGS
();
341
m_test
=
true
;
342
}
343
344
uint32_t
345
Ipv4AddressGeneratorImpl::MaskToIndex
(
Ipv4Mask
mask)
const
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
375
Ipv4AddressGenerator::Init
(
376
const
Ipv4Address
net,
377
const
Ipv4Mask
mask,
378
const
Ipv4Address
addr)
379
{
380
NS_LOG_FUNCTION_NOARGS
();
381
382
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
383
->Init (net, mask, addr);
384
}
385
386
Ipv4Address
387
Ipv4AddressGenerator::NextNetwork
(
const
Ipv4Mask
mask)
388
{
389
NS_LOG_FUNCTION_NOARGS
();
390
391
return
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
392
->NextNetwork (mask);
393
}
394
395
Ipv4Address
396
Ipv4AddressGenerator::GetNetwork
(
const
Ipv4Mask
mask)
397
{
398
NS_LOG_FUNCTION_NOARGS
();
399
400
return
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
401
->GetNetwork (mask);
402
}
403
404
void
405
Ipv4AddressGenerator::InitAddress
(
406
const
Ipv4Address
addr,
407
const
Ipv4Mask
mask)
408
{
409
NS_LOG_FUNCTION_NOARGS
();
410
411
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
412
->InitAddress (addr, mask);
413
}
414
415
Ipv4Address
416
Ipv4AddressGenerator::GetAddress
(
const
Ipv4Mask
mask)
417
{
418
NS_LOG_FUNCTION_NOARGS
();
419
420
return
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
421
->GetAddress (mask);
422
}
423
424
Ipv4Address
425
Ipv4AddressGenerator::NextAddress
(
const
Ipv4Mask
mask)
426
{
427
NS_LOG_FUNCTION_NOARGS
();
428
429
return
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
430
->NextAddress (mask);
431
}
432
433
void
434
Ipv4AddressGenerator::Reset
(
void
)
435
{
436
NS_LOG_FUNCTION_NOARGS
();
437
438
return
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
439
->Reset ();
440
}
441
442
bool
443
Ipv4AddressGenerator::AddAllocated
(
const
Ipv4Address
addr)
444
{
445
NS_LOG_FUNCTION_NOARGS
();
446
447
return
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
448
->AddAllocated (addr);
449
}
450
451
void
452
Ipv4AddressGenerator::TestMode
(
void
)
453
{
454
NS_LOG_FUNCTION_NOARGS
();
455
456
SimulationSingleton<Ipv4AddressGeneratorImpl>::Get
()
457
->TestMode ();
458
}
459
460
}
// namespace ns3
461
src
internet
model
ipv4-address-generator.cc
Generated on Tue Oct 9 2012 16:45:38 for ns-3 by
1.8.1.2