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
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",
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",
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());
233 m_rttTrace(echo.GetSequenceNumber(), delta);
234
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
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;
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
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 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
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
@ 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: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
TracedCallback< const PingReport & > m_reportTrace
TracedCallback for final ping report.
Definition: ping.h:225
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< 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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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:840
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
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 AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
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:702
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