A Discrete-Event Network Simulator
API
 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 "ping6.h"
22 #include "ns3/log.h"
23 #include "ns3/nstime.h"
24 #include "ns3/simulator.h"
25 #include "ns3/socket-factory.h"
26 #include "ns3/packet.h"
27 #include "ns3/socket.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/ipv6.h"
30 #include "ns3/ipv6-address.h"
31 #include "ns3/inet6-socket-address.h"
32 #include "ns3/icmpv6-header.h"
33 #include "ns3/ipv6-raw-socket-factory.h"
34 #include "ns3/ipv6-header.h"
35 #include "ns3/ipv6-extension-header.h"
36 
37 
38 namespace ns3
39 {
40 
41 NS_LOG_COMPONENT_DEFINE ("Ping6Application");
42 
44 
46 {
47  static TypeId tid = TypeId ("ns3::Ping6")
49  .SetGroupName("Internet-Apps")
50  .AddConstructor<Ping6>()
51  .AddAttribute ("MaxPackets",
52  "The maximum number of packets the application will send",
53  UintegerValue (100),
55  MakeUintegerChecker<uint32_t>())
56  .AddAttribute ("Interval",
57  "The time to wait between packets",
58  TimeValue (Seconds (1.0)),
60  MakeTimeChecker ())
61  .AddAttribute ("RemoteIpv6",
62  "The Ipv6Address of the outbound packets",
64  MakeIpv6AddressAccessor (&Ping6::m_peerAddress),
65  MakeIpv6AddressChecker ())
66  .AddAttribute ("LocalIpv6",
67  "Local Ipv6Address of the sender",
69  MakeIpv6AddressAccessor (&Ping6::m_localAddress),
70  MakeIpv6AddressChecker ())
71  .AddAttribute ("PacketSize",
72  "Size of packets generated",
73  UintegerValue (100),
75  MakeUintegerChecker<uint32_t>())
76  ;
77  return tid;
78 }
79 
81 {
83  m_sent = 0;
84  m_socket = 0;
85  m_seq = 0;
86  m_sendEvent = EventId ();
87 }
88 
90 {
92  m_socket = 0;
93 }
94 
96 {
99 }
100 
102 {
104 
105  if (!m_socket)
106  {
107  TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
109 
111 
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 
165  Ipv6Address src;
166  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
167 
168  if (m_ifIndex > 0)
169  {
170  /* hack to have ifIndex in Ipv6RawSocketImpl
171  * maybe add a SetIfIndex in Ipv6RawSocketImpl directly
172  */
173  for (uint32_t i = 0; i < GetNode ()->GetObject<Ipv6> ()->GetNAddresses (m_ifIndex); i++)
174  {
175  Ipv6InterfaceAddress srcIa;
176  srcIa = GetNode ()->GetObject<Ipv6> ()->GetAddress (m_ifIndex, i);
177 
178  if (srcIa.IsInSameSubnet (m_peerAddress))
179  {
180  src = srcIa.GetAddress ();
181  break;
182  }
183  }
184  }
185  else
186  {
187  src = m_localAddress;
188  }
189 
190  uint32_t size = m_size;
191  if (m_size<4)
192  {
193  NS_LOG_WARN ("ICMPv6 echo request payload size must be >= 4");
194  size = 4;
195  }
196 
197  uint8_t* data = new uint8_t[size];
198  memset(data, 0, size);
199  data[0] = 0xDE;
200  data[1] = 0xAD;
201  data[2] = 0xBE;
202  data[3] = 0xEF;
203 
204  Ptr<Packet> p = Create<Packet> (data, size);
205  Icmpv6Echo req (1);
206 
207  req.SetId (0xBEEF);
208  req.SetSeq (m_seq);
209  m_seq++;
210 
211  /* we do not calculate pseudo header checksum here, because we are not sure about
212  * source IPv6 address. Checksum is calculated in Ipv6RawSocketImpl.
213  */
214 
215  p->AddHeader (req);
216  m_socket->Bind (Inet6SocketAddress (src, 0));
217 
218  /* use Loose Routing (routing type 0) */
219  if (m_routers.size ())
220  {
221  Ipv6ExtensionLooseRoutingHeader routingHeader;
222  routingHeader.SetNextHeader (Ipv6Header::IPV6_ICMPV6);
223  routingHeader.SetTypeRouting (0);
224  routingHeader.SetSegmentsLeft (m_routers.size ());
225  routingHeader.SetRoutersAddress (m_routers);
226  p->AddHeader (routingHeader);
228  }
229 
231  ++m_sent;
232 
233  NS_LOG_INFO ("Sent " << p->GetSize () << " bytes to " << m_peerAddress);
234 
235  if (m_sent < m_count)
236  {
238  }
239 
240  delete[] data;
241 }
242 
244 {
245  NS_LOG_FUNCTION (this << socket);
246 
247  Ptr<Packet> packet=0;
248  Address from;
249  while ((packet = socket->RecvFrom (from)))
250  {
252  {
253  Ipv6Header hdr;
254  Icmpv6Echo reply (0);
255  Icmpv6DestinationUnreachable destUnreach;
256  Icmpv6TimeExceeded timeExceeded;
258 
259  packet->RemoveHeader (hdr);
260 
261  uint8_t type;
262  packet->CopyData (&type, sizeof(type));
263 
264  switch (type)
265  {
267  packet->RemoveHeader (reply);
268 
269  NS_LOG_INFO ("Received Echo Reply size = " << std::dec << packet->GetSize () <<
270  " bytes from " << address.GetIpv6 () <<
271  " id = " << (uint16_t)reply.GetId () <<
272  " seq = " << (uint16_t)reply.GetSeq () <<
273  " Hop Count = " << (uint16_t) (64 - hdr.GetHopLimit ()));
274  break;
276  packet->RemoveHeader (destUnreach);
277 
278  NS_LOG_INFO ("Received Destination Unreachable from " << address.GetIpv6 ());
279  break;
281  packet->RemoveHeader (timeExceeded);
282 
283  NS_LOG_INFO ("Received Time Exceeded from " << address.GetIpv6 ());
284  break;
285  default:
286  break;
287  }
288  }
289  }
290 }
291 
292 } /* namespace ns3 */
293 
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
virtual ~Ping6()
Destructor.
Definition: ping6.cc:89
uint16_t GetId() const
Get the ID of the packet.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void StopApplication()
Stop the application.
Definition: ping6.cc:132
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:81
void SetTypeRouting(uint8_t typeRouting)
Set the "Type of Routing" field.
Introspection did not find any typical Config paths.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
IPv6 address associated with an interface.
void SetRouters(std::vector< Ipv6Address > routers)
Set routers for routing type 0 (loose routing).
Definition: ping6.cc:155
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:311
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Callback< R > MakeNullCallback(void)
Definition: callback.h:1635
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:90
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
void SetIfIndex(uint32_t ifIndex)
Set the out interface index.
Definition: ping6.cc:144
Introspection did not find any typical Config paths.
Ipv6Address GetAddress() const
Get the IPv6 address.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1221
Introspection did not find any typical Config paths.
The base class for all ns3 applications.
Definition: application.h:60
AttributeValue implementation for Time.
Definition: nstime.h:957
Hold an unsigned integer type.
Definition: uinteger.h:44
uint8_t data[writeSize]
Ptr< Node > GetNode() const
Definition: application.cc:104
uint32_t m_sent
Number of packets sent.
Definition: ping6.h:137
An Inet6 address class.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
virtual void StartApplication()
Start the application.
Definition: ping6.cc:101
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
std::vector< Ipv6Address > m_routers
Routers addresses for routing type 0.
Definition: ping6.h:182
A ping6 application.
Definition: ping6.h:45
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
bool IsInSameSubnet(Ipv6Address b) const
Checks if the address is in the same subnet.
virtual void DoDispose(void)
Destructor implementation.
Definition: application.cc:83
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:90
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
Ping6()
Constructor.
Definition: ping6.cc:80
AttributeValue implementation for Ipv6Address.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:958
Introspection did not find any typical Config paths.
Describes an IPv6 address.
Definition: ipv6-address.h:48
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
void SetRemote(Ipv6Address ipv6)
Set the remote peer.
Definition: ping6.cc:126
An identifier for simulation events.
Definition: event-id.h:53
uint16_t m_seq
Sequence number.
Definition: ping6.h:167
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
uint32_t m_ifIndex
Out interface (i.e.
Definition: ping6.h:177
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
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
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:356
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
virtual void DoDispose()
Dispose this object;.
Definition: ping6.cc:95
tuple address
Definition: first.py:37
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
static TypeId GetTypeId()
Get the type ID.
Definition: ping6.cc:45
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:191
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:827
Ipv6Address m_peerAddress
Peer address.
Definition: ping6.h:157
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
void HandleRead(Ptr< Socket > socket)
Receive method.
Definition: ping6.cc:243
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:752
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.