Bug Summary

File:/tmp/asd-nat/home/nat/Work/ns-3-dev-git/build/../src/internet/model/ipv6-address-generator.cc
Location:line 302, column 26
Description:The left operand of '>>' is a garbage value

Annotated Source Code

1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2008 University of Washington
4 * Copyright (c) 2011 Atishay Jain
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <list>
21#include "ns3/abort.h"
22#include "ns3/assert.h"
23#include "ns3/log.h"
24#include "ns3/simulation-singleton.h"
25#include "ipv6-address-generator.h"
26
27namespace ns3 {
28
29NS_LOG_COMPONENT_DEFINE ("Ipv6AddressGenerator")static ns3::LogComponent g_log = ns3::LogComponent ("Ipv6AddressGenerator"
, "../src/internet/model/ipv6-address-generator.cc")
;
30
31/**
32 * \ingroup address
33 *
34 * \brief Implementation class of Ipv6AddressGenerator
35 * This generator assigns addresses sequentially from a provided
36 * network address; used in topology code. It also keeps track of all
37 * addresses assigned to perform duplicate detection.
38 *
39 */
40class Ipv6AddressGeneratorImpl
41{
42public:
43 Ipv6AddressGeneratorImpl ();
44 virtual ~Ipv6AddressGeneratorImpl ();
45
46 /**
47 * \brief Initialise the base network and interfaceId for the generator
48 *
49 * The first call to NextAddress() or GetAddress() will return the
50 * value passed in.
51 *
52 * \param net The network for the base Ipv6Address
53 * \param prefix The prefix of the base Ipv6Address
54 * \param interfaceId The base interface ID used for initialization
55 */
56 void Init (const Ipv6Address net, const Ipv6Prefix prefix,
57 const Ipv6Address interfaceId);
58
59 /**
60 * \brief Get the next network according to the given Ipv6Prefix
61 *
62 * This operation is a pre-increment, meaning that the internal state
63 * is changed before returning the new network address.
64 *
65 * This also resets the interface ID to the base interface ID that was
66 * used for initialization.
67 *
68 * \param prefix The Ipv6Prefix used to set the next network
69 * \returns the IPv6 address of the next network
70 */
71 Ipv6Address NextNetwork (const Ipv6Prefix prefix);
72
73 /**
74 * \brief Get the current network of the given Ipv6Prefix
75 *
76 * Does not change the internal state; this just peeks at the current
77 * network
78 *
79 * \param prefix The Ipv6Prefix for the current network
80 * \returns the IPv6 address of the current network
81 */
82 Ipv6Address GetNetwork (const Ipv6Prefix prefix) const;
83
84 /**
85 * \brief Set the interfaceId for the given Ipv6Prefix
86 *
87 * \param interfaceId The interfaceId to set for the current Ipv6Prefix
88 * \param prefix The Ipv6Prefix whose address is to be set
89 */
90 void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
91
92 /**
93 * \brief Get the Ipv6Address that will be allocated upon NextAddress ()
94 *
95 * Does not change the internal state; just is used to peek the next
96 * address that will be allocated upon NextAddress ()
97 *
98 * \param prefix The Ipv6Prefix for the current network
99 * \returns the IPv6 address
100 */
101 Ipv6Address GetAddress (const Ipv6Prefix prefix) const;
102
103 /**
104 * \brief Allocate the next Ipv6Address for the configured network and prefix
105 *
106 * This operation is a post-increment, meaning that the first address
107 * allocated will be the one that was initially configured.
108 *
109 * \param prefix The Ipv6Prefix for the current network
110 * \returns the IPv6 address
111 */
112 Ipv6Address NextAddress (const Ipv6Prefix prefix);
113
114 /**
115 * \brief Reset the networks and Ipv6Address to zero
116 */
117 void Reset (void);
118
119 /**
120 * \brief Add the Ipv6Address to the list of IPv6 entries
121 *
122 * Typically, this is used by external address allocators that want
123 * to make use of this class's ability to track duplicates. AddAllocated
124 * is always called internally for any address generated by NextAddress ()
125 *
126 * \param addr The Ipv6Address to be added to the list of Ipv6 entries
127 * \returns true on success
128 */
129 bool AddAllocated (const Ipv6Address addr);
130
131 /**
132 * \brief Used to turn off fatal errors and assertions, for testing
133 */
134 void TestMode (void);
135
136private:
137 static const uint32_t N_BITS = 128; //!< the number of bits in the address
138 static const uint32_t MOST_SIGNIFICANT_BIT = 0x80; //!< MSB set to 1
139
140 /**
141 * \brief Create an index number for the prefix
142 * \param prefix the prefix to index
143 * \returns an index
144 */
145 uint32_t PrefixToIndex (Ipv6Prefix prefix) const;
146
147 /**
148 * \brief This class holds the state for a given network
149 */
150 class NetworkState
151 {
152public:
153 uint8_t prefix[16]; //!< the network prefix
154 uint32_t shift; //!< a shift
155 uint8_t network[16]; //!< the network
156 uint8_t addr[16]; //!< the address
157 uint8_t addrMax[16]; //!< the maximum address
158 };
159
160 NetworkState m_netTable[N_BITS]; //!< the available networks
161
162 /**
163 * \brief This class holds the allocated addresses
164 */
165 class Entry
166 {
167public:
168 uint8_t addrLow[16]; //!< the lowest allocated address
169 uint8_t addrHigh[16]; //!< the highest allocated address
170 };
171
172 std::list<Entry> m_entries; //!< contained of allocated addresses
173 Ipv6Address m_base; //!< base address
174 bool m_test; //!< test mode (if true)
175};
176
177Ipv6AddressGeneratorImpl::Ipv6AddressGeneratorImpl ()
178 : m_entries (),
179 m_base ("::1"),
180 m_test (false)
181{
182 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
183 Reset ();
184}
185
186void
187Ipv6AddressGeneratorImpl::Reset (void)
188{
189 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
190
191 uint8_t prefix[16] = { 0};
192
193 for (uint32_t i = 0; i < N_BITS; ++i)
194 {
195 for (uint32_t j = 0; j < 16; ++j)
196 {
197 m_netTable[i].prefix[j] = prefix[j];
198 }
199 for (uint32_t j = 0; j < 15; ++j)
200 {
201 prefix[15 - j] >>= 1;
202 prefix[15 - j] |= (prefix[15 - j - 1] & 1);
203 }
204 prefix[0] |= MOST_SIGNIFICANT_BIT;
205 for (uint32_t j = 0; j < 15; ++j)
206 {
207 m_netTable[i].network[j] = 0;
208 }
209 m_netTable[i].network[15] = 1;
210 for (uint32_t j = 0; j < 15; ++j)
211 {
212 m_netTable[i].addr[j] = 0;
213 }
214 m_netTable[i].addr[15] = 1;
215 for (uint32_t j = 0; j < 16; ++j)
216 {
217 m_netTable[i].addrMax[j] = ~prefix[j];
218 }
219 m_netTable[i].shift = N_BITS - i;
220 }
221 m_entries.clear ();
222 m_base = Ipv6Address ("::1");
223 m_test = false;
224}
225
226Ipv6AddressGeneratorImpl::~Ipv6AddressGeneratorImpl ()
227{
228 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
229}
230
231void
232Ipv6AddressGeneratorImpl::Init (
233 const Ipv6Address net,
234 const Ipv6Prefix prefix,
235 const Ipv6Address interfaceId)
236{
237 NS_LOG_FUNCTION (this << net << prefix << interfaceId)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << net << prefix << interfaceId; std::
clog << ")" << std::endl; } } while (false)
;
238
239 m_base = interfaceId;
240 //
241 // We're going to be playing with the actual bits in the network and prefix so
242 // pull them out into ints.
243 //
244 uint8_t prefixBits[16];
245 prefix.GetBytes (prefixBits);
246 uint8_t netBits[16];
247 net.GetBytes (netBits);
248 uint8_t interfaceIdBits[16];
249 interfaceId.GetBytes (interfaceIdBits);
250 //
251 // Some quick reasonableness testing.
252 //
253 // Convert the network prefix into an index into the network number table.
254 // The network number comes in to us properly aligned for the prefix and so
255 // needs to be shifted right into the normalized position (lowest bit of the
256 // network number at bit zero of the int that holds it).
257 //
258 uint32_t index = PrefixToIndex (prefix);
259 NS_LOG_DEBUG ("Index " << index)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_DEBUG) << "] "; }; std::clog << "Index " <<
index << std::endl; } } while (false)
;
260 uint32_t a = m_netTable[index].shift / 8;
261 uint32_t b = m_netTable[index].shift % 8;
262 for (int32_t j = 15 - a; j >= 0; j--)
263 {
264 m_netTable[index].network[j + a] = netBits[j];
265 }
266 for (uint32_t j = 0; j < a; j++)
267 {
268 m_netTable[index].network[j] = 0;
269 }
270 for (uint32_t j = 15; j >= a; j--)
271 {
272 m_netTable[index].network[j] = m_netTable[index].network[j] >> b;
273 m_netTable[index].network[j] |= m_netTable[index].network[j - 1] << (8 - b);
274 }
275 for (int32_t j = 0; j < 16; j++)
276 {
277 m_netTable[index].addr[j] = interfaceIdBits[j];
278 }
279 return;
280}
281
282Ipv6Address
283Ipv6AddressGeneratorImpl::GetNetwork (
284 const Ipv6Prefix prefix) const
285{
286 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
287 uint8_t nw[16];
288 uint32_t index = PrefixToIndex (prefix);
289 uint32_t a = m_netTable[index].shift / 8;
290 uint32_t b = m_netTable[index].shift % 8;
291 for (uint32_t j = 0; j < 16 - a; ++j)
2
Loop condition is true. Entering loop body
3
Loop condition is false. Execution continues on line 295
292 {
293 nw[j] = m_netTable[index].network[j + a];
294 }
295 for (uint32_t j = 16 - a; j < 16; ++j)
4
Assuming 'j' is >= 16
5
Loop condition is false. Execution continues on line 299
296 {
297 nw[j] = 0;
298 }
299 for (uint32_t j = 0; j < 15; j++)
6
Loop condition is true. Entering loop body
300 {
301 nw[j] = nw[j] << b;
302 nw[j] |= nw[j + 1] >> (8 - b);
7
The left operand of '>>' is a garbage value
303 }
304 nw[15] = nw[15] << b;
305
306 return Ipv6Address (nw);
307}
308
309Ipv6Address
310Ipv6AddressGeneratorImpl::NextNetwork (
311 const Ipv6Prefix prefix)
312{
313 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
314
315 uint32_t index = PrefixToIndex (prefix);
316 // Reset the base to what was initialized
317 uint8_t interfaceIdBits[16];
318 m_base.GetBytes (interfaceIdBits);
319 for (int32_t j = 0; j < 16; j++)
320 {
321 m_netTable[index].addr[j] = interfaceIdBits[j];
322 }
323
324 for (int32_t j = 15; j >= 0; j--)
325 {
326 if (m_netTable[index].network[j] < 0xff)
327 {
328 ++m_netTable[index].network[j];
329 break;
330 }
331 else
332 {
333 ++m_netTable[index].network[j];
334 }
335 }
336
337 uint8_t nw[16];
338 uint32_t a = m_netTable[index].shift / 8;
339 uint32_t b = m_netTable[index].shift % 8;
340 for (uint32_t j = 0; j < 16 - a; ++j)
341 {
342 nw[j] = m_netTable[index].network[j + a];
343 }
344 for (uint32_t j = 16 - a; j < 16; ++j)
345 {
346 nw[j] = 0;
347 }
348 for (uint32_t j = 0; j < 15; j++)
349 {
350 nw[j] = nw[j] << b;
351 nw[j] |= nw[j + 1] >> (8 - b);
352 }
353 nw[15] = nw[15] << b;
354
355 return Ipv6Address (nw);
356
357}
358
359void
360Ipv6AddressGeneratorImpl::InitAddress (
361 const Ipv6Address interfaceId,
362 const Ipv6Prefix prefix)
363{
364 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
365
366 uint32_t index = PrefixToIndex (prefix);
367 uint8_t interfaceIdBits[16];
368 interfaceId.GetBytes (interfaceIdBits);
369
370 for (uint32_t j = 0; j < 16; ++j)
371 {
372 m_netTable[index].addr[j] = interfaceIdBits[j];
373 }
374}
375
376Ipv6Address
377Ipv6AddressGeneratorImpl::GetAddress (const Ipv6Prefix prefix) const
378{
379 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
380
381 uint32_t index = PrefixToIndex (prefix);
382
383 uint8_t nw[16];
384 uint32_t a = m_netTable[index].shift / 8;
385 uint32_t b = m_netTable[index].shift % 8;
386 for (uint32_t j = 0; j < 16 - a; ++j)
387 {
388 nw[j] = m_netTable[index].network[j + a];
389 }
390 for (uint32_t j = 16 - a; j < 16; ++j)
391 {
392 nw[j] = 0;
393 }
394 for (uint32_t j = 0; j < 15; j++)
395 {
396 nw[j] = nw[j] << b;
397 nw[j] |= nw[j + 1] >> (8 - b);
398 }
399 nw[15] = nw[15] << b;
400 for (uint32_t j = 0; j < 16; j++)
401 {
402 nw[j] |= m_netTable[index].addr[j];
403 }
404
405 return Ipv6Address (nw);
406}
407
408Ipv6Address
409Ipv6AddressGeneratorImpl::NextAddress (const Ipv6Prefix prefix)
410{
411 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
412
413 uint32_t index = PrefixToIndex (prefix);
414
415 uint8_t ad[16];
416 uint32_t a = m_netTable[index].shift / 8;
417 uint32_t b = m_netTable[index].shift % 8;
418 for (uint32_t j = 0; j < 16 - a; ++j)
419 {
420 ad[j] = m_netTable[index].network[j + a];
421 }
422 for (uint32_t j = 16 - a; j < 16; ++j)
423 {
424 ad[j] = 0;
425 }
426 for (uint32_t j = 0; j < 15; j++)
427 {
428 ad[j] = ad[j] << b;
429 ad[j] |= ad[j + 1] >> (8 - b);
430 }
431 ad[15] = ad[15] << b;
432 for (uint32_t j = 0; j < 16; j++)
433 {
434 ad[j] |= m_netTable[index].addr[j];
435 }
436 Ipv6Address addr = Ipv6Address (ad);
437
438 for (int32_t j = 15; j >= 0; j--)
439 {
440 if (m_netTable[index].addr[j] < 0xff)
441 {
442 ++m_netTable[index].addr[j];
443 break;
444 }
445 else
446 {
447 ++m_netTable[index].addr[j];
448 }
449 }
450
451 //
452 // Make a note that we've allocated this address -- used for address collision
453 // detection.
454 //
455 AddAllocated (addr);
456 return addr;
457}
458
459bool
460Ipv6AddressGeneratorImpl::AddAllocated (const Ipv6Address address)
461{
462 NS_LOG_FUNCTION (this << address)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << address; std::clog << ")" << std::
endl; } } while (false)
;
463
464 uint8_t addr[16];
465 address.GetBytes (addr);
466
467 std::list<Entry>::iterator i;
468
469 for (i = m_entries.begin (); i != m_entries.end (); ++i)
470 {
471 NS_LOG_LOGIC ("examine entry: " << Ipv6Address ((*i).addrLow) <<do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "examine entry: "
<< Ipv6Address ((*i).addrLow) << " to " <<
Ipv6Address ((*i).addrHigh) << std::endl; } } while (false
)
472 " to " << Ipv6Address ((*i).addrHigh))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "examine entry: "
<< Ipv6Address ((*i).addrLow) << " to " <<
Ipv6Address ((*i).addrHigh) << std::endl; } } while (false
)
;
473 //
474 // First things first. Is there an address collision -- that is, does the
475 // new address fall in a previously allocated block of addresses.
476 //
477 if (!(Ipv6Address (addr) < Ipv6Address ((*i).addrLow))
478 && ((Ipv6Address (addr) < Ipv6Address ((*i).addrHigh))
479 || (Ipv6Address (addr) == Ipv6Address ((*i).addrHigh))))
480 {
481 NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Ipv6AddressGeneratorImpl::Add(): Address Collision: "
<< Ipv6Address (addr) << std::endl; } } while (false
)
;
482 if (!m_test)
483 {
484 NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr))do { std::cerr << "msg=\"" << "Ipv6AddressGeneratorImpl::Add(): Address Collision: "
<< Ipv6Address (addr) << "\", "; do { std::cerr <<
"file=" << "../src/internet/model/ipv6-address-generator.cc"
<< ", line=" << 484 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false)
;
485 }
486 return false;
487 }
488 //
489 // If the new address is less than the lowest address in the current
490 // block and can't be merged into to the current block, then insert it
491 // as a new block before the current block.
492 //
493 uint8_t taddr[16];
494 for (uint32_t j = 0; j < 16; j++)
495 {
496 taddr[j] = (*i).addrLow[j];
497 }
498 taddr[15] -= 1;
499 if (Ipv6Address (addr) < Ipv6Address (taddr))
500 {
501 break;
502 }
503 //
504 // If the new address fits at the end of the block, look ahead to the next
505 // block and make sure it's not a collision there. If we won't overlap,
506 // then just extend the current block by one address. We expect that
507 // completely filled network ranges will be a fairly rare occurrence,
508 // so we don't worry about collapsing address range blocks.
509 //
510 for (uint32_t j = 0; j < 16; j++)
511 {
512 taddr[j] = (*i).addrLow[j];
513 }
514 taddr[15] += 1;
515 if (Ipv6Address (addr) == Ipv6Address (taddr))
516 {
517 std::list<Entry>::iterator j = i;
518 ++j;
519
520 if (j != m_entries.end ())
521 {
522 if (Ipv6Address (addr) == Ipv6Address ((*j).addrLow))
523 {
524 NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): "do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Ipv6AddressGeneratorImpl::Add(): "
"Address Collision: " << Ipv6Address (addr) << std
::endl; } } while (false)
525 "Address Collision: " << Ipv6Address (addr))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Ipv6AddressGeneratorImpl::Add(): "
"Address Collision: " << Ipv6Address (addr) << std
::endl; } } while (false)
;
526 if (!m_test)
527 {
528 NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr))do { std::cerr << "msg=\"" << "Ipv6AddressGeneratorImpl::Add(): Address Collision: "
<< Ipv6Address (addr) << "\", "; do { std::cerr <<
"file=" << "../src/internet/model/ipv6-address-generator.cc"
<< ", line=" << 528 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false)
;
529 }
530 return false;
531 }
532 }
533
534 NS_LOG_LOGIC ("New addrHigh = " << Ipv6Address (addr))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New addrHigh = "
<< Ipv6Address (addr) << std::endl; } } while (false
)
;
535 for (uint32_t j = 0; j < 16; j++)
536 {
537 (*i).addrHigh[j] = addr[j];
538 }
539 return true;
540 }
541 //
542 // If we get here, we know that the next lower block of addresses
543 // couldn't have been extended to include this new address since the
544 // code immediately above would have been executed and that next lower
545 // block extended upward. So we know it's safe to extend the current
546 // block down to includ the new address.
547 //
548 for (uint32_t j = 0; j < 16; j++)
549 {
550 taddr[j] = (*i).addrLow[j];
551 }
552 taddr[15] -= 1;
553 if ((Ipv6Address (addr) == Ipv6Address (taddr)))
554 {
555 NS_LOG_LOGIC ("New addrLow = " << Ipv6Address (addr))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New addrLow = "
<< Ipv6Address (addr) << std::endl; } } while (false
)
;
556 for (uint32_t j = 0; j < 16; j++)
557 {
558 (*i).addrLow[j] = addr[j];
559 }
560 return true;
561 }
562 }
563
564 Entry entry;
565 for (uint32_t j = 0; j < 16; j++)
566 {
567 entry.addrLow[j] = entry.addrHigh[j] = addr[j];
568 }
569 m_entries.insert (i, entry);
570 return true;
571}
572
573void
574Ipv6AddressGeneratorImpl::TestMode (void)
575{
576 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
577 m_test = true;
578}
579
580uint32_t
581Ipv6AddressGeneratorImpl::PrefixToIndex (Ipv6Prefix prefix) const
582{
583 //
584 // We've been given a prefix that has a higher order bit set for each bit of
585 // the network number. In order to translate this prefix into an index,
586 // we just need to count the number of zero bits in the prefix. We do this
587 // in a loop in which we shift the prefix right until we find the first
588 // nonzero bit. This tells us the number of zero bits, and from this we
589 // infer the number of nonzero bits which is the number of bits in the prefix.
590 //
591 // We use the number of bits in the prefix as the number of bits in the
592 // network number and as the index into the network number state table.
593 //
594 uint8_t prefixBits[16];
595 prefix.GetBytes (prefixBits);
596
597 for (int32_t i = 15; i >= 0; --i)
598 {
599 for (uint32_t j = 0; j < 8; ++j)
600 {
601 if (prefixBits[i] & 1)
602 {
603 uint32_t index = N_BITS - (15 - i) * 8 - j;
604 NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix")do { if (!(index > 0 && index < N_BITS)) { std::
cerr << "aborted. cond=\"" << "!(index > 0 && index < N_BITS)"
<< "\", "; do { std::cerr << "msg=\"" << "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix"
<< "\", "; do { std::cerr << "file=" << "../src/internet/model/ipv6-address-generator.cc"
<< ", line=" << 604 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
605 return index;
606 }
607 prefixBits[i] >>= 1;
608 }
609 }
610 NS_ASSERT_MSG (false, "Ipv6AddressGenerator::PrefixToIndex(): Impossible")do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "Ipv6AddressGenerator::PrefixToIndex(): Impossible"
<< "\", "; do { std::cerr << "file=" << "../src/internet/model/ipv6-address-generator.cc"
<< ", line=" << 610 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
611 return 0;
612}
613
614void
615Ipv6AddressGenerator::Init (
616 const Ipv6Address net,
617 const Ipv6Prefix prefix,
618 const Ipv6Address interfaceId)
619{
620 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
621
622 SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
623 ->Init (net, prefix, interfaceId);
624}
625
626Ipv6Address
627Ipv6AddressGenerator::NextNetwork (const Ipv6Prefix prefix)
628{
629 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
630
631 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
632 ->NextNetwork (prefix);
633}
634
635Ipv6Address
636Ipv6AddressGenerator::GetNetwork (const Ipv6Prefix prefix)
637{
638 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
639
640 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
1
Calling 'Ipv6AddressGeneratorImpl::GetNetwork'
641 ->GetNetwork (prefix);
642}
643
644void
645Ipv6AddressGenerator::InitAddress (
646 const Ipv6Address interfaceId,
647 const Ipv6Prefix prefix)
648{
649 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
650
651 SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
652 ->InitAddress (interfaceId, prefix);
653}
654
655Ipv6Address
656Ipv6AddressGenerator::GetAddress (const Ipv6Prefix prefix)
657{
658 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
659
660 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
661 ->GetAddress (prefix);
662}
663
664Ipv6Address
665Ipv6AddressGenerator::NextAddress (const Ipv6Prefix prefix)
666{
667 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
668
669 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
670 ->NextAddress (prefix);
671}
672
673void
674Ipv6AddressGenerator::Reset (void)
675{
676 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
677
678 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
679 ->Reset ();
680}
681
682bool
683Ipv6AddressGenerator::AddAllocated (const Ipv6Address addr)
684{
685 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
686
687 return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
688 ->AddAllocated (addr);
689}
690
691void
692Ipv6AddressGenerator::TestMode (void)
693{
694 NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "()" << std::endl; } } while (false
)
;
695
696 SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
697 ->TestMode ();
698}
699
700} // namespace ns3
701