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