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
ipv6-interface.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2007-2009 Strasbourg University
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
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19
*/
20
21
#include "ns3/log.h"
22
#include "ns3/node.h"
23
#include "ns3/packet.h"
24
25
#include "
ipv6-interface.h
"
26
#include "ns3/net-device.h"
27
#include "
loopback-net-device.h
"
28
#include "ns3/mac16-address.h"
29
#include "ns3/mac64-address.h"
30
#include "
ipv6-l3-protocol.h
"
31
#include "
icmpv6-l4-protocol.h
"
32
#include "
ndisc-cache.h
"
33
34
namespace
ns3
35
{
36
37
NS_LOG_COMPONENT_DEFINE
(
"Ipv6Interface"
);
38
39
NS_OBJECT_ENSURE_REGISTERED
(Ipv6Interface);
40
41
TypeId
Ipv6Interface::GetTypeId
()
42
{
43
static
TypeId
tid =
TypeId
(
"ns3::Ipv6Interface"
)
44
.
SetParent
<
Object
> ()
45
;
46
return
tid;
47
}
48
49
Ipv6Interface::Ipv6Interface
()
50
: m_ifup (false),
51
m_forwarding (true),
52
m_metric (1),
53
m_node (0),
54
m_device (0),
55
m_ndCache (0),
56
m_curHopLimit (0),
57
m_baseReachableTime (0),
58
m_reachableTime (0),
59
m_retransTimer (0)
60
{
61
NS_LOG_FUNCTION
(
this
);
62
}
63
64
Ipv6Interface::~Ipv6Interface
()
65
{
66
NS_LOG_FUNCTION_NOARGS
();
67
}
68
69
void
Ipv6Interface::DoDispose
()
70
{
71
NS_LOG_FUNCTION_NOARGS
();
72
m_node
= 0;
73
m_device
= 0;
74
m_ndCache
= 0;
75
Object::DoDispose
();
76
}
77
78
void
Ipv6Interface::DoSetup
()
79
{
80
NS_LOG_FUNCTION_NOARGS
();
81
82
if
(
m_node
== 0 ||
m_device
== 0)
83
{
84
return
;
85
}
86
87
/* set up link-local address */
88
if
(!DynamicCast<LoopbackNetDevice> (
m_device
))
/* no autoconf for ip6-localhost */
89
{
90
Address
addr =
GetDevice
()->
GetAddress
();
91
92
if
(
Mac64Address::IsMatchingType
(addr))
93
{
94
Ipv6InterfaceAddress
ifaddr =
Ipv6InterfaceAddress
(
Ipv6Address::MakeAutoconfiguredLinkLocalAddress
(
Mac64Address::ConvertFrom
(addr)),
Ipv6Prefix
(64));
95
AddAddress
(ifaddr);
96
}
97
else
if
(
Mac48Address::IsMatchingType
(addr))
98
{
99
Ipv6InterfaceAddress
ifaddr =
Ipv6InterfaceAddress
(
Ipv6Address::MakeAutoconfiguredLinkLocalAddress
(
Mac48Address::ConvertFrom
(addr)),
Ipv6Prefix
(64));
100
AddAddress
(ifaddr);
101
}
102
else
if
(
Mac16Address::IsMatchingType
(addr))
103
{
104
Ipv6InterfaceAddress
ifaddr =
Ipv6InterfaceAddress
(
Ipv6Address::MakeAutoconfiguredLinkLocalAddress
(
Mac16Address::ConvertFrom
(addr)),
Ipv6Prefix
(64));
105
AddAddress
(ifaddr);
106
}
107
else
108
{
109
NS_ASSERT_MSG
(
false
,
"IPv6 autoconf for this kind of address not implemented."
);
110
}
111
}
112
else
113
{
114
return
;
/* no NDISC cache for ip6-localhost */
115
}
116
117
Ptr<Icmpv6L4Protocol>
icmpv6 =
m_node
->
GetObject
<
Ipv6L3Protocol
> ()->GetIcmpv6 ();
118
if
(
m_device
->
NeedsArp
())
119
{
120
m_ndCache
= icmpv6->CreateCache (
m_device
,
this
);
121
}
122
}
123
124
void
Ipv6Interface::SetNode
(
Ptr<Node>
node)
125
{
126
NS_LOG_FUNCTION
(
this
<< node);
127
m_node
= node;
128
DoSetup
();
129
}
130
131
void
Ipv6Interface::SetDevice
(
Ptr<NetDevice>
device)
132
{
133
NS_LOG_FUNCTION
(
this
<< device);
134
m_device
= device;
135
DoSetup
();
136
}
137
138
Ptr<NetDevice>
Ipv6Interface::GetDevice
()
const
139
{
140
NS_LOG_FUNCTION_NOARGS
();
141
return
m_device
;
142
}
143
144
void
Ipv6Interface::SetMetric
(uint16_t metric)
145
{
146
NS_LOG_FUNCTION
(
this
<< metric);
147
m_metric
= metric;
148
}
149
150
uint16_t
Ipv6Interface::GetMetric
()
const
151
{
152
NS_LOG_FUNCTION_NOARGS
();
153
return
m_metric
;
154
}
155
156
bool
Ipv6Interface::IsUp
()
const
157
{
158
NS_LOG_FUNCTION_NOARGS
();
159
return
m_ifup
;
160
}
161
162
bool
Ipv6Interface::IsDown
()
const
163
{
164
NS_LOG_FUNCTION_NOARGS
();
165
return
!
m_ifup
;
166
}
167
168
void
Ipv6Interface::SetUp
()
169
{
170
NS_LOG_FUNCTION_NOARGS
();
171
172
if
(
m_ifup
)
173
{
174
return
;
175
}
176
m_ifup
=
true
;
177
}
178
179
void
Ipv6Interface::SetDown
()
180
{
181
NS_LOG_FUNCTION_NOARGS
();
182
m_ifup
=
false
;
183
m_addresses
.clear ();
184
}
185
186
bool
Ipv6Interface::IsForwarding
()
const
187
{
188
NS_LOG_FUNCTION_NOARGS
();
189
return
m_forwarding
;
190
}
191
192
void
Ipv6Interface::SetForwarding
(
bool
forwarding)
193
{
194
NS_LOG_FUNCTION
(
this
<< forwarding);
195
m_forwarding
= forwarding;
196
}
197
198
bool
Ipv6Interface::AddAddress
(
Ipv6InterfaceAddress
iface)
199
{
200
NS_LOG_FUNCTION_NOARGS
();
201
Ipv6Address
addr = iface.
GetAddress
();
202
203
/* DAD handling */
204
if
(!addr.
IsAny
())
205
{
206
for
(
Ipv6InterfaceAddressListCI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
207
{
208
if
((*it).GetAddress () == addr)
209
{
210
return
false
;
211
}
212
}
213
214
m_addresses
.push_back (iface);
215
216
if
(!addr.
IsAny
() || !addr.
IsLocalhost
())
217
{
218
/* DAD handling */
219
Ptr<Icmpv6L4Protocol>
icmpv6 =
m_node
->
GetObject
<
Ipv6L3Protocol
> ()->GetIcmpv6 ();
220
221
if
(icmpv6 && icmpv6->IsAlwaysDad ())
222
{
223
Simulator::Schedule
(Seconds (0.), &
Icmpv6L4Protocol::DoDAD
, icmpv6, addr,
this
);
224
Simulator::Schedule
(Seconds (1.), &
Icmpv6L4Protocol::FunctionDadTimeout
, icmpv6,
this
, addr);
225
}
226
}
227
return
true
;
228
}
229
230
/* bad address */
231
return
false
;
232
}
233
234
Ipv6InterfaceAddress
Ipv6Interface::GetLinkLocalAddress
()
const
235
{
236
/* IPv6 interface has always at least one IPv6 link-local address */
237
NS_LOG_FUNCTION_NOARGS
();
238
239
for
(
Ipv6InterfaceAddressListCI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
240
{
241
if
((*it).GetAddress ().IsLinkLocal ())
242
{
243
return
(*it);
244
}
245
}
246
NS_ASSERT_MSG
(
false
,
"No link-local address on interface "
<<
this
);
247
Ipv6InterfaceAddress
addr;
248
return
addr;
/* quiet compiler */
249
}
250
251
Ipv6InterfaceAddress
Ipv6Interface::GetAddress
(uint32_t index)
const
252
{
253
NS_LOG_FUNCTION
(
this
<< index);
254
uint32_t i = 0;
255
256
if
(
m_addresses
.size () > index)
257
{
258
for
(
Ipv6InterfaceAddressListCI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
259
{
260
if
(i == index)
261
{
262
return
(*it);
263
}
264
i++;
265
}
266
}
267
268
NS_ASSERT_MSG
(
false
,
"Address "
<< index <<
" not found"
);
269
Ipv6InterfaceAddress
addr;
270
return
addr;
/* quiet compiler */
271
}
272
273
uint32_t
Ipv6Interface::GetNAddresses
()
const
274
{
275
NS_LOG_FUNCTION_NOARGS
();
276
return
m_addresses
.size ();
277
}
278
279
Ipv6InterfaceAddress
Ipv6Interface::RemoveAddress
(uint32_t index)
280
{
281
NS_LOG_FUNCTION
(
this
<< index);
282
uint32_t i = 0;
283
284
if
(
m_addresses
.size () < index)
285
{
286
NS_ASSERT_MSG
(
false
,
"Try to remove index that don't exist in Ipv6Interface::RemoveAddress"
);
287
}
288
289
for
(
Ipv6InterfaceAddressListI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
290
{
291
if
(i == index)
292
{
293
Ipv6InterfaceAddress
iface = (*it);
294
m_addresses
.erase (it);
295
return
iface;
296
}
297
298
i++;
299
}
300
301
NS_ASSERT_MSG
(
false
,
"Address "
<< index <<
" not found"
);
302
Ipv6InterfaceAddress
addr;
303
return
addr;
/* quiet compiler */
304
}
305
306
Ipv6InterfaceAddress
307
Ipv6Interface::RemoveAddress
(
Ipv6Address
address
)
308
{
309
NS_LOG_FUNCTION
(
this
<< address);
310
311
if
(address == address.
GetLoopback
())
312
{
313
NS_LOG_WARN
(
"Cannot remove loopback address."
);
314
return
Ipv6InterfaceAddress
();
315
}
316
317
for
(
Ipv6InterfaceAddressListI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
318
{
319
if
((*it).GetAddress() ==
address
)
320
{
321
Ipv6InterfaceAddress
iface = (*it);
322
m_addresses
.erase(it);
323
return
iface;
324
}
325
}
326
return
Ipv6InterfaceAddress
();
327
}
328
329
Ipv6InterfaceAddress
Ipv6Interface::GetAddressMatchingDestination
(
Ipv6Address
dst)
330
{
331
NS_LOG_FUNCTION
(
this
<< dst);
332
333
for
(Ipv6InterfaceAddressList::const_iterator it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
334
{
335
Ipv6InterfaceAddress
ifaddr = (*it);
336
337
if
(ifaddr.
GetPrefix
().
IsMatch
(ifaddr.
GetAddress
(), dst))
338
{
339
return
ifaddr;
340
}
341
}
342
343
/* NS_ASSERT_MSG (false, "Not matching address."); */
344
Ipv6InterfaceAddress
ret;
345
return
ret;
/* quiet compiler */
346
}
347
348
void
Ipv6Interface::Send
(
Ptr<Packet>
p,
Ipv6Address
dest)
349
{
350
NS_LOG_FUNCTION
(
this
<< p << dest);
351
Ptr<Ipv6L3Protocol>
ipv6 =
m_node
->
GetObject
<
Ipv6L3Protocol
> ();
352
353
if
(!
IsUp
())
354
{
355
return
;
356
}
357
358
/* check if destination is localhost (::1) */
359
if
(DynamicCast<LoopbackNetDevice> (
m_device
))
360
{
364
m_device
->
Send
(p,
m_device
->
GetBroadcast
(),
Ipv6L3Protocol::PROT_NUMBER
);
365
return
;
366
}
367
368
/* check if destination is for one of our interface */
369
for
(
Ipv6InterfaceAddressListCI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
370
{
371
if
(dest == (*it).GetAddress ())
372
{
373
ipv6->Receive (
m_device
, p,
Ipv6L3Protocol::PROT_NUMBER
,
374
m_device
->
GetBroadcast
(),
375
m_device
->
GetBroadcast
(),
376
NetDevice::PACKET_HOST
// note: linux uses PACKET_LOOPBACK here
377
);
378
return
;
379
}
380
}
381
382
/* other address */
383
if
(
m_device
->
NeedsArp
())
384
{
385
NS_LOG_LOGIC
(
"Needs ARP"
<<
" "
<< dest);
386
Ptr<Icmpv6L4Protocol>
icmpv6 = ipv6->GetIcmpv6 ();
387
Address
hardwareDestination;
388
bool
found =
false
;
389
390
NS_ASSERT
(icmpv6);
391
392
if
(dest.
IsMulticast
())
393
{
394
NS_LOG_LOGIC
(
"IsMulticast"
);
395
NS_ASSERT_MSG
(
m_device
->
IsMulticast
(),
"Ipv6Interface::SendTo (): Sending multicast packet over non-multicast device"
);
396
397
hardwareDestination =
m_device
->
GetMulticast
(dest);
398
found =
true
;
399
}
400
else
401
{
402
NS_LOG_LOGIC
(
"NDISC Lookup"
);
403
found = icmpv6->Lookup (p, dest,
GetDevice
(),
m_ndCache
, &hardwareDestination);
404
}
405
406
if
(found)
407
{
408
NS_LOG_LOGIC
(
"Address Resolved. Send."
);
409
m_device
->
Send
(p, hardwareDestination,
Ipv6L3Protocol::PROT_NUMBER
);
410
}
411
}
412
else
413
{
414
NS_LOG_LOGIC
(
"Doesn't need ARP"
);
415
m_device
->
Send
(p,
m_device
->
GetBroadcast
(),
Ipv6L3Protocol::PROT_NUMBER
);
416
}
417
}
418
419
void
Ipv6Interface::SetCurHopLimit
(uint8_t curHopLimit)
420
{
421
NS_LOG_FUNCTION
(
this
<< curHopLimit);
422
m_curHopLimit
= curHopLimit;
423
}
424
425
uint8_t
Ipv6Interface::GetCurHopLimit
()
const
426
{
427
NS_LOG_FUNCTION_NOARGS
();
428
return
m_curHopLimit
;
429
}
430
431
void
Ipv6Interface::SetBaseReachableTime
(uint16_t baseReachableTime)
432
{
433
NS_LOG_FUNCTION
(
this
<< baseReachableTime);
434
m_baseReachableTime
= baseReachableTime;
435
}
436
437
uint16_t
Ipv6Interface::GetBaseReachableTime
()
const
438
{
439
NS_LOG_FUNCTION_NOARGS
();
440
return
m_baseReachableTime
;
441
}
442
443
void
Ipv6Interface::SetReachableTime
(uint16_t reachableTime)
444
{
445
NS_LOG_FUNCTION
(
this
<< reachableTime);
446
m_reachableTime
= reachableTime;
447
}
448
449
uint16_t
Ipv6Interface::GetReachableTime
()
const
450
{
451
NS_LOG_FUNCTION_NOARGS
();
452
return
m_reachableTime
;
453
}
454
455
void
Ipv6Interface::SetRetransTimer
(uint16_t retransTimer)
456
{
457
NS_LOG_FUNCTION
(
this
<< retransTimer);
458
m_retransTimer
= retransTimer;
459
}
460
461
uint16_t
Ipv6Interface::GetRetransTimer
()
const
462
{
463
NS_LOG_FUNCTION_NOARGS
();
464
return
m_retransTimer
;
465
}
466
467
void
Ipv6Interface::SetState
(
Ipv6Address
address
,
Ipv6InterfaceAddress::State_e
state)
468
{
469
NS_LOG_FUNCTION
(
this
<< address << state);
470
471
for
(
Ipv6InterfaceAddressListI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
472
{
473
if
((*it).GetAddress () ==
address
)
474
{
475
(*it).SetState (state);
476
return
;
477
}
478
}
479
/* not found, maybe address has expired */
480
}
481
482
void
Ipv6Interface::SetNsDadUid
(
Ipv6Address
address
, uint32_t uid)
483
{
484
NS_LOG_FUNCTION
(
this
<< address << uid);
485
486
for
(
Ipv6InterfaceAddressListI
it =
m_addresses
.begin (); it !=
m_addresses
.end (); ++it)
487
{
488
if
((*it).GetAddress () ==
address
)
489
{
490
(*it).SetNsDadUid (uid);
491
return
;
492
}
493
}
494
/* not found, maybe address has expired */
495
}
496
497
}
/* namespace ns3 */
498
src
internet
model
ipv6-interface.cc
Generated on Fri Aug 30 2013 01:42:51 for ns-3 by
1.8.1.2