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
ping6.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/nstime.h"
23
#include "ns3/simulator.h"
24
#include "ns3/socket-factory.h"
25
#include "ns3/packet.h"
26
#include "ns3/socket.h"
27
#include "ns3/uinteger.h"
28
#include "ns3/ipv6.h"
29
#include "ns3/ipv6-address.h"
30
#include "ns3/inet6-socket-address.h"
31
#include "ns3/icmpv6-header.h"
32
#include "ns3/ipv6-raw-socket-factory.h"
33
#include "ns3/ipv6-header.h"
34
#include "ns3/ipv6-extension-header.h"
35
36
#include "
ping6.h
"
37
38
namespace
ns3
39
{
40
41
NS_LOG_COMPONENT_DEFINE
(
"Ping6Application"
);
42
43
NS_OBJECT_ENSURE_REGISTERED
(Ping6);
44
45
TypeId
Ping6::GetTypeId
()
46
{
47
static
TypeId
tid =
TypeId
(
"ns3::Ping6"
)
48
.
SetParent
<
Application
>()
49
.AddConstructor<Ping6>()
50
.AddAttribute (
"MaxPackets"
,
51
"The maximum number of packets the application will send"
,
52
UintegerValue
(100),
53
MakeUintegerAccessor (&
Ping6::m_count
),
54
MakeUintegerChecker<uint32_t>())
55
.AddAttribute (
"Interval"
,
56
"The time to wait between packets"
,
57
TimeValue
(
Seconds
(1.0)),
58
MakeTimeAccessor (&
Ping6::m_interval
),
59
MakeTimeChecker ())
60
.AddAttribute (
"RemoteIpv6"
,
61
"The Ipv6Address of the outbound packets"
,
62
Ipv6AddressValue
(),
63
MakeIpv6AddressAccessor (&
Ping6::m_peerAddress
),
64
MakeIpv6AddressChecker ())
65
.AddAttribute (
"LocalIpv6"
,
66
"Local Ipv6Address of the sender"
,
67
Ipv6AddressValue
(),
68
MakeIpv6AddressAccessor (&
Ping6::m_localAddress
),
69
MakeIpv6AddressChecker ())
70
.AddAttribute (
"PacketSize"
,
71
"Size of packets generated"
,
72
UintegerValue
(100),
73
MakeUintegerAccessor (&
Ping6::m_size
),
74
MakeUintegerChecker<uint32_t>())
75
;
76
return
tid;
77
}
78
79
Ping6::Ping6
()
80
{
81
NS_LOG_FUNCTION_NOARGS
();
82
m_sent
= 0;
83
m_socket
= 0;
84
m_seq
= 0;
85
m_sendEvent
=
EventId
();
86
}
87
88
Ping6::~Ping6
()
89
{
90
NS_LOG_FUNCTION_NOARGS
();
91
m_socket
= 0;
92
}
93
94
void
Ping6::DoDispose
()
95
{
96
NS_LOG_FUNCTION_NOARGS
();
97
Application::DoDispose
();
98
}
99
100
void
Ping6::StartApplication
()
101
{
102
NS_LOG_FUNCTION_NOARGS
();
103
104
if
(!
m_socket
)
105
{
106
TypeId
tid =
TypeId::LookupByName
(
"ns3::Ipv6RawSocketFactory"
);
107
m_socket
=
Socket::CreateSocket
(
GetNode
(), tid);
108
109
NS_ASSERT
(
m_socket
);
110
111
m_socket
->
Bind
(
Inet6SocketAddress
(
m_localAddress
, 0));
112
m_socket
->
Connect
(
Inet6SocketAddress
(
m_peerAddress
, 0));
113
m_socket
->
SetAttribute
(
"Protocol"
,
UintegerValue
(
Ipv6Header::IPV6_ICMPV6
));
114
m_socket
->
SetRecvCallback
(
MakeCallback
(&
Ping6::HandleRead
,
this
));
115
}
116
117
ScheduleTransmit
(
Seconds
(0.));
118
}
119
120
void
Ping6::SetLocal
(
Ipv6Address
ipv6)
121
{
122
NS_LOG_FUNCTION
(
this
<< ipv6);
123
m_localAddress
= ipv6;
124
}
125
126
void
Ping6::SetRemote
(
Ipv6Address
ipv6)
127
{
128
NS_LOG_FUNCTION
(
this
<< ipv6);
129
m_peerAddress
= ipv6;
130
}
131
132
void
Ping6::StopApplication
()
133
{
134
NS_LOG_FUNCTION_NOARGS
();
135
136
if
(
m_socket
)
137
{
138
m_socket
->
SetRecvCallback
(
MakeNullCallback
<
void
,
Ptr<Socket>
>());
139
}
140
141
Simulator::Cancel
(
m_sendEvent
);
142
}
143
144
void
Ping6::SetIfIndex
(uint32_t ifIndex)
145
{
146
m_ifIndex
= ifIndex;
147
}
148
149
void
Ping6::ScheduleTransmit
(
Time
dt)
150
{
151
NS_LOG_FUNCTION
(
this
<< dt);
152
m_sendEvent
=
Simulator::Schedule
(dt, &
Ping6::Send
,
this
);
153
}
154
155
void
Ping6::SetRouters
(std::vector<Ipv6Address> routers)
156
{
157
m_routers
= routers;
158
}
159
160
void
Ping6::Send
()
161
{
162
NS_LOG_FUNCTION_NOARGS
();
163
NS_ASSERT
(
m_sendEvent
.
IsExpired
());
164
Ptr<Packet>
p = 0;
165
uint8_t*
data
=
new
uint8_t[
m_size
];
166
Ipv6Address
src;
167
Ptr<Ipv6>
ipv6 =
GetNode
()->
GetObject
<
Ipv6
> ();
168
169
if
(
m_ifIndex
> 0)
170
{
171
/* hack to have ifIndex in Ipv6RawSocketImpl
172
* maybe add a SetIfIndex in Ipv6RawSocketImpl directly
173
*/
174
src =
GetNode
()->
GetObject
<
Ipv6
> ()->GetAddress (
m_ifIndex
, 0).
GetAddress
();
175
}
176
else
177
{
178
src =
m_localAddress
;
179
}
180
181
NS_ASSERT_MSG
(
m_size
>= 4,
"ICMPv6 echo request payload size must be >= 4"
);
182
data[0] = 0xDE;
183
data[1] = 0xAD;
184
data[2] = 0xBE;
185
data[3] = 0xEF;
186
187
p = Create<Packet> (
data
, 4);
188
p->AddAtEnd (Create<Packet> (
m_size
- 4));
189
Icmpv6Echo
req (1);
190
191
req.
SetId
(0xBEEF);
192
req.
SetSeq
(
m_seq
);
193
m_seq
++;
194
195
/* we do not calculate pseudo header checksum here, because we are not sure about
196
* source IPv6 address. Checksum is calculated in Ipv6RawSocketImpl.
197
*/
198
199
p->AddHeader (req);
200
m_socket
->
Bind
(
Inet6SocketAddress
(src, 0));
201
202
/* use Loose Routing (routing type 0) */
203
if
(
m_routers
.size ())
204
{
205
Ipv6ExtensionLooseRoutingHeader
routingHeader;
206
routingHeader.
SetNextHeader
(
Ipv6Header::IPV6_ICMPV6
);
207
routingHeader.
SetLength
(
m_routers
.size () * 16 + 8);
208
routingHeader.
SetTypeRouting
(0);
209
routingHeader.
SetSegmentsLeft
(
m_routers
.size ());
210
routingHeader.
SetRoutersAddress
(
m_routers
);
211
p->AddHeader (routingHeader);
212
m_socket
->
SetAttribute
(
"Protocol"
,
UintegerValue
(
Ipv6Header::IPV6_EXT_ROUTING
));
213
}
214
215
m_socket
->
Send
(p, 0);
216
++
m_sent
;
217
218
NS_LOG_INFO
(
"Sent "
<< p->GetSize () <<
" bytes to "
<<
m_peerAddress
);
219
220
if
(
m_sent
<
m_count
)
221
{
222
ScheduleTransmit
(
m_interval
);
223
}
224
225
delete
[]
data
;
226
}
227
228
void
Ping6::HandleRead
(
Ptr<Socket>
socket)
229
{
230
NS_LOG_FUNCTION
(
this
<< socket);
231
232
Ptr<Packet>
packet=0;
233
Address
from;
234
while
((packet = socket->
RecvFrom
(from)))
235
{
236
if
(
Inet6SocketAddress::IsMatchingType
(from))
237
{
238
Ipv6Header
hdr;
239
Icmpv6Echo
reply (0);
240
Inet6SocketAddress
address =
Inet6SocketAddress::ConvertFrom
(from);
241
242
packet->
RemoveHeader
(hdr);
243
244
uint8_t type;
245
packet->
CopyData
(&type,
sizeof
(type));
246
247
switch
(type)
248
{
249
case
Icmpv6Header::ICMPV6_ECHO_REPLY
:
250
packet->
RemoveHeader
(reply);
251
252
NS_LOG_INFO
(
"Received Echo Reply size = "
<< std::dec << packet->
GetSize
() <<
" bytes from "
<< address.
GetIpv6
() <<
" id = "
<< (uint16_t)reply.
GetId
() <<
" seq = "
<< (uint16_t)reply.
GetSeq
());
253
break
;
254
default
:
255
/* other type, discard */
256
break
;
257
}
258
}
259
}
260
}
261
262
}
/* namespace ns3 */
263
src
applications
model
ping6.cc
Generated on Tue Oct 9 2012 16:45:33 for ns-3 by
1.8.1.2