18 #include "ns3/assert.h"
19 #include "ns3/boolean.h"
20 #include "ns3/icmpv4.h"
21 #include "ns3/inet-socket-address.h"
22 #include "ns3/ipv4-address.h"
24 #include "ns3/packet.h"
25 #include "ns3/socket.h"
26 #include "ns3/trace-source-accessor.h"
27 #include "ns3/uinteger.h"
39 static TypeId tid = TypeId(
"ns3::V4Ping")
40 .SetParent<Application>()
41 .SetGroupName(
"Internet-Apps")
43 .AddAttribute(
"Remote",
44 "The address of the machine we want to ping.",
46 MakeIpv4AddressAccessor(&V4Ping::m_remote),
47 MakeIpv4AddressChecker())
48 .AddAttribute(
"Verbose",
49 "Produce usual output.",
53 .AddAttribute(
"Interval",
54 "Wait interval seconds between sending each packet.",
59 "The number of data bytes to be sent, real packet will "
60 "be 8 (ICMP) + 20 (IP) bytes longer.",
63 MakeUintegerChecker<uint32_t>(16))
64 .AddTraceSource(
"Rtt",
65 "The rtt calculated by the ping.",
67 "ns3::Time::TracedCallback");
93 if (m_next.IsRunning())
103 V4Ping::GetApplicationId()
const
106 Ptr<Node> node = GetNode();
107 for (uint32_t i = 0; i < node->GetNApplications(); ++i)
109 if (node->GetApplication(i) ==
this)
119 V4Ping::Receive(Ptr<Socket> socket)
122 while (m_socket->GetRxAvailable() > 0)
125 Ptr<Packet> p = m_socket->RecvFrom(0xffffffff, 0, from);
131 p->RemoveHeader(ipv4);
132 uint32_t recvSize = p->GetSize();
135 p->RemoveHeader(icmp);
139 p->RemoveHeader(echo);
140 std::map<uint16_t, Time>::iterator i = m_sent.find(echo.GetSequenceNumber());
142 if (i != m_sent.end() && echo.GetIdentifier() == 0)
144 uint32_t* buf =
new uint32_t[m_size];
145 uint32_t dataSize = echo.GetDataSize();
148 if (dataSize == m_size)
150 echo.GetData((uint8_t*)buf);
151 Read32((
const uint8_t*)&buf[0], nodeId);
152 Read32((
const uint8_t*)&buf[1], appId);
154 if (nodeId == GetNode()->GetId() && appId == GetApplicationId())
156 Time sendTime = i->second;
161 m_avgRtt.Update(
delta.GetMilliSeconds());
167 std::cout << recvSize <<
" bytes from " << realFrom.GetIpv4() <<
":"
168 <<
" icmp_seq=" << echo.GetSequenceNumber()
169 <<
" ttl=" << (unsigned)ipv4.GetTtl()
183 V4Ping::Write32(uint8_t* buffer,
const uint32_t
data)
186 buffer[0] = (
data >> 0) & 0xff;
187 buffer[1] = (
data >> 8) & 0xff;
188 buffer[2] = (
data >> 16) & 0xff;
189 buffer[3] = (
data >> 24) & 0xff;
194 V4Ping::Read32(
const uint8_t* buffer, uint32_t&
data)
197 data = (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + buffer[0];
206 Ptr<Packet> p = Create<Packet>();
208 echo.SetSequenceNumber(m_seq);
210 echo.SetIdentifier(0);
218 uint8_t*
data =
new uint8_t[m_size];
219 for (uint32_t i = 0; i < m_size; ++i)
225 uint32_t tmp = GetNode()->GetId();
226 Write32(&
data[0 *
sizeof(uint32_t)], tmp);
228 tmp = GetApplicationId();
229 Write32(&
data[1 *
sizeof(uint32_t)], tmp);
231 Ptr<Packet> dataPacket = Create<Packet>((uint8_t*)
data, m_size);
232 echo.SetData(dataPacket);
239 header.EnableChecksum();
241 p->AddHeader(header);
243 m_socket->Send(p, 0);
249 V4Ping::StartApplication()
256 std::cout <<
"PING " << m_remote <<
" - " << m_size <<
" bytes of data - " << m_size + 28
257 <<
" bytes including ICMP and IPv4 headers.\n";
262 m_socket->SetAttribute(
"Protocol", UintegerValue(1));
263 m_socket->SetRecvCallback(
MakeCallback(&V4Ping::Receive,
this));
266 status = m_socket->Bind(src);
268 InetSocketAddress dst = InetSocketAddress(m_remote, 0);
269 status = m_socket->Connect(dst);
276 V4Ping::StopApplication()
280 if (m_next.IsRunning())
291 std::ostringstream os;
293 os <<
"--- " << m_remote <<
" ping statistics ---\n"
294 << m_seq <<
" packets transmitted, " << m_recv <<
" received, "
295 << ((m_seq - m_recv) * 100 / m_seq) <<
"% packet loss, "
298 if (m_avgRtt.Count() > 0)
300 os <<
"rtt min/avg/max/mdev = " << m_avgRtt.Min() <<
"/" << m_avgRtt.Avg() <<
"/"
301 << m_avgRtt.Max() <<
"/" << m_avgRtt.Stddev() <<
" ms\n";
303 std::cout << os.str();
void DoDispose() override
Destructor implementation.
static bool IsMatchingType(const Address &address)
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
static Ipv4Address GetAny()
AttributeValue implementation for Ipv4Address.
static bool ChecksumEnabled()
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 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...
static TypeId LookupByName(std::string name)
Get a TypeId by name.
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
#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 > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#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 Seconds(double 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.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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 > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.