A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
53/// This value is used to quickly identify ECHO packets generated by this app.
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",
69 .AddAttribute("VerboseMode",
70 "Configure verbose, quiet, or silent output",
72 MakeEnumAccessor<VerboseMode>(&Ping::m_verbose),
74 "Verbose",
76 "Quiet",
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",
101 .AddAttribute("Timeout",
102 "Time to wait for a response if no RTT samples are available",
103 TimeValue(Seconds(1)),
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
141void
143{
144 NS_LOG_FUNCTION(this);
146 m_socket = nullptr;
148}
149
150uint64_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
171void
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());
239 m_rttTrace(echo.GetSequenceNumber(), delta);
240
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 }
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 }
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
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 }
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
377 {
379 }
380}
381
382// Writes data to buffer in little-endian format; least significant byte
383// of data is at lowest buffer address
384void
385Ping::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
399uint64_t
400Ping::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
422void
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;
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);
460 {
461 header.EnableChecksum();
462 }
463 p->AddHeader(header);
465 returnValue = m_socket->SendTo(p, 0, dest);
466 }
467 else
468 {
469 // Using IPv6
470 Icmpv6Echo echo(true);
471
472 echo.SetSeq(m_seq);
473 echo.SetId(PING_ID);
474
475 // In the Icmpv6Echo the payload is just the content of the packet.
476 p = dataPacket->Copy();
477
478 p->AddHeader(echo);
479
480 /* use Loose Routing (routing type 0) */
481 if (!m_routers.empty())
482 {
485 routingHeader.SetTypeRouting(0);
486 routingHeader.SetSegmentsLeft(m_routers.size());
487 routingHeader.SetRoutersAddress(m_routers);
488 p->AddHeader(routingHeader);
490 }
491
492 returnValue =
494
495 // Loose routing could have changed (temporarily) the protocol. Set it again to receive the
496 // replies.
498 }
499 if (returnValue > 0)
500 {
501 m_sent.emplace_back(Simulator::Now(), false);
502 m_txTrace(m_seq, p);
503 }
504 else
505 {
506 NS_LOG_INFO("Send failure; socket return value: " << returnValue);
507 }
508 m_seq++;
509 delete[] data;
510
511 if (m_count == 0 || m_seq < m_count)
512 {
514 }
515
516 // We have sent all the requests. Schedule a shutdown after the linger time
517 if (m_count > 0 && m_seq == m_count)
518 {
519 Time lingerTime = m_avgRtt.Count() > 0 ? MilliSeconds(2 * m_avgRtt.Max()) : m_timeout;
520 Simulator::Schedule(lingerTime, &Ping::StopApplication, this);
521 }
522}
523
524void
526{
527 NS_LOG_FUNCTION(this);
528
530 {
531 NS_ABORT_MSG("Destination Address value must be set when starting application");
532 }
533
535
537 m_reportPrinted = false;
539 {
541 {
543 std::cout << "PING " << realFrom.GetIpv4() << " - " << m_size << " bytes of data; "
544 << m_size + 28 << " bytes including ICMP and IPv4 headers.\n";
545 }
547 {
549 std::cout << "PING " << realFrom.GetIpv6() << " - " << m_size << " bytes of data; "
550 << m_size + 48 << " bytes including ICMP and IPv6 headers.\n";
551 }
552 else
553 {
554 NS_ABORT_MSG("Invalid Address");
555 }
556 }
557
559 {
560 m_socket =
561 Socket::CreateSocket(GetNode(), TypeId::LookupByName("ns3::Ipv4RawSocketFactory"));
562 NS_ASSERT_MSG(m_socket, "Ping::StartApplication: can not create socket.");
563 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.");
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
625void
627{
628 NS_LOG_FUNCTION(this);
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
644void
646{
647 if (m_reportPrinted)
648 {
649 return;
650 }
651 m_reportPrinted = true;
652
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
697void
698Ping::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
AttributeValue implementation for Address.
Definition: address.h:286
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:160
EventId m_stopEvent
The event that will fire at m_stopTime to end the application.
Definition: application.h:162
Ptr< Node > GetNode() const
Definition: application.cc:108
Ptr< Node > m_node
The node that this application is installed on.
Definition: application.h:158
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 GetId() const
Definition: node.cc:117
static bool ChecksumEnabled()
Definition: node.cc:278
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
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:214
uint32_t m_recv
Received packets counter.
Definition: ping.h:232
Time m_started
Start time to report total ping time.
Definition: ping.h:236
bool m_reportPrinted
True if the report has been printed already.
Definition: ping.h:271
std::vector< EchoRequestData > m_sent
All sent but not answered packets. Map icmp seqno -> when sent, acked at least once.
Definition: ping.h:264
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:273
@ SILENT
Silent output (no terminal output at all)
Definition: ping.h:72
@ VERBOSE
Verbose output (similar to real ping output)
Definition: ping.h:70
@ QUIET
Quiet output (similar to real 'ping -q' output)
Definition: ping.h:71
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:278
~Ping() override
Destructor.
Definition: ping.cc:136
TracedCallback< uint16_t, Ptr< Packet > > m_txTrace
Callbacks for tracing the packet Tx events.
Definition: ping.h:222
uint64_t m_appSignature
App signature: ID of the node where the app is installed || ID of the Application.
Definition: ping.h:281
uint32_t m_count
Number of packets to be sent.
Definition: ping.h:266
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:525
TracedCallback< const PingReport & > m_reportTrace
TracedCallback for final ping report.
Definition: ping.h:228
void StopApplication() override
Application specific shutdown code.
Definition: ping.cc:626
Average< double > m_avgRtt
Average rtt is ms.
Definition: ping.h:238
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:207
static TypeId GetTypeId()
Get the type ID.
Definition: ping.cc:57
bool m_multipleDestinations
Destination is Broadcast or Multicast.
Definition: ping.h:275
uint16_t m_seq
ICMP ECHO sequence number.
Definition: ping.h:220
uint32_t m_duplicate
Duplicate packets counter.
Definition: ping.h:234
Address m_interfaceAddress
Sender Local Address.
Definition: ping.h:203
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:218
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:205
EventId m_next
Next packet will be sent.
Definition: ping.h:240
Ptr< Socket > m_socket
The socket we send packets from.
Definition: ping.h:216
VerboseMode m_verbose
Variable to stor verbose mode.
Definition: ping.h:230
TracedCallback< uint16_t, DropReason > m_dropTrace
TracedCallback for drop events.
Definition: ping.h:226
Time m_timeout
Time to wait for a response, in seconds.
Definition: ping.h:269
TracedCallback< uint16_t, Time > m_rttTrace
TracedCallback for RTT samples.
Definition: ping.h:224
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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 SetIpTos(uint8_t ipTos)
Manually set IP Type of Service field.
Definition: socket.cc:434
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: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 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:1406
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:836
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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 AttributeChecker > MakeAddressChecker()
Definition: address.cc:180
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Definition: address.h:286
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
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:305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
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:706
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:189
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