A Discrete-Event Network Simulator
API
ping.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Chandrakant Jena
3  * Copyright (c) 2007-2009 Strasbourg University (original Ping6 code)
4  * Copyright (c) 2008 INRIA (original Ping code)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Chandrakant Jena <chandrakant.barcelona@gmail.com>
20  * Tommaso Pecorella <tommaso.pecorella@unifi.it>
21  *
22  * Derived from original v4Ping application (author: Mathieu Lacage)
23  * Derived from original ping6 application (author: Sebastien Vincent)
24  */
25 
26 #include "ping.h"
27 
28 #include "ns3/abort.h"
29 #include "ns3/assert.h"
30 #include "ns3/boolean.h"
31 #include "ns3/enum.h"
32 #include "ns3/icmpv4.h"
33 #include "ns3/icmpv6-header.h"
34 #include "ns3/inet-socket-address.h"
35 #include "ns3/ipv4-address.h"
36 #include "ns3/ipv6-extension-header.h"
37 #include "ns3/ipv6-header.h"
38 #include "ns3/ipv6-l3-protocol.h"
39 #include "ns3/ipv6-packet-info-tag.h"
40 #include "ns3/log.h"
41 #include "ns3/packet.h"
42 #include "ns3/socket.h"
43 #include "ns3/trace-source-accessor.h"
44 #include "ns3/uinteger.h"
45 
46 namespace ns3
47 {
48 
50 
52 
54 constexpr uint16_t PING_ID{0xbeef};
55 
56 TypeId
58 {
59  static TypeId tid =
60  TypeId("ns3::Ping")
62  .SetGroupName("Internet-Apps")
63  .AddConstructor<Ping>()
64  .AddAttribute("Destination",
65  "The unicast IPv4 or IPv6 address of the machine we want to ping",
66  AddressValue(),
67  MakeAddressAccessor(&Ping::m_destination),
68  MakeAddressChecker())
69  .AddAttribute("VerboseMode",
70  "Configure verbose, quiet, or silent output",
71  EnumValue(VerboseMode::VERBOSE),
72  MakeEnumAccessor<VerboseMode>(&Ping::m_verbose),
73  MakeEnumChecker(VerboseMode::VERBOSE,
74  "Verbose",
75  VerboseMode::QUIET,
76  "Quiet",
77  VerboseMode::SILENT,
78  "Silent"))
79  .AddAttribute("Interval",
80  "Time interval between sending each packet",
81  TimeValue(Seconds(1)),
84  .AddAttribute(
85  "Size",
86  "The number of data bytes to be sent, before ICMP and IP headers are added",
87  UintegerValue(56),
89  MakeUintegerChecker<uint32_t>(16))
90  .AddAttribute(
91  "Count",
92  "The maximum number of packets the application will send (zero means no limits)",
93  UintegerValue(0),
95  MakeUintegerChecker<uint32_t>())
96  .AddAttribute("InterfaceAddress",
97  "Local address of the sender",
98  AddressValue(),
99  MakeAddressAccessor(&Ping::m_interfaceAddress),
100  MakeAddressChecker())
101  .AddAttribute("Timeout",
102  "Time to wait for a response if no RTT samples are available",
103  TimeValue(Seconds(1)),
105  MakeTimeChecker())
106  .AddAttribute("Tos",
107  "The Type of Service used to send the ICMP Echo Requests. "
108  "All 8 bits of the TOS byte are set (including ECN bits).",
109  UintegerValue(0),
111  MakeUintegerChecker<uint8_t>())
112  .AddTraceSource("Tx",
113  "The sequence number and ICMP echo response packet.",
115  "ns3::Ping::TxTrace")
116  .AddTraceSource("Rtt",
117  "The sequence number and RTT sample.",
119  "ns3::Ping::RttTrace")
120  .AddTraceSource("Drop",
121  "Drop events due to destination unreachable or other errors.",
123  "ns3::Ping::DropTrace")
124  .AddTraceSource("Report",
125  "Summary report at close of application.",
127  "ns3::Ping::ReportTrace");
128  return tid;
129 }
130 
132 {
133  NS_LOG_FUNCTION(this);
134 }
135 
137 {
138  NS_LOG_FUNCTION(this);
139 }
140 
141 void
143 {
144  NS_LOG_FUNCTION(this);
145  StopApplication();
146  m_socket = nullptr;
148 }
149 
150 uint64_t
152 {
153  NS_LOG_FUNCTION(this);
154 
155  uint64_t appSignature = GetNode()->GetId();
156  appSignature <<= 32;
157 
158  Ptr<Node> node = GetNode();
159  for (uint32_t i = 0; i < node->GetNApplications(); ++i)
160  {
161  if (node->GetApplication(i) == this)
162  {
163  appSignature += i;
164  return appSignature;
165  }
166  }
167  NS_ASSERT_MSG(false, "forgot to add application to node");
168  return 0; // quiet compiler
169 }
170 
171 void
173 {
174  NS_LOG_FUNCTION(this << socket);
175 
176  while (m_socket->GetRxAvailable() > 0)
177  {
178  Address from;
179  Ptr<Packet> packet = m_socket->RecvFrom(from);
180  uint32_t recvSize = packet->GetSize();
181  NS_LOG_DEBUG("recv " << recvSize << " bytes " << *packet);
182 
184  {
186  Ipv4Header ipv4Hdr;
187  packet->RemoveHeader(ipv4Hdr);
188  recvSize -= ipv4Hdr.GetSerializedSize();
189  Icmpv4Header icmp;
190  packet->RemoveHeader(icmp);
191 
192  switch (icmp.GetType())
193  {
195  Icmpv4Echo echo;
196  packet->RemoveHeader(echo);
197 
198  if (echo.GetIdentifier() != PING_ID)
199  {
200  return;
201  }
202 
203  NS_LOG_INFO("Received Echo Reply size = "
204  << std::dec << recvSize << " bytes from " << realFrom.GetIpv4()
205  << " id = " << echo.GetIdentifier()
206  << " seq = " << echo.GetSequenceNumber()
207  << " TTL = " << static_cast<uint16_t>(ipv4Hdr.GetTtl()));
208 
209  uint32_t dataSize = echo.GetDataSize();
210  if (dataSize < 8)
211  {
212  NS_LOG_INFO("Packet too short, discarding");
213  return;
214  }
215  auto buf = new uint8_t[dataSize];
216  echo.GetData(buf);
217  uint64_t appSignature = Read64(buf);
218  delete[] buf;
219 
220  if (appSignature == m_appSignature)
221  {
222  Time sendTime = m_sent.at(echo.GetSequenceNumber()).txTime;
223  NS_ASSERT(Simulator::Now() >= sendTime);
224  Time delta = Simulator::Now() - sendTime;
225 
226  bool dupReply = false;
227  if (m_sent.at(echo.GetSequenceNumber()).acked)
228  {
229  m_duplicate++;
230  dupReply = true;
231  }
232  else
233  {
234  m_recv++;
235  m_sent.at(echo.GetSequenceNumber()).acked = true;
236  }
237 
238  m_avgRtt.Update(delta.GetMilliSeconds());
240 
241  if (m_verbose == VerboseMode::VERBOSE)
242  {
243  std::cout << recvSize << " bytes from " << realFrom.GetIpv4() << ":"
244  << " icmp_seq=" << echo.GetSequenceNumber()
245  << " ttl=" << static_cast<uint16_t>(ipv4Hdr.GetTtl())
246  << " time=" << delta.GetMicroSeconds() / 1000.0 << " ms";
247  if (dupReply && !m_multipleDestinations)
248  {
249  std::cout << " (DUP!)";
250  }
251  std::cout << "\n";
252  }
253  }
254 
255  break;
256  }
258  Icmpv4DestinationUnreachable destUnreach;
259  packet->RemoveHeader(destUnreach);
260 
261  NS_LOG_INFO("Received Destination Unreachable from " << realFrom.GetIpv4());
262  break;
263  }
265  Icmpv4TimeExceeded timeExceeded;
266  packet->RemoveHeader(timeExceeded);
267 
268  NS_LOG_INFO("Received Time Exceeded from " << realFrom.GetIpv4());
269  break;
270  }
271  default:
272  break;
273  }
274  }
275  else if (Inet6SocketAddress::IsMatchingType(from))
276  {
278  Ipv6Header ipv6Hdr;
279 
280  // We need the IP interface index.
281  Ipv6PacketInfoTag infoTag;
282  packet->RemovePacketTag(infoTag);
284  Ipv6Address myAddr = infoTag.GetAddress();
285  int32_t ipIfIndex = ipv6->GetInterfaceForAddress(myAddr);
286 
287  packet->RemoveHeader(ipv6Hdr);
288  recvSize -= ipv6Hdr.GetSerializedSize();
289  uint8_t type;
290  packet->CopyData(&type, sizeof(type));
291 
292  switch (type)
293  {
295  Icmpv6Echo echo(false);
296  packet->RemoveHeader(echo);
297 
298  if (echo.GetId() != PING_ID)
299  {
300  return;
301  }
302 
303  NS_LOG_INFO("Received Echo Reply size = "
304  << std::dec << recvSize << " bytes from " << realFrom.GetIpv6()
305  << " id = " << echo.GetId() << " seq = " << echo.GetSeq()
306  << " Hop Count = " << static_cast<uint16_t>(ipv6Hdr.GetHopLimit()));
307 
308  uint32_t dataSize = packet->GetSize();
309  if (dataSize < 8)
310  {
311  NS_LOG_INFO("Packet too short, discarding");
312  return;
313  }
314  auto buf = new uint8_t[dataSize];
315  packet->CopyData(buf, dataSize);
316  uint64_t appSignature = Read64(buf);
317  delete[] buf;
318 
319  if (appSignature == m_appSignature)
320  {
321  Time sendTime = m_sent.at(echo.GetSeq()).txTime;
322  NS_ASSERT(Simulator::Now() >= sendTime);
323  Time delta = Simulator::Now() - sendTime;
324 
325  bool dupReply = false;
326  if (m_sent.at(echo.GetSeq()).acked)
327  {
328  m_duplicate++;
329  dupReply = true;
330  }
331  else
332  {
333  m_recv++;
334  m_sent.at(echo.GetSeq()).acked = true;
335  }
336 
337  m_avgRtt.Update(delta.GetMilliSeconds());
338  m_rttTrace(echo.GetSeq(), delta);
339 
340  if (m_verbose == VerboseMode::VERBOSE)
341  {
342  std::cout << recvSize << " bytes from (" << realFrom.GetIpv6() << "):"
343  << " icmp_seq=" << echo.GetSeq()
344  << " ttl=" << static_cast<uint16_t>(ipv6Hdr.GetHopLimit())
345  << " time=" << delta.GetMicroSeconds() / 1000.0 << " ms";
346  if (dupReply)
347  {
348  std::cout << " (DUP!)";
349  }
350  std::cout << "\n";
351  }
352  }
353  ipv6->ReachabilityHint(ipIfIndex, realFrom.GetIpv6());
354  break;
355  }
357  Icmpv6DestinationUnreachable destUnreach;
358  packet->RemoveHeader(destUnreach);
359 
360  NS_LOG_INFO("Received Destination Unreachable from " << realFrom.GetIpv6());
361  break;
362  }
364  Icmpv6TimeExceeded timeExceeded;
365  packet->RemoveHeader(timeExceeded);
366 
367  NS_LOG_INFO("Received Time Exceeded from " << realFrom.GetIpv6());
368  break;
369  }
370  default:
371  break;
372  }
373  }
374  }
375 
376  if (!m_multipleDestinations && m_count > 0 && m_recv == m_count)
377  {
379  }
380 }
381 
382 // Writes data to buffer in little-endian format; least significant byte
383 // of data is at lowest buffer address
384 void
385 Ping::Write64(uint8_t* buffer, const uint64_t data)
386 {
387  NS_LOG_FUNCTION(this << (void*)buffer << data);
388  buffer[0] = (data >> 0) & 0xff;
389  buffer[1] = (data >> 8) & 0xff;
390  buffer[2] = (data >> 16) & 0xff;
391  buffer[3] = (data >> 24) & 0xff;
392  buffer[4] = (data >> 32) & 0xff;
393  buffer[5] = (data >> 40) & 0xff;
394  buffer[6] = (data >> 48) & 0xff;
395  buffer[7] = (data >> 56) & 0xff;
396 }
397 
398 // Read data from a little-endian formatted buffer to data
399 uint64_t
400 Ping::Read64(const uint8_t* buffer)
401 {
402  NS_LOG_FUNCTION(this << (void*)buffer);
403  uint64_t data = buffer[7];
404  data <<= 8;
405  data |= buffer[6];
406  data <<= 8;
407  data |= buffer[5];
408  data <<= 8;
409  data |= buffer[4];
410  data <<= 8;
411  data |= buffer[3];
412  data <<= 8;
413  data |= buffer[2];
414  data <<= 8;
415  data |= buffer[1];
416  data <<= 8;
417  data |= buffer[0];
418 
419  return data;
420 }
421 
422 void
424 {
425  NS_LOG_FUNCTION(this);
426 
427  NS_LOG_INFO("m_seq=" << m_seq);
428 
429  // Prepare the payload.
430  // We must write quantities out in some form of network order. Since there
431  // isn't an htonl to work with we just follow the convention in pcap traces
432  // (where any difference would show up anyway) and borrow that code. Don't
433  // be too surprised when you see that this is a little endian convention.
434  //
435  auto data = new uint8_t[m_size];
436  memset(data, 0, m_size);
437  NS_ASSERT_MSG(m_size >= 16, "ECHO Payload size must be at least 16 bytes");
438 
440  Ptr<Packet> dataPacket = Create<Packet>(data, m_size);
441 
442  Ptr<Packet> p = Create<Packet>();
443  int returnValue = 0;
444 
445  if (!m_useIpv6)
446  {
447  // Using IPv4
448  Icmpv4Echo echo;
449  echo.SetSequenceNumber(m_seq);
450  echo.SetIdentifier(PING_ID);
451 
452  // In the Icmpv4Echo the payload is part of the header.
453  echo.SetData(dataPacket);
454 
455  p->AddHeader(echo);
456  Icmpv4Header header;
458  header.SetCode(0);
459  if (Node::ChecksumEnabled())
460  {
461  header.EnableChecksum();
462  }
463  p->AddHeader(header);
465  dest.SetTos(m_tos);
466  returnValue = m_socket->SendTo(p, 0, dest);
467  }
468  else
469  {
470  // Using IPv6
471  Icmpv6Echo echo(true);
472 
473  echo.SetSeq(m_seq);
474  echo.SetId(PING_ID);
475 
476  // In the Icmpv6Echo the payload is just the content of the packet.
477  p = dataPacket->Copy();
478 
479  p->AddHeader(echo);
480 
481  /* use Loose Routing (routing type 0) */
482  if (!m_routers.empty())
483  {
484  Ipv6ExtensionLooseRoutingHeader routingHeader;
485  routingHeader.SetNextHeader(Ipv6Header::IPV6_ICMPV6);
486  routingHeader.SetTypeRouting(0);
487  routingHeader.SetSegmentsLeft(m_routers.size());
488  routingHeader.SetRoutersAddress(m_routers);
489  p->AddHeader(routingHeader);
491  }
492 
493  returnValue =
495 
496  // Loose routing could have changed (temporarily) the protocol. Set it again to receive the
497  // replies.
499  }
500  if (returnValue > 0)
501  {
502  m_sent.emplace_back(Simulator::Now(), false);
503  m_txTrace(m_seq, p);
504  }
505  else
506  {
507  NS_LOG_INFO("Send failure; socket return value: " << returnValue);
508  }
509  m_seq++;
510  delete[] data;
511 
512  if (m_count == 0 || m_seq < m_count)
513  {
515  }
516 
517  // We have sent all the requests. Schedule a shutdown after the linger time
518  if (m_count > 0 && m_seq == m_count)
519  {
520  Time lingerTime = m_avgRtt.Count() > 0 ? MilliSeconds(2 * m_avgRtt.Max()) : m_timeout;
521  Simulator::Schedule(lingerTime, &Ping::StopApplication, this);
522  }
523 }
524 
525 void
527 {
528  NS_LOG_FUNCTION(this);
529 
530  if (m_destination.IsInvalid())
531  {
532  NS_ABORT_MSG("Destination Address value must be set when starting application");
533  }
534 
536 
538  m_reportPrinted = false;
539  if (m_verbose == VerboseMode::VERBOSE || m_verbose == VerboseMode::QUIET)
540  {
542  {
544  std::cout << "PING " << realFrom.GetIpv4() << " - " << m_size << " bytes of data; "
545  << m_size + 28 << " bytes including ICMP and IPv4 headers.\n";
546  }
548  {
550  std::cout << "PING " << realFrom.GetIpv6() << " - " << m_size << " bytes of data; "
551  << m_size + 48 << " bytes including ICMP and IPv6 headers.\n";
552  }
553  else
554  {
555  NS_ABORT_MSG("Invalid Address");
556  }
557  }
558 
560  {
561  m_socket =
562  Socket::CreateSocket(GetNode(), TypeId::LookupByName("ns3::Ipv4RawSocketFactory"));
563  NS_ASSERT_MSG(m_socket, "Ping::StartApplication: can not create socket.");
564  m_socket->SetAttribute("Protocol", UintegerValue(1)); // icmp
566  m_useIpv6 = false;
567 
570  }
572  {
573  m_socket =
574  Socket::CreateSocket(GetNode(), TypeId::LookupByName("ns3::Ipv6RawSocketFactory"));
575  NS_ASSERT_MSG(m_socket, "Ping::StartApplication: can not create socket.");
578  m_socket->SetRecvPktInfo(true);
579  m_useIpv6 = true;
580 
583  }
584  else
585  {
586  NS_ABORT_MSG("Destination Address value must be of type Ipv4 or Ipv6");
587  }
588 
590  {
592  {
594  int status = m_socket->Bind(senderInet);
595  NS_ASSERT_MSG(status == 0, "Failed to bind IPv4 socket");
596  }
598  {
599  Inet6SocketAddress senderInet =
601  int status = m_socket->Bind(senderInet);
602  NS_ASSERT_MSG(status == 0, "Failed to bind IPv6 socket");
603  }
604  else
605  {
606  NS_ABORT_MSG("Sender Address value must be of type Ipv4 or Ipv6");
607  }
608  }
609 
610  // Guess how large should be the data storage and pre-book it.
611  if (m_count == 0)
612  {
613  Time delta = m_stopTime - Now();
614  int64_t guessedTx = Div(delta, m_interval) + 1;
615  m_sent.reserve(guessedTx);
616  }
617  else
618  {
619  m_sent.reserve(m_count);
620  }
621 
622  Send();
623 }
624 
625 void
627 {
628  NS_LOG_FUNCTION(this);
629  if (m_stopEvent.IsRunning())
630  {
632  }
633  if (m_next.IsRunning())
634  {
635  m_next.Cancel();
636  }
637  if (m_socket)
638  {
639  m_socket->Close();
640  }
641  PrintReport();
642 }
643 
644 void
646 {
647  if (m_reportPrinted)
648  {
649  return;
650  }
651  m_reportPrinted = true;
652 
653  if (m_verbose == VerboseMode::VERBOSE || m_verbose == VerboseMode::QUIET)
654  {
655  std::ostringstream os;
656  os.precision(4);
658  {
660  os << "\n--- " << realFrom.GetIpv4() << " ping statistics ---\n";
661  }
663  {
665  os << "\n--- " << realFrom.GetIpv6() << " ping statistics ---\n";
666  }
667  os << m_seq << " packets transmitted, " << m_recv << " received, ";
668  if (m_duplicate)
669  {
670  os << m_duplicate << " duplicates, ";
671  }
672 
673  // note: integer math to match Linux implementation and avoid turning a 99.9% into a 100%.
674  os << ((m_seq - m_recv) * 100 / m_seq) << "% packet loss, "
675  << "time " << (Simulator::Now() - m_started).GetMilliSeconds() << "ms\n";
676 
677  if (m_avgRtt.Count() > 0)
678  {
679  os << "rtt min/avg/max/mdev = " << m_avgRtt.Min() << "/" << m_avgRtt.Avg() << "/"
680  << m_avgRtt.Max() << "/" << m_avgRtt.Stddev() << " ms\n";
681  }
682  std::cout << os.str();
683  }
684  PingReport report;
685  report.m_transmitted = m_seq;
686  report.m_received = m_recv;
687  // note: integer math to match Linux implementation and avoid turning a 99.9% into a 100%.
688  report.m_loss = (m_seq - m_recv) * 100 / m_seq;
689  report.m_duration = (Simulator::Now() - m_started);
690  report.m_rttMin = m_avgRtt.Min();
691  report.m_rttAvg = m_avgRtt.Avg();
692  report.m_rttMax = m_avgRtt.Max();
693  report.m_rttMdev = m_avgRtt.Stddev();
694  m_reportTrace(report);
695 }
696 
697 void
698 Ping::SetRouters(const std::vector<Ipv6Address>& routers)
699 {
700  m_routers = routers;
701 }
702 
703 } // namespace ns3
a polymophic address class
Definition: address.h:101
bool IsInvalid() const
Definition: address.cc:71
The base class for all ns3 applications.
Definition: application.h:62
void DoDispose() override
Destructor implementation.
Definition: application.cc:86
Time m_stopTime
The simulation time that the application will end.
Definition: application.h:151
EventId m_stopEvent
The event that will fire at m_stopTime to end the application.
Definition: application.h:153
Ptr< Node > GetNode() const
Definition: application.cc:108
Ptr< Node > m_node
The node that this application is installed on.
Definition: application.h:149
double Avg() const
Sample average.
Definition: average.h:108
T Min() const
Sample minimum.
Definition: average.h:90
T Max() const
Sample maximum.
Definition: average.h:99
void Update(const T &x)
Add new sample.
Definition: average.h:56
uint32_t Count() const
Sample size.
Definition: average.h:81
double Stddev() const
Sample standard deviation.
Definition: average.h:135
Hold variables of type enum.
Definition: enum.h:62
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
ICMP Destination Unreachable header.
Definition: icmpv4.h:175
ICMP Echo header.
Definition: icmpv4.h:110
uint32_t GetData(uint8_t payload[]) const
Get the Echo data.
Definition: icmpv4.cc:207
void SetIdentifier(uint16_t id)
Set the Echo identifier.
Definition: icmpv4.cc:150
void SetData(Ptr< const Packet > data)
Set the Echo data.
Definition: icmpv4.cc:164
uint16_t GetIdentifier() const
Get the Echo identifier.
Definition: icmpv4.cc:186
void SetSequenceNumber(uint16_t seq)
Set the Echo sequence number.
Definition: icmpv4.cc:157
uint32_t GetDataSize() const
Get the Echo data size.
Definition: icmpv4.cc:200
uint16_t GetSequenceNumber() const
Get the Echo sequence number.
Definition: icmpv4.cc:193
Base class for all the ICMP packet headers.
Definition: icmpv4.h:43
@ ICMPV4_TIME_EXCEEDED
Definition: icmpv4.h:53
@ ICMPV4_DEST_UNREACH
Definition: icmpv4.h:51
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:123
void SetType(uint8_t type)
Set ICMP type.
Definition: icmpv4.cc:116
void EnableChecksum()
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:60
uint8_t GetType() const
Get ICMP type.
Definition: icmpv4.cc:130
ICMP Time Exceeded header.
Definition: icmpv4.h:250
ICMPv6 Error Destination Unreachable header.
ICMPv6 Echo message.
void SetId(uint16_t id)
Set the ID of the packet.
uint16_t GetId() const
Get the ID of the packet.
void SetSeq(uint16_t seq)
Set the sequence number.
uint16_t GetSeq() const
Get the sequence number.
@ ICMPV6_ERROR_DESTINATION_UNREACHABLE
Definition: icmpv6-header.h:45
ICMPv6 Error Time Exceeded header.
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
bool IsMulticast() const
static Ipv4Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
bool IsBroadcast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
uint32_t GetSerializedSize() const override
Definition: ipv4-header.cc:384
uint8_t GetTtl() const
Definition: ipv4-header.cc:274
Describes an IPv6 address.
Definition: ipv6-address.h:49
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
void SetTypeRouting(uint8_t typeRouting)
Set the "Type of Routing" field.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.
Packet header for IPv6.
Definition: ipv6-header.h:35
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:100
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: ipv6-header.cc:159
IPv6 layer implementation.
This class implements a tag that carries socket ancillary data to the socket interface.
Ipv6Address GetAddress() const
Get the tag's address.
uint32_t GetNApplications() const
Definition: node.cc:190
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:180
uint32_t GetId() const
Definition: node.cc:117
static bool ChecksumEnabled()
Definition: node.cc:285
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
This application behaves similarly to the Unix ping application, although with fewer options supporte...
Definition: ping.h:56
uint32_t m_size
Specifies the number of data bytes to be sent.
Definition: ping.h:213
uint32_t m_recv
Received packets counter.
Definition: ping.h:231
Time m_started
Start time to report total ping time.
Definition: ping.h:235
bool m_reportPrinted
True if the report has been printed already.
Definition: ping.h:270
std::vector< EchoRequestData > m_sent
All sent but not answered packets. Map icmp seqno -> when sent, acked at least once.
Definition: ping.h:263
uint64_t Read64(const uint8_t *buffer)
Writes data from a little-endian formatted buffer to data.
Definition: ping.cc:400
bool m_useIpv6
Use IPv4 (false) or IPv6 (true)
Definition: ping.h:272
void SetRouters(const std::vector< Ipv6Address > &routers)
Set routers for IPv6 routing type 0 (loose routing).
Definition: ping.cc:698
std::vector< Ipv6Address > m_routers
Routers addresses for IPv6 routing type 0.
Definition: ping.h:277
~Ping() override
Destructor.
Definition: ping.cc:136
TracedCallback< uint16_t, Ptr< Packet > > m_txTrace
Callbacks for tracing the packet Tx events.
Definition: ping.h:221
uint64_t m_appSignature
App signature: ID of the node where the app is installed || ID of the Application.
Definition: ping.h:280
uint32_t m_count
Number of packets to be sent.
Definition: ping.h:265
uint64_t GetApplicationSignature() const
Return the application signatiure.
Definition: ping.cc:151
void Send()
Send one Ping (ICMPv4 ECHO or ICMPv6 ECHO) to the destination.
Definition: ping.cc:423
void DoDispose() override
Destructor implementation.
Definition: ping.cc:142
void StartApplication() override
Application specific startup code.
Definition: ping.cc:526
TracedCallback< const PingReport & > m_reportTrace
TracedCallback for final ping report.
Definition: ping.h:227
void StopApplication() override
Application specific shutdown code.
Definition: ping.cc:626
Average< double > m_avgRtt
Average rtt is ms.
Definition: ping.h:237
void PrintReport()
Print the report.
Definition: ping.cc:645
Ping()
Constructor.
Definition: ping.cc:131
Time m_interval
Wait interval between ECHO requests.
Definition: ping.h:206
static TypeId GetTypeId()
Get the type ID.
Definition: ping.cc:57
bool m_multipleDestinations
Destination is Broadcast or Multicast.
Definition: ping.h:274
uint16_t m_seq
ICMP ECHO sequence number.
Definition: ping.h:219
uint32_t m_duplicate
Duplicate packets counter.
Definition: ping.h:233
Address m_interfaceAddress
Sender Local Address.
Definition: ping.h:202
void Receive(Ptr< Socket > socket)
Receive an ICMPv4 or an ICMPv6 Echo reply.
Definition: ping.cc:172
uint8_t m_tos
The Type of Service carried by ICMP ECHOs.
Definition: ping.h:217
void Write64(uint8_t *buffer, const uint64_t data)
Writes data to buffer in little-endian format.
Definition: ping.cc:385
Address m_destination
Remote address.
Definition: ping.h:204
EventId m_next
Next packet will be sent.
Definition: ping.h:239
Ptr< Socket > m_socket
The socket we send packets from.
Definition: ping.h:215
VerboseMode m_verbose
Variable to stor verbose mode.
Definition: ping.h:229
TracedCallback< uint16_t, DropReason > m_dropTrace
TracedCallback for drop events.
Definition: ping.h:225
Time m_timeout
Time to wait for a response, in seconds.
Definition: ping.h:268
TracedCallback< uint16_t, Time > m_rttTrace
TracedCallback for RTT samples.
Definition: ping.h:223
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:354
virtual uint32_t GetRxAvailable() const =0
Return number of bytes which can be returned from one or multiple calls to Recv.
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
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:72
virtual int Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
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.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
Definition: length.cc:482
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
constexpr uint16_t PING_ID
This value is used to quickly identify ECHO packets generated by this app.
Definition: ping.cc:54
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:194
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
uint8_t data[writeSize]
A ping report provides all of the data that is typically output to the terminal when the application ...
Definition: ping.h:92
Time m_duration
Duration of the application.
Definition: ping.h:96
uint16_t m_loss
Percentage of lost packets (decimal value 0-100)
Definition: ping.h:95
double m_rttAvg
rtt avg value
Definition: ping.h:98
double m_rttMdev
rtt mdev value
Definition: ping.h:100
uint32_t m_received
Number of echo replies received.
Definition: ping.h:94
double m_rttMin
rtt min value
Definition: ping.h:97
uint32_t m_transmitted
Number of echo requests sent.
Definition: ping.h:93
double m_rttMax
rtt max value
Definition: ping.h:99