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
icmpv4-l4-protocol.cc
Go to the documentation of this file.
1
#include "
icmpv4-l4-protocol.h
"
2
#include "
ipv4-raw-socket-factory-impl.h
"
3
#include "
ipv4-interface.h
"
4
#include "
ipv4-l3-protocol.h
"
5
#include "ns3/assert.h"
6
#include "ns3/log.h"
7
#include "ns3/node.h"
8
#include "ns3/packet.h"
9
#include "ns3/boolean.h"
10
#include "ns3/ipv4-route.h"
11
12
namespace
ns3 {
13
14
NS_LOG_COMPONENT_DEFINE
(
"Icmpv4L4Protocol"
);
15
16
NS_OBJECT_ENSURE_REGISTERED
(Icmpv4L4Protocol);
17
18
// see rfc 792
19
const
uint8_t
Icmpv4L4Protocol::PROT_NUMBER
= 1;
20
21
TypeId
22
Icmpv4L4Protocol::GetTypeId
(
void
)
23
{
24
static
TypeId
tid =
TypeId
(
"ns3::Icmpv4L4Protocol"
)
25
.
SetParent
<
IpL4Protocol
> ()
26
.AddConstructor<Icmpv4L4Protocol> ()
27
;
28
return
tid;
29
}
30
31
Icmpv4L4Protocol::Icmpv4L4Protocol
()
32
: m_node (0)
33
{
34
NS_LOG_FUNCTION
(
this
);
35
}
36
Icmpv4L4Protocol::~Icmpv4L4Protocol
()
37
{
38
NS_LOG_FUNCTION
(
this
);
39
NS_ASSERT
(
m_node
== 0);
40
}
41
42
void
43
Icmpv4L4Protocol::SetNode
(
Ptr<Node>
node)
44
{
45
NS_LOG_FUNCTION
(
this
<< node);
46
m_node
= node;
47
}
48
49
/*
50
* This method is called by AddAgregate and completes the aggregation
51
* by setting the node in the ICMP stack and adding ICMP factory to
52
* IPv4 stack connected to the node
53
*/
54
void
55
Icmpv4L4Protocol::NotifyNewAggregate
()
56
{
57
NS_LOG_FUNCTION
(
this
);
58
if
(
m_node
== 0)
59
{
60
Ptr<Node>
node = this->GetObject<Node> ();
61
if
(node != 0)
62
{
63
Ptr<Ipv4>
ipv4 = this->GetObject<Ipv4> ();
64
if
(ipv4 != 0 &&
m_downTarget
.
IsNull
())
65
{
66
this->
SetNode
(node);
67
ipv4->
Insert
(
this
);
68
Ptr<Ipv4RawSocketFactoryImpl>
rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
69
ipv4->
AggregateObject
(rawFactory);
70
this->
SetDownTarget
(
MakeCallback
(&
Ipv4::Send
, ipv4));
71
}
72
}
73
}
74
Object::NotifyNewAggregate
();
75
}
76
77
uint16_t
78
Icmpv4L4Protocol::GetStaticProtocolNumber
(
void
)
79
{
80
NS_LOG_FUNCTION_NOARGS
();
81
return
PROT_NUMBER
;
82
}
83
84
int
85
Icmpv4L4Protocol::GetProtocolNumber
(
void
)
const
86
{
87
NS_LOG_FUNCTION
(
this
);
88
return
PROT_NUMBER
;
89
}
90
void
91
Icmpv4L4Protocol::SendMessage
(
Ptr<Packet>
packet,
Ipv4Address
dest, uint8_t type, uint8_t code)
92
{
93
NS_LOG_FUNCTION
(
this
<< packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
94
Ptr<Ipv4>
ipv4 =
m_node
->
GetObject
<
Ipv4
> ();
95
NS_ASSERT
(ipv4 != 0 && ipv4->
GetRoutingProtocol
() != 0);
96
Ipv4Header
header;
97
header.
SetDestination
(dest);
98
header.SetProtocol (
PROT_NUMBER
);
99
Socket::SocketErrno
errno_;
100
Ptr<Ipv4Route>
route;
101
Ptr<NetDevice>
oif (0);
//specify non-zero if bound to a source address
102
route = ipv4->
GetRoutingProtocol
()->
RouteOutput
(packet, header, oif, errno_);
103
if
(route != 0)
104
{
105
NS_LOG_LOGIC
(
"Route exists"
);
106
Ipv4Address
source = route->
GetSource
();
107
SendMessage
(packet, source, dest, type, code, route);
108
}
109
else
110
{
111
NS_LOG_WARN
(
"drop icmp message"
);
112
}
113
}
114
115
void
116
Icmpv4L4Protocol::SendMessage
(
Ptr<Packet>
packet,
Ipv4Address
source,
Ipv4Address
dest, uint8_t type, uint8_t code,
Ptr<Ipv4Route>
route)
117
{
118
NS_LOG_FUNCTION
(
this
<< packet << source << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code) << route);
119
Icmpv4Header
icmp;
120
icmp.
SetType
(type);
121
icmp.
SetCode
(code);
122
if
(
Node::ChecksumEnabled
())
123
{
124
icmp.
EnableChecksum
();
125
}
126
packet->
AddHeader
(icmp);
127
128
m_downTarget
(packet, source, dest,
PROT_NUMBER
, route);
129
}
130
void
131
Icmpv4L4Protocol::SendDestUnreachFragNeeded
(
Ipv4Header
header,
132
Ptr<const Packet>
orgData,
133
uint16_t nextHopMtu)
134
{
135
NS_LOG_FUNCTION
(
this
<< header << *orgData << nextHopMtu);
136
SendDestUnreach
(header, orgData,
Icmpv4DestinationUnreachable::FRAG_NEEDED
, nextHopMtu);
137
}
138
void
139
Icmpv4L4Protocol::SendDestUnreachPort
(
Ipv4Header
header,
140
Ptr<const Packet>
orgData)
141
{
142
NS_LOG_FUNCTION
(
this
<< header << *orgData);
143
SendDestUnreach
(header, orgData,
Icmpv4DestinationUnreachable::PORT_UNREACHABLE
, 0);
144
}
145
void
146
Icmpv4L4Protocol::SendDestUnreach
(
Ipv4Header
header,
Ptr<const Packet>
orgData,
147
uint8_t code, uint16_t nextHopMtu)
148
{
149
NS_LOG_FUNCTION
(
this
<< header << *orgData << (uint32_t) code << nextHopMtu);
150
Ptr<Packet>
p = Create<Packet> ();
151
Icmpv4DestinationUnreachable
unreach;
152
unreach.
SetNextHopMtu
(nextHopMtu);
153
unreach.SetHeader (header);
154
unreach.SetData (orgData);
155
p->
AddHeader
(unreach);
156
SendMessage
(p, header.
GetSource
(),
Icmpv4Header::DEST_UNREACH
, code);
157
}
158
159
void
160
Icmpv4L4Protocol::SendTimeExceededTtl
(
Ipv4Header
header,
Ptr<const Packet>
orgData)
161
{
162
NS_LOG_FUNCTION
(
this
<< header << *orgData);
163
Ptr<Packet>
p = Create<Packet> ();
164
Icmpv4TimeExceeded
time;
165
time.
SetHeader
(header);
166
time.SetData (orgData);
167
p->
AddHeader
(time);
168
SendMessage
(p, header.
GetSource
(),
Icmpv4Header::TIME_EXCEEDED
,
Icmpv4TimeExceeded::TIME_TO_LIVE
);
169
}
170
171
void
172
Icmpv4L4Protocol::HandleEcho
(
Ptr<Packet>
p,
173
Icmpv4Header
header,
174
Ipv4Address
source,
175
Ipv4Address
destination)
176
{
177
NS_LOG_FUNCTION
(
this
<< p << header << source << destination);
178
179
Ptr<Packet>
reply = Create<Packet> ();
180
Icmpv4Echo
echo;
181
p->
RemoveHeader
(echo);
182
reply->
AddHeader
(echo);
183
SendMessage
(reply, destination, source,
Icmpv4Header::ECHO_REPLY
, 0, 0);
184
}
185
void
186
Icmpv4L4Protocol::Forward
(
Ipv4Address
source,
Icmpv4Header
icmp,
187
uint32_t info,
Ipv4Header
ipHeader,
188
const
uint8_t payload[8])
189
{
190
NS_LOG_FUNCTION
(
this
<< source << icmp << info << ipHeader << payload);
191
192
Ptr<Ipv4>
ipv4 =
m_node
->
GetObject
<
Ipv4
> ();
193
Ptr<IpL4Protocol>
l4 = ipv4->
GetProtocol
(ipHeader.
GetProtocol
());
194
if
(l4 != 0)
195
{
196
l4->
ReceiveIcmp
(source, ipHeader.
GetTtl
(), icmp.
GetType
(), icmp.
GetCode
(),
197
info, ipHeader.
GetSource
(), ipHeader.
GetDestination
(), payload);
198
}
199
}
200
void
201
Icmpv4L4Protocol::HandleDestUnreach
(
Ptr<Packet>
p,
202
Icmpv4Header
icmp,
203
Ipv4Address
source,
204
Ipv4Address
destination)
205
{
206
NS_LOG_FUNCTION
(
this
<< p << icmp << source << destination);
207
208
Icmpv4DestinationUnreachable
unreach;
209
p->
PeekHeader
(unreach);
210
uint8_t payload[8];
211
unreach.
GetData
(payload);
212
Ipv4Header
ipHeader = unreach.
GetHeader
();
213
Forward
(source, icmp, unreach.
GetNextHopMtu
(), ipHeader, payload);
214
}
215
void
216
Icmpv4L4Protocol::HandleTimeExceeded
(
Ptr<Packet>
p,
217
Icmpv4Header
icmp,
218
Ipv4Address
source,
219
Ipv4Address
destination)
220
{
221
NS_LOG_FUNCTION
(
this
<< p << icmp << source << destination);
222
223
Icmpv4TimeExceeded
time;
224
p->
PeekHeader
(time);
225
uint8_t payload[8];
226
time.
GetData
(payload);
227
Ipv4Header
ipHeader = time.
GetHeader
();
228
// info field is zero for TimeExceeded on linux
229
Forward
(source, icmp, 0, ipHeader, payload);
230
}
231
232
enum
IpL4Protocol::RxStatus
233
Icmpv4L4Protocol::Receive
(
Ptr<Packet>
p,
234
Ipv4Header
const
&header,
235
Ptr<Ipv4Interface>
incomingInterface)
236
{
237
NS_LOG_FUNCTION
(
this
<< p << header << incomingInterface);
238
239
Icmpv4Header
icmp;
240
p->
RemoveHeader
(icmp);
241
switch
(icmp.
GetType
()) {
242
case
Icmpv4Header::ECHO
:
243
HandleEcho
(p, icmp, header.
GetSource
(), header.
GetDestination
());
244
break
;
245
case
Icmpv4Header::DEST_UNREACH
:
246
HandleDestUnreach
(p, icmp, header.
GetSource
(), header.
GetDestination
());
247
break
;
248
case
Icmpv4Header::TIME_EXCEEDED
:
249
HandleTimeExceeded
(p, icmp, header.
GetSource
(), header.
GetDestination
());
250
break
;
251
default
:
252
NS_LOG_DEBUG
(icmp <<
" "
<< *p);
253
break
;
254
}
255
return
IpL4Protocol::RX_OK
;
256
}
257
enum
IpL4Protocol::RxStatus
258
Icmpv4L4Protocol::Receive
(
Ptr<Packet>
p,
259
Ipv6Header
const
&header,
260
Ptr<Ipv6Interface>
incomingInterface)
261
{
262
NS_LOG_FUNCTION
(
this
<< p << header.
GetSourceAddress
() << header.
GetDestinationAddress
() << incomingInterface);
263
return
IpL4Protocol::RX_ENDPOINT_UNREACH
;
264
}
265
void
266
Icmpv4L4Protocol::DoDispose
(
void
)
267
{
268
NS_LOG_FUNCTION
(
this
);
269
m_node
= 0;
270
m_downTarget
.
Nullify
();
271
IpL4Protocol::DoDispose
();
272
}
273
274
void
275
Icmpv4L4Protocol::SetDownTarget
(
IpL4Protocol::DownTargetCallback
callback)
276
{
277
NS_LOG_FUNCTION
(
this
<< &callback);
278
m_downTarget
= callback;
279
}
280
281
void
282
Icmpv4L4Protocol::SetDownTarget6
(
IpL4Protocol::DownTargetCallback6
callback)
283
{
284
NS_LOG_FUNCTION
(
this
<< &callback);
285
}
286
287
IpL4Protocol::DownTargetCallback
288
Icmpv4L4Protocol::GetDownTarget
(
void
)
const
289
{
290
NS_LOG_FUNCTION
(
this
);
291
return
m_downTarget
;
292
}
293
294
IpL4Protocol::DownTargetCallback6
295
Icmpv4L4Protocol::GetDownTarget6
(
void
)
const
296
{
297
NS_LOG_FUNCTION
(
this
);
298
return
(
IpL4Protocol::DownTargetCallback6
)NULL;
299
}
300
301
}
// namespace ns3
src
internet
model
icmpv4-l4-protocol.cc
Generated on Tue May 14 2013 11:08:21 for ns-3 by
1.8.1.2