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
46namespace ns3
47{
48
50
52
54constexpr uint16_t PING_ID{0xbeef};
55
56TypeId
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",
67 MakeAddressAccessor(&Ping::m_destination),
68 MakeAddressChecker())
69 .AddAttribute("VerboseMode",
70 "Configure verbose, quiet, or silent output",
71 EnumValue(VerboseMode::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",
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)",
95 MakeUintegerChecker<uint32_t>())
96 .AddAttribute("InterfaceAddress",
97 "Local address of the sender",
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)),
106 .AddTraceSource("Tx",
107 "The sequence number and ICMP echo response packet.",
109 "ns3::Ping::TxTrace")
110 .AddTraceSource("Rtt",
111 "The sequence number and RTT sample.",
113 "ns3::Ping::RttTrace")
114 .AddTraceSource("Drop",
115 "Drop events due to destination unreachable or other errors.",
117 "ns3::Ping::DropTrace")
118 .AddTraceSource("Report",
119 "Summary report at close of application.",
121 "ns3::Ping::ReportTrace");
122 return tid;
123}
124
126{
127 NS_LOG_FUNCTION(this);
128}
129
131{
132 NS_LOG_FUNCTION(this);
133}
134
135void
137{
138 NS_LOG_FUNCTION(this);
140 m_socket = nullptr;
142}
143
144uint64_t
146{
147 NS_LOG_FUNCTION(this);
148
149 uint64_t appSignature = GetNode()->GetId();
150 appSignature <<= 32;
151
152 Ptr<Node> node = GetNode();
153 for (uint32_t i = 0; i < node->GetNApplications(); ++i)
154 {
155 if (node->GetApplication(i) == this)
156 {
157 appSignature += i;
158 return appSignature;
159 }
160 }
161 NS_ASSERT_MSG(false, "forgot to add application to node");
162 return 0; // quiet compiler
163}
164
165void
167{
168 NS_LOG_FUNCTION(this << socket);
169
170 while (m_socket->GetRxAvailable() > 0)
171 {
172 Address from;
173 Ptr<Packet> packet = m_socket->RecvFrom(from);
174 uint32_t recvSize = packet->GetSize();
175 NS_LOG_DEBUG("recv " << recvSize << " bytes " << *packet);
176
178 {
180 Ipv4Header ipv4Hdr;
181 packet->RemoveHeader(ipv4Hdr);
182 recvSize -= ipv4Hdr.GetSerializedSize();
183 Icmpv4Header icmp;
184 packet->RemoveHeader(icmp);
185
186 switch (icmp.GetType())
187 {
189 Icmpv4Echo echo;
190 packet->RemoveHeader(echo);
191
192 if (echo.GetIdentifier() != PING_ID)
193 {
194 return;
195 }
196
197 NS_LOG_INFO("Received Echo Reply size = "
198 << std::dec << recvSize << " bytes from " << realFrom.GetIpv4()
199 << " id = " << echo.GetIdentifier()
200 << " seq = " << echo.GetSequenceNumber()
201 << " TTL = " << static_cast<uint16_t>(ipv4Hdr.GetTtl()));
202
203 uint32_t dataSize = echo.GetDataSize();
204 if (dataSize < 8)
205 {
206 NS_LOG_INFO("Packet too short, discarding");
207 return;
208 }
209 uint8_t* buf = new uint8_t[dataSize];
210 echo.GetData(buf);
211 uint64_t appSignature = Read64(buf);
212 delete[] buf;
213
214 if (appSignature == m_appSignature)
215 {
216 Time sendTime = m_sent.at(echo.GetSequenceNumber()).txTime;
217 NS_ASSERT(Simulator::Now() >= sendTime);
218 Time delta = Simulator::Now() - sendTime;
219
220 bool dupReply = false;
221 if (m_sent.at(echo.GetSequenceNumber()).acked)
222 {
223 m_duplicate++;
224 dupReply = true;
225 }
226 else
227 {
228 m_recv++;
229 m_sent.at(echo.GetSequenceNumber()).acked = true;
230 }
231
232 m_avgRtt.Update(delta.GetMilliSeconds());
234
235 if (m_verbose == VerboseMode::VERBOSE)
236 {
237 std::cout << recvSize << " bytes from " << realFrom.GetIpv4() << ":"
238 << " icmp_seq=" << echo.GetSequenceNumber()
239 << " ttl=" << static_cast<uint16_t>(ipv4Hdr.GetTtl())
240 << " time=" << delta.GetMicroSeconds() / 1000.0 << " ms";
241 if (dupReply && !m_multipleDestinations)
242 {
243 std::cout << " (DUP!)";
244 }
245 std::cout << "\n";
246 }
247 }
248
249 break;
250 }
253 packet->RemoveHeader(destUnreach);
254
255 NS_LOG_INFO("Received Destination Unreachable from " << realFrom.GetIpv4());
256 break;
257 }
259 Icmpv4TimeExceeded timeExceeded;
260 packet->RemoveHeader(timeExceeded);
261
262 NS_LOG_INFO("Received Time Exceeded from " << realFrom.GetIpv4());
263 break;
264 }
265 default:
266 break;
267 }
268 }
270 {
272 Ipv6Header ipv6Hdr;
273
274 // We need the IP interface index.
275 Ipv6PacketInfoTag infoTag;
276 packet->RemovePacketTag(infoTag);
278 Ipv6Address myAddr = infoTag.GetAddress();
279 int32_t ipIfIndex = ipv6->GetInterfaceForAddress(myAddr);
280
281 packet->RemoveHeader(ipv6Hdr);
282 recvSize -= ipv6Hdr.GetSerializedSize();
283 uint8_t type;
284 packet->CopyData(&type, sizeof(type));
285
286 switch (type)
287 {
289 Icmpv6Echo echo(0);
290 packet->RemoveHeader(echo);
291
292 if (echo.GetId() != PING_ID)
293 {
294 return;
295 }
296
297 NS_LOG_INFO("Received Echo Reply size = "
298 << std::dec << recvSize << " bytes from " << realFrom.GetIpv6()
299 << " id = " << echo.GetId() << " seq = " << echo.GetSeq()
300 << " Hop Count = " << static_cast<uint16_t>(ipv6Hdr.GetHopLimit()));
301
302 uint32_t dataSize = packet->GetSize();
303 if (dataSize < 8)
304 {
305 NS_LOG_INFO("Packet too short, discarding");
306 return;
307 }
308 uint8_t* buf = new uint8_t[dataSize];
309 packet->CopyData(buf, dataSize);
310 uint64_t appSignature = Read64(buf);
311 delete[] buf;
312
313 if (appSignature == m_appSignature)
314 {
315 Time sendTime = m_sent.at(echo.GetSeq()).txTime;
316 NS_ASSERT(Simulator::Now() >= sendTime);
317 Time delta = Simulator::Now() - sendTime;
318
319 bool dupReply = false;
320 if (m_sent.at(echo.GetSeq()).acked)
321 {
322 m_duplicate++;
323 dupReply = true;
324 }
325 else
326 {
327 m_recv++;
328 m_sent.at(echo.GetSeq()).acked = true;
329 }
330
331 m_avgRtt.Update(delta.GetMilliSeconds());
332 m_rttTrace(echo.GetSeq(), delta);
333
334 if (m_verbose == VerboseMode::VERBOSE)
335 {
336 std::cout << recvSize << " bytes from (" << realFrom.GetIpv6() << "):"
337 << " icmp_seq=" << echo.GetSeq()
338 << " ttl=" << static_cast<uint16_t>(ipv6Hdr.GetHopLimit())
339 << " time=" << delta.GetMicroSeconds() / 1000.0 << " ms";
340 if (dupReply)
341 {
342 std::cout << " (DUP!)";
343 }
344 std::cout << "\n";
345 }
346 }
347 ipv6->ReachabilityHint(ipIfIndex, realFrom.GetIpv6());
348 break;
349 }
352 packet->RemoveHeader(destUnreach);
353
354 NS_LOG_INFO("Received Destination Unreachable from " << realFrom.GetIpv6());
355 break;
356 }
358 Icmpv6TimeExceeded timeExceeded;
359 packet->RemoveHeader(timeExceeded);
360
361 NS_LOG_INFO("Received Time Exceeded from " << realFrom.GetIpv6());
362 break;
363 }
364 default:
365 break;
366 }
367 }
368 }
369
371 {
373 }
374}
375
376// Writes data to buffer in little-endian format; least significant byte
377// of data is at lowest buffer address
378void
379Ping::Write64(uint8_t* buffer, const uint64_t data)
380{
381 NS_LOG_FUNCTION(this << (void*)buffer << data);
382 buffer[0] = (data >> 0) & 0xff;
383 buffer[1] = (data >> 8) & 0xff;
384 buffer[2] = (data >> 16) & 0xff;
385 buffer[3] = (data >> 24) & 0xff;
386 buffer[4] = (data >> 32) & 0xff;
387 buffer[5] = (data >> 40) & 0xff;
388 buffer[6] = (data >> 48) & 0xff;
389 buffer[7] = (data >> 56) & 0xff;
390}
391
392// Read data from a little-endian formatted buffer to data
393uint64_t
394Ping::Read64(const uint8_t* buffer)
395{
396 NS_LOG_FUNCTION(this << (void*)buffer);
397 uint64_t data = buffer[7];
398 data <<= 8;
399 data |= buffer[6];
400 data <<= 8;
401 data |= buffer[5];
402 data <<= 8;
403 data |= buffer[4];
404 data <<= 8;
405 data |= buffer[3];
406 data <<= 8;
407 data |= buffer[2];
408 data <<= 8;
409 data |= buffer[1];
410 data <<= 8;
411 data |= buffer[0];
412
413 return data;
414}
415
416void
418{
419 NS_LOG_FUNCTION(this);
420
421 NS_LOG_INFO("m_seq=" << m_seq);
422
423 // Prepare the payload.
424 // We must write quantities out in some form of network order. Since there
425 // isn't an htonl to work with we just follow the convention in pcap traces
426 // (where any difference would show up anyway) and borrow that code. Don't
427 // be too surprised when you see that this is a little endian convention.
428 //
429 uint8_t* data = new uint8_t[m_size];
430 memset(data, 0, m_size);
431 NS_ASSERT_MSG(m_size >= 16, "ECHO Payload size must be at least 16 bytes");
432
434 Ptr<Packet> dataPacket = Create<Packet>(data, m_size);
435
436 Ptr<Packet> p = Create<Packet>();
437 int returnValue = 0;
438
439 if (!m_useIpv6)
440 {
441 // Using IPv4
442 Icmpv4Echo echo;
445
446 // In the Icmpv4Echo the payload is part of the header.
447 echo.SetData(dataPacket);
448
449 p->AddHeader(echo);
450 Icmpv4Header header;
452 header.SetCode(0);
454 {
455 header.EnableChecksum();
456 }
457 p->AddHeader(header);
458 returnValue =
460 }
461 else
462 {
463 // Using IPv6
464 Icmpv6Echo echo(true);
465
466 echo.SetSeq(m_seq);
467 echo.SetId(PING_ID);
468
469 // In the Icmpv6Echo the payload is just the content of the packet.
470 p = dataPacket->Copy();
471
472 p->AddHeader(echo);
473
474 /* use Loose Routing (routing type 0) */
475 if (!m_routers.empty())
476 {
479 routingHeader.SetTypeRouting(0);
480 routingHeader.SetSegmentsLeft(m_routers.size());
481 routingHeader.SetRoutersAddress(m_routers);
482 p->AddHeader(routingHeader);
484 }
485
486 returnValue =
488
489 // Loose routing could have changed (temporarily) the protocol. Set it again to receive the
490 // replies.
492 }
493 if (returnValue > 0)
494 {
495 m_sent.emplace_back(Simulator::Now(), false);
496 m_txTrace(m_seq, p);
497 }
498 else
499 {
500 NS_LOG_INFO("Send failure; socket return value: " << returnValue);
501 }
502 m_seq++;
503 delete[] data;
504
505 if (m_count == 0 || m_seq < m_count)
506 {
508 }
509
510 // We have sent all the requests. Schedule a shutdown after the linger time
511 if (m_count > 0 && m_seq == m_count)
512 {
513 Time lingerTime = m_avgRtt.Count() > 0 ? MilliSeconds(2 * m_avgRtt.Max()) : m_timeout;
514 Simulator::Schedule(lingerTime, &Ping::StopApplication, this);
515 }
516}
517
518void
520{
521 NS_LOG_FUNCTION(this);
522
524 {
525 NS_ABORT_MSG("Destination Address value must be set when starting application");
526 }
527
529
531 m_reportPrinted = false;
532 if (m_verbose == VerboseMode::VERBOSE || m_verbose == VerboseMode::QUIET)
533 {
535 {
537 std::cout << "PING " << realFrom.GetIpv4() << " - " << m_size << " bytes of data; "
538 << m_size + 28 << " bytes including ICMP and IPv4 headers.\n";
539 }
541 {
543 std::cout << "PING " << realFrom.GetIpv6() << " - " << m_size << " bytes of data; "
544 << m_size + 48 << " bytes including ICMP and IPv6 headers.\n";
545 }
546 else
547 {
548 NS_ABORT_MSG("Invalid Address");
549 }
550 }
551
553 {
554 m_socket =
555 Socket::CreateSocket(GetNode(), TypeId::LookupByName("ns3::Ipv4RawSocketFactory"));
556 NS_ASSERT_MSG(m_socket, "Ping::StartApplication: can not create socket.");
557 m_socket->SetAttribute("Protocol", UintegerValue(1)); // icmp
559 m_useIpv6 = false;
560
563 }
565 {
566 m_socket =
567 Socket::CreateSocket(GetNode(), TypeId::LookupByName("ns3::Ipv6RawSocketFactory"));
568 NS_ASSERT_MSG(m_socket, "Ping::StartApplication: can not create socket.");
572 m_useIpv6 = true;
573
576 }
577 else
578 {
579 NS_ABORT_MSG("Destination Address value must be of type Ipv4 or Ipv6");
580 }
581
583 {
585 {
586 InetSocketAddress senderInet =
588 int status = m_socket->Bind(senderInet);
589 NS_ASSERT_MSG(status == 0, "Failed to bind IPv4 socket");
590 }
592 {
593 Inet6SocketAddress senderInet =
595 int status = m_socket->Bind(senderInet);
596 NS_ASSERT_MSG(status == 0, "Failed to bind IPv6 socket");
597 }
598 else
599 {
600 NS_ABORT_MSG("Sender Address value must be of type Ipv4 or Ipv6");
601 }
602 }
603
604 // Guess how large should be the data storage and pre-book it.
605 if (m_count == 0)
606 {
607 Time delta = m_stopTime - Now();
608 int64_t guessedTx = Div(delta, m_interval) + 1;
609 m_sent.reserve(guessedTx);
610 }
611 else
612 {
613 m_sent.reserve(m_count);
614 }
615
616 Send();
617}
618
619void
621{
622 NS_LOG_FUNCTION(this);
624 {
626 }
627 if (m_next.IsRunning())
628 {
629 m_next.Cancel();
630 }
631 if (m_socket)
632 {
633 m_socket->Close();
634 }
635 PrintReport();
636}
637
638void
640{
641 if (m_reportPrinted)
642 {
643 return;
644 }
645 m_reportPrinted = true;
646
647 if (m_verbose == VerboseMode::VERBOSE || m_verbose == VerboseMode::QUIET)
648 {
649 std::ostringstream os;
650 os.precision(4);
652 {
654 os << "\n--- " << realFrom.GetIpv4() << " ping statistics ---\n";
655 }
657 {
659 os << "\n--- " << realFrom.GetIpv6() << " ping statistics ---\n";
660 }
661 os << m_seq << " packets transmitted, " << m_recv << " received, ";
662 if (m_duplicate)
663 {
664 os << m_duplicate << " duplicates, ";
665 }
666
667 // note: integer math to match Linux implementation and avoid turning a 99.9% into a 100%.
668 os << ((m_seq - m_recv) * 100 / m_seq) << "% packet loss, "
669 << "time " << (Simulator::Now() - m_started).GetMilliSeconds() << "ms\n";
670
671 if (m_avgRtt.Count() > 0)
672 {
673 os << "rtt min/avg/max/mdev = " << m_avgRtt.Min() << "/" << m_avgRtt.Avg() << "/"
674 << m_avgRtt.Max() << "/" << m_avgRtt.Stddev() << " ms\n";
675 }
676 std::cout << os.str();
677 }
678 PingReport report;
679 report.m_transmitted = m_seq;
680 report.m_received = m_recv;
681 // note: integer math to match Linux implementation and avoid turning a 99.9% into a 100%.
682 report.m_loss = (m_seq - m_recv) * 100 / m_seq;
683 report.m_duration = (Simulator::Now() - m_started);
684 report.m_rttMin = m_avgRtt.Min();
685 report.m_rttAvg = m_avgRtt.Avg();
686 report.m_rttMax = m_avgRtt.Max();
687 report.m_rttMdev = m_avgRtt.Stddev();
688 m_reportTrace(report);
689}
690
691void
692Ping::SetRouters(const std::vector<Ipv6Address>& routers)
693{
694 m_routers = routers;
695}
696
697} // namespace ns3
a polymophic address class
Definition: address.h:100
bool IsInvalid() const
Definition: address.cc:71
AttributeValue implementation for Address.
The base class for all ns3 applications.
Definition: application.h:61
void DoDispose() override
Destructor implementation.
Definition: application.cc:85
Time m_stopTime
The simulation time that the application will end.
Definition: application.h:150
EventId m_stopEvent
The event that will fire at m_stopTime to end the application.
Definition: application.h:152
Ptr< Node > GetNode() const
Definition: application.cc:107
Ptr< Node > m_node
The node that this application is installed on.
Definition: application.h:148
double Avg() const
Sample average.
Definition: average.h:107
T Min() const
Sample minimum.
Definition: average.h:89
T Max() const
Sample maximum.
Definition: average.h:98
void Update(const T &x)
Add new sample.
Definition: average.h:55
uint32_t Count() const
Sample size.
Definition: average.h:80
double Stddev() const
Sample standard deviation.
Definition: average.h:134
Hold variables of type enum.
Definition: enum.h:56
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:174
ICMP Echo header.
Definition: icmpv4.h:109
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:42
@ ICMPV4_TIME_EXCEEDED
Definition: icmpv4.h:52
@ ICMPV4_DEST_UNREACH
Definition: icmpv4.h:50
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:249
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:290
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
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:986
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:862
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:229
Time m_started
Start time to report total ping time.
Definition: ping.h:233
bool m_reportPrinted
True if the report has been printed already.
Definition: ping.h:268
std::vector< EchoRequestData > m_sent
All sent but not answered packets. Map icmp seqno -> when sent, acked at least once.
Definition: ping.h:261
uint64_t Read64(const uint8_t *buffer)
Writes data from a little-endian formatted buffer to data.
Definition: ping.cc:394
bool m_useIpv6
Use IPv4 (false) or IPv6 (true)
Definition: ping.h:270
void SetRouters(const std::vector< Ipv6Address > &routers)
Set routers for IPv6 routing type 0 (loose routing).
Definition: ping.cc:692
std::vector< Ipv6Address > m_routers
Routers addresses for IPv6 routing type 0.
Definition: ping.h:275
~Ping() override
Destructor.
Definition: ping.cc:130
TracedCallback< uint16_t, Ptr< Packet > > m_txTrace
Callbacks for tracing the packet Tx events.
Definition: ping.h:219
uint64_t m_appSignature
App signature: ID of the node where the app is installed || ID of the Application.
Definition: ping.h:278
uint32_t m_count
Number of packets to be sent.
Definition: ping.h:263
uint64_t GetApplicationSignature() const
Return the application signatiure.
Definition: ping.cc:145
void Send()
Send one Ping (ICMPv4 ECHO or ICMPv6 ECHO) to the destination.
Definition: ping.cc:417
void DoDispose() override
Destructor implementation.
Definition: ping.cc:136
void StartApplication() override
Application specific startup code.
Definition: ping.cc:519
void StopApplication() override
Application specific shutdown code.
Definition: ping.cc:620
Average< double > m_avgRtt
Average rtt is ms.
Definition: ping.h:235
void PrintReport()
Print the report.
Definition: ping.cc:639
Ping()
Constructor.
Definition: ping.cc:125
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:272
uint16_t m_seq
ICMP ECHO sequence number.
Definition: ping.h:217
uint32_t m_duplicate
Duplicate packets counter.
Definition: ping.h:231
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:166
void Write64(uint8_t *buffer, const uint64_t data)
Writes data to buffer in little-endian format.
Definition: ping.cc:379
Address m_destination
Remote address.
Definition: ping.h:204
EventId m_next
Next packet will be sent.
Definition: ping.h:237
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:227
TracedCallback< const struct PingReport & > m_reportTrace
TracedCallback for final ping report.
Definition: ping.h:225
TracedCallback< uint16_t, DropReason > m_dropTrace
TracedCallback for drop events.
Definition: ping.h:223
Time m_timeout
Time to wait for a response, in seconds.
Definition: ping.h:266
TracedCallback< uint16_t, Time > m_rttTrace
TracedCallback for RTT samples.
Definition: ping.h:221
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
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.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:352
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:126
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 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
AttributeValue implementation for Time.
Definition: nstime.h:1423
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:839
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:205
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#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:296
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
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.
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:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163
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