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