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 "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 
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 
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  */
175  for (uint32_t i = 0; i < GetNode ()->GetObject<Ipv6> ()->GetNAddresses (m_ifIndex); i++)
176  {
177  src = GetNode ()->GetObject<Ipv6> ()->GetAddress (m_ifIndex, i).GetAddress ();
178  Ipv6InterfaceAddress srcIa (src);
179  if ( srcIa.GetScope() == dstIa.GetScope() )
180  {
181  break;
182  }
183  }
184  }
185  else
186  {
187  src = m_localAddress;
188  }
189 
190  NS_ASSERT_MSG (m_size >= 4, "ICMPv6 echo request payload size must be >= 4");
191  data[0] = 0xDE;
192  data[1] = 0xAD;
193  data[2] = 0xBE;
194  data[3] = 0xEF;
195 
196  p = Create<Packet> (data, 4);
197  p->AddAtEnd (Create<Packet> (m_size - 4));
198  Icmpv6Echo req (1);
199 
200  req.SetId (0xBEEF);
201  req.SetSeq (m_seq);
202  m_seq++;
203 
204  /* we do not calculate pseudo header checksum here, because we are not sure about
205  * source IPv6 address. Checksum is calculated in Ipv6RawSocketImpl.
206  */
207 
208  p->AddHeader (req);
209  m_socket->Bind (Inet6SocketAddress (src, 0));
210 
211  /* use Loose Routing (routing type 0) */
212  if (m_routers.size ())
213  {
214  Ipv6ExtensionLooseRoutingHeader routingHeader;
215  routingHeader.SetNextHeader (Ipv6Header::IPV6_ICMPV6);
216  routingHeader.SetLength (m_routers.size () * 16 + 8);
217  routingHeader.SetTypeRouting (0);
218  routingHeader.SetSegmentsLeft (m_routers.size ());
219  routingHeader.SetRoutersAddress (m_routers);
220  p->AddHeader (routingHeader);
222  }
223 
224  m_socket->Send (p, 0);
225  ++m_sent;
226 
227  NS_LOG_INFO ("Sent " << p->GetSize () << " bytes to " << m_peerAddress);
228 
229  if (m_sent < m_count)
230  {
232  }
233 
234  delete[] data;
235 }
236 
238 {
239  NS_LOG_FUNCTION (this << socket);
240 
241  Ptr<Packet> packet=0;
242  Address from;
243  while ((packet = socket->RecvFrom (from)))
244  {
246  {
247  Ipv6Header hdr;
248  Icmpv6Echo reply (0);
250 
251  packet->RemoveHeader (hdr);
252 
253  uint8_t type;
254  packet->CopyData (&type, sizeof(type));
255 
256  switch (type)
257  {
259  packet->RemoveHeader (reply);
260 
261  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 ());
262  break;
263  default:
264  /* other type, discard */
265  break;
266  }
267  }
268  }
269 }
270 
271 } /* namespace ns3 */
272 
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:268
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 values and allow control of global simulation resolution
Definition: nstime.h:81
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
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
Definition: packet.h:650
#define NS_LOG_INFO(msg)
Definition: log.h:264
static void Cancel(const EventId &id)
Definition: simulator.cc:268
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
Callback< R > MakeNullCallback(void)
Definition: callback.h:1395
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
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:828
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
uint8_t data[writeSize]
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Ptr< Node > GetNode() const
Definition: application.cc:103
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:1238
virtual void StartApplication()
Start the application.
Definition: ping6.cc:100
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
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:46
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
Ipv6InterfaceAddress::Scope_e GetScope() const
Get address scope.
void SetRemote(Ipv6Address ipv6)
Set the remote peer.
Definition: ping6.cc:126
NS_LOG_COMPONENT_DEFINE("PacketLossCounter")
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)
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
Definition: time.cc:404
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Definition: packet.cc:381
virtual void DoDispose()
Dispose this object;.
Definition: ping6.cc:94
void SetSeq(uint16_t seq)
Set the sequence number.
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
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:360
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
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:237
static TypeId LookupByName(std::string name)
Definition: type-id.cc:535
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.