A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ping6.cc
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 
46 {
47  static TypeId tid = TypeId ("ns3::Ping6")
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",
63  MakeIpv6AddressAccessor (&Ping6::m_peerAddress),
64  MakeIpv6AddressChecker ())
65  .AddAttribute ("LocalIpv6",
66  "Local Ipv6Address of the sender",
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 
80 {
82  m_sent = 0;
83  m_socket = 0;
84  m_seq = 0;
85  m_sendEvent = EventId ();
86 }
87 
89 {
91  m_socket = 0;
92 }
93 
95 {
98 }
99 
101 {
103 
104  if (!m_socket)
105  {
106  TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
108 
110 
113  m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6));
115  }
116 
117  ScheduleTransmit (Seconds (0.));
118 }
119 
121 {
122  NS_LOG_FUNCTION (this << ipv6);
123  m_localAddress = ipv6;
124 }
125 
127 {
128  NS_LOG_FUNCTION (this << ipv6);
129  m_peerAddress = ipv6;
130 }
131 
133 {
135 
136  if (m_socket)
137  {
139  }
140 
142 }
143 
144 void Ping6::SetIfIndex (uint32_t ifIndex)
145 {
146  m_ifIndex = ifIndex;
147 }
148 
150 {
151  NS_LOG_FUNCTION (this << dt);
153 }
154 
155 void Ping6::SetRouters (std::vector<Ipv6Address> routers)
156 {
157  m_routers = routers;
158 }
159 
160 void Ping6::Send ()
161 {
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  {
223  }
224 
225  delete[] data;
226 }
227 
229 {
230  NS_LOG_FUNCTION (this << socket);
231 
232  Ptr<Packet> packet=0;
233  Address from;
234  while ((packet = socket->RecvFrom (from)))
235  {
237  {
238  Ipv6Header hdr;
239  Icmpv6Echo reply (0);
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 
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
virtual ~Ping6()
Destructor.
Definition: ping6.cc:88
uint16_t GetId() const
Get the ID of the packet.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
keep track of time unit.
Definition: nstime.h:149
Packet header for IPv6.
Definition: ipv6-header.h:33
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual void StopApplication()
Stop the application.
Definition: ping6.cc:132
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:79
void SetTypeRouting(uint8_t typeRouting)
Set the "Type of Routing" field.
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
void SetRouters(std::vector< Ipv6Address > routers)
Set routers for routing type 0 (loose routing).
Definition: ping6.cc:155
uint32_t GetSize(void) const
Definition: packet.h:620
#define NS_LOG_INFO(msg)
Definition: log.h:264
static void Cancel(const EventId &id)
Definition: simulator.cc:267
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
Time m_interval
Intervall between packets sent.
Definition: ping6.h:147
void Send()
Send a packet.
Definition: ping6.cc:160
a polymophic address class
Definition: address.h:86
void SetIfIndex(uint32_t ifIndex)
Set the out interface index. This is to send to link-local (unicast or multicast) address when a node...
Definition: ping6.cc:144
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
The base class for all ns3 applications.
Definition: application.h:61
hold objects of type ns3::Time
Definition: nstime.h:700
virtual Ipv6InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Get IPv6 address on specified IPv6 interface.
Hold an unsigned integer type.
Definition: uinteger.h:46
Ptr< Node > GetNode() const
Definition: application.cc:103
uint32_t m_sent
Number of packets sent.
Definition: ping6.h:137
An Inet6 address class.
virtual void StartApplication()
Start the application.
Definition: ping6.cc:100
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
std::vector< Ipv6Address > m_routers
Routers addresses for routing type 0.
Definition: ping6.h:182
void SetLocal(Ipv6Address ipv6)
Set the local address.
Definition: ping6.cc:120
uint16_t GetSeq() const
Get the sequence number.
uint32_t m_size
Size of the packet.
Definition: ping6.h:142
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual void DoDispose(void)
Definition: application.cc:82
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
Ptr< Socket > m_socket
Local socket.
Definition: ping6.h:162
Callback< R > MakeNullCallback(void)
Definition: callback.h:781
Ping6()
Constructor.
Definition: ping6.cc:79
Hold objects of type ns3::Ipv6Address.
ICMPv6 Echo message.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Describes an IPv6 address.
Definition: ipv6-address.h:44
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
void SetRemote(Ipv6Address ipv6)
Set the remote peer.
Definition: ping6.cc:126
an identifier for simulation events.
Definition: event-id.h:46
uint16_t m_seq
Sequence number.
Definition: ping6.h:167
uint32_t m_ifIndex
Out interface (i.e. for link-local communication).
Definition: ping6.h:177
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Ipv6Address m_localAddress
Local address.
Definition: ping6.h:152
static bool IsMatchingType(const Address &addr)
If the address match.
void ScheduleTransmit(Time dt)
Schedule sending a packet.
Definition: ping6.cc:149
void SetLength(uint16_t length)
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Definition: packet.cc:398
virtual void DoDispose()
Dispose this object;.
Definition: ping6.cc:94
void SetSeq(uint16_t seq)
Set the sequence number.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
EventId m_sendEvent
Event ID.
Definition: ping6.h:172
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
static TypeId GetTypeId()
Get the type ID.
Definition: ping6.cc:45
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
bool IsExpired(void) const
Definition: event-id.cc:53
Ptr< T > GetObject(void) const
Definition: object.h:332
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
Ipv6Address m_peerAddress
Peer address.
Definition: ping6.h:157
void SetId(uint16_t id)
Set the ID of the packet.
void HandleRead(Ptr< Socket > socket)
Receive method.
Definition: ping6.cc:228
static TypeId LookupByName(std::string name)
Definition: type-id.cc:415
uint32_t m_count
Number of "Echo request" packets that will be sent.
Definition: ping6.h:132
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.