29#include "ns3/assert.h"
30#include "ns3/boolean.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"
41#include "ns3/packet.h"
42#include "ns3/socket.h"
43#include "ns3/trace-source-accessor.h"
44#include "ns3/uinteger.h"
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",
79 .AddAttribute(
"Interval",
80 "Time interval between sending each packet",
86 "The number of data bytes to be sent, before ICMP and IP headers are added",
89 MakeUintegerChecker<uint32_t>(16))
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",
100 MakeAddressChecker())
101 .AddAttribute(
"Timeout",
102 "Time to wait for a response if no RTT samples are available",
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");
153 for (
uint32_t i = 0; i < node->GetNApplications(); ++i)
155 if (node->GetApplication(i) ==
this)
174 uint32_t recvSize = packet->GetSize();
175 NS_LOG_DEBUG(
"recv " << recvSize <<
" bytes " << *packet);
181 packet->RemoveHeader(ipv4Hdr);
184 packet->RemoveHeader(icmp);
190 packet->RemoveHeader(echo);
198 << std::dec << recvSize <<
" bytes from " << realFrom.
GetIpv4()
201 <<
" TTL = " <<
static_cast<uint16_t
>(ipv4Hdr.
GetTtl()));
209 uint8_t* buf =
new uint8_t[dataSize];
211 uint64_t appSignature =
Read64(buf);
220 bool dupReply =
false;
237 std::cout << recvSize <<
" bytes from " << realFrom.
GetIpv4() <<
":"
239 <<
" ttl=" <<
static_cast<uint16_t
>(ipv4Hdr.
GetTtl())
240 <<
" time=" << delta.GetMicroSeconds() / 1000.0 <<
" ms";
243 std::cout <<
" (DUP!)";
253 packet->RemoveHeader(destUnreach);
260 packet->RemoveHeader(timeExceeded);
276 packet->RemovePacketTag(infoTag);
279 int32_t ipIfIndex = ipv6->GetInterfaceForAddress(myAddr);
281 packet->RemoveHeader(ipv6Hdr);
284 packet->CopyData(&type,
sizeof(type));
290 packet->RemoveHeader(echo);
298 << std::dec << recvSize <<
" bytes from " << realFrom.
GetIpv6()
299 <<
" id = " << echo.
GetId() <<
" seq = " << echo.
GetSeq()
300 <<
" Hop Count = " <<
static_cast<uint16_t
>(ipv6Hdr.
GetHopLimit()));
302 uint32_t dataSize = packet->GetSize();
308 uint8_t* buf =
new uint8_t[dataSize];
309 packet->CopyData(buf, dataSize);
310 uint64_t appSignature =
Read64(buf);
319 bool dupReply =
false;
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";
342 std::cout <<
" (DUP!)";
347 ipv6->ReachabilityHint(ipIfIndex, realFrom.
GetIpv6());
352 packet->RemoveHeader(destUnreach);
359 packet->RemoveHeader(timeExceeded);
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;
397 uint64_t
data = buffer[7];
457 p->AddHeader(header);
470 p = dataPacket->Copy();
482 p->AddHeader(routingHeader);
500 NS_LOG_INFO(
"Send failure; socket return value: " << returnValue);
525 NS_ABORT_MSG(
"Destination Address value must be set when starting application");
537 std::cout <<
"PING " << realFrom.
GetIpv4() <<
" - " <<
m_size <<
" bytes of data; "
538 <<
m_size + 28 <<
" bytes including ICMP and IPv4 headers.\n";
543 std::cout <<
"PING " << realFrom.
GetIpv6() <<
" - " <<
m_size <<
" bytes of data; "
544 <<
m_size + 48 <<
" bytes including ICMP and IPv6 headers.\n";
579 NS_ABORT_MSG(
"Destination Address value must be of type Ipv4 or Ipv6");
600 NS_ABORT_MSG(
"Sender Address value must be of type Ipv4 or Ipv6");
609 m_sent.reserve(guessedTx);
649 std::ostringstream os;
654 os <<
"\n--- " << realFrom.
GetIpv4() <<
" ping statistics ---\n";
659 os <<
"\n--- " << realFrom.
GetIpv6() <<
" ping statistics ---\n";
661 os <<
m_seq <<
" packets transmitted, " <<
m_recv <<
" received, ";
676 std::cout << os.str();
a polymophic address class
AttributeValue implementation for Address.
The base class for all ns3 applications.
void DoDispose() override
Destructor implementation.
Time m_stopTime
The simulation time that the application will end.
EventId m_stopEvent
The event that will fire at m_stopTime to end the application.
Ptr< Node > GetNode() const
Ptr< Node > m_node
The node that this application is installed on.
double Avg() const
Sample average.
T Min() const
Sample minimum.
T Max() const
Sample maximum.
void Update(const T &x)
Add new sample.
uint32_t Count() const
Sample size.
double Stddev() const
Sample standard deviation.
Hold variables of type enum.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
ICMP Destination Unreachable header.
uint32_t GetData(uint8_t payload[]) const
Get the Echo data.
void SetIdentifier(uint16_t id)
Set the Echo identifier.
void SetData(Ptr< const Packet > data)
Set the Echo data.
uint16_t GetIdentifier() const
Get the Echo identifier.
void SetSequenceNumber(uint16_t seq)
Set the Echo sequence number.
uint32_t GetDataSize() const
Get the Echo data size.
uint16_t GetSequenceNumber() const
Get the Echo sequence number.
ICMP Time Exceeded header.
ICMPv6 Error Destination Unreachable header.
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 Time Exceeded header.
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.
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.
static Ipv4Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
Describes an IPv6 address.
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.
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.
static bool ChecksumEnabled()
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
This application behaves similarly to the Unix ping application, although with fewer options supporte...
uint32_t m_size
Specifies the number of data bytes to be sent.
uint32_t m_recv
Received packets counter.
Time m_started
Start time to report total ping time.
bool m_reportPrinted
True if the report has been printed already.
std::vector< EchoRequestData > m_sent
All sent but not answered packets. Map icmp seqno -> when sent, acked at least once.
uint64_t Read64(const uint8_t *buffer)
Writes data from a little-endian formatted buffer to data.
bool m_useIpv6
Use IPv4 (false) or IPv6 (true)
@ SILENT
Silent output (no terminal output at all)
@ VERBOSE
Verbose output (similar to real ping output)
@ QUIET
Quiet output (similar to real 'ping -q' output)
void SetRouters(const std::vector< Ipv6Address > &routers)
Set routers for IPv6 routing type 0 (loose routing).
std::vector< Ipv6Address > m_routers
Routers addresses for IPv6 routing type 0.
~Ping() override
Destructor.
TracedCallback< uint16_t, Ptr< Packet > > m_txTrace
Callbacks for tracing the packet Tx events.
uint64_t m_appSignature
App signature: ID of the node where the app is installed || ID of the Application.
uint32_t m_count
Number of packets to be sent.
uint64_t GetApplicationSignature() const
Return the application signatiure.
void Send()
Send one Ping (ICMPv4 ECHO or ICMPv6 ECHO) to the destination.
void DoDispose() override
Destructor implementation.
void StartApplication() override
Application specific startup code.
TracedCallback< const PingReport & > m_reportTrace
TracedCallback for final ping report.
void StopApplication() override
Application specific shutdown code.
Average< double > m_avgRtt
Average rtt is ms.
void PrintReport()
Print the report.
Time m_interval
Wait interval between ECHO requests.
static TypeId GetTypeId()
Get the type ID.
bool m_multipleDestinations
Destination is Broadcast or Multicast.
uint16_t m_seq
ICMP ECHO sequence number.
uint32_t m_duplicate
Duplicate packets counter.
Address m_interfaceAddress
Sender Local Address.
void Receive(Ptr< Socket > socket)
Receive an ICMPv4 or an ICMPv6 Echo reply.
void Write64(uint8_t *buffer, const uint64_t data)
Writes data to buffer in little-endian format.
Address m_destination
Remote address.
EventId m_next
Next packet will be sent.
Ptr< Socket > m_socket
The socket we send packets from.
VerboseMode m_verbose
Variable to stor verbose mode.
TracedCallback< uint16_t, DropReason > m_dropTrace
TracedCallback for drop events.
Time m_timeout
Time to wait for a response, in seconds.
TracedCallback< uint16_t, Time > m_rttTrace
TracedCallback for RTT samples.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
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.
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.
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...
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.
AttributeValue implementation for Time.
a unique identifier for an interface.
static TypeId LookupByName(std::string name)
Get a TypeId by name.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#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.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
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.
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...
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
A ping report provides all of the data that is typically output to the terminal when the application ...
Time m_duration
Duration of the application.
uint16_t m_loss
Percentage of lost packets (decimal value 0-100)
double m_rttAvg
rtt avg value
double m_rttMdev
rtt mdev value
uint32_t m_received
Number of echo replies received.
double m_rttMin
rtt min value
uint32_t m_transmitted
Number of echo requests sent.
double m_rttMax
rtt max value